diff --git a/honk/Makefile b/honk/Makefile
index 475bb7a64..eace91c2f 100644
--- a/honk/Makefile
+++ b/honk/Makefile
@@ -5,11 +5,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=honk
-PKG_VERSION:=2026.11.08~62b1390
-PKG_RELEASE:=33
+PKG_VERSION:=2026.11.09~6484888
+PKG_RELEASE:=34
HONK_SRC_URL:=https://github.com/daeuniverse/honk.git
-HONK_SRC_VERSION:=62b1390401d9b5eb00dfaddad3e11db4a2539fdf
+HONK_SRC_VERSION:=64848881b7304e250e7a25422f4f1d86a5975eca
PKG_LICENSE:=AGPL-3.0-only
PKG_LICENSE_FILES:=LICENSE
diff --git a/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js b/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js
index f6878483f..92aa87f60 100644
--- a/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js
+++ b/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js
@@ -339,10 +339,10 @@ const rules_type = [
{
label: _('Inbound'),
types: [
- //['IN-PORT'],
- //['IN-TYPE'],
+ ['IN-PORT'],
+ ['IN-TYPE'],
//['IN-USER'],
- //['IN-NAME'],
+ ['IN-NAME'],
['REMATCH-NAME']
]
},
@@ -1327,6 +1327,7 @@ function loadLabelValues(uciconfig, sectiontype, options = {}) {
switch (sectiontype) {
case 'proxy_group':
+ case 'inbound':
case 'node':
case 'provider':
uci.sections(uciconfig, sectiontype, (res) => {
@@ -1814,6 +1815,9 @@ function validateBase64Key(length, section_id, value) {
if (value)
if (value.length !== length || !value.match(/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/) || value[length-1] !== '=')
return _('Expecting: %s').format(_('valid base64 key with %d characters').format(length));
+ else
+ if (this.rmempty === false || (this.optional ?? true) !== false)
+ return _('Expecting: %s').format(_('non-empty value'));
return true;
}
@@ -2115,25 +2119,25 @@ return baseclass.extend({
handleGenKey,
handleReload,
handleRemoveIdles,
- textvalue2Value,
+ textvalue2Value, // this
// validate
validateAuth,
validateAuthUsername,
validateAuthPassword,
- validateCommonPort,
+ validateCommonPort, // this
validateBytesize,
validateTimeDuration,
validateJson,
validateUUID,
validateUrl,
validateHexstr,
- validateBase64Key,
+ validateBase64Key, // this
validateSha256Key,
- validateMTLSClientAuth,
- validatePresetIDs,
- validateShadowsocksPassword,
+ validateMTLSClientAuth, // this
+ validatePresetIDs, // this
+ validateShadowsocksPassword, // this
validateSudokuCustomTable,
- validateUniqueValue,
+ validateUniqueValue, // this
// file operations
lsDir,
readFile,
diff --git a/luci-app-fchomo/htdocs/luci-static/resources/fchomo/listeners.js b/luci-app-fchomo/htdocs/luci-static/resources/fchomo/listeners.js
index cf5497ae2..16098d4a3 100644
--- a/luci-app-fchomo/htdocs/luci-static/resources/fchomo/listeners.js
+++ b/luci-app-fchomo/htdocs/luci-static/resources/fchomo/listeners.js
@@ -402,10 +402,19 @@ function renderListeners(s, uciconfig, isClient) {
o.value('3', _('v3'));
o.value('4', _('v4'));
o.value('5', _('v5'));
+ o.value('6', _('v6'));
o.default = '4';
o.depends('type', 'snell');
o.modalonly = true;
+ o = s.taboption('field_general', form.ListValue, 'snell_mode', _('Traffic mode'));
+ o.value('', _('Keep default'));
+ o.value('default', _('Default'));
+ o.value('unshaped', _('No obfuscation'));
+ o.value('unsafe-raw', _('No encryption No obfuscation'));
+ o.depends({type: 'snell', snell_version: /^(6)$/});
+ o.modalonly = true;
+
/* VMess / VLESS fields */
o = s.taboption('field_general', hm.GenValue, 'vmess_uuid', _('UUID'));
o.rmempty = false;
@@ -693,11 +702,20 @@ function renderListeners(s, uciconfig, isClient) {
//o.value('kcp-tun', _('kcp-tun'));
o.validate = function(section_id, value) {
const type = this.section.getOption('type').formvalue(section_id);
+ const snell_version = this.section.getOption('snell_version').formvalue(section_id);
if (value) {
- if (type === 'snell' && !['obfs', 'shadow-tls', 'restls', 'jls'].includes(value)) {
- return _('Expecting: Only support %s.').format(_('obfs-simple') +
- ' / ' + _('ShadowTLS') +
+ if (type === 'snell' && !['shadow-tls', 'restls', 'jls'].includes(value)) {
+ let obfs_simple_supported = true;
+ if (Number(snell_version) < 6) {
+ if (value === 'obfs')
+ return true;
+ } else
+ obfs_simple_supported = false;
+
+ return _('Expecting: Only support %s.').format(
+ (obfs_simple_supported ? _('obfs-simple') + ' / ' : '') +
+ _('ShadowTLS') +
' / ' + _('Restls') +
' / ' + _('JLS'));
}
diff --git a/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/client.js b/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/client.js
index 193cfd765..388517f92 100644
--- a/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/client.js
+++ b/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/client.js
@@ -404,13 +404,23 @@ const parseRulesYaml = hm.parseYaml.extend({
else
[type, factor] = logical_payload[i].split(',');
- if (type === 'RULE-SET')
+ if (type === 'IN-TYPE') {
+ factor = factor.toLowerCase(); // Multi-values are not supported in Factor ++
+ //factor = factor.replace(/\/.*/, '').toLowerCase();
+ } else if (type === 'IN-NAME')
+ factor = this.calcID(hm.glossary["inbound"].field, factor);
+ else if (type === 'RULE-SET')
factor = this.calcID(hm.glossary["ruleset"].field, factor);
entry.setPayload(i, {type: type.toUpperCase(), factor: factor, deny: deny ? true : null});
}
else if (payload)
- if (tp === 'RULE-SET')
+ if (tp === 'IN-TYPE') {
+ entry.setPayload(0, {factor: payload.toLowerCase()}); // Multi-values are not supported in Factor ++
+ // entry.setPayload(0, {factor: payload.replace(/\/.*/, '').toLowerCase()});
+ } else if (tp === 'IN-NAME')
+ entry.setPayload(0, {factor: this.calcID(hm.glossary["inbound"].field, payload)});
+ else if (tp === 'RULE-SET')
entry.setPayload(0, {factor: this.calcID(hm.glossary["ruleset"].field, payload)});
else
entry.setPayload(0, {factor: payload});
@@ -429,7 +439,7 @@ const parseRulesYaml = hm.parseYaml.extend({
parseRules(line) {
// parse rules
- // https://github.com/muink/mihomo/blob/ad730ae9744971dfaa75bda20cfc2ffe07eeb59d/config/config.go#L1090-L1118
+ // https://github.com/muink/mihomo/blob/63bd52ec794b7051569b76ede2f6cdbf4c091fda/config/config.go#L1102-L1130
let [tp, payload, target, params] = this.ParseRulePayload(line, true);
if (!target)
return null; // error: format invalid
@@ -563,27 +573,6 @@ function renderPayload(s, total, uciconfig) {
o.depends(Object.fromEntries([[prefix + 'type', /\bPROCESS\b/]]));
initPayload(o, n, 'factor', uciconfig);
- o = s.option(form.ListValue, prefix + 'rematchname', _('Factor') + ` ${n+1}`);
- if (n === 0)
- o.depends('type', 'REMATCH-NAME');
- o.depends(prefix + 'type', 'REMATCH-NAME');
- initPayload(o, n, 'factor', uciconfig);
- o.load = L.bind(function(n, key, uciconfig, section_id) {
- hm.loadLabel.call(this, [
- ['', _('-- Please choose --')],
- ...hm.loadLabelValues(this.config, 'rematch-name')
- ], section_id);
-
- return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayload(n)[key];
- }, o, n, 'factor', uciconfig)
-
- o = s.option(form.Value, prefix + 'uint', _('Factor') + ` ${n+1}`);
- o.datatype = 'uinteger';
- if (n === 0)
- o.depends('type', 'UID');
- o.depends(prefix + 'type', 'UID');
- initPayload(o, n, 'factor', uciconfig);
-
o = s.option(form.Value, prefix + 'ip', _('Factor') + ` ${n+1}`);
o.datatype = 'cidr';
if (n === 0) {
@@ -613,6 +602,63 @@ function renderPayload(s, total, uciconfig) {
return result;
}
+ o = s.option(form.MultiValue, prefix + 'intype', _('Factor') + ` ${n+1}`);
+ hm.inbound_type.forEach((res) => {
+ o.value.apply(o, res);
+ })
+ if (n === 0)
+ o.depends('type', 'IN-TYPE');
+ o.depends(prefix + 'type', 'IN-TYPE');
+ initPayload(o, n, 'factor', uciconfig);
+ o.load = L.bind(function(n, key, uciconfig, section_id) {
+ return (new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayload(n)[key] || '')
+ .split('/');
+ }, o, n, 'factor', uciconfig)
+ o.onchange = function(ev, section_id, value) {
+ let UIEl = this.section.getUIElement(section_id, 'entry');
+
+ let n = this.option.match(/^payload(\d+)_/)[1];
+ let rule = new RulesEntry(UIEl.getValue()).setPayload(n, {factor: value.join('/')});
+
+ UIEl.node.previousSibling.innerText = rule.toString('mihomo');
+ UIEl.setValue(rule.toString('json'));
+ }
+
+ o = s.option(form.ListValue, prefix + 'inname', _('Factor') + ` ${n+1}`);
+ if (n === 0)
+ o.depends('type', 'IN-NAME');
+ o.depends(prefix + 'type', 'IN-NAME');
+ initPayload(o, n, 'factor', uciconfig);
+ o.load = L.bind(function(n, key, uciconfig, section_id) {
+ hm.loadLabel.call(this, [
+ ['', _('-- Please choose --')],
+ ...hm.loadLabelValues(this.config, 'inbound')
+ ], section_id);
+
+ return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayload(n)[key];
+ }, o, n, 'factor', uciconfig)
+
+ o = s.option(form.ListValue, prefix + 'rematchname', _('Factor') + ` ${n+1}`);
+ if (n === 0)
+ o.depends('type', 'REMATCH-NAME');
+ o.depends(prefix + 'type', 'REMATCH-NAME');
+ initPayload(o, n, 'factor', uciconfig);
+ o.load = L.bind(function(n, key, uciconfig, section_id) {
+ hm.loadLabel.call(this, [
+ ['', _('-- Please choose --')],
+ ...hm.loadLabelValues(this.config, 'rematch-name')
+ ], section_id);
+
+ return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayload(n)[key];
+ }, o, n, 'factor', uciconfig)
+
+ o = s.option(form.Value, prefix + 'uint', _('Factor') + ` ${n+1}`);
+ o.datatype = 'uinteger';
+ if (n === 0)
+ o.depends('type', 'UID');
+ o.depends(prefix + 'type', 'UID');
+ initPayload(o, n, 'factor', uciconfig);
+
o = s.option(form.ListValue, prefix + 'l4', _('Factor') + ` ${n+1}`);
o.value('udp', _('UDP'));
o.value('tcp', _('TCP'));
@@ -702,6 +748,8 @@ function renderPayload(s, total, uciconfig) {
initDynamicPayload(o, n, 'factor', uciconfig);
o.load = L.bind(function(n, key, uciconfig, section_id) {
hm.loadLabel.call(this, [
+ ...hm.inbound_type.map(e => [e, _('IN-TYPE')]), // Multi-values are not supported
+ ...hm.loadLabelValues(this.config, 'inbound').map(e => [e, _('IN-NAME')]),
...hm.loadLabelValues(this.config, 'rematch-name').map(e => [e, _('REMATCH-NAME')]),
[['udp', _('UDP')], _('NETWORK')],
[['tcp', _('TCP')], _('NETWORK')],
@@ -1306,6 +1354,10 @@ return view.extend({
'- SRC-IP-SUFFIX,192.168.1.201/8,DIRECT\n' +
'- DST-PORT,80,DIRECT\n' +
'- SRC-PORT,7777,DIRECT\n' +
+ '- IN-PORT,7890/7893,GLOBAL\n' +
+ '- IN-TYPE,SOCKS/HTTP,GLOBAL\n' +
+ '- IN-NAME,ss,GLOBAL\n' +
+ '- REMATCH-NAME,rematch1,GLOBAL\n' +
'- PROCESS-PATH,/usr/bin/wget,auto\n' +
'- PROCESS-PATH-WILDCARD,/usr/*/wget,GLOBAL\n' +
'- PROCESS-PATH-REGEX,.*bin/wget,auto\n' +
diff --git a/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js b/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js
index 7e81b1525..94fcca8f9 100644
--- a/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js
+++ b/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js
@@ -517,13 +517,23 @@ return view.extend({
so.value('3', _('v3'));
so.value('4', _('v4'));
so.value('5', _('v5'));
+ so.value('6', _('v6'));
so.default = '4';
so.depends('type', 'snell');
so.modalonly = true;
so = ss.taboption('field_general', form.Flag, 'snell_reuse', _('Connection reuse'));
so.default = so.disabled;
- so.depends({type: 'snell', snell_version: /^(4|5)$/});
+ so.depends({type: 'snell', snell_version: /^(4|5|6)$/});
+ so.modalonly = true;
+
+ so = ss.taboption('field_general', form.ListValue, 'snell_mode', _('Traffic mode'),
+ _('Must be consistent with the server.'));
+ so.value('', _('Keep default'));
+ so.value('default', _('Default'));
+ so.value('unshaped', _('No obfuscation'));
+ so.value('unsafe-raw', _('No encryption No obfuscation'));
+ so.depends({type: 'snell', snell_version: /^(6)$/});
so.modalonly = true;
/* VMess / VLESS fields */
@@ -1254,7 +1264,7 @@ return view.extend({
so = ss.taboption('field_general', form.Flag, 'udp', _('Force UDP'));
so.default = so.disabled;
so.depends({type: /^(rematch|direct|socks5|ss|mieru|vmess|vless|trojan|anytls|trusttunnel|zerotier|wireguard|tailscale|masque|easytier)$/});
- so.depends({type: 'snell', snell_version: /^(3|4|5)$/});
+ so.depends({type: 'snell', snell_version: /^(3|4|5|6)$/});
so.modalonly = true;
so = ss.taboption('field_general', form.Flag, 'uot', _('UoT'),
@@ -1287,11 +1297,20 @@ return view.extend({
//so.value('kcptun', _('kcptun'));
so.validate = function(section_id, value) {
const type = this.section.getOption('type').formvalue(section_id);
+ const snell_version = this.section.getOption('snell_version').formvalue(section_id);
if (value) {
- if (type === 'snell' && !['obfs', 'shadow-tls', 'restls', 'jls'].includes(value)) {
- return _('Expecting: Only support %s.').format(_('obfs-simple') +
- ' / ' + _('ShadowTLS') +
+ if (type === 'snell' && !['shadow-tls', 'restls', 'jls'].includes(value)) {
+ let obfs_simple_supported = true;
+ if (Number(snell_version) < 6) {
+ if (value === 'obfs')
+ return true;
+ } else
+ obfs_simple_supported = false;
+
+ return _('Expecting: Only support %s.').format(
+ (obfs_simple_supported ? _('obfs-simple') + ' / ' : '') +
+ _('ShadowTLS') +
' / ' + _('Restls') +
' / ' + _('JLS'));
}
diff --git a/luci-app-fchomo/po/templates/fchomo.pot b/luci-app-fchomo/po/templates/fchomo.pot
index 85eb48a9c..e6487e15d 100644
--- a/luci-app-fchomo/po/templates/fchomo.pot
+++ b/luci-app-fchomo/po/templates/fchomo.pot
@@ -1,12 +1,12 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
-#: htdocs/luci-static/resources/view/fchomo/node.js:962
+#: htdocs/luci-static/resources/view/fchomo/node.js:972
msgid "%s Hostname"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1686
-#: htdocs/luci-static/resources/view/fchomo/node.js:1696
+#: htdocs/luci-static/resources/view/fchomo/node.js:1708
+#: htdocs/luci-static/resources/view/fchomo/node.js:1718
msgid "%s UDP port. 0 selects an available port."
msgstr ""
@@ -14,7 +14,7 @@ msgstr ""
msgid "%s log"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:815
+#: htdocs/luci-static/resources/view/fchomo/node.js:825
msgid "%s of the %s used to receiving remote debugging log."
msgstr ""
@@ -27,23 +27,23 @@ msgstr ""
msgid "%s ports"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:785
#: htdocs/luci-static/resources/fchomo.js:788
+#: htdocs/luci-static/resources/fchomo.js:791
#: htdocs/luci-static/resources/view/fchomo/client.js:318
msgid "(Imported)"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1488
-#: htdocs/luci-static/resources/fchomo.js:1494
-#: htdocs/luci-static/resources/fchomo/listeners.js:1160
-#: htdocs/luci-static/resources/fchomo/listeners.js:1168
-#: htdocs/luci-static/resources/fchomo/listeners.js:1177
+#: htdocs/luci-static/resources/fchomo.js:1491
+#: htdocs/luci-static/resources/fchomo.js:1497
+#: htdocs/luci-static/resources/fchomo/listeners.js:1178
+#: htdocs/luci-static/resources/fchomo/listeners.js:1186
+#: htdocs/luci-static/resources/fchomo/listeners.js:1195
#: htdocs/luci-static/resources/view/fchomo/global.js:572
#: htdocs/luci-static/resources/view/fchomo/global.js:578
-#: htdocs/luci-static/resources/view/fchomo/node.js:1527
-#: htdocs/luci-static/resources/view/fchomo/node.js:1533
-#: htdocs/luci-static/resources/view/fchomo/node.js:1541
-#: htdocs/luci-static/resources/view/fchomo/node.js:1547
+#: htdocs/luci-static/resources/view/fchomo/node.js:1550
+#: htdocs/luci-static/resources/view/fchomo/node.js:1556
+#: htdocs/luci-static/resources/view/fchomo/node.js:1564
+#: htdocs/luci-static/resources/view/fchomo/node.js:1570
msgid "(mTLS)"
msgstr ""
@@ -65,10 +65,10 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1113
#: htdocs/luci-static/resources/view/fchomo/client.js:1369
#: htdocs/luci-static/resources/view/fchomo/node.js:305
-#: htdocs/luci-static/resources/view/fchomo/node.js:2735
-#: htdocs/luci-static/resources/view/fchomo/node.js:2746
-#: htdocs/luci-static/resources/view/fchomo/node.js:2765
-#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2756
+#: htdocs/luci-static/resources/view/fchomo/node.js:2767
+#: htdocs/luci-static/resources/view/fchomo/node.js:2786
+#: htdocs/luci-static/resources/view/fchomo/node.js:2797
msgid "-- Please choose --"
msgstr ""
@@ -97,7 +97,7 @@ msgstr ""
msgid "2022-blake3-chacha20-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1697
+#: htdocs/luci-static/resources/view/fchomo/node.js:1719
msgid "-1 disables it."
msgstr ""
@@ -105,11 +105,11 @@ msgstr ""
msgid "0 or 1 only."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1138
-#: htdocs/luci-static/resources/fchomo/listeners.js:1153
-#: htdocs/luci-static/resources/fchomo/listeners.js:1178
-#: htdocs/luci-static/resources/view/fchomo/node.js:1534
-#: htdocs/luci-static/resources/view/fchomo/node.js:1548
+#: htdocs/luci-static/resources/fchomo/listeners.js:1156
+#: htdocs/luci-static/resources/fchomo/listeners.js:1171
+#: htdocs/luci-static/resources/fchomo/listeners.js:1196
+#: htdocs/luci-static/resources/view/fchomo/node.js:1557
+#: htdocs/luci-static/resources/view/fchomo/node.js:1571
msgid "Save your configuration before uploading files!"
msgstr ""
@@ -182,7 +182,7 @@ msgstr ""
msgid "ASN version"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:983
+#: htdocs/luci-static/resources/view/fchomo/node.js:993
msgid "Accept routes"
msgstr ""
@@ -211,11 +211,11 @@ msgstr ""
msgid "Add a inbound"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2196
+#: htdocs/luci-static/resources/view/fchomo/node.js:2217
msgid "Add a provider"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2709
+#: htdocs/luci-static/resources/view/fchomo/node.js:2730
msgid "Add a proxy chain"
msgstr ""
@@ -239,15 +239,15 @@ msgstr ""
msgid "Add a sub rule"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2493
+#: htdocs/luci-static/resources/view/fchomo/node.js:2514
msgid "Add prefix"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2497
+#: htdocs/luci-static/resources/view/fchomo/node.js:2518
msgid "Add suffix"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:870
+#: htdocs/luci-static/resources/view/fchomo/node.js:880
msgid "Add the base64 text of the planet file here."
msgstr ""
@@ -256,7 +256,7 @@ msgstr ""
msgid "Address"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1160
+#: htdocs/luci-static/resources/view/fchomo/node.js:1174
msgid "After disabling, communication will only be possible via relay."
msgstr ""
@@ -284,7 +284,7 @@ msgstr ""
msgid "All ports"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:994
+#: htdocs/luci-static/resources/view/fchomo/node.js:1004
msgid "Allow LAN access"
msgstr ""
@@ -294,19 +294,19 @@ msgid ""
"network from a public website, it must be enabled."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:995
+#: htdocs/luci-static/resources/view/fchomo/node.js:1005
msgid "Allow access to the local LAN via the exit node."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1061
+#: htdocs/luci-static/resources/fchomo/listeners.js:1079
msgid "Allow insecure connections"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1148
+#: htdocs/luci-static/resources/view/fchomo/node.js:1162
msgid "Allow this node to be an exit node."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:943
+#: htdocs/luci-static/resources/view/fchomo/node.js:953
msgid "Allowed IPs"
msgstr ""
@@ -318,8 +318,8 @@ msgstr ""
msgid "Already in updating."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:424
-#: htdocs/luci-static/resources/view/fchomo/node.js:544
+#: htdocs/luci-static/resources/fchomo/listeners.js:433
+#: htdocs/luci-static/resources/view/fchomo/node.js:554
msgid "Alter ID"
msgstr ""
@@ -332,11 +332,11 @@ msgstr ""
msgid "Application version"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:978
+#: htdocs/luci-static/resources/view/fchomo/node.js:988
msgid "As ephemeral node"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1147
+#: htdocs/luci-static/resources/view/fchomo/node.js:1161
msgid "As exit node"
msgstr ""
@@ -349,35 +349,35 @@ msgstr ""
msgid "As the TOP upstream of dnsmasq."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:472
+#: htdocs/luci-static/resources/fchomo/listeners.js:481
msgid "Auth timeout"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:566
+#: htdocs/luci-static/resources/view/fchomo/node.js:576
msgid "Authenticated length"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:973
+#: htdocs/luci-static/resources/view/fchomo/node.js:983
msgid "Authentication key"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:376
-#: htdocs/luci-static/resources/fchomo/listeners.js:1353
+#: htdocs/luci-static/resources/fchomo/listeners.js:1371
#: htdocs/luci-static/resources/view/fchomo/global.js:423
#: htdocs/luci-static/resources/view/fchomo/node.js:467
#: htdocs/luci-static/resources/view/fchomo/node.js:491
-#: htdocs/luci-static/resources/view/fchomo/node.js:850
-#: htdocs/luci-static/resources/view/fchomo/node.js:1202
-#: htdocs/luci-static/resources/view/fchomo/node.js:2002
+#: htdocs/luci-static/resources/view/fchomo/node.js:860
+#: htdocs/luci-static/resources/view/fchomo/node.js:1216
+#: htdocs/luci-static/resources/view/fchomo/node.js:2023
msgid "Auto"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1815
+#: htdocs/luci-static/resources/view/fchomo/node.js:1836
msgid "Auto Enable when %s is empty."
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:139
-#: htdocs/luci-static/resources/view/fchomo/node.js:1618
+#: htdocs/luci-static/resources/view/fchomo/node.js:1641
msgid "Auto configure firewall"
msgstr ""
@@ -389,8 +389,8 @@ msgstr ""
msgid "Auto update resources."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:653
-#: htdocs/luci-static/resources/view/fchomo/node.js:1227
+#: htdocs/luci-static/resources/fchomo/listeners.js:662
+#: htdocs/luci-static/resources/view/fchomo/node.js:1241
msgid "BBR profile"
msgstr ""
@@ -398,19 +398,19 @@ msgstr ""
msgid "Baidu"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1002
+#: htdocs/luci-static/resources/view/fchomo/node.js:1012
msgid "Base64 encoded ECDSA private key on the NIST P-256 curve."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1010
+#: htdocs/luci-static/resources/view/fchomo/node.js:1020
msgid "Base64 encoded ECDSA public key on the NIST P-256 curve."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1095
+#: htdocs/luci-static/resources/view/fchomo/node.js:1108
msgid "Base64 encoded X25519 private key."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1111
+#: htdocs/luci-static/resources/view/fchomo/node.js:1125
msgid "Base64 encoded X25519 public key."
msgstr ""
@@ -432,13 +432,13 @@ msgid "Binary mrs"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/global.js:766
-#: htdocs/luci-static/resources/view/fchomo/node.js:2163
-#: htdocs/luci-static/resources/view/fchomo/node.js:2582
+#: htdocs/luci-static/resources/view/fchomo/node.js:2184
+#: htdocs/luci-static/resources/view/fchomo/node.js:2603
msgid "Bind interface"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2164
-#: htdocs/luci-static/resources/view/fchomo/node.js:2583
+#: htdocs/luci-static/resources/view/fchomo/node.js:2185
+#: htdocs/luci-static/resources/view/fchomo/node.js:2604
msgid "Bind outbound interface."
msgstr ""
@@ -503,24 +503,24 @@ msgstr ""
msgid "CORS allowed origins, * will be used if empty."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:901
+#: htdocs/luci-static/resources/fchomo.js:904
msgid "Cancel"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1468
-#: htdocs/luci-static/resources/view/fchomo/node.js:1507
+#: htdocs/luci-static/resources/fchomo.js:1471
+#: htdocs/luci-static/resources/view/fchomo/node.js:1530
msgid "Cert fingerprint"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1469
-#: htdocs/luci-static/resources/view/fchomo/node.js:1508
+#: htdocs/luci-static/resources/fchomo.js:1472
+#: htdocs/luci-static/resources/view/fchomo/node.js:1531
msgid ""
"Certificate fingerprint. Used to implement SSL Pinning and prevent MitM."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1488
-#: htdocs/luci-static/resources/fchomo/listeners.js:1115
-#: htdocs/luci-static/resources/view/fchomo/node.js:1527
+#: htdocs/luci-static/resources/fchomo.js:1491
+#: htdocs/luci-static/resources/fchomo/listeners.js:1133
+#: htdocs/luci-static/resources/view/fchomo/node.js:1550
msgid "Certificate path"
msgstr ""
@@ -559,7 +559,7 @@ msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:282
#: htdocs/luci-static/resources/view/fchomo/node.js:340
#: htdocs/luci-static/resources/view/fchomo/node.js:399
-#: htdocs/luci-static/resources/view/fchomo/node.js:550
+#: htdocs/luci-static/resources/view/fchomo/node.js:560
msgid "Chipher"
msgstr ""
@@ -578,27 +578,27 @@ msgid ""
"to download the latest initial package."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1489
-#: htdocs/luci-static/resources/fchomo.js:1495
-#: htdocs/luci-static/resources/fchomo/listeners.js:869
-#: htdocs/luci-static/resources/fchomo/listeners.js:1169
+#: htdocs/luci-static/resources/fchomo.js:1492
+#: htdocs/luci-static/resources/fchomo.js:1498
+#: htdocs/luci-static/resources/fchomo/listeners.js:887
+#: htdocs/luci-static/resources/fchomo/listeners.js:1187
#: htdocs/luci-static/resources/view/fchomo/global.js:579
-#: htdocs/luci-static/resources/view/fchomo/node.js:1392
-#: htdocs/luci-static/resources/view/fchomo/node.js:1528
-#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/view/fchomo/node.js:1415
+#: htdocs/luci-static/resources/view/fchomo/node.js:1551
+#: htdocs/luci-static/resources/view/fchomo/node.js:1565
#: root/usr/share/luci/menu.d/luci-app-fchomo.json:22
msgid "Client"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1168
+#: htdocs/luci-static/resources/fchomo/listeners.js:1186
msgid "Client Auth Certificate path"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1160
+#: htdocs/luci-static/resources/fchomo/listeners.js:1178
msgid "Client Auth type"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1573
+#: htdocs/luci-static/resources/view/fchomo/node.js:1596
msgid "Client fingerprint"
msgstr ""
@@ -606,15 +606,15 @@ msgstr ""
msgid "Client key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:603
+#: htdocs/luci-static/resources/view/fchomo/node.js:613
msgid "Client metadata"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1094
+#: htdocs/luci-static/resources/view/fchomo/node.js:1107
msgid "Client private key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1110
+#: htdocs/luci-static/resources/view/fchomo/node.js:1124
msgid "Client public key"
msgstr ""
@@ -622,8 +622,8 @@ msgstr ""
msgid "Client status"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1771
-#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1792
+#: htdocs/luci-static/resources/view/fchomo/node.js:1824
msgid "Cloudflare WARP"
msgstr ""
@@ -636,18 +636,18 @@ msgstr ""
msgid "Common ports (bypass P2P traffic)"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1661
+#: htdocs/luci-static/resources/fchomo.js:1663
msgid "Complete"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1040
+#: htdocs/luci-static/resources/view/fchomo/node.js:1050
msgid "Configuration Document"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:645
+#: htdocs/luci-static/resources/fchomo/listeners.js:654
#: htdocs/luci-static/resources/view/fchomo/global.js:549
-#: htdocs/luci-static/resources/view/fchomo/node.js:1210
-#: htdocs/luci-static/resources/view/fchomo/node.js:1218
+#: htdocs/luci-static/resources/view/fchomo/node.js:1224
+#: htdocs/luci-static/resources/view/fchomo/node.js:1232
msgid "Congestion controller"
msgstr ""
@@ -655,12 +655,12 @@ msgstr ""
msgid "Connection check"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:524
+#: htdocs/luci-static/resources/view/fchomo/node.js:525
msgid "Connection reuse"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:590
-#: htdocs/luci-static/resources/view/fchomo/node.js:784
+#: htdocs/luci-static/resources/fchomo/listeners.js:599
+#: htdocs/luci-static/resources/view/fchomo/node.js:794
msgid "Connection-level receive window size"
msgstr ""
@@ -668,19 +668,19 @@ msgstr ""
msgid "Conservative"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:770
+#: htdocs/luci-static/resources/fchomo.js:773
msgid "Content copied to clipboard!"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:698
-#: htdocs/luci-static/resources/view/fchomo/node.js:2353
-#: htdocs/luci-static/resources/view/fchomo/node.js:2379
+#: htdocs/luci-static/resources/view/fchomo/node.js:2374
+#: htdocs/luci-static/resources/view/fchomo/node.js:2400
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:359
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:385
msgid "Content will not be verified, Please make sure you enter it correctly."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2352
+#: htdocs/luci-static/resources/view/fchomo/node.js:2373
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:358
msgid "Contents"
msgstr ""
@@ -689,11 +689,11 @@ msgstr ""
msgid "Contents have been saved."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:967
+#: htdocs/luci-static/resources/view/fchomo/node.js:977
msgid "Control server"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:772
+#: htdocs/luci-static/resources/fchomo.js:775
msgid "Copy"
msgstr ""
@@ -705,7 +705,7 @@ msgstr ""
msgid "Cron expression"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:968
+#: htdocs/luci-static/resources/view/fchomo/node.js:978
msgid "Custom %s control server."
msgstr ""
@@ -713,7 +713,7 @@ msgstr ""
msgid "Custom Direct List"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2484
+#: htdocs/luci-static/resources/view/fchomo/node.js:2505
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:431
msgid "Custom HTTP header."
msgstr ""
@@ -739,7 +739,7 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1831
#: htdocs/luci-static/resources/view/fchomo/client.js:1840
#: htdocs/luci-static/resources/view/fchomo/client.js:1915
-#: htdocs/luci-static/resources/view/fchomo/node.js:1174
+#: htdocs/luci-static/resources/view/fchomo/node.js:1188
msgid "DNS policy"
msgstr ""
@@ -750,8 +750,8 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:907
#: htdocs/luci-static/resources/view/fchomo/client.js:1524
#: htdocs/luci-static/resources/view/fchomo/client.js:1533
-#: htdocs/luci-static/resources/view/fchomo/node.js:1173
-#: htdocs/luci-static/resources/view/fchomo/node.js:1869
+#: htdocs/luci-static/resources/view/fchomo/node.js:1187
+#: htdocs/luci-static/resources/view/fchomo/node.js:1890
msgid "DNS server"
msgstr ""
@@ -768,10 +768,15 @@ msgid "Dashboard version"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:131
-#: htdocs/luci-static/resources/view/fchomo/node.js:825
+#: htdocs/luci-static/resources/view/fchomo/node.js:835
msgid "Debug"
msgstr ""
+#: htdocs/luci-static/resources/fchomo/listeners.js:412
+#: htdocs/luci-static/resources/view/fchomo/node.js:533
+msgid "Default"
+msgstr ""
+
#: htdocs/luci-static/resources/view/fchomo/client.js:58
msgid "Default DNS (issued by WAN)"
msgstr ""
@@ -786,7 +791,7 @@ msgstr ""
msgid "Default selected"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:562
+#: htdocs/luci-static/resources/fchomo/listeners.js:571
msgid "Default version, Support %s."
msgstr ""
@@ -794,15 +799,15 @@ msgstr ""
msgid "Derive from priv-key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:944
+#: htdocs/luci-static/resources/view/fchomo/node.js:954
msgid "Destination addresses allowed to be forwarded via Wireguard."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2732
+#: htdocs/luci-static/resources/view/fchomo/node.js:2753
msgid "Destination provider"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2743
+#: htdocs/luci-static/resources/view/fchomo/node.js:2764
msgid "Destination proxy node"
msgstr ""
@@ -810,8 +815,8 @@ msgstr ""
msgid "Dial fields"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2755
-#: htdocs/luci-static/resources/view/fchomo/node.js:2785
+#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2806
msgid "Different chain head/tail"
msgstr ""
@@ -831,10 +836,10 @@ msgstr ""
msgid "Direct MAC-s"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:500
+#: htdocs/luci-static/resources/fchomo/listeners.js:509
#: htdocs/luci-static/resources/view/fchomo/global.js:424
-#: htdocs/luci-static/resources/view/fchomo/node.js:718
-#: htdocs/luci-static/resources/view/fchomo/node.js:852
+#: htdocs/luci-static/resources/view/fchomo/node.js:728
+#: htdocs/luci-static/resources/view/fchomo/node.js:862
msgid "Disable"
msgstr ""
@@ -850,11 +855,11 @@ msgstr ""
msgid "Disable ICMP Forwarding"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1159
+#: htdocs/luci-static/resources/view/fchomo/node.js:1173
msgid "Disable P2P"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1448
+#: htdocs/luci-static/resources/view/fchomo/node.js:1471
msgid "Disable SNI"
msgstr ""
@@ -881,32 +886,32 @@ msgstr ""
msgid "Domain"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1449
+#: htdocs/luci-static/resources/view/fchomo/node.js:1472
msgid "Donot send server name in ClientHello."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1481
+#: htdocs/luci-static/resources/fchomo.js:1484
#: htdocs/luci-static/resources/view/fchomo/client.js:1676
-#: htdocs/luci-static/resources/view/fchomo/node.js:1520
-#: htdocs/luci-static/resources/view/fchomo/node.js:2566
+#: htdocs/luci-static/resources/view/fchomo/node.js:1543
+#: htdocs/luci-static/resources/view/fchomo/node.js:2587
msgid "Donot verifying server certificate."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1405
-#: htdocs/luci-static/resources/view/fchomo/node.js:2140
+#: htdocs/luci-static/resources/fchomo/listeners.js:1423
+#: htdocs/luci-static/resources/view/fchomo/node.js:2161
msgid "Download bandwidth"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1406
-#: htdocs/luci-static/resources/view/fchomo/node.js:2141
+#: htdocs/luci-static/resources/fchomo/listeners.js:1424
+#: htdocs/luci-static/resources/view/fchomo/node.js:2162
msgid "Download bandwidth in Mbps."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1518
+#: htdocs/luci-static/resources/fchomo.js:1521
msgid "Download failed: %s"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1514
+#: htdocs/luci-static/resources/fchomo.js:1517
msgid "Download successful."
msgstr ""
@@ -918,16 +923,16 @@ msgstr ""
msgid "Dual stack"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1567
+#: htdocs/luci-static/resources/view/fchomo/node.js:1590
msgid "ECH HTTPS record query servername"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1226
-#: htdocs/luci-static/resources/view/fchomo/node.js:1561
+#: htdocs/luci-static/resources/fchomo/listeners.js:1244
+#: htdocs/luci-static/resources/view/fchomo/node.js:1584
msgid "ECH config"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1185
+#: htdocs/luci-static/resources/fchomo/listeners.js:1203
msgid "ECH key"
msgstr ""
@@ -943,11 +948,11 @@ msgstr ""
msgid "ETag support"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1980
+#: htdocs/luci-static/resources/view/fchomo/node.js:2001
msgid "Early Data first packet length limit."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1986
+#: htdocs/luci-static/resources/view/fchomo/node.js:2007
msgid "Early Data header name"
msgstr ""
@@ -967,7 +972,7 @@ msgstr ""
msgid "Edit ruleset"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2350
+#: htdocs/luci-static/resources/view/fchomo/node.js:2371
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:356
msgid "Editer"
msgstr ""
@@ -991,22 +996,22 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/global.js:422
#: htdocs/luci-static/resources/view/fchomo/global.js:712
#: htdocs/luci-static/resources/view/fchomo/node.js:267
-#: htdocs/luci-static/resources/view/fchomo/node.js:2323
-#: htdocs/luci-static/resources/view/fchomo/node.js:2605
-#: htdocs/luci-static/resources/view/fchomo/node.js:2719
+#: htdocs/luci-static/resources/view/fchomo/node.js:2344
+#: htdocs/luci-static/resources/view/fchomo/node.js:2626
+#: htdocs/luci-static/resources/view/fchomo/node.js:2740
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:283
#: htdocs/luci-static/resources/view/fchomo/server.js:49
msgid "Enable"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:672
+#: htdocs/luci-static/resources/view/fchomo/node.js:682
msgid ""
"Enable 0-RTT QUIC connection handshake on the client side. This is not "
"impacting much on the performance, as the protocol is fully multiplexed.
Disabling this is highly recommended, as it is vulnerable to replay attacks."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:671
+#: htdocs/luci-static/resources/view/fchomo/node.js:681
msgid "Enable 0-RTT handshake"
msgstr ""
@@ -1016,33 +1021,33 @@ msgid ""
"conversion for outbound connections"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1555
+#: htdocs/luci-static/resources/view/fchomo/node.js:1578
msgid "Enable ECH"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1165
+#: htdocs/luci-static/resources/view/fchomo/node.js:1179
msgid "Enable MagicDNS"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1393
-#: htdocs/luci-static/resources/view/fchomo/node.js:2128
+#: htdocs/luci-static/resources/fchomo/listeners.js:1411
+#: htdocs/luci-static/resources/view/fchomo/node.js:2149
msgid "Enable TCP Brutal"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1394
-#: htdocs/luci-static/resources/view/fchomo/node.js:2129
+#: htdocs/luci-static/resources/fchomo/listeners.js:1412
+#: htdocs/luci-static/resources/view/fchomo/node.js:2150
msgid "Enable TCP Brutal congestion control algorithm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1130
+#: htdocs/luci-static/resources/view/fchomo/node.js:1144
msgid "Enable encryption"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:666
+#: htdocs/luci-static/resources/view/fchomo/node.js:676
msgid "Enable fast open"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2117
+#: htdocs/luci-static/resources/view/fchomo/node.js:2138
msgid "Enable multiplexing only for TCP."
msgstr ""
@@ -1051,37 +1056,37 @@ msgstr ""
msgid "Enable obfuscate for downlink"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1388
-#: htdocs/luci-static/resources/view/fchomo/node.js:2111
+#: htdocs/luci-static/resources/fchomo/listeners.js:1406
+#: htdocs/luci-static/resources/view/fchomo/node.js:2132
msgid "Enable padding"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2122
+#: htdocs/luci-static/resources/view/fchomo/node.js:2143
msgid "Enable statistic"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1257
-#: htdocs/luci-static/resources/view/fchomo/node.js:2542
+#: htdocs/luci-static/resources/view/fchomo/node.js:1271
+#: htdocs/luci-static/resources/view/fchomo/node.js:2563
msgid ""
"Enable the SUoT protocol, requires server support. Conflict with Multiplex."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:507
-#: htdocs/luci-static/resources/view/fchomo/node.js:725
+#: htdocs/luci-static/resources/fchomo/listeners.js:516
+#: htdocs/luci-static/resources/view/fchomo/node.js:735
msgid ""
"Enabling obfuscation will make the server incompatible with standard QUIC "
"connections, losing the ability to masquerade with HTTP/3."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:843
+#: htdocs/luci-static/resources/view/fchomo/node.js:853
msgid "Encrypted Hello"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1135
+#: htdocs/luci-static/resources/view/fchomo/node.js:1149
msgid "Encryption algorithm"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:832
+#: htdocs/luci-static/resources/fchomo/listeners.js:850
msgid "Encryption method"
msgstr ""
@@ -1104,7 +1109,7 @@ msgid ""
"if empty."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2663
+#: htdocs/luci-static/resources/view/fchomo/node.js:2684
msgid "Exclude matched node types."
msgstr ""
@@ -1115,15 +1120,15 @@ msgid ""
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1251
-#: htdocs/luci-static/resources/view/fchomo/node.js:2656
+#: htdocs/luci-static/resources/view/fchomo/node.js:2677
msgid "Exclude nodes that meet keywords or regexps."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:989
+#: htdocs/luci-static/resources/view/fchomo/node.js:999
msgid "Exit node"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1115
+#: htdocs/luci-static/resources/view/fchomo/node.js:1129
msgid "Exit nodes"
msgstr ""
@@ -1132,46 +1137,46 @@ msgid "Expand/Collapse result"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1194
-#: htdocs/luci-static/resources/view/fchomo/node.js:2641
+#: htdocs/luci-static/resources/view/fchomo/node.js:2662
msgid "Expected HTTP code. 204 will be used if empty."
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1196
-#: htdocs/luci-static/resources/view/fchomo/node.js:2643
+#: htdocs/luci-static/resources/view/fchomo/node.js:2664
msgid "Expected status"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:529
#: htdocs/luci-static/resources/fchomo.js:532
#: htdocs/luci-static/resources/fchomo.js:535
-#: htdocs/luci-static/resources/fchomo.js:1678
-#: htdocs/luci-static/resources/fchomo.js:1686
-#: htdocs/luci-static/resources/fchomo.js:1694
-#: htdocs/luci-static/resources/fchomo.js:1717
-#: htdocs/luci-static/resources/fchomo.js:1720
-#: htdocs/luci-static/resources/fchomo.js:1727
-#: htdocs/luci-static/resources/fchomo.js:1743
-#: htdocs/luci-static/resources/fchomo.js:1752
-#: htdocs/luci-static/resources/fchomo.js:1764
-#: htdocs/luci-static/resources/fchomo.js:1767
-#: htdocs/luci-static/resources/fchomo.js:1777
-#: htdocs/luci-static/resources/fchomo.js:1789
-#: htdocs/luci-static/resources/fchomo.js:1792
-#: htdocs/luci-static/resources/fchomo.js:1805
-#: htdocs/luci-static/resources/fchomo.js:1814
-#: htdocs/luci-static/resources/fchomo.js:1823
-#: htdocs/luci-static/resources/fchomo.js:1832
-#: htdocs/luci-static/resources/fchomo.js:1867
+#: htdocs/luci-static/resources/fchomo.js:1680
+#: htdocs/luci-static/resources/fchomo.js:1688
+#: htdocs/luci-static/resources/fchomo.js:1696
+#: htdocs/luci-static/resources/fchomo.js:1719
+#: htdocs/luci-static/resources/fchomo.js:1722
+#: htdocs/luci-static/resources/fchomo.js:1729
+#: htdocs/luci-static/resources/fchomo.js:1745
+#: htdocs/luci-static/resources/fchomo.js:1754
+#: htdocs/luci-static/resources/fchomo.js:1766
+#: htdocs/luci-static/resources/fchomo.js:1769
+#: htdocs/luci-static/resources/fchomo.js:1779
+#: htdocs/luci-static/resources/fchomo.js:1791
+#: htdocs/luci-static/resources/fchomo.js:1794
+#: htdocs/luci-static/resources/fchomo.js:1807
+#: htdocs/luci-static/resources/fchomo.js:1816
+#: htdocs/luci-static/resources/fchomo.js:1825
+#: htdocs/luci-static/resources/fchomo.js:1834
#: htdocs/luci-static/resources/fchomo.js:1869
-#: htdocs/luci-static/resources/fchomo.js:1882
-#: htdocs/luci-static/resources/fchomo.js:1888
-#: htdocs/luci-static/resources/fchomo.js:1895
-#: htdocs/luci-static/resources/fchomo.js:1904
+#: htdocs/luci-static/resources/fchomo.js:1871
+#: htdocs/luci-static/resources/fchomo.js:1884
+#: htdocs/luci-static/resources/fchomo.js:1890
+#: htdocs/luci-static/resources/fchomo.js:1897
+#: htdocs/luci-static/resources/fchomo.js:1906
#: htdocs/luci-static/resources/fchomo/listeners.js:291
#: htdocs/luci-static/resources/fchomo/listeners.js:346
-#: htdocs/luci-static/resources/fchomo/listeners.js:861
-#: htdocs/luci-static/resources/fchomo/listeners.js:892
-#: htdocs/luci-static/resources/fchomo/listeners.js:993
+#: htdocs/luci-static/resources/fchomo/listeners.js:879
+#: htdocs/luci-static/resources/fchomo/listeners.js:910
+#: htdocs/luci-static/resources/fchomo/listeners.js:1011
#: htdocs/luci-static/resources/view/fchomo/client.js:71
#: htdocs/luci-static/resources/view/fchomo/client.js:1059
#: htdocs/luci-static/resources/view/fchomo/client.js:1604
@@ -1180,25 +1185,25 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/node.js:444
#: htdocs/luci-static/resources/view/fchomo/node.js:497
#: htdocs/luci-static/resources/view/fchomo/node.js:499
-#: htdocs/luci-static/resources/view/fchomo/node.js:900
-#: htdocs/luci-static/resources/view/fchomo/node.js:1415
-#: htdocs/luci-static/resources/view/fchomo/node.js:2755
-#: htdocs/luci-static/resources/view/fchomo/node.js:2785
+#: htdocs/luci-static/resources/view/fchomo/node.js:910
+#: htdocs/luci-static/resources/view/fchomo/node.js:1438
+#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2806
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:311
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:325
msgid "Expecting: %s"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1129
+#: htdocs/luci-static/resources/fchomo/listeners.js:1147
msgid "Expecting: Cannot be empty."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1240
-#: htdocs/luci-static/resources/view/fchomo/node.js:1589
+#: htdocs/luci-static/resources/fchomo/listeners.js:1258
+#: htdocs/luci-static/resources/view/fchomo/node.js:1612
msgid "Expecting: Cannot be enabled when %s is enabled."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1124
+#: htdocs/luci-static/resources/fchomo/listeners.js:1142
msgid "Expecting: Keep empty when %s is enabled."
msgstr ""
@@ -1207,15 +1212,15 @@ msgstr ""
msgid "Expecting: Least one of %s or %s."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:699
-#: htdocs/luci-static/resources/fchomo/listeners.js:705
-#: htdocs/luci-static/resources/fchomo/listeners.js:1314
-#: htdocs/luci-static/resources/fchomo/listeners.js:1321
-#: htdocs/luci-static/resources/view/fchomo/node.js:1289
-#: htdocs/luci-static/resources/view/fchomo/node.js:1295
-#: htdocs/luci-static/resources/view/fchomo/node.js:1895
-#: htdocs/luci-static/resources/view/fchomo/node.js:1902
-#: htdocs/luci-static/resources/view/fchomo/node.js:1910
+#: htdocs/luci-static/resources/fchomo/listeners.js:716
+#: htdocs/luci-static/resources/fchomo/listeners.js:723
+#: htdocs/luci-static/resources/fchomo/listeners.js:1332
+#: htdocs/luci-static/resources/fchomo/listeners.js:1339
+#: htdocs/luci-static/resources/view/fchomo/node.js:1311
+#: htdocs/luci-static/resources/view/fchomo/node.js:1318
+#: htdocs/luci-static/resources/view/fchomo/node.js:1916
+#: htdocs/luci-static/resources/view/fchomo/node.js:1923
+#: htdocs/luci-static/resources/view/fchomo/node.js:1931
msgid "Expecting: Only support %s."
msgstr ""
@@ -1235,19 +1240,19 @@ msgstr ""
msgid "Factor"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1619
+#: htdocs/luci-static/resources/fchomo.js:1621
msgid "Failed to execute \"/etc/init.d/fchomo %s %s\" reason: %s"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1572
+#: htdocs/luci-static/resources/fchomo.js:1574
msgid "Failed to generate %s, error: %s."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:2004
+#: htdocs/luci-static/resources/fchomo.js:2006
msgid "Failed to upload %s, error: %s."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:2023
+#: htdocs/luci-static/resources/fchomo.js:2025
msgid "Failed to upload, error: %s."
msgstr ""
@@ -1267,16 +1272,16 @@ msgstr ""
msgid "Fallback filter"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:849
+#: htdocs/luci-static/resources/view/fchomo/node.js:859
msgid "Fallback mode"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:856
+#: htdocs/luci-static/resources/view/fchomo/node.js:866
msgid "Fallback relay"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1246
-#: htdocs/luci-static/resources/view/fchomo/node.js:2650
+#: htdocs/luci-static/resources/view/fchomo/node.js:2671
msgid "Filter nodes that meet keywords or regexps."
msgstr ""
@@ -1302,12 +1307,12 @@ msgid "Final DNS server (For poisoned domains)"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:138
-#: htdocs/luci-static/resources/view/fchomo/node.js:1617
+#: htdocs/luci-static/resources/view/fchomo/node.js:1640
msgid "Firewall"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:416
-#: htdocs/luci-static/resources/view/fchomo/node.js:536
+#: htdocs/luci-static/resources/fchomo/listeners.js:425
+#: htdocs/luci-static/resources/view/fchomo/node.js:546
msgid "Flow"
msgstr ""
@@ -1318,23 +1323,23 @@ msgid ""
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1195
-#: htdocs/luci-static/resources/view/fchomo/node.js:2503
-#: htdocs/luci-static/resources/view/fchomo/node.js:2511
-#: htdocs/luci-static/resources/view/fchomo/node.js:2642
+#: htdocs/luci-static/resources/view/fchomo/node.js:2524
+#: htdocs/luci-static/resources/view/fchomo/node.js:2532
+#: htdocs/luci-static/resources/view/fchomo/node.js:2663
msgid ""
"For format see %s."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:851
+#: htdocs/luci-static/resources/view/fchomo/node.js:861
msgid "Force"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1864
+#: htdocs/luci-static/resources/view/fchomo/node.js:1885
msgid "Force DNS remote resolution."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1250
+#: htdocs/luci-static/resources/view/fchomo/node.js:1264
msgid "Force UDP"
msgstr ""
@@ -1346,7 +1351,7 @@ msgstr ""
msgid "Format"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:785
+#: htdocs/luci-static/resources/fchomo/listeners.js:803
msgid "Forwarding rate limit"
msgstr ""
@@ -1357,7 +1362,7 @@ msgstr ""
msgid "FullCombo Shark!"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1935
+#: htdocs/luci-static/resources/view/fchomo/node.js:1956
msgid "GET"
msgstr ""
@@ -1365,8 +1370,8 @@ msgstr ""
msgid "GFW list version"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:502
-#: htdocs/luci-static/resources/view/fchomo/node.js:720
+#: htdocs/luci-static/resources/fchomo/listeners.js:511
+#: htdocs/luci-static/resources/view/fchomo/node.js:730
msgid "Gecko"
msgstr ""
@@ -1377,7 +1382,7 @@ msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:119
#: htdocs/luci-static/resources/view/fchomo/client.js:1050
#: htdocs/luci-static/resources/view/fchomo/node.js:252
-#: htdocs/luci-static/resources/view/fchomo/node.js:2313
+#: htdocs/luci-static/resources/view/fchomo/node.js:2334
msgid "General fields"
msgstr ""
@@ -1385,17 +1390,17 @@ msgstr ""
msgid "General settings"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:721
-#: htdocs/luci-static/resources/fchomo.js:723
-#: htdocs/luci-static/resources/fchomo.js:737
+#: htdocs/luci-static/resources/fchomo.js:722
+#: htdocs/luci-static/resources/fchomo.js:724
#: htdocs/luci-static/resources/fchomo.js:739
+#: htdocs/luci-static/resources/fchomo.js:741
#: htdocs/luci-static/resources/fchomo/listeners.js:269
#: htdocs/luci-static/resources/fchomo/listeners.js:313
#: htdocs/luci-static/resources/fchomo/listeners.js:315
-#: htdocs/luci-static/resources/fchomo/listeners.js:965
-#: htdocs/luci-static/resources/fchomo/listeners.js:1218
+#: htdocs/luci-static/resources/fchomo/listeners.js:983
+#: htdocs/luci-static/resources/fchomo/listeners.js:1236
#: htdocs/luci-static/resources/view/fchomo/global.js:616
-#: htdocs/luci-static/resources/view/fchomo/node.js:2471
+#: htdocs/luci-static/resources/view/fchomo/node.js:2492
msgid "Generate"
msgstr ""
@@ -1442,7 +1447,7 @@ msgstr ""
msgid "Global Authentication"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:560
+#: htdocs/luci-static/resources/view/fchomo/node.js:570
msgid "Global padding"
msgstr ""
@@ -1464,17 +1469,17 @@ msgstr ""
#: htdocs/luci-static/resources/fchomo.js:191
#: htdocs/luci-static/resources/fchomo.js:228
-#: htdocs/luci-static/resources/fchomo/listeners.js:717
-#: htdocs/luci-static/resources/view/fchomo/node.js:1307
-#: htdocs/luci-static/resources/view/fchomo/node.js:1882
-#: htdocs/luci-static/resources/view/fchomo/node.js:1895
-#: htdocs/luci-static/resources/view/fchomo/node.js:1902
+#: htdocs/luci-static/resources/fchomo/listeners.js:735
+#: htdocs/luci-static/resources/view/fchomo/node.js:1330
+#: htdocs/luci-static/resources/view/fchomo/node.js:1903
+#: htdocs/luci-static/resources/view/fchomo/node.js:1916
+#: htdocs/luci-static/resources/view/fchomo/node.js:1923
msgid "HTTP"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/node.js:333
-#: htdocs/luci-static/resources/view/fchomo/node.js:1957
-#: htdocs/luci-static/resources/view/fchomo/node.js:2483
+#: htdocs/luci-static/resources/view/fchomo/node.js:1978
+#: htdocs/luci-static/resources/view/fchomo/node.js:2504
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:430
msgid "HTTP header"
msgstr ""
@@ -1500,7 +1505,7 @@ msgstr ""
msgid "HTTP mask: %s"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1934
+#: htdocs/luci-static/resources/view/fchomo/node.js:1955
msgid "HTTP request method"
msgstr ""
@@ -1513,15 +1518,15 @@ msgstr ""
msgid "HTTP/3"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:525
+#: htdocs/luci-static/resources/fchomo/listeners.js:534
msgid ""
"HTTP3 server behavior when authentication fails.
A 404 page will be "
"returned if empty."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1883
-#: htdocs/luci-static/resources/view/fchomo/node.js:1896
-#: htdocs/luci-static/resources/view/fchomo/node.js:1903
+#: htdocs/luci-static/resources/view/fchomo/node.js:1904
+#: htdocs/luci-static/resources/view/fchomo/node.js:1917
+#: htdocs/luci-static/resources/view/fchomo/node.js:1924
msgid "HTTPUpgrade"
msgstr ""
@@ -1533,58 +1538,58 @@ msgstr ""
msgid "Handshake mode"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:767
+#: htdocs/luci-static/resources/fchomo/listeners.js:785
msgid "Handshake target proxy"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:722
+#: htdocs/luci-static/resources/fchomo/listeners.js:740
msgid "Handshake target that supports TLS 1.3"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:353
-#: htdocs/luci-static/resources/view/fchomo/node.js:1242
+#: htdocs/luci-static/resources/view/fchomo/node.js:1256
msgid "Handshake timeout"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:550
+#: htdocs/luci-static/resources/fchomo/listeners.js:559
msgid "Header to read real client IP from (e.g. X-Forwarded-For)"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:968
+#: htdocs/luci-static/resources/view/fchomo/node.js:978
msgid "Headscale/Tailscale"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:796
+#: htdocs/luci-static/resources/view/fchomo/node.js:806
msgid "Health check"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1164
-#: htdocs/luci-static/resources/view/fchomo/node.js:2610
+#: htdocs/luci-static/resources/view/fchomo/node.js:2631
msgid "Health check URL"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1193
-#: htdocs/luci-static/resources/view/fchomo/node.js:2640
+#: htdocs/luci-static/resources/view/fchomo/node.js:2661
msgid "Health check expected status"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1173
-#: htdocs/luci-static/resources/view/fchomo/node.js:2620
+#: htdocs/luci-static/resources/view/fchomo/node.js:2641
msgid "Health check interval"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1180
-#: htdocs/luci-static/resources/view/fchomo/node.js:2627
+#: htdocs/luci-static/resources/view/fchomo/node.js:2648
msgid "Health check timeout"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1052
-#: htdocs/luci-static/resources/view/fchomo/node.js:2315
+#: htdocs/luci-static/resources/view/fchomo/node.js:2336
msgid "Health fields"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:678
-#: htdocs/luci-static/resources/view/fchomo/node.js:759
+#: htdocs/luci-static/resources/view/fchomo/node.js:688
+#: htdocs/luci-static/resources/view/fchomo/node.js:769
msgid "Heartbeat interval"
msgstr ""
@@ -1592,16 +1597,16 @@ msgstr ""
msgid "Hidden"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:730
-#: htdocs/luci-static/resources/view/fchomo/node.js:1312
+#: htdocs/luci-static/resources/fchomo/listeners.js:748
+#: htdocs/luci-static/resources/view/fchomo/node.js:1335
msgid "Host that supports TLS 1.3"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1194
+#: htdocs/luci-static/resources/view/fchomo/node.js:1208
msgid "Host-key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1189
+#: htdocs/luci-static/resources/view/fchomo/node.js:1203
msgid "Host-key algorithms"
msgstr ""
@@ -1609,12 +1614,12 @@ msgstr ""
msgid "Host/SNI override"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1063
+#: htdocs/luci-static/resources/view/fchomo/node.js:1073
msgid "Hostname"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1458
-#: htdocs/luci-static/resources/view/fchomo/node.js:1455
+#: htdocs/luci-static/resources/fchomo.js:1461
+#: htdocs/luci-static/resources/view/fchomo/node.js:1478
msgid ""
"Hostname that the client attempts to connect to at the start of the TLS "
"handshake process."
@@ -1648,24 +1653,24 @@ msgstr ""
msgid "IP CIDR"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:635
+#: htdocs/luci-static/resources/view/fchomo/node.js:645
msgid "IP override"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1200
-#: htdocs/luci-static/resources/view/fchomo/node.js:1210
+#: htdocs/luci-static/resources/view/fchomo/node.js:1214
+#: htdocs/luci-static/resources/view/fchomo/node.js:1224
msgid "IP stack"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2177
-#: htdocs/luci-static/resources/view/fchomo/node.js:2596
+#: htdocs/luci-static/resources/view/fchomo/node.js:2198
+#: htdocs/luci-static/resources/view/fchomo/node.js:2617
msgid "IP version"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1767
-#: htdocs/luci-static/resources/view/fchomo/node.js:1771
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1788
+#: htdocs/luci-static/resources/view/fchomo/node.js:1792
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
msgid "IPv4"
msgstr ""
@@ -1673,9 +1678,9 @@ msgstr ""
msgid "IPv4 only"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
-#: htdocs/luci-static/resources/view/fchomo/node.js:1799
-#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
+#: htdocs/luci-static/resources/view/fchomo/node.js:1820
+#: htdocs/luci-static/resources/view/fchomo/node.js:1824
msgid "IPv6"
msgstr ""
@@ -1692,19 +1697,19 @@ msgstr ""
msgid "Icon"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:608
+#: htdocs/luci-static/resources/view/fchomo/node.js:618
msgid "Idle session check interval"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:615
+#: htdocs/luci-static/resources/view/fchomo/node.js:625
msgid "Idle session timeout"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:662
+#: htdocs/luci-static/resources/fchomo/listeners.js:671
msgid "Idle timeout"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1720
+#: htdocs/luci-static/resources/fchomo.js:1722
msgid "If All ports is selected, uncheck others"
msgstr ""
@@ -1712,17 +1717,17 @@ msgstr ""
msgid "If Block is selected, uncheck others"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:492
+#: htdocs/luci-static/resources/fchomo/listeners.js:501
msgid "Ignore client bandwidth"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1154
+#: htdocs/luci-static/resources/view/fchomo/node.js:1168
msgid ""
"Ignore the number of intermediate hops and select the path with the lowest "
"total latency."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:906
+#: htdocs/luci-static/resources/fchomo.js:909
msgid "Import"
msgstr ""
@@ -1738,8 +1743,8 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1812
#: htdocs/luci-static/resources/view/fchomo/client.js:1847
#: htdocs/luci-static/resources/view/fchomo/client.js:1868
-#: htdocs/luci-static/resources/view/fchomo/node.js:2203
-#: htdocs/luci-static/resources/view/fchomo/node.js:2301
+#: htdocs/luci-static/resources/view/fchomo/node.js:2224
+#: htdocs/luci-static/resources/view/fchomo/node.js:2322
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:164
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:260
msgid "Import mihomo config"
@@ -1751,48 +1756,48 @@ msgstr ""
msgid "Import rule-set links"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:481
-#: htdocs/luci-static/resources/fchomo/listeners.js:487
-#: htdocs/luci-static/resources/view/fchomo/node.js:694
-#: htdocs/luci-static/resources/view/fchomo/node.js:700
-#: htdocs/luci-static/resources/view/fchomo/node.js:2548
-#: htdocs/luci-static/resources/view/fchomo/node.js:2554
+#: htdocs/luci-static/resources/fchomo/listeners.js:490
+#: htdocs/luci-static/resources/fchomo/listeners.js:496
+#: htdocs/luci-static/resources/view/fchomo/node.js:704
+#: htdocs/luci-static/resources/view/fchomo/node.js:710
+#: htdocs/luci-static/resources/view/fchomo/node.js:2569
+#: htdocs/luci-static/resources/view/fchomo/node.js:2575
msgid "In Mbps."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:786
+#: htdocs/luci-static/resources/fchomo/listeners.js:804
msgid "In bps. 0 means no speed limit."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2391
+#: htdocs/luci-static/resources/view/fchomo/node.js:2412
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:403
msgid "In bytes. %s will be used if empty."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1289
-#: htdocs/luci-static/resources/view/fchomo/node.js:679
-#: htdocs/luci-static/resources/view/fchomo/node.js:686
-#: htdocs/luci-static/resources/view/fchomo/node.js:760
+#: htdocs/luci-static/resources/fchomo/listeners.js:1307
+#: htdocs/luci-static/resources/view/fchomo/node.js:689
+#: htdocs/luci-static/resources/view/fchomo/node.js:696
+#: htdocs/luci-static/resources/view/fchomo/node.js:770
msgid "In millisecond."
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1181
#: htdocs/luci-static/resources/view/fchomo/client.js:1227
-#: htdocs/luci-static/resources/view/fchomo/node.js:2628
+#: htdocs/luci-static/resources/view/fchomo/node.js:2649
msgid "In millisecond. %s will be used if empty."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2026
+#: htdocs/luci-static/resources/view/fchomo/node.js:2047
msgid "In milliseconds."
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:207
#: htdocs/luci-static/resources/fchomo/listeners.js:354
-#: htdocs/luci-static/resources/fchomo/listeners.js:473
-#: htdocs/luci-static/resources/fchomo/listeners.js:663
-#: htdocs/luci-static/resources/view/fchomo/node.js:609
-#: htdocs/luci-static/resources/view/fchomo/node.js:616
-#: htdocs/luci-static/resources/view/fchomo/node.js:1973
+#: htdocs/luci-static/resources/fchomo/listeners.js:482
+#: htdocs/luci-static/resources/fchomo/listeners.js:672
+#: htdocs/luci-static/resources/view/fchomo/node.js:619
+#: htdocs/luci-static/resources/view/fchomo/node.js:626
+#: htdocs/luci-static/resources/view/fchomo/node.js:1994
msgid "In seconds."
msgstr ""
@@ -1800,21 +1805,21 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/global.js:446
#: htdocs/luci-static/resources/view/fchomo/global.js:451
#: htdocs/luci-static/resources/view/fchomo/global.js:537
-#: htdocs/luci-static/resources/view/fchomo/node.js:712
-#: htdocs/luci-static/resources/view/fchomo/node.js:2397
-#: htdocs/luci-static/resources/view/fchomo/node.js:2621
+#: htdocs/luci-static/resources/view/fchomo/node.js:722
+#: htdocs/luci-static/resources/view/fchomo/node.js:2418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2642
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:409
msgid "In seconds. %s will be used if empty."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1243
+#: htdocs/luci-static/resources/view/fchomo/node.js:1257
msgid ""
"In seconds. After configuration, the handshake is not affected by the outer "
"connection timeout."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:881
-#: htdocs/luci-static/resources/view/fchomo/node.js:1404
+#: htdocs/luci-static/resources/fchomo/listeners.js:899
+#: htdocs/luci-static/resources/view/fchomo/node.js:1427
msgid ""
"In the order of one Padding-Length and one Padding-"
"Interval, infinite concatenation."
@@ -1855,17 +1860,17 @@ msgstr ""
msgid "Info"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:572
-#: htdocs/luci-static/resources/view/fchomo/node.js:766
+#: htdocs/luci-static/resources/fchomo/listeners.js:581
+#: htdocs/luci-static/resources/view/fchomo/node.js:776
msgid "Initial congestion window size"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2330
+#: htdocs/luci-static/resources/view/fchomo/node.js:2351
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:299
msgid "Inline"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:826
+#: htdocs/luci-static/resources/view/fchomo/node.js:836
msgid "Insane"
msgstr ""
@@ -1873,19 +1878,19 @@ msgstr ""
msgid "Interface Control"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:692
-#: htdocs/luci-static/resources/fchomo/listeners.js:702
-#: htdocs/luci-static/resources/fchomo/listeners.js:707
-#: htdocs/luci-static/resources/fchomo/listeners.js:1126
-#: htdocs/luci-static/resources/fchomo/listeners.js:1242
-#: htdocs/luci-static/resources/view/fchomo/node.js:1282
-#: htdocs/luci-static/resources/view/fchomo/node.js:1292
-#: htdocs/luci-static/resources/view/fchomo/node.js:1297
-#: htdocs/luci-static/resources/view/fchomo/node.js:1591
+#: htdocs/luci-static/resources/fchomo/listeners.js:701
+#: htdocs/luci-static/resources/fchomo/listeners.js:720
+#: htdocs/luci-static/resources/fchomo/listeners.js:725
+#: htdocs/luci-static/resources/fchomo/listeners.js:1144
+#: htdocs/luci-static/resources/fchomo/listeners.js:1260
+#: htdocs/luci-static/resources/view/fchomo/node.js:1296
+#: htdocs/luci-static/resources/view/fchomo/node.js:1315
+#: htdocs/luci-static/resources/view/fchomo/node.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1614
msgid "JLS"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:893
+#: htdocs/luci-static/resources/view/fchomo/node.js:903
msgid "Join %s. Format: %s"
msgstr ""
@@ -1894,13 +1899,15 @@ msgstr ""
#: htdocs/luci-static/resources/fchomo.js:97
#: htdocs/luci-static/resources/fchomo.js:211
#: htdocs/luci-static/resources/fchomo.js:454
-#: htdocs/luci-static/resources/view/fchomo/node.js:1136
-#: htdocs/luci-static/resources/view/fchomo/node.js:1201
-#: htdocs/luci-static/resources/view/fchomo/node.js:2570
+#: htdocs/luci-static/resources/fchomo/listeners.js:411
+#: htdocs/luci-static/resources/view/fchomo/node.js:532
+#: htdocs/luci-static/resources/view/fchomo/node.js:1150
+#: htdocs/luci-static/resources/view/fchomo/node.js:1215
+#: htdocs/luci-static/resources/view/fchomo/node.js:2591
msgid "Keep default"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2062
+#: htdocs/luci-static/resources/view/fchomo/node.js:2083
msgid "Keep-alive period"
msgstr ""
@@ -1909,13 +1916,13 @@ msgstr ""
msgid "Key"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1494
-#: htdocs/luci-static/resources/fchomo/listeners.js:1145
-#: htdocs/luci-static/resources/view/fchomo/node.js:1541
+#: htdocs/luci-static/resources/fchomo.js:1497
+#: htdocs/luci-static/resources/fchomo/listeners.js:1163
+#: htdocs/luci-static/resources/view/fchomo/node.js:1564
msgid "Key path"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:900
+#: htdocs/luci-static/resources/fchomo/listeners.js:918
msgid "Keypairs"
msgstr ""
@@ -1938,18 +1945,18 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1818
#: htdocs/luci-static/resources/view/fchomo/client.js:1874
#: htdocs/luci-static/resources/view/fchomo/node.js:262
-#: htdocs/luci-static/resources/view/fchomo/node.js:2318
-#: htdocs/luci-static/resources/view/fchomo/node.js:2714
+#: htdocs/luci-static/resources/view/fchomo/node.js:2339
+#: htdocs/luci-static/resources/view/fchomo/node.js:2735
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:278
msgid "Label"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1153
+#: htdocs/luci-static/resources/view/fchomo/node.js:1167
msgid "Latency first"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1187
-#: htdocs/luci-static/resources/view/fchomo/node.js:2634
+#: htdocs/luci-static/resources/view/fchomo/node.js:2655
msgid "Lazy"
msgstr ""
@@ -1966,7 +1973,7 @@ msgstr ""
msgid "Legacy"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:425
+#: htdocs/luci-static/resources/fchomo/listeners.js:434
msgid ""
"Legacy protocol support (VMess MD5 Authentication) is provided for "
"compatibility purposes only, use of alterId > 1 is not recommended."
@@ -1976,19 +1983,19 @@ msgstr ""
msgid "Less compatibility and sometimes better performance."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1116
+#: htdocs/luci-static/resources/view/fchomo/node.js:1130
msgid "List of exit nodes to use (%s of peer nodes)."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1124
+#: htdocs/luci-static/resources/view/fchomo/node.js:1138
msgid ""
"List of local subnets (CIDR) to be open to other peers in the EasyTier "
"network."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1463
-#: htdocs/luci-static/resources/fchomo/listeners.js:1068
-#: htdocs/luci-static/resources/view/fchomo/node.js:1461
+#: htdocs/luci-static/resources/fchomo.js:1466
+#: htdocs/luci-static/resources/fchomo/listeners.js:1086
+#: htdocs/luci-static/resources/view/fchomo/node.js:1484
msgid "List of supported application level protocols, in order of preference."
msgstr ""
@@ -2006,8 +2013,8 @@ msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:154
#: htdocs/luci-static/resources/view/fchomo/client.js:1467
-#: htdocs/luci-static/resources/view/fchomo/node.js:1685
-#: htdocs/luci-static/resources/view/fchomo/node.js:1695
+#: htdocs/luci-static/resources/view/fchomo/node.js:1707
+#: htdocs/luci-static/resources/view/fchomo/node.js:1717
msgid "Listen port"
msgstr ""
@@ -2019,7 +2026,7 @@ msgstr ""
msgid "Listen routing mark (Fwmark)"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1733
+#: htdocs/luci-static/resources/view/fchomo/node.js:1754
msgid "Listeners"
msgstr ""
@@ -2027,7 +2034,7 @@ msgstr ""
msgid "Load balance"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2328
+#: htdocs/luci-static/resources/view/fchomo/node.js:2349
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:297
msgid "Local"
msgstr ""
@@ -2052,7 +2059,7 @@ msgstr ""
msgid "Logical"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:837
+#: htdocs/luci-static/resources/view/fchomo/node.js:847
msgid "Low Bandwidth Mode"
msgstr ""
@@ -2072,7 +2079,7 @@ msgid "Lowercase only"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/global.js:524
-#: htdocs/luci-static/resources/view/fchomo/node.js:1833
+#: htdocs/luci-static/resources/view/fchomo/node.js:1854
msgid "MTU"
msgstr ""
@@ -2080,7 +2087,7 @@ msgstr ""
msgid "Masque"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:524
+#: htdocs/luci-static/resources/fchomo/listeners.js:533
msgid "Masquerade"
msgstr ""
@@ -2112,24 +2119,24 @@ msgstr ""
msgid "Match rule set."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1979
+#: htdocs/luci-static/resources/view/fchomo/node.js:2000
msgid "Max Early Data"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:466
-#: htdocs/luci-static/resources/view/fchomo/node.js:660
+#: htdocs/luci-static/resources/fchomo/listeners.js:475
+#: htdocs/luci-static/resources/view/fchomo/node.js:670
msgid "Max UDP relay packet size"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1365
+#: htdocs/luci-static/resources/fchomo/listeners.js:1383
msgid "Max buffered posts"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2037
+#: htdocs/luci-static/resources/view/fchomo/node.js:2058
msgid "Max concurrency"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2042
+#: htdocs/luci-static/resources/view/fchomo/node.js:2063
msgid "Max connections"
msgstr ""
@@ -2137,56 +2144,56 @@ msgstr ""
msgid "Max count of failures"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:578
-#: htdocs/luci-static/resources/view/fchomo/node.js:772
+#: htdocs/luci-static/resources/fchomo/listeners.js:587
+#: htdocs/luci-static/resources/view/fchomo/node.js:782
msgid "Max datagram frame size"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:486
-#: htdocs/luci-static/resources/view/fchomo/node.js:699
+#: htdocs/luci-static/resources/fchomo/listeners.js:495
+#: htdocs/luci-static/resources/view/fchomo/node.js:709
msgid "Max download speed"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1376
-#: htdocs/luci-static/resources/view/fchomo/node.js:2019
+#: htdocs/luci-static/resources/fchomo/listeners.js:1394
+#: htdocs/luci-static/resources/view/fchomo/node.js:2040
msgid "Max each POST bytes"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1236
+#: htdocs/luci-static/resources/view/fchomo/node.js:1250
msgid "Max open streams"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:537
+#: htdocs/luci-static/resources/fchomo/listeners.js:546
msgid "Max realms"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:543
+#: htdocs/luci-static/resources/fchomo/listeners.js:552
msgid "Max realms per client IP"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2052
+#: htdocs/luci-static/resources/view/fchomo/node.js:2073
msgid "Max request times"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2057
+#: htdocs/luci-static/resources/view/fchomo/node.js:2078
msgid "Max reusable seconds"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2047
+#: htdocs/luci-static/resources/view/fchomo/node.js:2068
msgid "Max reuse times"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:480
-#: htdocs/luci-static/resources/view/fchomo/node.js:693
+#: htdocs/luci-static/resources/fchomo/listeners.js:489
+#: htdocs/luci-static/resources/view/fchomo/node.js:703
msgid "Max upload speed"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2083
-#: htdocs/luci-static/resources/view/fchomo/node.js:2103
+#: htdocs/luci-static/resources/view/fchomo/node.js:2104
+#: htdocs/luci-static/resources/view/fchomo/node.js:2124
msgid "Maximum connections"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2101
+#: htdocs/luci-static/resources/view/fchomo/node.js:2122
msgid ""
"Maximum multiplexed streams in a connection before opening a new connection."
"
Conflict with %s and %s."
@@ -2204,7 +2211,7 @@ msgid ""
"rate."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2100
+#: htdocs/luci-static/resources/view/fchomo/node.js:2121
msgid "Maximum streams"
msgstr ""
@@ -2225,15 +2232,15 @@ msgstr ""
msgid "Mihomo server"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:622
+#: htdocs/luci-static/resources/view/fchomo/node.js:632
msgid "Min of idle sessions to keep"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2025
+#: htdocs/luci-static/resources/view/fchomo/node.js:2046
msgid "Min posts interval"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2092
+#: htdocs/luci-static/resources/view/fchomo/node.js:2113
msgid ""
"Minimum multiplexed streams in a connection before opening a new connection."
msgstr ""
@@ -2243,8 +2250,8 @@ msgstr ""
msgid "Minimum padding rate"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2091
-#: htdocs/luci-static/resources/view/fchomo/node.js:2103
+#: htdocs/luci-static/resources/view/fchomo/node.js:2112
+#: htdocs/luci-static/resources/view/fchomo/node.js:2124
msgid "Minimum streams"
msgstr ""
@@ -2265,8 +2272,8 @@ msgstr ""
msgid "Mixed port"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1383
-#: htdocs/luci-static/resources/view/fchomo/node.js:2069
+#: htdocs/luci-static/resources/fchomo/listeners.js:1401
+#: htdocs/luci-static/resources/view/fchomo/node.js:2090
msgid "Multiplex"
msgstr ""
@@ -2279,12 +2286,16 @@ msgstr ""
msgid "Multiplexing"
msgstr ""
+#: htdocs/luci-static/resources/view/fchomo/node.js:531
+msgid "Must be consistent with the server."
+msgstr ""
+
#: htdocs/luci-static/resources/view/fchomo/client.js:706
#: htdocs/luci-static/resources/view/fchomo/client.js:707
msgid "NETWORK"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1751
+#: htdocs/luci-static/resources/view/fchomo/node.js:1772
msgid "NO Listener"
msgstr ""
@@ -2293,11 +2304,11 @@ msgstr ""
msgid "NOT"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:630
+#: htdocs/luci-static/resources/fchomo/listeners.js:639
msgid "Name of the Proxy group as outbound."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2403
+#: htdocs/luci-static/resources/view/fchomo/node.js:2424
msgid "Name of the Proxy group to download provider."
msgstr ""
@@ -2305,11 +2316,11 @@ msgstr ""
msgid "Name of the Proxy group to download rule set."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:618
+#: htdocs/luci-static/resources/fchomo/listeners.js:627
msgid "Name of the Sub rule used for inbound matching."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:644
+#: htdocs/luci-static/resources/view/fchomo/node.js:654
msgid "Native UDP"
msgstr ""
@@ -2318,15 +2329,15 @@ msgid "Native appearance"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:362
-#: htdocs/luci-static/resources/view/fchomo/node.js:1016
+#: htdocs/luci-static/resources/view/fchomo/node.js:1026
msgid "Network"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:669
+#: htdocs/luci-static/resources/fchomo/listeners.js:678
msgid "Network type"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2572
+#: htdocs/luci-static/resources/view/fchomo/node.js:2593
msgid "No"
msgstr ""
@@ -2334,7 +2345,7 @@ msgstr ""
msgid "No Authentication IP ranges"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1360
+#: htdocs/luci-static/resources/fchomo/listeners.js:1378
msgid "No SSE header"
msgstr ""
@@ -2342,16 +2353,26 @@ msgstr ""
msgid "No add'l params"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2009
+#: htdocs/luci-static/resources/fchomo/listeners.js:414
+#: htdocs/luci-static/resources/view/fchomo/node.js:535
+msgid "No encryption No obfuscation"
+msgstr ""
+
+#: htdocs/luci-static/resources/view/fchomo/node.js:2030
msgid "No gRPC header"
msgstr ""
+#: htdocs/luci-static/resources/fchomo/listeners.js:413
+#: htdocs/luci-static/resources/view/fchomo/node.js:534
+msgid "No obfuscation"
+msgstr ""
+
#: htdocs/luci-static/resources/view/fchomo/client.js:1188
-#: htdocs/luci-static/resources/view/fchomo/node.js:2635
+#: htdocs/luci-static/resources/view/fchomo/node.js:2656
msgid "No testing is performed when this provider node is not in use."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:867
+#: htdocs/luci-static/resources/fchomo.js:870
msgid "No valid %s found."
msgstr ""
@@ -2365,17 +2386,17 @@ msgid "Node"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1250
-#: htdocs/luci-static/resources/view/fchomo/node.js:2655
+#: htdocs/luci-static/resources/view/fchomo/node.js:2676
msgid "Node exclude filter"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1255
-#: htdocs/luci-static/resources/view/fchomo/node.js:2662
+#: htdocs/luci-static/resources/view/fchomo/node.js:2683
msgid "Node exclude type"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1245
-#: htdocs/luci-static/resources/view/fchomo/node.js:2649
+#: htdocs/luci-static/resources/view/fchomo/node.js:2670
msgid "Node filter"
msgstr ""
@@ -2387,7 +2408,7 @@ msgstr ""
msgid "None"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:822
+#: htdocs/luci-static/resources/view/fchomo/node.js:832
msgid "Normal"
msgstr ""
@@ -2395,11 +2416,11 @@ msgstr ""
msgid "Not Installed"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1396
+#: htdocs/luci-static/resources/fchomo.js:1399
msgid "Not Running"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2680
+#: htdocs/luci-static/resources/view/fchomo/node.js:2701
msgid "Note: The subscription of provider %s is includes %s."
msgstr ""
@@ -2411,30 +2432,30 @@ msgstr ""
msgid "ON"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:716
-#: htdocs/luci-static/resources/view/fchomo/node.js:1306
+#: htdocs/luci-static/resources/fchomo/listeners.js:734
+#: htdocs/luci-static/resources/view/fchomo/node.js:1329
msgid "Obfs Mode"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:519
-#: htdocs/luci-static/resources/view/fchomo/node.js:737
+#: htdocs/luci-static/resources/fchomo/listeners.js:528
+#: htdocs/luci-static/resources/view/fchomo/node.js:747
msgid "Obfuscate maximum packet size"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:514
-#: htdocs/luci-static/resources/view/fchomo/node.js:732
+#: htdocs/luci-static/resources/fchomo/listeners.js:523
+#: htdocs/luci-static/resources/view/fchomo/node.js:742
msgid "Obfuscate minimum packet size"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:506
-#: htdocs/luci-static/resources/view/fchomo/node.js:724
+#: htdocs/luci-static/resources/fchomo/listeners.js:515
+#: htdocs/luci-static/resources/view/fchomo/node.js:734
msgid "Obfuscate password"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:298
-#: htdocs/luci-static/resources/fchomo/listeners.js:499
+#: htdocs/luci-static/resources/fchomo/listeners.js:508
#: htdocs/luci-static/resources/view/fchomo/node.js:415
-#: htdocs/luci-static/resources/view/fchomo/node.js:717
+#: htdocs/luci-static/resources/view/fchomo/node.js:727
msgid "Obfuscate type"
msgstr ""
@@ -2449,7 +2470,7 @@ msgstr ""
msgid "One or more numbers in the range 0-63 separated by commas"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1062
+#: htdocs/luci-static/resources/fchomo/listeners.js:1080
msgid "Only applicable when %s are used as a frontend."
msgstr ""
@@ -2458,7 +2479,7 @@ msgstr ""
msgid "Only applies to the %s."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1057
+#: htdocs/luci-static/resources/view/fchomo/node.js:1067
msgid ""
"Only nodes using the same %s and %s as this network are permitted to perform "
"a handshake or relay traffic through this node."
@@ -2468,11 +2489,11 @@ msgstr ""
msgid "Only process traffic from specific interfaces. Leave empty for all."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1734
+#: htdocs/luci-static/resources/view/fchomo/node.js:1755
msgid "Only the address %s is valid."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1390
+#: htdocs/luci-static/resources/fchomo.js:1393
msgid "Open Dashboard"
msgstr ""
@@ -2488,7 +2509,7 @@ msgstr ""
msgid "Other"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2520
+#: htdocs/luci-static/resources/view/fchomo/node.js:2541
msgid "Other configuration items"
msgstr ""
@@ -2496,9 +2517,9 @@ msgstr ""
msgid "Outbound"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1474
-#: htdocs/luci-static/resources/view/fchomo/node.js:1513
-#: htdocs/luci-static/resources/view/fchomo/node.js:2559
+#: htdocs/luci-static/resources/fchomo.js:1477
+#: htdocs/luci-static/resources/view/fchomo/node.js:1536
+#: htdocs/luci-static/resources/view/fchomo/node.js:2580
msgid "Override cert DNSName"
msgstr ""
@@ -2508,11 +2529,11 @@ msgid "Override destination"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1051
-#: htdocs/luci-static/resources/view/fchomo/node.js:2314
+#: htdocs/luci-static/resources/view/fchomo/node.js:2335
msgid "Override fields"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:636
+#: htdocs/luci-static/resources/view/fchomo/node.js:646
msgid "Override the IP address of the server that DNS response."
msgstr ""
@@ -2528,7 +2549,7 @@ msgstr ""
msgid "Override the existing ECS in original request."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1568
+#: htdocs/luci-static/resources/view/fchomo/node.js:1591
msgid "Overrides the domain name used for HTTPS record queries."
msgstr ""
@@ -2536,42 +2557,42 @@ msgstr ""
msgid "Overview"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1936
+#: htdocs/luci-static/resources/view/fchomo/node.js:1957
msgid "POST"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1937
+#: htdocs/luci-static/resources/view/fchomo/node.js:1958
msgid "PUT"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:572
+#: htdocs/luci-static/resources/view/fchomo/node.js:582
msgid "Packet encoding"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2014
+#: htdocs/luci-static/resources/view/fchomo/node.js:2035
msgid "Padding bytes"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:455
+#: htdocs/luci-static/resources/fchomo/listeners.js:464
msgid "Padding scheme"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:879
-#: htdocs/luci-static/resources/view/fchomo/node.js:1402
+#: htdocs/luci-static/resources/fchomo/listeners.js:897
+#: htdocs/luci-static/resources/view/fchomo/node.js:1425
msgid "Paddings"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:167
#: htdocs/luci-static/resources/fchomo/listeners.js:184
-#: htdocs/luci-static/resources/fchomo/listeners.js:745
+#: htdocs/luci-static/resources/fchomo/listeners.js:763
#: htdocs/luci-static/resources/view/fchomo/node.js:327
#: htdocs/luci-static/resources/view/fchomo/node.js:348
-#: htdocs/luci-static/resources/view/fchomo/node.js:1327
+#: htdocs/luci-static/resources/view/fchomo/node.js:1350
msgid "Password"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:596
-#: htdocs/luci-static/resources/view/fchomo/node.js:790
+#: htdocs/luci-static/resources/fchomo/listeners.js:605
+#: htdocs/luci-static/resources/view/fchomo/node.js:800
msgid "Path MTU Discovery"
msgstr ""
@@ -2583,17 +2604,17 @@ msgstr ""
msgid "Path in bundle: %s"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:819
-#: htdocs/luci-static/resources/view/fchomo/node.js:2378
+#: htdocs/luci-static/resources/fchomo/listeners.js:837
+#: htdocs/luci-static/resources/view/fchomo/node.js:2399
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:384
msgid "Payload"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:929
+#: htdocs/luci-static/resources/view/fchomo/node.js:939
msgid "Peer public key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1068
+#: htdocs/luci-static/resources/view/fchomo/node.js:1078
msgid "Peers"
msgstr ""
@@ -2603,15 +2624,15 @@ msgid ""
"it is not needed."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:956
+#: htdocs/luci-static/resources/view/fchomo/node.js:966
msgid "Periodically sends data packets to maintain connection persistence."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:955
+#: htdocs/luci-static/resources/view/fchomo/node.js:965
msgid "Persistent keepalive"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:830
+#: htdocs/luci-static/resources/view/fchomo/node.js:840
msgid "Physical MTU"
msgstr ""
@@ -2632,8 +2653,8 @@ msgid ""
"standards."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2351
-#: htdocs/luci-static/resources/view/fchomo/node.js:2377
+#: htdocs/luci-static/resources/view/fchomo/node.js:2372
+#: htdocs/luci-static/resources/view/fchomo/node.js:2398
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:357
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:383
msgid ""
@@ -2647,13 +2668,13 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1541
#: htdocs/luci-static/resources/view/fchomo/client.js:1796
#: htdocs/luci-static/resources/view/fchomo/client.js:1848
-#: htdocs/luci-static/resources/view/fchomo/node.js:2204
+#: htdocs/luci-static/resources/view/fchomo/node.js:2225
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:165
msgid "Please type %s fields of mihomo config."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:682
-#: htdocs/luci-static/resources/view/fchomo/node.js:1270
+#: htdocs/luci-static/resources/fchomo/listeners.js:691
+#: htdocs/luci-static/resources/view/fchomo/node.js:1284
msgid "Plugin"
msgstr ""
@@ -2662,8 +2683,8 @@ msgstr ""
msgid "Plugin fields"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:688
-#: htdocs/luci-static/resources/view/fchomo/node.js:1276
+#: htdocs/luci-static/resources/fchomo/listeners.js:697
+#: htdocs/luci-static/resources/view/fchomo/node.js:1290
msgid "Plugin type"
msgstr ""
@@ -2672,11 +2693,11 @@ msgstr ""
msgid "Port"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1729
+#: htdocs/luci-static/resources/fchomo.js:1731
msgid "Port %s alrealy exists!"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:711
+#: htdocs/luci-static/resources/view/fchomo/node.js:721
msgid "Port hop interval"
msgstr ""
@@ -2689,18 +2710,18 @@ msgid "Ports"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:154
-#: htdocs/luci-static/resources/view/fchomo/node.js:706
+#: htdocs/luci-static/resources/view/fchomo/node.js:716
msgid "Ports pool"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:392
-#: htdocs/luci-static/resources/fchomo/listeners.js:531
+#: htdocs/luci-static/resources/fchomo/listeners.js:540
#: htdocs/luci-static/resources/view/fchomo/node.js:507
-#: htdocs/luci-static/resources/view/fchomo/node.js:936
+#: htdocs/luci-static/resources/view/fchomo/node.js:946
msgid "Pre-shared key"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1437
+#: htdocs/luci-static/resources/fchomo.js:1440
msgid "Pre-shared key of rendezvous server"
msgstr ""
@@ -2717,34 +2738,34 @@ msgid ""
"Prevent ICMP loopback issues in some cases. Ping will not show real delay."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1685
-#: htdocs/luci-static/resources/view/fchomo/node.js:1686
+#: htdocs/luci-static/resources/view/fchomo/node.js:1707
+#: htdocs/luci-static/resources/view/fchomo/node.js:1708
msgid "Primary"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/global.js:768
#: htdocs/luci-static/resources/view/fchomo/global.js:785
-#: htdocs/luci-static/resources/view/fchomo/node.js:2165
-#: htdocs/luci-static/resources/view/fchomo/node.js:2172
-#: htdocs/luci-static/resources/view/fchomo/node.js:2584
-#: htdocs/luci-static/resources/view/fchomo/node.js:2591
+#: htdocs/luci-static/resources/view/fchomo/node.js:2186
+#: htdocs/luci-static/resources/view/fchomo/node.js:2193
+#: htdocs/luci-static/resources/view/fchomo/node.js:2605
+#: htdocs/luci-static/resources/view/fchomo/node.js:2612
msgid "Priority: Proxy Node > Global."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1180
+#: htdocs/luci-static/resources/view/fchomo/node.js:1194
msgid "Priv-key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1184
+#: htdocs/luci-static/resources/view/fchomo/node.js:1198
msgid "Priv-key passphrase"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:908
-#: htdocs/luci-static/resources/view/fchomo/node.js:1001
+#: htdocs/luci-static/resources/view/fchomo/node.js:918
+#: htdocs/luci-static/resources/view/fchomo/node.js:1011
msgid "Private key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1056
+#: htdocs/luci-static/resources/view/fchomo/node.js:1066
msgid "Private room"
msgstr ""
@@ -2756,33 +2777,33 @@ msgstr ""
msgid "Process matching mode"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2510
+#: htdocs/luci-static/resources/view/fchomo/node.js:2531
msgid "Programmable replacement"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/global.js:716
-#: htdocs/luci-static/resources/view/fchomo/node.js:2075
+#: htdocs/luci-static/resources/view/fchomo/node.js:2096
msgid "Protocol"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:567
+#: htdocs/luci-static/resources/view/fchomo/node.js:577
msgid "Protocol parameter. Enable length block encryption."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:561
+#: htdocs/luci-static/resources/view/fchomo/node.js:571
msgid ""
"Protocol parameter. Will waste traffic randomly if enabled (enabled by "
"default in v2ray and cannot be disabled)."
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1108
-#: htdocs/luci-static/resources/view/fchomo/node.js:2187
-#: htdocs/luci-static/resources/view/fchomo/node.js:2196
-#: htdocs/luci-static/resources/view/fchomo/node.js:2725
+#: htdocs/luci-static/resources/view/fchomo/node.js:2208
+#: htdocs/luci-static/resources/view/fchomo/node.js:2217
+#: htdocs/luci-static/resources/view/fchomo/node.js:2746
msgid "Provider"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2384
+#: htdocs/luci-static/resources/view/fchomo/node.js:2405
msgid "Provider URL"
msgstr ""
@@ -2805,20 +2826,20 @@ msgid "Proxy MAC-s"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/node.js:225
-#: htdocs/luci-static/resources/view/fchomo/node.js:2724
+#: htdocs/luci-static/resources/view/fchomo/node.js:2745
msgid "Proxy Node"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2700
-#: htdocs/luci-static/resources/view/fchomo/node.js:2709
+#: htdocs/luci-static/resources/view/fchomo/node.js:2721
+#: htdocs/luci-static/resources/view/fchomo/node.js:2730
msgid "Proxy chain"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:629
-#: htdocs/luci-static/resources/fchomo/listeners.js:1009
+#: htdocs/luci-static/resources/fchomo/listeners.js:638
+#: htdocs/luci-static/resources/fchomo/listeners.js:1027
#: htdocs/luci-static/resources/view/fchomo/client.js:809
#: htdocs/luci-static/resources/view/fchomo/client.js:1639
-#: htdocs/luci-static/resources/view/fchomo/node.js:2402
+#: htdocs/luci-static/resources/view/fchomo/node.js:2423
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:414
msgid "Proxy group"
msgstr ""
@@ -2835,22 +2856,22 @@ msgstr ""
msgid "Proxy routerself"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:925
+#: htdocs/luci-static/resources/view/fchomo/node.js:935
msgid "Public key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:645
-#: htdocs/luci-static/resources/view/fchomo/node.js:801
+#: htdocs/luci-static/resources/view/fchomo/node.js:655
+#: htdocs/luci-static/resources/view/fchomo/node.js:811
msgid "QUIC"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:567
-#: htdocs/luci-static/resources/view/fchomo/node.js:754
+#: htdocs/luci-static/resources/fchomo/listeners.js:576
+#: htdocs/luci-static/resources/view/fchomo/node.js:764
msgid "QUIC based 0-RTT"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:561
-#: htdocs/luci-static/resources/view/fchomo/node.js:743
+#: htdocs/luci-static/resources/fchomo/listeners.js:570
+#: htdocs/luci-static/resources/view/fchomo/node.js:753
msgid "QUIC versions"
msgstr ""
@@ -2859,39 +2880,39 @@ msgstr ""
msgid "Quick Reload"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1127
-#: htdocs/luci-static/resources/fchomo/listeners.js:1233
-#: htdocs/luci-static/resources/view/fchomo/node.js:1582
+#: htdocs/luci-static/resources/fchomo/listeners.js:1145
+#: htdocs/luci-static/resources/fchomo/listeners.js:1251
+#: htdocs/luci-static/resources/view/fchomo/node.js:1605
msgid "REALITY"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1608
+#: htdocs/luci-static/resources/view/fchomo/node.js:1631
msgid "REALITY X25519MLKEM768 PQC support"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1281
+#: htdocs/luci-static/resources/fchomo/listeners.js:1299
msgid "REALITY certificate issued to"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1249
+#: htdocs/luci-static/resources/fchomo/listeners.js:1267
msgid "REALITY handshake server"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1288
+#: htdocs/luci-static/resources/fchomo/listeners.js:1306
msgid "REALITY max time difference"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1256
+#: htdocs/luci-static/resources/fchomo/listeners.js:1274
msgid "REALITY private key"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1271
-#: htdocs/luci-static/resources/view/fchomo/node.js:1598
+#: htdocs/luci-static/resources/fchomo/listeners.js:1289
+#: htdocs/luci-static/resources/view/fchomo/node.js:1621
msgid "REALITY public key"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1275
-#: htdocs/luci-static/resources/view/fchomo/node.js:1603
+#: htdocs/luci-static/resources/fchomo/listeners.js:1293
+#: htdocs/luci-static/resources/view/fchomo/node.js:1626
msgid "REALITY short ID"
msgstr ""
@@ -2905,9 +2926,9 @@ msgstr ""
msgid "REMATCH-NAME marking"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:850
-#: htdocs/luci-static/resources/fchomo/listeners.js:869
-#: htdocs/luci-static/resources/view/fchomo/node.js:1392
+#: htdocs/luci-static/resources/fchomo/listeners.js:868
+#: htdocs/luci-static/resources/fchomo/listeners.js:887
+#: htdocs/luci-static/resources/view/fchomo/node.js:1415
msgid "RTT"
msgstr ""
@@ -2927,19 +2948,19 @@ msgstr ""
msgid "Randomized traffic characteristics"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1426
+#: htdocs/luci-static/resources/fchomo.js:1429
msgid "Realm"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1442
+#: htdocs/luci-static/resources/fchomo.js:1445
msgid "Realm ID"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:554
+#: htdocs/luci-static/resources/fchomo/listeners.js:563
msgid "Realm name pattern"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2681
+#: htdocs/luci-static/resources/view/fchomo/node.js:2702
msgid ""
"Recommended to adjust Client DNS configuration based on actual conditions."
msgstr ""
@@ -2960,7 +2981,7 @@ msgstr ""
msgid "Redirect TCP + Tun UDP"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:838
+#: htdocs/luci-static/resources/view/fchomo/node.js:848
msgid "Reduces background traffic and network configuration refresh frequency."
msgstr ""
@@ -2968,7 +2989,7 @@ msgstr ""
msgid "Refresh every %s seconds."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1383
+#: htdocs/luci-static/resources/fchomo.js:1386
#: htdocs/luci-static/resources/view/fchomo/client.js:966
#: htdocs/luci-static/resources/view/fchomo/global.js:193
#: htdocs/luci-static/resources/view/fchomo/server.js:45
@@ -2987,46 +3008,46 @@ msgstr ""
msgid "Rematching routing rules"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2329
+#: htdocs/luci-static/resources/view/fchomo/node.js:2350
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:298
msgid "Remote"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1863
+#: htdocs/luci-static/resources/view/fchomo/node.js:1884
msgid "Remote DNS resolve"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:821
+#: htdocs/luci-static/resources/view/fchomo/node.js:831
msgid "Remote trace level"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:814
+#: htdocs/luci-static/resources/view/fchomo/node.js:824
msgid "Remote trace target"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1650
+#: htdocs/luci-static/resources/fchomo.js:1652
msgid "Remove"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1655
+#: htdocs/luci-static/resources/fchomo.js:1657
#: htdocs/luci-static/resources/view/fchomo/node.js:244
#: htdocs/luci-static/resources/view/fchomo/node.js:246
-#: htdocs/luci-static/resources/view/fchomo/node.js:2305
-#: htdocs/luci-static/resources/view/fchomo/node.js:2307
+#: htdocs/luci-static/resources/view/fchomo/node.js:2326
+#: htdocs/luci-static/resources/view/fchomo/node.js:2328
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:270
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:272
msgid "Remove idles"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1431
+#: htdocs/luci-static/resources/fchomo.js:1434
msgid "Rendezvous server"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2501
+#: htdocs/luci-static/resources/view/fchomo/node.js:2522
msgid "Replace name"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2502
+#: htdocs/luci-static/resources/view/fchomo/node.js:2523
msgid "Replace node name."
msgstr ""
@@ -3034,13 +3055,13 @@ msgstr ""
msgid "Request"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1339
-#: htdocs/luci-static/resources/view/fchomo/node.js:1943
-#: htdocs/luci-static/resources/view/fchomo/node.js:1950
+#: htdocs/luci-static/resources/fchomo/listeners.js:1357
+#: htdocs/luci-static/resources/view/fchomo/node.js:1964
+#: htdocs/luci-static/resources/view/fchomo/node.js:1971
msgid "Request path"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:685
+#: htdocs/luci-static/resources/view/fchomo/node.js:695
msgid "Request timeout"
msgstr ""
@@ -3053,11 +3074,11 @@ msgid "Require any"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:481
-#: htdocs/luci-static/resources/view/fchomo/node.js:1609
+#: htdocs/luci-static/resources/view/fchomo/node.js:1632
msgid "Requires server support."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:950
+#: htdocs/luci-static/resources/view/fchomo/node.js:960
msgid "Reserved field bytes"
msgstr ""
@@ -3065,20 +3086,20 @@ msgstr ""
msgid "Resources management"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:691
-#: htdocs/luci-static/resources/fchomo/listeners.js:701
-#: htdocs/luci-static/resources/fchomo/listeners.js:706
-#: htdocs/luci-static/resources/fchomo/listeners.js:1125
-#: htdocs/luci-static/resources/fchomo/listeners.js:1241
-#: htdocs/luci-static/resources/view/fchomo/node.js:1281
-#: htdocs/luci-static/resources/view/fchomo/node.js:1291
-#: htdocs/luci-static/resources/view/fchomo/node.js:1296
-#: htdocs/luci-static/resources/view/fchomo/node.js:1590
+#: htdocs/luci-static/resources/fchomo/listeners.js:700
+#: htdocs/luci-static/resources/fchomo/listeners.js:719
+#: htdocs/luci-static/resources/fchomo/listeners.js:724
+#: htdocs/luci-static/resources/fchomo/listeners.js:1143
+#: htdocs/luci-static/resources/fchomo/listeners.js:1259
+#: htdocs/luci-static/resources/view/fchomo/node.js:1295
+#: htdocs/luci-static/resources/view/fchomo/node.js:1314
+#: htdocs/luci-static/resources/view/fchomo/node.js:1319
+#: htdocs/luci-static/resources/view/fchomo/node.js:1613
msgid "Restls"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:760
-#: htdocs/luci-static/resources/view/fchomo/node.js:1350
+#: htdocs/luci-static/resources/fchomo/listeners.js:778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1373
msgid "Restls script"
msgstr ""
@@ -3101,13 +3122,13 @@ msgstr ""
msgid "Reusing a single tunnel to carry multiple target connections within it."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1046
-#: htdocs/luci-static/resources/view/fchomo/node.js:1058
+#: htdocs/luci-static/resources/view/fchomo/node.js:1056
+#: htdocs/luci-static/resources/view/fchomo/node.js:1068
msgid "Room name"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1051
-#: htdocs/luci-static/resources/view/fchomo/node.js:1058
+#: htdocs/luci-static/resources/view/fchomo/node.js:1061
+#: htdocs/luci-static/resources/view/fchomo/node.js:1068
msgid "Room secret"
msgstr ""
@@ -3124,10 +3145,10 @@ msgstr ""
msgid "Routing GFW"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:612
+#: htdocs/luci-static/resources/fchomo/listeners.js:621
#: htdocs/luci-static/resources/view/fchomo/global.js:784
-#: htdocs/luci-static/resources/view/fchomo/node.js:2171
-#: htdocs/luci-static/resources/view/fchomo/node.js:2590
+#: htdocs/luci-static/resources/view/fchomo/node.js:2192
+#: htdocs/luci-static/resources/view/fchomo/node.js:2611
msgid "Routing mark (Fwmark)"
msgstr ""
@@ -3175,7 +3196,7 @@ msgstr ""
msgid "Rule set URL"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:824
+#: htdocs/luci-static/resources/view/fchomo/node.js:834
msgid "Rules"
msgstr ""
@@ -3187,7 +3208,7 @@ msgstr ""
msgid "Ruleset-URI-Scheme"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1396
+#: htdocs/luci-static/resources/fchomo.js:1399
msgid "Running"
msgstr ""
@@ -3211,7 +3232,7 @@ msgstr ""
msgid "STUN"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1448
+#: htdocs/luci-static/resources/fchomo.js:1451
msgid "STUN servers"
msgstr ""
@@ -3219,12 +3240,12 @@ msgstr ""
msgid "SUB-RULE"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1262
+#: htdocs/luci-static/resources/view/fchomo/node.js:1276
msgid "SUoT version"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:501
-#: htdocs/luci-static/resources/view/fchomo/node.js:719
+#: htdocs/luci-static/resources/fchomo/listeners.js:510
+#: htdocs/luci-static/resources/view/fchomo/node.js:729
msgid "Salamander"
msgstr ""
@@ -3241,12 +3262,12 @@ msgstr ""
msgid "Save"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1695
-#: htdocs/luci-static/resources/view/fchomo/node.js:1696
+#: htdocs/luci-static/resources/view/fchomo/node.js:1717
+#: htdocs/luci-static/resources/view/fchomo/node.js:1718
msgid "Secondary"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1074
+#: htdocs/luci-static/resources/view/fchomo/node.js:1084
msgid "Secure mode"
msgstr ""
@@ -3275,9 +3296,9 @@ msgstr ""
msgid "Send random ticket of 300s-600s duration for client 0-RTT reuse."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:850
-#: htdocs/luci-static/resources/fchomo/listeners.js:1116
-#: htdocs/luci-static/resources/fchomo/listeners.js:1146
+#: htdocs/luci-static/resources/fchomo/listeners.js:868
+#: htdocs/luci-static/resources/fchomo/listeners.js:1134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1164
#: htdocs/luci-static/resources/view/fchomo/server.js:58
#: root/usr/share/luci/menu.d/luci-app-fchomo.json:62
msgid "Server"
@@ -3287,13 +3308,13 @@ msgstr ""
msgid "Server address"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1333
-#: htdocs/luci-static/resources/view/fchomo/node.js:1922
-#: htdocs/luci-static/resources/view/fchomo/node.js:1928
+#: htdocs/luci-static/resources/fchomo/listeners.js:1351
+#: htdocs/luci-static/resources/view/fchomo/node.js:1943
+#: htdocs/luci-static/resources/view/fchomo/node.js:1949
msgid "Server hostname"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1009
+#: htdocs/luci-static/resources/view/fchomo/node.js:1019
msgid "Server public key"
msgstr ""
@@ -3310,15 +3331,15 @@ msgstr ""
msgid "ShadowQUIC"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:690
-#: htdocs/luci-static/resources/fchomo/listeners.js:700
-#: htdocs/luci-static/resources/fchomo/listeners.js:705
-#: htdocs/luci-static/resources/fchomo/listeners.js:1124
-#: htdocs/luci-static/resources/fchomo/listeners.js:1240
-#: htdocs/luci-static/resources/view/fchomo/node.js:1280
-#: htdocs/luci-static/resources/view/fchomo/node.js:1290
-#: htdocs/luci-static/resources/view/fchomo/node.js:1295
-#: htdocs/luci-static/resources/view/fchomo/node.js:1589
+#: htdocs/luci-static/resources/fchomo/listeners.js:699
+#: htdocs/luci-static/resources/fchomo/listeners.js:718
+#: htdocs/luci-static/resources/fchomo/listeners.js:723
+#: htdocs/luci-static/resources/fchomo/listeners.js:1142
+#: htdocs/luci-static/resources/fchomo/listeners.js:1258
+#: htdocs/luci-static/resources/view/fchomo/node.js:1294
+#: htdocs/luci-static/resources/view/fchomo/node.js:1313
+#: htdocs/luci-static/resources/view/fchomo/node.js:1318
+#: htdocs/luci-static/resources/view/fchomo/node.js:1612
msgid "ShadowTLS"
msgstr ""
@@ -3327,22 +3348,22 @@ msgstr ""
msgid "Shadowsocks"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:437
-#: htdocs/luci-static/resources/view/fchomo/node.js:585
+#: htdocs/luci-static/resources/fchomo/listeners.js:446
+#: htdocs/luci-static/resources/view/fchomo/node.js:595
msgid "Shadowsocks chipher"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:432
-#: htdocs/luci-static/resources/view/fchomo/node.js:580
+#: htdocs/luci-static/resources/fchomo/listeners.js:441
+#: htdocs/luci-static/resources/view/fchomo/node.js:590
msgid "Shadowsocks encrypt"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:445
-#: htdocs/luci-static/resources/view/fchomo/node.js:593
+#: htdocs/luci-static/resources/fchomo/listeners.js:454
+#: htdocs/luci-static/resources/view/fchomo/node.js:603
msgid "Shadowsocks password"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2123
+#: htdocs/luci-static/resources/view/fchomo/node.js:2144
msgid "Show connections in the dashboard for breaking connections easier."
msgstr ""
@@ -3354,15 +3375,15 @@ msgstr ""
msgid "Simple round-robin all nodes"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2390
+#: htdocs/luci-static/resources/view/fchomo/node.js:2411
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:402
msgid "Size limit"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1480
+#: htdocs/luci-static/resources/fchomo.js:1483
#: htdocs/luci-static/resources/view/fchomo/client.js:1675
-#: htdocs/luci-static/resources/view/fchomo/node.js:1519
-#: htdocs/luci-static/resources/view/fchomo/node.js:2565
+#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/view/fchomo/node.js:2586
msgid "Skip cert verify"
msgstr ""
@@ -3431,12 +3452,12 @@ msgstr ""
msgid "Strategy"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:584
-#: htdocs/luci-static/resources/view/fchomo/node.js:778
+#: htdocs/luci-static/resources/fchomo/listeners.js:593
+#: htdocs/luci-static/resources/view/fchomo/node.js:788
msgid "Stream-level receive window size"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:617
+#: htdocs/luci-static/resources/fchomo/listeners.js:626
#: htdocs/luci-static/resources/view/fchomo/client.js:1396
#: htdocs/luci-static/resources/view/fchomo/client.js:1405
msgid "Sub rule"
@@ -3446,11 +3467,11 @@ msgstr ""
msgid "Sub rule group"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1123
+#: htdocs/luci-static/resources/view/fchomo/node.js:1137
msgid "Subnet proxy"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:870
+#: htdocs/luci-static/resources/fchomo.js:873
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:242
msgid "Successfully imported %s %s of total %s."
msgstr ""
@@ -3459,7 +3480,7 @@ msgstr ""
msgid "Successfully updated."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:2020
+#: htdocs/luci-static/resources/fchomo.js:2022
msgid "Successfully uploaded."
msgstr ""
@@ -3468,7 +3489,7 @@ msgstr ""
msgid "Sudoku"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:744
+#: htdocs/luci-static/resources/view/fchomo/node.js:754
msgid "Support %s, default %s."
msgstr ""
@@ -3501,7 +3522,7 @@ msgstr ""
#: htdocs/luci-static/resources/fchomo.js:237
#: htdocs/luci-static/resources/fchomo.js:238
#: htdocs/luci-static/resources/fchomo.js:249
-#: htdocs/luci-static/resources/fchomo/listeners.js:670
+#: htdocs/luci-static/resources/fchomo/listeners.js:679
#: htdocs/luci-static/resources/view/fchomo/client.js:618
#: htdocs/luci-static/resources/view/fchomo/client.js:707
msgid "TCP"
@@ -3515,7 +3536,7 @@ msgstr ""
msgid "TCP idle timeout"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2116
+#: htdocs/luci-static/resources/view/fchomo/node.js:2137
msgid "TCP only"
msgstr ""
@@ -3543,36 +3564,36 @@ msgstr ""
msgid "TCP/UDP"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2147
-#: htdocs/luci-static/resources/view/fchomo/node.js:2526
+#: htdocs/luci-static/resources/view/fchomo/node.js:2168
+#: htdocs/luci-static/resources/view/fchomo/node.js:2547
msgid "TFO"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1171
+#: htdocs/luci-static/resources/view/fchomo/node.js:1185
msgid "TLD DNS zone"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1172
+#: htdocs/luci-static/resources/view/fchomo/node.js:1186
msgid "TLD DNS zone used by MagicDNS, default is %s."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:718
-#: htdocs/luci-static/resources/fchomo/listeners.js:1026
+#: htdocs/luci-static/resources/fchomo/listeners.js:736
+#: htdocs/luci-static/resources/fchomo/listeners.js:1044
#: htdocs/luci-static/resources/view/fchomo/global.js:558
#: htdocs/luci-static/resources/view/fchomo/node.js:472
-#: htdocs/luci-static/resources/view/fchomo/node.js:1308
-#: htdocs/luci-static/resources/view/fchomo/node.js:1429
+#: htdocs/luci-static/resources/view/fchomo/node.js:1331
+#: htdocs/luci-static/resources/view/fchomo/node.js:1452
msgid "TLS"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1462
-#: htdocs/luci-static/resources/fchomo/listeners.js:1067
-#: htdocs/luci-static/resources/view/fchomo/node.js:1460
+#: htdocs/luci-static/resources/fchomo.js:1465
+#: htdocs/luci-static/resources/fchomo/listeners.js:1085
+#: htdocs/luci-static/resources/view/fchomo/node.js:1483
msgid "TLS ALPN"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1457
-#: htdocs/luci-static/resources/view/fchomo/node.js:1454
+#: htdocs/luci-static/resources/fchomo.js:1460
+#: htdocs/luci-static/resources/view/fchomo/node.js:1477
msgid "TLS SNI"
msgstr ""
@@ -3591,44 +3612,44 @@ msgid "TURN"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:246
-#: htdocs/luci-static/resources/view/fchomo/node.js:962
+#: htdocs/luci-static/resources/view/fchomo/node.js:972
msgid "Tailscale"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:604
+#: htdocs/luci-static/resources/fchomo/listeners.js:613
msgid "Target address"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:493
+#: htdocs/luci-static/resources/fchomo/listeners.js:502
msgid ""
"Tell the client to use the BBR flow control algorithm instead of Hysteria CC."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1766
-#: htdocs/luci-static/resources/view/fchomo/node.js:1770
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
-#: htdocs/luci-static/resources/view/fchomo/node.js:1798
-#: htdocs/luci-static/resources/view/fchomo/node.js:1802
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1787
+#: htdocs/luci-static/resources/view/fchomo/node.js:1791
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
+#: htdocs/luci-static/resources/view/fchomo/node.js:1819
+#: htdocs/luci-static/resources/view/fchomo/node.js:1823
msgid "The %s address used by local machine in the %s network."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1495
-#: htdocs/luci-static/resources/fchomo/listeners.js:1146
-#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/fchomo.js:1498
+#: htdocs/luci-static/resources/fchomo/listeners.js:1164
+#: htdocs/luci-static/resources/view/fchomo/node.js:1565
msgid "The %s private key, in PEM format."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1489
-#: htdocs/luci-static/resources/fchomo/listeners.js:1116
-#: htdocs/luci-static/resources/fchomo/listeners.js:1169
+#: htdocs/luci-static/resources/fchomo.js:1492
+#: htdocs/luci-static/resources/fchomo/listeners.js:1134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1187
#: htdocs/luci-static/resources/view/fchomo/global.js:579
-#: htdocs/luci-static/resources/view/fchomo/node.js:1528
+#: htdocs/luci-static/resources/view/fchomo/node.js:1551
msgid "The %s public key, in PEM format."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1562
+#: htdocs/luci-static/resources/view/fchomo/node.js:1585
msgid ""
"The ECH parameter of the HTTPS record for the domain. Leave empty to resolve "
"via DNS."
@@ -3642,7 +3663,7 @@ msgstr ""
msgid "The ED25519 master public key or UUID generated by Sudoku."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:604
+#: htdocs/luci-static/resources/view/fchomo/node.js:614
msgid "The client metadata sent to the server."
msgstr ""
@@ -3650,14 +3671,14 @@ msgstr ""
msgid "The default value is 2:00 every day."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1244
+#: htdocs/luci-static/resources/view/fchomo/node.js:1258
msgid ""
"The default value is %s, indicating that only the outer "
"connection timeout is used."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:882
-#: htdocs/luci-static/resources/view/fchomo/node.js:1405
+#: htdocs/luci-static/resources/fchomo/listeners.js:900
+#: htdocs/luci-static/resources/view/fchomo/node.js:1428
msgid ""
"The first padding must have a probability of 100% and at least 35 bytes."
msgstr ""
@@ -3672,34 +3693,34 @@ msgstr ""
msgid "The matching %s will be deemed as poisoned."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:768
+#: htdocs/luci-static/resources/fchomo/listeners.js:786
msgid "The proxy used to connect to the handshake target."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1010
+#: htdocs/luci-static/resources/fchomo/listeners.js:1028
msgid "The proxy used to connect to the rendezvous server."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:880
-#: htdocs/luci-static/resources/view/fchomo/node.js:1403
+#: htdocs/luci-static/resources/fchomo/listeners.js:898
+#: htdocs/luci-static/resources/view/fchomo/node.js:1426
msgid "The server and client can set different padding parameters."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1227
+#: htdocs/luci-static/resources/fchomo/listeners.js:1245
#: htdocs/luci-static/resources/view/fchomo/global.js:623
msgid "This ECH parameter needs to be added to the HTTPS record of the domain."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1483
+#: htdocs/luci-static/resources/fchomo.js:1486
#: htdocs/luci-static/resources/view/fchomo/client.js:1678
-#: htdocs/luci-static/resources/view/fchomo/node.js:1522
-#: htdocs/luci-static/resources/view/fchomo/node.js:2568
+#: htdocs/luci-static/resources/view/fchomo/node.js:1545
+#: htdocs/luci-static/resources/view/fchomo/node.js:2589
msgid ""
"This is DANGEROUS, your traffic is almost like "
"PLAIN TEXT! Use at your own risk!"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:650
+#: htdocs/luci-static/resources/view/fchomo/node.js:660
msgid ""
"This is the TUIC port of the SUoT protocol, designed to provide a QUIC "
"stream based UDP relay mode that TUIC does not provide."
@@ -3728,23 +3749,28 @@ msgstr ""
msgid "Tproxy port"
msgstr ""
+#: htdocs/luci-static/resources/fchomo/listeners.js:410
+#: htdocs/luci-static/resources/view/fchomo/node.js:530
+msgid "Traffic mode"
+msgstr ""
+
#: htdocs/luci-static/resources/fchomo/listeners.js:213
#: htdocs/luci-static/resources/view/fchomo/node.js:386
msgid "Traffic pattern"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2762
+#: htdocs/luci-static/resources/view/fchomo/node.js:2783
msgid "Transit proxy group"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2773
+#: htdocs/luci-static/resources/view/fchomo/node.js:2794
msgid "Transit proxy node"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:194
-#: htdocs/luci-static/resources/fchomo/listeners.js:1297
+#: htdocs/luci-static/resources/fchomo/listeners.js:1315
#: htdocs/luci-static/resources/view/fchomo/node.js:363
-#: htdocs/luci-static/resources/view/fchomo/node.js:1875
+#: htdocs/luci-static/resources/view/fchomo/node.js:1896
msgid "Transport"
msgstr ""
@@ -3753,8 +3779,8 @@ msgstr ""
msgid "Transport fields"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1302
-#: htdocs/luci-static/resources/view/fchomo/node.js:1880
+#: htdocs/luci-static/resources/fchomo/listeners.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1901
msgid "Transport type"
msgstr ""
@@ -3772,7 +3798,7 @@ msgstr ""
msgid "TrustTunnel"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:549
+#: htdocs/luci-static/resources/fchomo/listeners.js:558
msgid "Trusted proxy header"
msgstr ""
@@ -3796,7 +3822,7 @@ msgstr ""
msgid "Tunnel"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:852
+#: htdocs/luci-static/resources/view/fchomo/node.js:862
msgid "Turns TCP relay off."
msgstr ""
@@ -3807,8 +3833,8 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:871
#: htdocs/luci-static/resources/view/fchomo/client.js:1069
#: htdocs/luci-static/resources/view/fchomo/node.js:271
-#: htdocs/luci-static/resources/view/fchomo/node.js:2327
-#: htdocs/luci-static/resources/view/fchomo/node.js:2723
+#: htdocs/luci-static/resources/view/fchomo/node.js:2348
+#: htdocs/luci-static/resources/view/fchomo/node.js:2744
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:296
msgid "Type"
msgstr ""
@@ -3823,11 +3849,11 @@ msgstr ""
#: htdocs/luci-static/resources/fchomo.js:245
#: htdocs/luci-static/resources/fchomo.js:246
#: htdocs/luci-static/resources/fchomo.js:247
-#: htdocs/luci-static/resources/fchomo/listeners.js:671
-#: htdocs/luci-static/resources/fchomo/listeners.js:676
+#: htdocs/luci-static/resources/fchomo/listeners.js:680
+#: htdocs/luci-static/resources/fchomo/listeners.js:685
#: htdocs/luci-static/resources/view/fchomo/client.js:617
#: htdocs/luci-static/resources/view/fchomo/client.js:706
-#: htdocs/luci-static/resources/view/fchomo/node.js:2536
+#: htdocs/luci-static/resources/view/fchomo/node.js:2557
msgid "UDP"
msgstr ""
@@ -3835,20 +3861,20 @@ msgstr ""
msgid "UDP NAT expiration time"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:649
-#: htdocs/luci-static/resources/view/fchomo/node.js:749
+#: htdocs/luci-static/resources/view/fchomo/node.js:659
+#: htdocs/luci-static/resources/view/fchomo/node.js:759
msgid "UDP over stream"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:655
+#: htdocs/luci-static/resources/view/fchomo/node.js:665
msgid "UDP over stream version"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:642
+#: htdocs/luci-static/resources/view/fchomo/node.js:652
msgid "UDP packet relay mode."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:641
+#: htdocs/luci-static/resources/view/fchomo/node.js:651
msgid "UDP relay mode"
msgstr ""
@@ -3864,14 +3890,14 @@ msgid "URL test"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:222
-#: htdocs/luci-static/resources/fchomo/listeners.js:410
-#: htdocs/luci-static/resources/fchomo/listeners.js:460
-#: htdocs/luci-static/resources/view/fchomo/node.js:530
-#: htdocs/luci-static/resources/view/fchomo/node.js:629
+#: htdocs/luci-static/resources/fchomo/listeners.js:419
+#: htdocs/luci-static/resources/fchomo/listeners.js:469
+#: htdocs/luci-static/resources/view/fchomo/node.js:540
+#: htdocs/luci-static/resources/view/fchomo/node.js:639
msgid "UUID"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1521
+#: htdocs/luci-static/resources/fchomo.js:1524
msgid "Unable to download unsupported type: %s"
msgstr ""
@@ -3896,8 +3922,8 @@ msgstr ""
msgid "Unknown error: %s"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1256
-#: htdocs/luci-static/resources/view/fchomo/node.js:2541
+#: htdocs/luci-static/resources/view/fchomo/node.js:1270
+#: htdocs/luci-static/resources/view/fchomo/node.js:2562
msgid "UoT"
msgstr ""
@@ -3905,24 +3931,24 @@ msgstr ""
msgid "Update failed."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2396
+#: htdocs/luci-static/resources/view/fchomo/node.js:2417
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:408
msgid "Update interval"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1399
-#: htdocs/luci-static/resources/view/fchomo/node.js:2134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1417
+#: htdocs/luci-static/resources/view/fchomo/node.js:2155
msgid "Upload bandwidth"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1400
-#: htdocs/luci-static/resources/view/fchomo/node.js:2135
+#: htdocs/luci-static/resources/fchomo/listeners.js:1418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2156
msgid "Upload bandwidth in Mbps."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1137
-#: htdocs/luci-static/resources/fchomo/listeners.js:1177
-#: htdocs/luci-static/resources/view/fchomo/node.js:1533
+#: htdocs/luci-static/resources/fchomo/listeners.js:1155
+#: htdocs/luci-static/resources/fchomo/listeners.js:1195
+#: htdocs/luci-static/resources/view/fchomo/node.js:1556
msgid "Upload certificate"
msgstr ""
@@ -3930,29 +3956,29 @@ msgstr ""
msgid "Upload initial package"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1152
-#: htdocs/luci-static/resources/view/fchomo/node.js:1547
+#: htdocs/luci-static/resources/fchomo/listeners.js:1170
+#: htdocs/luci-static/resources/view/fchomo/node.js:1570
msgid "Upload key"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1140
-#: htdocs/luci-static/resources/fchomo/listeners.js:1155
-#: htdocs/luci-static/resources/fchomo/listeners.js:1180
+#: htdocs/luci-static/resources/fchomo/listeners.js:1158
+#: htdocs/luci-static/resources/fchomo/listeners.js:1173
+#: htdocs/luci-static/resources/fchomo/listeners.js:1198
#: htdocs/luci-static/resources/view/fchomo/global.js:306
-#: htdocs/luci-static/resources/view/fchomo/node.js:1536
-#: htdocs/luci-static/resources/view/fchomo/node.js:1550
+#: htdocs/luci-static/resources/view/fchomo/node.js:1559
+#: htdocs/luci-static/resources/view/fchomo/node.js:1573
msgid "Upload..."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1813
+#: htdocs/luci-static/resources/view/fchomo/node.js:1834
msgid "Use DHCP"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1814
+#: htdocs/luci-static/resources/view/fchomo/node.js:1835
msgid "Use DHCP to obtain IP address."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:844
+#: htdocs/luci-static/resources/view/fchomo/node.js:854
msgid "Use protocol-13 extended encryption for outgoing HELLO packets."
msgstr ""
@@ -3962,15 +3988,15 @@ msgstr ""
msgid "Use sub rule"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1117
+#: htdocs/luci-static/resources/view/fchomo/node.js:1131
msgid "Used to forward traffic to the specified nodes for external access."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:869
+#: htdocs/luci-static/resources/view/fchomo/node.js:879
msgid "Used to replace the built-in official %s."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:863
+#: htdocs/luci-static/resources/view/fchomo/node.js:873
msgid "Used to replace the contents of default %s."
msgstr ""
@@ -3994,9 +4020,9 @@ msgstr ""
msgid "Used to resolve the domain of the Proxy node."
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1475
-#: htdocs/luci-static/resources/view/fchomo/node.js:1514
-#: htdocs/luci-static/resources/view/fchomo/node.js:2560
+#: htdocs/luci-static/resources/fchomo.js:1478
+#: htdocs/luci-static/resources/view/fchomo/node.js:1537
+#: htdocs/luci-static/resources/view/fchomo/node.js:2581
msgid "Used to verify the hostname on the returned certificates."
msgstr ""
@@ -4009,9 +4035,9 @@ msgid "User-hint is mandatory"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:162
-#: htdocs/luci-static/resources/fchomo/listeners.js:738
+#: htdocs/luci-static/resources/fchomo/listeners.js:756
#: htdocs/luci-static/resources/view/fchomo/node.js:322
-#: htdocs/luci-static/resources/view/fchomo/node.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1343
msgid "Username"
msgstr ""
@@ -4019,23 +4045,23 @@ msgstr ""
msgid "Users filter mode"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:851
+#: htdocs/luci-static/resources/view/fchomo/node.js:861
msgid "Uses TCP relay only."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:850
+#: htdocs/luci-static/resources/view/fchomo/node.js:860
msgid "Uses relay after UDP direct failure."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1174
+#: htdocs/luci-static/resources/view/fchomo/node.js:1188
msgid "Using this in conjunction with %s is recommended."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1991
+#: htdocs/luci-static/resources/view/fchomo/node.js:2012
msgid "V2ray HTTPUpgrade"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1996
+#: htdocs/luci-static/resources/view/fchomo/node.js:2017
msgid "V2ray HTTPUpgrade fast open"
msgstr ""
@@ -4049,9 +4075,9 @@ msgstr ""
msgid "VMess"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
msgid "VPN"
msgstr ""
@@ -4059,17 +4085,17 @@ msgstr ""
msgid "VPN fields"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:900
+#: htdocs/luci-static/resources/view/fchomo/node.js:910
msgid "Valid 16-digit Moon World ID and 10-digit Node ID of Moon Root server."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2333
-#: htdocs/luci-static/resources/view/fchomo/node.js:2729
+#: htdocs/luci-static/resources/view/fchomo/node.js:2354
+#: htdocs/luci-static/resources/view/fchomo/node.js:2750
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:339
msgid "Value"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:823
+#: htdocs/luci-static/resources/view/fchomo/node.js:833
msgid "Verbose"
msgstr ""
@@ -4078,27 +4104,27 @@ msgid "Verify if given"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:399
-#: htdocs/luci-static/resources/fchomo/listeners.js:752
+#: htdocs/luci-static/resources/fchomo/listeners.js:770
#: htdocs/luci-static/resources/view/fchomo/node.js:514
-#: htdocs/luci-static/resources/view/fchomo/node.js:1334
+#: htdocs/luci-static/resources/view/fchomo/node.js:1357
msgid "Version"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1342
+#: htdocs/luci-static/resources/view/fchomo/node.js:1365
msgid "Version hint"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1116
-#: htdocs/luci-static/resources/view/fchomo/node.js:1782
-#: htdocs/luci-static/resources/view/fchomo/node.js:1815
+#: htdocs/luci-static/resources/view/fchomo/node.js:1130
+#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1836
msgid "Virtual IPv4 address"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1789
+#: htdocs/luci-static/resources/view/fchomo/node.js:1810
msgid "Virtual IPv6 address"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1756
+#: htdocs/luci-static/resources/view/fchomo/node.js:1777
msgid "Virtual address"
msgstr ""
@@ -4116,15 +4142,15 @@ msgid "Warning"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:377
-#: htdocs/luci-static/resources/fchomo/listeners.js:1304
-#: htdocs/luci-static/resources/fchomo/listeners.js:1315
#: htdocs/luci-static/resources/fchomo/listeners.js:1322
+#: htdocs/luci-static/resources/fchomo/listeners.js:1333
+#: htdocs/luci-static/resources/fchomo/listeners.js:1340
#: htdocs/luci-static/resources/view/fchomo/node.js:468
#: htdocs/luci-static/resources/view/fchomo/node.js:497
-#: htdocs/luci-static/resources/view/fchomo/node.js:1885
-#: htdocs/luci-static/resources/view/fchomo/node.js:1898
-#: htdocs/luci-static/resources/view/fchomo/node.js:1905
-#: htdocs/luci-static/resources/view/fchomo/node.js:1911
+#: htdocs/luci-static/resources/view/fchomo/node.js:1906
+#: htdocs/luci-static/resources/view/fchomo/node.js:1919
+#: htdocs/luci-static/resources/view/fchomo/node.js:1926
+#: htdocs/luci-static/resources/view/fchomo/node.js:1932
msgid "WebSocket"
msgstr ""
@@ -4132,11 +4158,11 @@ msgstr ""
msgid "When used as a server, HomeProxy is a better choice."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1166
+#: htdocs/luci-static/resources/view/fchomo/node.js:1180
msgid "Whether to accept DNS configurations distributed by the network."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:984
+#: htdocs/luci-static/resources/view/fchomo/node.js:994
msgid "Whether to accept routes advertised by other nodes."
msgstr ""
@@ -4148,53 +4174,53 @@ msgstr ""
msgid "WireGuard"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:930
+#: htdocs/luci-static/resources/view/fchomo/node.js:940
msgid "WireGuard peer public key."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:937
+#: htdocs/luci-static/resources/view/fchomo/node.js:947
msgid "WireGuard pre-shared key."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:909
+#: htdocs/luci-static/resources/view/fchomo/node.js:919
msgid "WireGuard requires base64-encoded private keys."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1767
-#: htdocs/luci-static/resources/view/fchomo/node.js:1799
+#: htdocs/luci-static/resources/view/fchomo/node.js:1788
+#: htdocs/luci-static/resources/view/fchomo/node.js:1820
msgid "Wireguard"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1305
-#: htdocs/luci-static/resources/fchomo/listeners.js:1316
-#: htdocs/luci-static/resources/view/fchomo/node.js:1886
-#: htdocs/luci-static/resources/view/fchomo/node.js:1906
+#: htdocs/luci-static/resources/fchomo/listeners.js:1323
+#: htdocs/luci-static/resources/fchomo/listeners.js:1334
+#: htdocs/luci-static/resources/view/fchomo/node.js:1907
+#: htdocs/luci-static/resources/view/fchomo/node.js:1927
msgid "XHTTP"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1352
-#: htdocs/luci-static/resources/view/fchomo/node.js:2001
+#: htdocs/luci-static/resources/fchomo/listeners.js:1370
+#: htdocs/luci-static/resources/view/fchomo/node.js:2022
msgid "XHTTP mode"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2032
+#: htdocs/luci-static/resources/view/fchomo/node.js:2053
msgid "XMUX"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2037
-#: htdocs/luci-static/resources/view/fchomo/node.js:2042
-#: htdocs/luci-static/resources/view/fchomo/node.js:2047
-#: htdocs/luci-static/resources/view/fchomo/node.js:2052
-#: htdocs/luci-static/resources/view/fchomo/node.js:2057
-#: htdocs/luci-static/resources/view/fchomo/node.js:2062
+#: htdocs/luci-static/resources/view/fchomo/node.js:2058
+#: htdocs/luci-static/resources/view/fchomo/node.js:2063
+#: htdocs/luci-static/resources/view/fchomo/node.js:2068
+#: htdocs/luci-static/resources/view/fchomo/node.js:2073
+#: htdocs/luci-static/resources/view/fchomo/node.js:2078
+#: htdocs/luci-static/resources/view/fchomo/node.js:2083
msgid "XMUX:"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:841
+#: htdocs/luci-static/resources/fchomo/listeners.js:859
msgid "XOR mode"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:575
+#: htdocs/luci-static/resources/view/fchomo/node.js:585
msgid "Xudp (Xray-core)"
msgstr ""
@@ -4202,11 +4228,11 @@ msgstr ""
msgid "Yaml text"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2571
+#: htdocs/luci-static/resources/view/fchomo/node.js:2592
msgid "Yes"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1173
+#: htdocs/luci-static/resources/view/fchomo/node.js:1187
msgid ""
"You can add %s in the %s to resolve A/PTR records within the virtual network."
msgstr ""
@@ -4215,7 +4241,7 @@ msgstr ""
msgid "YouTube"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:2002
+#: htdocs/luci-static/resources/fchomo.js:2004
msgid "Your %s was successfully uploaded. Size: %sB."
msgstr ""
@@ -4223,14 +4249,14 @@ msgstr ""
msgid "ZeroTier"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:831
+#: htdocs/luci-static/resources/view/fchomo/node.js:841
msgid "ZeroTier UDP payload MTU."
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:422
#: htdocs/luci-static/resources/fchomo.js:435
#: htdocs/luci-static/resources/fchomo.js:440
-#: htdocs/luci-static/resources/view/fchomo/node.js:555
+#: htdocs/luci-static/resources/view/fchomo/node.js:565
msgid "aes-128-gcm"
msgstr ""
@@ -4243,19 +4269,19 @@ msgstr ""
msgid "aes-256-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1139
+#: htdocs/luci-static/resources/view/fchomo/node.js:1153
msgid "aes-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1140
+#: htdocs/luci-static/resources/view/fchomo/node.js:1154
msgid "aes-gcm-256"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2439
msgid "age private key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2479
+#: htdocs/luci-static/resources/view/fchomo/node.js:2500
msgid "age public key"
msgstr ""
@@ -4267,7 +4293,7 @@ msgstr ""
msgid "age-x25519"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:552
+#: htdocs/luci-static/resources/view/fchomo/node.js:562
msgid "auto"
msgstr ""
@@ -4280,13 +4306,13 @@ msgstr ""
msgid "bbr3"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1142
-#: htdocs/luci-static/resources/fchomo/listeners.js:1182
-#: htdocs/luci-static/resources/view/fchomo/node.js:1538
+#: htdocs/luci-static/resources/fchomo/listeners.js:1160
+#: htdocs/luci-static/resources/fchomo/listeners.js:1200
+#: htdocs/luci-static/resources/view/fchomo/node.js:1561
msgid "certificate"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1138
+#: htdocs/luci-static/resources/view/fchomo/node.js:1152
msgid "chacha20"
msgstr ""
@@ -4296,7 +4322,7 @@ msgstr ""
msgid "chacha20-ietf-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:556
+#: htdocs/luci-static/resources/view/fchomo/node.js:566
msgid "chacha20-poly1305"
msgstr ""
@@ -4305,8 +4331,8 @@ msgstr ""
msgid "cubic"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:793
-#: htdocs/luci-static/resources/fchomo/listeners.js:824
+#: htdocs/luci-static/resources/fchomo/listeners.js:811
+#: htdocs/luci-static/resources/fchomo/listeners.js:842
msgid "decryption"
msgstr ""
@@ -4314,13 +4340,13 @@ msgstr ""
msgid "dnsmasq selects upstream on its own. (may affect CDN accuracy)"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2553
+#: htdocs/luci-static/resources/view/fchomo/node.js:2574
msgid "down"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:828
-#: htdocs/luci-static/resources/view/fchomo/node.js:1357
+#: htdocs/luci-static/resources/fchomo/listeners.js:846
#: htdocs/luci-static/resources/view/fchomo/node.js:1380
+#: htdocs/luci-static/resources/view/fchomo/node.js:1403
msgid "encryption"
msgstr ""
@@ -4329,55 +4355,55 @@ msgstr ""
msgid "false = bandwidth optimized downlink; true = pure Sudoku downlink."
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1303
-#: htdocs/luci-static/resources/fchomo/listeners.js:1314
#: htdocs/luci-static/resources/fchomo/listeners.js:1321
-#: htdocs/luci-static/resources/view/fchomo/node.js:1884
-#: htdocs/luci-static/resources/view/fchomo/node.js:1897
-#: htdocs/luci-static/resources/view/fchomo/node.js:1904
-#: htdocs/luci-static/resources/view/fchomo/node.js:1910
+#: htdocs/luci-static/resources/fchomo/listeners.js:1332
+#: htdocs/luci-static/resources/fchomo/listeners.js:1339
+#: htdocs/luci-static/resources/view/fchomo/node.js:1905
+#: htdocs/luci-static/resources/view/fchomo/node.js:1918
+#: htdocs/luci-static/resources/view/fchomo/node.js:1925
+#: htdocs/luci-static/resources/view/fchomo/node.js:1931
msgid "gRPC"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1967
+#: htdocs/luci-static/resources/view/fchomo/node.js:1988
msgid "gRPC User-Agent"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1972
+#: htdocs/luci-static/resources/view/fchomo/node.js:1993
msgid "gRPC ping interval"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1346
-#: htdocs/luci-static/resources/view/fchomo/node.js:1963
+#: htdocs/luci-static/resources/fchomo/listeners.js:1364
+#: htdocs/luci-static/resources/view/fchomo/node.js:1984
msgid "gRPC service name"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/global.js:517
-#: htdocs/luci-static/resources/view/fchomo/node.js:1205
+#: htdocs/luci-static/resources/view/fchomo/node.js:1219
msgid "gVisor"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1020
+#: htdocs/luci-static/resources/view/fchomo/node.js:1030
msgid "h2"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2079
+#: htdocs/luci-static/resources/view/fchomo/node.js:2100
msgid "h2mux"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1018
+#: htdocs/luci-static/resources/view/fchomo/node.js:1028
msgid "h3"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1019
+#: htdocs/luci-static/resources/view/fchomo/node.js:1029
msgid "h3-l4proxy"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:993
+#: htdocs/luci-static/resources/fchomo/listeners.js:1011
msgid "least one keypair required"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2694
+#: htdocs/luci-static/resources/view/fchomo/node.js:2715
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:444
msgid "luci-app-tinyfilemanager is not installed, please install it first."
msgstr ""
@@ -4387,7 +4413,7 @@ msgid "metacubexd"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/global.js:515
-#: htdocs/luci-static/resources/view/fchomo/node.js:1203
+#: htdocs/luci-static/resources/view/fchomo/node.js:1217
msgid "mihomo IP stack (MIPS)"
msgstr ""
@@ -4397,7 +4423,7 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1576
#: htdocs/luci-static/resources/view/fchomo/client.js:1810
#: htdocs/luci-static/resources/view/fchomo/client.js:1866
-#: htdocs/luci-static/resources/view/fchomo/node.js:2299
+#: htdocs/luci-static/resources/view/fchomo/node.js:2320
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:258
msgid "mihomo config"
msgstr ""
@@ -4406,8 +4432,8 @@ msgstr ""
msgid "mlkem768x25519plus"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2152
-#: htdocs/luci-static/resources/view/fchomo/node.js:2531
+#: htdocs/luci-static/resources/view/fchomo/node.js:2173
+#: htdocs/luci-static/resources/view/fchomo/node.js:2552
msgid "mpTCP"
msgstr ""
@@ -4419,18 +4445,21 @@ msgstr ""
msgid "no-resolve"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1717
-#: htdocs/luci-static/resources/fchomo.js:1832
-#: htdocs/luci-static/resources/fchomo.js:1867
-#: htdocs/luci-static/resources/fchomo.js:1895
+#: htdocs/luci-static/resources/fchomo.js:1719
+#: htdocs/luci-static/resources/fchomo.js:1834
+#: htdocs/luci-static/resources/fchomo.js:1869
+#: htdocs/luci-static/resources/fchomo.js:1897
msgid "non-empty value"
msgstr ""
+#: htdocs/luci-static/resources/fchomo.js:271
#: htdocs/luci-static/resources/fchomo.js:420
#: htdocs/luci-static/resources/fchomo.js:434
#: htdocs/luci-static/resources/fchomo.js:446
-#: htdocs/luci-static/resources/view/fchomo/node.js:553
-#: htdocs/luci-static/resources/view/fchomo/node.js:573
+#: htdocs/luci-static/resources/fchomo/listeners.js:628
+#: htdocs/luci-static/resources/fchomo/listeners.js:631
+#: htdocs/luci-static/resources/view/fchomo/node.js:563
+#: htdocs/luci-static/resources/view/fchomo/node.js:583
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:335
msgid "none"
msgstr ""
@@ -4443,16 +4472,10 @@ msgstr ""
msgid "not included \",\""
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:271
-#: htdocs/luci-static/resources/fchomo/listeners.js:619
-#: htdocs/luci-static/resources/fchomo/listeners.js:622
-msgid "null"
-msgstr ""
-
-#: htdocs/luci-static/resources/fchomo/listeners.js:689
-#: htdocs/luci-static/resources/fchomo/listeners.js:699
-#: htdocs/luci-static/resources/view/fchomo/node.js:1277
-#: htdocs/luci-static/resources/view/fchomo/node.js:1289
+#: htdocs/luci-static/resources/fchomo/listeners.js:698
+#: htdocs/luci-static/resources/fchomo/listeners.js:717
+#: htdocs/luci-static/resources/view/fchomo/node.js:1291
+#: htdocs/luci-static/resources/view/fchomo/node.js:1312
msgid "obfs-simple"
msgstr ""
@@ -4464,32 +4487,32 @@ msgstr ""
msgid "only applies when %s is not %s."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1141
+#: htdocs/luci-static/resources/view/fchomo/node.js:1155
msgid "openssl-aes128-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1142
+#: htdocs/luci-static/resources/view/fchomo/node.js:1156
msgid "openssl-aes256-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1143
+#: htdocs/luci-static/resources/view/fchomo/node.js:1157
msgid "openssl-chacha20"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2512
+#: htdocs/luci-static/resources/view/fchomo/node.js:2533
msgid "override.override-expr"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2504
+#: htdocs/luci-static/resources/view/fchomo/node.js:2525
msgid "override.proxy-name"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:574
+#: htdocs/luci-static/resources/view/fchomo/node.js:584
msgid "packet addr (v2ray-core v5+)"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1356
-#: htdocs/luci-static/resources/view/fchomo/node.js:2005
+#: htdocs/luci-static/resources/fchomo/listeners.js:1374
+#: htdocs/luci-static/resources/view/fchomo/node.js:2026
msgid "packet-up"
msgstr ""
@@ -4498,8 +4521,8 @@ msgstr ""
msgid "poll"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1157
-#: htdocs/luci-static/resources/view/fchomo/node.js:1552
+#: htdocs/luci-static/resources/fchomo/listeners.js:1175
+#: htdocs/luci-static/resources/view/fchomo/node.js:1575
msgid "private key"
msgstr ""
@@ -4520,7 +4543,7 @@ msgstr ""
msgid "rule-set"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2077
+#: htdocs/luci-static/resources/view/fchomo/node.js:2098
msgid "smux"
msgstr ""
@@ -4533,17 +4556,17 @@ msgstr ""
msgid "src"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1354
-#: htdocs/luci-static/resources/view/fchomo/node.js:2003
+#: htdocs/luci-static/resources/fchomo/listeners.js:1372
+#: htdocs/luci-static/resources/view/fchomo/node.js:2024
msgid "stream-one"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1355
-#: htdocs/luci-static/resources/view/fchomo/node.js:2004
+#: htdocs/luci-static/resources/fchomo/listeners.js:1373
+#: htdocs/luci-static/resources/view/fchomo/node.js:2025
msgid "stream-up"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1371
+#: htdocs/luci-static/resources/fchomo/listeners.js:1389
msgid "stream-up server seconds"
msgstr ""
@@ -4555,11 +4578,11 @@ msgstr ""
msgid "sudoku-keypair"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1344
+#: htdocs/luci-static/resources/view/fchomo/node.js:1367
msgid "tls12"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1345
+#: htdocs/luci-static/resources/view/fchomo/node.js:1368
msgid "tls13"
msgstr ""
@@ -4575,35 +4598,35 @@ msgstr ""
msgid "unique identifier"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1904
+#: htdocs/luci-static/resources/fchomo.js:1906
msgid "unique value"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2547
+#: htdocs/luci-static/resources/view/fchomo/node.js:2568
msgid "up"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:400
-#: htdocs/luci-static/resources/fchomo/listeners.js:753
+#: htdocs/luci-static/resources/fchomo/listeners.js:771
#: htdocs/luci-static/resources/view/fchomo/node.js:515
-#: htdocs/luci-static/resources/view/fchomo/node.js:656
-#: htdocs/luci-static/resources/view/fchomo/node.js:1263
-#: htdocs/luci-static/resources/view/fchomo/node.js:1335
+#: htdocs/luci-static/resources/view/fchomo/node.js:666
+#: htdocs/luci-static/resources/view/fchomo/node.js:1277
+#: htdocs/luci-static/resources/view/fchomo/node.js:1358
msgid "v1"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:401
-#: htdocs/luci-static/resources/fchomo/listeners.js:754
+#: htdocs/luci-static/resources/fchomo/listeners.js:772
#: htdocs/luci-static/resources/view/fchomo/node.js:516
-#: htdocs/luci-static/resources/view/fchomo/node.js:1264
-#: htdocs/luci-static/resources/view/fchomo/node.js:1336
+#: htdocs/luci-static/resources/view/fchomo/node.js:1278
+#: htdocs/luci-static/resources/view/fchomo/node.js:1359
msgid "v2"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:402
-#: htdocs/luci-static/resources/fchomo/listeners.js:755
+#: htdocs/luci-static/resources/fchomo/listeners.js:773
#: htdocs/luci-static/resources/view/fchomo/node.js:517
-#: htdocs/luci-static/resources/view/fchomo/node.js:1337
+#: htdocs/luci-static/resources/view/fchomo/node.js:1360
msgid "v3"
msgstr ""
@@ -4617,42 +4640,47 @@ msgstr ""
msgid "v5"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1764
-#: htdocs/luci-static/resources/fchomo.js:1767
+#: htdocs/luci-static/resources/fchomo/listeners.js:405
+#: htdocs/luci-static/resources/view/fchomo/node.js:520
+msgid "v6"
+msgstr ""
+
+#: htdocs/luci-static/resources/fchomo.js:1766
+#: htdocs/luci-static/resources/fchomo.js:1769
msgid "valid JSON format"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1823
+#: htdocs/luci-static/resources/fchomo.js:1825
msgid "valid SHA256 string with %d characters"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1789
-#: htdocs/luci-static/resources/fchomo.js:1792
+#: htdocs/luci-static/resources/fchomo.js:1791
+#: htdocs/luci-static/resources/fchomo.js:1794
msgid "valid URL"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1814
+#: htdocs/luci-static/resources/fchomo.js:1816
msgid "valid base64 key with %d characters"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1882
-#: htdocs/luci-static/resources/fchomo.js:1888
+#: htdocs/luci-static/resources/fchomo.js:1884
+#: htdocs/luci-static/resources/fchomo.js:1890
msgid "valid format: 2x, 2p, 4v"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1805
+#: htdocs/luci-static/resources/fchomo.js:1807
msgid "valid hex string with %d characters"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1869
+#: htdocs/luci-static/resources/fchomo.js:1871
msgid "valid key length with %d characters"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1727
+#: htdocs/luci-static/resources/fchomo.js:1729
msgid "valid port value"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1777
+#: htdocs/luci-static/resources/fchomo.js:1779
msgid "valid uuid"
msgstr ""
@@ -4668,7 +4696,7 @@ msgstr ""
msgid "xchacha20-ietf-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1137
+#: htdocs/luci-static/resources/view/fchomo/node.js:1151
msgid "xor"
msgstr ""
@@ -4676,7 +4704,7 @@ msgstr ""
msgid "yacd-meta"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2078
+#: htdocs/luci-static/resources/view/fchomo/node.js:2099
msgid "yamux"
msgstr ""
@@ -4684,14 +4712,14 @@ msgstr ""
msgid "zashboard"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:554
+#: htdocs/luci-static/resources/view/fchomo/node.js:564
msgid "zero"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1544
+#: htdocs/luci-static/resources/fchomo.js:1547
msgid "🔗"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1523
+#: htdocs/luci-static/resources/fchomo.js:1526
msgid "🡇"
msgstr ""
diff --git a/luci-app-fchomo/po/zh_Hans/fchomo.po b/luci-app-fchomo/po/zh_Hans/fchomo.po
index c6d18dcf1..74b92b4e3 100644
--- a/luci-app-fchomo/po/zh_Hans/fchomo.po
+++ b/luci-app-fchomo/po/zh_Hans/fchomo.po
@@ -8,12 +8,12 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
-#: htdocs/luci-static/resources/view/fchomo/node.js:962
+#: htdocs/luci-static/resources/view/fchomo/node.js:972
msgid "%s Hostname"
msgstr "%s 主机名称"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1686
-#: htdocs/luci-static/resources/view/fchomo/node.js:1696
+#: htdocs/luci-static/resources/view/fchomo/node.js:1708
+#: htdocs/luci-static/resources/view/fchomo/node.js:1718
msgid "%s UDP port. 0 selects an available port."
msgstr "%s UDP 端口。0 自动选择一个可用端口。"
@@ -21,7 +21,7 @@ msgstr "%s UDP 端口。0 自动选择一个可用端口。"
msgid "%s log"
msgstr "%s 日志"
-#: htdocs/luci-static/resources/view/fchomo/node.js:815
+#: htdocs/luci-static/resources/view/fchomo/node.js:825
msgid "%s of the %s used to receiving remote debugging log."
msgstr "%s,用于接收远程调试日志的 %s 的。"
@@ -34,23 +34,23 @@ msgstr "%s,用于接收远程调试日志的 %s 的。"
msgid "%s ports"
msgstr "%s 端口"
-#: htdocs/luci-static/resources/fchomo.js:785
#: htdocs/luci-static/resources/fchomo.js:788
+#: htdocs/luci-static/resources/fchomo.js:791
#: htdocs/luci-static/resources/view/fchomo/client.js:318
msgid "(Imported)"
msgstr "(已导入)"
-#: htdocs/luci-static/resources/fchomo.js:1488
-#: htdocs/luci-static/resources/fchomo.js:1494
-#: htdocs/luci-static/resources/fchomo/listeners.js:1160
-#: htdocs/luci-static/resources/fchomo/listeners.js:1168
-#: htdocs/luci-static/resources/fchomo/listeners.js:1177
+#: htdocs/luci-static/resources/fchomo.js:1491
+#: htdocs/luci-static/resources/fchomo.js:1497
+#: htdocs/luci-static/resources/fchomo/listeners.js:1178
+#: htdocs/luci-static/resources/fchomo/listeners.js:1186
+#: htdocs/luci-static/resources/fchomo/listeners.js:1195
#: htdocs/luci-static/resources/view/fchomo/global.js:572
#: htdocs/luci-static/resources/view/fchomo/global.js:578
-#: htdocs/luci-static/resources/view/fchomo/node.js:1527
-#: htdocs/luci-static/resources/view/fchomo/node.js:1533
-#: htdocs/luci-static/resources/view/fchomo/node.js:1541
-#: htdocs/luci-static/resources/view/fchomo/node.js:1547
+#: htdocs/luci-static/resources/view/fchomo/node.js:1550
+#: htdocs/luci-static/resources/view/fchomo/node.js:1556
+#: htdocs/luci-static/resources/view/fchomo/node.js:1564
+#: htdocs/luci-static/resources/view/fchomo/node.js:1570
msgid "(mTLS)"
msgstr ""
@@ -72,10 +72,10 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1113
#: htdocs/luci-static/resources/view/fchomo/client.js:1369
#: htdocs/luci-static/resources/view/fchomo/node.js:305
-#: htdocs/luci-static/resources/view/fchomo/node.js:2735
-#: htdocs/luci-static/resources/view/fchomo/node.js:2746
-#: htdocs/luci-static/resources/view/fchomo/node.js:2765
-#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2756
+#: htdocs/luci-static/resources/view/fchomo/node.js:2767
+#: htdocs/luci-static/resources/view/fchomo/node.js:2786
+#: htdocs/luci-static/resources/view/fchomo/node.js:2797
msgid "-- Please choose --"
msgstr "-- 请选择 --"
@@ -104,7 +104,7 @@ msgstr ""
msgid "2022-blake3-chacha20-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1697
+#: htdocs/luci-static/resources/view/fchomo/node.js:1719
msgid "-1 disables it."
msgstr "-1 表示禁用它。"
@@ -112,11 +112,11 @@ msgstr "-1 表示禁用它。"
msgid "0 or 1 only."
msgstr "仅限 0 或 1。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1138
-#: htdocs/luci-static/resources/fchomo/listeners.js:1153
-#: htdocs/luci-static/resources/fchomo/listeners.js:1178
-#: htdocs/luci-static/resources/view/fchomo/node.js:1534
-#: htdocs/luci-static/resources/view/fchomo/node.js:1548
+#: htdocs/luci-static/resources/fchomo/listeners.js:1156
+#: htdocs/luci-static/resources/fchomo/listeners.js:1171
+#: htdocs/luci-static/resources/fchomo/listeners.js:1196
+#: htdocs/luci-static/resources/view/fchomo/node.js:1557
+#: htdocs/luci-static/resources/view/fchomo/node.js:1571
msgid "Save your configuration before uploading files!"
msgstr "上传文件前请先保存配置!"
@@ -191,7 +191,7 @@ msgstr "ASCII 数据流"
msgid "ASN version"
msgstr "ASN 版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:983
+#: htdocs/luci-static/resources/view/fchomo/node.js:993
msgid "Accept routes"
msgstr "接受路由"
@@ -220,11 +220,11 @@ msgstr "新增 节点"
msgid "Add a inbound"
msgstr "新增 入站"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2196
+#: htdocs/luci-static/resources/view/fchomo/node.js:2217
msgid "Add a provider"
msgstr "新增 供应商"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2709
+#: htdocs/luci-static/resources/view/fchomo/node.js:2730
msgid "Add a proxy chain"
msgstr "新增 代理链"
@@ -248,15 +248,15 @@ msgstr "新增 服务器"
msgid "Add a sub rule"
msgstr "新增 子规则"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2493
+#: htdocs/luci-static/resources/view/fchomo/node.js:2514
msgid "Add prefix"
msgstr "添加前缀"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2497
+#: htdocs/luci-static/resources/view/fchomo/node.js:2518
msgid "Add suffix"
msgstr "添加后缀"
-#: htdocs/luci-static/resources/view/fchomo/node.js:870
+#: htdocs/luci-static/resources/view/fchomo/node.js:880
msgid "Add the base64 text of the planet file here."
msgstr "在此处添加行星文件的 base64 文本。"
@@ -265,7 +265,7 @@ msgstr "在此处添加行星文件的 base64 文本。"
msgid "Address"
msgstr "地址"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1160
+#: htdocs/luci-static/resources/view/fchomo/node.js:1174
msgid "After disabling, communication will only be possible via relay."
msgstr "禁用后,只能通过中继进行通信。"
@@ -294,7 +294,7 @@ msgstr "允许所有"
msgid "All ports"
msgstr "所有端口"
-#: htdocs/luci-static/resources/view/fchomo/node.js:994
+#: htdocs/luci-static/resources/view/fchomo/node.js:1004
msgid "Allow LAN access"
msgstr "允许局域网访问"
@@ -305,19 +305,19 @@ msgid ""
msgstr ""
"允许从私有网络访问。要从公共网站访问私有网络上的 API,则必须启用。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:995
+#: htdocs/luci-static/resources/view/fchomo/node.js:1005
msgid "Allow access to the local LAN via the exit node."
msgstr "允许通过出口节点访问本地局域网。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1061
+#: htdocs/luci-static/resources/fchomo/listeners.js:1079
msgid "Allow insecure connections"
msgstr "允许不安全的连接"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1148
+#: htdocs/luci-static/resources/view/fchomo/node.js:1162
msgid "Allow this node to be an exit node."
msgstr "允许此节点成为出口节点。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:943
+#: htdocs/luci-static/resources/view/fchomo/node.js:953
msgid "Allowed IPs"
msgstr "允许的 IP"
@@ -329,8 +329,8 @@ msgstr "已是最新版本。"
msgid "Already in updating."
msgstr "已在更新中。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:424
-#: htdocs/luci-static/resources/view/fchomo/node.js:544
+#: htdocs/luci-static/resources/fchomo/listeners.js:433
+#: htdocs/luci-static/resources/view/fchomo/node.js:554
msgid "Alter ID"
msgstr "额外 ID"
@@ -343,11 +343,11 @@ msgstr ""
msgid "Application version"
msgstr "应用版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:978
+#: htdocs/luci-static/resources/view/fchomo/node.js:988
msgid "As ephemeral node"
msgstr "作为临时节点"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1147
+#: htdocs/luci-static/resources/view/fchomo/node.js:1161
msgid "As exit node"
msgstr "作为出口节点"
@@ -360,35 +360,35 @@ msgstr "作为 dnsmasq 的最优先上游"
msgid "As the TOP upstream of dnsmasq."
msgstr "作为 dnsmasq 的最优先上游。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:472
+#: htdocs/luci-static/resources/fchomo/listeners.js:481
msgid "Auth timeout"
msgstr "认证超时"
-#: htdocs/luci-static/resources/view/fchomo/node.js:566
+#: htdocs/luci-static/resources/view/fchomo/node.js:576
msgid "Authenticated length"
msgstr "认证长度"
-#: htdocs/luci-static/resources/view/fchomo/node.js:973
+#: htdocs/luci-static/resources/view/fchomo/node.js:983
msgid "Authentication key"
msgstr "验证密钥"
#: htdocs/luci-static/resources/fchomo/listeners.js:376
-#: htdocs/luci-static/resources/fchomo/listeners.js:1353
+#: htdocs/luci-static/resources/fchomo/listeners.js:1371
#: htdocs/luci-static/resources/view/fchomo/global.js:423
#: htdocs/luci-static/resources/view/fchomo/node.js:467
#: htdocs/luci-static/resources/view/fchomo/node.js:491
-#: htdocs/luci-static/resources/view/fchomo/node.js:850
-#: htdocs/luci-static/resources/view/fchomo/node.js:1202
-#: htdocs/luci-static/resources/view/fchomo/node.js:2002
+#: htdocs/luci-static/resources/view/fchomo/node.js:860
+#: htdocs/luci-static/resources/view/fchomo/node.js:1216
+#: htdocs/luci-static/resources/view/fchomo/node.js:2023
msgid "Auto"
msgstr "自动"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1815
+#: htdocs/luci-static/resources/view/fchomo/node.js:1836
msgid "Auto Enable when %s is empty."
msgstr "当 %s 为空时自动启用。"
#: htdocs/luci-static/resources/fchomo/listeners.js:139
-#: htdocs/luci-static/resources/view/fchomo/node.js:1618
+#: htdocs/luci-static/resources/view/fchomo/node.js:1641
msgid "Auto configure firewall"
msgstr "自动配置防火墙"
@@ -400,8 +400,8 @@ msgstr "自动更新"
msgid "Auto update resources."
msgstr "自动更新资源文件。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:653
-#: htdocs/luci-static/resources/view/fchomo/node.js:1227
+#: htdocs/luci-static/resources/fchomo/listeners.js:662
+#: htdocs/luci-static/resources/view/fchomo/node.js:1241
msgid "BBR profile"
msgstr "BBR 配置文件"
@@ -409,19 +409,19 @@ msgstr "BBR 配置文件"
msgid "Baidu"
msgstr "百度"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1002
+#: htdocs/luci-static/resources/view/fchomo/node.js:1012
msgid "Base64 encoded ECDSA private key on the NIST P-256 curve."
msgstr "基于 NIST P-256 曲线的 Base64 编码 ECDSA 私钥。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1010
+#: htdocs/luci-static/resources/view/fchomo/node.js:1020
msgid "Base64 encoded ECDSA public key on the NIST P-256 curve."
msgstr "基于 NIST P-256 曲线的 Base64 编码 ECDSA 公钥。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1095
+#: htdocs/luci-static/resources/view/fchomo/node.js:1108
msgid "Base64 encoded X25519 private key."
msgstr "Base64 编码的 X25519 私钥。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1111
+#: htdocs/luci-static/resources/view/fchomo/node.js:1125
msgid "Base64 encoded X25519 public key."
msgstr "Base64 编码的 X25519 公钥。"
@@ -443,13 +443,13 @@ msgid "Binary mrs"
msgstr "二进制 mrs"
#: htdocs/luci-static/resources/view/fchomo/global.js:766
-#: htdocs/luci-static/resources/view/fchomo/node.js:2163
-#: htdocs/luci-static/resources/view/fchomo/node.js:2582
+#: htdocs/luci-static/resources/view/fchomo/node.js:2184
+#: htdocs/luci-static/resources/view/fchomo/node.js:2603
msgid "Bind interface"
msgstr "绑定接口"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2164
-#: htdocs/luci-static/resources/view/fchomo/node.js:2583
+#: htdocs/luci-static/resources/view/fchomo/node.js:2185
+#: htdocs/luci-static/resources/view/fchomo/node.js:2604
msgid "Bind outbound interface."
msgstr "绑定出站接口。"
@@ -514,24 +514,24 @@ msgstr "CORS 允许私有网络"
msgid "CORS allowed origins, * will be used if empty."
msgstr "CORS 允许的来源,留空则使用 *。"
-#: htdocs/luci-static/resources/fchomo.js:901
+#: htdocs/luci-static/resources/fchomo.js:904
msgid "Cancel"
msgstr "取消"
-#: htdocs/luci-static/resources/fchomo.js:1468
-#: htdocs/luci-static/resources/view/fchomo/node.js:1507
+#: htdocs/luci-static/resources/fchomo.js:1471
+#: htdocs/luci-static/resources/view/fchomo/node.js:1530
msgid "Cert fingerprint"
msgstr "证书指纹"
-#: htdocs/luci-static/resources/fchomo.js:1469
-#: htdocs/luci-static/resources/view/fchomo/node.js:1508
+#: htdocs/luci-static/resources/fchomo.js:1472
+#: htdocs/luci-static/resources/view/fchomo/node.js:1531
msgid ""
"Certificate fingerprint. Used to implement SSL Pinning and prevent MitM."
msgstr "证书指纹。用于实现 SSL证书固定 并防止 MitM。"
-#: htdocs/luci-static/resources/fchomo.js:1488
-#: htdocs/luci-static/resources/fchomo/listeners.js:1115
-#: htdocs/luci-static/resources/view/fchomo/node.js:1527
+#: htdocs/luci-static/resources/fchomo.js:1491
+#: htdocs/luci-static/resources/fchomo/listeners.js:1133
+#: htdocs/luci-static/resources/view/fchomo/node.js:1550
msgid "Certificate path"
msgstr "证书路径"
@@ -571,7 +571,7 @@ msgstr "大陆域名列表版本"
#: htdocs/luci-static/resources/fchomo/listeners.js:282
#: htdocs/luci-static/resources/view/fchomo/node.js:340
#: htdocs/luci-static/resources/view/fchomo/node.js:399
-#: htdocs/luci-static/resources/view/fchomo/node.js:550
+#: htdocs/luci-static/resources/view/fchomo/node.js:560
msgid "Chipher"
msgstr "加密方法"
@@ -592,27 +592,27 @@ msgstr ""
"点击此处下载"
"最新的初始包。"
-#: htdocs/luci-static/resources/fchomo.js:1489
-#: htdocs/luci-static/resources/fchomo.js:1495
-#: htdocs/luci-static/resources/fchomo/listeners.js:869
-#: htdocs/luci-static/resources/fchomo/listeners.js:1169
+#: htdocs/luci-static/resources/fchomo.js:1492
+#: htdocs/luci-static/resources/fchomo.js:1498
+#: htdocs/luci-static/resources/fchomo/listeners.js:887
+#: htdocs/luci-static/resources/fchomo/listeners.js:1187
#: htdocs/luci-static/resources/view/fchomo/global.js:579
-#: htdocs/luci-static/resources/view/fchomo/node.js:1392
-#: htdocs/luci-static/resources/view/fchomo/node.js:1528
-#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/view/fchomo/node.js:1415
+#: htdocs/luci-static/resources/view/fchomo/node.js:1551
+#: htdocs/luci-static/resources/view/fchomo/node.js:1565
#: root/usr/share/luci/menu.d/luci-app-fchomo.json:22
msgid "Client"
msgstr "客户端"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1168
+#: htdocs/luci-static/resources/fchomo/listeners.js:1186
msgid "Client Auth Certificate path"
msgstr "客户端认证证书路径"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1160
+#: htdocs/luci-static/resources/fchomo/listeners.js:1178
msgid "Client Auth type"
msgstr "客户端认证类型"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1573
+#: htdocs/luci-static/resources/view/fchomo/node.js:1596
msgid "Client fingerprint"
msgstr "客户端指纹"
@@ -620,15 +620,15 @@ msgstr "客户端指纹"
msgid "Client key"
msgstr "客户端密钥"
-#: htdocs/luci-static/resources/view/fchomo/node.js:603
+#: htdocs/luci-static/resources/view/fchomo/node.js:613
msgid "Client metadata"
msgstr "客户端元数据"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1094
+#: htdocs/luci-static/resources/view/fchomo/node.js:1107
msgid "Client private key"
msgstr "客户端私钥"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1110
+#: htdocs/luci-static/resources/view/fchomo/node.js:1124
msgid "Client public key"
msgstr "客户端公钥"
@@ -636,8 +636,8 @@ msgstr "客户端公钥"
msgid "Client status"
msgstr "客户端状态"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1771
-#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1792
+#: htdocs/luci-static/resources/view/fchomo/node.js:1824
msgid "Cloudflare WARP"
msgstr ""
@@ -650,18 +650,18 @@ msgstr "收集数据中..."
msgid "Common ports (bypass P2P traffic)"
msgstr "常用端口(绕过 P2P 流量)"
-#: htdocs/luci-static/resources/fchomo.js:1661
+#: htdocs/luci-static/resources/fchomo.js:1663
msgid "Complete"
msgstr "完成"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1040
+#: htdocs/luci-static/resources/view/fchomo/node.js:1050
msgid "Configuration Document"
msgstr "配置文档"
-#: htdocs/luci-static/resources/fchomo/listeners.js:645
+#: htdocs/luci-static/resources/fchomo/listeners.js:654
#: htdocs/luci-static/resources/view/fchomo/global.js:549
-#: htdocs/luci-static/resources/view/fchomo/node.js:1210
-#: htdocs/luci-static/resources/view/fchomo/node.js:1218
+#: htdocs/luci-static/resources/view/fchomo/node.js:1224
+#: htdocs/luci-static/resources/view/fchomo/node.js:1232
msgid "Congestion controller"
msgstr "拥塞控制器"
@@ -669,12 +669,12 @@ msgstr "拥塞控制器"
msgid "Connection check"
msgstr "连接检查"
-#: htdocs/luci-static/resources/view/fchomo/node.js:524
+#: htdocs/luci-static/resources/view/fchomo/node.js:525
msgid "Connection reuse"
msgstr "连接复用"
-#: htdocs/luci-static/resources/fchomo/listeners.js:590
-#: htdocs/luci-static/resources/view/fchomo/node.js:784
+#: htdocs/luci-static/resources/fchomo/listeners.js:599
+#: htdocs/luci-static/resources/view/fchomo/node.js:794
msgid "Connection-level receive window size"
msgstr "连接级接收窗口大小"
@@ -682,19 +682,19 @@ msgstr "连接级接收窗口大小"
msgid "Conservative"
msgstr "保守"
-#: htdocs/luci-static/resources/fchomo.js:770
+#: htdocs/luci-static/resources/fchomo.js:773
msgid "Content copied to clipboard!"
msgstr "内容已复制到剪贴板!"
#: htdocs/luci-static/resources/view/fchomo/client.js:698
-#: htdocs/luci-static/resources/view/fchomo/node.js:2353
-#: htdocs/luci-static/resources/view/fchomo/node.js:2379
+#: htdocs/luci-static/resources/view/fchomo/node.js:2374
+#: htdocs/luci-static/resources/view/fchomo/node.js:2400
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:359
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:385
msgid "Content will not be verified, Please make sure you enter it correctly."
msgstr "内容将不会被验证,请确保输入正确。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2352
+#: htdocs/luci-static/resources/view/fchomo/node.js:2373
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:358
msgid "Contents"
msgstr "内容"
@@ -703,11 +703,11 @@ msgstr "内容"
msgid "Contents have been saved."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:967
+#: htdocs/luci-static/resources/view/fchomo/node.js:977
msgid "Control server"
msgstr "控制服务器"
-#: htdocs/luci-static/resources/fchomo.js:772
+#: htdocs/luci-static/resources/fchomo.js:775
msgid "Copy"
msgstr "复制"
@@ -719,7 +719,7 @@ msgstr "核心版本"
msgid "Cron expression"
msgstr "Cron 表达式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:968
+#: htdocs/luci-static/resources/view/fchomo/node.js:978
msgid "Custom %s control server."
msgstr "自定义 %s 控制服务器。"
@@ -727,7 +727,7 @@ msgstr "自定义 %s 控制服务器。"
msgid "Custom Direct List"
msgstr "自定义直连列表"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2484
+#: htdocs/luci-static/resources/view/fchomo/node.js:2505
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:431
msgid "Custom HTTP header."
msgstr "自定义 HTTP header。"
@@ -753,7 +753,7 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1831
#: htdocs/luci-static/resources/view/fchomo/client.js:1840
#: htdocs/luci-static/resources/view/fchomo/client.js:1915
-#: htdocs/luci-static/resources/view/fchomo/node.js:1174
+#: htdocs/luci-static/resources/view/fchomo/node.js:1188
msgid "DNS policy"
msgstr "DNS 策略"
@@ -764,8 +764,8 @@ msgstr " DNS 端口"
#: htdocs/luci-static/resources/view/fchomo/client.js:907
#: htdocs/luci-static/resources/view/fchomo/client.js:1524
#: htdocs/luci-static/resources/view/fchomo/client.js:1533
-#: htdocs/luci-static/resources/view/fchomo/node.js:1173
-#: htdocs/luci-static/resources/view/fchomo/node.js:1869
+#: htdocs/luci-static/resources/view/fchomo/node.js:1187
+#: htdocs/luci-static/resources/view/fchomo/node.js:1890
msgid "DNS server"
msgstr "DNS 服务器"
@@ -782,10 +782,15 @@ msgid "Dashboard version"
msgstr "面板版本"
#: htdocs/luci-static/resources/fchomo.js:131
-#: htdocs/luci-static/resources/view/fchomo/node.js:825
+#: htdocs/luci-static/resources/view/fchomo/node.js:835
msgid "Debug"
msgstr "调试"
+#: htdocs/luci-static/resources/fchomo/listeners.js:412
+#: htdocs/luci-static/resources/view/fchomo/node.js:533
+msgid "Default"
+msgstr "默认"
+
#: htdocs/luci-static/resources/view/fchomo/client.js:58
msgid "Default DNS (issued by WAN)"
msgstr "默认 DNS(由 WAN 下发)"
@@ -800,7 +805,7 @@ msgstr "默认 DNS 服务器"
msgid "Default selected"
msgstr "默认选中"
-#: htdocs/luci-static/resources/fchomo/listeners.js:562
+#: htdocs/luci-static/resources/fchomo/listeners.js:571
msgid "Default version, Support %s."
msgstr "默认版本,支持 %s。"
@@ -808,15 +813,15 @@ msgstr "默认版本,支持 %s。"
msgid "Derive from priv-key"
msgstr "从私钥派生"
-#: htdocs/luci-static/resources/view/fchomo/node.js:944
+#: htdocs/luci-static/resources/view/fchomo/node.js:954
msgid "Destination addresses allowed to be forwarded via Wireguard."
msgstr "允许通过 WireGuard 转发的目的地址"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2732
+#: htdocs/luci-static/resources/view/fchomo/node.js:2753
msgid "Destination provider"
msgstr "落地供应商"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2743
+#: htdocs/luci-static/resources/view/fchomo/node.js:2764
msgid "Destination proxy node"
msgstr "落地代理节点"
@@ -824,8 +829,8 @@ msgstr "落地代理节点"
msgid "Dial fields"
msgstr "拨号字段"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2755
-#: htdocs/luci-static/resources/view/fchomo/node.js:2785
+#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2806
msgid "Different chain head/tail"
msgstr "不同的链头/链尾"
@@ -845,10 +850,10 @@ msgstr "直连 IPv6 地址"
msgid "Direct MAC-s"
msgstr "直连 MAC 地址"
-#: htdocs/luci-static/resources/fchomo/listeners.js:500
+#: htdocs/luci-static/resources/fchomo/listeners.js:509
#: htdocs/luci-static/resources/view/fchomo/global.js:424
-#: htdocs/luci-static/resources/view/fchomo/node.js:718
-#: htdocs/luci-static/resources/view/fchomo/node.js:852
+#: htdocs/luci-static/resources/view/fchomo/node.js:728
+#: htdocs/luci-static/resources/view/fchomo/node.js:862
msgid "Disable"
msgstr "禁用"
@@ -864,11 +869,11 @@ msgstr "禁用 quic-go 的 通用分段卸载(GSO)"
msgid "Disable ICMP Forwarding"
msgstr "禁用 ICMP 转发"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1159
+#: htdocs/luci-static/resources/view/fchomo/node.js:1173
msgid "Disable P2P"
msgstr "禁用 P2P"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1448
+#: htdocs/luci-static/resources/view/fchomo/node.js:1471
msgid "Disable SNI"
msgstr "禁用 SNI"
@@ -897,32 +902,32 @@ msgstr ""
msgid "Domain"
msgstr "域名"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1449
+#: htdocs/luci-static/resources/view/fchomo/node.js:1472
msgid "Donot send server name in ClientHello."
msgstr "不要在 ClientHello 中发送服务器名称。"
-#: htdocs/luci-static/resources/fchomo.js:1481
+#: htdocs/luci-static/resources/fchomo.js:1484
#: htdocs/luci-static/resources/view/fchomo/client.js:1676
-#: htdocs/luci-static/resources/view/fchomo/node.js:1520
-#: htdocs/luci-static/resources/view/fchomo/node.js:2566
+#: htdocs/luci-static/resources/view/fchomo/node.js:1543
+#: htdocs/luci-static/resources/view/fchomo/node.js:2587
msgid "Donot verifying server certificate."
msgstr "不验证服务器证书。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1405
-#: htdocs/luci-static/resources/view/fchomo/node.js:2140
+#: htdocs/luci-static/resources/fchomo/listeners.js:1423
+#: htdocs/luci-static/resources/view/fchomo/node.js:2161
msgid "Download bandwidth"
msgstr "下载带宽"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1406
-#: htdocs/luci-static/resources/view/fchomo/node.js:2141
+#: htdocs/luci-static/resources/fchomo/listeners.js:1424
+#: htdocs/luci-static/resources/view/fchomo/node.js:2162
msgid "Download bandwidth in Mbps."
msgstr "下载带宽(单位:Mbps)。"
-#: htdocs/luci-static/resources/fchomo.js:1518
+#: htdocs/luci-static/resources/fchomo.js:1521
msgid "Download failed: %s"
msgstr "下载失败: %s"
-#: htdocs/luci-static/resources/fchomo.js:1514
+#: htdocs/luci-static/resources/fchomo.js:1517
msgid "Download successful."
msgstr "下载成功。"
@@ -934,16 +939,16 @@ msgstr "目的地 IP"
msgid "Dual stack"
msgstr "双栈"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1567
+#: htdocs/luci-static/resources/view/fchomo/node.js:1590
msgid "ECH HTTPS record query servername"
msgstr "ECH HTTPS 记录查询域名"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1226
-#: htdocs/luci-static/resources/view/fchomo/node.js:1561
+#: htdocs/luci-static/resources/fchomo/listeners.js:1244
+#: htdocs/luci-static/resources/view/fchomo/node.js:1584
msgid "ECH config"
msgstr "ECH 配置"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1185
+#: htdocs/luci-static/resources/fchomo/listeners.js:1203
msgid "ECH key"
msgstr "ECH 密钥"
@@ -959,11 +964,11 @@ msgstr "EDNS 客户端子网"
msgid "ETag support"
msgstr "ETag 支持"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1980
+#: htdocs/luci-static/resources/view/fchomo/node.js:2001
msgid "Early Data first packet length limit."
msgstr "前置数据长度阈值"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1986
+#: htdocs/luci-static/resources/view/fchomo/node.js:2007
msgid "Early Data header name"
msgstr "前置数据标头"
@@ -983,7 +988,7 @@ msgstr "编辑出站"
msgid "Edit ruleset"
msgstr "编辑规则集"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2350
+#: htdocs/luci-static/resources/view/fchomo/node.js:2371
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:356
msgid "Editer"
msgstr "编辑器"
@@ -1007,15 +1012,15 @@ msgstr "为空时回退"
#: htdocs/luci-static/resources/view/fchomo/global.js:422
#: htdocs/luci-static/resources/view/fchomo/global.js:712
#: htdocs/luci-static/resources/view/fchomo/node.js:267
-#: htdocs/luci-static/resources/view/fchomo/node.js:2323
-#: htdocs/luci-static/resources/view/fchomo/node.js:2605
-#: htdocs/luci-static/resources/view/fchomo/node.js:2719
+#: htdocs/luci-static/resources/view/fchomo/node.js:2344
+#: htdocs/luci-static/resources/view/fchomo/node.js:2626
+#: htdocs/luci-static/resources/view/fchomo/node.js:2740
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:283
#: htdocs/luci-static/resources/view/fchomo/server.js:49
msgid "Enable"
msgstr "启用"
-#: htdocs/luci-static/resources/view/fchomo/node.js:672
+#: htdocs/luci-static/resources/view/fchomo/node.js:682
msgid ""
"Enable 0-RTT QUIC connection handshake on the client side. This is not "
"impacting much on the performance, as the protocol is fully multiplexed.
强烈建议禁用此功能,因为它容易受到重放攻击。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:671
+#: htdocs/luci-static/resources/view/fchomo/node.js:681
msgid "Enable 0-RTT handshake"
msgstr "启用 0-RTT 握手"
@@ -1036,33 +1041,33 @@ msgstr ""
"为出站连接启用 IP4P 转换"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1555
+#: htdocs/luci-static/resources/view/fchomo/node.js:1578
msgid "Enable ECH"
msgstr "启用 ECH"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1165
+#: htdocs/luci-static/resources/view/fchomo/node.js:1179
msgid "Enable MagicDNS"
msgstr "启用 MagicDNS"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1393
-#: htdocs/luci-static/resources/view/fchomo/node.js:2128
+#: htdocs/luci-static/resources/fchomo/listeners.js:1411
+#: htdocs/luci-static/resources/view/fchomo/node.js:2149
msgid "Enable TCP Brutal"
msgstr "启用 TCP Brutal"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1394
-#: htdocs/luci-static/resources/view/fchomo/node.js:2129
+#: htdocs/luci-static/resources/fchomo/listeners.js:1412
+#: htdocs/luci-static/resources/view/fchomo/node.js:2150
msgid "Enable TCP Brutal congestion control algorithm"
msgstr "启用 TCP Brutal 拥塞控制算法。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1130
+#: htdocs/luci-static/resources/view/fchomo/node.js:1144
msgid "Enable encryption"
msgstr "启用加密"
-#: htdocs/luci-static/resources/view/fchomo/node.js:666
+#: htdocs/luci-static/resources/view/fchomo/node.js:676
msgid "Enable fast open"
msgstr "启用 Fast open"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2117
+#: htdocs/luci-static/resources/view/fchomo/node.js:2138
msgid "Enable multiplexing only for TCP."
msgstr "仅为 TCP 启用多路复用。"
@@ -1071,37 +1076,37 @@ msgstr "仅为 TCP 启用多路复用。"
msgid "Enable obfuscate for downlink"
msgstr "启用下行链路混淆"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1388
-#: htdocs/luci-static/resources/view/fchomo/node.js:2111
+#: htdocs/luci-static/resources/fchomo/listeners.js:1406
+#: htdocs/luci-static/resources/view/fchomo/node.js:2132
msgid "Enable padding"
msgstr "启用填充"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2122
+#: htdocs/luci-static/resources/view/fchomo/node.js:2143
msgid "Enable statistic"
msgstr "启用统计"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1257
-#: htdocs/luci-static/resources/view/fchomo/node.js:2542
+#: htdocs/luci-static/resources/view/fchomo/node.js:1271
+#: htdocs/luci-static/resources/view/fchomo/node.js:2563
msgid ""
"Enable the SUoT protocol, requires server support. Conflict with Multiplex."
msgstr "启用 SUoT 协议,需要服务端支持。与多路复用冲突。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:507
-#: htdocs/luci-static/resources/view/fchomo/node.js:725
+#: htdocs/luci-static/resources/fchomo/listeners.js:516
+#: htdocs/luci-static/resources/view/fchomo/node.js:735
msgid ""
"Enabling obfuscation will make the server incompatible with standard QUIC "
"connections, losing the ability to masquerade with HTTP/3."
msgstr "启用混淆将使服务器与标准的 QUIC 连接不兼容,失去 HTTP/3 伪装的能力。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:843
+#: htdocs/luci-static/resources/view/fchomo/node.js:853
msgid "Encrypted Hello"
msgstr "加密 Hello"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1135
+#: htdocs/luci-static/resources/view/fchomo/node.js:1149
msgid "Encryption algorithm"
msgstr "加密算法"
-#: htdocs/luci-static/resources/fchomo/listeners.js:832
+#: htdocs/luci-static/resources/fchomo/listeners.js:850
msgid "Encryption method"
msgstr "加密方法"
@@ -1124,7 +1129,7 @@ msgid ""
"if empty."
msgstr "超过此限制将会触发强制健康检查。留空则使用 5。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2663
+#: htdocs/luci-static/resources/view/fchomo/node.js:2684
msgid "Exclude matched node types."
msgstr "排除匹配的节点类型。"
@@ -1137,15 +1142,15 @@ msgstr ""
"rel=\"noreferrer noopener\">此处。"
#: htdocs/luci-static/resources/view/fchomo/client.js:1251
-#: htdocs/luci-static/resources/view/fchomo/node.js:2656
+#: htdocs/luci-static/resources/view/fchomo/node.js:2677
msgid "Exclude nodes that meet keywords or regexps."
msgstr "排除匹配关键词或表达式的节点。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:989
+#: htdocs/luci-static/resources/view/fchomo/node.js:999
msgid "Exit node"
msgstr "出口节点"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1115
+#: htdocs/luci-static/resources/view/fchomo/node.js:1129
msgid "Exit nodes"
msgstr "出口节点"
@@ -1154,46 +1159,46 @@ msgid "Expand/Collapse result"
msgstr "展开/收起 结果"
#: htdocs/luci-static/resources/view/fchomo/client.js:1194
-#: htdocs/luci-static/resources/view/fchomo/node.js:2641
+#: htdocs/luci-static/resources/view/fchomo/node.js:2662
msgid "Expected HTTP code. 204 will be used if empty."
msgstr "预期的 HTTP code。留空则使用 204。"
#: htdocs/luci-static/resources/view/fchomo/client.js:1196
-#: htdocs/luci-static/resources/view/fchomo/node.js:2643
+#: htdocs/luci-static/resources/view/fchomo/node.js:2664
msgid "Expected status"
msgstr "预期状态"
#: htdocs/luci-static/resources/fchomo.js:529
#: htdocs/luci-static/resources/fchomo.js:532
#: htdocs/luci-static/resources/fchomo.js:535
-#: htdocs/luci-static/resources/fchomo.js:1678
-#: htdocs/luci-static/resources/fchomo.js:1686
-#: htdocs/luci-static/resources/fchomo.js:1694
-#: htdocs/luci-static/resources/fchomo.js:1717
-#: htdocs/luci-static/resources/fchomo.js:1720
-#: htdocs/luci-static/resources/fchomo.js:1727
-#: htdocs/luci-static/resources/fchomo.js:1743
-#: htdocs/luci-static/resources/fchomo.js:1752
-#: htdocs/luci-static/resources/fchomo.js:1764
-#: htdocs/luci-static/resources/fchomo.js:1767
-#: htdocs/luci-static/resources/fchomo.js:1777
-#: htdocs/luci-static/resources/fchomo.js:1789
-#: htdocs/luci-static/resources/fchomo.js:1792
-#: htdocs/luci-static/resources/fchomo.js:1805
-#: htdocs/luci-static/resources/fchomo.js:1814
-#: htdocs/luci-static/resources/fchomo.js:1823
-#: htdocs/luci-static/resources/fchomo.js:1832
-#: htdocs/luci-static/resources/fchomo.js:1867
+#: htdocs/luci-static/resources/fchomo.js:1680
+#: htdocs/luci-static/resources/fchomo.js:1688
+#: htdocs/luci-static/resources/fchomo.js:1696
+#: htdocs/luci-static/resources/fchomo.js:1719
+#: htdocs/luci-static/resources/fchomo.js:1722
+#: htdocs/luci-static/resources/fchomo.js:1729
+#: htdocs/luci-static/resources/fchomo.js:1745
+#: htdocs/luci-static/resources/fchomo.js:1754
+#: htdocs/luci-static/resources/fchomo.js:1766
+#: htdocs/luci-static/resources/fchomo.js:1769
+#: htdocs/luci-static/resources/fchomo.js:1779
+#: htdocs/luci-static/resources/fchomo.js:1791
+#: htdocs/luci-static/resources/fchomo.js:1794
+#: htdocs/luci-static/resources/fchomo.js:1807
+#: htdocs/luci-static/resources/fchomo.js:1816
+#: htdocs/luci-static/resources/fchomo.js:1825
+#: htdocs/luci-static/resources/fchomo.js:1834
#: htdocs/luci-static/resources/fchomo.js:1869
-#: htdocs/luci-static/resources/fchomo.js:1882
-#: htdocs/luci-static/resources/fchomo.js:1888
-#: htdocs/luci-static/resources/fchomo.js:1895
-#: htdocs/luci-static/resources/fchomo.js:1904
+#: htdocs/luci-static/resources/fchomo.js:1871
+#: htdocs/luci-static/resources/fchomo.js:1884
+#: htdocs/luci-static/resources/fchomo.js:1890
+#: htdocs/luci-static/resources/fchomo.js:1897
+#: htdocs/luci-static/resources/fchomo.js:1906
#: htdocs/luci-static/resources/fchomo/listeners.js:291
#: htdocs/luci-static/resources/fchomo/listeners.js:346
-#: htdocs/luci-static/resources/fchomo/listeners.js:861
-#: htdocs/luci-static/resources/fchomo/listeners.js:892
-#: htdocs/luci-static/resources/fchomo/listeners.js:993
+#: htdocs/luci-static/resources/fchomo/listeners.js:879
+#: htdocs/luci-static/resources/fchomo/listeners.js:910
+#: htdocs/luci-static/resources/fchomo/listeners.js:1011
#: htdocs/luci-static/resources/view/fchomo/client.js:71
#: htdocs/luci-static/resources/view/fchomo/client.js:1059
#: htdocs/luci-static/resources/view/fchomo/client.js:1604
@@ -1202,25 +1207,25 @@ msgstr "预期状态"
#: htdocs/luci-static/resources/view/fchomo/node.js:444
#: htdocs/luci-static/resources/view/fchomo/node.js:497
#: htdocs/luci-static/resources/view/fchomo/node.js:499
-#: htdocs/luci-static/resources/view/fchomo/node.js:900
-#: htdocs/luci-static/resources/view/fchomo/node.js:1415
-#: htdocs/luci-static/resources/view/fchomo/node.js:2755
-#: htdocs/luci-static/resources/view/fchomo/node.js:2785
+#: htdocs/luci-static/resources/view/fchomo/node.js:910
+#: htdocs/luci-static/resources/view/fchomo/node.js:1438
+#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2806
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:311
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:325
msgid "Expecting: %s"
msgstr "请输入:%s"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1129
+#: htdocs/luci-static/resources/fchomo/listeners.js:1147
msgid "Expecting: Cannot be empty."
msgstr "请输入:不能为空。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1240
-#: htdocs/luci-static/resources/view/fchomo/node.js:1589
+#: htdocs/luci-static/resources/fchomo/listeners.js:1258
+#: htdocs/luci-static/resources/view/fchomo/node.js:1612
msgid "Expecting: Cannot be enabled when %s is enabled."
msgstr "请输入:当 %s 启用时,无法启用。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1124
+#: htdocs/luci-static/resources/fchomo/listeners.js:1142
msgid "Expecting: Keep empty when %s is enabled."
msgstr "请输入:启用 %s 时保持为空。"
@@ -1229,15 +1234,15 @@ msgstr "请输入:启用 %s 时保持为空。"
msgid "Expecting: Least one of %s or %s."
msgstr "请输入:至少包含 %s 或 %s 中的一个。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:699
-#: htdocs/luci-static/resources/fchomo/listeners.js:705
-#: htdocs/luci-static/resources/fchomo/listeners.js:1314
-#: htdocs/luci-static/resources/fchomo/listeners.js:1321
-#: htdocs/luci-static/resources/view/fchomo/node.js:1289
-#: htdocs/luci-static/resources/view/fchomo/node.js:1295
-#: htdocs/luci-static/resources/view/fchomo/node.js:1895
-#: htdocs/luci-static/resources/view/fchomo/node.js:1902
-#: htdocs/luci-static/resources/view/fchomo/node.js:1910
+#: htdocs/luci-static/resources/fchomo/listeners.js:716
+#: htdocs/luci-static/resources/fchomo/listeners.js:723
+#: htdocs/luci-static/resources/fchomo/listeners.js:1332
+#: htdocs/luci-static/resources/fchomo/listeners.js:1339
+#: htdocs/luci-static/resources/view/fchomo/node.js:1311
+#: htdocs/luci-static/resources/view/fchomo/node.js:1318
+#: htdocs/luci-static/resources/view/fchomo/node.js:1916
+#: htdocs/luci-static/resources/view/fchomo/node.js:1923
+#: htdocs/luci-static/resources/view/fchomo/node.js:1931
msgid "Expecting: Only support %s."
msgstr "请输入:仅支援 %s。"
@@ -1257,19 +1262,19 @@ msgstr "实验性"
msgid "Factor"
msgstr "条件"
-#: htdocs/luci-static/resources/fchomo.js:1619
+#: htdocs/luci-static/resources/fchomo.js:1621
msgid "Failed to execute \"/etc/init.d/fchomo %s %s\" reason: %s"
msgstr "无法执行 \"/etc/init.d/fchomo %s %s\" 原因: %s"
-#: htdocs/luci-static/resources/fchomo.js:1572
+#: htdocs/luci-static/resources/fchomo.js:1574
msgid "Failed to generate %s, error: %s."
msgstr "生成 %s 失败,错误:%s。"
-#: htdocs/luci-static/resources/fchomo.js:2004
+#: htdocs/luci-static/resources/fchomo.js:2006
msgid "Failed to upload %s, error: %s."
msgstr "上传 %s 失败,错误:%s。"
-#: htdocs/luci-static/resources/fchomo.js:2023
+#: htdocs/luci-static/resources/fchomo.js:2025
msgid "Failed to upload, error: %s."
msgstr "上传失败,错误:%s。"
@@ -1289,16 +1294,16 @@ msgstr "後備 DNS 服务器"
msgid "Fallback filter"
msgstr "後備过滤器"
-#: htdocs/luci-static/resources/view/fchomo/node.js:849
+#: htdocs/luci-static/resources/view/fchomo/node.js:859
msgid "Fallback mode"
msgstr "自动回退模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:856
+#: htdocs/luci-static/resources/view/fchomo/node.js:866
msgid "Fallback relay"
msgstr "自动回退中继"
#: htdocs/luci-static/resources/view/fchomo/client.js:1246
-#: htdocs/luci-static/resources/view/fchomo/node.js:2650
+#: htdocs/luci-static/resources/view/fchomo/node.js:2671
msgid "Filter nodes that meet keywords or regexps."
msgstr "过滤匹配关键字或表达式的节点。"
@@ -1324,12 +1329,12 @@ msgid "Final DNS server (For poisoned domains)"
msgstr "兜底 DNS 服务器 (用于已被投毒污染的域名)"
#: htdocs/luci-static/resources/fchomo/listeners.js:138
-#: htdocs/luci-static/resources/view/fchomo/node.js:1617
+#: htdocs/luci-static/resources/view/fchomo/node.js:1640
msgid "Firewall"
msgstr "防火墙"
-#: htdocs/luci-static/resources/fchomo/listeners.js:416
-#: htdocs/luci-static/resources/view/fchomo/node.js:536
+#: htdocs/luci-static/resources/fchomo/listeners.js:425
+#: htdocs/luci-static/resources/view/fchomo/node.js:546
msgid "Flow"
msgstr "流控"
@@ -1342,9 +1347,9 @@ msgstr ""
"noopener\">%s."
#: htdocs/luci-static/resources/view/fchomo/client.js:1195
-#: htdocs/luci-static/resources/view/fchomo/node.js:2503
-#: htdocs/luci-static/resources/view/fchomo/node.js:2511
-#: htdocs/luci-static/resources/view/fchomo/node.js:2642
+#: htdocs/luci-static/resources/view/fchomo/node.js:2524
+#: htdocs/luci-static/resources/view/fchomo/node.js:2532
+#: htdocs/luci-static/resources/view/fchomo/node.js:2663
msgid ""
"For format see %s."
@@ -1352,15 +1357,15 @@ msgstr ""
"格式请参阅 %s"
"a>."
-#: htdocs/luci-static/resources/view/fchomo/node.js:851
+#: htdocs/luci-static/resources/view/fchomo/node.js:861
msgid "Force"
msgstr "强制"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1864
+#: htdocs/luci-static/resources/view/fchomo/node.js:1885
msgid "Force DNS remote resolution."
msgstr "强制 DNS 远程解析。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1250
+#: htdocs/luci-static/resources/view/fchomo/node.js:1264
msgid "Force UDP"
msgstr "强制开启 UDP"
@@ -1372,7 +1377,7 @@ msgstr "强制嗅探域名"
msgid "Format"
msgstr "格式"
-#: htdocs/luci-static/resources/fchomo/listeners.js:785
+#: htdocs/luci-static/resources/fchomo/listeners.js:803
msgid "Forwarding rate limit"
msgstr "转发速率限制"
@@ -1383,7 +1388,7 @@ msgstr "转发速率限制"
msgid "FullCombo Shark!"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1935
+#: htdocs/luci-static/resources/view/fchomo/node.js:1956
msgid "GET"
msgstr ""
@@ -1391,8 +1396,8 @@ msgstr ""
msgid "GFW list version"
msgstr "GFW 域名列表版本"
-#: htdocs/luci-static/resources/fchomo/listeners.js:502
-#: htdocs/luci-static/resources/view/fchomo/node.js:720
+#: htdocs/luci-static/resources/fchomo/listeners.js:511
+#: htdocs/luci-static/resources/view/fchomo/node.js:730
msgid "Gecko"
msgstr ""
@@ -1403,7 +1408,7 @@ msgstr "常规"
#: htdocs/luci-static/resources/fchomo/listeners.js:119
#: htdocs/luci-static/resources/view/fchomo/client.js:1050
#: htdocs/luci-static/resources/view/fchomo/node.js:252
-#: htdocs/luci-static/resources/view/fchomo/node.js:2313
+#: htdocs/luci-static/resources/view/fchomo/node.js:2334
msgid "General fields"
msgstr "常规字段"
@@ -1411,17 +1416,17 @@ msgstr "常规字段"
msgid "General settings"
msgstr "常规设置"
-#: htdocs/luci-static/resources/fchomo.js:721
-#: htdocs/luci-static/resources/fchomo.js:723
-#: htdocs/luci-static/resources/fchomo.js:737
+#: htdocs/luci-static/resources/fchomo.js:722
+#: htdocs/luci-static/resources/fchomo.js:724
#: htdocs/luci-static/resources/fchomo.js:739
+#: htdocs/luci-static/resources/fchomo.js:741
#: htdocs/luci-static/resources/fchomo/listeners.js:269
#: htdocs/luci-static/resources/fchomo/listeners.js:313
#: htdocs/luci-static/resources/fchomo/listeners.js:315
-#: htdocs/luci-static/resources/fchomo/listeners.js:965
-#: htdocs/luci-static/resources/fchomo/listeners.js:1218
+#: htdocs/luci-static/resources/fchomo/listeners.js:983
+#: htdocs/luci-static/resources/fchomo/listeners.js:1236
#: htdocs/luci-static/resources/view/fchomo/global.js:616
-#: htdocs/luci-static/resources/view/fchomo/node.js:2471
+#: htdocs/luci-static/resources/view/fchomo/node.js:2492
msgid "Generate"
msgstr "生成"
@@ -1468,7 +1473,7 @@ msgstr "全局"
msgid "Global Authentication"
msgstr "全局认证"
-#: htdocs/luci-static/resources/view/fchomo/node.js:560
+#: htdocs/luci-static/resources/view/fchomo/node.js:570
msgid "Global padding"
msgstr "全局填充"
@@ -1490,17 +1495,17 @@ msgstr "组"
#: htdocs/luci-static/resources/fchomo.js:191
#: htdocs/luci-static/resources/fchomo.js:228
-#: htdocs/luci-static/resources/fchomo/listeners.js:717
-#: htdocs/luci-static/resources/view/fchomo/node.js:1307
-#: htdocs/luci-static/resources/view/fchomo/node.js:1882
-#: htdocs/luci-static/resources/view/fchomo/node.js:1895
-#: htdocs/luci-static/resources/view/fchomo/node.js:1902
+#: htdocs/luci-static/resources/fchomo/listeners.js:735
+#: htdocs/luci-static/resources/view/fchomo/node.js:1330
+#: htdocs/luci-static/resources/view/fchomo/node.js:1903
+#: htdocs/luci-static/resources/view/fchomo/node.js:1916
+#: htdocs/luci-static/resources/view/fchomo/node.js:1923
msgid "HTTP"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/node.js:333
-#: htdocs/luci-static/resources/view/fchomo/node.js:1957
-#: htdocs/luci-static/resources/view/fchomo/node.js:2483
+#: htdocs/luci-static/resources/view/fchomo/node.js:1978
+#: htdocs/luci-static/resources/view/fchomo/node.js:2504
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:430
msgid "HTTP header"
msgstr "HTTP header"
@@ -1526,7 +1531,7 @@ msgstr "HTTP 伪装多路复用"
msgid "HTTP mask: %s"
msgstr "HTTP 伪装: %s"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1934
+#: htdocs/luci-static/resources/view/fchomo/node.js:1955
msgid "HTTP request method"
msgstr "HTTP 请求方法"
@@ -1539,15 +1544,15 @@ msgstr "HTTP 根路径"
msgid "HTTP/3"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:525
+#: htdocs/luci-static/resources/fchomo/listeners.js:534
msgid ""
"HTTP3 server behavior when authentication fails.
A 404 page will be "
"returned if empty."
msgstr "身份验证失败时的 HTTP3 服务器响应。默认返回 404 页面。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1883
-#: htdocs/luci-static/resources/view/fchomo/node.js:1896
-#: htdocs/luci-static/resources/view/fchomo/node.js:1903
+#: htdocs/luci-static/resources/view/fchomo/node.js:1904
+#: htdocs/luci-static/resources/view/fchomo/node.js:1917
+#: htdocs/luci-static/resources/view/fchomo/node.js:1924
msgid "HTTPUpgrade"
msgstr ""
@@ -1559,58 +1564,58 @@ msgstr "处理域名"
msgid "Handshake mode"
msgstr "握手模式"
-#: htdocs/luci-static/resources/fchomo/listeners.js:767
+#: htdocs/luci-static/resources/fchomo/listeners.js:785
msgid "Handshake target proxy"
msgstr "握手目标代理"
-#: htdocs/luci-static/resources/fchomo/listeners.js:722
+#: htdocs/luci-static/resources/fchomo/listeners.js:740
msgid "Handshake target that supports TLS 1.3"
msgstr "握手目标 (支援 TLS 1.3)"
#: htdocs/luci-static/resources/fchomo/listeners.js:353
-#: htdocs/luci-static/resources/view/fchomo/node.js:1242
+#: htdocs/luci-static/resources/view/fchomo/node.js:1256
msgid "Handshake timeout"
msgstr "握手超时"
-#: htdocs/luci-static/resources/fchomo/listeners.js:550
+#: htdocs/luci-static/resources/fchomo/listeners.js:559
msgid "Header to read real client IP from (e.g. X-Forwarded-For)"
msgstr "用于读取客户端真实 IP 的 Header(例如 X-Forwarded-For)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:968
+#: htdocs/luci-static/resources/view/fchomo/node.js:978
msgid "Headscale/Tailscale"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:796
+#: htdocs/luci-static/resources/view/fchomo/node.js:806
msgid "Health check"
msgstr "健康检查"
#: htdocs/luci-static/resources/view/fchomo/client.js:1164
-#: htdocs/luci-static/resources/view/fchomo/node.js:2610
+#: htdocs/luci-static/resources/view/fchomo/node.js:2631
msgid "Health check URL"
msgstr "健康检查 URL"
#: htdocs/luci-static/resources/view/fchomo/client.js:1193
-#: htdocs/luci-static/resources/view/fchomo/node.js:2640
+#: htdocs/luci-static/resources/view/fchomo/node.js:2661
msgid "Health check expected status"
msgstr "健康检查预期状态"
#: htdocs/luci-static/resources/view/fchomo/client.js:1173
-#: htdocs/luci-static/resources/view/fchomo/node.js:2620
+#: htdocs/luci-static/resources/view/fchomo/node.js:2641
msgid "Health check interval"
msgstr "健康检查间隔"
#: htdocs/luci-static/resources/view/fchomo/client.js:1180
-#: htdocs/luci-static/resources/view/fchomo/node.js:2627
+#: htdocs/luci-static/resources/view/fchomo/node.js:2648
msgid "Health check timeout"
msgstr "健康检查超时"
#: htdocs/luci-static/resources/view/fchomo/client.js:1052
-#: htdocs/luci-static/resources/view/fchomo/node.js:2315
+#: htdocs/luci-static/resources/view/fchomo/node.js:2336
msgid "Health fields"
msgstr "健康字段"
-#: htdocs/luci-static/resources/view/fchomo/node.js:678
-#: htdocs/luci-static/resources/view/fchomo/node.js:759
+#: htdocs/luci-static/resources/view/fchomo/node.js:688
+#: htdocs/luci-static/resources/view/fchomo/node.js:769
msgid "Heartbeat interval"
msgstr "心跳间隔"
@@ -1618,16 +1623,16 @@ msgstr "心跳间隔"
msgid "Hidden"
msgstr "隐藏"
-#: htdocs/luci-static/resources/fchomo/listeners.js:730
-#: htdocs/luci-static/resources/view/fchomo/node.js:1312
+#: htdocs/luci-static/resources/fchomo/listeners.js:748
+#: htdocs/luci-static/resources/view/fchomo/node.js:1335
msgid "Host that supports TLS 1.3"
msgstr "主机名称 (支援 TLS 1.3)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1194
+#: htdocs/luci-static/resources/view/fchomo/node.js:1208
msgid "Host-key"
msgstr "主机密钥"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1189
+#: htdocs/luci-static/resources/view/fchomo/node.js:1203
msgid "Host-key algorithms"
msgstr "主机密钥算法"
@@ -1635,12 +1640,12 @@ msgstr "主机密钥算法"
msgid "Host/SNI override"
msgstr "主机/SNI 覆盖"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1063
+#: htdocs/luci-static/resources/view/fchomo/node.js:1073
msgid "Hostname"
msgstr "主机名"
-#: htdocs/luci-static/resources/fchomo.js:1458
-#: htdocs/luci-static/resources/view/fchomo/node.js:1455
+#: htdocs/luci-static/resources/fchomo.js:1461
+#: htdocs/luci-static/resources/view/fchomo/node.js:1478
msgid ""
"Hostname that the client attempts to connect to at the start of the TLS "
"handshake process."
@@ -1674,24 +1679,24 @@ msgstr ""
msgid "IP CIDR"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:635
+#: htdocs/luci-static/resources/view/fchomo/node.js:645
msgid "IP override"
msgstr "IP 覆写"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1200
-#: htdocs/luci-static/resources/view/fchomo/node.js:1210
+#: htdocs/luci-static/resources/view/fchomo/node.js:1214
+#: htdocs/luci-static/resources/view/fchomo/node.js:1224
msgid "IP stack"
msgstr "IP 协议栈"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2177
-#: htdocs/luci-static/resources/view/fchomo/node.js:2596
+#: htdocs/luci-static/resources/view/fchomo/node.js:2198
+#: htdocs/luci-static/resources/view/fchomo/node.js:2617
msgid "IP version"
msgstr "IP 版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1767
-#: htdocs/luci-static/resources/view/fchomo/node.js:1771
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1788
+#: htdocs/luci-static/resources/view/fchomo/node.js:1792
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
msgid "IPv4"
msgstr "IPv4"
@@ -1699,9 +1704,9 @@ msgstr "IPv4"
msgid "IPv4 only"
msgstr "仅 IPv4"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
-#: htdocs/luci-static/resources/view/fchomo/node.js:1799
-#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
+#: htdocs/luci-static/resources/view/fchomo/node.js:1820
+#: htdocs/luci-static/resources/view/fchomo/node.js:1824
msgid "IPv6"
msgstr "IPv6"
@@ -1718,19 +1723,19 @@ msgstr "IPv6 支持"
msgid "Icon"
msgstr "图标"
-#: htdocs/luci-static/resources/view/fchomo/node.js:608
+#: htdocs/luci-static/resources/view/fchomo/node.js:618
msgid "Idle session check interval"
msgstr "闲置会话检查间隔"
-#: htdocs/luci-static/resources/view/fchomo/node.js:615
+#: htdocs/luci-static/resources/view/fchomo/node.js:625
msgid "Idle session timeout"
msgstr "闲置会话超时"
-#: htdocs/luci-static/resources/fchomo/listeners.js:662
+#: htdocs/luci-static/resources/fchomo/listeners.js:671
msgid "Idle timeout"
msgstr "闲置超时"
-#: htdocs/luci-static/resources/fchomo.js:1720
+#: htdocs/luci-static/resources/fchomo.js:1722
msgid "If All ports is selected, uncheck others"
msgstr "如果选择了“所有端口”,则取消选中“其他”"
@@ -1738,17 +1743,17 @@ msgstr "如果选择了“所有端口”,则取消选中“其他”"
msgid "If Block is selected, uncheck others"
msgstr "如果选择了“阻止”,则取消选中“其他”"
-#: htdocs/luci-static/resources/fchomo/listeners.js:492
+#: htdocs/luci-static/resources/fchomo/listeners.js:501
msgid "Ignore client bandwidth"
msgstr "忽略客户端带宽"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1154
+#: htdocs/luci-static/resources/view/fchomo/node.js:1168
msgid ""
"Ignore the number of intermediate hops and select the path with the lowest "
"total latency."
msgstr "忽略中继跳数,选择总延迟最低的路径。"
-#: htdocs/luci-static/resources/fchomo.js:906
+#: htdocs/luci-static/resources/fchomo.js:909
msgid "Import"
msgstr "导入"
@@ -1764,8 +1769,8 @@ msgstr "导入"
#: htdocs/luci-static/resources/view/fchomo/client.js:1812
#: htdocs/luci-static/resources/view/fchomo/client.js:1847
#: htdocs/luci-static/resources/view/fchomo/client.js:1868
-#: htdocs/luci-static/resources/view/fchomo/node.js:2203
-#: htdocs/luci-static/resources/view/fchomo/node.js:2301
+#: htdocs/luci-static/resources/view/fchomo/node.js:2224
+#: htdocs/luci-static/resources/view/fchomo/node.js:2322
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:164
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:260
msgid "Import mihomo config"
@@ -1777,48 +1782,48 @@ msgstr "导入 mihomo 配置"
msgid "Import rule-set links"
msgstr "导入规则集链接"
-#: htdocs/luci-static/resources/fchomo/listeners.js:481
-#: htdocs/luci-static/resources/fchomo/listeners.js:487
-#: htdocs/luci-static/resources/view/fchomo/node.js:694
-#: htdocs/luci-static/resources/view/fchomo/node.js:700
-#: htdocs/luci-static/resources/view/fchomo/node.js:2548
-#: htdocs/luci-static/resources/view/fchomo/node.js:2554
+#: htdocs/luci-static/resources/fchomo/listeners.js:490
+#: htdocs/luci-static/resources/fchomo/listeners.js:496
+#: htdocs/luci-static/resources/view/fchomo/node.js:704
+#: htdocs/luci-static/resources/view/fchomo/node.js:710
+#: htdocs/luci-static/resources/view/fchomo/node.js:2569
+#: htdocs/luci-static/resources/view/fchomo/node.js:2575
msgid "In Mbps."
msgstr "单位为 Mbps。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:786
+#: htdocs/luci-static/resources/fchomo/listeners.js:804
msgid "In bps. 0 means no speed limit."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2391
+#: htdocs/luci-static/resources/view/fchomo/node.js:2412
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:403
msgid "In bytes. %s will be used if empty."
msgstr "单位为字节。留空则使用 %s。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1289
-#: htdocs/luci-static/resources/view/fchomo/node.js:679
-#: htdocs/luci-static/resources/view/fchomo/node.js:686
-#: htdocs/luci-static/resources/view/fchomo/node.js:760
+#: htdocs/luci-static/resources/fchomo/listeners.js:1307
+#: htdocs/luci-static/resources/view/fchomo/node.js:689
+#: htdocs/luci-static/resources/view/fchomo/node.js:696
+#: htdocs/luci-static/resources/view/fchomo/node.js:770
msgid "In millisecond."
msgstr "单位为毫秒。"
#: htdocs/luci-static/resources/view/fchomo/client.js:1181
#: htdocs/luci-static/resources/view/fchomo/client.js:1227
-#: htdocs/luci-static/resources/view/fchomo/node.js:2628
+#: htdocs/luci-static/resources/view/fchomo/node.js:2649
msgid "In millisecond. %s will be used if empty."
msgstr "单位为毫秒。留空则使用 %s。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2026
+#: htdocs/luci-static/resources/view/fchomo/node.js:2047
msgid "In milliseconds."
msgstr "单位为毫秒。"
#: htdocs/luci-static/resources/fchomo/listeners.js:207
#: htdocs/luci-static/resources/fchomo/listeners.js:354
-#: htdocs/luci-static/resources/fchomo/listeners.js:473
-#: htdocs/luci-static/resources/fchomo/listeners.js:663
-#: htdocs/luci-static/resources/view/fchomo/node.js:609
-#: htdocs/luci-static/resources/view/fchomo/node.js:616
-#: htdocs/luci-static/resources/view/fchomo/node.js:1973
+#: htdocs/luci-static/resources/fchomo/listeners.js:482
+#: htdocs/luci-static/resources/fchomo/listeners.js:672
+#: htdocs/luci-static/resources/view/fchomo/node.js:619
+#: htdocs/luci-static/resources/view/fchomo/node.js:626
+#: htdocs/luci-static/resources/view/fchomo/node.js:1994
msgid "In seconds."
msgstr "单位为秒。"
@@ -1826,21 +1831,21 @@ msgstr "单位为秒。"
#: htdocs/luci-static/resources/view/fchomo/global.js:446
#: htdocs/luci-static/resources/view/fchomo/global.js:451
#: htdocs/luci-static/resources/view/fchomo/global.js:537
-#: htdocs/luci-static/resources/view/fchomo/node.js:712
-#: htdocs/luci-static/resources/view/fchomo/node.js:2397
-#: htdocs/luci-static/resources/view/fchomo/node.js:2621
+#: htdocs/luci-static/resources/view/fchomo/node.js:722
+#: htdocs/luci-static/resources/view/fchomo/node.js:2418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2642
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:409
msgid "In seconds. %s will be used if empty."
msgstr "单位为秒。留空则使用 %s。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1243
+#: htdocs/luci-static/resources/view/fchomo/node.js:1257
msgid ""
"In seconds. After configuration, the handshake is not affected by the outer "
"connection timeout."
msgstr "单位为秒。配置后握手时不受外层连接超时影响。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:881
-#: htdocs/luci-static/resources/view/fchomo/node.js:1404
+#: htdocs/luci-static/resources/fchomo/listeners.js:899
+#: htdocs/luci-static/resources/view/fchomo/node.js:1427
msgid ""
"In the order of one Padding-Length and one Padding-"
"Interval, infinite concatenation."
@@ -1883,17 +1888,17 @@ msgstr "引入所有代理节点。"
msgid "Info"
msgstr "信息"
-#: htdocs/luci-static/resources/fchomo/listeners.js:572
-#: htdocs/luci-static/resources/view/fchomo/node.js:766
+#: htdocs/luci-static/resources/fchomo/listeners.js:581
+#: htdocs/luci-static/resources/view/fchomo/node.js:776
msgid "Initial congestion window size"
msgstr "初始拥塞窗口大小"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2330
+#: htdocs/luci-static/resources/view/fchomo/node.js:2351
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:299
msgid "Inline"
msgstr "内嵌"
-#: htdocs/luci-static/resources/view/fchomo/node.js:826
+#: htdocs/luci-static/resources/view/fchomo/node.js:836
msgid "Insane"
msgstr "噩梦"
@@ -1901,19 +1906,19 @@ msgstr "噩梦"
msgid "Interface Control"
msgstr "接口控制"
-#: htdocs/luci-static/resources/fchomo/listeners.js:692
-#: htdocs/luci-static/resources/fchomo/listeners.js:702
-#: htdocs/luci-static/resources/fchomo/listeners.js:707
-#: htdocs/luci-static/resources/fchomo/listeners.js:1126
-#: htdocs/luci-static/resources/fchomo/listeners.js:1242
-#: htdocs/luci-static/resources/view/fchomo/node.js:1282
-#: htdocs/luci-static/resources/view/fchomo/node.js:1292
-#: htdocs/luci-static/resources/view/fchomo/node.js:1297
-#: htdocs/luci-static/resources/view/fchomo/node.js:1591
+#: htdocs/luci-static/resources/fchomo/listeners.js:701
+#: htdocs/luci-static/resources/fchomo/listeners.js:720
+#: htdocs/luci-static/resources/fchomo/listeners.js:725
+#: htdocs/luci-static/resources/fchomo/listeners.js:1144
+#: htdocs/luci-static/resources/fchomo/listeners.js:1260
+#: htdocs/luci-static/resources/view/fchomo/node.js:1296
+#: htdocs/luci-static/resources/view/fchomo/node.js:1315
+#: htdocs/luci-static/resources/view/fchomo/node.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1614
msgid "JLS"
msgstr "JLS"
-#: htdocs/luci-static/resources/view/fchomo/node.js:893
+#: htdocs/luci-static/resources/view/fchomo/node.js:903
msgid "Join %s. Format: %s"
msgstr "加入 %s。格式:%s"
@@ -1922,13 +1927,15 @@ msgstr "加入 %s。格式:%s"
#: htdocs/luci-static/resources/fchomo.js:97
#: htdocs/luci-static/resources/fchomo.js:211
#: htdocs/luci-static/resources/fchomo.js:454
-#: htdocs/luci-static/resources/view/fchomo/node.js:1136
-#: htdocs/luci-static/resources/view/fchomo/node.js:1201
-#: htdocs/luci-static/resources/view/fchomo/node.js:2570
+#: htdocs/luci-static/resources/fchomo/listeners.js:411
+#: htdocs/luci-static/resources/view/fchomo/node.js:532
+#: htdocs/luci-static/resources/view/fchomo/node.js:1150
+#: htdocs/luci-static/resources/view/fchomo/node.js:1215
+#: htdocs/luci-static/resources/view/fchomo/node.js:2591
msgid "Keep default"
msgstr "保持缺省"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2062
+#: htdocs/luci-static/resources/view/fchomo/node.js:2083
msgid "Keep-alive period"
msgstr "Keep-alive 周期"
@@ -1937,13 +1944,13 @@ msgstr "Keep-alive 周期"
msgid "Key"
msgstr "密钥"
-#: htdocs/luci-static/resources/fchomo.js:1494
-#: htdocs/luci-static/resources/fchomo/listeners.js:1145
-#: htdocs/luci-static/resources/view/fchomo/node.js:1541
+#: htdocs/luci-static/resources/fchomo.js:1497
+#: htdocs/luci-static/resources/fchomo/listeners.js:1163
+#: htdocs/luci-static/resources/view/fchomo/node.js:1564
msgid "Key path"
msgstr "证书路径"
-#: htdocs/luci-static/resources/fchomo/listeners.js:900
+#: htdocs/luci-static/resources/fchomo/listeners.js:918
msgid "Keypairs"
msgstr "密钥对"
@@ -1966,18 +1973,18 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1818
#: htdocs/luci-static/resources/view/fchomo/client.js:1874
#: htdocs/luci-static/resources/view/fchomo/node.js:262
-#: htdocs/luci-static/resources/view/fchomo/node.js:2318
-#: htdocs/luci-static/resources/view/fchomo/node.js:2714
+#: htdocs/luci-static/resources/view/fchomo/node.js:2339
+#: htdocs/luci-static/resources/view/fchomo/node.js:2735
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:278
msgid "Label"
msgstr "标签"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1153
+#: htdocs/luci-static/resources/view/fchomo/node.js:1167
msgid "Latency first"
msgstr "延迟优先"
#: htdocs/luci-static/resources/view/fchomo/client.js:1187
-#: htdocs/luci-static/resources/view/fchomo/node.js:2634
+#: htdocs/luci-static/resources/view/fchomo/node.js:2655
msgid "Lazy"
msgstr "怠惰状态"
@@ -1994,7 +2001,7 @@ msgstr "怠惰查询。"
msgid "Legacy"
msgstr "传统"
-#: htdocs/luci-static/resources/fchomo/listeners.js:425
+#: htdocs/luci-static/resources/fchomo/listeners.js:434
msgid ""
"Legacy protocol support (VMess MD5 Authentication) is provided for "
"compatibility purposes only, use of alterId > 1 is not recommended."
@@ -2006,19 +2013,19 @@ msgstr ""
msgid "Less compatibility and sometimes better performance."
msgstr "有时性能更好。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1116
+#: htdocs/luci-static/resources/view/fchomo/node.js:1130
msgid "List of exit nodes to use (%s of peer nodes)."
msgstr "要使用的出口节点列表(对端节点的 %s)。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1124
+#: htdocs/luci-static/resources/view/fchomo/node.js:1138
msgid ""
"List of local subnets (CIDR) to be open to other peers in the EasyTier "
"network."
msgstr "要向 EasyTier 网络中的其他对端开放的本地子网的列表(CIDR)。"
-#: htdocs/luci-static/resources/fchomo.js:1463
-#: htdocs/luci-static/resources/fchomo/listeners.js:1068
-#: htdocs/luci-static/resources/view/fchomo/node.js:1461
+#: htdocs/luci-static/resources/fchomo.js:1466
+#: htdocs/luci-static/resources/fchomo/listeners.js:1086
+#: htdocs/luci-static/resources/view/fchomo/node.js:1484
msgid "List of supported application level protocols, in order of preference."
msgstr "支持的应用层协议协商列表,按顺序排列。"
@@ -2036,8 +2043,8 @@ msgstr "监听接口"
#: htdocs/luci-static/resources/fchomo/listeners.js:154
#: htdocs/luci-static/resources/view/fchomo/client.js:1467
-#: htdocs/luci-static/resources/view/fchomo/node.js:1685
-#: htdocs/luci-static/resources/view/fchomo/node.js:1695
+#: htdocs/luci-static/resources/view/fchomo/node.js:1707
+#: htdocs/luci-static/resources/view/fchomo/node.js:1717
msgid "Listen port"
msgstr "监听端口"
@@ -2049,7 +2056,7 @@ msgstr "监听端口"
msgid "Listen routing mark (Fwmark)"
msgstr "监听路由标记 (Fwmark)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1733
+#: htdocs/luci-static/resources/view/fchomo/node.js:1754
msgid "Listeners"
msgstr "监听"
@@ -2057,7 +2064,7 @@ msgstr "监听"
msgid "Load balance"
msgstr "负载均衡"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2328
+#: htdocs/luci-static/resources/view/fchomo/node.js:2349
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:297
msgid "Local"
msgstr "本地"
@@ -2082,7 +2089,7 @@ msgstr "日志等级"
msgid "Logical"
msgstr "逻辑"
-#: htdocs/luci-static/resources/view/fchomo/node.js:837
+#: htdocs/luci-static/resources/view/fchomo/node.js:847
msgid "Low Bandwidth Mode"
msgstr "低带宽模式"
@@ -2102,7 +2109,7 @@ msgid "Lowercase only"
msgstr "仅限小写"
#: htdocs/luci-static/resources/view/fchomo/global.js:524
-#: htdocs/luci-static/resources/view/fchomo/node.js:1833
+#: htdocs/luci-static/resources/view/fchomo/node.js:1854
msgid "MTU"
msgstr "MTU"
@@ -2110,7 +2117,7 @@ msgstr "MTU"
msgid "Masque"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:524
+#: htdocs/luci-static/resources/fchomo/listeners.js:533
msgid "Masquerade"
msgstr "伪装"
@@ -2142,24 +2149,24 @@ msgstr "匹配响应通过 ipcidr"
msgid "Match rule set."
msgstr "匹配规则集。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1979
+#: htdocs/luci-static/resources/view/fchomo/node.js:2000
msgid "Max Early Data"
msgstr "前置数据最大值"
-#: htdocs/luci-static/resources/fchomo/listeners.js:466
-#: htdocs/luci-static/resources/view/fchomo/node.js:660
+#: htdocs/luci-static/resources/fchomo/listeners.js:475
+#: htdocs/luci-static/resources/view/fchomo/node.js:670
msgid "Max UDP relay packet size"
msgstr "UDP 中继数据包最大尺寸"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1365
+#: htdocs/luci-static/resources/fchomo/listeners.js:1383
msgid "Max buffered posts"
msgstr "POST 最大缓冲"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2037
+#: htdocs/luci-static/resources/view/fchomo/node.js:2058
msgid "Max concurrency"
msgstr "最大并发"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2042
+#: htdocs/luci-static/resources/view/fchomo/node.js:2063
msgid "Max connections"
msgstr "最大连接数"
@@ -2167,56 +2174,56 @@ msgstr "最大连接数"
msgid "Max count of failures"
msgstr "最大失败次数"
-#: htdocs/luci-static/resources/fchomo/listeners.js:578
-#: htdocs/luci-static/resources/view/fchomo/node.js:772
+#: htdocs/luci-static/resources/fchomo/listeners.js:587
+#: htdocs/luci-static/resources/view/fchomo/node.js:782
msgid "Max datagram frame size"
msgstr "最大数据报帧大小"
-#: htdocs/luci-static/resources/fchomo/listeners.js:486
-#: htdocs/luci-static/resources/view/fchomo/node.js:699
+#: htdocs/luci-static/resources/fchomo/listeners.js:495
+#: htdocs/luci-static/resources/view/fchomo/node.js:709
msgid "Max download speed"
msgstr "最大下载速度"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1376
-#: htdocs/luci-static/resources/view/fchomo/node.js:2019
+#: htdocs/luci-static/resources/fchomo/listeners.js:1394
+#: htdocs/luci-static/resources/view/fchomo/node.js:2040
msgid "Max each POST bytes"
msgstr "POST 最大字节数"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1236
+#: htdocs/luci-static/resources/view/fchomo/node.js:1250
msgid "Max open streams"
msgstr "限制打开流的数量"
-#: htdocs/luci-static/resources/fchomo/listeners.js:537
+#: htdocs/luci-static/resources/fchomo/listeners.js:546
msgid "Max realms"
msgstr "最大 Realms 总数"
-#: htdocs/luci-static/resources/fchomo/listeners.js:543
+#: htdocs/luci-static/resources/fchomo/listeners.js:552
msgid "Max realms per client IP"
msgstr "每客户端 IP 最大 Realms 总数"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2052
+#: htdocs/luci-static/resources/view/fchomo/node.js:2073
msgid "Max request times"
msgstr "最大请求次数"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2057
+#: htdocs/luci-static/resources/view/fchomo/node.js:2078
msgid "Max reusable seconds"
msgstr "最大可复用秒数"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2047
+#: htdocs/luci-static/resources/view/fchomo/node.js:2068
msgid "Max reuse times"
msgstr "最大复用次数"
-#: htdocs/luci-static/resources/fchomo/listeners.js:480
-#: htdocs/luci-static/resources/view/fchomo/node.js:693
+#: htdocs/luci-static/resources/fchomo/listeners.js:489
+#: htdocs/luci-static/resources/view/fchomo/node.js:703
msgid "Max upload speed"
msgstr "最大上传速度"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2083
-#: htdocs/luci-static/resources/view/fchomo/node.js:2103
+#: htdocs/luci-static/resources/view/fchomo/node.js:2104
+#: htdocs/luci-static/resources/view/fchomo/node.js:2124
msgid "Maximum connections"
msgstr "最大连接数"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2101
+#: htdocs/luci-static/resources/view/fchomo/node.js:2122
msgid ""
"Maximum multiplexed streams in a connection before opening a new connection."
"
Conflict with %s and %s."
@@ -2236,7 +2243,7 @@ msgid ""
"rate."
msgstr "最大填充率必须大于等于最小填充率。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2100
+#: htdocs/luci-static/resources/view/fchomo/node.js:2121
msgid "Maximum streams"
msgstr "最大流数量"
@@ -2257,15 +2264,15 @@ msgstr "Mihomo 客户端"
msgid "Mihomo server"
msgstr "Mihomo 服务端"
-#: htdocs/luci-static/resources/view/fchomo/node.js:622
+#: htdocs/luci-static/resources/view/fchomo/node.js:632
msgid "Min of idle sessions to keep"
msgstr "要保留的最少闲置会话数"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2025
+#: htdocs/luci-static/resources/view/fchomo/node.js:2046
msgid "Min posts interval"
msgstr "POST 请求最小间隔时间"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2092
+#: htdocs/luci-static/resources/view/fchomo/node.js:2113
msgid ""
"Minimum multiplexed streams in a connection before opening a new connection."
msgstr "在打开新连接之前,连接中的最小多路复用流数量。"
@@ -2275,8 +2282,8 @@ msgstr "在打开新连接之前,连接中的最小多路复用流数量。"
msgid "Minimum padding rate"
msgstr "最小填充率"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2091
-#: htdocs/luci-static/resources/view/fchomo/node.js:2103
+#: htdocs/luci-static/resources/view/fchomo/node.js:2112
+#: htdocs/luci-static/resources/view/fchomo/node.js:2124
msgid "Minimum streams"
msgstr "最小流数量"
@@ -2297,8 +2304,8 @@ msgstr "混合 系统 TCP 栈和 gVisor UDP 栈。"
msgid "Mixed port"
msgstr "混合端口"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1383
-#: htdocs/luci-static/resources/view/fchomo/node.js:2069
+#: htdocs/luci-static/resources/fchomo/listeners.js:1401
+#: htdocs/luci-static/resources/view/fchomo/node.js:2090
msgid "Multiplex"
msgstr "多路复用"
@@ -2311,12 +2318,16 @@ msgstr "多路复用字段"
msgid "Multiplexing"
msgstr "多路复用"
+#: htdocs/luci-static/resources/view/fchomo/node.js:531
+msgid "Must be consistent with the server."
+msgstr "必须与服务器保持一致。"
+
#: htdocs/luci-static/resources/view/fchomo/client.js:706
#: htdocs/luci-static/resources/view/fchomo/client.js:707
msgid "NETWORK"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1751
+#: htdocs/luci-static/resources/view/fchomo/node.js:1772
msgid "NO Listener"
msgstr "无监听"
@@ -2325,11 +2336,11 @@ msgstr "无监听"
msgid "NOT"
msgstr "NOT"
-#: htdocs/luci-static/resources/fchomo/listeners.js:630
+#: htdocs/luci-static/resources/fchomo/listeners.js:639
msgid "Name of the Proxy group as outbound."
msgstr "出站代理组的名称。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2403
+#: htdocs/luci-static/resources/view/fchomo/node.js:2424
msgid "Name of the Proxy group to download provider."
msgstr "用于下载供应商订阅的代理组名称。"
@@ -2337,11 +2348,11 @@ msgstr "用于下载供应商订阅的代理组名称。"
msgid "Name of the Proxy group to download rule set."
msgstr "用于下载规则集订阅的代理组名称。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:618
+#: htdocs/luci-static/resources/fchomo/listeners.js:627
msgid "Name of the Sub rule used for inbound matching."
msgstr "用于入站匹配的子规则名称。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:644
+#: htdocs/luci-static/resources/view/fchomo/node.js:654
msgid "Native UDP"
msgstr "原生 UDP"
@@ -2350,15 +2361,15 @@ msgid "Native appearance"
msgstr "原生外观"
#: htdocs/luci-static/resources/fchomo.js:362
-#: htdocs/luci-static/resources/view/fchomo/node.js:1016
+#: htdocs/luci-static/resources/view/fchomo/node.js:1026
msgid "Network"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:669
+#: htdocs/luci-static/resources/fchomo/listeners.js:678
msgid "Network type"
msgstr "网络类型"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2572
+#: htdocs/luci-static/resources/view/fchomo/node.js:2593
msgid "No"
msgstr ""
@@ -2366,7 +2377,7 @@ msgstr ""
msgid "No Authentication IP ranges"
msgstr "无需认证的 IP 范围"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1360
+#: htdocs/luci-static/resources/fchomo/listeners.js:1378
msgid "No SSE header"
msgstr "无 SSE header"
@@ -2374,16 +2385,26 @@ msgstr "无 SSE header"
msgid "No add'l params"
msgstr "无附加参数"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2009
+#: htdocs/luci-static/resources/fchomo/listeners.js:414
+#: htdocs/luci-static/resources/view/fchomo/node.js:535
+msgid "No encryption No obfuscation"
+msgstr "无加密无混淆"
+
+#: htdocs/luci-static/resources/view/fchomo/node.js:2030
msgid "No gRPC header"
msgstr "无 gRPC header"
+#: htdocs/luci-static/resources/fchomo/listeners.js:413
+#: htdocs/luci-static/resources/view/fchomo/node.js:534
+msgid "No obfuscation"
+msgstr "无混淆"
+
#: htdocs/luci-static/resources/view/fchomo/client.js:1188
-#: htdocs/luci-static/resources/view/fchomo/node.js:2635
+#: htdocs/luci-static/resources/view/fchomo/node.js:2656
msgid "No testing is performed when this provider node is not in use."
msgstr "当此供应商的节点未使用时,不执行任何测试。"
-#: htdocs/luci-static/resources/fchomo.js:867
+#: htdocs/luci-static/resources/fchomo.js:870
msgid "No valid %s found."
msgstr "未找到有效的%s。"
@@ -2397,17 +2418,17 @@ msgid "Node"
msgstr "节点"
#: htdocs/luci-static/resources/view/fchomo/client.js:1250
-#: htdocs/luci-static/resources/view/fchomo/node.js:2655
+#: htdocs/luci-static/resources/view/fchomo/node.js:2676
msgid "Node exclude filter"
msgstr "排除节点"
#: htdocs/luci-static/resources/view/fchomo/client.js:1255
-#: htdocs/luci-static/resources/view/fchomo/node.js:2662
+#: htdocs/luci-static/resources/view/fchomo/node.js:2683
msgid "Node exclude type"
msgstr "排除节点类型"
#: htdocs/luci-static/resources/view/fchomo/client.js:1245
-#: htdocs/luci-static/resources/view/fchomo/node.js:2649
+#: htdocs/luci-static/resources/view/fchomo/node.js:2670
msgid "Node filter"
msgstr "过滤节点"
@@ -2419,7 +2440,7 @@ msgstr "节点切换容差"
msgid "None"
msgstr "无"
-#: htdocs/luci-static/resources/view/fchomo/node.js:822
+#: htdocs/luci-static/resources/view/fchomo/node.js:832
msgid "Normal"
msgstr "正常"
@@ -2427,11 +2448,11 @@ msgstr "正常"
msgid "Not Installed"
msgstr "未安装"
-#: htdocs/luci-static/resources/fchomo.js:1396
+#: htdocs/luci-static/resources/fchomo.js:1399
msgid "Not Running"
msgstr "未在运行"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2680
+#: htdocs/luci-static/resources/view/fchomo/node.js:2701
msgid "Note: The subscription of provider %s is includes %s."
msgstr "注意:供应商 %s 的订阅包含 %s。"
@@ -2443,30 +2464,30 @@ msgstr ""
msgid "ON"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:716
-#: htdocs/luci-static/resources/view/fchomo/node.js:1306
+#: htdocs/luci-static/resources/fchomo/listeners.js:734
+#: htdocs/luci-static/resources/view/fchomo/node.js:1329
msgid "Obfs Mode"
msgstr "Obfs 模式"
-#: htdocs/luci-static/resources/fchomo/listeners.js:519
-#: htdocs/luci-static/resources/view/fchomo/node.js:737
+#: htdocs/luci-static/resources/fchomo/listeners.js:528
+#: htdocs/luci-static/resources/view/fchomo/node.js:747
msgid "Obfuscate maximum packet size"
msgstr "混淆最大数据包大小"
-#: htdocs/luci-static/resources/fchomo/listeners.js:514
-#: htdocs/luci-static/resources/view/fchomo/node.js:732
+#: htdocs/luci-static/resources/fchomo/listeners.js:523
+#: htdocs/luci-static/resources/view/fchomo/node.js:742
msgid "Obfuscate minimum packet size"
msgstr "混淆最小数据包大小"
-#: htdocs/luci-static/resources/fchomo/listeners.js:506
-#: htdocs/luci-static/resources/view/fchomo/node.js:724
+#: htdocs/luci-static/resources/fchomo/listeners.js:515
+#: htdocs/luci-static/resources/view/fchomo/node.js:734
msgid "Obfuscate password"
msgstr "混淆密码"
#: htdocs/luci-static/resources/fchomo/listeners.js:298
-#: htdocs/luci-static/resources/fchomo/listeners.js:499
+#: htdocs/luci-static/resources/fchomo/listeners.js:508
#: htdocs/luci-static/resources/view/fchomo/node.js:415
-#: htdocs/luci-static/resources/view/fchomo/node.js:717
+#: htdocs/luci-static/resources/view/fchomo/node.js:727
msgid "Obfuscate type"
msgstr "混淆类型"
@@ -2481,7 +2502,7 @@ msgstr "混淆为%s"
msgid "One or more numbers in the range 0-63 separated by commas"
msgstr "0-63 范围内的一个或多个数字,以逗号分隔"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1062
+#: htdocs/luci-static/resources/fchomo/listeners.js:1080
msgid "Only applicable when %s are used as a frontend."
msgstr "仅当 %s 用作前端时适用。"
@@ -2490,7 +2511,7 @@ msgstr "仅当 %s 用作前端时适用。"
msgid "Only applies to the %s."
msgstr "只对%s生效。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1057
+#: htdocs/luci-static/resources/view/fchomo/node.js:1067
msgid ""
"Only nodes using the same %s and %s as this network are permitted to perform "
"a handshake or relay traffic through this node."
@@ -2500,11 +2521,11 @@ msgstr "仅允许使用与本网络相同的 %s 和 %s 的节点通过此节点
msgid "Only process traffic from specific interfaces. Leave empty for all."
msgstr "只处理来自指定接口的流量。留空表示全部。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1734
+#: htdocs/luci-static/resources/view/fchomo/node.js:1755
msgid "Only the address %s is valid."
msgstr "只有地址 %s 是有效的。"
-#: htdocs/luci-static/resources/fchomo.js:1390
+#: htdocs/luci-static/resources/fchomo.js:1393
msgid "Open Dashboard"
msgstr "打开面板"
@@ -2520,7 +2541,7 @@ msgstr "该选项已弃用,请使用%s作为代替。"
msgid "Other"
msgstr "其他"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2520
+#: htdocs/luci-static/resources/view/fchomo/node.js:2541
msgid "Other configuration items"
msgstr "其他配置项"
@@ -2528,9 +2549,9 @@ msgstr "其他配置项"
msgid "Outbound"
msgstr "出站"
-#: htdocs/luci-static/resources/fchomo.js:1474
-#: htdocs/luci-static/resources/view/fchomo/node.js:1513
-#: htdocs/luci-static/resources/view/fchomo/node.js:2559
+#: htdocs/luci-static/resources/fchomo.js:1477
+#: htdocs/luci-static/resources/view/fchomo/node.js:1536
+#: htdocs/luci-static/resources/view/fchomo/node.js:2580
msgid "Override cert DNSName"
msgstr "覆盖证书 DNSName"
@@ -2540,11 +2561,11 @@ msgid "Override destination"
msgstr "覆盖目标地址"
#: htdocs/luci-static/resources/view/fchomo/client.js:1051
-#: htdocs/luci-static/resources/view/fchomo/node.js:2314
+#: htdocs/luci-static/resources/view/fchomo/node.js:2335
msgid "Override fields"
msgstr "覆盖字段"
-#: htdocs/luci-static/resources/view/fchomo/node.js:636
+#: htdocs/luci-static/resources/view/fchomo/node.js:646
msgid "Override the IP address of the server that DNS response."
msgstr "覆盖 DNS 回应的服务器的 IP 地址。"
@@ -2560,7 +2581,7 @@ msgstr "使用嗅探到的域名覆盖连接目标。"
msgid "Override the existing ECS in original request."
msgstr "覆盖原始请求中已有的 ECS。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1568
+#: htdocs/luci-static/resources/view/fchomo/node.js:1591
msgid "Overrides the domain name used for HTTPS record queries."
msgstr "覆盖用于 HTTPS 记录查询的域名。"
@@ -2568,42 +2589,42 @@ msgstr "覆盖用于 HTTPS 记录查询的域名。"
msgid "Overview"
msgstr "概览"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1936
+#: htdocs/luci-static/resources/view/fchomo/node.js:1957
msgid "POST"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1937
+#: htdocs/luci-static/resources/view/fchomo/node.js:1958
msgid "PUT"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:572
+#: htdocs/luci-static/resources/view/fchomo/node.js:582
msgid "Packet encoding"
msgstr "数据包编码"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2014
+#: htdocs/luci-static/resources/view/fchomo/node.js:2035
msgid "Padding bytes"
msgstr "填充字节"
-#: htdocs/luci-static/resources/fchomo/listeners.js:455
+#: htdocs/luci-static/resources/fchomo/listeners.js:464
msgid "Padding scheme"
msgstr "填充方案"
-#: htdocs/luci-static/resources/fchomo/listeners.js:879
-#: htdocs/luci-static/resources/view/fchomo/node.js:1402
+#: htdocs/luci-static/resources/fchomo/listeners.js:897
+#: htdocs/luci-static/resources/view/fchomo/node.js:1425
msgid "Paddings"
msgstr "填充 (Paddings)"
#: htdocs/luci-static/resources/fchomo/listeners.js:167
#: htdocs/luci-static/resources/fchomo/listeners.js:184
-#: htdocs/luci-static/resources/fchomo/listeners.js:745
+#: htdocs/luci-static/resources/fchomo/listeners.js:763
#: htdocs/luci-static/resources/view/fchomo/node.js:327
#: htdocs/luci-static/resources/view/fchomo/node.js:348
-#: htdocs/luci-static/resources/view/fchomo/node.js:1327
+#: htdocs/luci-static/resources/view/fchomo/node.js:1350
msgid "Password"
msgstr "密码"
-#: htdocs/luci-static/resources/fchomo/listeners.js:596
-#: htdocs/luci-static/resources/view/fchomo/node.js:790
+#: htdocs/luci-static/resources/fchomo/listeners.js:605
+#: htdocs/luci-static/resources/view/fchomo/node.js:800
msgid "Path MTU Discovery"
msgstr "路径 MTU 发现"
@@ -2615,17 +2636,17 @@ msgstr "捆绑包路径"
msgid "Path in bundle: %s"
msgstr "在捆绑包%s中的路径"
-#: htdocs/luci-static/resources/fchomo/listeners.js:819
-#: htdocs/luci-static/resources/view/fchomo/node.js:2378
+#: htdocs/luci-static/resources/fchomo/listeners.js:837
+#: htdocs/luci-static/resources/view/fchomo/node.js:2399
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:384
msgid "Payload"
msgstr "Payload"
-#: htdocs/luci-static/resources/view/fchomo/node.js:929
+#: htdocs/luci-static/resources/view/fchomo/node.js:939
msgid "Peer public key"
msgstr "对端公钥"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1068
+#: htdocs/luci-static/resources/view/fchomo/node.js:1078
msgid "Peers"
msgstr "对等端点"
@@ -2635,15 +2656,15 @@ msgid ""
"it is not needed."
msgstr "性能可能会略有下降,建议仅在需要时开启。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:956
+#: htdocs/luci-static/resources/view/fchomo/node.js:966
msgid "Periodically sends data packets to maintain connection persistence."
msgstr "定期发送数据包以维持连接持久性。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:955
+#: htdocs/luci-static/resources/view/fchomo/node.js:965
msgid "Persistent keepalive"
msgstr "持久连接"
-#: htdocs/luci-static/resources/view/fchomo/node.js:830
+#: htdocs/luci-static/resources/view/fchomo/node.js:840
msgid "Physical MTU"
msgstr "物理 MTU"
@@ -2666,8 +2687,8 @@ msgid ""
"standards."
msgstr "链接格式标准请参考 %s。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2351
-#: htdocs/luci-static/resources/view/fchomo/node.js:2377
+#: htdocs/luci-static/resources/view/fchomo/node.js:2372
+#: htdocs/luci-static/resources/view/fchomo/node.js:2398
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:357
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:383
msgid ""
@@ -2682,13 +2703,13 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1541
#: htdocs/luci-static/resources/view/fchomo/client.js:1796
#: htdocs/luci-static/resources/view/fchomo/client.js:1848
-#: htdocs/luci-static/resources/view/fchomo/node.js:2204
+#: htdocs/luci-static/resources/view/fchomo/node.js:2225
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:165
msgid "Please type %s fields of mihomo config."
msgstr "请输入 mihomo 配置的 %s 字段。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:682
-#: htdocs/luci-static/resources/view/fchomo/node.js:1270
+#: htdocs/luci-static/resources/fchomo/listeners.js:691
+#: htdocs/luci-static/resources/view/fchomo/node.js:1284
msgid "Plugin"
msgstr "插件"
@@ -2697,8 +2718,8 @@ msgstr "插件"
msgid "Plugin fields"
msgstr "插件字段"
-#: htdocs/luci-static/resources/fchomo/listeners.js:688
-#: htdocs/luci-static/resources/view/fchomo/node.js:1276
+#: htdocs/luci-static/resources/fchomo/listeners.js:697
+#: htdocs/luci-static/resources/view/fchomo/node.js:1290
msgid "Plugin type"
msgstr "插件类型"
@@ -2707,11 +2728,11 @@ msgstr "插件类型"
msgid "Port"
msgstr "端口"
-#: htdocs/luci-static/resources/fchomo.js:1729
+#: htdocs/luci-static/resources/fchomo.js:1731
msgid "Port %s alrealy exists!"
msgstr "端口 %s 已存在!"
-#: htdocs/luci-static/resources/view/fchomo/node.js:711
+#: htdocs/luci-static/resources/view/fchomo/node.js:721
msgid "Port hop interval"
msgstr "端口跳跃间隔"
@@ -2724,18 +2745,18 @@ msgid "Ports"
msgstr "端口"
#: htdocs/luci-static/resources/fchomo/listeners.js:154
-#: htdocs/luci-static/resources/view/fchomo/node.js:706
+#: htdocs/luci-static/resources/view/fchomo/node.js:716
msgid "Ports pool"
msgstr "端口池"
#: htdocs/luci-static/resources/fchomo/listeners.js:392
-#: htdocs/luci-static/resources/fchomo/listeners.js:531
+#: htdocs/luci-static/resources/fchomo/listeners.js:540
#: htdocs/luci-static/resources/view/fchomo/node.js:507
-#: htdocs/luci-static/resources/view/fchomo/node.js:936
+#: htdocs/luci-static/resources/view/fchomo/node.js:946
msgid "Pre-shared key"
msgstr "预共享密钥"
-#: htdocs/luci-static/resources/fchomo.js:1437
+#: htdocs/luci-static/resources/fchomo.js:1440
msgid "Pre-shared key of rendezvous server"
msgstr "牵线服务器的预共享密钥"
@@ -2752,34 +2773,34 @@ msgid ""
"Prevent ICMP loopback issues in some cases. Ping will not show real delay."
msgstr "防止某些情况下的 ICMP 环回问题。Ping 不会显示实际延迟。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1685
-#: htdocs/luci-static/resources/view/fchomo/node.js:1686
+#: htdocs/luci-static/resources/view/fchomo/node.js:1707
+#: htdocs/luci-static/resources/view/fchomo/node.js:1708
msgid "Primary"
msgstr "主要"
#: htdocs/luci-static/resources/view/fchomo/global.js:768
#: htdocs/luci-static/resources/view/fchomo/global.js:785
-#: htdocs/luci-static/resources/view/fchomo/node.js:2165
-#: htdocs/luci-static/resources/view/fchomo/node.js:2172
-#: htdocs/luci-static/resources/view/fchomo/node.js:2584
-#: htdocs/luci-static/resources/view/fchomo/node.js:2591
+#: htdocs/luci-static/resources/view/fchomo/node.js:2186
+#: htdocs/luci-static/resources/view/fchomo/node.js:2193
+#: htdocs/luci-static/resources/view/fchomo/node.js:2605
+#: htdocs/luci-static/resources/view/fchomo/node.js:2612
msgid "Priority: Proxy Node > Global."
msgstr "优先级: 代理节点 > 全局。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1180
+#: htdocs/luci-static/resources/view/fchomo/node.js:1194
msgid "Priv-key"
msgstr "密钥"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1184
+#: htdocs/luci-static/resources/view/fchomo/node.js:1198
msgid "Priv-key passphrase"
msgstr "密钥密码"
-#: htdocs/luci-static/resources/view/fchomo/node.js:908
-#: htdocs/luci-static/resources/view/fchomo/node.js:1001
+#: htdocs/luci-static/resources/view/fchomo/node.js:918
+#: htdocs/luci-static/resources/view/fchomo/node.js:1011
msgid "Private key"
msgstr "私钥"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1056
+#: htdocs/luci-static/resources/view/fchomo/node.js:1066
msgid "Private room"
msgstr "私密房间"
@@ -2791,33 +2812,33 @@ msgstr "进程"
msgid "Process matching mode"
msgstr "进程匹配模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2510
+#: htdocs/luci-static/resources/view/fchomo/node.js:2531
msgid "Programmable replacement"
msgstr "可编程替换"
#: htdocs/luci-static/resources/view/fchomo/global.js:716
-#: htdocs/luci-static/resources/view/fchomo/node.js:2075
+#: htdocs/luci-static/resources/view/fchomo/node.js:2096
msgid "Protocol"
msgstr "协议"
-#: htdocs/luci-static/resources/view/fchomo/node.js:567
+#: htdocs/luci-static/resources/view/fchomo/node.js:577
msgid "Protocol parameter. Enable length block encryption."
msgstr "协议参数。启用长度块加密。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:561
+#: htdocs/luci-static/resources/view/fchomo/node.js:571
msgid ""
"Protocol parameter. Will waste traffic randomly if enabled (enabled by "
"default in v2ray and cannot be disabled)."
msgstr "协议参数。 如启用会随机浪费流量(在 v2ray 中默认启用并且无法禁用)。"
#: htdocs/luci-static/resources/view/fchomo/client.js:1108
-#: htdocs/luci-static/resources/view/fchomo/node.js:2187
-#: htdocs/luci-static/resources/view/fchomo/node.js:2196
-#: htdocs/luci-static/resources/view/fchomo/node.js:2725
+#: htdocs/luci-static/resources/view/fchomo/node.js:2208
+#: htdocs/luci-static/resources/view/fchomo/node.js:2217
+#: htdocs/luci-static/resources/view/fchomo/node.js:2746
msgid "Provider"
msgstr "供应商"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2384
+#: htdocs/luci-static/resources/view/fchomo/node.js:2405
msgid "Provider URL"
msgstr "供应商订阅 URL"
@@ -2840,20 +2861,20 @@ msgid "Proxy MAC-s"
msgstr "代理 MAC 地址"
#: htdocs/luci-static/resources/view/fchomo/node.js:225
-#: htdocs/luci-static/resources/view/fchomo/node.js:2724
+#: htdocs/luci-static/resources/view/fchomo/node.js:2745
msgid "Proxy Node"
msgstr "代理节点"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2700
-#: htdocs/luci-static/resources/view/fchomo/node.js:2709
+#: htdocs/luci-static/resources/view/fchomo/node.js:2721
+#: htdocs/luci-static/resources/view/fchomo/node.js:2730
msgid "Proxy chain"
msgstr "代理链"
-#: htdocs/luci-static/resources/fchomo/listeners.js:629
-#: htdocs/luci-static/resources/fchomo/listeners.js:1009
+#: htdocs/luci-static/resources/fchomo/listeners.js:638
+#: htdocs/luci-static/resources/fchomo/listeners.js:1027
#: htdocs/luci-static/resources/view/fchomo/client.js:809
#: htdocs/luci-static/resources/view/fchomo/client.js:1639
-#: htdocs/luci-static/resources/view/fchomo/node.js:2402
+#: htdocs/luci-static/resources/view/fchomo/node.js:2423
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:414
msgid "Proxy group"
msgstr "代理组"
@@ -2870,22 +2891,22 @@ msgstr "代理模式"
msgid "Proxy routerself"
msgstr "代理路由器自身"
-#: htdocs/luci-static/resources/view/fchomo/node.js:925
+#: htdocs/luci-static/resources/view/fchomo/node.js:935
msgid "Public key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:645
-#: htdocs/luci-static/resources/view/fchomo/node.js:801
+#: htdocs/luci-static/resources/view/fchomo/node.js:655
+#: htdocs/luci-static/resources/view/fchomo/node.js:811
msgid "QUIC"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:567
-#: htdocs/luci-static/resources/view/fchomo/node.js:754
+#: htdocs/luci-static/resources/fchomo/listeners.js:576
+#: htdocs/luci-static/resources/view/fchomo/node.js:764
msgid "QUIC based 0-RTT"
msgstr "基于 QUIC 的 0-RTT"
-#: htdocs/luci-static/resources/fchomo/listeners.js:561
-#: htdocs/luci-static/resources/view/fchomo/node.js:743
+#: htdocs/luci-static/resources/fchomo/listeners.js:570
+#: htdocs/luci-static/resources/view/fchomo/node.js:753
msgid "QUIC versions"
msgstr "QUIC 版本"
@@ -2894,39 +2915,39 @@ msgstr "QUIC 版本"
msgid "Quick Reload"
msgstr "快速重载"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1127
-#: htdocs/luci-static/resources/fchomo/listeners.js:1233
-#: htdocs/luci-static/resources/view/fchomo/node.js:1582
+#: htdocs/luci-static/resources/fchomo/listeners.js:1145
+#: htdocs/luci-static/resources/fchomo/listeners.js:1251
+#: htdocs/luci-static/resources/view/fchomo/node.js:1605
msgid "REALITY"
msgstr "REALITY"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1608
+#: htdocs/luci-static/resources/view/fchomo/node.js:1631
msgid "REALITY X25519MLKEM768 PQC support"
msgstr "REALITY X25519MLKEM768 后量子加密支持"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1281
+#: htdocs/luci-static/resources/fchomo/listeners.js:1299
msgid "REALITY certificate issued to"
msgstr "REALITY 证书颁发给"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1249
+#: htdocs/luci-static/resources/fchomo/listeners.js:1267
msgid "REALITY handshake server"
msgstr "REALITY 握手服务器"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1288
+#: htdocs/luci-static/resources/fchomo/listeners.js:1306
msgid "REALITY max time difference"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1256
+#: htdocs/luci-static/resources/fchomo/listeners.js:1274
msgid "REALITY private key"
msgstr "REALITY 私钥"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1271
-#: htdocs/luci-static/resources/view/fchomo/node.js:1598
+#: htdocs/luci-static/resources/fchomo/listeners.js:1289
+#: htdocs/luci-static/resources/view/fchomo/node.js:1621
msgid "REALITY public key"
msgstr "REALITY 公钥"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1275
-#: htdocs/luci-static/resources/view/fchomo/node.js:1603
+#: htdocs/luci-static/resources/fchomo/listeners.js:1293
+#: htdocs/luci-static/resources/view/fchomo/node.js:1626
msgid "REALITY short ID"
msgstr "REALITY 标识符"
@@ -2940,9 +2961,9 @@ msgstr ""
msgid "REMATCH-NAME marking"
msgstr "REMATCH-NAME 打标"
-#: htdocs/luci-static/resources/fchomo/listeners.js:850
-#: htdocs/luci-static/resources/fchomo/listeners.js:869
-#: htdocs/luci-static/resources/view/fchomo/node.js:1392
+#: htdocs/luci-static/resources/fchomo/listeners.js:868
+#: htdocs/luci-static/resources/fchomo/listeners.js:887
+#: htdocs/luci-static/resources/view/fchomo/node.js:1415
msgid "RTT"
msgstr ""
@@ -2962,19 +2983,19 @@ msgstr "留空将使用随机令牌。"
msgid "Randomized traffic characteristics"
msgstr "随机化流量特征"
-#: htdocs/luci-static/resources/fchomo.js:1426
+#: htdocs/luci-static/resources/fchomo.js:1429
msgid "Realm"
msgstr "Realm"
-#: htdocs/luci-static/resources/fchomo.js:1442
+#: htdocs/luci-static/resources/fchomo.js:1445
msgid "Realm ID"
msgstr "Realm ID"
-#: htdocs/luci-static/resources/fchomo/listeners.js:554
+#: htdocs/luci-static/resources/fchomo/listeners.js:563
msgid "Realm name pattern"
msgstr "Realm 名称模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2681
+#: htdocs/luci-static/resources/view/fchomo/node.js:2702
msgid ""
"Recommended to adjust Client DNS configuration based on actual conditions."
msgstr "建议根据实际情况调整客户端 DNS 配置。"
@@ -2995,7 +3016,7 @@ msgstr "Redirect TCP + TProxy UDP"
msgid "Redirect TCP + Tun UDP"
msgstr "Redirect TCP + Tun UDP"
-#: htdocs/luci-static/resources/view/fchomo/node.js:838
+#: htdocs/luci-static/resources/view/fchomo/node.js:848
msgid "Reduces background traffic and network configuration refresh frequency."
msgstr "降低后台流量和网络配置刷新频率。"
@@ -3003,7 +3024,7 @@ msgstr "降低后台流量和网络配置刷新频率。"
msgid "Refresh every %s seconds."
msgstr "每 %s 秒刷新。"
-#: htdocs/luci-static/resources/fchomo.js:1383
+#: htdocs/luci-static/resources/fchomo.js:1386
#: htdocs/luci-static/resources/view/fchomo/client.js:966
#: htdocs/luci-static/resources/view/fchomo/global.js:193
#: htdocs/luci-static/resources/view/fchomo/server.js:45
@@ -3022,46 +3043,46 @@ msgstr "再路由"
msgid "Rematching routing rules"
msgstr "重新匹配路由规则"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2329
+#: htdocs/luci-static/resources/view/fchomo/node.js:2350
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:298
msgid "Remote"
msgstr "远程"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1863
+#: htdocs/luci-static/resources/view/fchomo/node.js:1884
msgid "Remote DNS resolve"
msgstr "远程 DNS 解析"
-#: htdocs/luci-static/resources/view/fchomo/node.js:821
+#: htdocs/luci-static/resources/view/fchomo/node.js:831
msgid "Remote trace level"
msgstr "远程跟踪级别"
-#: htdocs/luci-static/resources/view/fchomo/node.js:814
+#: htdocs/luci-static/resources/view/fchomo/node.js:824
msgid "Remote trace target"
msgstr "远程跟踪目标"
-#: htdocs/luci-static/resources/fchomo.js:1650
+#: htdocs/luci-static/resources/fchomo.js:1652
msgid "Remove"
msgstr "移除"
-#: htdocs/luci-static/resources/fchomo.js:1655
+#: htdocs/luci-static/resources/fchomo.js:1657
#: htdocs/luci-static/resources/view/fchomo/node.js:244
#: htdocs/luci-static/resources/view/fchomo/node.js:246
-#: htdocs/luci-static/resources/view/fchomo/node.js:2305
-#: htdocs/luci-static/resources/view/fchomo/node.js:2307
+#: htdocs/luci-static/resources/view/fchomo/node.js:2326
+#: htdocs/luci-static/resources/view/fchomo/node.js:2328
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:270
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:272
msgid "Remove idles"
msgstr "移除闲置"
-#: htdocs/luci-static/resources/fchomo.js:1431
+#: htdocs/luci-static/resources/fchomo.js:1434
msgid "Rendezvous server"
msgstr "牵线服务器"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2501
+#: htdocs/luci-static/resources/view/fchomo/node.js:2522
msgid "Replace name"
msgstr "名称替换"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2502
+#: htdocs/luci-static/resources/view/fchomo/node.js:2523
msgid "Replace node name."
msgstr "替换节点名称"
@@ -3069,13 +3090,13 @@ msgstr "替换节点名称"
msgid "Request"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1339
-#: htdocs/luci-static/resources/view/fchomo/node.js:1943
-#: htdocs/luci-static/resources/view/fchomo/node.js:1950
+#: htdocs/luci-static/resources/fchomo/listeners.js:1357
+#: htdocs/luci-static/resources/view/fchomo/node.js:1964
+#: htdocs/luci-static/resources/view/fchomo/node.js:1971
msgid "Request path"
msgstr "请求路径"
-#: htdocs/luci-static/resources/view/fchomo/node.js:685
+#: htdocs/luci-static/resources/view/fchomo/node.js:695
msgid "Request timeout"
msgstr "请求超时"
@@ -3088,11 +3109,11 @@ msgid "Require any"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:481
-#: htdocs/luci-static/resources/view/fchomo/node.js:1609
+#: htdocs/luci-static/resources/view/fchomo/node.js:1632
msgid "Requires server support."
msgstr "需要服务器支持。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:950
+#: htdocs/luci-static/resources/view/fchomo/node.js:960
msgid "Reserved field bytes"
msgstr "保留字段字节"
@@ -3100,20 +3121,20 @@ msgstr "保留字段字节"
msgid "Resources management"
msgstr "资源管理"
-#: htdocs/luci-static/resources/fchomo/listeners.js:691
-#: htdocs/luci-static/resources/fchomo/listeners.js:701
-#: htdocs/luci-static/resources/fchomo/listeners.js:706
-#: htdocs/luci-static/resources/fchomo/listeners.js:1125
-#: htdocs/luci-static/resources/fchomo/listeners.js:1241
-#: htdocs/luci-static/resources/view/fchomo/node.js:1281
-#: htdocs/luci-static/resources/view/fchomo/node.js:1291
-#: htdocs/luci-static/resources/view/fchomo/node.js:1296
-#: htdocs/luci-static/resources/view/fchomo/node.js:1590
+#: htdocs/luci-static/resources/fchomo/listeners.js:700
+#: htdocs/luci-static/resources/fchomo/listeners.js:719
+#: htdocs/luci-static/resources/fchomo/listeners.js:724
+#: htdocs/luci-static/resources/fchomo/listeners.js:1143
+#: htdocs/luci-static/resources/fchomo/listeners.js:1259
+#: htdocs/luci-static/resources/view/fchomo/node.js:1295
+#: htdocs/luci-static/resources/view/fchomo/node.js:1314
+#: htdocs/luci-static/resources/view/fchomo/node.js:1319
+#: htdocs/luci-static/resources/view/fchomo/node.js:1613
msgid "Restls"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:760
-#: htdocs/luci-static/resources/view/fchomo/node.js:1350
+#: htdocs/luci-static/resources/fchomo/listeners.js:778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1373
msgid "Restls script"
msgstr "Restls 剧本"
@@ -3136,13 +3157,13 @@ msgstr "重用 HTTP 连接以减少每次建立连接的 RTT。"
msgid "Reusing a single tunnel to carry multiple target connections within it."
msgstr "复用单条隧道使其内部承载多条目标连线。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1046
-#: htdocs/luci-static/resources/view/fchomo/node.js:1058
+#: htdocs/luci-static/resources/view/fchomo/node.js:1056
+#: htdocs/luci-static/resources/view/fchomo/node.js:1068
msgid "Room name"
msgstr "房间名称"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1051
-#: htdocs/luci-static/resources/view/fchomo/node.js:1058
+#: htdocs/luci-static/resources/view/fchomo/node.js:1061
+#: htdocs/luci-static/resources/view/fchomo/node.js:1068
msgid "Room secret"
msgstr "房间密码"
@@ -3159,10 +3180,10 @@ msgstr "路由 DSCP"
msgid "Routing GFW"
msgstr "路由 GFW 流量"
-#: htdocs/luci-static/resources/fchomo/listeners.js:612
+#: htdocs/luci-static/resources/fchomo/listeners.js:621
#: htdocs/luci-static/resources/view/fchomo/global.js:784
-#: htdocs/luci-static/resources/view/fchomo/node.js:2171
-#: htdocs/luci-static/resources/view/fchomo/node.js:2590
+#: htdocs/luci-static/resources/view/fchomo/node.js:2192
+#: htdocs/luci-static/resources/view/fchomo/node.js:2611
msgid "Routing mark (Fwmark)"
msgstr "路由标记 (Fwmark)"
@@ -3210,7 +3231,7 @@ msgstr "规则集"
msgid "Rule set URL"
msgstr "规则集订阅 URL"
-#: htdocs/luci-static/resources/view/fchomo/node.js:824
+#: htdocs/luci-static/resources/view/fchomo/node.js:834
msgid "Rules"
msgstr "规则"
@@ -3222,7 +3243,7 @@ msgstr "规则集"
msgid "Ruleset-URI-Scheme"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1396
+#: htdocs/luci-static/resources/fchomo.js:1399
msgid "Running"
msgstr "正在运行"
@@ -3246,7 +3267,7 @@ msgstr ""
msgid "STUN"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1448
+#: htdocs/luci-static/resources/fchomo.js:1451
msgid "STUN servers"
msgstr "STUN 服务器"
@@ -3254,12 +3275,12 @@ msgstr "STUN 服务器"
msgid "SUB-RULE"
msgstr "SUB-RULE"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1262
+#: htdocs/luci-static/resources/view/fchomo/node.js:1276
msgid "SUoT version"
msgstr "SUoT 版本"
-#: htdocs/luci-static/resources/fchomo/listeners.js:501
-#: htdocs/luci-static/resources/view/fchomo/node.js:719
+#: htdocs/luci-static/resources/fchomo/listeners.js:510
+#: htdocs/luci-static/resources/view/fchomo/node.js:729
msgid "Salamander"
msgstr "Salamander"
@@ -3276,12 +3297,12 @@ msgstr "相同 来源地址 和 目标地址 请求。相同节点"
msgid "Save"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1695
-#: htdocs/luci-static/resources/view/fchomo/node.js:1696
+#: htdocs/luci-static/resources/view/fchomo/node.js:1717
+#: htdocs/luci-static/resources/view/fchomo/node.js:1718
msgid "Secondary"
msgstr "次要"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1074
+#: htdocs/luci-static/resources/view/fchomo/node.js:1084
msgid "Secure mode"
msgstr "安全模式"
@@ -3310,9 +3331,9 @@ msgstr "同时向%s和%s发起查询。"
msgid "Send random ticket of 300s-600s duration for client 0-RTT reuse."
msgstr "发送 300-600 秒的随机票证,以供客户端 0-RTT 重用。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:850
-#: htdocs/luci-static/resources/fchomo/listeners.js:1116
-#: htdocs/luci-static/resources/fchomo/listeners.js:1146
+#: htdocs/luci-static/resources/fchomo/listeners.js:868
+#: htdocs/luci-static/resources/fchomo/listeners.js:1134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1164
#: htdocs/luci-static/resources/view/fchomo/server.js:58
#: root/usr/share/luci/menu.d/luci-app-fchomo.json:62
msgid "Server"
@@ -3322,13 +3343,13 @@ msgstr "服务端"
msgid "Server address"
msgstr "服务器地址"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1333
-#: htdocs/luci-static/resources/view/fchomo/node.js:1922
-#: htdocs/luci-static/resources/view/fchomo/node.js:1928
+#: htdocs/luci-static/resources/fchomo/listeners.js:1351
+#: htdocs/luci-static/resources/view/fchomo/node.js:1943
+#: htdocs/luci-static/resources/view/fchomo/node.js:1949
msgid "Server hostname"
msgstr "服务器主机名称"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1009
+#: htdocs/luci-static/resources/view/fchomo/node.js:1019
msgid "Server public key"
msgstr "服务器公钥"
@@ -3345,15 +3366,15 @@ msgstr "服务状态"
msgid "ShadowQUIC"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:690
-#: htdocs/luci-static/resources/fchomo/listeners.js:700
-#: htdocs/luci-static/resources/fchomo/listeners.js:705
-#: htdocs/luci-static/resources/fchomo/listeners.js:1124
-#: htdocs/luci-static/resources/fchomo/listeners.js:1240
-#: htdocs/luci-static/resources/view/fchomo/node.js:1280
-#: htdocs/luci-static/resources/view/fchomo/node.js:1290
-#: htdocs/luci-static/resources/view/fchomo/node.js:1295
-#: htdocs/luci-static/resources/view/fchomo/node.js:1589
+#: htdocs/luci-static/resources/fchomo/listeners.js:699
+#: htdocs/luci-static/resources/fchomo/listeners.js:718
+#: htdocs/luci-static/resources/fchomo/listeners.js:723
+#: htdocs/luci-static/resources/fchomo/listeners.js:1142
+#: htdocs/luci-static/resources/fchomo/listeners.js:1258
+#: htdocs/luci-static/resources/view/fchomo/node.js:1294
+#: htdocs/luci-static/resources/view/fchomo/node.js:1313
+#: htdocs/luci-static/resources/view/fchomo/node.js:1318
+#: htdocs/luci-static/resources/view/fchomo/node.js:1612
msgid "ShadowTLS"
msgstr ""
@@ -3362,22 +3383,22 @@ msgstr ""
msgid "Shadowsocks"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:437
-#: htdocs/luci-static/resources/view/fchomo/node.js:585
+#: htdocs/luci-static/resources/fchomo/listeners.js:446
+#: htdocs/luci-static/resources/view/fchomo/node.js:595
msgid "Shadowsocks chipher"
msgstr "Shadowsocks 加密方法"
-#: htdocs/luci-static/resources/fchomo/listeners.js:432
-#: htdocs/luci-static/resources/view/fchomo/node.js:580
+#: htdocs/luci-static/resources/fchomo/listeners.js:441
+#: htdocs/luci-static/resources/view/fchomo/node.js:590
msgid "Shadowsocks encrypt"
msgstr "Shadowsocks 加密"
-#: htdocs/luci-static/resources/fchomo/listeners.js:445
-#: htdocs/luci-static/resources/view/fchomo/node.js:593
+#: htdocs/luci-static/resources/fchomo/listeners.js:454
+#: htdocs/luci-static/resources/view/fchomo/node.js:603
msgid "Shadowsocks password"
msgstr "Shadowsocks 密码"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2123
+#: htdocs/luci-static/resources/view/fchomo/node.js:2144
msgid "Show connections in the dashboard for breaking connections easier."
msgstr "在面板中显示连接以便于打断连接。"
@@ -3389,15 +3410,15 @@ msgstr "静音"
msgid "Simple round-robin all nodes"
msgstr "简单轮替所有节点"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2390
+#: htdocs/luci-static/resources/view/fchomo/node.js:2411
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:402
msgid "Size limit"
msgstr "大小限制"
-#: htdocs/luci-static/resources/fchomo.js:1480
+#: htdocs/luci-static/resources/fchomo.js:1483
#: htdocs/luci-static/resources/view/fchomo/client.js:1675
-#: htdocs/luci-static/resources/view/fchomo/node.js:1519
-#: htdocs/luci-static/resources/view/fchomo/node.js:2565
+#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/view/fchomo/node.js:2586
msgid "Skip cert verify"
msgstr "跳过证书验证"
@@ -3466,12 +3487,12 @@ msgstr ""
msgid "Strategy"
msgstr "策略"
-#: htdocs/luci-static/resources/fchomo/listeners.js:584
-#: htdocs/luci-static/resources/view/fchomo/node.js:778
+#: htdocs/luci-static/resources/fchomo/listeners.js:593
+#: htdocs/luci-static/resources/view/fchomo/node.js:788
msgid "Stream-level receive window size"
msgstr "流级接收窗口大小"
-#: htdocs/luci-static/resources/fchomo/listeners.js:617
+#: htdocs/luci-static/resources/fchomo/listeners.js:626
#: htdocs/luci-static/resources/view/fchomo/client.js:1396
#: htdocs/luci-static/resources/view/fchomo/client.js:1405
msgid "Sub rule"
@@ -3481,11 +3502,11 @@ msgstr "子规则"
msgid "Sub rule group"
msgstr "子规则组"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1123
+#: htdocs/luci-static/resources/view/fchomo/node.js:1137
msgid "Subnet proxy"
msgstr "子网代理"
-#: htdocs/luci-static/resources/fchomo.js:870
+#: htdocs/luci-static/resources/fchomo.js:873
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:242
msgid "Successfully imported %s %s of total %s."
msgstr "已成功导入 %s 个%s (共 %s 个)。"
@@ -3494,7 +3515,7 @@ msgstr "已成功导入 %s 个%s (共 %s 个)。"
msgid "Successfully updated."
msgstr "更新成功。"
-#: htdocs/luci-static/resources/fchomo.js:2020
+#: htdocs/luci-static/resources/fchomo.js:2022
msgid "Successfully uploaded."
msgstr "已成功上传。"
@@ -3503,7 +3524,7 @@ msgstr "已成功上传。"
msgid "Sudoku"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:744
+#: htdocs/luci-static/resources/view/fchomo/node.js:754
msgid "Support %s, default %s."
msgstr "支持 %s,默认 %s。"
@@ -3538,7 +3559,7 @@ msgstr "系统 DNS"
#: htdocs/luci-static/resources/fchomo.js:237
#: htdocs/luci-static/resources/fchomo.js:238
#: htdocs/luci-static/resources/fchomo.js:249
-#: htdocs/luci-static/resources/fchomo/listeners.js:670
+#: htdocs/luci-static/resources/fchomo/listeners.js:679
#: htdocs/luci-static/resources/view/fchomo/client.js:618
#: htdocs/luci-static/resources/view/fchomo/client.js:707
msgid "TCP"
@@ -3552,7 +3573,7 @@ msgstr "TCP 并发"
msgid "TCP idle timeout"
msgstr "TCP 闲置超时"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2116
+#: htdocs/luci-static/resources/view/fchomo/node.js:2137
msgid "TCP only"
msgstr "仅 TCP"
@@ -3580,36 +3601,36 @@ msgstr "TCP-Keep-Alive 间隔"
msgid "TCP/UDP"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2147
-#: htdocs/luci-static/resources/view/fchomo/node.js:2526
+#: htdocs/luci-static/resources/view/fchomo/node.js:2168
+#: htdocs/luci-static/resources/view/fchomo/node.js:2547
msgid "TFO"
msgstr "TCP 快速打开 (TFO)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1171
+#: htdocs/luci-static/resources/view/fchomo/node.js:1185
msgid "TLD DNS zone"
msgstr "TLD DNS 区域"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1172
+#: htdocs/luci-static/resources/view/fchomo/node.js:1186
msgid "TLD DNS zone used by MagicDNS, default is %s."
msgstr "MagicDNS 使用的 TLD DNS 区域,默认为 %s。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:718
-#: htdocs/luci-static/resources/fchomo/listeners.js:1026
+#: htdocs/luci-static/resources/fchomo/listeners.js:736
+#: htdocs/luci-static/resources/fchomo/listeners.js:1044
#: htdocs/luci-static/resources/view/fchomo/global.js:558
#: htdocs/luci-static/resources/view/fchomo/node.js:472
-#: htdocs/luci-static/resources/view/fchomo/node.js:1308
-#: htdocs/luci-static/resources/view/fchomo/node.js:1429
+#: htdocs/luci-static/resources/view/fchomo/node.js:1331
+#: htdocs/luci-static/resources/view/fchomo/node.js:1452
msgid "TLS"
msgstr "TLS"
-#: htdocs/luci-static/resources/fchomo.js:1462
-#: htdocs/luci-static/resources/fchomo/listeners.js:1067
-#: htdocs/luci-static/resources/view/fchomo/node.js:1460
+#: htdocs/luci-static/resources/fchomo.js:1465
+#: htdocs/luci-static/resources/fchomo/listeners.js:1085
+#: htdocs/luci-static/resources/view/fchomo/node.js:1483
msgid "TLS ALPN"
msgstr "TLS ALPN"
-#: htdocs/luci-static/resources/fchomo.js:1457
-#: htdocs/luci-static/resources/view/fchomo/node.js:1454
+#: htdocs/luci-static/resources/fchomo.js:1460
+#: htdocs/luci-static/resources/view/fchomo/node.js:1477
msgid "TLS SNI"
msgstr ""
@@ -3628,44 +3649,44 @@ msgid "TURN"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:246
-#: htdocs/luci-static/resources/view/fchomo/node.js:962
+#: htdocs/luci-static/resources/view/fchomo/node.js:972
msgid "Tailscale"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:604
+#: htdocs/luci-static/resources/fchomo/listeners.js:613
msgid "Target address"
msgstr "目标地址"
-#: htdocs/luci-static/resources/fchomo/listeners.js:493
+#: htdocs/luci-static/resources/fchomo/listeners.js:502
msgid ""
"Tell the client to use the BBR flow control algorithm instead of Hysteria CC."
msgstr "让客户端使用 BBR 流控算法。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1766
-#: htdocs/luci-static/resources/view/fchomo/node.js:1770
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
-#: htdocs/luci-static/resources/view/fchomo/node.js:1798
-#: htdocs/luci-static/resources/view/fchomo/node.js:1802
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1787
+#: htdocs/luci-static/resources/view/fchomo/node.js:1791
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
+#: htdocs/luci-static/resources/view/fchomo/node.js:1819
+#: htdocs/luci-static/resources/view/fchomo/node.js:1823
msgid "The %s address used by local machine in the %s network."
msgstr "本机 %s 地址,用于在 %s 网络中使用。"
-#: htdocs/luci-static/resources/fchomo.js:1495
-#: htdocs/luci-static/resources/fchomo/listeners.js:1146
-#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/fchomo.js:1498
+#: htdocs/luci-static/resources/fchomo/listeners.js:1164
+#: htdocs/luci-static/resources/view/fchomo/node.js:1565
msgid "The %s private key, in PEM format."
msgstr "%s私钥,需要 PEM 格式。"
-#: htdocs/luci-static/resources/fchomo.js:1489
-#: htdocs/luci-static/resources/fchomo/listeners.js:1116
-#: htdocs/luci-static/resources/fchomo/listeners.js:1169
+#: htdocs/luci-static/resources/fchomo.js:1492
+#: htdocs/luci-static/resources/fchomo/listeners.js:1134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1187
#: htdocs/luci-static/resources/view/fchomo/global.js:579
-#: htdocs/luci-static/resources/view/fchomo/node.js:1528
+#: htdocs/luci-static/resources/view/fchomo/node.js:1551
msgid "The %s public key, in PEM format."
msgstr "%s公钥,需要 PEM 格式。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1562
+#: htdocs/luci-static/resources/view/fchomo/node.js:1585
msgid ""
"The ECH parameter of the HTTPS record for the domain. Leave empty to resolve "
"via DNS."
@@ -3679,7 +3700,7 @@ msgstr "Sudoku 服务器提供的 ED25519 可用私钥 或 UUID。"
msgid "The ED25519 master public key or UUID generated by Sudoku."
msgstr "Sudoku 生成的 ED25519 主公钥 或 UUID。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:604
+#: htdocs/luci-static/resources/view/fchomo/node.js:614
msgid "The client metadata sent to the server."
msgstr "发送到服务器的客户端元数据。"
@@ -3687,14 +3708,14 @@ msgstr "发送到服务器的客户端元数据。"
msgid "The default value is 2:00 every day."
msgstr "默认值为每天 2:00。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1244
+#: htdocs/luci-static/resources/view/fchomo/node.js:1258
msgid ""
"The default value is %s, indicating that only the outer "
"connection timeout is used."
msgstr "默认值为%s,表示仅使用外层连接超时。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:882
-#: htdocs/luci-static/resources/view/fchomo/node.js:1405
+#: htdocs/luci-static/resources/fchomo/listeners.js:900
+#: htdocs/luci-static/resources/view/fchomo/node.js:1428
msgid ""
"The first padding must have a probability of 100% and at least 35 bytes."
msgstr "首个填充必须为 100% 的概率并且至少 35 字节。"
@@ -3709,35 +3730,35 @@ msgstr "匹配 %s 的将被视为未被投毒污染。"
msgid "The matching %s will be deemed as poisoned."
msgstr "匹配 %s 的将被视为已被投毒污染。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:768
+#: htdocs/luci-static/resources/fchomo/listeners.js:786
msgid "The proxy used to connect to the handshake target."
msgstr "用于连接握手目标的代理。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1010
+#: htdocs/luci-static/resources/fchomo/listeners.js:1028
msgid "The proxy used to connect to the rendezvous server."
msgstr "用于连接牵线服务器的代理。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:880
-#: htdocs/luci-static/resources/view/fchomo/node.js:1403
+#: htdocs/luci-static/resources/fchomo/listeners.js:898
+#: htdocs/luci-static/resources/view/fchomo/node.js:1426
msgid "The server and client can set different padding parameters."
msgstr "服务器和客户端可以设置不同的填充参数。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1227
+#: htdocs/luci-static/resources/fchomo/listeners.js:1245
#: htdocs/luci-static/resources/view/fchomo/global.js:623
msgid "This ECH parameter needs to be added to the HTTPS record of the domain."
msgstr "此 ECH 参数需要添加到域名的 HTTPS 记录中。"
-#: htdocs/luci-static/resources/fchomo.js:1483
+#: htdocs/luci-static/resources/fchomo.js:1486
#: htdocs/luci-static/resources/view/fchomo/client.js:1678
-#: htdocs/luci-static/resources/view/fchomo/node.js:1522
-#: htdocs/luci-static/resources/view/fchomo/node.js:2568
+#: htdocs/luci-static/resources/view/fchomo/node.js:1545
+#: htdocs/luci-static/resources/view/fchomo/node.js:2589
msgid ""
"This is DANGEROUS, your traffic is almost like "
"PLAIN TEXT! Use at your own risk!"
msgstr ""
"这是危险行为,您的流量将几乎等同于明文!使用风险自负!"
-#: htdocs/luci-static/resources/view/fchomo/node.js:650
+#: htdocs/luci-static/resources/view/fchomo/node.js:660
msgid ""
"This is the TUIC port of the SUoT protocol, designed to provide a QUIC "
"stream based UDP relay mode that TUIC does not provide."
@@ -3769,23 +3790,28 @@ msgstr "Tproxy Fwmark/fwmask"
msgid "Tproxy port"
msgstr "Tproxy 端口"
+#: htdocs/luci-static/resources/fchomo/listeners.js:410
+#: htdocs/luci-static/resources/view/fchomo/node.js:530
+msgid "Traffic mode"
+msgstr "流量模式"
+
#: htdocs/luci-static/resources/fchomo/listeners.js:213
#: htdocs/luci-static/resources/view/fchomo/node.js:386
msgid "Traffic pattern"
msgstr "流量模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2762
+#: htdocs/luci-static/resources/view/fchomo/node.js:2783
msgid "Transit proxy group"
msgstr "中转代理组"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2773
+#: htdocs/luci-static/resources/view/fchomo/node.js:2794
msgid "Transit proxy node"
msgstr "中转代理节点"
#: htdocs/luci-static/resources/fchomo/listeners.js:194
-#: htdocs/luci-static/resources/fchomo/listeners.js:1297
+#: htdocs/luci-static/resources/fchomo/listeners.js:1315
#: htdocs/luci-static/resources/view/fchomo/node.js:363
-#: htdocs/luci-static/resources/view/fchomo/node.js:1875
+#: htdocs/luci-static/resources/view/fchomo/node.js:1896
msgid "Transport"
msgstr "传输层"
@@ -3794,8 +3820,8 @@ msgstr "传输层"
msgid "Transport fields"
msgstr "传输层字段"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1302
-#: htdocs/luci-static/resources/view/fchomo/node.js:1880
+#: htdocs/luci-static/resources/fchomo/listeners.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1901
msgid "Transport type"
msgstr "传输层类型"
@@ -3813,7 +3839,7 @@ msgstr ""
msgid "TrustTunnel"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:549
+#: htdocs/luci-static/resources/fchomo/listeners.js:558
msgid "Trusted proxy header"
msgstr "可信代理 Header"
@@ -3837,7 +3863,7 @@ msgstr "Tun 堆栈"
msgid "Tunnel"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:852
+#: htdocs/luci-static/resources/view/fchomo/node.js:862
msgid "Turns TCP relay off."
msgstr "关闭 TCP 中继。"
@@ -3848,8 +3874,8 @@ msgstr "关闭 TCP 中继。"
#: htdocs/luci-static/resources/view/fchomo/client.js:871
#: htdocs/luci-static/resources/view/fchomo/client.js:1069
#: htdocs/luci-static/resources/view/fchomo/node.js:271
-#: htdocs/luci-static/resources/view/fchomo/node.js:2327
-#: htdocs/luci-static/resources/view/fchomo/node.js:2723
+#: htdocs/luci-static/resources/view/fchomo/node.js:2348
+#: htdocs/luci-static/resources/view/fchomo/node.js:2744
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:296
msgid "Type"
msgstr "类型"
@@ -3864,11 +3890,11 @@ msgstr "类型"
#: htdocs/luci-static/resources/fchomo.js:245
#: htdocs/luci-static/resources/fchomo.js:246
#: htdocs/luci-static/resources/fchomo.js:247
-#: htdocs/luci-static/resources/fchomo/listeners.js:671
-#: htdocs/luci-static/resources/fchomo/listeners.js:676
+#: htdocs/luci-static/resources/fchomo/listeners.js:680
+#: htdocs/luci-static/resources/fchomo/listeners.js:685
#: htdocs/luci-static/resources/view/fchomo/client.js:617
#: htdocs/luci-static/resources/view/fchomo/client.js:706
-#: htdocs/luci-static/resources/view/fchomo/node.js:2536
+#: htdocs/luci-static/resources/view/fchomo/node.js:2557
msgid "UDP"
msgstr "UDP"
@@ -3876,20 +3902,20 @@ msgstr "UDP"
msgid "UDP NAT expiration time"
msgstr "UDP NAT 过期时间"
-#: htdocs/luci-static/resources/view/fchomo/node.js:649
-#: htdocs/luci-static/resources/view/fchomo/node.js:749
+#: htdocs/luci-static/resources/view/fchomo/node.js:659
+#: htdocs/luci-static/resources/view/fchomo/node.js:759
msgid "UDP over stream"
msgstr "UDP over stream"
-#: htdocs/luci-static/resources/view/fchomo/node.js:655
+#: htdocs/luci-static/resources/view/fchomo/node.js:665
msgid "UDP over stream version"
msgstr "UDP over stream 版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:642
+#: htdocs/luci-static/resources/view/fchomo/node.js:652
msgid "UDP packet relay mode."
msgstr "UDP 包中继模式。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:641
+#: htdocs/luci-static/resources/view/fchomo/node.js:651
msgid "UDP relay mode"
msgstr "UDP 中继模式"
@@ -3905,14 +3931,14 @@ msgid "URL test"
msgstr "自动选择"
#: htdocs/luci-static/resources/fchomo/listeners.js:222
-#: htdocs/luci-static/resources/fchomo/listeners.js:410
-#: htdocs/luci-static/resources/fchomo/listeners.js:460
-#: htdocs/luci-static/resources/view/fchomo/node.js:530
-#: htdocs/luci-static/resources/view/fchomo/node.js:629
+#: htdocs/luci-static/resources/fchomo/listeners.js:419
+#: htdocs/luci-static/resources/fchomo/listeners.js:469
+#: htdocs/luci-static/resources/view/fchomo/node.js:540
+#: htdocs/luci-static/resources/view/fchomo/node.js:639
msgid "UUID"
msgstr "UUID"
-#: htdocs/luci-static/resources/fchomo.js:1521
+#: htdocs/luci-static/resources/fchomo.js:1524
msgid "Unable to download unsupported type: %s"
msgstr "无法下载不支持的类型: %s"
@@ -3937,8 +3963,8 @@ msgstr "未知错误。"
msgid "Unknown error: %s"
msgstr "未知错误:%s"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1256
-#: htdocs/luci-static/resources/view/fchomo/node.js:2541
+#: htdocs/luci-static/resources/view/fchomo/node.js:1270
+#: htdocs/luci-static/resources/view/fchomo/node.js:2562
msgid "UoT"
msgstr "UDP over TCP (UoT)"
@@ -3946,24 +3972,24 @@ msgstr "UDP over TCP (UoT)"
msgid "Update failed."
msgstr "更新失败。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2396
+#: htdocs/luci-static/resources/view/fchomo/node.js:2417
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:408
msgid "Update interval"
msgstr "更新间隔"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1399
-#: htdocs/luci-static/resources/view/fchomo/node.js:2134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1417
+#: htdocs/luci-static/resources/view/fchomo/node.js:2155
msgid "Upload bandwidth"
msgstr "上传带宽"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1400
-#: htdocs/luci-static/resources/view/fchomo/node.js:2135
+#: htdocs/luci-static/resources/fchomo/listeners.js:1418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2156
msgid "Upload bandwidth in Mbps."
msgstr "上传带宽(单位:Mbps)。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1137
-#: htdocs/luci-static/resources/fchomo/listeners.js:1177
-#: htdocs/luci-static/resources/view/fchomo/node.js:1533
+#: htdocs/luci-static/resources/fchomo/listeners.js:1155
+#: htdocs/luci-static/resources/fchomo/listeners.js:1195
+#: htdocs/luci-static/resources/view/fchomo/node.js:1556
msgid "Upload certificate"
msgstr "上传证书"
@@ -3971,29 +3997,29 @@ msgstr "上传证书"
msgid "Upload initial package"
msgstr "上传初始资源包"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1152
-#: htdocs/luci-static/resources/view/fchomo/node.js:1547
+#: htdocs/luci-static/resources/fchomo/listeners.js:1170
+#: htdocs/luci-static/resources/view/fchomo/node.js:1570
msgid "Upload key"
msgstr "上传密钥"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1140
-#: htdocs/luci-static/resources/fchomo/listeners.js:1155
-#: htdocs/luci-static/resources/fchomo/listeners.js:1180
+#: htdocs/luci-static/resources/fchomo/listeners.js:1158
+#: htdocs/luci-static/resources/fchomo/listeners.js:1173
+#: htdocs/luci-static/resources/fchomo/listeners.js:1198
#: htdocs/luci-static/resources/view/fchomo/global.js:306
-#: htdocs/luci-static/resources/view/fchomo/node.js:1536
-#: htdocs/luci-static/resources/view/fchomo/node.js:1550
+#: htdocs/luci-static/resources/view/fchomo/node.js:1559
+#: htdocs/luci-static/resources/view/fchomo/node.js:1573
msgid "Upload..."
msgstr "上传..."
-#: htdocs/luci-static/resources/view/fchomo/node.js:1813
+#: htdocs/luci-static/resources/view/fchomo/node.js:1834
msgid "Use DHCP"
msgstr "使用 DHCP"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1814
+#: htdocs/luci-static/resources/view/fchomo/node.js:1835
msgid "Use DHCP to obtain IP address."
msgstr "使用 DHCP 获取 IP 地址。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:844
+#: htdocs/luci-static/resources/view/fchomo/node.js:854
msgid "Use protocol-13 extended encryption for outgoing HELLO packets."
msgstr "对传出的 HELLO 数据包使用 协议-13 扩展加密。"
@@ -4003,15 +4029,15 @@ msgstr "对传出的 HELLO 数据包使用 协议-13 扩展加密。"
msgid "Use sub rule"
msgstr "使用子规则"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1117
+#: htdocs/luci-static/resources/view/fchomo/node.js:1131
msgid "Used to forward traffic to the specified nodes for external access."
msgstr "用于将流量转发至指定节点,以供外部访问。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:869
+#: htdocs/luci-static/resources/view/fchomo/node.js:879
msgid "Used to replace the built-in official %s."
msgstr "用于替换内置的官方 %s。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:863
+#: htdocs/luci-static/resources/view/fchomo/node.js:873
msgid "Used to replace the contents of default %s."
msgstr "用于替换默认的 %s 的内容。"
@@ -4035,9 +4061,9 @@ msgstr "用于解析 DNS 服务器的域名。必须是 IP。"
msgid "Used to resolve the domain of the Proxy node."
msgstr "用于解析代理节点的域名。"
-#: htdocs/luci-static/resources/fchomo.js:1475
-#: htdocs/luci-static/resources/view/fchomo/node.js:1514
-#: htdocs/luci-static/resources/view/fchomo/node.js:2560
+#: htdocs/luci-static/resources/fchomo.js:1478
+#: htdocs/luci-static/resources/view/fchomo/node.js:1537
+#: htdocs/luci-static/resources/view/fchomo/node.js:2581
msgid "Used to verify the hostname on the returned certificates."
msgstr "用于验证返回的证书上的主机名。"
@@ -4050,9 +4076,9 @@ msgid "User-hint is mandatory"
msgstr "User-hint 是必填项"
#: htdocs/luci-static/resources/fchomo/listeners.js:162
-#: htdocs/luci-static/resources/fchomo/listeners.js:738
+#: htdocs/luci-static/resources/fchomo/listeners.js:756
#: htdocs/luci-static/resources/view/fchomo/node.js:322
-#: htdocs/luci-static/resources/view/fchomo/node.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1343
msgid "Username"
msgstr "用户名"
@@ -4060,23 +4086,23 @@ msgstr "用户名"
msgid "Users filter mode"
msgstr "使用者过滤模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:851
+#: htdocs/luci-static/resources/view/fchomo/node.js:861
msgid "Uses TCP relay only."
msgstr "仅使用 TCP 中继。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:850
+#: htdocs/luci-static/resources/view/fchomo/node.js:860
msgid "Uses relay after UDP direct failure."
msgstr "UDP 直连失败后使用中继。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1174
+#: htdocs/luci-static/resources/view/fchomo/node.js:1188
msgid "Using this in conjunction with %s is recommended."
msgstr "建议与 %s 结合使用。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1991
+#: htdocs/luci-static/resources/view/fchomo/node.js:2012
msgid "V2ray HTTPUpgrade"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1996
+#: htdocs/luci-static/resources/view/fchomo/node.js:2017
msgid "V2ray HTTPUpgrade fast open"
msgstr ""
@@ -4090,9 +4116,9 @@ msgstr ""
msgid "VMess"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
msgid "VPN"
msgstr ""
@@ -4100,17 +4126,17 @@ msgstr ""
msgid "VPN fields"
msgstr "VPN 字段"
-#: htdocs/luci-static/resources/view/fchomo/node.js:900
+#: htdocs/luci-static/resources/view/fchomo/node.js:910
msgid "Valid 16-digit Moon World ID and 10-digit Node ID of Moon Root server."
msgstr "有效的 16-位数 Moon World ID 和 10-位数 Moon Root 服务器 Node ID。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2333
-#: htdocs/luci-static/resources/view/fchomo/node.js:2729
+#: htdocs/luci-static/resources/view/fchomo/node.js:2354
+#: htdocs/luci-static/resources/view/fchomo/node.js:2750
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:339
msgid "Value"
msgstr "可视化值"
-#: htdocs/luci-static/resources/view/fchomo/node.js:823
+#: htdocs/luci-static/resources/view/fchomo/node.js:833
msgid "Verbose"
msgstr "详细"
@@ -4119,27 +4145,27 @@ msgid "Verify if given"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:399
-#: htdocs/luci-static/resources/fchomo/listeners.js:752
+#: htdocs/luci-static/resources/fchomo/listeners.js:770
#: htdocs/luci-static/resources/view/fchomo/node.js:514
-#: htdocs/luci-static/resources/view/fchomo/node.js:1334
+#: htdocs/luci-static/resources/view/fchomo/node.js:1357
msgid "Version"
msgstr "版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1342
+#: htdocs/luci-static/resources/view/fchomo/node.js:1365
msgid "Version hint"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1116
-#: htdocs/luci-static/resources/view/fchomo/node.js:1782
-#: htdocs/luci-static/resources/view/fchomo/node.js:1815
+#: htdocs/luci-static/resources/view/fchomo/node.js:1130
+#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1836
msgid "Virtual IPv4 address"
msgstr "虚拟 IPv4 地址"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1789
+#: htdocs/luci-static/resources/view/fchomo/node.js:1810
msgid "Virtual IPv6 address"
msgstr "虚拟 IPv6 地址"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1756
+#: htdocs/luci-static/resources/view/fchomo/node.js:1777
msgid "Virtual address"
msgstr "虚拟地址"
@@ -4157,15 +4183,15 @@ msgid "Warning"
msgstr "警告"
#: htdocs/luci-static/resources/fchomo/listeners.js:377
-#: htdocs/luci-static/resources/fchomo/listeners.js:1304
-#: htdocs/luci-static/resources/fchomo/listeners.js:1315
#: htdocs/luci-static/resources/fchomo/listeners.js:1322
+#: htdocs/luci-static/resources/fchomo/listeners.js:1333
+#: htdocs/luci-static/resources/fchomo/listeners.js:1340
#: htdocs/luci-static/resources/view/fchomo/node.js:468
#: htdocs/luci-static/resources/view/fchomo/node.js:497
-#: htdocs/luci-static/resources/view/fchomo/node.js:1885
-#: htdocs/luci-static/resources/view/fchomo/node.js:1898
-#: htdocs/luci-static/resources/view/fchomo/node.js:1905
-#: htdocs/luci-static/resources/view/fchomo/node.js:1911
+#: htdocs/luci-static/resources/view/fchomo/node.js:1906
+#: htdocs/luci-static/resources/view/fchomo/node.js:1919
+#: htdocs/luci-static/resources/view/fchomo/node.js:1926
+#: htdocs/luci-static/resources/view/fchomo/node.js:1932
msgid "WebSocket"
msgstr ""
@@ -4173,11 +4199,11 @@ msgstr ""
msgid "When used as a server, HomeProxy is a better choice."
msgstr "用作服务端时,HomeProxy 是更好的选择。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1166
+#: htdocs/luci-static/resources/view/fchomo/node.js:1180
msgid "Whether to accept DNS configurations distributed by the network."
msgstr "是否接受由网络分发的 DNS 配置。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:984
+#: htdocs/luci-static/resources/view/fchomo/node.js:994
msgid "Whether to accept routes advertised by other nodes."
msgstr "是否接受其他节点发布的路由。"
@@ -4189,53 +4215,53 @@ msgstr "白名单"
msgid "WireGuard"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:930
+#: htdocs/luci-static/resources/view/fchomo/node.js:940
msgid "WireGuard peer public key."
msgstr "WireGuard 对端公钥。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:937
+#: htdocs/luci-static/resources/view/fchomo/node.js:947
msgid "WireGuard pre-shared key."
msgstr "WireGuard 预共享密钥。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:909
+#: htdocs/luci-static/resources/view/fchomo/node.js:919
msgid "WireGuard requires base64-encoded private keys."
msgstr "WireGuard 要求 base64 编码的私钥。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1767
-#: htdocs/luci-static/resources/view/fchomo/node.js:1799
+#: htdocs/luci-static/resources/view/fchomo/node.js:1788
+#: htdocs/luci-static/resources/view/fchomo/node.js:1820
msgid "Wireguard"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1305
-#: htdocs/luci-static/resources/fchomo/listeners.js:1316
-#: htdocs/luci-static/resources/view/fchomo/node.js:1886
-#: htdocs/luci-static/resources/view/fchomo/node.js:1906
+#: htdocs/luci-static/resources/fchomo/listeners.js:1323
+#: htdocs/luci-static/resources/fchomo/listeners.js:1334
+#: htdocs/luci-static/resources/view/fchomo/node.js:1907
+#: htdocs/luci-static/resources/view/fchomo/node.js:1927
msgid "XHTTP"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1352
-#: htdocs/luci-static/resources/view/fchomo/node.js:2001
+#: htdocs/luci-static/resources/fchomo/listeners.js:1370
+#: htdocs/luci-static/resources/view/fchomo/node.js:2022
msgid "XHTTP mode"
msgstr "XHTTP 模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2032
+#: htdocs/luci-static/resources/view/fchomo/node.js:2053
msgid "XMUX"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2037
-#: htdocs/luci-static/resources/view/fchomo/node.js:2042
-#: htdocs/luci-static/resources/view/fchomo/node.js:2047
-#: htdocs/luci-static/resources/view/fchomo/node.js:2052
-#: htdocs/luci-static/resources/view/fchomo/node.js:2057
-#: htdocs/luci-static/resources/view/fchomo/node.js:2062
+#: htdocs/luci-static/resources/view/fchomo/node.js:2058
+#: htdocs/luci-static/resources/view/fchomo/node.js:2063
+#: htdocs/luci-static/resources/view/fchomo/node.js:2068
+#: htdocs/luci-static/resources/view/fchomo/node.js:2073
+#: htdocs/luci-static/resources/view/fchomo/node.js:2078
+#: htdocs/luci-static/resources/view/fchomo/node.js:2083
msgid "XMUX:"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:841
+#: htdocs/luci-static/resources/fchomo/listeners.js:859
msgid "XOR mode"
msgstr "XOR 模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:575
+#: htdocs/luci-static/resources/view/fchomo/node.js:585
msgid "Xudp (Xray-core)"
msgstr ""
@@ -4243,11 +4269,11 @@ msgstr ""
msgid "Yaml text"
msgstr "Yaml 格式文本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2571
+#: htdocs/luci-static/resources/view/fchomo/node.js:2592
msgid "Yes"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1173
+#: htdocs/luci-static/resources/view/fchomo/node.js:1187
msgid ""
"You can add %s in the %s to resolve A/PTR records within the virtual network."
msgstr "您可以将 %s 添加到 %s 中,以解析虚拟网络内的 A/PTR 记录。"
@@ -4256,7 +4282,7 @@ msgstr "您可以将 %s 添加到 %s 中,以解析虚拟网络内的 A/PTR 记
msgid "YouTube"
msgstr "油管"
-#: htdocs/luci-static/resources/fchomo.js:2002
+#: htdocs/luci-static/resources/fchomo.js:2004
msgid "Your %s was successfully uploaded. Size: %sB."
msgstr "您的 %s 已成功上传。大小:%sB。"
@@ -4264,14 +4290,14 @@ msgstr "您的 %s 已成功上传。大小:%sB。"
msgid "ZeroTier"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:831
+#: htdocs/luci-static/resources/view/fchomo/node.js:841
msgid "ZeroTier UDP payload MTU."
msgstr "ZeroTier UDP 有效载荷 MTU。"
#: htdocs/luci-static/resources/fchomo.js:422
#: htdocs/luci-static/resources/fchomo.js:435
#: htdocs/luci-static/resources/fchomo.js:440
-#: htdocs/luci-static/resources/view/fchomo/node.js:555
+#: htdocs/luci-static/resources/view/fchomo/node.js:565
msgid "aes-128-gcm"
msgstr ""
@@ -4284,19 +4310,19 @@ msgstr ""
msgid "aes-256-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1139
+#: htdocs/luci-static/resources/view/fchomo/node.js:1153
msgid "aes-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1140
+#: htdocs/luci-static/resources/view/fchomo/node.js:1154
msgid "aes-gcm-256"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2439
msgid "age private key"
msgstr "age 私钥"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2479
+#: htdocs/luci-static/resources/view/fchomo/node.js:2500
msgid "age public key"
msgstr "age 公钥"
@@ -4308,7 +4334,7 @@ msgstr ""
msgid "age-x25519"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:552
+#: htdocs/luci-static/resources/view/fchomo/node.js:562
msgid "auto"
msgstr "自动"
@@ -4321,13 +4347,13 @@ msgstr "bbr"
msgid "bbr3"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1142
-#: htdocs/luci-static/resources/fchomo/listeners.js:1182
-#: htdocs/luci-static/resources/view/fchomo/node.js:1538
+#: htdocs/luci-static/resources/fchomo/listeners.js:1160
+#: htdocs/luci-static/resources/fchomo/listeners.js:1200
+#: htdocs/luci-static/resources/view/fchomo/node.js:1561
msgid "certificate"
msgstr "证书"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1138
+#: htdocs/luci-static/resources/view/fchomo/node.js:1152
msgid "chacha20"
msgstr ""
@@ -4337,7 +4363,7 @@ msgstr ""
msgid "chacha20-ietf-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:556
+#: htdocs/luci-static/resources/view/fchomo/node.js:566
msgid "chacha20-poly1305"
msgstr ""
@@ -4346,8 +4372,8 @@ msgstr ""
msgid "cubic"
msgstr "cubic"
-#: htdocs/luci-static/resources/fchomo/listeners.js:793
-#: htdocs/luci-static/resources/fchomo/listeners.js:824
+#: htdocs/luci-static/resources/fchomo/listeners.js:811
+#: htdocs/luci-static/resources/fchomo/listeners.js:842
msgid "decryption"
msgstr "decryption"
@@ -4355,13 +4381,13 @@ msgstr "decryption"
msgid "dnsmasq selects upstream on its own. (may affect CDN accuracy)"
msgstr "dnsmasq 自行选择上游服务器。 (可能影响 CDN 准确性)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2553
+#: htdocs/luci-static/resources/view/fchomo/node.js:2574
msgid "down"
msgstr "Hysteria 下载速率"
-#: htdocs/luci-static/resources/fchomo/listeners.js:828
-#: htdocs/luci-static/resources/view/fchomo/node.js:1357
+#: htdocs/luci-static/resources/fchomo/listeners.js:846
#: htdocs/luci-static/resources/view/fchomo/node.js:1380
+#: htdocs/luci-static/resources/view/fchomo/node.js:1403
msgid "encryption"
msgstr "encryption"
@@ -4370,55 +4396,55 @@ msgstr "encryption"
msgid "false = bandwidth optimized downlink; true = pure Sudoku downlink."
msgstr "false = 带宽优化下行 true = 纯 Sudoku 下行。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1303
-#: htdocs/luci-static/resources/fchomo/listeners.js:1314
#: htdocs/luci-static/resources/fchomo/listeners.js:1321
-#: htdocs/luci-static/resources/view/fchomo/node.js:1884
-#: htdocs/luci-static/resources/view/fchomo/node.js:1897
-#: htdocs/luci-static/resources/view/fchomo/node.js:1904
-#: htdocs/luci-static/resources/view/fchomo/node.js:1910
+#: htdocs/luci-static/resources/fchomo/listeners.js:1332
+#: htdocs/luci-static/resources/fchomo/listeners.js:1339
+#: htdocs/luci-static/resources/view/fchomo/node.js:1905
+#: htdocs/luci-static/resources/view/fchomo/node.js:1918
+#: htdocs/luci-static/resources/view/fchomo/node.js:1925
+#: htdocs/luci-static/resources/view/fchomo/node.js:1931
msgid "gRPC"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1967
+#: htdocs/luci-static/resources/view/fchomo/node.js:1988
msgid "gRPC User-Agent"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1972
+#: htdocs/luci-static/resources/view/fchomo/node.js:1993
msgid "gRPC ping interval"
msgstr "gRPC ping 间隔"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1346
-#: htdocs/luci-static/resources/view/fchomo/node.js:1963
+#: htdocs/luci-static/resources/fchomo/listeners.js:1364
+#: htdocs/luci-static/resources/view/fchomo/node.js:1984
msgid "gRPC service name"
msgstr "gRPC 服务名称"
#: htdocs/luci-static/resources/view/fchomo/global.js:517
-#: htdocs/luci-static/resources/view/fchomo/node.js:1205
+#: htdocs/luci-static/resources/view/fchomo/node.js:1219
msgid "gVisor"
msgstr "gVisor"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1020
+#: htdocs/luci-static/resources/view/fchomo/node.js:1030
msgid "h2"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2079
+#: htdocs/luci-static/resources/view/fchomo/node.js:2100
msgid "h2mux"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1018
+#: htdocs/luci-static/resources/view/fchomo/node.js:1028
msgid "h3"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1019
+#: htdocs/luci-static/resources/view/fchomo/node.js:1029
msgid "h3-l4proxy"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:993
+#: htdocs/luci-static/resources/fchomo/listeners.js:1011
msgid "least one keypair required"
msgstr "至少需要一对密钥"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2694
+#: htdocs/luci-static/resources/view/fchomo/node.js:2715
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:444
msgid "luci-app-tinyfilemanager is not installed, please install it first."
msgstr "luci-app-tinyfilemanager 未安装,请先安装它。"
@@ -4428,7 +4454,7 @@ msgid "metacubexd"
msgstr "metacubexd"
#: htdocs/luci-static/resources/view/fchomo/global.js:515
-#: htdocs/luci-static/resources/view/fchomo/node.js:1203
+#: htdocs/luci-static/resources/view/fchomo/node.js:1217
msgid "mihomo IP stack (MIPS)"
msgstr "mihomo IP 协议栈(MIPS)"
@@ -4438,7 +4464,7 @@ msgstr "mihomo IP 协议栈(MIPS)"
#: htdocs/luci-static/resources/view/fchomo/client.js:1576
#: htdocs/luci-static/resources/view/fchomo/client.js:1810
#: htdocs/luci-static/resources/view/fchomo/client.js:1866
-#: htdocs/luci-static/resources/view/fchomo/node.js:2299
+#: htdocs/luci-static/resources/view/fchomo/node.js:2320
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:258
msgid "mihomo config"
msgstr "mihomo 配置"
@@ -4447,8 +4473,8 @@ msgstr "mihomo 配置"
msgid "mlkem768x25519plus"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2152
-#: htdocs/luci-static/resources/view/fchomo/node.js:2531
+#: htdocs/luci-static/resources/view/fchomo/node.js:2173
+#: htdocs/luci-static/resources/view/fchomo/node.js:2552
msgid "mpTCP"
msgstr "多路径 TCP (mpTCP)"
@@ -4460,18 +4486,21 @@ msgstr "new_reno"
msgid "no-resolve"
msgstr "no-resolve"
-#: htdocs/luci-static/resources/fchomo.js:1717
-#: htdocs/luci-static/resources/fchomo.js:1832
-#: htdocs/luci-static/resources/fchomo.js:1867
-#: htdocs/luci-static/resources/fchomo.js:1895
+#: htdocs/luci-static/resources/fchomo.js:1719
+#: htdocs/luci-static/resources/fchomo.js:1834
+#: htdocs/luci-static/resources/fchomo.js:1869
+#: htdocs/luci-static/resources/fchomo.js:1897
msgid "non-empty value"
msgstr "非空值"
+#: htdocs/luci-static/resources/fchomo.js:271
#: htdocs/luci-static/resources/fchomo.js:420
#: htdocs/luci-static/resources/fchomo.js:434
#: htdocs/luci-static/resources/fchomo.js:446
-#: htdocs/luci-static/resources/view/fchomo/node.js:553
-#: htdocs/luci-static/resources/view/fchomo/node.js:573
+#: htdocs/luci-static/resources/fchomo/listeners.js:628
+#: htdocs/luci-static/resources/fchomo/listeners.js:631
+#: htdocs/luci-static/resources/view/fchomo/node.js:563
+#: htdocs/luci-static/resources/view/fchomo/node.js:583
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:335
msgid "none"
msgstr "无"
@@ -4484,16 +4513,10 @@ msgstr "未找到"
msgid "not included \",\""
msgstr "不包含 \",\""
-#: htdocs/luci-static/resources/fchomo.js:271
-#: htdocs/luci-static/resources/fchomo/listeners.js:619
-#: htdocs/luci-static/resources/fchomo/listeners.js:622
-msgid "null"
-msgstr ""
-
-#: htdocs/luci-static/resources/fchomo/listeners.js:689
-#: htdocs/luci-static/resources/fchomo/listeners.js:699
-#: htdocs/luci-static/resources/view/fchomo/node.js:1277
-#: htdocs/luci-static/resources/view/fchomo/node.js:1289
+#: htdocs/luci-static/resources/fchomo/listeners.js:698
+#: htdocs/luci-static/resources/fchomo/listeners.js:717
+#: htdocs/luci-static/resources/view/fchomo/node.js:1291
+#: htdocs/luci-static/resources/view/fchomo/node.js:1312
msgid "obfs-simple"
msgstr ""
@@ -4505,32 +4528,32 @@ msgstr "仅当 %s 为 %s 时适用。"
msgid "only applies when %s is not %s."
msgstr "仅当 %s 不为 %s 时适用。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1141
+#: htdocs/luci-static/resources/view/fchomo/node.js:1155
msgid "openssl-aes128-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1142
+#: htdocs/luci-static/resources/view/fchomo/node.js:1156
msgid "openssl-aes256-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1143
+#: htdocs/luci-static/resources/view/fchomo/node.js:1157
msgid "openssl-chacha20"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2512
+#: htdocs/luci-static/resources/view/fchomo/node.js:2533
msgid "override.override-expr"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2504
+#: htdocs/luci-static/resources/view/fchomo/node.js:2525
msgid "override.proxy-name"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:574
+#: htdocs/luci-static/resources/view/fchomo/node.js:584
msgid "packet addr (v2ray-core v5+)"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1356
-#: htdocs/luci-static/resources/view/fchomo/node.js:2005
+#: htdocs/luci-static/resources/fchomo/listeners.js:1374
+#: htdocs/luci-static/resources/view/fchomo/node.js:2026
msgid "packet-up"
msgstr ""
@@ -4539,8 +4562,8 @@ msgstr ""
msgid "poll"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1157
-#: htdocs/luci-static/resources/view/fchomo/node.js:1552
+#: htdocs/luci-static/resources/fchomo/listeners.js:1175
+#: htdocs/luci-static/resources/view/fchomo/node.js:1575
msgid "private key"
msgstr "私钥"
@@ -4561,7 +4584,7 @@ msgstr "需要使用 API 的前端适配。"
msgid "rule-set"
msgstr "规则集"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2077
+#: htdocs/luci-static/resources/view/fchomo/node.js:2098
msgid "smux"
msgstr ""
@@ -4574,17 +4597,17 @@ msgstr ""
msgid "src"
msgstr "src"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1354
-#: htdocs/luci-static/resources/view/fchomo/node.js:2003
+#: htdocs/luci-static/resources/fchomo/listeners.js:1372
+#: htdocs/luci-static/resources/view/fchomo/node.js:2024
msgid "stream-one"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1355
-#: htdocs/luci-static/resources/view/fchomo/node.js:2004
+#: htdocs/luci-static/resources/fchomo/listeners.js:1373
+#: htdocs/luci-static/resources/view/fchomo/node.js:2025
msgid "stream-up"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1371
+#: htdocs/luci-static/resources/fchomo/listeners.js:1389
msgid "stream-up server seconds"
msgstr ""
@@ -4596,11 +4619,11 @@ msgstr ""
msgid "sudoku-keypair"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1344
+#: htdocs/luci-static/resources/view/fchomo/node.js:1367
msgid "tls12"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1345
+#: htdocs/luci-static/resources/view/fchomo/node.js:1368
msgid "tls13"
msgstr ""
@@ -4616,35 +4639,35 @@ msgstr "独立 UCI 标识"
msgid "unique identifier"
msgstr "独立标识"
-#: htdocs/luci-static/resources/fchomo.js:1904
+#: htdocs/luci-static/resources/fchomo.js:1906
msgid "unique value"
msgstr "独立值"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2547
+#: htdocs/luci-static/resources/view/fchomo/node.js:2568
msgid "up"
msgstr "Hysteria 上传速率"
#: htdocs/luci-static/resources/fchomo/listeners.js:400
-#: htdocs/luci-static/resources/fchomo/listeners.js:753
+#: htdocs/luci-static/resources/fchomo/listeners.js:771
#: htdocs/luci-static/resources/view/fchomo/node.js:515
-#: htdocs/luci-static/resources/view/fchomo/node.js:656
-#: htdocs/luci-static/resources/view/fchomo/node.js:1263
-#: htdocs/luci-static/resources/view/fchomo/node.js:1335
+#: htdocs/luci-static/resources/view/fchomo/node.js:666
+#: htdocs/luci-static/resources/view/fchomo/node.js:1277
+#: htdocs/luci-static/resources/view/fchomo/node.js:1358
msgid "v1"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:401
-#: htdocs/luci-static/resources/fchomo/listeners.js:754
+#: htdocs/luci-static/resources/fchomo/listeners.js:772
#: htdocs/luci-static/resources/view/fchomo/node.js:516
-#: htdocs/luci-static/resources/view/fchomo/node.js:1264
-#: htdocs/luci-static/resources/view/fchomo/node.js:1336
+#: htdocs/luci-static/resources/view/fchomo/node.js:1278
+#: htdocs/luci-static/resources/view/fchomo/node.js:1359
msgid "v2"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:402
-#: htdocs/luci-static/resources/fchomo/listeners.js:755
+#: htdocs/luci-static/resources/fchomo/listeners.js:773
#: htdocs/luci-static/resources/view/fchomo/node.js:517
-#: htdocs/luci-static/resources/view/fchomo/node.js:1337
+#: htdocs/luci-static/resources/view/fchomo/node.js:1360
msgid "v3"
msgstr ""
@@ -4658,42 +4681,47 @@ msgstr ""
msgid "v5"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1764
-#: htdocs/luci-static/resources/fchomo.js:1767
+#: htdocs/luci-static/resources/fchomo/listeners.js:405
+#: htdocs/luci-static/resources/view/fchomo/node.js:520
+msgid "v6"
+msgstr ""
+
+#: htdocs/luci-static/resources/fchomo.js:1766
+#: htdocs/luci-static/resources/fchomo.js:1769
msgid "valid JSON format"
msgstr "有效的 JSON 格式"
-#: htdocs/luci-static/resources/fchomo.js:1823
+#: htdocs/luci-static/resources/fchomo.js:1825
msgid "valid SHA256 string with %d characters"
msgstr "包含 %d 个字符的有效 SHA256 字符串"
-#: htdocs/luci-static/resources/fchomo.js:1789
-#: htdocs/luci-static/resources/fchomo.js:1792
+#: htdocs/luci-static/resources/fchomo.js:1791
+#: htdocs/luci-static/resources/fchomo.js:1794
msgid "valid URL"
msgstr "有效网址"
-#: htdocs/luci-static/resources/fchomo.js:1814
+#: htdocs/luci-static/resources/fchomo.js:1816
msgid "valid base64 key with %d characters"
msgstr "包含 %d 个字符的有效 base64 密钥"
-#: htdocs/luci-static/resources/fchomo.js:1882
-#: htdocs/luci-static/resources/fchomo.js:1888
+#: htdocs/luci-static/resources/fchomo.js:1884
+#: htdocs/luci-static/resources/fchomo.js:1890
msgid "valid format: 2x, 2p, 4v"
msgstr "有效格式: 2x, 2p, 4v"
-#: htdocs/luci-static/resources/fchomo.js:1805
+#: htdocs/luci-static/resources/fchomo.js:1807
msgid "valid hex string with %d characters"
msgstr "包含 %d 个字符的有效 Hex 字符串"
-#: htdocs/luci-static/resources/fchomo.js:1869
+#: htdocs/luci-static/resources/fchomo.js:1871
msgid "valid key length with %d characters"
msgstr "包含 %d 个字符的有效密钥"
-#: htdocs/luci-static/resources/fchomo.js:1727
+#: htdocs/luci-static/resources/fchomo.js:1729
msgid "valid port value"
msgstr "有效端口值"
-#: htdocs/luci-static/resources/fchomo.js:1777
+#: htdocs/luci-static/resources/fchomo.js:1779
msgid "valid uuid"
msgstr "有效 uuid"
@@ -4709,7 +4737,7 @@ msgstr ""
msgid "xchacha20-ietf-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1137
+#: htdocs/luci-static/resources/view/fchomo/node.js:1151
msgid "xor"
msgstr ""
@@ -4717,7 +4745,7 @@ msgstr ""
msgid "yacd-meta"
msgstr "yacd-meta"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2078
+#: htdocs/luci-static/resources/view/fchomo/node.js:2099
msgid "yamux"
msgstr ""
@@ -4725,14 +4753,14 @@ msgstr ""
msgid "zashboard"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:554
+#: htdocs/luci-static/resources/view/fchomo/node.js:564
msgid "zero"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1544
+#: htdocs/luci-static/resources/fchomo.js:1547
msgid "🔗"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1523
+#: htdocs/luci-static/resources/fchomo.js:1526
msgid "🡇"
msgstr ""
diff --git a/luci-app-fchomo/po/zh_Hant/fchomo.po b/luci-app-fchomo/po/zh_Hant/fchomo.po
index 05d209f03..27d064de9 100644
--- a/luci-app-fchomo/po/zh_Hant/fchomo.po
+++ b/luci-app-fchomo/po/zh_Hant/fchomo.po
@@ -8,12 +8,12 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
-#: htdocs/luci-static/resources/view/fchomo/node.js:962
+#: htdocs/luci-static/resources/view/fchomo/node.js:972
msgid "%s Hostname"
msgstr "%s 主機名稱"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1686
-#: htdocs/luci-static/resources/view/fchomo/node.js:1696
+#: htdocs/luci-static/resources/view/fchomo/node.js:1708
+#: htdocs/luci-static/resources/view/fchomo/node.js:1718
msgid "%s UDP port. 0 selects an available port."
msgstr "%s UDP 連接埠。 0 自動選擇一個可用連接埠。"
@@ -21,7 +21,7 @@ msgstr "%s UDP 連接埠。 0 自動選擇一個可用連接埠。"
msgid "%s log"
msgstr "%s 日誌"
-#: htdocs/luci-static/resources/view/fchomo/node.js:815
+#: htdocs/luci-static/resources/view/fchomo/node.js:825
msgid "%s of the %s used to receiving remote debugging log."
msgstr "%s,用於接收遠端偵錯日誌的 %s 的。"
@@ -34,23 +34,23 @@ msgstr "%s,用於接收遠端偵錯日誌的 %s 的。"
msgid "%s ports"
msgstr "%s 連接埠"
-#: htdocs/luci-static/resources/fchomo.js:785
#: htdocs/luci-static/resources/fchomo.js:788
+#: htdocs/luci-static/resources/fchomo.js:791
#: htdocs/luci-static/resources/view/fchomo/client.js:318
msgid "(Imported)"
msgstr "(已導入)"
-#: htdocs/luci-static/resources/fchomo.js:1488
-#: htdocs/luci-static/resources/fchomo.js:1494
-#: htdocs/luci-static/resources/fchomo/listeners.js:1160
-#: htdocs/luci-static/resources/fchomo/listeners.js:1168
-#: htdocs/luci-static/resources/fchomo/listeners.js:1177
+#: htdocs/luci-static/resources/fchomo.js:1491
+#: htdocs/luci-static/resources/fchomo.js:1497
+#: htdocs/luci-static/resources/fchomo/listeners.js:1178
+#: htdocs/luci-static/resources/fchomo/listeners.js:1186
+#: htdocs/luci-static/resources/fchomo/listeners.js:1195
#: htdocs/luci-static/resources/view/fchomo/global.js:572
#: htdocs/luci-static/resources/view/fchomo/global.js:578
-#: htdocs/luci-static/resources/view/fchomo/node.js:1527
-#: htdocs/luci-static/resources/view/fchomo/node.js:1533
-#: htdocs/luci-static/resources/view/fchomo/node.js:1541
-#: htdocs/luci-static/resources/view/fchomo/node.js:1547
+#: htdocs/luci-static/resources/view/fchomo/node.js:1550
+#: htdocs/luci-static/resources/view/fchomo/node.js:1556
+#: htdocs/luci-static/resources/view/fchomo/node.js:1564
+#: htdocs/luci-static/resources/view/fchomo/node.js:1570
msgid "(mTLS)"
msgstr ""
@@ -72,10 +72,10 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1113
#: htdocs/luci-static/resources/view/fchomo/client.js:1369
#: htdocs/luci-static/resources/view/fchomo/node.js:305
-#: htdocs/luci-static/resources/view/fchomo/node.js:2735
-#: htdocs/luci-static/resources/view/fchomo/node.js:2746
-#: htdocs/luci-static/resources/view/fchomo/node.js:2765
-#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2756
+#: htdocs/luci-static/resources/view/fchomo/node.js:2767
+#: htdocs/luci-static/resources/view/fchomo/node.js:2786
+#: htdocs/luci-static/resources/view/fchomo/node.js:2797
msgid "-- Please choose --"
msgstr "-- 請選擇 --"
@@ -104,7 +104,7 @@ msgstr ""
msgid "2022-blake3-chacha20-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1697
+#: htdocs/luci-static/resources/view/fchomo/node.js:1719
msgid "-1 disables it."
msgstr "-1 表示停用它。"
@@ -112,11 +112,11 @@ msgstr "-1 表示停用它。"
msgid "0 or 1 only."
msgstr "僅限 0 或 1。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1138
-#: htdocs/luci-static/resources/fchomo/listeners.js:1153
-#: htdocs/luci-static/resources/fchomo/listeners.js:1178
-#: htdocs/luci-static/resources/view/fchomo/node.js:1534
-#: htdocs/luci-static/resources/view/fchomo/node.js:1548
+#: htdocs/luci-static/resources/fchomo/listeners.js:1156
+#: htdocs/luci-static/resources/fchomo/listeners.js:1171
+#: htdocs/luci-static/resources/fchomo/listeners.js:1196
+#: htdocs/luci-static/resources/view/fchomo/node.js:1557
+#: htdocs/luci-static/resources/view/fchomo/node.js:1571
msgid "Save your configuration before uploading files!"
msgstr "上傳文件前請先保存配置!"
@@ -191,7 +191,7 @@ msgstr "ASCII 資料流"
msgid "ASN version"
msgstr "ASN 版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:983
+#: htdocs/luci-static/resources/view/fchomo/node.js:993
msgid "Accept routes"
msgstr "接受路由"
@@ -220,11 +220,11 @@ msgstr "新增 節點"
msgid "Add a inbound"
msgstr "新增 入站"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2196
+#: htdocs/luci-static/resources/view/fchomo/node.js:2217
msgid "Add a provider"
msgstr "新增 供應商"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2709
+#: htdocs/luci-static/resources/view/fchomo/node.js:2730
msgid "Add a proxy chain"
msgstr "新增 代理鏈"
@@ -248,15 +248,15 @@ msgstr "新增 伺服器"
msgid "Add a sub rule"
msgstr "新增 子規則"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2493
+#: htdocs/luci-static/resources/view/fchomo/node.js:2514
msgid "Add prefix"
msgstr "添加前綴"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2497
+#: htdocs/luci-static/resources/view/fchomo/node.js:2518
msgid "Add suffix"
msgstr "添加後綴"
-#: htdocs/luci-static/resources/view/fchomo/node.js:870
+#: htdocs/luci-static/resources/view/fchomo/node.js:880
msgid "Add the base64 text of the planet file here."
msgstr "在此處新增行星檔案的 base64 文本。"
@@ -265,7 +265,7 @@ msgstr "在此處新增行星檔案的 base64 文本。"
msgid "Address"
msgstr "位址"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1160
+#: htdocs/luci-static/resources/view/fchomo/node.js:1174
msgid "After disabling, communication will only be possible via relay."
msgstr "停用後,只能透過中繼進行通訊。"
@@ -294,7 +294,7 @@ msgstr "允許所有"
msgid "All ports"
msgstr "所有連接埠"
-#: htdocs/luci-static/resources/view/fchomo/node.js:994
+#: htdocs/luci-static/resources/view/fchomo/node.js:1004
msgid "Allow LAN access"
msgstr "允許區域網路訪問"
@@ -305,19 +305,19 @@ msgid ""
msgstr ""
"允許從私有網路訪問。要從公共網站訪問私有網路上的 API,則必須啟用。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:995
+#: htdocs/luci-static/resources/view/fchomo/node.js:1005
msgid "Allow access to the local LAN via the exit node."
msgstr "允許透過出口節點存取本地區域網路。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1061
+#: htdocs/luci-static/resources/fchomo/listeners.js:1079
msgid "Allow insecure connections"
msgstr "允許不安全的連線"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1148
+#: htdocs/luci-static/resources/view/fchomo/node.js:1162
msgid "Allow this node to be an exit node."
msgstr "允許此節點成為出口節點。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:943
+#: htdocs/luci-static/resources/view/fchomo/node.js:953
msgid "Allowed IPs"
msgstr "允許的 IP"
@@ -329,8 +329,8 @@ msgstr "已是最新版本。"
msgid "Already in updating."
msgstr "已在更新中。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:424
-#: htdocs/luci-static/resources/view/fchomo/node.js:544
+#: htdocs/luci-static/resources/fchomo/listeners.js:433
+#: htdocs/luci-static/resources/view/fchomo/node.js:554
msgid "Alter ID"
msgstr "額外 ID"
@@ -343,11 +343,11 @@ msgstr ""
msgid "Application version"
msgstr "應用版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:978
+#: htdocs/luci-static/resources/view/fchomo/node.js:988
msgid "As ephemeral node"
msgstr "作為臨時節點"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1147
+#: htdocs/luci-static/resources/view/fchomo/node.js:1161
msgid "As exit node"
msgstr "作為出口節點"
@@ -360,35 +360,35 @@ msgstr "作為 dnsmasq 的最優先上游"
msgid "As the TOP upstream of dnsmasq."
msgstr "作為 dnsmasq 的最優先上游。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:472
+#: htdocs/luci-static/resources/fchomo/listeners.js:481
msgid "Auth timeout"
msgstr "認證逾時"
-#: htdocs/luci-static/resources/view/fchomo/node.js:566
+#: htdocs/luci-static/resources/view/fchomo/node.js:576
msgid "Authenticated length"
msgstr "認證長度"
-#: htdocs/luci-static/resources/view/fchomo/node.js:973
+#: htdocs/luci-static/resources/view/fchomo/node.js:983
msgid "Authentication key"
msgstr "認證金鑰"
#: htdocs/luci-static/resources/fchomo/listeners.js:376
-#: htdocs/luci-static/resources/fchomo/listeners.js:1353
+#: htdocs/luci-static/resources/fchomo/listeners.js:1371
#: htdocs/luci-static/resources/view/fchomo/global.js:423
#: htdocs/luci-static/resources/view/fchomo/node.js:467
#: htdocs/luci-static/resources/view/fchomo/node.js:491
-#: htdocs/luci-static/resources/view/fchomo/node.js:850
-#: htdocs/luci-static/resources/view/fchomo/node.js:1202
-#: htdocs/luci-static/resources/view/fchomo/node.js:2002
+#: htdocs/luci-static/resources/view/fchomo/node.js:860
+#: htdocs/luci-static/resources/view/fchomo/node.js:1216
+#: htdocs/luci-static/resources/view/fchomo/node.js:2023
msgid "Auto"
msgstr "自動"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1815
+#: htdocs/luci-static/resources/view/fchomo/node.js:1836
msgid "Auto Enable when %s is empty."
msgstr "當 %s 為空時自動啟用。"
#: htdocs/luci-static/resources/fchomo/listeners.js:139
-#: htdocs/luci-static/resources/view/fchomo/node.js:1618
+#: htdocs/luci-static/resources/view/fchomo/node.js:1641
msgid "Auto configure firewall"
msgstr "自動配置防火牆"
@@ -400,8 +400,8 @@ msgstr "自動更新"
msgid "Auto update resources."
msgstr "自動更新資源文件。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:653
-#: htdocs/luci-static/resources/view/fchomo/node.js:1227
+#: htdocs/luci-static/resources/fchomo/listeners.js:662
+#: htdocs/luci-static/resources/view/fchomo/node.js:1241
msgid "BBR profile"
msgstr "BBR 設定檔"
@@ -409,19 +409,19 @@ msgstr "BBR 設定檔"
msgid "Baidu"
msgstr "百度"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1002
+#: htdocs/luci-static/resources/view/fchomo/node.js:1012
msgid "Base64 encoded ECDSA private key on the NIST P-256 curve."
msgstr "基於 NIST P-256 曲線的 Base64 編碼 ECDSA 私鑰。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1010
+#: htdocs/luci-static/resources/view/fchomo/node.js:1020
msgid "Base64 encoded ECDSA public key on the NIST P-256 curve."
msgstr "基於 NIST P-256 曲線的 Base64 編碼 ECDSA 公鑰。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1095
+#: htdocs/luci-static/resources/view/fchomo/node.js:1108
msgid "Base64 encoded X25519 private key."
msgstr "Base64 編碼的 X25519 私鑰。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1111
+#: htdocs/luci-static/resources/view/fchomo/node.js:1125
msgid "Base64 encoded X25519 public key."
msgstr "Base64 編碼的 X25519 公鑰。"
@@ -443,13 +443,13 @@ msgid "Binary mrs"
msgstr "二進位 mrs"
#: htdocs/luci-static/resources/view/fchomo/global.js:766
-#: htdocs/luci-static/resources/view/fchomo/node.js:2163
-#: htdocs/luci-static/resources/view/fchomo/node.js:2582
+#: htdocs/luci-static/resources/view/fchomo/node.js:2184
+#: htdocs/luci-static/resources/view/fchomo/node.js:2603
msgid "Bind interface"
msgstr "綁定介面"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2164
-#: htdocs/luci-static/resources/view/fchomo/node.js:2583
+#: htdocs/luci-static/resources/view/fchomo/node.js:2185
+#: htdocs/luci-static/resources/view/fchomo/node.js:2604
msgid "Bind outbound interface."
msgstr "綁定出站介面。"
@@ -514,24 +514,24 @@ msgstr "CORS 允許私有網路"
msgid "CORS allowed origins, * will be used if empty."
msgstr "CORS 允許的來源,留空則使用 *。"
-#: htdocs/luci-static/resources/fchomo.js:901
+#: htdocs/luci-static/resources/fchomo.js:904
msgid "Cancel"
msgstr "取消"
-#: htdocs/luci-static/resources/fchomo.js:1468
-#: htdocs/luci-static/resources/view/fchomo/node.js:1507
+#: htdocs/luci-static/resources/fchomo.js:1471
+#: htdocs/luci-static/resources/view/fchomo/node.js:1530
msgid "Cert fingerprint"
msgstr "憑證指紋"
-#: htdocs/luci-static/resources/fchomo.js:1469
-#: htdocs/luci-static/resources/view/fchomo/node.js:1508
+#: htdocs/luci-static/resources/fchomo.js:1472
+#: htdocs/luci-static/resources/view/fchomo/node.js:1531
msgid ""
"Certificate fingerprint. Used to implement SSL Pinning and prevent MitM."
msgstr "憑證指紋。用於實現 SSL憑證固定 並防止 MitM。"
-#: htdocs/luci-static/resources/fchomo.js:1488
-#: htdocs/luci-static/resources/fchomo/listeners.js:1115
-#: htdocs/luci-static/resources/view/fchomo/node.js:1527
+#: htdocs/luci-static/resources/fchomo.js:1491
+#: htdocs/luci-static/resources/fchomo/listeners.js:1133
+#: htdocs/luci-static/resources/view/fchomo/node.js:1550
msgid "Certificate path"
msgstr "憑證路徑"
@@ -571,7 +571,7 @@ msgstr "大陸網域清單版本"
#: htdocs/luci-static/resources/fchomo/listeners.js:282
#: htdocs/luci-static/resources/view/fchomo/node.js:340
#: htdocs/luci-static/resources/view/fchomo/node.js:399
-#: htdocs/luci-static/resources/view/fchomo/node.js:550
+#: htdocs/luci-static/resources/view/fchomo/node.js:560
msgid "Chipher"
msgstr "加密方法"
@@ -592,27 +592,27 @@ msgstr ""
"點擊此處下載"
"最新的初始包。"
-#: htdocs/luci-static/resources/fchomo.js:1489
-#: htdocs/luci-static/resources/fchomo.js:1495
-#: htdocs/luci-static/resources/fchomo/listeners.js:869
-#: htdocs/luci-static/resources/fchomo/listeners.js:1169
+#: htdocs/luci-static/resources/fchomo.js:1492
+#: htdocs/luci-static/resources/fchomo.js:1498
+#: htdocs/luci-static/resources/fchomo/listeners.js:887
+#: htdocs/luci-static/resources/fchomo/listeners.js:1187
#: htdocs/luci-static/resources/view/fchomo/global.js:579
-#: htdocs/luci-static/resources/view/fchomo/node.js:1392
-#: htdocs/luci-static/resources/view/fchomo/node.js:1528
-#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/view/fchomo/node.js:1415
+#: htdocs/luci-static/resources/view/fchomo/node.js:1551
+#: htdocs/luci-static/resources/view/fchomo/node.js:1565
#: root/usr/share/luci/menu.d/luci-app-fchomo.json:22
msgid "Client"
msgstr "客戶端"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1168
+#: htdocs/luci-static/resources/fchomo/listeners.js:1186
msgid "Client Auth Certificate path"
msgstr "客戶端認證憑證路徑"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1160
+#: htdocs/luci-static/resources/fchomo/listeners.js:1178
msgid "Client Auth type"
msgstr "客戶端認證類型"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1573
+#: htdocs/luci-static/resources/view/fchomo/node.js:1596
msgid "Client fingerprint"
msgstr "客戶端指紋"
@@ -620,15 +620,15 @@ msgstr "客戶端指紋"
msgid "Client key"
msgstr "客戶端密鑰"
-#: htdocs/luci-static/resources/view/fchomo/node.js:603
+#: htdocs/luci-static/resources/view/fchomo/node.js:613
msgid "Client metadata"
msgstr "客戶端元資料"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1094
+#: htdocs/luci-static/resources/view/fchomo/node.js:1107
msgid "Client private key"
msgstr "客戶端私鑰"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1110
+#: htdocs/luci-static/resources/view/fchomo/node.js:1124
msgid "Client public key"
msgstr "客戶端公鑰"
@@ -636,8 +636,8 @@ msgstr "客戶端公鑰"
msgid "Client status"
msgstr "客戶端狀態"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1771
-#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1792
+#: htdocs/luci-static/resources/view/fchomo/node.js:1824
msgid "Cloudflare WARP"
msgstr ""
@@ -650,18 +650,18 @@ msgstr "收集資料中..."
msgid "Common ports (bypass P2P traffic)"
msgstr "常用連接埠(繞過 P2P 流量)"
-#: htdocs/luci-static/resources/fchomo.js:1661
+#: htdocs/luci-static/resources/fchomo.js:1663
msgid "Complete"
msgstr "完成"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1040
+#: htdocs/luci-static/resources/view/fchomo/node.js:1050
msgid "Configuration Document"
msgstr "配置文檔"
-#: htdocs/luci-static/resources/fchomo/listeners.js:645
+#: htdocs/luci-static/resources/fchomo/listeners.js:654
#: htdocs/luci-static/resources/view/fchomo/global.js:549
-#: htdocs/luci-static/resources/view/fchomo/node.js:1210
-#: htdocs/luci-static/resources/view/fchomo/node.js:1218
+#: htdocs/luci-static/resources/view/fchomo/node.js:1224
+#: htdocs/luci-static/resources/view/fchomo/node.js:1232
msgid "Congestion controller"
msgstr "擁塞控制器"
@@ -669,12 +669,12 @@ msgstr "擁塞控制器"
msgid "Connection check"
msgstr "連接檢查"
-#: htdocs/luci-static/resources/view/fchomo/node.js:524
+#: htdocs/luci-static/resources/view/fchomo/node.js:525
msgid "Connection reuse"
msgstr "連接重用"
-#: htdocs/luci-static/resources/fchomo/listeners.js:590
-#: htdocs/luci-static/resources/view/fchomo/node.js:784
+#: htdocs/luci-static/resources/fchomo/listeners.js:599
+#: htdocs/luci-static/resources/view/fchomo/node.js:794
msgid "Connection-level receive window size"
msgstr "連接級接收視窗大小"
@@ -682,19 +682,19 @@ msgstr "連接級接收視窗大小"
msgid "Conservative"
msgstr "保守"
-#: htdocs/luci-static/resources/fchomo.js:770
+#: htdocs/luci-static/resources/fchomo.js:773
msgid "Content copied to clipboard!"
msgstr "內容已複製到剪貼簿!"
#: htdocs/luci-static/resources/view/fchomo/client.js:698
-#: htdocs/luci-static/resources/view/fchomo/node.js:2353
-#: htdocs/luci-static/resources/view/fchomo/node.js:2379
+#: htdocs/luci-static/resources/view/fchomo/node.js:2374
+#: htdocs/luci-static/resources/view/fchomo/node.js:2400
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:359
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:385
msgid "Content will not be verified, Please make sure you enter it correctly."
msgstr "內容將不會被驗證,請確保輸入正確。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2352
+#: htdocs/luci-static/resources/view/fchomo/node.js:2373
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:358
msgid "Contents"
msgstr "內容"
@@ -703,11 +703,11 @@ msgstr "內容"
msgid "Contents have been saved."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:967
+#: htdocs/luci-static/resources/view/fchomo/node.js:977
msgid "Control server"
msgstr "控制伺服器"
-#: htdocs/luci-static/resources/fchomo.js:772
+#: htdocs/luci-static/resources/fchomo.js:775
msgid "Copy"
msgstr "複製"
@@ -719,7 +719,7 @@ msgstr "核心版本"
msgid "Cron expression"
msgstr "Cron 表達式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:968
+#: htdocs/luci-static/resources/view/fchomo/node.js:978
msgid "Custom %s control server."
msgstr "自訂 %s 控制伺服器。"
@@ -727,7 +727,7 @@ msgstr "自訂 %s 控制伺服器。"
msgid "Custom Direct List"
msgstr "自訂直連清單"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2484
+#: htdocs/luci-static/resources/view/fchomo/node.js:2505
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:431
msgid "Custom HTTP header."
msgstr "自訂 HTTP header。"
@@ -753,7 +753,7 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1831
#: htdocs/luci-static/resources/view/fchomo/client.js:1840
#: htdocs/luci-static/resources/view/fchomo/client.js:1915
-#: htdocs/luci-static/resources/view/fchomo/node.js:1174
+#: htdocs/luci-static/resources/view/fchomo/node.js:1188
msgid "DNS policy"
msgstr "DNS 策略"
@@ -764,8 +764,8 @@ msgstr " DNS 連接埠"
#: htdocs/luci-static/resources/view/fchomo/client.js:907
#: htdocs/luci-static/resources/view/fchomo/client.js:1524
#: htdocs/luci-static/resources/view/fchomo/client.js:1533
-#: htdocs/luci-static/resources/view/fchomo/node.js:1173
-#: htdocs/luci-static/resources/view/fchomo/node.js:1869
+#: htdocs/luci-static/resources/view/fchomo/node.js:1187
+#: htdocs/luci-static/resources/view/fchomo/node.js:1890
msgid "DNS server"
msgstr "DNS 伺服器"
@@ -782,10 +782,15 @@ msgid "Dashboard version"
msgstr "面板版本"
#: htdocs/luci-static/resources/fchomo.js:131
-#: htdocs/luci-static/resources/view/fchomo/node.js:825
+#: htdocs/luci-static/resources/view/fchomo/node.js:835
msgid "Debug"
msgstr "調試"
+#: htdocs/luci-static/resources/fchomo/listeners.js:412
+#: htdocs/luci-static/resources/view/fchomo/node.js:533
+msgid "Default"
+msgstr "預設"
+
#: htdocs/luci-static/resources/view/fchomo/client.js:58
msgid "Default DNS (issued by WAN)"
msgstr "預設 DNS(由 WAN 下發)"
@@ -800,7 +805,7 @@ msgstr "預設 DNS 伺服器"
msgid "Default selected"
msgstr "預設選中"
-#: htdocs/luci-static/resources/fchomo/listeners.js:562
+#: htdocs/luci-static/resources/fchomo/listeners.js:571
msgid "Default version, Support %s."
msgstr "預設版本,支援 %s。"
@@ -808,15 +813,15 @@ msgstr "預設版本,支援 %s。"
msgid "Derive from priv-key"
msgstr "從私鑰派生"
-#: htdocs/luci-static/resources/view/fchomo/node.js:944
+#: htdocs/luci-static/resources/view/fchomo/node.js:954
msgid "Destination addresses allowed to be forwarded via Wireguard."
msgstr "允許通過 WireGuard 轉發的目的位址"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2732
+#: htdocs/luci-static/resources/view/fchomo/node.js:2753
msgid "Destination provider"
msgstr "落地供應商"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2743
+#: htdocs/luci-static/resources/view/fchomo/node.js:2764
msgid "Destination proxy node"
msgstr "落地代理節點"
@@ -824,8 +829,8 @@ msgstr "落地代理節點"
msgid "Dial fields"
msgstr "撥號欄位"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2755
-#: htdocs/luci-static/resources/view/fchomo/node.js:2785
+#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2806
msgid "Different chain head/tail"
msgstr "不同的鏈頭/鏈尾"
@@ -845,10 +850,10 @@ msgstr "直連 IPv6 位址"
msgid "Direct MAC-s"
msgstr "直連 MAC 位址"
-#: htdocs/luci-static/resources/fchomo/listeners.js:500
+#: htdocs/luci-static/resources/fchomo/listeners.js:509
#: htdocs/luci-static/resources/view/fchomo/global.js:424
-#: htdocs/luci-static/resources/view/fchomo/node.js:718
-#: htdocs/luci-static/resources/view/fchomo/node.js:852
+#: htdocs/luci-static/resources/view/fchomo/node.js:728
+#: htdocs/luci-static/resources/view/fchomo/node.js:862
msgid "Disable"
msgstr "停用"
@@ -864,11 +869,11 @@ msgstr "停用 quic-go 的 通用分段卸載(GSO)"
msgid "Disable ICMP Forwarding"
msgstr "禁用 ICMP 轉發"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1159
+#: htdocs/luci-static/resources/view/fchomo/node.js:1173
msgid "Disable P2P"
msgstr "停用 P2P"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1448
+#: htdocs/luci-static/resources/view/fchomo/node.js:1471
msgid "Disable SNI"
msgstr "停用 SNI"
@@ -897,32 +902,32 @@ msgstr ""
msgid "Domain"
msgstr "網域"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1449
+#: htdocs/luci-static/resources/view/fchomo/node.js:1472
msgid "Donot send server name in ClientHello."
msgstr "不要在 ClientHello 中傳送伺服器名稱。"
-#: htdocs/luci-static/resources/fchomo.js:1481
+#: htdocs/luci-static/resources/fchomo.js:1484
#: htdocs/luci-static/resources/view/fchomo/client.js:1676
-#: htdocs/luci-static/resources/view/fchomo/node.js:1520
-#: htdocs/luci-static/resources/view/fchomo/node.js:2566
+#: htdocs/luci-static/resources/view/fchomo/node.js:1543
+#: htdocs/luci-static/resources/view/fchomo/node.js:2587
msgid "Donot verifying server certificate."
msgstr "不驗證伺服器憑證。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1405
-#: htdocs/luci-static/resources/view/fchomo/node.js:2140
+#: htdocs/luci-static/resources/fchomo/listeners.js:1423
+#: htdocs/luci-static/resources/view/fchomo/node.js:2161
msgid "Download bandwidth"
msgstr "下載頻寬"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1406
-#: htdocs/luci-static/resources/view/fchomo/node.js:2141
+#: htdocs/luci-static/resources/fchomo/listeners.js:1424
+#: htdocs/luci-static/resources/view/fchomo/node.js:2162
msgid "Download bandwidth in Mbps."
msgstr "下載頻寬(單位:Mbps)。"
-#: htdocs/luci-static/resources/fchomo.js:1518
+#: htdocs/luci-static/resources/fchomo.js:1521
msgid "Download failed: %s"
msgstr "下載失敗: %s"
-#: htdocs/luci-static/resources/fchomo.js:1514
+#: htdocs/luci-static/resources/fchomo.js:1517
msgid "Download successful."
msgstr "下載成功。"
@@ -934,16 +939,16 @@ msgstr "目的地 IP"
msgid "Dual stack"
msgstr "雙棧"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1567
+#: htdocs/luci-static/resources/view/fchomo/node.js:1590
msgid "ECH HTTPS record query servername"
msgstr "ECH HTTPS 記錄查詢網域"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1226
-#: htdocs/luci-static/resources/view/fchomo/node.js:1561
+#: htdocs/luci-static/resources/fchomo/listeners.js:1244
+#: htdocs/luci-static/resources/view/fchomo/node.js:1584
msgid "ECH config"
msgstr "ECH 配置"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1185
+#: htdocs/luci-static/resources/fchomo/listeners.js:1203
msgid "ECH key"
msgstr "ECH 密鑰"
@@ -959,11 +964,11 @@ msgstr "EDNS 客戶端子網"
msgid "ETag support"
msgstr "ETag 支援"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1980
+#: htdocs/luci-static/resources/view/fchomo/node.js:2001
msgid "Early Data first packet length limit."
msgstr "前置數據長度閾值"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1986
+#: htdocs/luci-static/resources/view/fchomo/node.js:2007
msgid "Early Data header name"
msgstr "前置數據標頭"
@@ -983,7 +988,7 @@ msgstr "編輯出站"
msgid "Edit ruleset"
msgstr "編輯規則集"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2350
+#: htdocs/luci-static/resources/view/fchomo/node.js:2371
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:356
msgid "Editer"
msgstr "編輯器"
@@ -1007,15 +1012,15 @@ msgstr "為空時回退"
#: htdocs/luci-static/resources/view/fchomo/global.js:422
#: htdocs/luci-static/resources/view/fchomo/global.js:712
#: htdocs/luci-static/resources/view/fchomo/node.js:267
-#: htdocs/luci-static/resources/view/fchomo/node.js:2323
-#: htdocs/luci-static/resources/view/fchomo/node.js:2605
-#: htdocs/luci-static/resources/view/fchomo/node.js:2719
+#: htdocs/luci-static/resources/view/fchomo/node.js:2344
+#: htdocs/luci-static/resources/view/fchomo/node.js:2626
+#: htdocs/luci-static/resources/view/fchomo/node.js:2740
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:283
#: htdocs/luci-static/resources/view/fchomo/server.js:49
msgid "Enable"
msgstr "啟用"
-#: htdocs/luci-static/resources/view/fchomo/node.js:672
+#: htdocs/luci-static/resources/view/fchomo/node.js:682
msgid ""
"Enable 0-RTT QUIC connection handshake on the client side. This is not "
"impacting much on the performance, as the protocol is fully multiplexed.
強烈建議停用此功能,因為它容易受到重放攻擊。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:671
+#: htdocs/luci-static/resources/view/fchomo/node.js:681
msgid "Enable 0-RTT handshake"
msgstr "啟用 0-RTT 握手"
@@ -1036,33 +1041,33 @@ msgstr ""
"為出站連線啟用 IP4P 轉換"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1555
+#: htdocs/luci-static/resources/view/fchomo/node.js:1578
msgid "Enable ECH"
msgstr "啟用 ECH"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1165
+#: htdocs/luci-static/resources/view/fchomo/node.js:1179
msgid "Enable MagicDNS"
msgstr "啟用 MagicDNS"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1393
-#: htdocs/luci-static/resources/view/fchomo/node.js:2128
+#: htdocs/luci-static/resources/fchomo/listeners.js:1411
+#: htdocs/luci-static/resources/view/fchomo/node.js:2149
msgid "Enable TCP Brutal"
msgstr "啟用 TCP Brutal"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1394
-#: htdocs/luci-static/resources/view/fchomo/node.js:2129
+#: htdocs/luci-static/resources/fchomo/listeners.js:1412
+#: htdocs/luci-static/resources/view/fchomo/node.js:2150
msgid "Enable TCP Brutal congestion control algorithm"
msgstr "啟用 TCP Brutal 擁塞控制演算法。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1130
+#: htdocs/luci-static/resources/view/fchomo/node.js:1144
msgid "Enable encryption"
msgstr "啟用加密"
-#: htdocs/luci-static/resources/view/fchomo/node.js:666
+#: htdocs/luci-static/resources/view/fchomo/node.js:676
msgid "Enable fast open"
msgstr "啟用 Fast open"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2117
+#: htdocs/luci-static/resources/view/fchomo/node.js:2138
msgid "Enable multiplexing only for TCP."
msgstr "僅為 TCP 啟用多路復用。"
@@ -1071,37 +1076,37 @@ msgstr "僅為 TCP 啟用多路復用。"
msgid "Enable obfuscate for downlink"
msgstr "啟用下行鏈路混淆"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1388
-#: htdocs/luci-static/resources/view/fchomo/node.js:2111
+#: htdocs/luci-static/resources/fchomo/listeners.js:1406
+#: htdocs/luci-static/resources/view/fchomo/node.js:2132
msgid "Enable padding"
msgstr "啟用填充"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2122
+#: htdocs/luci-static/resources/view/fchomo/node.js:2143
msgid "Enable statistic"
msgstr "啟用統計"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1257
-#: htdocs/luci-static/resources/view/fchomo/node.js:2542
+#: htdocs/luci-static/resources/view/fchomo/node.js:1271
+#: htdocs/luci-static/resources/view/fchomo/node.js:2563
msgid ""
"Enable the SUoT protocol, requires server support. Conflict with Multiplex."
msgstr "啟用 SUoT 協議,需要服務端支援。與多路復用衝突。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:507
-#: htdocs/luci-static/resources/view/fchomo/node.js:725
+#: htdocs/luci-static/resources/fchomo/listeners.js:516
+#: htdocs/luci-static/resources/view/fchomo/node.js:735
msgid ""
"Enabling obfuscation will make the server incompatible with standard QUIC "
"connections, losing the ability to masquerade with HTTP/3."
msgstr "啟用混淆將使伺服器與標準的 QUIC 連線不相容,失去 HTTP/3 偽裝的能力。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:843
+#: htdocs/luci-static/resources/view/fchomo/node.js:853
msgid "Encrypted Hello"
msgstr "加密 Hello"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1135
+#: htdocs/luci-static/resources/view/fchomo/node.js:1149
msgid "Encryption algorithm"
msgstr "加密演算法"
-#: htdocs/luci-static/resources/fchomo/listeners.js:832
+#: htdocs/luci-static/resources/fchomo/listeners.js:850
msgid "Encryption method"
msgstr "加密方法"
@@ -1124,7 +1129,7 @@ msgid ""
"if empty."
msgstr "超過此限制將會觸發強制健康檢查。留空則使用 5。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2663
+#: htdocs/luci-static/resources/view/fchomo/node.js:2684
msgid "Exclude matched node types."
msgstr "排除匹配的節點類型。"
@@ -1137,15 +1142,15 @@ msgstr ""
"rel=\"noreferrer noopener\">此處。"
#: htdocs/luci-static/resources/view/fchomo/client.js:1251
-#: htdocs/luci-static/resources/view/fchomo/node.js:2656
+#: htdocs/luci-static/resources/view/fchomo/node.js:2677
msgid "Exclude nodes that meet keywords or regexps."
msgstr "排除匹配關鍵字或表達式的節點。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:989
+#: htdocs/luci-static/resources/view/fchomo/node.js:999
msgid "Exit node"
msgstr "出口節點"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1115
+#: htdocs/luci-static/resources/view/fchomo/node.js:1129
msgid "Exit nodes"
msgstr "出口節點"
@@ -1154,46 +1159,46 @@ msgid "Expand/Collapse result"
msgstr "展開/收起 結果"
#: htdocs/luci-static/resources/view/fchomo/client.js:1194
-#: htdocs/luci-static/resources/view/fchomo/node.js:2641
+#: htdocs/luci-static/resources/view/fchomo/node.js:2662
msgid "Expected HTTP code. 204 will be used if empty."
msgstr "預期的 HTTP code。留空則使用 204。"
#: htdocs/luci-static/resources/view/fchomo/client.js:1196
-#: htdocs/luci-static/resources/view/fchomo/node.js:2643
+#: htdocs/luci-static/resources/view/fchomo/node.js:2664
msgid "Expected status"
msgstr "預期狀態"
#: htdocs/luci-static/resources/fchomo.js:529
#: htdocs/luci-static/resources/fchomo.js:532
#: htdocs/luci-static/resources/fchomo.js:535
-#: htdocs/luci-static/resources/fchomo.js:1678
-#: htdocs/luci-static/resources/fchomo.js:1686
-#: htdocs/luci-static/resources/fchomo.js:1694
-#: htdocs/luci-static/resources/fchomo.js:1717
-#: htdocs/luci-static/resources/fchomo.js:1720
-#: htdocs/luci-static/resources/fchomo.js:1727
-#: htdocs/luci-static/resources/fchomo.js:1743
-#: htdocs/luci-static/resources/fchomo.js:1752
-#: htdocs/luci-static/resources/fchomo.js:1764
-#: htdocs/luci-static/resources/fchomo.js:1767
-#: htdocs/luci-static/resources/fchomo.js:1777
-#: htdocs/luci-static/resources/fchomo.js:1789
-#: htdocs/luci-static/resources/fchomo.js:1792
-#: htdocs/luci-static/resources/fchomo.js:1805
-#: htdocs/luci-static/resources/fchomo.js:1814
-#: htdocs/luci-static/resources/fchomo.js:1823
-#: htdocs/luci-static/resources/fchomo.js:1832
-#: htdocs/luci-static/resources/fchomo.js:1867
+#: htdocs/luci-static/resources/fchomo.js:1680
+#: htdocs/luci-static/resources/fchomo.js:1688
+#: htdocs/luci-static/resources/fchomo.js:1696
+#: htdocs/luci-static/resources/fchomo.js:1719
+#: htdocs/luci-static/resources/fchomo.js:1722
+#: htdocs/luci-static/resources/fchomo.js:1729
+#: htdocs/luci-static/resources/fchomo.js:1745
+#: htdocs/luci-static/resources/fchomo.js:1754
+#: htdocs/luci-static/resources/fchomo.js:1766
+#: htdocs/luci-static/resources/fchomo.js:1769
+#: htdocs/luci-static/resources/fchomo.js:1779
+#: htdocs/luci-static/resources/fchomo.js:1791
+#: htdocs/luci-static/resources/fchomo.js:1794
+#: htdocs/luci-static/resources/fchomo.js:1807
+#: htdocs/luci-static/resources/fchomo.js:1816
+#: htdocs/luci-static/resources/fchomo.js:1825
+#: htdocs/luci-static/resources/fchomo.js:1834
#: htdocs/luci-static/resources/fchomo.js:1869
-#: htdocs/luci-static/resources/fchomo.js:1882
-#: htdocs/luci-static/resources/fchomo.js:1888
-#: htdocs/luci-static/resources/fchomo.js:1895
-#: htdocs/luci-static/resources/fchomo.js:1904
+#: htdocs/luci-static/resources/fchomo.js:1871
+#: htdocs/luci-static/resources/fchomo.js:1884
+#: htdocs/luci-static/resources/fchomo.js:1890
+#: htdocs/luci-static/resources/fchomo.js:1897
+#: htdocs/luci-static/resources/fchomo.js:1906
#: htdocs/luci-static/resources/fchomo/listeners.js:291
#: htdocs/luci-static/resources/fchomo/listeners.js:346
-#: htdocs/luci-static/resources/fchomo/listeners.js:861
-#: htdocs/luci-static/resources/fchomo/listeners.js:892
-#: htdocs/luci-static/resources/fchomo/listeners.js:993
+#: htdocs/luci-static/resources/fchomo/listeners.js:879
+#: htdocs/luci-static/resources/fchomo/listeners.js:910
+#: htdocs/luci-static/resources/fchomo/listeners.js:1011
#: htdocs/luci-static/resources/view/fchomo/client.js:71
#: htdocs/luci-static/resources/view/fchomo/client.js:1059
#: htdocs/luci-static/resources/view/fchomo/client.js:1604
@@ -1202,25 +1207,25 @@ msgstr "預期狀態"
#: htdocs/luci-static/resources/view/fchomo/node.js:444
#: htdocs/luci-static/resources/view/fchomo/node.js:497
#: htdocs/luci-static/resources/view/fchomo/node.js:499
-#: htdocs/luci-static/resources/view/fchomo/node.js:900
-#: htdocs/luci-static/resources/view/fchomo/node.js:1415
-#: htdocs/luci-static/resources/view/fchomo/node.js:2755
-#: htdocs/luci-static/resources/view/fchomo/node.js:2785
+#: htdocs/luci-static/resources/view/fchomo/node.js:910
+#: htdocs/luci-static/resources/view/fchomo/node.js:1438
+#: htdocs/luci-static/resources/view/fchomo/node.js:2776
+#: htdocs/luci-static/resources/view/fchomo/node.js:2806
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:311
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:325
msgid "Expecting: %s"
msgstr "請輸入:%s"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1129
+#: htdocs/luci-static/resources/fchomo/listeners.js:1147
msgid "Expecting: Cannot be empty."
msgstr "請輸入:不能為空。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1240
-#: htdocs/luci-static/resources/view/fchomo/node.js:1589
+#: htdocs/luci-static/resources/fchomo/listeners.js:1258
+#: htdocs/luci-static/resources/view/fchomo/node.js:1612
msgid "Expecting: Cannot be enabled when %s is enabled."
msgstr "請輸入:當 %s 啟用時,無法啟用。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1124
+#: htdocs/luci-static/resources/fchomo/listeners.js:1142
msgid "Expecting: Keep empty when %s is enabled."
msgstr "請輸入:啟用 %s 時保持為空。"
@@ -1229,15 +1234,15 @@ msgstr "請輸入:啟用 %s 時保持為空。"
msgid "Expecting: Least one of %s or %s."
msgstr "請輸入:至少包含 %s 或 %s 中的一個。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:699
-#: htdocs/luci-static/resources/fchomo/listeners.js:705
-#: htdocs/luci-static/resources/fchomo/listeners.js:1314
-#: htdocs/luci-static/resources/fchomo/listeners.js:1321
-#: htdocs/luci-static/resources/view/fchomo/node.js:1289
-#: htdocs/luci-static/resources/view/fchomo/node.js:1295
-#: htdocs/luci-static/resources/view/fchomo/node.js:1895
-#: htdocs/luci-static/resources/view/fchomo/node.js:1902
-#: htdocs/luci-static/resources/view/fchomo/node.js:1910
+#: htdocs/luci-static/resources/fchomo/listeners.js:716
+#: htdocs/luci-static/resources/fchomo/listeners.js:723
+#: htdocs/luci-static/resources/fchomo/listeners.js:1332
+#: htdocs/luci-static/resources/fchomo/listeners.js:1339
+#: htdocs/luci-static/resources/view/fchomo/node.js:1311
+#: htdocs/luci-static/resources/view/fchomo/node.js:1318
+#: htdocs/luci-static/resources/view/fchomo/node.js:1916
+#: htdocs/luci-static/resources/view/fchomo/node.js:1923
+#: htdocs/luci-static/resources/view/fchomo/node.js:1931
msgid "Expecting: Only support %s."
msgstr "請輸入:僅支援 %s。"
@@ -1257,19 +1262,19 @@ msgstr "實驗性"
msgid "Factor"
msgstr "條件"
-#: htdocs/luci-static/resources/fchomo.js:1619
+#: htdocs/luci-static/resources/fchomo.js:1621
msgid "Failed to execute \"/etc/init.d/fchomo %s %s\" reason: %s"
msgstr "無法執行 \"/etc/init.d/fchomo %s %s\" 原因: %s"
-#: htdocs/luci-static/resources/fchomo.js:1572
+#: htdocs/luci-static/resources/fchomo.js:1574
msgid "Failed to generate %s, error: %s."
msgstr "生成 %s 失敗,錯誤:%s。"
-#: htdocs/luci-static/resources/fchomo.js:2004
+#: htdocs/luci-static/resources/fchomo.js:2006
msgid "Failed to upload %s, error: %s."
msgstr "上傳 %s 失敗,錯誤:%s。"
-#: htdocs/luci-static/resources/fchomo.js:2023
+#: htdocs/luci-static/resources/fchomo.js:2025
msgid "Failed to upload, error: %s."
msgstr "上傳失敗,錯誤:%s。"
@@ -1289,16 +1294,16 @@ msgstr "後備 DNS 伺服器"
msgid "Fallback filter"
msgstr "後備過濾器"
-#: htdocs/luci-static/resources/view/fchomo/node.js:849
+#: htdocs/luci-static/resources/view/fchomo/node.js:859
msgid "Fallback mode"
msgstr "自動回退模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:856
+#: htdocs/luci-static/resources/view/fchomo/node.js:866
msgid "Fallback relay"
msgstr "自動回退中繼"
#: htdocs/luci-static/resources/view/fchomo/client.js:1246
-#: htdocs/luci-static/resources/view/fchomo/node.js:2650
+#: htdocs/luci-static/resources/view/fchomo/node.js:2671
msgid "Filter nodes that meet keywords or regexps."
msgstr "過濾匹配關鍵字或表達式的節點。"
@@ -1324,12 +1329,12 @@ msgid "Final DNS server (For poisoned domains)"
msgstr "兜底 DNS 伺服器 (用於已被投毒汙染的網域)"
#: htdocs/luci-static/resources/fchomo/listeners.js:138
-#: htdocs/luci-static/resources/view/fchomo/node.js:1617
+#: htdocs/luci-static/resources/view/fchomo/node.js:1640
msgid "Firewall"
msgstr "防火牆"
-#: htdocs/luci-static/resources/fchomo/listeners.js:416
-#: htdocs/luci-static/resources/view/fchomo/node.js:536
+#: htdocs/luci-static/resources/fchomo/listeners.js:425
+#: htdocs/luci-static/resources/view/fchomo/node.js:546
msgid "Flow"
msgstr "流控"
@@ -1342,9 +1347,9 @@ msgstr ""
"noopener\">%s."
#: htdocs/luci-static/resources/view/fchomo/client.js:1195
-#: htdocs/luci-static/resources/view/fchomo/node.js:2503
-#: htdocs/luci-static/resources/view/fchomo/node.js:2511
-#: htdocs/luci-static/resources/view/fchomo/node.js:2642
+#: htdocs/luci-static/resources/view/fchomo/node.js:2524
+#: htdocs/luci-static/resources/view/fchomo/node.js:2532
+#: htdocs/luci-static/resources/view/fchomo/node.js:2663
msgid ""
"For format see %s."
@@ -1352,15 +1357,15 @@ msgstr ""
"格式請參閱 %s"
"a>."
-#: htdocs/luci-static/resources/view/fchomo/node.js:851
+#: htdocs/luci-static/resources/view/fchomo/node.js:861
msgid "Force"
msgstr "強制"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1864
+#: htdocs/luci-static/resources/view/fchomo/node.js:1885
msgid "Force DNS remote resolution."
msgstr "強制 DNS 遠端解析。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1250
+#: htdocs/luci-static/resources/view/fchomo/node.js:1264
msgid "Force UDP"
msgstr "強制開啟 UDP"
@@ -1372,7 +1377,7 @@ msgstr "強制嗅探網域"
msgid "Format"
msgstr "格式"
-#: htdocs/luci-static/resources/fchomo/listeners.js:785
+#: htdocs/luci-static/resources/fchomo/listeners.js:803
msgid "Forwarding rate limit"
msgstr "轉發速率限制"
@@ -1383,7 +1388,7 @@ msgstr "轉發速率限制"
msgid "FullCombo Shark!"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1935
+#: htdocs/luci-static/resources/view/fchomo/node.js:1956
msgid "GET"
msgstr ""
@@ -1391,8 +1396,8 @@ msgstr ""
msgid "GFW list version"
msgstr "GFW 網域清單版本"
-#: htdocs/luci-static/resources/fchomo/listeners.js:502
-#: htdocs/luci-static/resources/view/fchomo/node.js:720
+#: htdocs/luci-static/resources/fchomo/listeners.js:511
+#: htdocs/luci-static/resources/view/fchomo/node.js:730
msgid "Gecko"
msgstr ""
@@ -1403,7 +1408,7 @@ msgstr "常規"
#: htdocs/luci-static/resources/fchomo/listeners.js:119
#: htdocs/luci-static/resources/view/fchomo/client.js:1050
#: htdocs/luci-static/resources/view/fchomo/node.js:252
-#: htdocs/luci-static/resources/view/fchomo/node.js:2313
+#: htdocs/luci-static/resources/view/fchomo/node.js:2334
msgid "General fields"
msgstr "常規欄位"
@@ -1411,17 +1416,17 @@ msgstr "常規欄位"
msgid "General settings"
msgstr "常規設定"
-#: htdocs/luci-static/resources/fchomo.js:721
-#: htdocs/luci-static/resources/fchomo.js:723
-#: htdocs/luci-static/resources/fchomo.js:737
+#: htdocs/luci-static/resources/fchomo.js:722
+#: htdocs/luci-static/resources/fchomo.js:724
#: htdocs/luci-static/resources/fchomo.js:739
+#: htdocs/luci-static/resources/fchomo.js:741
#: htdocs/luci-static/resources/fchomo/listeners.js:269
#: htdocs/luci-static/resources/fchomo/listeners.js:313
#: htdocs/luci-static/resources/fchomo/listeners.js:315
-#: htdocs/luci-static/resources/fchomo/listeners.js:965
-#: htdocs/luci-static/resources/fchomo/listeners.js:1218
+#: htdocs/luci-static/resources/fchomo/listeners.js:983
+#: htdocs/luci-static/resources/fchomo/listeners.js:1236
#: htdocs/luci-static/resources/view/fchomo/global.js:616
-#: htdocs/luci-static/resources/view/fchomo/node.js:2471
+#: htdocs/luci-static/resources/view/fchomo/node.js:2492
msgid "Generate"
msgstr "生成"
@@ -1468,7 +1473,7 @@ msgstr "全域"
msgid "Global Authentication"
msgstr "全域認證"
-#: htdocs/luci-static/resources/view/fchomo/node.js:560
+#: htdocs/luci-static/resources/view/fchomo/node.js:570
msgid "Global padding"
msgstr "全域填充"
@@ -1490,17 +1495,17 @@ msgstr "組"
#: htdocs/luci-static/resources/fchomo.js:191
#: htdocs/luci-static/resources/fchomo.js:228
-#: htdocs/luci-static/resources/fchomo/listeners.js:717
-#: htdocs/luci-static/resources/view/fchomo/node.js:1307
-#: htdocs/luci-static/resources/view/fchomo/node.js:1882
-#: htdocs/luci-static/resources/view/fchomo/node.js:1895
-#: htdocs/luci-static/resources/view/fchomo/node.js:1902
+#: htdocs/luci-static/resources/fchomo/listeners.js:735
+#: htdocs/luci-static/resources/view/fchomo/node.js:1330
+#: htdocs/luci-static/resources/view/fchomo/node.js:1903
+#: htdocs/luci-static/resources/view/fchomo/node.js:1916
+#: htdocs/luci-static/resources/view/fchomo/node.js:1923
msgid "HTTP"
msgstr ""
#: htdocs/luci-static/resources/view/fchomo/node.js:333
-#: htdocs/luci-static/resources/view/fchomo/node.js:1957
-#: htdocs/luci-static/resources/view/fchomo/node.js:2483
+#: htdocs/luci-static/resources/view/fchomo/node.js:1978
+#: htdocs/luci-static/resources/view/fchomo/node.js:2504
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:430
msgid "HTTP header"
msgstr "HTTP header"
@@ -1526,7 +1531,7 @@ msgstr "HTTP 偽裝多路復用"
msgid "HTTP mask: %s"
msgstr "HTTP 偽裝: %s"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1934
+#: htdocs/luci-static/resources/view/fchomo/node.js:1955
msgid "HTTP request method"
msgstr "HTTP 請求方法"
@@ -1539,15 +1544,15 @@ msgstr "HTTP 根路徑"
msgid "HTTP/3"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:525
+#: htdocs/luci-static/resources/fchomo/listeners.js:534
msgid ""
"HTTP3 server behavior when authentication fails.
A 404 page will be "
"returned if empty."
msgstr "身份驗證失敗時的 HTTP3 伺服器回應。預設回傳 404 頁面。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1883
-#: htdocs/luci-static/resources/view/fchomo/node.js:1896
-#: htdocs/luci-static/resources/view/fchomo/node.js:1903
+#: htdocs/luci-static/resources/view/fchomo/node.js:1904
+#: htdocs/luci-static/resources/view/fchomo/node.js:1917
+#: htdocs/luci-static/resources/view/fchomo/node.js:1924
msgid "HTTPUpgrade"
msgstr ""
@@ -1559,58 +1564,58 @@ msgstr "處理網域"
msgid "Handshake mode"
msgstr "握手模式"
-#: htdocs/luci-static/resources/fchomo/listeners.js:767
+#: htdocs/luci-static/resources/fchomo/listeners.js:785
msgid "Handshake target proxy"
msgstr "握手目標代理"
-#: htdocs/luci-static/resources/fchomo/listeners.js:722
+#: htdocs/luci-static/resources/fchomo/listeners.js:740
msgid "Handshake target that supports TLS 1.3"
msgstr "握手目標 (支援 TLS 1.3)"
#: htdocs/luci-static/resources/fchomo/listeners.js:353
-#: htdocs/luci-static/resources/view/fchomo/node.js:1242
+#: htdocs/luci-static/resources/view/fchomo/node.js:1256
msgid "Handshake timeout"
msgstr "握手逾時"
-#: htdocs/luci-static/resources/fchomo/listeners.js:550
+#: htdocs/luci-static/resources/fchomo/listeners.js:559
msgid "Header to read real client IP from (e.g. X-Forwarded-For)"
msgstr "用於讀取客戶端真實 IP 的 Header(例如 X-Forwarded-For)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:968
+#: htdocs/luci-static/resources/view/fchomo/node.js:978
msgid "Headscale/Tailscale"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:796
+#: htdocs/luci-static/resources/view/fchomo/node.js:806
msgid "Health check"
msgstr "健康檢查"
#: htdocs/luci-static/resources/view/fchomo/client.js:1164
-#: htdocs/luci-static/resources/view/fchomo/node.js:2610
+#: htdocs/luci-static/resources/view/fchomo/node.js:2631
msgid "Health check URL"
msgstr "健康檢查 URL"
#: htdocs/luci-static/resources/view/fchomo/client.js:1193
-#: htdocs/luci-static/resources/view/fchomo/node.js:2640
+#: htdocs/luci-static/resources/view/fchomo/node.js:2661
msgid "Health check expected status"
msgstr "健康檢查预期状态"
#: htdocs/luci-static/resources/view/fchomo/client.js:1173
-#: htdocs/luci-static/resources/view/fchomo/node.js:2620
+#: htdocs/luci-static/resources/view/fchomo/node.js:2641
msgid "Health check interval"
msgstr "健康檢查間隔"
#: htdocs/luci-static/resources/view/fchomo/client.js:1180
-#: htdocs/luci-static/resources/view/fchomo/node.js:2627
+#: htdocs/luci-static/resources/view/fchomo/node.js:2648
msgid "Health check timeout"
msgstr "健康檢查逾時"
#: htdocs/luci-static/resources/view/fchomo/client.js:1052
-#: htdocs/luci-static/resources/view/fchomo/node.js:2315
+#: htdocs/luci-static/resources/view/fchomo/node.js:2336
msgid "Health fields"
msgstr "健康欄位"
-#: htdocs/luci-static/resources/view/fchomo/node.js:678
-#: htdocs/luci-static/resources/view/fchomo/node.js:759
+#: htdocs/luci-static/resources/view/fchomo/node.js:688
+#: htdocs/luci-static/resources/view/fchomo/node.js:769
msgid "Heartbeat interval"
msgstr "心跳間隔"
@@ -1618,16 +1623,16 @@ msgstr "心跳間隔"
msgid "Hidden"
msgstr "隱藏"
-#: htdocs/luci-static/resources/fchomo/listeners.js:730
-#: htdocs/luci-static/resources/view/fchomo/node.js:1312
+#: htdocs/luci-static/resources/fchomo/listeners.js:748
+#: htdocs/luci-static/resources/view/fchomo/node.js:1335
msgid "Host that supports TLS 1.3"
msgstr "主機名稱 (支援 TLS 1.3)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1194
+#: htdocs/luci-static/resources/view/fchomo/node.js:1208
msgid "Host-key"
msgstr "主機金鑰"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1189
+#: htdocs/luci-static/resources/view/fchomo/node.js:1203
msgid "Host-key algorithms"
msgstr "主機金鑰演算法"
@@ -1635,12 +1640,12 @@ msgstr "主機金鑰演算法"
msgid "Host/SNI override"
msgstr "主機/SNI 覆蓋"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1063
+#: htdocs/luci-static/resources/view/fchomo/node.js:1073
msgid "Hostname"
msgstr "主機名稱"
-#: htdocs/luci-static/resources/fchomo.js:1458
-#: htdocs/luci-static/resources/view/fchomo/node.js:1455
+#: htdocs/luci-static/resources/fchomo.js:1461
+#: htdocs/luci-static/resources/view/fchomo/node.js:1478
msgid ""
"Hostname that the client attempts to connect to at the start of the TLS "
"handshake process."
@@ -1674,24 +1679,24 @@ msgstr ""
msgid "IP CIDR"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:635
+#: htdocs/luci-static/resources/view/fchomo/node.js:645
msgid "IP override"
msgstr "IP 覆寫"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1200
-#: htdocs/luci-static/resources/view/fchomo/node.js:1210
+#: htdocs/luci-static/resources/view/fchomo/node.js:1214
+#: htdocs/luci-static/resources/view/fchomo/node.js:1224
msgid "IP stack"
msgstr "IP 協定棧"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2177
-#: htdocs/luci-static/resources/view/fchomo/node.js:2596
+#: htdocs/luci-static/resources/view/fchomo/node.js:2198
+#: htdocs/luci-static/resources/view/fchomo/node.js:2617
msgid "IP version"
msgstr "IP 版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1767
-#: htdocs/luci-static/resources/view/fchomo/node.js:1771
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1788
+#: htdocs/luci-static/resources/view/fchomo/node.js:1792
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
msgid "IPv4"
msgstr "IPv4"
@@ -1699,9 +1704,9 @@ msgstr "IPv4"
msgid "IPv4 only"
msgstr "僅 IPv4"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
-#: htdocs/luci-static/resources/view/fchomo/node.js:1799
-#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
+#: htdocs/luci-static/resources/view/fchomo/node.js:1820
+#: htdocs/luci-static/resources/view/fchomo/node.js:1824
msgid "IPv6"
msgstr "IPv6"
@@ -1718,19 +1723,19 @@ msgstr "IPv6 支援"
msgid "Icon"
msgstr "圖標"
-#: htdocs/luci-static/resources/view/fchomo/node.js:608
+#: htdocs/luci-static/resources/view/fchomo/node.js:618
msgid "Idle session check interval"
msgstr "閒置會話檢查間隔"
-#: htdocs/luci-static/resources/view/fchomo/node.js:615
+#: htdocs/luci-static/resources/view/fchomo/node.js:625
msgid "Idle session timeout"
msgstr "閒置會話逾時"
-#: htdocs/luci-static/resources/fchomo/listeners.js:662
+#: htdocs/luci-static/resources/fchomo/listeners.js:671
msgid "Idle timeout"
msgstr "閒置逾時"
-#: htdocs/luci-static/resources/fchomo.js:1720
+#: htdocs/luci-static/resources/fchomo.js:1722
msgid "If All ports is selected, uncheck others"
msgstr "如果選擇了“所有連接埠”,則取消選取“其他”"
@@ -1738,17 +1743,17 @@ msgstr "如果選擇了“所有連接埠”,則取消選取“其他”"
msgid "If Block is selected, uncheck others"
msgstr "如果選擇了“封鎖”,則取消選取“其他”"
-#: htdocs/luci-static/resources/fchomo/listeners.js:492
+#: htdocs/luci-static/resources/fchomo/listeners.js:501
msgid "Ignore client bandwidth"
msgstr "忽略客戶端頻寬"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1154
+#: htdocs/luci-static/resources/view/fchomo/node.js:1168
msgid ""
"Ignore the number of intermediate hops and select the path with the lowest "
"total latency."
msgstr "忽略中繼跳數,選擇總延遲最低的路徑。"
-#: htdocs/luci-static/resources/fchomo.js:906
+#: htdocs/luci-static/resources/fchomo.js:909
msgid "Import"
msgstr "導入"
@@ -1764,8 +1769,8 @@ msgstr "導入"
#: htdocs/luci-static/resources/view/fchomo/client.js:1812
#: htdocs/luci-static/resources/view/fchomo/client.js:1847
#: htdocs/luci-static/resources/view/fchomo/client.js:1868
-#: htdocs/luci-static/resources/view/fchomo/node.js:2203
-#: htdocs/luci-static/resources/view/fchomo/node.js:2301
+#: htdocs/luci-static/resources/view/fchomo/node.js:2224
+#: htdocs/luci-static/resources/view/fchomo/node.js:2322
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:164
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:260
msgid "Import mihomo config"
@@ -1777,48 +1782,48 @@ msgstr "導入 mihomo 配置"
msgid "Import rule-set links"
msgstr "導入規則集連結"
-#: htdocs/luci-static/resources/fchomo/listeners.js:481
-#: htdocs/luci-static/resources/fchomo/listeners.js:487
-#: htdocs/luci-static/resources/view/fchomo/node.js:694
-#: htdocs/luci-static/resources/view/fchomo/node.js:700
-#: htdocs/luci-static/resources/view/fchomo/node.js:2548
-#: htdocs/luci-static/resources/view/fchomo/node.js:2554
+#: htdocs/luci-static/resources/fchomo/listeners.js:490
+#: htdocs/luci-static/resources/fchomo/listeners.js:496
+#: htdocs/luci-static/resources/view/fchomo/node.js:704
+#: htdocs/luci-static/resources/view/fchomo/node.js:710
+#: htdocs/luci-static/resources/view/fchomo/node.js:2569
+#: htdocs/luci-static/resources/view/fchomo/node.js:2575
msgid "In Mbps."
msgstr "單位為 Mbps。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:786
+#: htdocs/luci-static/resources/fchomo/listeners.js:804
msgid "In bps. 0 means no speed limit."
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2391
+#: htdocs/luci-static/resources/view/fchomo/node.js:2412
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:403
msgid "In bytes. %s will be used if empty."
msgstr "單位為位元組。留空則使用 %s。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1289
-#: htdocs/luci-static/resources/view/fchomo/node.js:679
-#: htdocs/luci-static/resources/view/fchomo/node.js:686
-#: htdocs/luci-static/resources/view/fchomo/node.js:760
+#: htdocs/luci-static/resources/fchomo/listeners.js:1307
+#: htdocs/luci-static/resources/view/fchomo/node.js:689
+#: htdocs/luci-static/resources/view/fchomo/node.js:696
+#: htdocs/luci-static/resources/view/fchomo/node.js:770
msgid "In millisecond."
msgstr "單位為毫秒。"
#: htdocs/luci-static/resources/view/fchomo/client.js:1181
#: htdocs/luci-static/resources/view/fchomo/client.js:1227
-#: htdocs/luci-static/resources/view/fchomo/node.js:2628
+#: htdocs/luci-static/resources/view/fchomo/node.js:2649
msgid "In millisecond. %s will be used if empty."
msgstr "單位為毫秒。留空則使用 %s。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2026
+#: htdocs/luci-static/resources/view/fchomo/node.js:2047
msgid "In milliseconds."
msgstr "單位為毫秒。"
#: htdocs/luci-static/resources/fchomo/listeners.js:207
#: htdocs/luci-static/resources/fchomo/listeners.js:354
-#: htdocs/luci-static/resources/fchomo/listeners.js:473
-#: htdocs/luci-static/resources/fchomo/listeners.js:663
-#: htdocs/luci-static/resources/view/fchomo/node.js:609
-#: htdocs/luci-static/resources/view/fchomo/node.js:616
-#: htdocs/luci-static/resources/view/fchomo/node.js:1973
+#: htdocs/luci-static/resources/fchomo/listeners.js:482
+#: htdocs/luci-static/resources/fchomo/listeners.js:672
+#: htdocs/luci-static/resources/view/fchomo/node.js:619
+#: htdocs/luci-static/resources/view/fchomo/node.js:626
+#: htdocs/luci-static/resources/view/fchomo/node.js:1994
msgid "In seconds."
msgstr "單位為秒。"
@@ -1826,21 +1831,21 @@ msgstr "單位為秒。"
#: htdocs/luci-static/resources/view/fchomo/global.js:446
#: htdocs/luci-static/resources/view/fchomo/global.js:451
#: htdocs/luci-static/resources/view/fchomo/global.js:537
-#: htdocs/luci-static/resources/view/fchomo/node.js:712
-#: htdocs/luci-static/resources/view/fchomo/node.js:2397
-#: htdocs/luci-static/resources/view/fchomo/node.js:2621
+#: htdocs/luci-static/resources/view/fchomo/node.js:722
+#: htdocs/luci-static/resources/view/fchomo/node.js:2418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2642
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:409
msgid "In seconds. %s will be used if empty."
msgstr "單位為秒。留空則使用 %s。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1243
+#: htdocs/luci-static/resources/view/fchomo/node.js:1257
msgid ""
"In seconds. After configuration, the handshake is not affected by the outer "
"connection timeout."
msgstr "單位為秒。配置後握手時不受外層連線逾時影響。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:881
-#: htdocs/luci-static/resources/view/fchomo/node.js:1404
+#: htdocs/luci-static/resources/fchomo/listeners.js:899
+#: htdocs/luci-static/resources/view/fchomo/node.js:1427
msgid ""
"In the order of one Padding-Length and one Padding-"
"Interval, infinite concatenation."
@@ -1883,17 +1888,17 @@ msgstr "引入所有代理節點。"
msgid "Info"
msgstr "訊息"
-#: htdocs/luci-static/resources/fchomo/listeners.js:572
-#: htdocs/luci-static/resources/view/fchomo/node.js:766
+#: htdocs/luci-static/resources/fchomo/listeners.js:581
+#: htdocs/luci-static/resources/view/fchomo/node.js:776
msgid "Initial congestion window size"
msgstr "初始擁塞視窗大小"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2330
+#: htdocs/luci-static/resources/view/fchomo/node.js:2351
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:299
msgid "Inline"
msgstr "內嵌"
-#: htdocs/luci-static/resources/view/fchomo/node.js:826
+#: htdocs/luci-static/resources/view/fchomo/node.js:836
msgid "Insane"
msgstr "噩夢"
@@ -1901,19 +1906,19 @@ msgstr "噩夢"
msgid "Interface Control"
msgstr "介面控制"
-#: htdocs/luci-static/resources/fchomo/listeners.js:692
-#: htdocs/luci-static/resources/fchomo/listeners.js:702
-#: htdocs/luci-static/resources/fchomo/listeners.js:707
-#: htdocs/luci-static/resources/fchomo/listeners.js:1126
-#: htdocs/luci-static/resources/fchomo/listeners.js:1242
-#: htdocs/luci-static/resources/view/fchomo/node.js:1282
-#: htdocs/luci-static/resources/view/fchomo/node.js:1292
-#: htdocs/luci-static/resources/view/fchomo/node.js:1297
-#: htdocs/luci-static/resources/view/fchomo/node.js:1591
+#: htdocs/luci-static/resources/fchomo/listeners.js:701
+#: htdocs/luci-static/resources/fchomo/listeners.js:720
+#: htdocs/luci-static/resources/fchomo/listeners.js:725
+#: htdocs/luci-static/resources/fchomo/listeners.js:1144
+#: htdocs/luci-static/resources/fchomo/listeners.js:1260
+#: htdocs/luci-static/resources/view/fchomo/node.js:1296
+#: htdocs/luci-static/resources/view/fchomo/node.js:1315
+#: htdocs/luci-static/resources/view/fchomo/node.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1614
msgid "JLS"
msgstr "JLS"
-#: htdocs/luci-static/resources/view/fchomo/node.js:893
+#: htdocs/luci-static/resources/view/fchomo/node.js:903
msgid "Join %s. Format: %s"
msgstr "加入 %s。格式:%s"
@@ -1922,13 +1927,15 @@ msgstr "加入 %s。格式:%s"
#: htdocs/luci-static/resources/fchomo.js:97
#: htdocs/luci-static/resources/fchomo.js:211
#: htdocs/luci-static/resources/fchomo.js:454
-#: htdocs/luci-static/resources/view/fchomo/node.js:1136
-#: htdocs/luci-static/resources/view/fchomo/node.js:1201
-#: htdocs/luci-static/resources/view/fchomo/node.js:2570
+#: htdocs/luci-static/resources/fchomo/listeners.js:411
+#: htdocs/luci-static/resources/view/fchomo/node.js:532
+#: htdocs/luci-static/resources/view/fchomo/node.js:1150
+#: htdocs/luci-static/resources/view/fchomo/node.js:1215
+#: htdocs/luci-static/resources/view/fchomo/node.js:2591
msgid "Keep default"
msgstr "保持預設"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2062
+#: htdocs/luci-static/resources/view/fchomo/node.js:2083
msgid "Keep-alive period"
msgstr "Keep-alive 週期"
@@ -1937,13 +1944,13 @@ msgstr "Keep-alive 週期"
msgid "Key"
msgstr "密鑰"
-#: htdocs/luci-static/resources/fchomo.js:1494
-#: htdocs/luci-static/resources/fchomo/listeners.js:1145
-#: htdocs/luci-static/resources/view/fchomo/node.js:1541
+#: htdocs/luci-static/resources/fchomo.js:1497
+#: htdocs/luci-static/resources/fchomo/listeners.js:1163
+#: htdocs/luci-static/resources/view/fchomo/node.js:1564
msgid "Key path"
msgstr "憑證路徑"
-#: htdocs/luci-static/resources/fchomo/listeners.js:900
+#: htdocs/luci-static/resources/fchomo/listeners.js:918
msgid "Keypairs"
msgstr "密鑰對"
@@ -1966,18 +1973,18 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1818
#: htdocs/luci-static/resources/view/fchomo/client.js:1874
#: htdocs/luci-static/resources/view/fchomo/node.js:262
-#: htdocs/luci-static/resources/view/fchomo/node.js:2318
-#: htdocs/luci-static/resources/view/fchomo/node.js:2714
+#: htdocs/luci-static/resources/view/fchomo/node.js:2339
+#: htdocs/luci-static/resources/view/fchomo/node.js:2735
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:278
msgid "Label"
msgstr "標籤"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1153
+#: htdocs/luci-static/resources/view/fchomo/node.js:1167
msgid "Latency first"
msgstr "延遲優先"
#: htdocs/luci-static/resources/view/fchomo/client.js:1187
-#: htdocs/luci-static/resources/view/fchomo/node.js:2634
+#: htdocs/luci-static/resources/view/fchomo/node.js:2655
msgid "Lazy"
msgstr "怠惰狀態"
@@ -1994,7 +2001,7 @@ msgstr "怠惰查詢。"
msgid "Legacy"
msgstr "傳統"
-#: htdocs/luci-static/resources/fchomo/listeners.js:425
+#: htdocs/luci-static/resources/fchomo/listeners.js:434
msgid ""
"Legacy protocol support (VMess MD5 Authentication) is provided for "
"compatibility purposes only, use of alterId > 1 is not recommended."
@@ -2006,19 +2013,19 @@ msgstr ""
msgid "Less compatibility and sometimes better performance."
msgstr "有時效能較好。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1116
+#: htdocs/luci-static/resources/view/fchomo/node.js:1130
msgid "List of exit nodes to use (%s of peer nodes)."
msgstr "要使用的出口節點清單(對端節點的 %s)。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1124
+#: htdocs/luci-static/resources/view/fchomo/node.js:1138
msgid ""
"List of local subnets (CIDR) to be open to other peers in the EasyTier "
"network."
msgstr "要向 EasyTier 網路中的其他對端開放的本機子網的清單(CIDR)。"
-#: htdocs/luci-static/resources/fchomo.js:1463
-#: htdocs/luci-static/resources/fchomo/listeners.js:1068
-#: htdocs/luci-static/resources/view/fchomo/node.js:1461
+#: htdocs/luci-static/resources/fchomo.js:1466
+#: htdocs/luci-static/resources/fchomo/listeners.js:1086
+#: htdocs/luci-static/resources/view/fchomo/node.js:1484
msgid "List of supported application level protocols, in order of preference."
msgstr "支援的應用層協議協商清單,依序排列。"
@@ -2036,8 +2043,8 @@ msgstr "監聽介面"
#: htdocs/luci-static/resources/fchomo/listeners.js:154
#: htdocs/luci-static/resources/view/fchomo/client.js:1467
-#: htdocs/luci-static/resources/view/fchomo/node.js:1685
-#: htdocs/luci-static/resources/view/fchomo/node.js:1695
+#: htdocs/luci-static/resources/view/fchomo/node.js:1707
+#: htdocs/luci-static/resources/view/fchomo/node.js:1717
msgid "Listen port"
msgstr "監聽埠"
@@ -2049,7 +2056,7 @@ msgstr "監聽埠"
msgid "Listen routing mark (Fwmark)"
msgstr "監聽路由標記 (Fwmark)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1733
+#: htdocs/luci-static/resources/view/fchomo/node.js:1754
msgid "Listeners"
msgstr "監聽"
@@ -2057,7 +2064,7 @@ msgstr "監聽"
msgid "Load balance"
msgstr "負載均衡"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2328
+#: htdocs/luci-static/resources/view/fchomo/node.js:2349
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:297
msgid "Local"
msgstr "本地"
@@ -2082,7 +2089,7 @@ msgstr "日誌等級"
msgid "Logical"
msgstr "邏輯"
-#: htdocs/luci-static/resources/view/fchomo/node.js:837
+#: htdocs/luci-static/resources/view/fchomo/node.js:847
msgid "Low Bandwidth Mode"
msgstr "低頻寬模式"
@@ -2102,7 +2109,7 @@ msgid "Lowercase only"
msgstr "僅限小寫"
#: htdocs/luci-static/resources/view/fchomo/global.js:524
-#: htdocs/luci-static/resources/view/fchomo/node.js:1833
+#: htdocs/luci-static/resources/view/fchomo/node.js:1854
msgid "MTU"
msgstr "MTU"
@@ -2110,7 +2117,7 @@ msgstr "MTU"
msgid "Masque"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:524
+#: htdocs/luci-static/resources/fchomo/listeners.js:533
msgid "Masquerade"
msgstr "偽裝"
@@ -2142,24 +2149,24 @@ msgstr "匹配回應通過 ipcidr"
msgid "Match rule set."
msgstr "匹配規則集。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1979
+#: htdocs/luci-static/resources/view/fchomo/node.js:2000
msgid "Max Early Data"
msgstr "前置數據最大值"
-#: htdocs/luci-static/resources/fchomo/listeners.js:466
-#: htdocs/luci-static/resources/view/fchomo/node.js:660
+#: htdocs/luci-static/resources/fchomo/listeners.js:475
+#: htdocs/luci-static/resources/view/fchomo/node.js:670
msgid "Max UDP relay packet size"
msgstr "UDP 中繼數據包最大尺寸"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1365
+#: htdocs/luci-static/resources/fchomo/listeners.js:1383
msgid "Max buffered posts"
msgstr "POST 最大緩衝"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2037
+#: htdocs/luci-static/resources/view/fchomo/node.js:2058
msgid "Max concurrency"
msgstr "最大並發"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2042
+#: htdocs/luci-static/resources/view/fchomo/node.js:2063
msgid "Max connections"
msgstr "最大連線數"
@@ -2167,56 +2174,56 @@ msgstr "最大連線數"
msgid "Max count of failures"
msgstr "最大失敗次數"
-#: htdocs/luci-static/resources/fchomo/listeners.js:578
-#: htdocs/luci-static/resources/view/fchomo/node.js:772
+#: htdocs/luci-static/resources/fchomo/listeners.js:587
+#: htdocs/luci-static/resources/view/fchomo/node.js:782
msgid "Max datagram frame size"
msgstr "最大資料封包大小"
-#: htdocs/luci-static/resources/fchomo/listeners.js:486
-#: htdocs/luci-static/resources/view/fchomo/node.js:699
+#: htdocs/luci-static/resources/fchomo/listeners.js:495
+#: htdocs/luci-static/resources/view/fchomo/node.js:709
msgid "Max download speed"
msgstr "最大下載速度"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1376
-#: htdocs/luci-static/resources/view/fchomo/node.js:2019
+#: htdocs/luci-static/resources/fchomo/listeners.js:1394
+#: htdocs/luci-static/resources/view/fchomo/node.js:2040
msgid "Max each POST bytes"
msgstr "POST 最大位元組數"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1236
+#: htdocs/luci-static/resources/view/fchomo/node.js:1250
msgid "Max open streams"
msgstr "限制打開流的數量"
-#: htdocs/luci-static/resources/fchomo/listeners.js:537
+#: htdocs/luci-static/resources/fchomo/listeners.js:546
msgid "Max realms"
msgstr "最大 Realms 數量"
-#: htdocs/luci-static/resources/fchomo/listeners.js:543
+#: htdocs/luci-static/resources/fchomo/listeners.js:552
msgid "Max realms per client IP"
msgstr "每客戶端 IP 最大 Realms 數量"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2052
+#: htdocs/luci-static/resources/view/fchomo/node.js:2073
msgid "Max request times"
msgstr "最大請求次數"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2057
+#: htdocs/luci-static/resources/view/fchomo/node.js:2078
msgid "Max reusable seconds"
msgstr "最大可重用秒數"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2047
+#: htdocs/luci-static/resources/view/fchomo/node.js:2068
msgid "Max reuse times"
msgstr "最大重用次數"
-#: htdocs/luci-static/resources/fchomo/listeners.js:480
-#: htdocs/luci-static/resources/view/fchomo/node.js:693
+#: htdocs/luci-static/resources/fchomo/listeners.js:489
+#: htdocs/luci-static/resources/view/fchomo/node.js:703
msgid "Max upload speed"
msgstr "最大上傳速度"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2083
-#: htdocs/luci-static/resources/view/fchomo/node.js:2103
+#: htdocs/luci-static/resources/view/fchomo/node.js:2104
+#: htdocs/luci-static/resources/view/fchomo/node.js:2124
msgid "Maximum connections"
msgstr "最大連線數"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2101
+#: htdocs/luci-static/resources/view/fchomo/node.js:2122
msgid ""
"Maximum multiplexed streams in a connection before opening a new connection."
"
Conflict with %s and %s."
@@ -2236,7 +2243,7 @@ msgid ""
"rate."
msgstr "最大填充率必須大於等于最小填充率。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2100
+#: htdocs/luci-static/resources/view/fchomo/node.js:2121
msgid "Maximum streams"
msgstr "最大流數量"
@@ -2257,15 +2264,15 @@ msgstr "Mihomo 客戶端"
msgid "Mihomo server"
msgstr "Mihomo 服務端"
-#: htdocs/luci-static/resources/view/fchomo/node.js:622
+#: htdocs/luci-static/resources/view/fchomo/node.js:632
msgid "Min of idle sessions to keep"
msgstr "要保留的最少閒置會話數"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2025
+#: htdocs/luci-static/resources/view/fchomo/node.js:2046
msgid "Min posts interval"
msgstr "POST 請求最小間隔時間"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2092
+#: htdocs/luci-static/resources/view/fchomo/node.js:2113
msgid ""
"Minimum multiplexed streams in a connection before opening a new connection."
msgstr "在開啟新連線之前,連線中的最小多路復用流數量。"
@@ -2275,8 +2282,8 @@ msgstr "在開啟新連線之前,連線中的最小多路復用流數量。"
msgid "Minimum padding rate"
msgstr "最小填充率"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2091
-#: htdocs/luci-static/resources/view/fchomo/node.js:2103
+#: htdocs/luci-static/resources/view/fchomo/node.js:2112
+#: htdocs/luci-static/resources/view/fchomo/node.js:2124
msgid "Minimum streams"
msgstr "最小流數量"
@@ -2297,8 +2304,8 @@ msgstr "混合 系統 TCP 堆栈和 gVisor UDP 堆栈
msgid "Mixed port"
msgstr "混合連接埠"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1383
-#: htdocs/luci-static/resources/view/fchomo/node.js:2069
+#: htdocs/luci-static/resources/fchomo/listeners.js:1401
+#: htdocs/luci-static/resources/view/fchomo/node.js:2090
msgid "Multiplex"
msgstr "多路復用"
@@ -2311,12 +2318,16 @@ msgstr "多路復用欄位"
msgid "Multiplexing"
msgstr "多路復用"
+#: htdocs/luci-static/resources/view/fchomo/node.js:531
+msgid "Must be consistent with the server."
+msgstr "必須與伺服器保持一致。"
+
#: htdocs/luci-static/resources/view/fchomo/client.js:706
#: htdocs/luci-static/resources/view/fchomo/client.js:707
msgid "NETWORK"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1751
+#: htdocs/luci-static/resources/view/fchomo/node.js:1772
msgid "NO Listener"
msgstr "無監聽"
@@ -2325,11 +2336,11 @@ msgstr "無監聽"
msgid "NOT"
msgstr "NOT"
-#: htdocs/luci-static/resources/fchomo/listeners.js:630
+#: htdocs/luci-static/resources/fchomo/listeners.js:639
msgid "Name of the Proxy group as outbound."
msgstr "出站代理組的名稱。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2403
+#: htdocs/luci-static/resources/view/fchomo/node.js:2424
msgid "Name of the Proxy group to download provider."
msgstr "用於下載供應商訂閱的代理組名稱。"
@@ -2337,11 +2348,11 @@ msgstr "用於下載供應商訂閱的代理組名稱。"
msgid "Name of the Proxy group to download rule set."
msgstr "用於下載規則集訂閱的代理組名稱。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:618
+#: htdocs/luci-static/resources/fchomo/listeners.js:627
msgid "Name of the Sub rule used for inbound matching."
msgstr "用於入站匹配的子規則名稱。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:644
+#: htdocs/luci-static/resources/view/fchomo/node.js:654
msgid "Native UDP"
msgstr "原生 UDP"
@@ -2350,15 +2361,15 @@ msgid "Native appearance"
msgstr "原生外觀"
#: htdocs/luci-static/resources/fchomo.js:362
-#: htdocs/luci-static/resources/view/fchomo/node.js:1016
+#: htdocs/luci-static/resources/view/fchomo/node.js:1026
msgid "Network"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:669
+#: htdocs/luci-static/resources/fchomo/listeners.js:678
msgid "Network type"
msgstr "網路類型"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2572
+#: htdocs/luci-static/resources/view/fchomo/node.js:2593
msgid "No"
msgstr ""
@@ -2366,7 +2377,7 @@ msgstr ""
msgid "No Authentication IP ranges"
msgstr "無需認證的 IP 範圍"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1360
+#: htdocs/luci-static/resources/fchomo/listeners.js:1378
msgid "No SSE header"
msgstr "無 SSE header"
@@ -2374,16 +2385,26 @@ msgstr "無 SSE header"
msgid "No add'l params"
msgstr "無附加參數"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2009
+#: htdocs/luci-static/resources/fchomo/listeners.js:414
+#: htdocs/luci-static/resources/view/fchomo/node.js:535
+msgid "No encryption No obfuscation"
+msgstr "無加密無混淆"
+
+#: htdocs/luci-static/resources/view/fchomo/node.js:2030
msgid "No gRPC header"
msgstr "無 gRPC header"
+#: htdocs/luci-static/resources/fchomo/listeners.js:413
+#: htdocs/luci-static/resources/view/fchomo/node.js:534
+msgid "No obfuscation"
+msgstr "無混淆"
+
#: htdocs/luci-static/resources/view/fchomo/client.js:1188
-#: htdocs/luci-static/resources/view/fchomo/node.js:2635
+#: htdocs/luci-static/resources/view/fchomo/node.js:2656
msgid "No testing is performed when this provider node is not in use."
msgstr "當此供應商的節點未使用時,不執行任何測試。"
-#: htdocs/luci-static/resources/fchomo.js:867
+#: htdocs/luci-static/resources/fchomo.js:870
msgid "No valid %s found."
msgstr "未找到有效的%s。"
@@ -2397,17 +2418,17 @@ msgid "Node"
msgstr "節點"
#: htdocs/luci-static/resources/view/fchomo/client.js:1250
-#: htdocs/luci-static/resources/view/fchomo/node.js:2655
+#: htdocs/luci-static/resources/view/fchomo/node.js:2676
msgid "Node exclude filter"
msgstr "排除節點"
#: htdocs/luci-static/resources/view/fchomo/client.js:1255
-#: htdocs/luci-static/resources/view/fchomo/node.js:2662
+#: htdocs/luci-static/resources/view/fchomo/node.js:2683
msgid "Node exclude type"
msgstr "排除節點類型"
#: htdocs/luci-static/resources/view/fchomo/client.js:1245
-#: htdocs/luci-static/resources/view/fchomo/node.js:2649
+#: htdocs/luci-static/resources/view/fchomo/node.js:2670
msgid "Node filter"
msgstr "過濾節點"
@@ -2419,7 +2440,7 @@ msgstr "節點切換容差"
msgid "None"
msgstr "無"
-#: htdocs/luci-static/resources/view/fchomo/node.js:822
+#: htdocs/luci-static/resources/view/fchomo/node.js:832
msgid "Normal"
msgstr "正常"
@@ -2427,11 +2448,11 @@ msgstr "正常"
msgid "Not Installed"
msgstr "未安裝"
-#: htdocs/luci-static/resources/fchomo.js:1396
+#: htdocs/luci-static/resources/fchomo.js:1399
msgid "Not Running"
msgstr "未在運作"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2680
+#: htdocs/luci-static/resources/view/fchomo/node.js:2701
msgid "Note: The subscription of provider %s is includes %s."
msgstr "注意:供應商 %s 的訂閱包含 %s。"
@@ -2443,30 +2464,30 @@ msgstr ""
msgid "ON"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:716
-#: htdocs/luci-static/resources/view/fchomo/node.js:1306
+#: htdocs/luci-static/resources/fchomo/listeners.js:734
+#: htdocs/luci-static/resources/view/fchomo/node.js:1329
msgid "Obfs Mode"
msgstr "Obfs 模式"
-#: htdocs/luci-static/resources/fchomo/listeners.js:519
-#: htdocs/luci-static/resources/view/fchomo/node.js:737
+#: htdocs/luci-static/resources/fchomo/listeners.js:528
+#: htdocs/luci-static/resources/view/fchomo/node.js:747
msgid "Obfuscate maximum packet size"
msgstr "混淆最大資料包大小"
-#: htdocs/luci-static/resources/fchomo/listeners.js:514
-#: htdocs/luci-static/resources/view/fchomo/node.js:732
+#: htdocs/luci-static/resources/fchomo/listeners.js:523
+#: htdocs/luci-static/resources/view/fchomo/node.js:742
msgid "Obfuscate minimum packet size"
msgstr "混淆最小資料包大小"
-#: htdocs/luci-static/resources/fchomo/listeners.js:506
-#: htdocs/luci-static/resources/view/fchomo/node.js:724
+#: htdocs/luci-static/resources/fchomo/listeners.js:515
+#: htdocs/luci-static/resources/view/fchomo/node.js:734
msgid "Obfuscate password"
msgstr "混淆密碼"
#: htdocs/luci-static/resources/fchomo/listeners.js:298
-#: htdocs/luci-static/resources/fchomo/listeners.js:499
+#: htdocs/luci-static/resources/fchomo/listeners.js:508
#: htdocs/luci-static/resources/view/fchomo/node.js:415
-#: htdocs/luci-static/resources/view/fchomo/node.js:717
+#: htdocs/luci-static/resources/view/fchomo/node.js:727
msgid "Obfuscate type"
msgstr "混淆類型"
@@ -2481,7 +2502,7 @@ msgstr "混淆為%s"
msgid "One or more numbers in the range 0-63 separated by commas"
msgstr "0-63 範圍內的一個或多個數字,以逗號分隔"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1062
+#: htdocs/luci-static/resources/fchomo/listeners.js:1080
msgid "Only applicable when %s are used as a frontend."
msgstr "僅當 %s 用作前端時適用。"
@@ -2490,7 +2511,7 @@ msgstr "僅當 %s 用作前端時適用。"
msgid "Only applies to the %s."
msgstr "只對%s生效。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1057
+#: htdocs/luci-static/resources/view/fchomo/node.js:1067
msgid ""
"Only nodes using the same %s and %s as this network are permitted to perform "
"a handshake or relay traffic through this node."
@@ -2500,11 +2521,11 @@ msgstr "僅允許使用與本網路相同的 %s 和 %s 的節點透過此節點
msgid "Only process traffic from specific interfaces. Leave empty for all."
msgstr "只處理來自指定介面的流量。留空表示全部。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1734
+#: htdocs/luci-static/resources/view/fchomo/node.js:1755
msgid "Only the address %s is valid."
msgstr "只有位址 %s 是有效的。"
-#: htdocs/luci-static/resources/fchomo.js:1390
+#: htdocs/luci-static/resources/fchomo.js:1393
msgid "Open Dashboard"
msgstr "打開面板"
@@ -2520,7 +2541,7 @@ msgstr "該選項已棄用,請使用%s作為代替。"
msgid "Other"
msgstr "其他"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2520
+#: htdocs/luci-static/resources/view/fchomo/node.js:2541
msgid "Other configuration items"
msgstr "其他配置項"
@@ -2528,9 +2549,9 @@ msgstr "其他配置項"
msgid "Outbound"
msgstr "出站"
-#: htdocs/luci-static/resources/fchomo.js:1474
-#: htdocs/luci-static/resources/view/fchomo/node.js:1513
-#: htdocs/luci-static/resources/view/fchomo/node.js:2559
+#: htdocs/luci-static/resources/fchomo.js:1477
+#: htdocs/luci-static/resources/view/fchomo/node.js:1536
+#: htdocs/luci-static/resources/view/fchomo/node.js:2580
msgid "Override cert DNSName"
msgstr "覆蓋憑證 DNSName"
@@ -2540,11 +2561,11 @@ msgid "Override destination"
msgstr "覆蓋目標位址"
#: htdocs/luci-static/resources/view/fchomo/client.js:1051
-#: htdocs/luci-static/resources/view/fchomo/node.js:2314
+#: htdocs/luci-static/resources/view/fchomo/node.js:2335
msgid "Override fields"
msgstr "覆蓋欄位"
-#: htdocs/luci-static/resources/view/fchomo/node.js:636
+#: htdocs/luci-static/resources/view/fchomo/node.js:646
msgid "Override the IP address of the server that DNS response."
msgstr "覆蓋 DNS 回應的伺服器的 IP 位址。"
@@ -2560,7 +2581,7 @@ msgstr "使用嗅探到的網域覆寫連線目標。"
msgid "Override the existing ECS in original request."
msgstr "覆蓋原始請求中已有的 ECS。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1568
+#: htdocs/luci-static/resources/view/fchomo/node.js:1591
msgid "Overrides the domain name used for HTTPS record queries."
msgstr "覆蓋用於 HTTPS 記錄查詢的網域。"
@@ -2568,42 +2589,42 @@ msgstr "覆蓋用於 HTTPS 記錄查詢的網域。"
msgid "Overview"
msgstr "概覽"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1936
+#: htdocs/luci-static/resources/view/fchomo/node.js:1957
msgid "POST"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1937
+#: htdocs/luci-static/resources/view/fchomo/node.js:1958
msgid "PUT"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:572
+#: htdocs/luci-static/resources/view/fchomo/node.js:582
msgid "Packet encoding"
msgstr "數據包編碼"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2014
+#: htdocs/luci-static/resources/view/fchomo/node.js:2035
msgid "Padding bytes"
msgstr "填充位元組"
-#: htdocs/luci-static/resources/fchomo/listeners.js:455
+#: htdocs/luci-static/resources/fchomo/listeners.js:464
msgid "Padding scheme"
msgstr "填充方案"
-#: htdocs/luci-static/resources/fchomo/listeners.js:879
-#: htdocs/luci-static/resources/view/fchomo/node.js:1402
+#: htdocs/luci-static/resources/fchomo/listeners.js:897
+#: htdocs/luci-static/resources/view/fchomo/node.js:1425
msgid "Paddings"
msgstr "填充 (Paddings)"
#: htdocs/luci-static/resources/fchomo/listeners.js:167
#: htdocs/luci-static/resources/fchomo/listeners.js:184
-#: htdocs/luci-static/resources/fchomo/listeners.js:745
+#: htdocs/luci-static/resources/fchomo/listeners.js:763
#: htdocs/luci-static/resources/view/fchomo/node.js:327
#: htdocs/luci-static/resources/view/fchomo/node.js:348
-#: htdocs/luci-static/resources/view/fchomo/node.js:1327
+#: htdocs/luci-static/resources/view/fchomo/node.js:1350
msgid "Password"
msgstr "密碼"
-#: htdocs/luci-static/resources/fchomo/listeners.js:596
-#: htdocs/luci-static/resources/view/fchomo/node.js:790
+#: htdocs/luci-static/resources/fchomo/listeners.js:605
+#: htdocs/luci-static/resources/view/fchomo/node.js:800
msgid "Path MTU Discovery"
msgstr "路徑 MTU 發現"
@@ -2615,17 +2636,17 @@ msgstr "捆綁包路徑"
msgid "Path in bundle: %s"
msgstr "在捆綁包%s中的路徑"
-#: htdocs/luci-static/resources/fchomo/listeners.js:819
-#: htdocs/luci-static/resources/view/fchomo/node.js:2378
+#: htdocs/luci-static/resources/fchomo/listeners.js:837
+#: htdocs/luci-static/resources/view/fchomo/node.js:2399
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:384
msgid "Payload"
msgstr "Payload"
-#: htdocs/luci-static/resources/view/fchomo/node.js:929
+#: htdocs/luci-static/resources/view/fchomo/node.js:939
msgid "Peer public key"
msgstr "對端公鑰"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1068
+#: htdocs/luci-static/resources/view/fchomo/node.js:1078
msgid "Peers"
msgstr "對等端點"
@@ -2635,15 +2656,15 @@ msgid ""
"it is not needed."
msgstr "效能可能會略有下降,建議僅在需要時開啟。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:956
+#: htdocs/luci-static/resources/view/fchomo/node.js:966
msgid "Periodically sends data packets to maintain connection persistence."
msgstr "定期發送資料包以維持連線持久性。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:955
+#: htdocs/luci-static/resources/view/fchomo/node.js:965
msgid "Persistent keepalive"
msgstr "持久連接"
-#: htdocs/luci-static/resources/view/fchomo/node.js:830
+#: htdocs/luci-static/resources/view/fchomo/node.js:840
msgid "Physical MTU"
msgstr "物理 MTU"
@@ -2666,8 +2687,8 @@ msgid ""
"standards."
msgstr "連結格式標準請參考 %s。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2351
-#: htdocs/luci-static/resources/view/fchomo/node.js:2377
+#: htdocs/luci-static/resources/view/fchomo/node.js:2372
+#: htdocs/luci-static/resources/view/fchomo/node.js:2398
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:357
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:383
msgid ""
@@ -2682,13 +2703,13 @@ msgstr ""
#: htdocs/luci-static/resources/view/fchomo/client.js:1541
#: htdocs/luci-static/resources/view/fchomo/client.js:1796
#: htdocs/luci-static/resources/view/fchomo/client.js:1848
-#: htdocs/luci-static/resources/view/fchomo/node.js:2204
+#: htdocs/luci-static/resources/view/fchomo/node.js:2225
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:165
msgid "Please type %s fields of mihomo config."
msgstr "請輸入 mihomo 配置的 %s 欄位。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:682
-#: htdocs/luci-static/resources/view/fchomo/node.js:1270
+#: htdocs/luci-static/resources/fchomo/listeners.js:691
+#: htdocs/luci-static/resources/view/fchomo/node.js:1284
msgid "Plugin"
msgstr "外掛"
@@ -2697,8 +2718,8 @@ msgstr "外掛"
msgid "Plugin fields"
msgstr "外掛欄位"
-#: htdocs/luci-static/resources/fchomo/listeners.js:688
-#: htdocs/luci-static/resources/view/fchomo/node.js:1276
+#: htdocs/luci-static/resources/fchomo/listeners.js:697
+#: htdocs/luci-static/resources/view/fchomo/node.js:1290
msgid "Plugin type"
msgstr "外掛類型"
@@ -2707,11 +2728,11 @@ msgstr "外掛類型"
msgid "Port"
msgstr "連接埠"
-#: htdocs/luci-static/resources/fchomo.js:1729
+#: htdocs/luci-static/resources/fchomo.js:1731
msgid "Port %s alrealy exists!"
msgstr "連接埠 %s 已存在!"
-#: htdocs/luci-static/resources/view/fchomo/node.js:711
+#: htdocs/luci-static/resources/view/fchomo/node.js:721
msgid "Port hop interval"
msgstr "連接埠跳躍間隔"
@@ -2724,18 +2745,18 @@ msgid "Ports"
msgstr "連接埠"
#: htdocs/luci-static/resources/fchomo/listeners.js:154
-#: htdocs/luci-static/resources/view/fchomo/node.js:706
+#: htdocs/luci-static/resources/view/fchomo/node.js:716
msgid "Ports pool"
msgstr "連接埠池"
#: htdocs/luci-static/resources/fchomo/listeners.js:392
-#: htdocs/luci-static/resources/fchomo/listeners.js:531
+#: htdocs/luci-static/resources/fchomo/listeners.js:540
#: htdocs/luci-static/resources/view/fchomo/node.js:507
-#: htdocs/luci-static/resources/view/fchomo/node.js:936
+#: htdocs/luci-static/resources/view/fchomo/node.js:946
msgid "Pre-shared key"
msgstr "預先共用金鑰"
-#: htdocs/luci-static/resources/fchomo.js:1437
+#: htdocs/luci-static/resources/fchomo.js:1440
msgid "Pre-shared key of rendezvous server"
msgstr "牽線伺服器的預先共用金鑰"
@@ -2752,34 +2773,34 @@ msgid ""
"Prevent ICMP loopback issues in some cases. Ping will not show real delay."
msgstr "防止某些情況下的 ICMP 環回問題。 Ping 不會顯示實際延遲。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1685
-#: htdocs/luci-static/resources/view/fchomo/node.js:1686
+#: htdocs/luci-static/resources/view/fchomo/node.js:1707
+#: htdocs/luci-static/resources/view/fchomo/node.js:1708
msgid "Primary"
msgstr "主要"
#: htdocs/luci-static/resources/view/fchomo/global.js:768
#: htdocs/luci-static/resources/view/fchomo/global.js:785
-#: htdocs/luci-static/resources/view/fchomo/node.js:2165
-#: htdocs/luci-static/resources/view/fchomo/node.js:2172
-#: htdocs/luci-static/resources/view/fchomo/node.js:2584
-#: htdocs/luci-static/resources/view/fchomo/node.js:2591
+#: htdocs/luci-static/resources/view/fchomo/node.js:2186
+#: htdocs/luci-static/resources/view/fchomo/node.js:2193
+#: htdocs/luci-static/resources/view/fchomo/node.js:2605
+#: htdocs/luci-static/resources/view/fchomo/node.js:2612
msgid "Priority: Proxy Node > Global."
msgstr "優先權: 代理節點 > 全域。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1180
+#: htdocs/luci-static/resources/view/fchomo/node.js:1194
msgid "Priv-key"
msgstr "金鑰"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1184
+#: htdocs/luci-static/resources/view/fchomo/node.js:1198
msgid "Priv-key passphrase"
msgstr "金鑰密碼"
-#: htdocs/luci-static/resources/view/fchomo/node.js:908
-#: htdocs/luci-static/resources/view/fchomo/node.js:1001
+#: htdocs/luci-static/resources/view/fchomo/node.js:918
+#: htdocs/luci-static/resources/view/fchomo/node.js:1011
msgid "Private key"
msgstr "私鑰"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1056
+#: htdocs/luci-static/resources/view/fchomo/node.js:1066
msgid "Private room"
msgstr "私密房間"
@@ -2791,33 +2812,33 @@ msgstr "進程"
msgid "Process matching mode"
msgstr "進程匹配模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2510
+#: htdocs/luci-static/resources/view/fchomo/node.js:2531
msgid "Programmable replacement"
msgstr "可編程替換"
#: htdocs/luci-static/resources/view/fchomo/global.js:716
-#: htdocs/luci-static/resources/view/fchomo/node.js:2075
+#: htdocs/luci-static/resources/view/fchomo/node.js:2096
msgid "Protocol"
msgstr "協議"
-#: htdocs/luci-static/resources/view/fchomo/node.js:567
+#: htdocs/luci-static/resources/view/fchomo/node.js:577
msgid "Protocol parameter. Enable length block encryption."
msgstr "協議參數。啟用長度塊加密。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:561
+#: htdocs/luci-static/resources/view/fchomo/node.js:571
msgid ""
"Protocol parameter. Will waste traffic randomly if enabled (enabled by "
"default in v2ray and cannot be disabled)."
msgstr "協議參數。 如啟用會隨機浪費流量(在 v2ray 中預設為啟用且無法停用)。"
#: htdocs/luci-static/resources/view/fchomo/client.js:1108
-#: htdocs/luci-static/resources/view/fchomo/node.js:2187
-#: htdocs/luci-static/resources/view/fchomo/node.js:2196
-#: htdocs/luci-static/resources/view/fchomo/node.js:2725
+#: htdocs/luci-static/resources/view/fchomo/node.js:2208
+#: htdocs/luci-static/resources/view/fchomo/node.js:2217
+#: htdocs/luci-static/resources/view/fchomo/node.js:2746
msgid "Provider"
msgstr "供應商"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2384
+#: htdocs/luci-static/resources/view/fchomo/node.js:2405
msgid "Provider URL"
msgstr "供應商訂閱 URL"
@@ -2840,20 +2861,20 @@ msgid "Proxy MAC-s"
msgstr "代理 MAC 位址"
#: htdocs/luci-static/resources/view/fchomo/node.js:225
-#: htdocs/luci-static/resources/view/fchomo/node.js:2724
+#: htdocs/luci-static/resources/view/fchomo/node.js:2745
msgid "Proxy Node"
msgstr "代理節點"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2700
-#: htdocs/luci-static/resources/view/fchomo/node.js:2709
+#: htdocs/luci-static/resources/view/fchomo/node.js:2721
+#: htdocs/luci-static/resources/view/fchomo/node.js:2730
msgid "Proxy chain"
msgstr "代理鏈"
-#: htdocs/luci-static/resources/fchomo/listeners.js:629
-#: htdocs/luci-static/resources/fchomo/listeners.js:1009
+#: htdocs/luci-static/resources/fchomo/listeners.js:638
+#: htdocs/luci-static/resources/fchomo/listeners.js:1027
#: htdocs/luci-static/resources/view/fchomo/client.js:809
#: htdocs/luci-static/resources/view/fchomo/client.js:1639
-#: htdocs/luci-static/resources/view/fchomo/node.js:2402
+#: htdocs/luci-static/resources/view/fchomo/node.js:2423
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:414
msgid "Proxy group"
msgstr "代理組"
@@ -2870,22 +2891,22 @@ msgstr "代理模式"
msgid "Proxy routerself"
msgstr "代理路由器自身"
-#: htdocs/luci-static/resources/view/fchomo/node.js:925
+#: htdocs/luci-static/resources/view/fchomo/node.js:935
msgid "Public key"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:645
-#: htdocs/luci-static/resources/view/fchomo/node.js:801
+#: htdocs/luci-static/resources/view/fchomo/node.js:655
+#: htdocs/luci-static/resources/view/fchomo/node.js:811
msgid "QUIC"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:567
-#: htdocs/luci-static/resources/view/fchomo/node.js:754
+#: htdocs/luci-static/resources/fchomo/listeners.js:576
+#: htdocs/luci-static/resources/view/fchomo/node.js:764
msgid "QUIC based 0-RTT"
msgstr "基於 QUIC 的 0-RTT"
-#: htdocs/luci-static/resources/fchomo/listeners.js:561
-#: htdocs/luci-static/resources/view/fchomo/node.js:743
+#: htdocs/luci-static/resources/fchomo/listeners.js:570
+#: htdocs/luci-static/resources/view/fchomo/node.js:753
msgid "QUIC versions"
msgstr "QUIC 版本"
@@ -2894,39 +2915,39 @@ msgstr "QUIC 版本"
msgid "Quick Reload"
msgstr "快速重載"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1127
-#: htdocs/luci-static/resources/fchomo/listeners.js:1233
-#: htdocs/luci-static/resources/view/fchomo/node.js:1582
+#: htdocs/luci-static/resources/fchomo/listeners.js:1145
+#: htdocs/luci-static/resources/fchomo/listeners.js:1251
+#: htdocs/luci-static/resources/view/fchomo/node.js:1605
msgid "REALITY"
msgstr "REALITY"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1608
+#: htdocs/luci-static/resources/view/fchomo/node.js:1631
msgid "REALITY X25519MLKEM768 PQC support"
msgstr "REALITY X25519MLKEM768 後量子加密支援"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1281
+#: htdocs/luci-static/resources/fchomo/listeners.js:1299
msgid "REALITY certificate issued to"
msgstr "REALITY 憑證頒發給"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1249
+#: htdocs/luci-static/resources/fchomo/listeners.js:1267
msgid "REALITY handshake server"
msgstr "REALITY 握手伺服器"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1288
+#: htdocs/luci-static/resources/fchomo/listeners.js:1306
msgid "REALITY max time difference"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1256
+#: htdocs/luci-static/resources/fchomo/listeners.js:1274
msgid "REALITY private key"
msgstr "REALITY 私鑰"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1271
-#: htdocs/luci-static/resources/view/fchomo/node.js:1598
+#: htdocs/luci-static/resources/fchomo/listeners.js:1289
+#: htdocs/luci-static/resources/view/fchomo/node.js:1621
msgid "REALITY public key"
msgstr "REALITY 公鑰"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1275
-#: htdocs/luci-static/resources/view/fchomo/node.js:1603
+#: htdocs/luci-static/resources/fchomo/listeners.js:1293
+#: htdocs/luci-static/resources/view/fchomo/node.js:1626
msgid "REALITY short ID"
msgstr "REALITY 標識符"
@@ -2940,9 +2961,9 @@ msgstr ""
msgid "REMATCH-NAME marking"
msgstr "REMATCH-NAME 打標"
-#: htdocs/luci-static/resources/fchomo/listeners.js:850
-#: htdocs/luci-static/resources/fchomo/listeners.js:869
-#: htdocs/luci-static/resources/view/fchomo/node.js:1392
+#: htdocs/luci-static/resources/fchomo/listeners.js:868
+#: htdocs/luci-static/resources/fchomo/listeners.js:887
+#: htdocs/luci-static/resources/view/fchomo/node.js:1415
msgid "RTT"
msgstr ""
@@ -2962,19 +2983,19 @@ msgstr "留空將使用隨機令牌。"
msgid "Randomized traffic characteristics"
msgstr "隨機化流量特徵"
-#: htdocs/luci-static/resources/fchomo.js:1426
+#: htdocs/luci-static/resources/fchomo.js:1429
msgid "Realm"
msgstr "Realm"
-#: htdocs/luci-static/resources/fchomo.js:1442
+#: htdocs/luci-static/resources/fchomo.js:1445
msgid "Realm ID"
msgstr "Realm ID"
-#: htdocs/luci-static/resources/fchomo/listeners.js:554
+#: htdocs/luci-static/resources/fchomo/listeners.js:563
msgid "Realm name pattern"
msgstr "Realm 名稱模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2681
+#: htdocs/luci-static/resources/view/fchomo/node.js:2702
msgid ""
"Recommended to adjust Client DNS configuration based on actual conditions."
msgstr "建議根據實際情況調整客戶端 DNS 配置。"
@@ -2995,7 +3016,7 @@ msgstr "Redirect TCP + TProxy UDP"
msgid "Redirect TCP + Tun UDP"
msgstr "Redirect TCP + Tun UDP"
-#: htdocs/luci-static/resources/view/fchomo/node.js:838
+#: htdocs/luci-static/resources/view/fchomo/node.js:848
msgid "Reduces background traffic and network configuration refresh frequency."
msgstr "降低後台流量和網路配置刷新頻率。"
@@ -3003,7 +3024,7 @@ msgstr "降低後台流量和網路配置刷新頻率。"
msgid "Refresh every %s seconds."
msgstr "每 %s 秒刷新。"
-#: htdocs/luci-static/resources/fchomo.js:1383
+#: htdocs/luci-static/resources/fchomo.js:1386
#: htdocs/luci-static/resources/view/fchomo/client.js:966
#: htdocs/luci-static/resources/view/fchomo/global.js:193
#: htdocs/luci-static/resources/view/fchomo/server.js:45
@@ -3022,46 +3043,46 @@ msgstr "再路由"
msgid "Rematching routing rules"
msgstr "重新匹配路由規則"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2329
+#: htdocs/luci-static/resources/view/fchomo/node.js:2350
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:298
msgid "Remote"
msgstr "遠端"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1863
+#: htdocs/luci-static/resources/view/fchomo/node.js:1884
msgid "Remote DNS resolve"
msgstr "遠端 DNS 解析"
-#: htdocs/luci-static/resources/view/fchomo/node.js:821
+#: htdocs/luci-static/resources/view/fchomo/node.js:831
msgid "Remote trace level"
msgstr "遠端追蹤等級"
-#: htdocs/luci-static/resources/view/fchomo/node.js:814
+#: htdocs/luci-static/resources/view/fchomo/node.js:824
msgid "Remote trace target"
msgstr "遠端追蹤目標"
-#: htdocs/luci-static/resources/fchomo.js:1650
+#: htdocs/luci-static/resources/fchomo.js:1652
msgid "Remove"
msgstr "移除"
-#: htdocs/luci-static/resources/fchomo.js:1655
+#: htdocs/luci-static/resources/fchomo.js:1657
#: htdocs/luci-static/resources/view/fchomo/node.js:244
#: htdocs/luci-static/resources/view/fchomo/node.js:246
-#: htdocs/luci-static/resources/view/fchomo/node.js:2305
-#: htdocs/luci-static/resources/view/fchomo/node.js:2307
+#: htdocs/luci-static/resources/view/fchomo/node.js:2326
+#: htdocs/luci-static/resources/view/fchomo/node.js:2328
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:270
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:272
msgid "Remove idles"
msgstr "移除閒置"
-#: htdocs/luci-static/resources/fchomo.js:1431
+#: htdocs/luci-static/resources/fchomo.js:1434
msgid "Rendezvous server"
msgstr "牽線伺服器"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2501
+#: htdocs/luci-static/resources/view/fchomo/node.js:2522
msgid "Replace name"
msgstr "名稱替換"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2502
+#: htdocs/luci-static/resources/view/fchomo/node.js:2523
msgid "Replace node name."
msgstr "替換節點名稱"
@@ -3069,13 +3090,13 @@ msgstr "替換節點名稱"
msgid "Request"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1339
-#: htdocs/luci-static/resources/view/fchomo/node.js:1943
-#: htdocs/luci-static/resources/view/fchomo/node.js:1950
+#: htdocs/luci-static/resources/fchomo/listeners.js:1357
+#: htdocs/luci-static/resources/view/fchomo/node.js:1964
+#: htdocs/luci-static/resources/view/fchomo/node.js:1971
msgid "Request path"
msgstr "請求路徑"
-#: htdocs/luci-static/resources/view/fchomo/node.js:685
+#: htdocs/luci-static/resources/view/fchomo/node.js:695
msgid "Request timeout"
msgstr "請求逾時"
@@ -3088,11 +3109,11 @@ msgid "Require any"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:481
-#: htdocs/luci-static/resources/view/fchomo/node.js:1609
+#: htdocs/luci-static/resources/view/fchomo/node.js:1632
msgid "Requires server support."
msgstr "需要伺服器支援。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:950
+#: htdocs/luci-static/resources/view/fchomo/node.js:960
msgid "Reserved field bytes"
msgstr "保留字段位元組"
@@ -3100,20 +3121,20 @@ msgstr "保留字段位元組"
msgid "Resources management"
msgstr "資源管理"
-#: htdocs/luci-static/resources/fchomo/listeners.js:691
-#: htdocs/luci-static/resources/fchomo/listeners.js:701
-#: htdocs/luci-static/resources/fchomo/listeners.js:706
-#: htdocs/luci-static/resources/fchomo/listeners.js:1125
-#: htdocs/luci-static/resources/fchomo/listeners.js:1241
-#: htdocs/luci-static/resources/view/fchomo/node.js:1281
-#: htdocs/luci-static/resources/view/fchomo/node.js:1291
-#: htdocs/luci-static/resources/view/fchomo/node.js:1296
-#: htdocs/luci-static/resources/view/fchomo/node.js:1590
+#: htdocs/luci-static/resources/fchomo/listeners.js:700
+#: htdocs/luci-static/resources/fchomo/listeners.js:719
+#: htdocs/luci-static/resources/fchomo/listeners.js:724
+#: htdocs/luci-static/resources/fchomo/listeners.js:1143
+#: htdocs/luci-static/resources/fchomo/listeners.js:1259
+#: htdocs/luci-static/resources/view/fchomo/node.js:1295
+#: htdocs/luci-static/resources/view/fchomo/node.js:1314
+#: htdocs/luci-static/resources/view/fchomo/node.js:1319
+#: htdocs/luci-static/resources/view/fchomo/node.js:1613
msgid "Restls"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:760
-#: htdocs/luci-static/resources/view/fchomo/node.js:1350
+#: htdocs/luci-static/resources/fchomo/listeners.js:778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1373
msgid "Restls script"
msgstr "Restls 劇本"
@@ -3136,13 +3157,13 @@ msgstr "重用 HTTP 連接以減少每次建立連接的 RTT。"
msgid "Reusing a single tunnel to carry multiple target connections within it."
msgstr "複用單條隧道使其內部承載多條目標連線。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1046
-#: htdocs/luci-static/resources/view/fchomo/node.js:1058
+#: htdocs/luci-static/resources/view/fchomo/node.js:1056
+#: htdocs/luci-static/resources/view/fchomo/node.js:1068
msgid "Room name"
msgstr "房間名稱"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1051
-#: htdocs/luci-static/resources/view/fchomo/node.js:1058
+#: htdocs/luci-static/resources/view/fchomo/node.js:1061
+#: htdocs/luci-static/resources/view/fchomo/node.js:1068
msgid "Room secret"
msgstr "房間密碼"
@@ -3159,10 +3180,10 @@ msgstr "路由 DSCP"
msgid "Routing GFW"
msgstr "路由 GFW 流量"
-#: htdocs/luci-static/resources/fchomo/listeners.js:612
+#: htdocs/luci-static/resources/fchomo/listeners.js:621
#: htdocs/luci-static/resources/view/fchomo/global.js:784
-#: htdocs/luci-static/resources/view/fchomo/node.js:2171
-#: htdocs/luci-static/resources/view/fchomo/node.js:2590
+#: htdocs/luci-static/resources/view/fchomo/node.js:2192
+#: htdocs/luci-static/resources/view/fchomo/node.js:2611
msgid "Routing mark (Fwmark)"
msgstr "路由標記 (Fwmark)"
@@ -3210,7 +3231,7 @@ msgstr "規則集"
msgid "Rule set URL"
msgstr "規則集訂閱 URL"
-#: htdocs/luci-static/resources/view/fchomo/node.js:824
+#: htdocs/luci-static/resources/view/fchomo/node.js:834
msgid "Rules"
msgstr "規則"
@@ -3222,7 +3243,7 @@ msgstr "規則集"
msgid "Ruleset-URI-Scheme"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1396
+#: htdocs/luci-static/resources/fchomo.js:1399
msgid "Running"
msgstr "正在運作"
@@ -3246,7 +3267,7 @@ msgstr ""
msgid "STUN"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1448
+#: htdocs/luci-static/resources/fchomo.js:1451
msgid "STUN servers"
msgstr "STUN 伺服器"
@@ -3254,12 +3275,12 @@ msgstr "STUN 伺服器"
msgid "SUB-RULE"
msgstr "SUB-RULE"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1262
+#: htdocs/luci-static/resources/view/fchomo/node.js:1276
msgid "SUoT version"
msgstr "SUoT 版本"
-#: htdocs/luci-static/resources/fchomo/listeners.js:501
-#: htdocs/luci-static/resources/view/fchomo/node.js:719
+#: htdocs/luci-static/resources/fchomo/listeners.js:510
+#: htdocs/luci-static/resources/view/fchomo/node.js:729
msgid "Salamander"
msgstr "Salamander"
@@ -3276,12 +3297,12 @@ msgstr "相同 來源位址 和 目標位址 請求。相同節點"
msgid "Save"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1695
-#: htdocs/luci-static/resources/view/fchomo/node.js:1696
+#: htdocs/luci-static/resources/view/fchomo/node.js:1717
+#: htdocs/luci-static/resources/view/fchomo/node.js:1718
msgid "Secondary"
msgstr "次要"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1074
+#: htdocs/luci-static/resources/view/fchomo/node.js:1084
msgid "Secure mode"
msgstr "安全模式"
@@ -3310,9 +3331,9 @@ msgstr "同時向%s和%s發起查詢。"
msgid "Send random ticket of 300s-600s duration for client 0-RTT reuse."
msgstr "發送 300-600 秒的隨機票證,以供客戶端 0-RTT 重用。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:850
-#: htdocs/luci-static/resources/fchomo/listeners.js:1116
-#: htdocs/luci-static/resources/fchomo/listeners.js:1146
+#: htdocs/luci-static/resources/fchomo/listeners.js:868
+#: htdocs/luci-static/resources/fchomo/listeners.js:1134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1164
#: htdocs/luci-static/resources/view/fchomo/server.js:58
#: root/usr/share/luci/menu.d/luci-app-fchomo.json:62
msgid "Server"
@@ -3322,13 +3343,13 @@ msgstr "服務端"
msgid "Server address"
msgstr "伺服器位址"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1333
-#: htdocs/luci-static/resources/view/fchomo/node.js:1922
-#: htdocs/luci-static/resources/view/fchomo/node.js:1928
+#: htdocs/luci-static/resources/fchomo/listeners.js:1351
+#: htdocs/luci-static/resources/view/fchomo/node.js:1943
+#: htdocs/luci-static/resources/view/fchomo/node.js:1949
msgid "Server hostname"
msgstr "伺服器主機名稱"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1009
+#: htdocs/luci-static/resources/view/fchomo/node.js:1019
msgid "Server public key"
msgstr "伺服器公鑰"
@@ -3345,15 +3366,15 @@ msgstr "服務狀態"
msgid "ShadowQUIC"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:690
-#: htdocs/luci-static/resources/fchomo/listeners.js:700
-#: htdocs/luci-static/resources/fchomo/listeners.js:705
-#: htdocs/luci-static/resources/fchomo/listeners.js:1124
-#: htdocs/luci-static/resources/fchomo/listeners.js:1240
-#: htdocs/luci-static/resources/view/fchomo/node.js:1280
-#: htdocs/luci-static/resources/view/fchomo/node.js:1290
-#: htdocs/luci-static/resources/view/fchomo/node.js:1295
-#: htdocs/luci-static/resources/view/fchomo/node.js:1589
+#: htdocs/luci-static/resources/fchomo/listeners.js:699
+#: htdocs/luci-static/resources/fchomo/listeners.js:718
+#: htdocs/luci-static/resources/fchomo/listeners.js:723
+#: htdocs/luci-static/resources/fchomo/listeners.js:1142
+#: htdocs/luci-static/resources/fchomo/listeners.js:1258
+#: htdocs/luci-static/resources/view/fchomo/node.js:1294
+#: htdocs/luci-static/resources/view/fchomo/node.js:1313
+#: htdocs/luci-static/resources/view/fchomo/node.js:1318
+#: htdocs/luci-static/resources/view/fchomo/node.js:1612
msgid "ShadowTLS"
msgstr ""
@@ -3362,22 +3383,22 @@ msgstr ""
msgid "Shadowsocks"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:437
-#: htdocs/luci-static/resources/view/fchomo/node.js:585
+#: htdocs/luci-static/resources/fchomo/listeners.js:446
+#: htdocs/luci-static/resources/view/fchomo/node.js:595
msgid "Shadowsocks chipher"
msgstr "Shadowsocks 加密方法"
-#: htdocs/luci-static/resources/fchomo/listeners.js:432
-#: htdocs/luci-static/resources/view/fchomo/node.js:580
+#: htdocs/luci-static/resources/fchomo/listeners.js:441
+#: htdocs/luci-static/resources/view/fchomo/node.js:590
msgid "Shadowsocks encrypt"
msgstr "Shadowsocks 加密"
-#: htdocs/luci-static/resources/fchomo/listeners.js:445
-#: htdocs/luci-static/resources/view/fchomo/node.js:593
+#: htdocs/luci-static/resources/fchomo/listeners.js:454
+#: htdocs/luci-static/resources/view/fchomo/node.js:603
msgid "Shadowsocks password"
msgstr "Shadowsocks 密碼"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2123
+#: htdocs/luci-static/resources/view/fchomo/node.js:2144
msgid "Show connections in the dashboard for breaking connections easier."
msgstr "在面板中顯示連線以便於打斷連線。"
@@ -3389,15 +3410,15 @@ msgstr "靜音"
msgid "Simple round-robin all nodes"
msgstr "簡單輪替所有節點"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2390
+#: htdocs/luci-static/resources/view/fchomo/node.js:2411
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:402
msgid "Size limit"
msgstr "大小限制"
-#: htdocs/luci-static/resources/fchomo.js:1480
+#: htdocs/luci-static/resources/fchomo.js:1483
#: htdocs/luci-static/resources/view/fchomo/client.js:1675
-#: htdocs/luci-static/resources/view/fchomo/node.js:1519
-#: htdocs/luci-static/resources/view/fchomo/node.js:2565
+#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/view/fchomo/node.js:2586
msgid "Skip cert verify"
msgstr "跳過憑證驗證"
@@ -3466,12 +3487,12 @@ msgstr ""
msgid "Strategy"
msgstr "策略"
-#: htdocs/luci-static/resources/fchomo/listeners.js:584
-#: htdocs/luci-static/resources/view/fchomo/node.js:778
+#: htdocs/luci-static/resources/fchomo/listeners.js:593
+#: htdocs/luci-static/resources/view/fchomo/node.js:788
msgid "Stream-level receive window size"
msgstr "流級接收視窗大小"
-#: htdocs/luci-static/resources/fchomo/listeners.js:617
+#: htdocs/luci-static/resources/fchomo/listeners.js:626
#: htdocs/luci-static/resources/view/fchomo/client.js:1396
#: htdocs/luci-static/resources/view/fchomo/client.js:1405
msgid "Sub rule"
@@ -3481,11 +3502,11 @@ msgstr "子規則"
msgid "Sub rule group"
msgstr "子規則組"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1123
+#: htdocs/luci-static/resources/view/fchomo/node.js:1137
msgid "Subnet proxy"
msgstr "子網代理"
-#: htdocs/luci-static/resources/fchomo.js:870
+#: htdocs/luci-static/resources/fchomo.js:873
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:242
msgid "Successfully imported %s %s of total %s."
msgstr "已成功匯入 %s 個%s (共 %s 個)。"
@@ -3494,7 +3515,7 @@ msgstr "已成功匯入 %s 個%s (共 %s 個)。"
msgid "Successfully updated."
msgstr "更新成功。"
-#: htdocs/luci-static/resources/fchomo.js:2020
+#: htdocs/luci-static/resources/fchomo.js:2022
msgid "Successfully uploaded."
msgstr "已成功上傳。"
@@ -3503,7 +3524,7 @@ msgstr "已成功上傳。"
msgid "Sudoku"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:744
+#: htdocs/luci-static/resources/view/fchomo/node.js:754
msgid "Support %s, default %s."
msgstr "支援 %s,預設 %s。"
@@ -3538,7 +3559,7 @@ msgstr "系統 DNS"
#: htdocs/luci-static/resources/fchomo.js:237
#: htdocs/luci-static/resources/fchomo.js:238
#: htdocs/luci-static/resources/fchomo.js:249
-#: htdocs/luci-static/resources/fchomo/listeners.js:670
+#: htdocs/luci-static/resources/fchomo/listeners.js:679
#: htdocs/luci-static/resources/view/fchomo/client.js:618
#: htdocs/luci-static/resources/view/fchomo/client.js:707
msgid "TCP"
@@ -3552,7 +3573,7 @@ msgstr "TCP 併發"
msgid "TCP idle timeout"
msgstr "TCP 閒置逾時"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2116
+#: htdocs/luci-static/resources/view/fchomo/node.js:2137
msgid "TCP only"
msgstr "僅 TCP"
@@ -3580,36 +3601,36 @@ msgstr "TCP-Keep-Alive 間隔"
msgid "TCP/UDP"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2147
-#: htdocs/luci-static/resources/view/fchomo/node.js:2526
+#: htdocs/luci-static/resources/view/fchomo/node.js:2168
+#: htdocs/luci-static/resources/view/fchomo/node.js:2547
msgid "TFO"
msgstr "TCP 快速開啟 (TFO)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1171
+#: htdocs/luci-static/resources/view/fchomo/node.js:1185
msgid "TLD DNS zone"
msgstr "TLD DNS 區域"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1172
+#: htdocs/luci-static/resources/view/fchomo/node.js:1186
msgid "TLD DNS zone used by MagicDNS, default is %s."
msgstr "MagicDNS 使用的 TLD DNS 區域,預設為 %s。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:718
-#: htdocs/luci-static/resources/fchomo/listeners.js:1026
+#: htdocs/luci-static/resources/fchomo/listeners.js:736
+#: htdocs/luci-static/resources/fchomo/listeners.js:1044
#: htdocs/luci-static/resources/view/fchomo/global.js:558
#: htdocs/luci-static/resources/view/fchomo/node.js:472
-#: htdocs/luci-static/resources/view/fchomo/node.js:1308
-#: htdocs/luci-static/resources/view/fchomo/node.js:1429
+#: htdocs/luci-static/resources/view/fchomo/node.js:1331
+#: htdocs/luci-static/resources/view/fchomo/node.js:1452
msgid "TLS"
msgstr "TLS"
-#: htdocs/luci-static/resources/fchomo.js:1462
-#: htdocs/luci-static/resources/fchomo/listeners.js:1067
-#: htdocs/luci-static/resources/view/fchomo/node.js:1460
+#: htdocs/luci-static/resources/fchomo.js:1465
+#: htdocs/luci-static/resources/fchomo/listeners.js:1085
+#: htdocs/luci-static/resources/view/fchomo/node.js:1483
msgid "TLS ALPN"
msgstr "TLS ALPN"
-#: htdocs/luci-static/resources/fchomo.js:1457
-#: htdocs/luci-static/resources/view/fchomo/node.js:1454
+#: htdocs/luci-static/resources/fchomo.js:1460
+#: htdocs/luci-static/resources/view/fchomo/node.js:1477
msgid "TLS SNI"
msgstr ""
@@ -3628,44 +3649,44 @@ msgid "TURN"
msgstr ""
#: htdocs/luci-static/resources/fchomo.js:246
-#: htdocs/luci-static/resources/view/fchomo/node.js:962
+#: htdocs/luci-static/resources/view/fchomo/node.js:972
msgid "Tailscale"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:604
+#: htdocs/luci-static/resources/fchomo/listeners.js:613
msgid "Target address"
msgstr "目標位址"
-#: htdocs/luci-static/resources/fchomo/listeners.js:493
+#: htdocs/luci-static/resources/fchomo/listeners.js:502
msgid ""
"Tell the client to use the BBR flow control algorithm instead of Hysteria CC."
msgstr "讓客戶端使用 BBR 流控演算法。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1766
-#: htdocs/luci-static/resources/view/fchomo/node.js:1770
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
-#: htdocs/luci-static/resources/view/fchomo/node.js:1798
-#: htdocs/luci-static/resources/view/fchomo/node.js:1802
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1787
+#: htdocs/luci-static/resources/view/fchomo/node.js:1791
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
+#: htdocs/luci-static/resources/view/fchomo/node.js:1819
+#: htdocs/luci-static/resources/view/fchomo/node.js:1823
msgid "The %s address used by local machine in the %s network."
msgstr "本機 %s 位址,用於在 %s 網路中使用。"
-#: htdocs/luci-static/resources/fchomo.js:1495
-#: htdocs/luci-static/resources/fchomo/listeners.js:1146
-#: htdocs/luci-static/resources/view/fchomo/node.js:1542
+#: htdocs/luci-static/resources/fchomo.js:1498
+#: htdocs/luci-static/resources/fchomo/listeners.js:1164
+#: htdocs/luci-static/resources/view/fchomo/node.js:1565
msgid "The %s private key, in PEM format."
msgstr "%s私鑰,需要 PEM 格式。"
-#: htdocs/luci-static/resources/fchomo.js:1489
-#: htdocs/luci-static/resources/fchomo/listeners.js:1116
-#: htdocs/luci-static/resources/fchomo/listeners.js:1169
+#: htdocs/luci-static/resources/fchomo.js:1492
+#: htdocs/luci-static/resources/fchomo/listeners.js:1134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1187
#: htdocs/luci-static/resources/view/fchomo/global.js:579
-#: htdocs/luci-static/resources/view/fchomo/node.js:1528
+#: htdocs/luci-static/resources/view/fchomo/node.js:1551
msgid "The %s public key, in PEM format."
msgstr "%s公鑰,需要 PEM 格式。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1562
+#: htdocs/luci-static/resources/view/fchomo/node.js:1585
msgid ""
"The ECH parameter of the HTTPS record for the domain. Leave empty to resolve "
"via DNS."
@@ -3679,7 +3700,7 @@ msgstr "Sudoku 伺服器提供的 ED25519 可用私鑰 或 UUID。"
msgid "The ED25519 master public key or UUID generated by Sudoku."
msgstr "Sudoku 產生的 ED25519 主公鑰 或 UUID。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:604
+#: htdocs/luci-static/resources/view/fchomo/node.js:614
msgid "The client metadata sent to the server."
msgstr "發送到伺服器的客戶端元資料。"
@@ -3687,14 +3708,14 @@ msgstr "發送到伺服器的客戶端元資料。"
msgid "The default value is 2:00 every day."
msgstr "預設值為每天 2:00。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1244
+#: htdocs/luci-static/resources/view/fchomo/node.js:1258
msgid ""
"The default value is %s, indicating that only the outer "
"connection timeout is used."
msgstr "預設值為%s,表示僅使用外層連線逾時。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:882
-#: htdocs/luci-static/resources/view/fchomo/node.js:1405
+#: htdocs/luci-static/resources/fchomo/listeners.js:900
+#: htdocs/luci-static/resources/view/fchomo/node.js:1428
msgid ""
"The first padding must have a probability of 100% and at least 35 bytes."
msgstr "首個填充必須為 100% 的機率並且至少 35 位元組。"
@@ -3709,35 +3730,35 @@ msgstr "匹配 %s 的將被視為未被投毒汙染。"
msgid "The matching %s will be deemed as poisoned."
msgstr "匹配 %s 的將被視為已被投毒汙染。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:768
+#: htdocs/luci-static/resources/fchomo/listeners.js:786
msgid "The proxy used to connect to the handshake target."
msgstr "用於連接握手目標的代理。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1010
+#: htdocs/luci-static/resources/fchomo/listeners.js:1028
msgid "The proxy used to connect to the rendezvous server."
msgstr "用於連接牽線伺服器的代理。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:880
-#: htdocs/luci-static/resources/view/fchomo/node.js:1403
+#: htdocs/luci-static/resources/fchomo/listeners.js:898
+#: htdocs/luci-static/resources/view/fchomo/node.js:1426
msgid "The server and client can set different padding parameters."
msgstr "伺服器和客戶端可以設定不同的填充參數。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1227
+#: htdocs/luci-static/resources/fchomo/listeners.js:1245
#: htdocs/luci-static/resources/view/fchomo/global.js:623
msgid "This ECH parameter needs to be added to the HTTPS record of the domain."
msgstr "此 ECH 參數需要加入到網域的 HTTPS 記錄中。"
-#: htdocs/luci-static/resources/fchomo.js:1483
+#: htdocs/luci-static/resources/fchomo.js:1486
#: htdocs/luci-static/resources/view/fchomo/client.js:1678
-#: htdocs/luci-static/resources/view/fchomo/node.js:1522
-#: htdocs/luci-static/resources/view/fchomo/node.js:2568
+#: htdocs/luci-static/resources/view/fchomo/node.js:1545
+#: htdocs/luci-static/resources/view/fchomo/node.js:2589
msgid ""
"This is DANGEROUS, your traffic is almost like "
"PLAIN TEXT! Use at your own risk!"
msgstr ""
"這是危險行為,您的流量將幾乎等同於明文!使用風險自負!"
-#: htdocs/luci-static/resources/view/fchomo/node.js:650
+#: htdocs/luci-static/resources/view/fchomo/node.js:660
msgid ""
"This is the TUIC port of the SUoT protocol, designed to provide a QUIC "
"stream based UDP relay mode that TUIC does not provide."
@@ -3769,23 +3790,28 @@ msgstr "Tproxy Fwmark/fwmask"
msgid "Tproxy port"
msgstr "Tproxy 連接埠"
+#: htdocs/luci-static/resources/fchomo/listeners.js:410
+#: htdocs/luci-static/resources/view/fchomo/node.js:530
+msgid "Traffic mode"
+msgstr "流量模式"
+
#: htdocs/luci-static/resources/fchomo/listeners.js:213
#: htdocs/luci-static/resources/view/fchomo/node.js:386
msgid "Traffic pattern"
msgstr "流量模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2762
+#: htdocs/luci-static/resources/view/fchomo/node.js:2783
msgid "Transit proxy group"
msgstr "中轉代理組"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2773
+#: htdocs/luci-static/resources/view/fchomo/node.js:2794
msgid "Transit proxy node"
msgstr "中轉代理節點"
#: htdocs/luci-static/resources/fchomo/listeners.js:194
-#: htdocs/luci-static/resources/fchomo/listeners.js:1297
+#: htdocs/luci-static/resources/fchomo/listeners.js:1315
#: htdocs/luci-static/resources/view/fchomo/node.js:363
-#: htdocs/luci-static/resources/view/fchomo/node.js:1875
+#: htdocs/luci-static/resources/view/fchomo/node.js:1896
msgid "Transport"
msgstr "傳輸層"
@@ -3794,8 +3820,8 @@ msgstr "傳輸層"
msgid "Transport fields"
msgstr "傳輸層欄位"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1302
-#: htdocs/luci-static/resources/view/fchomo/node.js:1880
+#: htdocs/luci-static/resources/fchomo/listeners.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1901
msgid "Transport type"
msgstr "傳輸層類型"
@@ -3813,7 +3839,7 @@ msgstr ""
msgid "TrustTunnel"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:549
+#: htdocs/luci-static/resources/fchomo/listeners.js:558
msgid "Trusted proxy header"
msgstr "可信代理 Header"
@@ -3837,7 +3863,7 @@ msgstr "Tun 堆栈"
msgid "Tunnel"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:852
+#: htdocs/luci-static/resources/view/fchomo/node.js:862
msgid "Turns TCP relay off."
msgstr "關閉 TCP 中繼。"
@@ -3848,8 +3874,8 @@ msgstr "關閉 TCP 中繼。"
#: htdocs/luci-static/resources/view/fchomo/client.js:871
#: htdocs/luci-static/resources/view/fchomo/client.js:1069
#: htdocs/luci-static/resources/view/fchomo/node.js:271
-#: htdocs/luci-static/resources/view/fchomo/node.js:2327
-#: htdocs/luci-static/resources/view/fchomo/node.js:2723
+#: htdocs/luci-static/resources/view/fchomo/node.js:2348
+#: htdocs/luci-static/resources/view/fchomo/node.js:2744
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:296
msgid "Type"
msgstr "類型"
@@ -3864,11 +3890,11 @@ msgstr "類型"
#: htdocs/luci-static/resources/fchomo.js:245
#: htdocs/luci-static/resources/fchomo.js:246
#: htdocs/luci-static/resources/fchomo.js:247
-#: htdocs/luci-static/resources/fchomo/listeners.js:671
-#: htdocs/luci-static/resources/fchomo/listeners.js:676
+#: htdocs/luci-static/resources/fchomo/listeners.js:680
+#: htdocs/luci-static/resources/fchomo/listeners.js:685
#: htdocs/luci-static/resources/view/fchomo/client.js:617
#: htdocs/luci-static/resources/view/fchomo/client.js:706
-#: htdocs/luci-static/resources/view/fchomo/node.js:2536
+#: htdocs/luci-static/resources/view/fchomo/node.js:2557
msgid "UDP"
msgstr "UDP"
@@ -3876,20 +3902,20 @@ msgstr "UDP"
msgid "UDP NAT expiration time"
msgstr "UDP NAT 過期時間"
-#: htdocs/luci-static/resources/view/fchomo/node.js:649
-#: htdocs/luci-static/resources/view/fchomo/node.js:749
+#: htdocs/luci-static/resources/view/fchomo/node.js:659
+#: htdocs/luci-static/resources/view/fchomo/node.js:759
msgid "UDP over stream"
msgstr "UDP over stream"
-#: htdocs/luci-static/resources/view/fchomo/node.js:655
+#: htdocs/luci-static/resources/view/fchomo/node.js:665
msgid "UDP over stream version"
msgstr "UDP over stream 版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:642
+#: htdocs/luci-static/resources/view/fchomo/node.js:652
msgid "UDP packet relay mode."
msgstr "UDP 包中繼模式。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:641
+#: htdocs/luci-static/resources/view/fchomo/node.js:651
msgid "UDP relay mode"
msgstr "UDP 中繼模式"
@@ -3905,14 +3931,14 @@ msgid "URL test"
msgstr "自動選擇"
#: htdocs/luci-static/resources/fchomo/listeners.js:222
-#: htdocs/luci-static/resources/fchomo/listeners.js:410
-#: htdocs/luci-static/resources/fchomo/listeners.js:460
-#: htdocs/luci-static/resources/view/fchomo/node.js:530
-#: htdocs/luci-static/resources/view/fchomo/node.js:629
+#: htdocs/luci-static/resources/fchomo/listeners.js:419
+#: htdocs/luci-static/resources/fchomo/listeners.js:469
+#: htdocs/luci-static/resources/view/fchomo/node.js:540
+#: htdocs/luci-static/resources/view/fchomo/node.js:639
msgid "UUID"
msgstr "UUID"
-#: htdocs/luci-static/resources/fchomo.js:1521
+#: htdocs/luci-static/resources/fchomo.js:1524
msgid "Unable to download unsupported type: %s"
msgstr "無法下載不支援的類型: %s"
@@ -3937,8 +3963,8 @@ msgstr "未知錯誤。"
msgid "Unknown error: %s"
msgstr "未知錯誤:%s"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1256
-#: htdocs/luci-static/resources/view/fchomo/node.js:2541
+#: htdocs/luci-static/resources/view/fchomo/node.js:1270
+#: htdocs/luci-static/resources/view/fchomo/node.js:2562
msgid "UoT"
msgstr "UDP over TCP (UoT)"
@@ -3946,24 +3972,24 @@ msgstr "UDP over TCP (UoT)"
msgid "Update failed."
msgstr "更新失敗。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2396
+#: htdocs/luci-static/resources/view/fchomo/node.js:2417
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:408
msgid "Update interval"
msgstr "更新間隔"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1399
-#: htdocs/luci-static/resources/view/fchomo/node.js:2134
+#: htdocs/luci-static/resources/fchomo/listeners.js:1417
+#: htdocs/luci-static/resources/view/fchomo/node.js:2155
msgid "Upload bandwidth"
msgstr "上傳頻寬"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1400
-#: htdocs/luci-static/resources/view/fchomo/node.js:2135
+#: htdocs/luci-static/resources/fchomo/listeners.js:1418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2156
msgid "Upload bandwidth in Mbps."
msgstr "上傳頻寬(單位:Mbps)。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1137
-#: htdocs/luci-static/resources/fchomo/listeners.js:1177
-#: htdocs/luci-static/resources/view/fchomo/node.js:1533
+#: htdocs/luci-static/resources/fchomo/listeners.js:1155
+#: htdocs/luci-static/resources/fchomo/listeners.js:1195
+#: htdocs/luci-static/resources/view/fchomo/node.js:1556
msgid "Upload certificate"
msgstr "上傳憑證"
@@ -3971,29 +3997,29 @@ msgstr "上傳憑證"
msgid "Upload initial package"
msgstr "上傳初始資源包"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1152
-#: htdocs/luci-static/resources/view/fchomo/node.js:1547
+#: htdocs/luci-static/resources/fchomo/listeners.js:1170
+#: htdocs/luci-static/resources/view/fchomo/node.js:1570
msgid "Upload key"
msgstr "上傳金鑰"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1140
-#: htdocs/luci-static/resources/fchomo/listeners.js:1155
-#: htdocs/luci-static/resources/fchomo/listeners.js:1180
+#: htdocs/luci-static/resources/fchomo/listeners.js:1158
+#: htdocs/luci-static/resources/fchomo/listeners.js:1173
+#: htdocs/luci-static/resources/fchomo/listeners.js:1198
#: htdocs/luci-static/resources/view/fchomo/global.js:306
-#: htdocs/luci-static/resources/view/fchomo/node.js:1536
-#: htdocs/luci-static/resources/view/fchomo/node.js:1550
+#: htdocs/luci-static/resources/view/fchomo/node.js:1559
+#: htdocs/luci-static/resources/view/fchomo/node.js:1573
msgid "Upload..."
msgstr "上傳..."
-#: htdocs/luci-static/resources/view/fchomo/node.js:1813
+#: htdocs/luci-static/resources/view/fchomo/node.js:1834
msgid "Use DHCP"
msgstr "使用 DHCP"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1814
+#: htdocs/luci-static/resources/view/fchomo/node.js:1835
msgid "Use DHCP to obtain IP address."
msgstr "使用 DHCP 取得 IP 位址。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:844
+#: htdocs/luci-static/resources/view/fchomo/node.js:854
msgid "Use protocol-13 extended encryption for outgoing HELLO packets."
msgstr "對傳出的 HELLO 封包使用 協定-13 擴充加密。"
@@ -4003,15 +4029,15 @@ msgstr "對傳出的 HELLO 封包使用 協定-13 擴充加密。"
msgid "Use sub rule"
msgstr "使用子規則"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1117
+#: htdocs/luci-static/resources/view/fchomo/node.js:1131
msgid "Used to forward traffic to the specified nodes for external access."
msgstr "用於將流量轉送至指定節點,以供外部存取。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:869
+#: htdocs/luci-static/resources/view/fchomo/node.js:879
msgid "Used to replace the built-in official %s."
msgstr "用於替換內建的官方 %s。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:863
+#: htdocs/luci-static/resources/view/fchomo/node.js:873
msgid "Used to replace the contents of default %s."
msgstr "用於替換預設的 %s 的內容。"
@@ -4035,9 +4061,9 @@ msgstr "用於解析 DNS 伺服器的網域。必須是 IP。"
msgid "Used to resolve the domain of the Proxy node."
msgstr "用於解析代理節點的網域。"
-#: htdocs/luci-static/resources/fchomo.js:1475
-#: htdocs/luci-static/resources/view/fchomo/node.js:1514
-#: htdocs/luci-static/resources/view/fchomo/node.js:2560
+#: htdocs/luci-static/resources/fchomo.js:1478
+#: htdocs/luci-static/resources/view/fchomo/node.js:1537
+#: htdocs/luci-static/resources/view/fchomo/node.js:2581
msgid "Used to verify the hostname on the returned certificates."
msgstr "用於驗證傳回的憑證上的主機名稱。"
@@ -4050,9 +4076,9 @@ msgid "User-hint is mandatory"
msgstr "User-hint 是必填項"
#: htdocs/luci-static/resources/fchomo/listeners.js:162
-#: htdocs/luci-static/resources/fchomo/listeners.js:738
+#: htdocs/luci-static/resources/fchomo/listeners.js:756
#: htdocs/luci-static/resources/view/fchomo/node.js:322
-#: htdocs/luci-static/resources/view/fchomo/node.js:1320
+#: htdocs/luci-static/resources/view/fchomo/node.js:1343
msgid "Username"
msgstr "使用者名稱"
@@ -4060,23 +4086,23 @@ msgstr "使用者名稱"
msgid "Users filter mode"
msgstr "使用者過濾模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:851
+#: htdocs/luci-static/resources/view/fchomo/node.js:861
msgid "Uses TCP relay only."
msgstr "僅使用 TCP 中繼。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:850
+#: htdocs/luci-static/resources/view/fchomo/node.js:860
msgid "Uses relay after UDP direct failure."
msgstr "UDP 直連失敗後使用中繼。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1174
+#: htdocs/luci-static/resources/view/fchomo/node.js:1188
msgid "Using this in conjunction with %s is recommended."
msgstr "建議與 %s 結合使用。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1991
+#: htdocs/luci-static/resources/view/fchomo/node.js:2012
msgid "V2ray HTTPUpgrade"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1996
+#: htdocs/luci-static/resources/view/fchomo/node.js:2017
msgid "V2ray HTTPUpgrade fast open"
msgstr ""
@@ -4090,9 +4116,9 @@ msgstr ""
msgid "VMess"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1757
-#: htdocs/luci-static/resources/view/fchomo/node.js:1783
-#: htdocs/luci-static/resources/view/fchomo/node.js:1790
+#: htdocs/luci-static/resources/view/fchomo/node.js:1778
+#: htdocs/luci-static/resources/view/fchomo/node.js:1804
+#: htdocs/luci-static/resources/view/fchomo/node.js:1811
msgid "VPN"
msgstr ""
@@ -4100,17 +4126,17 @@ msgstr ""
msgid "VPN fields"
msgstr "VPN 欄位"
-#: htdocs/luci-static/resources/view/fchomo/node.js:900
+#: htdocs/luci-static/resources/view/fchomo/node.js:910
msgid "Valid 16-digit Moon World ID and 10-digit Node ID of Moon Root server."
msgstr "有效的 16-位數 Moon World ID 和 10-位數 Moon Root 伺服器 Node ID。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2333
-#: htdocs/luci-static/resources/view/fchomo/node.js:2729
+#: htdocs/luci-static/resources/view/fchomo/node.js:2354
+#: htdocs/luci-static/resources/view/fchomo/node.js:2750
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:339
msgid "Value"
msgstr "可視化值"
-#: htdocs/luci-static/resources/view/fchomo/node.js:823
+#: htdocs/luci-static/resources/view/fchomo/node.js:833
msgid "Verbose"
msgstr "詳細"
@@ -4119,27 +4145,27 @@ msgid "Verify if given"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:399
-#: htdocs/luci-static/resources/fchomo/listeners.js:752
+#: htdocs/luci-static/resources/fchomo/listeners.js:770
#: htdocs/luci-static/resources/view/fchomo/node.js:514
-#: htdocs/luci-static/resources/view/fchomo/node.js:1334
+#: htdocs/luci-static/resources/view/fchomo/node.js:1357
msgid "Version"
msgstr "版本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1342
+#: htdocs/luci-static/resources/view/fchomo/node.js:1365
msgid "Version hint"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1116
-#: htdocs/luci-static/resources/view/fchomo/node.js:1782
-#: htdocs/luci-static/resources/view/fchomo/node.js:1815
+#: htdocs/luci-static/resources/view/fchomo/node.js:1130
+#: htdocs/luci-static/resources/view/fchomo/node.js:1803
+#: htdocs/luci-static/resources/view/fchomo/node.js:1836
msgid "Virtual IPv4 address"
msgstr "虛擬 IPv4 位址"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1789
+#: htdocs/luci-static/resources/view/fchomo/node.js:1810
msgid "Virtual IPv6 address"
msgstr "虛擬 IPv6 位址"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1756
+#: htdocs/luci-static/resources/view/fchomo/node.js:1777
msgid "Virtual address"
msgstr "虛擬位址"
@@ -4157,15 +4183,15 @@ msgid "Warning"
msgstr "警告"
#: htdocs/luci-static/resources/fchomo/listeners.js:377
-#: htdocs/luci-static/resources/fchomo/listeners.js:1304
-#: htdocs/luci-static/resources/fchomo/listeners.js:1315
#: htdocs/luci-static/resources/fchomo/listeners.js:1322
+#: htdocs/luci-static/resources/fchomo/listeners.js:1333
+#: htdocs/luci-static/resources/fchomo/listeners.js:1340
#: htdocs/luci-static/resources/view/fchomo/node.js:468
#: htdocs/luci-static/resources/view/fchomo/node.js:497
-#: htdocs/luci-static/resources/view/fchomo/node.js:1885
-#: htdocs/luci-static/resources/view/fchomo/node.js:1898
-#: htdocs/luci-static/resources/view/fchomo/node.js:1905
-#: htdocs/luci-static/resources/view/fchomo/node.js:1911
+#: htdocs/luci-static/resources/view/fchomo/node.js:1906
+#: htdocs/luci-static/resources/view/fchomo/node.js:1919
+#: htdocs/luci-static/resources/view/fchomo/node.js:1926
+#: htdocs/luci-static/resources/view/fchomo/node.js:1932
msgid "WebSocket"
msgstr ""
@@ -4173,11 +4199,11 @@ msgstr ""
msgid "When used as a server, HomeProxy is a better choice."
msgstr "用作服務端時,HomeProxy 是更好的選擇。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1166
+#: htdocs/luci-static/resources/view/fchomo/node.js:1180
msgid "Whether to accept DNS configurations distributed by the network."
msgstr "是否接受由網路分發的 DNS 配置。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:984
+#: htdocs/luci-static/resources/view/fchomo/node.js:994
msgid "Whether to accept routes advertised by other nodes."
msgstr "是否接受其他節點發布的路由。"
@@ -4189,53 +4215,53 @@ msgstr "白名單"
msgid "WireGuard"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:930
+#: htdocs/luci-static/resources/view/fchomo/node.js:940
msgid "WireGuard peer public key."
msgstr "WireGuard 對端公鑰。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:937
+#: htdocs/luci-static/resources/view/fchomo/node.js:947
msgid "WireGuard pre-shared key."
msgstr "WireGuard 預先共用金鑰。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:909
+#: htdocs/luci-static/resources/view/fchomo/node.js:919
msgid "WireGuard requires base64-encoded private keys."
msgstr "WireGuard 要求 base64 編碼的私鑰。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1767
-#: htdocs/luci-static/resources/view/fchomo/node.js:1799
+#: htdocs/luci-static/resources/view/fchomo/node.js:1788
+#: htdocs/luci-static/resources/view/fchomo/node.js:1820
msgid "Wireguard"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1305
-#: htdocs/luci-static/resources/fchomo/listeners.js:1316
-#: htdocs/luci-static/resources/view/fchomo/node.js:1886
-#: htdocs/luci-static/resources/view/fchomo/node.js:1906
+#: htdocs/luci-static/resources/fchomo/listeners.js:1323
+#: htdocs/luci-static/resources/fchomo/listeners.js:1334
+#: htdocs/luci-static/resources/view/fchomo/node.js:1907
+#: htdocs/luci-static/resources/view/fchomo/node.js:1927
msgid "XHTTP"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1352
-#: htdocs/luci-static/resources/view/fchomo/node.js:2001
+#: htdocs/luci-static/resources/fchomo/listeners.js:1370
+#: htdocs/luci-static/resources/view/fchomo/node.js:2022
msgid "XHTTP mode"
msgstr "XHTTP 模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2032
+#: htdocs/luci-static/resources/view/fchomo/node.js:2053
msgid "XMUX"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2037
-#: htdocs/luci-static/resources/view/fchomo/node.js:2042
-#: htdocs/luci-static/resources/view/fchomo/node.js:2047
-#: htdocs/luci-static/resources/view/fchomo/node.js:2052
-#: htdocs/luci-static/resources/view/fchomo/node.js:2057
-#: htdocs/luci-static/resources/view/fchomo/node.js:2062
+#: htdocs/luci-static/resources/view/fchomo/node.js:2058
+#: htdocs/luci-static/resources/view/fchomo/node.js:2063
+#: htdocs/luci-static/resources/view/fchomo/node.js:2068
+#: htdocs/luci-static/resources/view/fchomo/node.js:2073
+#: htdocs/luci-static/resources/view/fchomo/node.js:2078
+#: htdocs/luci-static/resources/view/fchomo/node.js:2083
msgid "XMUX:"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:841
+#: htdocs/luci-static/resources/fchomo/listeners.js:859
msgid "XOR mode"
msgstr "XOR 模式"
-#: htdocs/luci-static/resources/view/fchomo/node.js:575
+#: htdocs/luci-static/resources/view/fchomo/node.js:585
msgid "Xudp (Xray-core)"
msgstr ""
@@ -4243,11 +4269,11 @@ msgstr ""
msgid "Yaml text"
msgstr "Yaml 格式文本"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2571
+#: htdocs/luci-static/resources/view/fchomo/node.js:2592
msgid "Yes"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1173
+#: htdocs/luci-static/resources/view/fchomo/node.js:1187
msgid ""
"You can add %s in the %s to resolve A/PTR records within the virtual network."
msgstr "您可以將 %s 新增到 %s 中,以解析虛擬網路內的 A/PTR 記錄。"
@@ -4256,7 +4282,7 @@ msgstr "您可以將 %s 新增到 %s 中,以解析虛擬網路內的 A/PTR 記
msgid "YouTube"
msgstr "YouTube"
-#: htdocs/luci-static/resources/fchomo.js:2002
+#: htdocs/luci-static/resources/fchomo.js:2004
msgid "Your %s was successfully uploaded. Size: %sB."
msgstr "您的 %s 已成功上傳。大小:%sB。"
@@ -4264,14 +4290,14 @@ msgstr "您的 %s 已成功上傳。大小:%sB。"
msgid "ZeroTier"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:831
+#: htdocs/luci-static/resources/view/fchomo/node.js:841
msgid "ZeroTier UDP payload MTU."
msgstr "ZeroTier UDP 有效載荷 MTU。"
#: htdocs/luci-static/resources/fchomo.js:422
#: htdocs/luci-static/resources/fchomo.js:435
#: htdocs/luci-static/resources/fchomo.js:440
-#: htdocs/luci-static/resources/view/fchomo/node.js:555
+#: htdocs/luci-static/resources/view/fchomo/node.js:565
msgid "aes-128-gcm"
msgstr ""
@@ -4284,19 +4310,19 @@ msgstr ""
msgid "aes-256-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1139
+#: htdocs/luci-static/resources/view/fchomo/node.js:1153
msgid "aes-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1140
+#: htdocs/luci-static/resources/view/fchomo/node.js:1154
msgid "aes-gcm-256"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2418
+#: htdocs/luci-static/resources/view/fchomo/node.js:2439
msgid "age private key"
msgstr "age 私鑰"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2479
+#: htdocs/luci-static/resources/view/fchomo/node.js:2500
msgid "age public key"
msgstr "age 公鑰"
@@ -4308,7 +4334,7 @@ msgstr ""
msgid "age-x25519"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:552
+#: htdocs/luci-static/resources/view/fchomo/node.js:562
msgid "auto"
msgstr "自動"
@@ -4321,13 +4347,13 @@ msgstr "bbr"
msgid "bbr3"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1142
-#: htdocs/luci-static/resources/fchomo/listeners.js:1182
-#: htdocs/luci-static/resources/view/fchomo/node.js:1538
+#: htdocs/luci-static/resources/fchomo/listeners.js:1160
+#: htdocs/luci-static/resources/fchomo/listeners.js:1200
+#: htdocs/luci-static/resources/view/fchomo/node.js:1561
msgid "certificate"
msgstr "憑證"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1138
+#: htdocs/luci-static/resources/view/fchomo/node.js:1152
msgid "chacha20"
msgstr ""
@@ -4337,7 +4363,7 @@ msgstr ""
msgid "chacha20-ietf-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:556
+#: htdocs/luci-static/resources/view/fchomo/node.js:566
msgid "chacha20-poly1305"
msgstr ""
@@ -4346,8 +4372,8 @@ msgstr ""
msgid "cubic"
msgstr "cubic"
-#: htdocs/luci-static/resources/fchomo/listeners.js:793
-#: htdocs/luci-static/resources/fchomo/listeners.js:824
+#: htdocs/luci-static/resources/fchomo/listeners.js:811
+#: htdocs/luci-static/resources/fchomo/listeners.js:842
msgid "decryption"
msgstr "decryption"
@@ -4355,13 +4381,13 @@ msgstr "decryption"
msgid "dnsmasq selects upstream on its own. (may affect CDN accuracy)"
msgstr "dnsmasq 自行選擇上游服務器。 (可能影響 CDN 準確性)"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2553
+#: htdocs/luci-static/resources/view/fchomo/node.js:2574
msgid "down"
msgstr "Hysteria 下載速率"
-#: htdocs/luci-static/resources/fchomo/listeners.js:828
-#: htdocs/luci-static/resources/view/fchomo/node.js:1357
+#: htdocs/luci-static/resources/fchomo/listeners.js:846
#: htdocs/luci-static/resources/view/fchomo/node.js:1380
+#: htdocs/luci-static/resources/view/fchomo/node.js:1403
msgid "encryption"
msgstr "encryption"
@@ -4370,55 +4396,55 @@ msgstr "encryption"
msgid "false = bandwidth optimized downlink; true = pure Sudoku downlink."
msgstr "false = 頻寬最佳化下行 true = 純 Sudoku 下行。"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1303
-#: htdocs/luci-static/resources/fchomo/listeners.js:1314
#: htdocs/luci-static/resources/fchomo/listeners.js:1321
-#: htdocs/luci-static/resources/view/fchomo/node.js:1884
-#: htdocs/luci-static/resources/view/fchomo/node.js:1897
-#: htdocs/luci-static/resources/view/fchomo/node.js:1904
-#: htdocs/luci-static/resources/view/fchomo/node.js:1910
+#: htdocs/luci-static/resources/fchomo/listeners.js:1332
+#: htdocs/luci-static/resources/fchomo/listeners.js:1339
+#: htdocs/luci-static/resources/view/fchomo/node.js:1905
+#: htdocs/luci-static/resources/view/fchomo/node.js:1918
+#: htdocs/luci-static/resources/view/fchomo/node.js:1925
+#: htdocs/luci-static/resources/view/fchomo/node.js:1931
msgid "gRPC"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1967
+#: htdocs/luci-static/resources/view/fchomo/node.js:1988
msgid "gRPC User-Agent"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1972
+#: htdocs/luci-static/resources/view/fchomo/node.js:1993
msgid "gRPC ping interval"
msgstr "gRPC ping 間隔"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1346
-#: htdocs/luci-static/resources/view/fchomo/node.js:1963
+#: htdocs/luci-static/resources/fchomo/listeners.js:1364
+#: htdocs/luci-static/resources/view/fchomo/node.js:1984
msgid "gRPC service name"
msgstr "gRPC 服務名稱"
#: htdocs/luci-static/resources/view/fchomo/global.js:517
-#: htdocs/luci-static/resources/view/fchomo/node.js:1205
+#: htdocs/luci-static/resources/view/fchomo/node.js:1219
msgid "gVisor"
msgstr "gVisor"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1020
+#: htdocs/luci-static/resources/view/fchomo/node.js:1030
msgid "h2"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2079
+#: htdocs/luci-static/resources/view/fchomo/node.js:2100
msgid "h2mux"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1018
+#: htdocs/luci-static/resources/view/fchomo/node.js:1028
msgid "h3"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1019
+#: htdocs/luci-static/resources/view/fchomo/node.js:1029
msgid "h3-l4proxy"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:993
+#: htdocs/luci-static/resources/fchomo/listeners.js:1011
msgid "least one keypair required"
msgstr "至少需要一對密鑰"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2694
+#: htdocs/luci-static/resources/view/fchomo/node.js:2715
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:444
msgid "luci-app-tinyfilemanager is not installed, please install it first."
msgstr "luci-app-tinyfilemanager 未安裝,請先安裝它。"
@@ -4428,7 +4454,7 @@ msgid "metacubexd"
msgstr "metacubexd"
#: htdocs/luci-static/resources/view/fchomo/global.js:515
-#: htdocs/luci-static/resources/view/fchomo/node.js:1203
+#: htdocs/luci-static/resources/view/fchomo/node.js:1217
msgid "mihomo IP stack (MIPS)"
msgstr "mihomo IP 協定棧(MIPS)"
@@ -4438,7 +4464,7 @@ msgstr "mihomo IP 協定棧(MIPS)"
#: htdocs/luci-static/resources/view/fchomo/client.js:1576
#: htdocs/luci-static/resources/view/fchomo/client.js:1810
#: htdocs/luci-static/resources/view/fchomo/client.js:1866
-#: htdocs/luci-static/resources/view/fchomo/node.js:2299
+#: htdocs/luci-static/resources/view/fchomo/node.js:2320
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:258
msgid "mihomo config"
msgstr "mihomo 配置"
@@ -4447,8 +4473,8 @@ msgstr "mihomo 配置"
msgid "mlkem768x25519plus"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2152
-#: htdocs/luci-static/resources/view/fchomo/node.js:2531
+#: htdocs/luci-static/resources/view/fchomo/node.js:2173
+#: htdocs/luci-static/resources/view/fchomo/node.js:2552
msgid "mpTCP"
msgstr "多路徑 TCP (mpTCP)"
@@ -4460,18 +4486,21 @@ msgstr "new_reno"
msgid "no-resolve"
msgstr "no-resolve"
-#: htdocs/luci-static/resources/fchomo.js:1717
-#: htdocs/luci-static/resources/fchomo.js:1832
-#: htdocs/luci-static/resources/fchomo.js:1867
-#: htdocs/luci-static/resources/fchomo.js:1895
+#: htdocs/luci-static/resources/fchomo.js:1719
+#: htdocs/luci-static/resources/fchomo.js:1834
+#: htdocs/luci-static/resources/fchomo.js:1869
+#: htdocs/luci-static/resources/fchomo.js:1897
msgid "non-empty value"
msgstr "非空值"
+#: htdocs/luci-static/resources/fchomo.js:271
#: htdocs/luci-static/resources/fchomo.js:420
#: htdocs/luci-static/resources/fchomo.js:434
#: htdocs/luci-static/resources/fchomo.js:446
-#: htdocs/luci-static/resources/view/fchomo/node.js:553
-#: htdocs/luci-static/resources/view/fchomo/node.js:573
+#: htdocs/luci-static/resources/fchomo/listeners.js:628
+#: htdocs/luci-static/resources/fchomo/listeners.js:631
+#: htdocs/luci-static/resources/view/fchomo/node.js:563
+#: htdocs/luci-static/resources/view/fchomo/node.js:583
#: htdocs/luci-static/resources/view/fchomo/ruleset.js:335
msgid "none"
msgstr "無"
@@ -4484,16 +4513,10 @@ msgstr "未找到"
msgid "not included \",\""
msgstr "不包含 \",\""
-#: htdocs/luci-static/resources/fchomo.js:271
-#: htdocs/luci-static/resources/fchomo/listeners.js:619
-#: htdocs/luci-static/resources/fchomo/listeners.js:622
-msgid "null"
-msgstr ""
-
-#: htdocs/luci-static/resources/fchomo/listeners.js:689
-#: htdocs/luci-static/resources/fchomo/listeners.js:699
-#: htdocs/luci-static/resources/view/fchomo/node.js:1277
-#: htdocs/luci-static/resources/view/fchomo/node.js:1289
+#: htdocs/luci-static/resources/fchomo/listeners.js:698
+#: htdocs/luci-static/resources/fchomo/listeners.js:717
+#: htdocs/luci-static/resources/view/fchomo/node.js:1291
+#: htdocs/luci-static/resources/view/fchomo/node.js:1312
msgid "obfs-simple"
msgstr ""
@@ -4505,32 +4528,32 @@ msgstr "僅當 %s 為 %s 時適用。"
msgid "only applies when %s is not %s."
msgstr "僅當 %s 不為 %s 時適用。"
-#: htdocs/luci-static/resources/view/fchomo/node.js:1141
+#: htdocs/luci-static/resources/view/fchomo/node.js:1155
msgid "openssl-aes128-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1142
+#: htdocs/luci-static/resources/view/fchomo/node.js:1156
msgid "openssl-aes256-gcm"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1143
+#: htdocs/luci-static/resources/view/fchomo/node.js:1157
msgid "openssl-chacha20"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2512
+#: htdocs/luci-static/resources/view/fchomo/node.js:2533
msgid "override.override-expr"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:2504
+#: htdocs/luci-static/resources/view/fchomo/node.js:2525
msgid "override.proxy-name"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:574
+#: htdocs/luci-static/resources/view/fchomo/node.js:584
msgid "packet addr (v2ray-core v5+)"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1356
-#: htdocs/luci-static/resources/view/fchomo/node.js:2005
+#: htdocs/luci-static/resources/fchomo/listeners.js:1374
+#: htdocs/luci-static/resources/view/fchomo/node.js:2026
msgid "packet-up"
msgstr ""
@@ -4539,8 +4562,8 @@ msgstr ""
msgid "poll"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1157
-#: htdocs/luci-static/resources/view/fchomo/node.js:1552
+#: htdocs/luci-static/resources/fchomo/listeners.js:1175
+#: htdocs/luci-static/resources/view/fchomo/node.js:1575
msgid "private key"
msgstr "私鑰"
@@ -4561,7 +4584,7 @@ msgstr "需要使用 API 的前端適配。"
msgid "rule-set"
msgstr "規則集"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2077
+#: htdocs/luci-static/resources/view/fchomo/node.js:2098
msgid "smux"
msgstr ""
@@ -4574,17 +4597,17 @@ msgstr ""
msgid "src"
msgstr "src"
-#: htdocs/luci-static/resources/fchomo/listeners.js:1354
-#: htdocs/luci-static/resources/view/fchomo/node.js:2003
+#: htdocs/luci-static/resources/fchomo/listeners.js:1372
+#: htdocs/luci-static/resources/view/fchomo/node.js:2024
msgid "stream-one"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1355
-#: htdocs/luci-static/resources/view/fchomo/node.js:2004
+#: htdocs/luci-static/resources/fchomo/listeners.js:1373
+#: htdocs/luci-static/resources/view/fchomo/node.js:2025
msgid "stream-up"
msgstr ""
-#: htdocs/luci-static/resources/fchomo/listeners.js:1371
+#: htdocs/luci-static/resources/fchomo/listeners.js:1389
msgid "stream-up server seconds"
msgstr ""
@@ -4596,11 +4619,11 @@ msgstr ""
msgid "sudoku-keypair"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1344
+#: htdocs/luci-static/resources/view/fchomo/node.js:1367
msgid "tls12"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1345
+#: htdocs/luci-static/resources/view/fchomo/node.js:1368
msgid "tls13"
msgstr ""
@@ -4616,35 +4639,35 @@ msgstr "獨立 UCI 識別"
msgid "unique identifier"
msgstr "獨立標識"
-#: htdocs/luci-static/resources/fchomo.js:1904
+#: htdocs/luci-static/resources/fchomo.js:1906
msgid "unique value"
msgstr "獨立值"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2547
+#: htdocs/luci-static/resources/view/fchomo/node.js:2568
msgid "up"
msgstr "Hysteria 上傳速率"
#: htdocs/luci-static/resources/fchomo/listeners.js:400
-#: htdocs/luci-static/resources/fchomo/listeners.js:753
+#: htdocs/luci-static/resources/fchomo/listeners.js:771
#: htdocs/luci-static/resources/view/fchomo/node.js:515
-#: htdocs/luci-static/resources/view/fchomo/node.js:656
-#: htdocs/luci-static/resources/view/fchomo/node.js:1263
-#: htdocs/luci-static/resources/view/fchomo/node.js:1335
+#: htdocs/luci-static/resources/view/fchomo/node.js:666
+#: htdocs/luci-static/resources/view/fchomo/node.js:1277
+#: htdocs/luci-static/resources/view/fchomo/node.js:1358
msgid "v1"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:401
-#: htdocs/luci-static/resources/fchomo/listeners.js:754
+#: htdocs/luci-static/resources/fchomo/listeners.js:772
#: htdocs/luci-static/resources/view/fchomo/node.js:516
-#: htdocs/luci-static/resources/view/fchomo/node.js:1264
-#: htdocs/luci-static/resources/view/fchomo/node.js:1336
+#: htdocs/luci-static/resources/view/fchomo/node.js:1278
+#: htdocs/luci-static/resources/view/fchomo/node.js:1359
msgid "v2"
msgstr ""
#: htdocs/luci-static/resources/fchomo/listeners.js:402
-#: htdocs/luci-static/resources/fchomo/listeners.js:755
+#: htdocs/luci-static/resources/fchomo/listeners.js:773
#: htdocs/luci-static/resources/view/fchomo/node.js:517
-#: htdocs/luci-static/resources/view/fchomo/node.js:1337
+#: htdocs/luci-static/resources/view/fchomo/node.js:1360
msgid "v3"
msgstr ""
@@ -4658,42 +4681,47 @@ msgstr ""
msgid "v5"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1764
-#: htdocs/luci-static/resources/fchomo.js:1767
+#: htdocs/luci-static/resources/fchomo/listeners.js:405
+#: htdocs/luci-static/resources/view/fchomo/node.js:520
+msgid "v6"
+msgstr ""
+
+#: htdocs/luci-static/resources/fchomo.js:1766
+#: htdocs/luci-static/resources/fchomo.js:1769
msgid "valid JSON format"
msgstr "有效的 JSON 格式"
-#: htdocs/luci-static/resources/fchomo.js:1823
+#: htdocs/luci-static/resources/fchomo.js:1825
msgid "valid SHA256 string with %d characters"
msgstr "包含 %d 個字元的有效 SHA256 字串"
-#: htdocs/luci-static/resources/fchomo.js:1789
-#: htdocs/luci-static/resources/fchomo.js:1792
+#: htdocs/luci-static/resources/fchomo.js:1791
+#: htdocs/luci-static/resources/fchomo.js:1794
msgid "valid URL"
msgstr "有效網址"
-#: htdocs/luci-static/resources/fchomo.js:1814
+#: htdocs/luci-static/resources/fchomo.js:1816
msgid "valid base64 key with %d characters"
msgstr "包含 %d 個字元的有效 base64 金鑰"
-#: htdocs/luci-static/resources/fchomo.js:1882
-#: htdocs/luci-static/resources/fchomo.js:1888
+#: htdocs/luci-static/resources/fchomo.js:1884
+#: htdocs/luci-static/resources/fchomo.js:1890
msgid "valid format: 2x, 2p, 4v"
msgstr "有效格式: 2x, 2p, 4v"
-#: htdocs/luci-static/resources/fchomo.js:1805
+#: htdocs/luci-static/resources/fchomo.js:1807
msgid "valid hex string with %d characters"
msgstr "包含 %d 个字符的有效 Hex 字串"
-#: htdocs/luci-static/resources/fchomo.js:1869
+#: htdocs/luci-static/resources/fchomo.js:1871
msgid "valid key length with %d characters"
msgstr "包含 %d 個字元的有效金鑰"
-#: htdocs/luci-static/resources/fchomo.js:1727
+#: htdocs/luci-static/resources/fchomo.js:1729
msgid "valid port value"
msgstr "有效連接埠值"
-#: htdocs/luci-static/resources/fchomo.js:1777
+#: htdocs/luci-static/resources/fchomo.js:1779
msgid "valid uuid"
msgstr "有效 uuid"
@@ -4709,7 +4737,7 @@ msgstr ""
msgid "xchacha20-ietf-poly1305"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:1137
+#: htdocs/luci-static/resources/view/fchomo/node.js:1151
msgid "xor"
msgstr ""
@@ -4717,7 +4745,7 @@ msgstr ""
msgid "yacd-meta"
msgstr "yacd-meta"
-#: htdocs/luci-static/resources/view/fchomo/node.js:2078
+#: htdocs/luci-static/resources/view/fchomo/node.js:2099
msgid "yamux"
msgstr ""
@@ -4725,14 +4753,14 @@ msgstr ""
msgid "zashboard"
msgstr ""
-#: htdocs/luci-static/resources/view/fchomo/node.js:554
+#: htdocs/luci-static/resources/view/fchomo/node.js:564
msgid "zero"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1544
+#: htdocs/luci-static/resources/fchomo.js:1547
msgid "🔗"
msgstr ""
-#: htdocs/luci-static/resources/fchomo.js:1523
+#: htdocs/luci-static/resources/fchomo.js:1526
msgid "🡇"
msgstr ""
diff --git a/luci-app-fchomo/root/usr/share/fchomo/generate_client.uc b/luci-app-fchomo/root/usr/share/fchomo/generate_client.uc
index aa1a0b943..c3e9c8242 100644
--- a/luci-app-fchomo/root/usr/share/fchomo/generate_client.uc
+++ b/luci-app-fchomo/root/usr/share/fchomo/generate_client.uc
@@ -561,6 +561,7 @@ uci.foreach(uciconf, ucinode, (cfg) => {
psk: cfg.snell_psk,
version: strToInt(cfg.snell_version),
reuse: strToBool(cfg.snell_reuse),
+ mode: cfg.snell_mode,
/* VMess / VLESS */
flow: cfg.vless_flow,
diff --git a/luci-app-fchomo/root/usr/share/rpcd/ucode/luci.fchomo b/luci-app-fchomo/root/usr/share/rpcd/ucode/luci.fchomo
index 2beedf3b9..526ddc1a0 100644
--- a/luci-app-fchomo/root/usr/share/rpcd/ucode/luci.fchomo
+++ b/luci-app-fchomo/root/usr/share/rpcd/ucode/luci.fchomo
@@ -44,7 +44,7 @@ const methods = {
args: { type: 'type', params: 'params' },
call: function(req) {
/* https://github.com/MetaCubeX/mihomo/blob/Alpha/component/generator/cmd.go */
- if (!(req.args?.type in ['uuid',
+ if (!(req.args?.type in ['uuid', 'ss-password',
'reality-keypair', 'wg-keypair', 'sudoku-keypair',
'age-x25519', 'age-mlkem768-x25519', 'age-convert',
'vless-mlkem768', 'vless-x25519',
@@ -73,6 +73,8 @@ const methods = {
for (let line = fd.read('line'); length(line); line = fd.read('line')) {
if (type === 'uuid')
result.uuid = trim(line);
+ if (type === 'ss-password')
+ result.password = trim(line);
else if (type in ['reality-keypair', 'wg-keypair', 'sudoku-keypair']) {
let priv = match(trim(line), /PrivateKey: (.*)/);
if (priv)
diff --git a/luci-app-fchomo/root/usr/share/ucode/fchomo.uc b/luci-app-fchomo/root/usr/share/ucode/fchomo.uc
index c2bc27d8c..26d61f3f1 100644
--- a/luci-app-fchomo/root/usr/share/ucode/fchomo.uc
+++ b/luci-app-fchomo/root/usr/share/ucode/fchomo.uc
@@ -249,13 +249,13 @@ export function parseListener(cfg) {
} : null
/*{
}*/
- ] : ((cfg.type in ['mieru', 'anytls', 'tuic', 'hysteria2']) ? {
+ ] : (cfg.type in ['mieru', 'anytls', 'tuic', 'hysteria2']) ? {
/* Mieru / AnyTLS / Hysteria2 */
...arrToObj([[cfg.username, cfg.password]]),
/* Tuic */
...arrToObj([[cfg.uuid, cfg.password]])
- } : null),
+ } : null,
/* Shadowsocks */
cipher: cfg.shadowsocks_chipher,
@@ -288,6 +288,7 @@ export function parseListener(cfg) {
/* Snell */
psk: cfg.snell_psk,
version: cfg.snell_version,
+ mode: cfg.snell_mode,
/* VMess / VLESS */
decryption: cfg.vless_decryption === '1' ? parseVlessEncryption(cfg.vless_encryption_hmpayload, 'server') : null,
diff --git a/luci-app-honk/Makefile b/luci-app-honk/Makefile
index 36b7aa2de..4ed4e3099 100644
--- a/luci-app-honk/Makefile
+++ b/luci-app-honk/Makefile
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-honk
PKG_VERSION:=1.1.4
-PKG_RELEASE:=33
+PKG_RELEASE:=34
LUCI_TITLE:=LuCI support for honk
LUCI_PKGARCH:=all
diff --git a/luci-app-honk/root/etc/honk/doona/assets/AddCircle-D2cMd6zF.js b/luci-app-honk/root/etc/honk/doona/assets/AddCircle-6b-rL1eo.js
similarity index 83%
rename from luci-app-honk/root/etc/honk/doona/assets/AddCircle-D2cMd6zF.js
rename to luci-app-honk/root/etc/honk/doona/assets/AddCircle-6b-rL1eo.js
index 5ad2ff8f8..ab653e8a6 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/AddCircle-D2cMd6zF.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/AddCircle-6b-rL1eo.js
@@ -1 +1 @@
-import{j as r}from"./vendor-react-64fcanlc.js";import{I as a}from"./index-CUHkLMAp.js";function o(o){return r.jsx(a,{...o,children:r.jsx("path",{fill:"currentColor",d:"M10 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17m0 15.5a7 7 0 1 1 0-14 7 7 0 0 1 0 14m3.75-7.75h-3v-3a.75.75 0 0 0-1.5 0v3h-3a.75.75 0 0 0 0 1.5h3v3a.75.75 0 0 0 1.5 0v-3h3a.75.75 0 0 0 0-1.5"})})}export{o as A};
+import{j as r}from"./vendor-react-64fcanlc.js";import{I as a}from"./index-C06va4Yw.js";function o(o){return r.jsx(a,{...o,children:r.jsx("path",{fill:"currentColor",d:"M10 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17m0 15.5a7 7 0 1 1 0-14 7 7 0 0 1 0 14m3.75-7.75h-3v-3a.75.75 0 0 0-1.5 0v3h-3a.75.75 0 0 0 0 1.5h3v3a.75.75 0 0 0 1.5 0v-3h3a.75.75 0 0 0 0-1.5"})})}export{o as A};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/AppearanceControls-E-VPhjIz.js b/luci-app-honk/root/etc/honk/doona/assets/AppearanceControls-CEVO9-aR.js
similarity index 65%
rename from luci-app-honk/root/etc/honk/doona/assets/AppearanceControls-E-VPhjIz.js
rename to luci-app-honk/root/etc/honk/doona/assets/AppearanceControls-CEVO9-aR.js
index 7fb1c6541..440b41a70 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/AppearanceControls-E-VPhjIz.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/AppearanceControls-CEVO9-aR.js
@@ -1 +1 @@
-import{j as e,r as s}from"./vendor-react-64fcanlc.js";import{fT as l,fU as n,fV as a,cz as c,dI as t,cB as i,bE as r,fh as o,cA as u,dL as d,fW as h,dM as p,cC as m,u as x,b7 as b,fX as j,by as f,cD as v,fY as y,cE as g,cF as C,fZ as N,cG as A,T as S,I as M,bk as k,eh as L,B as I}from"./index-CUHkLMAp.js";import{a as w,b as q}from"./ItemText-CnEXu0-f.js";const D=e=>e>12,H=({orientation:s="vertical"})=>e.jsx(l,{orientation:s,className:"vertical"===s?"rp-vrule":"rp-hrule"}),E=e=>s=>{if("all"===s)return;const l=[...s][0];null!=l&&e(String(l))};function P({item:s,children:l,onAction:n}){return e.jsxs(A,{id:s.id,className:"rp-item",textValue:s.label,onAction:n,children:[e.jsx(w,{}),e.jsx(q,{i:s,children:l})]})}function V({children:l,content:n,label:x,quiet:b,small:j,size:f,chevron:v=!0,isDisabled:y,appearance:g,placement:C="bottom end",count:N,onIntent:A}){const S=N?e.jsx("span",{className:"rp-count","aria-hidden":"true",children:N}):null,M=a(y),[k,L]=s.useState(!1),I=c(),w=t(f),q=s.useRef(null),D=e.jsxs(i,{ref:q,className:g?"rp-select":o({quiet:b,small:j,icon:!v}),"data-size":w,"aria-label":x,"aria-describedby":M?.id,isDisabled:y,onHoverStart:A,onFocus:A,children:[l,S,v&&e.jsx(r,{className:"rp-chev"})]});return e.jsxs(u,{children:[v&&!M?D:e.jsxs(d,{delay:400,isOpen:k,onOpenChange:L,children:[e.jsx(h,{children:e.jsx("span",{className:"rp-tipwrap",tabIndex:y?0:-1,"data-passive":y?void 0:"",onPointerDown:e=>{y&&"touch"===e.pointerType&&L(e=>!e)},children:D})}),e.jsx(p,{triggerRef:q,children:M?.text??x})]}),e.jsx(m,{className:"rp-popover rp-list-popover",placement:C,boundaryElement:I,children:n})]})}function $({label:s,labelledBy:l,sections:n,headers:a=!0,focusedByCaller:c,onAction:t,searchLabel:i,actions:r=[]}){const o="function"==typeof n?n():n,u=!!i&&D(z(o)),d=e.jsxs(v,{"aria-label":s,"aria-labelledby":l??"",className:u?"rp-menu-scroll":void 0,autoFocus:!c&&void 0,children:[o.map(s=>e.jsxs(g,{"aria-label":a&&!s.hideHeader?void 0:s.title,selectionMode:s.selectionMode??"single",selectedKeys:[`/choice-${s.value}`],onSelectionChange:s.onChange&&E(e=>s.onChange(e.slice(8))),children:[a&&!s.hideHeader&&e.jsx(C,{className:"rp-sec-h",children:s.title}),s.items.map(s=>e.jsx(P,{item:{...s,id:`/choice-${s.id}`},onAction:t&&(()=>t(s.id))},s.id))]},s.title)),r.length>0&&e.jsx(H,{orientation:"horizontal"}),r.map(s=>e.jsx(F,{...s},s.label))]});return u?e.jsx(N,{label:i,children:d}):d}const z=e=>e.reduce((e,s)=>e+s.items.length,0);function B(e,s){for(const l of e){const n=l.items.find(e=>e.id===l.value);if(n)return e.length>1&&!l.plain&&n.label!==l.title?s("ui.sectionChoice",{section:l.title,item:n.label}):n.label}return""}const F=({label:s,icon:l,onAction:n})=>e.jsxs(A,{className:"rp-item rp-subitem",textValue:s,onAction:n,shouldCloseOnSelect:!0,children:[e.jsx("span",{className:"ic",children:l}),e.jsx(S,{children:s})]}),O=({id:s,label:l,icon:n,sections:a})=>{const c=x();return e.jsxs(A,{id:s,className:"rp-item rp-subitem",textValue:l,children:[e.jsx("span",{className:"ic",children:n}),e.jsx(S,{children:l}),e.jsxs("span",{className:"desc",children:[B(a,c),e.jsx(r,{className:"rp-chev-end"})]})]})};function R({label:l,submenus:n,actions:a=[]}){const c="function"==typeof n?n():n,t=x(),o=b(j),[u,d]="rtl"===f().direction?["ArrowLeft","ArrowRight"]:["ArrowRight","ArrowLeft"],[{open:h,left:p},g]=s.useState({open:null,left:null}),C=s.useRef(null),N=s.useId(),A=e=>{C.current?.focus(),g({open:e,left:null==e?h:null})};if(s.useEffect(()=>{const e=C.current;if(!e||null==h&&null==p)return;const s=null==h?`[data-key="${CSS.escape(`/submenu-${p}`)}"]`:'[aria-checked="true"], [role="menuitem"]',l=requestAnimationFrame(()=>{document.activeElement===e&&e.querySelector(s)?.focus()});return()=>cancelAnimationFrame(l)},[h,p]),!o)return e.jsxs(v,{"aria-label":l,"aria-labelledby":"",children:[c.map(s=>"sections"in s?e.jsxs(y,{children:[e.jsx(O,{id:`/submenu-${s.label}`,...s}),e.jsx(m,{className:"rp-popover rp-list-popover",offset:-4,crossOffset:-9,children:e.jsx($,{...s,headers:s.sections.length>1})})]},s.label):e.jsx(F,{...s},s.label)),a.map(s=>e.jsx(F,{...s},s.label))]});const S=null==h?null:c.find(e=>e.label===h);if(S&&"sections"in S){const s=()=>A(null),l=e=>{e.key!==d&&"Escape"!==e.key||(e.preventDefault(),e.stopPropagation(),s())};return e.jsxs("div",{ref:C,className:"rp-drill",tabIndex:-1,onKeyDownCapture:l,children:[e.jsxs(i,{className:"rp-item rp-drill-back","aria-label":t("ui.back"),onPress:s,children:[e.jsx(r,{className:"rp-chev-start"}),e.jsx("span",{id:N,children:S.label})]}),e.jsx($,{...S,labelledBy:N,headers:S.sections.length>1,focusedByCaller:!0})]})}const M=e=>c.find(s=>`/submenu-${s.label}`===e&&"sections"in s)?.label??null;return e.jsx("div",{ref:C,className:"rp-drill",tabIndex:-1,onKeyDownCapture:e=>{const s=M(e.target.dataset.key);e.key===u&&null!=s&&(e.preventDefault(),A(s))},children:e.jsxs(v,{"aria-label":l,"aria-labelledby":"",autoFocus:null==p&&void 0,shouldCloseOnSelect:!1,onAction:e=>{const s=M(String(e));null!=s&&A(s)},children:[c.map(s=>"sections"in s?e.jsx(O,{id:`/submenu-${s.label}`,...s},s.label):e.jsx(F,{...s},s.label)),a.map(s=>e.jsx(F,{...s},s.label))]})})}function T({label:s,items:l,selectionMode:n,value:a,onChange:c,onAction:t,searchLabel:i}){const r="function"==typeof l?l():l,o=!!i&&D(r.length),u=e.jsx(v,{"aria-label":s,"aria-labelledby":"",className:o?"rp-menu-scroll":void 0,selectionMode:n,disallowEmptySelection:"single"===n,selectedKeys:null==a?void 0:"string"==typeof a?[a]:a,onSelectionChange:c&&E(c),shouldCloseOnSelect:"multiple"!==n&&void 0,onAction:t&&(e=>t(String(e))),children:r.map(s=>e.jsx(P,{item:s},s.id))});return o?e.jsx(N,{label:i,children:u}):u}function K({items:s,selectionMode:l,value:a,onChange:c,sections:t,submenus:i,actions:r,onAction:o,searchLabel:u,triggerLabel:d,...h}){const p=t?Array.isArray(t)&&D(z(t)):i?Array.isArray(i)&&i.some(e=>"sections"in e&&!!e.searchLabel&&D(z(e.sections))):Array.isArray(s)&&D(s.length);return e.jsx(V,{...h,label:d??h.label,onIntent:h.onIntent??(u&&p?n:void 0),content:i?e.jsx(R,{label:h.label,submenus:i,actions:r}):t?e.jsx($,{label:h.label,sections:t,onAction:o,searchLabel:u,actions:r}):e.jsx(T,{label:h.label,items:s,selectionMode:l??(null==a?"none":"single"),value:a,onChange:c,onAction:o,searchLabel:u})})}function G(s){return e.jsxs(M,{...s,children:[e.jsx("circle",{cx:"10.859",cy:"5.521",r:"1.5",fill:"currentColor"}),e.jsx("circle",{cx:"6.859",cy:"7.521",r:"1.5",fill:"currentColor"}),e.jsx("circle",{cx:"6.859",cy:"12.521",r:"1.5",fill:"currentColor"}),e.jsx("circle",{cx:"10.859",cy:"14.521",r:"1.5",fill:"currentColor"}),e.jsx("path",{fill:"currentColor",d:"M11.003 18.771c-2.595-.018-4.935-.91-6.662-2.507-1.762-1.631-2.732-3.814-2.732-6.145s.97-4.514 2.732-6.144C6.192 2.257 8.683 1.27 11.17 1.27c2.157 0 4.143.737 5.594 2.074 1.048.97 1.626 2.27 1.626 3.659s-.578 2.69-1.625 3.66l-1.204 1.12c-.086.078-.188.206-.188.362s.102.284.188.364c.146.136.18.169.516.226.414.073.95.166 1.373.576l.001.001c.396.386.626.979.618 1.586-.008.59-.234 1.119-.636 1.49-1.625 1.513-3.97 2.382-6.431 2.382m.168-16c-2.114 0-4.233.84-5.81 2.304C3.907 6.42 3.108 8.211 3.108 10.12s.8 3.7 2.251 5.043c1.431 1.325 3.465 2.094 5.581 2.11 2.147 0 4.12-.723 5.473-1.983.133-.123.154-.31.156-.41.003-.223-.083-.41-.164-.49-.092-.088-.352-.134-.562-.17-.61-.106-.923-.254-1.306-.614-.428-.397-.664-.916-.664-1.46 0-.542.236-1.061.666-1.46l1.205-1.122c.74-.683 1.146-1.592 1.146-2.56s-.407-1.873-1.144-2.556c-1.172-1.08-2.797-1.675-4.576-1.675"})]})}function U(s){return e.jsxs(M,{...s,children:[e.jsx("path",{fill:"currentColor",d:"M10 18.78c-4.825 0-8.75-3.926-8.75-8.75S5.175 1.28 10 1.28s8.75 3.924 8.75 8.75-3.925 8.75-8.75 8.75m0-16c-3.998 0-7.25 3.251-7.25 7.25s3.252 7.25 7.25 7.25 7.25-3.253 7.25-7.25S13.998 2.78 10 2.78"}),e.jsx("path",{fill:"currentColor",d:"M10 14.384c0 .653.615 1.121 1.251.973 2.435-.566 4.249-2.75 4.249-5.357s-1.814-4.79-4.249-5.357c-.636-.148-1.251.32-1.251.973z"})]})}function W(s){return e.jsx(M,{...s,children:e.jsx("path",{fill:"currentColor",d:"M10 6.35c2.012 0 3.65 1.638 3.65 3.65s-1.638 3.65-3.65 3.65S6.35 12.012 6.35 10 7.988 6.35 10 6.35m0-1.5c-2.84 0-5.15 2.31-5.15 5.15s2.31 5.15 5.15 5.15 5.15-2.31 5.15-5.15S12.84 4.85 10 4.85M10 3.25c-.414 0-.75-.336-.75-.75V1.25c0-.414.336-.75.75-.75s.75.336.75.75V2.5c0 .414-.336.75-.75.75M10 19.5c-.414 0-.75-.336-.75-.75V17.5c0-.414.336-.75.75-.75s.75.336.75.75v1.25c0 .414-.336.75-.75.75M2.5 10.75H1.25c-.414 0-.75-.336-.75-.75s.336-.75.75-.75H2.5c.414 0 .75.336.75.75s-.336.75-.75.75M18.75 10.75H17.5c-.414 0-.75-.336-.75-.75s.336-.75.75-.75h1.25c.414 0 .75.336.75.75s-.336.75-.75.75M15.304 5.446c-.193 0-.384-.073-.53-.22-.294-.292-.294-.767 0-1.06l.883-.884c.293-.293.768-.293 1.06 0s.294.768 0 1.06l-.883.885c-.146.146-.338.22-.53.22M3.813 16.938c-.193 0-.384-.074-.53-.22-.294-.293-.294-.768 0-1.06l.883-.885c.293-.293.768-.293 1.06 0s.294.768 0 1.061l-.883.884c-.147.146-.338.22-.53.22M4.696 5.446c-.192 0-.383-.073-.53-.22l-.884-.883c-.293-.293-.293-.768 0-1.06s.768-.294 1.06 0l.885.883c.293.293.293.768 0 1.06-.147.147-.338.22-.53.22M16.188 16.938c-.193 0-.384-.074-.53-.22l-.885-.884c-.293-.293-.293-.768 0-1.06s.768-.294 1.061 0l.884.883c.293.293.293.768 0 1.06-.147.147-.338.22-.53.22"})})}function X(s){return e.jsx(M,{...s,children:e.jsx("path",{fill:"currentColor",d:"M12.25 2.5H7.834v-.75c0-.414-.336-.75-.75-.75s-.75.336-.75.75v.75H1.75c-.414 0-.75.336-.75.75s.336.75.75.75h7.878C9.17 6.271 7.792 7.876 6.272 8.934c-.479-.869-.843-1.76-1.068-2.645-.101-.401-.51-.648-.912-.542-.4.102-.644.51-.542.911.259 1.02.677 2.045 1.228 3.039-.793.395-1.563.66-2.195.802-.405.09-.659.491-.569.896.078.348.388.585.732.585q.082 0 .164-.018c.766-.171 1.705-.499 2.669-.996.824 1.19 1.83 2.311 2.988 3.284.14.118.312.176.482.176.214 0 .426-.091.575-.268.266-.317.225-.79-.092-1.056-1.031-.867-1.927-1.858-2.664-2.906C8.946 8.906 10.67 6.903 11.156 4h1.094c.414 0 .75-.336.75-.75s-.336-.75-.75-.75M18.94 17.958l-4.018-9.5c-.118-.277-.39-.458-.691-.458s-.573.18-.691.458l-4.02 9.5c-.16.38.018.821.399.982.384.165.822-.016.983-.398l1.28-3.026h4.097l1.28 3.026c.121.286.399.458.691.458q.148 0 .292-.06c.382-.16.56-.601.399-.982m-6.123-3.942 1.414-3.341 1.413 3.34z"})})}function Y({dark:s}){return e.jsxs("span",{className:"rp-icon-stack","data-dark":s||void 0,children:[e.jsx(U,{className:"moon"}),e.jsx(W,{className:"sun"})]})}function Z({lang:l,pickLang:n}){const a=x(),[c]=s.useState(l);return e.jsx(K,{quiet:!0,chevron:!1,label:a("ui.lang"),value:l,onChange:e=>n(e),items:k,children:e.jsx(X,{className:l!==c?"rp-icon-in":void 0},l)})}function J({dark:s,label:l,toggle:n}){return e.jsx(I,{quiet:!0,icon:!0,label:l,onPress:n,children:e.jsx(Y,{dark:s})})}function Q({ap:e,paletteSections:s}){return{palettes:s.map(s=>({...s,items:s.items.map(e=>({...e,aside:!0})),value:e.shownPalette,onChange:s=>e.pickPalette(s)}))}}function _({more:l,...n}){const a=x(),{palettes:c}=Q(n),t=n.ap.palette,[i]=s.useState(t);return e.jsx(K,{quiet:!0,chevron:!1,label:a("ui.palette"),sections:c,actions:l&&[l],onIntent:L,children:e.jsx(G,{className:t!==i?"rp-icon-in":void 0},t)})}export{K as C,H as D,Z as L,V as M,_ as P,J as S,X as T,U as a,G as b,D as l,Q as u};
+import{j as e,r as s}from"./vendor-react-64fcanlc.js";import{fV as l,fW as n,fX as a,cA as c,dK as t,cC as i,bF as r,fj as o,cB as u,dN as d,fY as h,dO as p,cD as m,u as x,b8 as b,fZ as j,bz as f,cE as v,f_ as g,cF as y,cG as C,f$ as N,cH as A,T as S,I as M,bl as k,ej as L,B as w}from"./index-C06va4Yw.js";import{a as I,b as q}from"./ItemText-D6SGBgOi.js";const D=e=>e>12,H=({orientation:s="vertical"})=>e.jsx(l,{orientation:s,className:"vertical"===s?"rp-vrule":"rp-hrule"}),$=e=>s=>{if("all"===s)return;const l=[...s][0];null!=l&&e(String(l))};function F({item:s,children:l,onAction:n}){return e.jsxs(A,{id:s.id,className:"rp-item",textValue:s.label,onAction:n,children:[e.jsx(I,{}),e.jsx(q,{i:s,children:l})]})}function O({children:l,content:n,label:x,quiet:b,small:j,size:f,chevron:v=!0,isDisabled:g,appearance:y,placement:C="bottom end",count:N,onIntent:A}){const S=N?e.jsx("span",{className:"rp-count","aria-hidden":"true",children:N}):null,M=a(g),[k,L]=s.useState(!1),w=c(),I=t(f),q=s.useRef(null),D=e.jsxs(i,{ref:q,className:y?"rp-select":o({quiet:b,small:j,icon:!v}),"data-size":I,"aria-label":x,"aria-describedby":M?.id,isDisabled:g,onHoverStart:A,onFocus:A,children:[l,S,v&&e.jsx(r,{className:"rp-chev"})]});return e.jsxs(u,{children:[v&&!M?D:e.jsxs(d,{delay:400,isOpen:k,onOpenChange:L,children:[e.jsx(h,{children:e.jsx("span",{className:"rp-tipwrap",tabIndex:g?0:-1,"data-passive":g?void 0:"",onPointerDown:e=>{g&&"touch"===e.pointerType&&L(e=>!e)},children:D})}),e.jsx(p,{triggerRef:q,children:M?.text??x})]}),e.jsx(m,{className:"rp-popover rp-list-popover",placement:C,boundaryElement:w,children:n})]})}function P({label:s,labelledBy:l,sections:n,headers:a=!0,focusedByCaller:c,onAction:t,searchLabel:i,actions:r=[]}){const o="function"==typeof n?n():n,u=!!i&&D(V(o)),d=e.jsxs(v,{"aria-label":s,"aria-labelledby":l??"",className:u?"rp-menu-scroll":void 0,autoFocus:!c&&void 0,children:[o.map(s=>e.jsxs(y,{"aria-label":a&&!s.hideHeader?void 0:s.title,selectionMode:s.selectionMode??"single",selectedKeys:[`/choice-${s.value}`],onSelectionChange:s.onChange&&$(e=>s.onChange(e.slice(8))),children:[a&&!s.hideHeader&&e.jsx(C,{className:"rp-sec-h",children:s.title}),s.items.map(s=>e.jsx(F,{item:{...s,id:`/choice-${s.id}`},onAction:t&&(()=>t(s.id))},s.id))]},s.title)),r.length>0&&e.jsx(H,{orientation:"horizontal"}),r.map(s=>e.jsx(B,{...s},s.label))]});return u?e.jsx(N,{label:i,children:d}):d}const V=e=>e.reduce((e,s)=>e+s.items.length,0);function z(e,s){for(const l of e){const n=l.items.find(e=>e.id===l.value);if(n)return e.length>1&&!l.plain&&n.label!==l.title?s("ui.sectionChoice",{section:l.title,item:n.label}):n.label}return""}const B=({label:s,icon:l,onAction:n})=>e.jsxs(A,{className:"rp-item rp-subitem",textValue:s,onAction:n,shouldCloseOnSelect:!0,children:[e.jsx("span",{className:"ic",children:l}),e.jsx(S,{children:s})]}),E=({id:s,label:l,icon:n,sections:a})=>{const c=x();return e.jsxs(A,{id:s,className:"rp-item rp-subitem",textValue:l,children:[e.jsx("span",{className:"ic",children:n}),e.jsx(S,{children:l}),e.jsxs("span",{className:"desc",children:[z(a,c),e.jsx(r,{className:"rp-chev-end"})]})]})};function K({label:l,submenus:n,actions:a=[]}){const c="function"==typeof n?n():n,t=x(),o=b(j),[u,d]="rtl"===f().direction?["ArrowLeft","ArrowRight"]:["ArrowRight","ArrowLeft"],[{open:h,left:p},y]=s.useState({open:null,left:null}),C=s.useRef(null),N=s.useId(),A=e=>{C.current?.focus(),y({open:e,left:null==e?h:null})};if(s.useEffect(()=>{const e=C.current;if(!e||null==h&&null==p)return;const s=null==h?`[data-key="${CSS.escape(`/submenu-${p}`)}"]`:'[aria-checked="true"], [role="menuitem"]',l=requestAnimationFrame(()=>{document.activeElement===e&&e.querySelector(s)?.focus()});return()=>cancelAnimationFrame(l)},[h,p]),!o)return e.jsxs(v,{"aria-label":l,"aria-labelledby":"",children:[c.map(s=>"sections"in s?e.jsxs(g,{children:[e.jsx(E,{id:`/submenu-${s.label}`,...s}),e.jsx(m,{className:"rp-popover rp-list-popover",offset:-4,crossOffset:-9,children:e.jsx(P,{...s,headers:s.sections.length>1})})]},s.label):e.jsx(B,{...s},s.label)),a.map(s=>e.jsx(B,{...s},s.label))]});const S=null==h?null:c.find(e=>e.label===h);if(S&&"sections"in S){const s=()=>A(null),l=e=>{e.key!==d&&"Escape"!==e.key||(e.preventDefault(),e.stopPropagation(),s())};return e.jsxs("div",{ref:C,className:"rp-drill",tabIndex:-1,onKeyDownCapture:l,children:[e.jsxs(i,{className:"rp-item rp-drill-back","aria-label":t("ui.back"),onPress:s,children:[e.jsx(r,{className:"rp-chev-start"}),e.jsx("span",{id:N,children:S.label})]}),e.jsx(P,{...S,labelledBy:N,headers:S.sections.length>1,focusedByCaller:!0})]})}const M=e=>c.find(s=>`/submenu-${s.label}`===e&&"sections"in s)?.label??null;return e.jsx("div",{ref:C,className:"rp-drill",tabIndex:-1,onKeyDownCapture:e=>{const s=M(e.target.dataset.key);e.key===u&&null!=s&&(e.preventDefault(),A(s))},children:e.jsxs(v,{"aria-label":l,"aria-labelledby":"",autoFocus:null==p&&void 0,shouldCloseOnSelect:!1,onAction:e=>{const s=M(String(e));null!=s&&A(s)},children:[c.map(s=>"sections"in s?e.jsx(E,{id:`/submenu-${s.label}`,...s},s.label):e.jsx(B,{...s},s.label)),a.map(s=>e.jsx(B,{...s},s.label))]})})}function R({label:s,items:l,selectionMode:n,value:a,onChange:c,onAction:t,searchLabel:i}){const r="function"==typeof l?l():l,o=!!i&&D(r.length),u=e.jsx(v,{"aria-label":s,"aria-labelledby":"",className:o?"rp-menu-scroll":void 0,selectionMode:n,disallowEmptySelection:"single"===n,selectedKeys:null==a?void 0:"string"==typeof a?[a]:a,onSelectionChange:c&&$(c),shouldCloseOnSelect:"multiple"!==n&&void 0,onAction:t&&(e=>t(String(e))),children:r.map(s=>e.jsx(F,{item:s},s.id))});return o?e.jsx(N,{label:i,children:u}):u}function T({items:s,selectionMode:l,value:a,onChange:c,sections:t,submenus:i,actions:r,onAction:o,searchLabel:u,triggerLabel:d,...h}){const p=t?Array.isArray(t)&&D(V(t)):i?Array.isArray(i)&&i.some(e=>"sections"in e&&!!e.searchLabel&&D(V(e.sections))):Array.isArray(s)&&D(s.length);return e.jsx(O,{...h,label:d??h.label,onIntent:h.onIntent??(u&&p?n:void 0),content:i?e.jsx(K,{label:h.label,submenus:i,actions:r}):t?e.jsx(P,{label:h.label,sections:t,onAction:o,searchLabel:u,actions:r}):e.jsx(R,{label:h.label,items:s,selectionMode:l??(null==a?"none":"single"),value:a,onChange:c,onAction:o,searchLabel:u})})}function G(s){return e.jsxs(M,{...s,children:[e.jsx("circle",{cx:"10.859",cy:"5.521",r:"1.5",fill:"currentColor"}),e.jsx("circle",{cx:"6.859",cy:"7.521",r:"1.5",fill:"currentColor"}),e.jsx("circle",{cx:"6.859",cy:"12.521",r:"1.5",fill:"currentColor"}),e.jsx("circle",{cx:"10.859",cy:"14.521",r:"1.5",fill:"currentColor"}),e.jsx("path",{fill:"currentColor",d:"M11.003 18.771c-2.595-.018-4.935-.91-6.662-2.507-1.762-1.631-2.732-3.814-2.732-6.145s.97-4.514 2.732-6.144C6.192 2.257 8.683 1.27 11.17 1.27c2.157 0 4.143.737 5.594 2.074 1.048.97 1.626 2.27 1.626 3.659s-.578 2.69-1.625 3.66l-1.204 1.12c-.086.078-.188.206-.188.362s.102.284.188.364c.146.136.18.169.516.226.414.073.95.166 1.373.576l.001.001c.396.386.626.979.618 1.586-.008.59-.234 1.119-.636 1.49-1.625 1.513-3.97 2.382-6.431 2.382m.168-16c-2.114 0-4.233.84-5.81 2.304C3.907 6.42 3.108 8.211 3.108 10.12s.8 3.7 2.251 5.043c1.431 1.325 3.465 2.094 5.581 2.11 2.147 0 4.12-.723 5.473-1.983.133-.123.154-.31.156-.41.003-.223-.083-.41-.164-.49-.092-.088-.352-.134-.562-.17-.61-.106-.923-.254-1.306-.614-.428-.397-.664-.916-.664-1.46 0-.542.236-1.061.666-1.46l1.205-1.122c.74-.683 1.146-1.592 1.146-2.56s-.407-1.873-1.144-2.556c-1.172-1.08-2.797-1.675-4.576-1.675"})]})}function W(s){return e.jsxs(M,{...s,children:[e.jsx("path",{fill:"currentColor",d:"M10 18.78c-4.825 0-8.75-3.926-8.75-8.75S5.175 1.28 10 1.28s8.75 3.924 8.75 8.75-3.925 8.75-8.75 8.75m0-16c-3.998 0-7.25 3.251-7.25 7.25s3.252 7.25 7.25 7.25 7.25-3.253 7.25-7.25S13.998 2.78 10 2.78"}),e.jsx("path",{fill:"currentColor",d:"M10 14.384c0 .653.615 1.121 1.251.973 2.435-.566 4.249-2.75 4.249-5.357s-1.814-4.79-4.249-5.357c-.636-.148-1.251.32-1.251.973z"})]})}function X(s){return e.jsx(M,{...s,children:e.jsx("path",{fill:"currentColor",d:"M10 6.35c2.012 0 3.65 1.638 3.65 3.65s-1.638 3.65-3.65 3.65S6.35 12.012 6.35 10 7.988 6.35 10 6.35m0-1.5c-2.84 0-5.15 2.31-5.15 5.15s2.31 5.15 5.15 5.15 5.15-2.31 5.15-5.15S12.84 4.85 10 4.85M10 3.25c-.414 0-.75-.336-.75-.75V1.25c0-.414.336-.75.75-.75s.75.336.75.75V2.5c0 .414-.336.75-.75.75M10 19.5c-.414 0-.75-.336-.75-.75V17.5c0-.414.336-.75.75-.75s.75.336.75.75v1.25c0 .414-.336.75-.75.75M2.5 10.75H1.25c-.414 0-.75-.336-.75-.75s.336-.75.75-.75H2.5c.414 0 .75.336.75.75s-.336.75-.75.75M18.75 10.75H17.5c-.414 0-.75-.336-.75-.75s.336-.75.75-.75h1.25c.414 0 .75.336.75.75s-.336.75-.75.75M15.304 5.446c-.193 0-.384-.073-.53-.22-.294-.292-.294-.767 0-1.06l.883-.884c.293-.293.768-.293 1.06 0s.294.768 0 1.06l-.883.885c-.146.146-.338.22-.53.22M3.813 16.938c-.193 0-.384-.074-.53-.22-.294-.293-.294-.768 0-1.06l.883-.885c.293-.293.768-.293 1.06 0s.294.768 0 1.061l-.883.884c-.147.146-.338.22-.53.22M4.696 5.446c-.192 0-.383-.073-.53-.22l-.884-.883c-.293-.293-.293-.768 0-1.06s.768-.294 1.06 0l.885.883c.293.293.293.768 0 1.06-.147.147-.338.22-.53.22M16.188 16.938c-.193 0-.384-.074-.53-.22l-.885-.884c-.293-.293-.293-.768 0-1.06s.768-.294 1.061 0l.884.883c.293.293.293.768 0 1.06-.147.147-.338.22-.53.22"})})}function Y(s){return e.jsx(M,{...s,children:e.jsx("path",{fill:"currentColor",d:"M12.25 2.5H7.834v-.75c0-.414-.336-.75-.75-.75s-.75.336-.75.75v.75H1.75c-.414 0-.75.336-.75.75s.336.75.75.75h7.878C9.17 6.271 7.792 7.876 6.272 8.934c-.479-.869-.843-1.76-1.068-2.645-.101-.401-.51-.648-.912-.542-.4.102-.644.51-.542.911.259 1.02.677 2.045 1.228 3.039-.793.395-1.563.66-2.195.802-.405.09-.659.491-.569.896.078.348.388.585.732.585q.082 0 .164-.018c.766-.171 1.705-.499 2.669-.996.824 1.19 1.83 2.311 2.988 3.284.14.118.312.176.482.176.214 0 .426-.091.575-.268.266-.317.225-.79-.092-1.056-1.031-.867-1.927-1.858-2.664-2.906C8.946 8.906 10.67 6.903 11.156 4h1.094c.414 0 .75-.336.75-.75s-.336-.75-.75-.75M18.94 17.958l-4.018-9.5c-.118-.277-.39-.458-.691-.458s-.573.18-.691.458l-4.02 9.5c-.16.38.018.821.399.982.384.165.822-.016.983-.398l1.28-3.026h4.097l1.28 3.026c.121.286.399.458.691.458q.148 0 .292-.06c.382-.16.56-.601.399-.982m-6.123-3.942 1.414-3.341 1.413 3.34z"})})}function Z({dark:s}){return e.jsxs("span",{className:"rp-icon-stack","data-dark":s||void 0,children:[e.jsx(W,{className:"moon"}),e.jsx(X,{className:"sun"})]})}function _({lang:l,pickLang:n}){const a=x(),[c]=s.useState(l);return e.jsx(T,{quiet:!0,chevron:!1,label:a("ui.lang"),value:l,onChange:e=>n(e),items:k,children:e.jsx(Y,{className:l!==c?"rp-icon-in":void 0},l)})}function J({dark:s,label:l,toggle:n}){return e.jsx(w,{quiet:!0,icon:!0,label:l,onPress:n,children:e.jsx(Z,{dark:s})})}function Q({ap:e,paletteSections:s}){return{palettes:s.map(s=>({...s,items:s.items.map(e=>({...e,aside:!0})),value:e.shownPalette,onChange:s=>e.pickPalette(s)}))}}function U({more:l,...n}){const a=x(),{palettes:c}=Q(n),t=n.ap.palette,[i]=s.useState(t);return e.jsx(T,{quiet:!0,chevron:!1,label:a("ui.palette"),sections:c,actions:l&&[l],onIntent:L,children:e.jsx(G,{className:t!==i?"rp-icon-in":void 0},t)})}export{T as C,H as D,_ as L,O as M,U as P,J as S,Y as T,W as a,G as b,D as l,Q as u};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/AreaChart-Ci1Uh0tf.js b/luci-app-honk/root/etc/honk/doona/assets/AreaChart-B0HmHYXx.js
similarity index 56%
rename from luci-app-honk/root/etc/honk/doona/assets/AreaChart-Ci1Uh0tf.js
rename to luci-app-honk/root/etc/honk/doona/assets/AreaChart-B0HmHYXx.js
index 7b13b2f5a..e8d40bf70 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/AreaChart-Ci1Uh0tf.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/AreaChart-B0HmHYXx.js
@@ -1 +1 @@
-import{r as e,j as t}from"./vendor-react-64fcanlc.js";import{u as a,g as s,gD as n,dV as o,gE as i}from"./index-CUHkLMAp.js";import{b as l,a_ as r,a$ as c,b0 as h,b1 as m,b2 as u,b3 as p,b4 as d,b5 as x,b6 as f}from"./activity-B3PmJo_X.js";import{G as M,C as g}from"./AreaCurve-DQSHOSpG.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./nodes-BYMoo8M1.js";import"./logs-C6Kb44nw.js";import"./Select-BA0NS1_z.js";import"./ItemText-CnEXu0-f.js";import"./AppearanceControls-E-VPhjIz.js";import"./array-C0VuvQyb.js";const j=[30,60,120,300,600,900,1800,3600,7200,21600,43200,86400].map(e=>1e3*e);function y(t,a){const[s,n]=e.useState([]),o=e.useRef("");return e.useLayoutEffect(()=>{const e=[a,...t].join("\0");if(e===o.current)return;o.current=e;const s=document.createElement("span");s.className="rp-area-tick",Object.assign(s.style,{position:"absolute",top:"-20000px",whiteSpace:"pre"}),document.body.appendChild(s),n(t.map(e=>{s.textContent=e;const{width:t,height:a}=s.getBoundingClientRect();return{width:t,height:a}})),s.remove()},[t,a]),s}function b({label:b,series:v,timestamps:w,fmt:k,locale:C,height:D=150,baseline:$="zero",window:N,fill:S,bare:A=!1,inset:E=2}){const L=a(),T=l(),B=e.useId(),[F,I]=s(Math.round,120),{tip:P,showAt:z,hide:K}=r(),[O,R]=e.useState(null),W=O&&O.indexvoid 0!==G&&void 0!==H?function(e,t){const a=t-e,s=j.find(e=>a/e<=6)??j[j.length-1],n=s>=864e5?6e4*new Date(t).getTimezoneOffset():0,o=[];for(let i=Math.ceil((e-n)/s)*s+n;i<=t;i+=s)i-e>=.04*a&&t-i>=.04*a&&o.push(i);return{ticks:o,step:s}}(G,H):void 0,[G,H]),V=U?U.step<6e4:_<18e4,q=U?U.step>=864e5:_>1296e5,J=e.useMemo(()=>q?n(C):o(C,V),[C,V,q]),{yDomain:Q,yTicks:X}=e.useMemo(()=>{const e=v.flatMap(e=>e.values.filter(e=>null!==e));let t=0,a=(e=>{const t=Math.pow(10,Math.floor(Math.log10(e))),a=e/t;return([1,1.2,1.5,2,2.5,3,4,5,6,8,10].find(e=>a<=e)??10)*t})(1.08*Math.max(1,...e));if("auto"===$&&e.length){const s=Math.min(...e),n=Math.max(...e),o=(e=>{const t=Math.pow(10,Math.floor(Math.log10(Math.max(e,1e-9)))),a=e/t;return(a<=1?.2:a<=2?.5:a<=5?1:2)*t})(Math.max(n-s,.02*n,1));t=Math.max(0,Math.floor(s/o)*o-o),a=Math.ceil(n/o)*o+o}return{yDomain:[t,a],yTicks:"auto"===$?[t,(t+a)/2,a]:[a/2,a]}},[v,$]),Y=e.useMemo(()=>{const e=w.length-1;return U?U.ticks:[...new Set((V?[0,Math.round(e/2),e]:[0,Math.round(e/3),Math.round(2*e/3),e]).map(e=>w[e]))]},[U,V,w]),Z=e.useMemo(()=>void 0!==G&&void 0!==H?[G,H]:[Math.min(...w),Math.max(...w)],[G,H,w]),ee=I?.width??0,te=I?.height??D,ae=A?E:20,se=A?2:8,ne=te-(A?2:30),oe=ee-(A?E:64),ie=e.useMemo(()=>[Math.min(Z[0],...w),Math.max(Z[1],...w)],[Z,w]),le=e.useCallback(e=>c(e,ie,[ae,oe]),[ie,ae,oe]),re=e.useCallback(e=>c(e,Q,[ne,se]),[Q,ne,se]),ce=e.useMemo(()=>w.map(le),[w,le]),he=e.useMemo(()=>v.map(e=>w.map((t,a)=>null==e.values[a]?null:{x:ce[a],y:re(e.values[a])})),[v,w,ce,re]),me={x:ae,y:se,width:oe-ae,height:ne-se},ue=(e,t)=>R({index:e,y:t}),pe=()=>{R(null),K()};e.useLayoutEffect(()=>{null!==W&&v.some(e=>null!=e.values[W])?z({x:ce[W],y:O?.y??(se+ne)/2,width:ee,bounds:A&&F.current?m(F.current):me,label:i(C).format(w[W]),lines:h(v,W,k,L)}):K()});const de=u(w.length,ue,pe),xe=e.useMemo(()=>Y.map(e=>J.format(e)),[Y,J]),fe=e.useMemo(()=>X.map(k),[X,k]),Me=y(xe,C),ge=y(fe,C),je=U?p(Y.map(le),Me.map(e=>e.width),0,ee,16,!0):function(e,t,a){const s=a=>[e[a]-(t[a]??0)/2,e[a]+(t[a]??0)/2],n=e.length-1,o=[];let i=1/0;for(let l=n;l>=0;l--){const[t,r]=s(l);r+a>i||l>0&&le.width),8),ye=p(X.map(re),ge.map(e=>e.height),0,te,5,!1),be=[...new Set([...(A?X:ye.map(e=>X[e.index])).map(re),se,ne])];return t.jsx("div",{ref:F,style:{height:D,width:"100%",flex:S?"1 0 auto":void 0,position:"relative"},onPointerLeave:de.onPointerLeave,children:w.length>0&&I&&t.jsxs(t.Fragment,{children:[t.jsx(d,{tip:P}),t.jsxs("svg",{className:"rp-activity-surface",width:ee,height:te,viewBox:`0 0 ${ee} ${te}`,style:{display:"block"},role:"application","aria-label":b,tabIndex:0,onFocus:de.onFocus,onBlur:de.onBlur,onKeyDown:de.onKeyDown,onPointerMove:e=>{const{x:t,y:a}=x(e,e.currentTarget,{width:ee,height:te});if(toe||ane)return void pe();const s=f(ce,t);ue(s,a)},children:[t.jsx("g",{className:"rp-area-grid",children:be.map(e=>t.jsx("line",{x1:ae,x2:oe,y1:e,y2:e,stroke:T["hl-med"],strokeDasharray:"2 4",fill:"none"},e))}),t.jsx("defs",{children:v.map((e,a)=>t.jsx(M,{id:B+a,color:e.color},e.label))}),v.map((e,a)=>t.jsx(g,{points:he[a],baseline:re(Math.max(0,Q[0])),color:e.color,id:B+a,strokeWidth:2},e.label)),null!==W&&t.jsx("path",{d:`M${ce[W]},${se}L${ce[W]},${ne}`,stroke:T.subtle,strokeDasharray:"3 3",fill:"none",pointerEvents:"none"}),!A&&t.jsxs(t.Fragment,{children:[t.jsx("g",{children:je.map(({index:e,position:a})=>t.jsx("text",{x:a,y:ne+8,className:"rp-area-tick",fill:T.subtle,textAnchor:"middle",children:t.jsx("tspan",{x:a,dy:"0.71em",children:xe[e]})},e))}),t.jsx("g",{className:"rp-area-y-ticks",children:ye.map(({index:e,position:a})=>t.jsx("text",{x:oe+8,y:a,className:"rp-area-tick",fill:T.subtle,textAnchor:"start",children:t.jsx("tspan",{x:oe+8,dy:"0.355em",children:k(X[e])})},e))})]}),null!==W&&v.map(e=>null==e.values[W]?null:t.jsx("circle",{cx:ce[W],cy:re(e.values[W]),r:4,fill:e.color,stroke:T.base,strokeWidth:2},e.label))]})]})})}export{b as AreaPlot};
+import{r as e,j as t}from"./vendor-react-64fcanlc.js";import{u as a,g as s,gE as n,dX as o,gF as i}from"./index-C06va4Yw.js";import{b as l,aZ as r,a_ as c,a$ as h,b0 as m,b1 as u,b2 as p,b3 as d,b4 as x,b5 as f}from"./activity-BoXvjA12.js";import{G as M,C as g}from"./AreaCurve-DQSHOSpG.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./nodes-oXccX15o.js";import"./logs-BtAlqVqe.js";import"./Select-hQ95uOjm.js";import"./ItemText-D6SGBgOi.js";import"./AppearanceControls-CEVO9-aR.js";import"./array-C0VuvQyb.js";const j=[30,60,120,300,600,900,1800,3600,7200,21600,43200,86400].map(e=>1e3*e);function y(t,a){const[s,n]=e.useState([]),o=e.useRef("");return e.useLayoutEffect(()=>{const e=[a,...t].join("\0");if(e===o.current)return;o.current=e;const s=document.createElement("span");s.className="rp-area-tick",Object.assign(s.style,{position:"absolute",top:"-20000px",whiteSpace:"pre"}),document.body.appendChild(s),n(t.map(e=>{s.textContent=e;const{width:t,height:a}=s.getBoundingClientRect();return{width:t,height:a}})),s.remove()},[t,a]),s}function b({label:b,series:v,timestamps:w,fmt:k,locale:C,height:D=150,baseline:$="zero",window:N,fill:S,bare:A=!1,inset:E=2}){const F=a(),L=l(),T=e.useId(),[B,I]=s(Math.round,120),{tip:P,showAt:W,hide:z}=r(),[K,O]=e.useState(null),R=K&&K.indexvoid 0!==G&&void 0!==H?function(e,t){const a=t-e,s=j.find(e=>a/e<=6)??j[j.length-1],n=s>=864e5?6e4*new Date(t).getTimezoneOffset():0,o=[];for(let i=Math.ceil((e-n)/s)*s+n;i<=t;i+=s)i-e>=.04*a&&t-i>=.04*a&&o.push(i);return{ticks:o,step:s}}(G,H):void 0,[G,H]),Z=X?X.step<6e4:_<18e4,q=X?X.step>=864e5:_>1296e5,J=e.useMemo(()=>q?n(C):o(C,Z),[C,Z,q]),{yDomain:Q,yTicks:U}=e.useMemo(()=>{const e=v.flatMap(e=>e.values.filter(e=>null!==e));let t=0,a=(e=>{const t=Math.pow(10,Math.floor(Math.log10(e))),a=e/t;return([1,1.2,1.5,2,2.5,3,4,5,6,8,10].find(e=>a<=e)??10)*t})(1.08*Math.max(1,...e));if("auto"===$&&e.length){const s=Math.min(...e),n=Math.max(...e),o=(e=>{const t=Math.pow(10,Math.floor(Math.log10(Math.max(e,1e-9)))),a=e/t;return(a<=1?.2:a<=2?.5:a<=5?1:2)*t})(Math.max(n-s,.02*n,1));t=Math.max(0,Math.floor(s/o)*o-o),a=Math.ceil(n/o)*o+o}return{yDomain:[t,a],yTicks:"auto"===$?[t,(t+a)/2,a]:[a/2,a]}},[v,$]),V=e.useMemo(()=>{const e=w.length-1;return X?X.ticks:[...new Set((Z?[0,Math.round(e/2),e]:[0,Math.round(e/3),Math.round(2*e/3),e]).map(e=>w[e]))]},[X,Z,w]),Y=e.useMemo(()=>void 0!==G&&void 0!==H?[G,H]:[Math.min(...w),Math.max(...w)],[G,H,w]),ee=I?.width??0,te=I?.height??D,ae=A?E:20,se=A?2:8,ne=te-(A?2:30),oe=ee-(A?E:64),ie=e.useMemo(()=>[Math.min(Y[0],...w),Math.max(Y[1],...w)],[Y,w]),le=e.useCallback(e=>c(e,ie,[ae,oe]),[ie,ae,oe]),re=e.useCallback(e=>c(e,Q,[ne,se]),[Q,ne,se]),ce=e.useMemo(()=>w.map(le),[w,le]),he=e.useMemo(()=>v.map(e=>w.map((t,a)=>null==e.values[a]?null:{x:ce[a],y:re(e.values[a])})),[v,w,ce,re]),me={x:ae,y:se,width:oe-ae,height:ne-se},ue=(e,t)=>O({index:e,y:t}),pe=()=>{O(null),z()};e.useLayoutEffect(()=>{null!==R&&v.some(e=>null!=e.values[R])?W({x:ce[R],y:K?.y??(se+ne)/2,width:ee,bounds:A&&B.current?m(B.current):me,label:i(C).format(w[R]),lines:h(v,R,k,F)}):z()});const de=u(w.length,ue,pe),xe=e.useMemo(()=>V.map(e=>J.format(e)),[V,J]),fe=e.useMemo(()=>U.map(k),[U,k]),Me=y(xe,C),ge=y(fe,C),je=X?p(V.map(le),Me.map(e=>e.width),0,ee,16,!0):function(e,t,a){const s=a=>[e[a]-(t[a]??0)/2,e[a]+(t[a]??0)/2],n=e.length-1,o=[];let i=1/0;for(let l=n;l>=0;l--){const[t,r]=s(l);r+a>i||l>0&&le.width),8),ye=p(U.map(re),ge.map(e=>e.height),0,te,5,!1),be=[...new Set([...(A?U:ye.map(e=>U[e.index])).map(re),se,ne])];return t.jsx("div",{ref:B,style:{height:D,width:"100%",flex:S?"1 0 auto":void 0,position:"relative"},onPointerLeave:de.onPointerLeave,children:w.length>0&&I&&t.jsxs(t.Fragment,{children:[t.jsx(d,{tip:P}),t.jsxs("svg",{className:"rp-activity-surface",width:ee,height:te,viewBox:`0 0 ${ee} ${te}`,style:{display:"block"},role:"application","aria-label":b,tabIndex:0,onFocus:de.onFocus,onBlur:de.onBlur,onKeyDown:de.onKeyDown,onPointerMove:e=>{const{x:t,y:a}=x(e,e.currentTarget,{width:ee,height:te});if(toe||ane)return void pe();const s=f(ce,t);ue(s,a)},children:[t.jsx("g",{className:"rp-area-grid",children:be.map(e=>t.jsx("line",{x1:ae,x2:oe,y1:e,y2:e,stroke:L["hl-med"],strokeDasharray:"2 4",fill:"none"},e))}),t.jsx("defs",{children:v.map((e,a)=>t.jsx(M,{id:T+a,color:e.color},e.label))}),v.map((e,a)=>t.jsx(g,{points:he[a],baseline:re(Math.max(0,Q[0])),color:e.color,id:T+a,strokeWidth:2},e.label)),null!==R&&t.jsx("path",{d:`M${ce[R]},${se}L${ce[R]},${ne}`,stroke:L.subtle,strokeDasharray:"3 3",fill:"none",pointerEvents:"none"}),!A&&t.jsxs(t.Fragment,{children:[t.jsx("g",{children:je.map(({index:e,position:a})=>t.jsx("text",{x:a,y:ne+8,className:"rp-area-tick",fill:L.subtle,textAnchor:"middle",children:t.jsx("tspan",{x:a,dy:"0.71em",children:xe[e]})},e))}),t.jsx("g",{className:"rp-area-y-ticks",children:ye.map(({index:e,position:a})=>t.jsx("text",{x:oe+8,y:a,className:"rp-area-tick",fill:L.subtle,textAnchor:"start",children:t.jsx("tspan",{x:oe+8,dy:"0.355em",children:k(U[e])})},e))})]}),null!==R&&v.map(e=>null==e.values[R]?null:t.jsx("circle",{cx:ce[R],cy:re(e.values[R]),r:4,fill:e.color,stroke:L.base,strokeWidth:2},e.label))]})]})})}export{b as AreaPlot};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/BackendText-Dtw6qhij.js b/luci-app-honk/root/etc/honk/doona/assets/BackendText-DK5RWFKi.js
similarity index 82%
rename from luci-app-honk/root/etc/honk/doona/assets/BackendText-Dtw6qhij.js
rename to luci-app-honk/root/etc/honk/doona/assets/BackendText-DK5RWFKi.js
index 0f451a62a..ef41a67b9 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/BackendText-Dtw6qhij.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/BackendText-DK5RWFKi.js
@@ -1 +1 @@
-import{j as r,r as s}from"./vendor-react-64fcanlc.js";import{u as e}from"./index-CUHkLMAp.js";import{D as t}from"./logs-C6Kb44nw.js";function n({texts:n}){const o=e();return n?.length?r.jsx(t,{flush:!0,title:o("config.backendText"),children:n.map((e,t)=>r.jsxs(s.Fragment,{children:[t>0&&r.jsx("br",{}),r.jsx("code",{children:e})]},t))}):null}export{n as B};
+import{j as r,r as s}from"./vendor-react-64fcanlc.js";import{u as e}from"./index-C06va4Yw.js";import{D as t}from"./logs-BtAlqVqe.js";function n({texts:n}){const o=e();return n?.length?r.jsx(t,{flush:!0,title:o("config.backendText"),children:n.map((e,t)=>r.jsxs(s.Fragment,{children:[t>0&&r.jsx("br",{}),r.jsx("code",{children:e})]},t))}):null}export{n as B};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/CardView-N7n2PJ-s.js b/luci-app-honk/root/etc/honk/doona/assets/CardView-jh7SJ_si.js
similarity index 82%
rename from luci-app-honk/root/etc/honk/doona/assets/CardView-N7n2PJ-s.js
rename to luci-app-honk/root/etc/honk/doona/assets/CardView-jh7SJ_si.js
index 56f3dd7ed..899b65bdf 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/CardView-N7n2PJ-s.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/CardView-jh7SJ_si.js
@@ -1 +1 @@
-import{j as e}from"./vendor-react-64fcanlc.js";import{a,$ as s}from"./GridList-CQPDUasC.js";import{T as i,cy as r,u as t,S as l,al as c}from"./index-CUHkLMAp.js";function n({label:a,items:i,selected:r,onSelect:n,loading:d,empty:o,children:m}){const p=t();return e.jsx(s,{className:"rp-cardview","aria-label":a,layout:"grid",items:i,dependencies:[m],selectionMode:"single",selectionBehavior:"replace",disallowEmptySelection:!0,selectedKeys:r?[r]:[],onSelectionChange:e=>{if("all"===e)return;const a=[...e][0];null!=a&&n(String(a))},renderEmptyState:()=>d?e.jsx(l,{shape:"cards",count:3,height:224,grid:!0,typical:!0}):e.jsx(c,{children:o??p("ui.empty")}),children:m})}function d({id:s,title:t,titleFull:l,meta:c,actions:n,children:d}){return e.jsxs(a,{id:s,textValue:t,className:r("rp-cardview-card"),children:[e.jsxs("div",{className:"rp-cardview-head",children:[e.jsx(i,{className:"rp-cardview-title",text:l,children:t}),n&&e.jsx("span",{className:"rp-cardview-actions",children:n})]}),c&&e.jsx("div",{className:"rp-cardview-meta",children:c}),d]})}export{d as C,n as a};
+import{j as e}from"./vendor-react-64fcanlc.js";import{a,$ as s}from"./GridList-Dgo5IXUg.js";import{T as i,cz as r,u as t,S as l,al as c}from"./index-C06va4Yw.js";function n({label:a,items:i,selected:r,onSelect:n,loading:d,empty:o,children:m}){const p=t();return e.jsx(s,{className:"rp-cardview","aria-label":a,layout:"grid",items:i,dependencies:[m],selectionMode:"single",selectionBehavior:"replace",disallowEmptySelection:!0,selectedKeys:r?[r]:[],onSelectionChange:e=>{if("all"===e)return;const a=[...e][0];null!=a&&n(String(a))},renderEmptyState:()=>d?e.jsx(l,{shape:"cards",count:3,height:228,grid:!0,typical:!0}):e.jsx(c,{children:o??p("ui.empty")}),children:m})}function d({id:s,title:t,titleFull:l,meta:c,actions:n,children:d}){return e.jsxs(a,{id:s,textValue:t,className:r("rp-cardview-card"),children:[e.jsxs("div",{className:"rp-cardview-head",children:[e.jsx(i,{className:"rp-cardview-title",text:l,children:t}),n&&e.jsx("span",{className:"rp-cardview-actions",children:n})]}),c&&e.jsx("div",{className:"rp-cardview-meta",children:c}),d]})}export{d as C,n as a};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Checkbox-8Iqnc6T1.js b/luci-app-honk/root/etc/honk/doona/assets/Checkbox-CsFZSc5N.js
similarity index 82%
rename from luci-app-honk/root/etc/honk/doona/assets/Checkbox-8Iqnc6T1.js
rename to luci-app-honk/root/etc/honk/doona/assets/Checkbox-CsFZSc5N.js
index 650c6a83f..bcaea40dd 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Checkbox-8Iqnc6T1.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Checkbox-CsFZSc5N.js
@@ -1 +1 @@
-import{r as s,j as e}from"./vendor-react-64fcanlc.js";import{g as a}from"./useGridSelectionCheckbox-CTBMGgmQ.js";import{C as i}from"./ItemText-CnEXu0-f.js";import{dw as r}from"./index-CUHkLMAp.js";function d({label:d,description:o,isSelected:l,onChange:c,isDisabled:n,slot:t}){const p=s.useId(),m=s.useId(),x=r({isDisabled:n});return e.jsxs(a,{className:"rp-radio rp-checkbox",slot:t,isSelected:l,onChange:c,isDisabled:x.isDisabled,"aria-labelledby":d?p:void 0,"aria-describedby":o?m:void 0,children:[e.jsx("span",{className:"rp-checkbox-mark",children:e.jsx(i,{})}),d&&e.jsxs("span",{className:"rp-radio-text",children:[e.jsx("span",{id:p,children:d}),o&&e.jsx("span",{id:m,className:"rp-note",children:o})]})]})}export{d as C};
+import{r as s,j as e}from"./vendor-react-64fcanlc.js";import{g as a}from"./useGridSelectionCheckbox-inhSeUkV.js";import{C as i}from"./ItemText-D6SGBgOi.js";import{dy as r}from"./index-C06va4Yw.js";function d({label:d,description:o,isSelected:l,onChange:c,isDisabled:n,slot:t}){const p=s.useId(),m=s.useId(),x=r({isDisabled:n});return e.jsxs(a,{className:"rp-radio rp-checkbox",slot:t,isSelected:l,onChange:c,isDisabled:x.isDisabled,"aria-labelledby":d?p:void 0,"aria-describedby":o?m:void 0,children:[e.jsx("span",{className:"rp-checkbox-mark",children:e.jsx(i,{})}),d&&e.jsxs("span",{className:"rp-radio-text",children:[e.jsx("span",{id:p,children:d}),o&&e.jsx("span",{id:m,className:"rp-note",children:o})]})]})}export{d as C};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/CheckboxSet-CZH2lrzI.js b/luci-app-honk/root/etc/honk/doona/assets/CheckboxSet-C1rY3UKa.js
similarity index 64%
rename from luci-app-honk/root/etc/honk/doona/assets/CheckboxSet-CZH2lrzI.js
rename to luci-app-honk/root/etc/honk/doona/assets/CheckboxSet-C1rY3UKa.js
index 720b40969..e0f42806f 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/CheckboxSet-CZH2lrzI.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/CheckboxSet-C1rY3UKa.js
@@ -1 +1 @@
-import{j as e,r as s}from"./vendor-react-64fcanlc.js";import{I as i,cK as l,cx as a,B as n,cn as r}from"./index-CUHkLMAp.js";import{C as c}from"./Checkbox-8Iqnc6T1.js";function d(s){return e.jsx(i,{...s,children:e.jsx("path",{fill:"currentColor",d:"M17.78 1.757C16.51.716 14.555.858 13.33 2.08L3.079 12.334c-.32.32-.559.717-.69 1.15l-1.384 4.584c-.08.265-.007.552.188.747.142.143.334.22.53.22q.11 0 .217-.032l4.582-1.384c.434-.13.832-.368 1.151-.688L18.028 6.575c.648-.647.993-1.545.948-2.46s-.482-1.775-1.195-2.358M2.846 17.163l.98-3.246q.042-.135.113-.257l2.41 2.409q-.123.07-.259.114zM16.966 5.516l-9.525 9.526-2.475-2.476 9.425-9.425c.386-.387.896-.586 1.39-.586.38 0 .752.119 1.05.362.392.321.621.772.646 1.272.025.494-.161.977-.51 1.327"})})}function o({children:s}){return e.jsx(r,{children:s})}function t({children:s,negate:i,onNegate:r,negateLabel:c,removeLabel:d,onRemove:t,isDisabled:b,removeDisabled:h}){return e.jsxs(l,{children:[s,e.jsxs(o,{children:[e.jsx(a,{isDisabled:b,isSelected:i,onChange:r,children:c}),e.jsx("span",{className:"rp-grow"}),e.jsx(n,{small:!0,isDisabled:b||h,onPress:t,children:d})]})]})}function b({label:i,hideLabel:l=!1,items:a,value:n,onChange:r,isDisabled:d}){const o=s.useId();return e.jsxs("div",{className:"rp-checkbox-set",role:"group","aria-labelledby":o,children:[e.jsx("span",{id:o,className:"rp-label",hidden:l,children:i}),e.jsx("div",{className:"rp-checkbox-options",children:a.map(s=>e.jsx(c,{label:s.label,description:s.description,isSelected:n.includes(s.id),isDisabled:d||s.isDisabled,onChange:e=>r(e?[...n,s.id]:n.filter(e=>e!==s.id))},s.id))})]})}export{b as C,d as E,t as a,o as b};
+import{j as e,r as s}from"./vendor-react-64fcanlc.js";import{I as i,cL as l,cy as a,B as r,co as n}from"./index-C06va4Yw.js";import{C as c}from"./Checkbox-CsFZSc5N.js";function d(s){return e.jsx(i,{...s,children:e.jsx("path",{fill:"currentColor",d:"M17.78 1.757C16.51.716 14.555.858 13.33 2.08L3.079 12.334c-.32.32-.559.717-.69 1.15l-1.384 4.584c-.08.265-.007.552.188.747.142.143.334.22.53.22q.11 0 .217-.032l4.582-1.384c.434-.13.832-.368 1.151-.688L18.028 6.575c.648-.647.993-1.545.948-2.46s-.482-1.775-1.195-2.358M2.846 17.163l.98-3.246q.042-.135.113-.257l2.41 2.409q-.123.07-.259.114zM16.966 5.516l-9.525 9.526-2.475-2.476 9.425-9.425c.386-.387.896-.586 1.39-.586.38 0 .752.119 1.05.362.392.321.621.772.646 1.272.025.494-.161.977-.51 1.327"})})}function o({children:s}){return e.jsx(n,{children:s})}function t({children:s,negate:i,onNegate:n,negateLabel:c,removeLabel:d,onRemove:t,isDisabled:b,removeDisabled:h}){return e.jsxs(l,{children:[s,e.jsxs(o,{children:[e.jsx(a,{isDisabled:b,isSelected:i,onChange:n,children:c}),e.jsx("span",{className:"rp-grow"}),e.jsx(r,{small:!0,isDisabled:b||h,onPress:t,children:d})]})]})}function b({label:i,hideLabel:l=!1,items:a,value:r,onChange:n,isDisabled:d}){const o=s.useId();return e.jsxs("div",{className:"rp-checkbox-set",role:"group","aria-labelledby":o,children:[e.jsx("span",{id:o,className:"rp-label",hidden:l,children:i}),e.jsx("div",{className:"rp-checkbox-options",children:a.map(s=>e.jsx(c,{label:s.label,description:s.description,isSelected:r.includes(s.id),isDisabled:d||s.isDisabled,onChange:e=>n(e?[...r,s.id]:r.filter(e=>e!==s.id))},s.id))})]})}export{b as C,d as E,t as a,o as b};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/CodeEditor-DCw5LkC0.js b/luci-app-honk/root/etc/honk/doona/assets/CodeEditor-9GVA7w36.js
similarity index 70%
rename from luci-app-honk/root/etc/honk/doona/assets/CodeEditor-DCw5LkC0.js
rename to luci-app-honk/root/etc/honk/doona/assets/CodeEditor-9GVA7w36.js
index adc19fe53..7a6679618 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/CodeEditor-DCw5LkC0.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/CodeEditor-9GVA7w36.js
@@ -1 +1 @@
-import{r as e,j as r}from"./vendor-react-64fcanlc.js";import{bW as t,gO as o,bV as n,fy as a,bz as c,u as s,cn as i,dG as l,B as d,cD as p,cG as m}from"./index-CUHkLMAp.js";import{S as u,a as f,E as g,C as b,b as v,l as h,c as x,h as y,d as k,r as w,e as j,f as C,g as R,i as A,j as L,s as E,k as M,t as O,m as D,n as F,o as N,p as S,q as $,u as B,v as q,w as I,x as T,y as V,z as G,D as H,R as z,A as K,B as U,F as W,G as P,H as J,I as X,J as _,K as Q,L as Y}from"./vendor-editor-50h2cCk6.js";import{d as Z,s as ee}from"./daeTokens-BVtuNnWZ.js";import{s as re}from"./nodes-BYMoo8M1.js";import{M as te}from"./AppearanceControls-E-VPhjIz.js";import{n as oe,A as ne}from"./logs-C6Kb44nw.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./index-DUM-iwa2.js";import"./ItemText-CnEXu0-f.js";import"./Select-BA0NS1_z.js";const ae=u.define({name:"dae",languageData:{commentTokens:{line:"#"},closeBrackets:{brackets:["(","{","'",'"']}},startState:ee,token:Z}),ce=["global","subscription","node","group","dns","routing"].map(e=>({label:e,type:"keyword"})),se=n.map(e=>({label:e,type:"property",apply:e+": "})),ie=["domain","dip","sip","dport","sport","l4proto","ipversion","pname","mac","dscp","qname","qtype","upstream"].map(e=>({label:e,type:"function",apply:e+"("})),le=["geosite","geoip","suffix","full","keyword","regex"].map(e=>({label:e,type:"constant",apply:e+":"})),de=o.map(e=>({label:e,type:"constant"})),pe=t.map(e=>({label:e,type:"keyword"})),me=["asis","reject"].map(e=>({label:e,type:"keyword"})),ue=["accept","reject"].map(e=>({label:e,type:"keyword"})),fe=[{label:"fallback",type:"keyword",apply:"fallback: "},{label:"include",type:"keyword",apply:"include "}],ge=e=>e.map(e=>({label:e.name,apply:e.written,type:"variable"}));function be(e){return f({override:[r=>function(e,r){const t=e.matchBefore(/[\w.-]*/);if(!t)return null;const o=e.state.doc.lineAt(e.pos),n=o.text.slice(0,e.pos-o.from),a=/->\s*[\w.-]*$/.test(n)||/^\s*fallback:\s*[\w.-]*$/.test(n);if(t.from===t.to&&!e.explicit&&!a)return null;const c=e.state.doc.sliceString(0,e.pos),{blocks:s,tokens:i}=re(c),l=i.at(-1);if(l?.to===e.pos&&("quoted"===l.kind||"comment"===l.kind))return null;const d=[],p=r=>r.close===e.pos;for(let f=s.find(p);f;f=f.children.find(p))d.push(f.name);const m=d[0];let u;if(a){const{groups:e,upstreams:t}=r();u="dns"!==m?[...ge(e),...pe]:[...ge(t),...d.includes("response")?ue:me]}else if(/\b(domain|dip|sip|qname)\(\s*[\w.-]*$/.test(n))u=le;else if(void 0===m)u=ce.map(e=>({...e,apply:(r,t,o,n)=>{const a=e.label+" {\n \n}";r.dispatch({changes:{from:o,to:n,insert:a},selection:{anchor:o+e.label.length+4}})}}));else if("routing"===m||"dns"===m)u=[...ie,...fe];else if("global"===m)u=se;else{if("group"!==m)return null;u=/\bpolicy\s*:\s*[\w.-]*$/.test(n)?de:[...de.map(e=>({...e,apply:"policy: "+e.label})),{label:"filter",type:"property",apply:"filter: "}]}return{from:t.from,options:u,validFor:/^[\w.-]*$/}}(r,e)]})}function ve(e){let r=!1;const t=r=>(r.state.readOnly&&e(),!1);return g.domEventHandlers({keydown:(e,r)=>function(e){return"Backspace"===e.key||"Delete"===e.key||"Enter"===e.key||1===[...e.key].length&&!e.ctrlKey&&!e.metaKey}(e)&&t(r),paste:(e,r)=>t(r),cut:(e,r)=>t(r),pointerdown:e=>(r="touch"===e.pointerType,!1),click:(e,o)=>r&&t(o)})}const he=[["Completions","cm.completions"],["Find","cm.find"],["Replace","cm.replace"],["next","cm.next"],["previous","cm.previous"],["all","cm.all"],["match case","cm.matchCase"],["regexp","cm.regexp"],["by word","cm.byWord"],["replace","cm.replaceOne"],["replace all","cm.replaceAll"],["close","ui.close"],["Go to line","cm.gotoLine"],["go","cm.go"],["current match","cm.currentMatch"],["replaced $ matches","cm.replacedMatches"],["replaced match on line $","cm.replacedOnLine"],["on line","cm.onLine"],["Selection deleted","cm.selectionDeleted"],["Control character","cm.controlCharacter"]],xe=e=>v.phrases.of(Object.fromEntries(he.map(([r,t])=>[r,e(t)]))),ye=g.theme({"&":{backgroundColor:"var(--rp-base)",color:"var(--rp-text)",border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-md)",fontSize:"var(--rp-text-sm)"},"&.cm-focused":{outline:"none",borderColor:"var(--rp-text)"},".cm-scroller":{fontFamily:"var(--rp-font-mono)",lineHeight:"var(--rp-line-body)",fontVariantLigatures:"none",borderRadius:"calc(var(--rp-r-md) - 1px)"},".cm-content":{padding:"var(--rp-space-2) 0",caretColor:"var(--rp-text)"},".cm-line":{padding:"0 var(--rp-space-3)"},".cm-gutters":{backgroundColor:"var(--rp-base)",color:"var(--rp-muted)",border:"none"},".cm-lineNumbers .cm-gutterElement":{padding:"0 var(--rp-space-2) 0 var(--rp-space-3)",minWidth:"40px"},".cm-activeLine, .cm-focusLine":{backgroundColor:"color-mix(in srgb, var(--rp-hl-med) 60%, transparent)"},".cm-activeLineGutter":{backgroundColor:"transparent",color:"var(--rp-text)"},".cm-selectionBackground, &.cm-focused .cm-selectionBackground, ::selection":{backgroundColor:"var(--rp-hl-high)"},".cm-cursor":{borderLeftColor:"var(--rp-text)"},".cm-matchingBracket":{backgroundColor:"color-mix(in srgb, var(--rp-accent) 20%, transparent)",outline:"none"},".cm-selectionMatch":{backgroundColor:"color-mix(in srgb, var(--rp-notice) 25%, transparent)"},".cm-gutter-lint":{width:"12px"},".cm-gutter-lint .cm-gutterElement":{padding:"0"},".cm-lint-marker":{width:"8px",height:"8px",margin:"6px 2px",borderRadius:"50%"},".cm-lint-marker-error":{content:"none",backgroundColor:"var(--rp-negative)"},".cm-lint-marker-warning":{content:"none",backgroundColor:"var(--rp-notice)"},".cm-lint-marker-info":{content:"none",backgroundColor:"var(--rp-foam)"},".cm-tooltip.cm-tooltip-lint":{backgroundColor:"var(--rp-text)",color:"var(--rp-on-text)",border:"none",borderRadius:"var(--rp-r-sm)",padding:"var(--rp-space-half) 0"},".cm-tooltip-lint .cm-diagnostic":{border:"none",padding:"var(--rp-space-half) var(--rp-space-2)",fontSize:"var(--rp-text-xs)",lineHeight:"16px",fontFamily:"inherit"},".cm-tooltip-lint .cm-diagnosticText":{color:"inherit"},".cm-diag-line-error":{backgroundColor:"color-mix(in srgb, var(--rp-negative) 14%, transparent)"},".cm-diag-line-warning":{backgroundColor:"color-mix(in srgb, var(--rp-notice) 16%, transparent)"},".cm-diag-line-info":{backgroundColor:"color-mix(in srgb, var(--rp-foam) 14%, transparent)"},".cm-lintRange-error":{backgroundImage:"none",textDecoration:"underline wavy var(--rp-negative)",textUnderlineOffset:"3px"},".cm-lintRange-warning":{backgroundImage:"none",textDecoration:"underline wavy var(--rp-notice)",textUnderlineOffset:"3px"},".cm-lintRange-info":{backgroundImage:"none",textDecoration:"underline dotted var(--rp-foam)",textUnderlineOffset:"3px"},".cm-tooltip":{backgroundColor:"var(--rp-surface)",border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-md)",color:"var(--rp-text)"},".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]":{backgroundColor:"var(--rp-selected)",color:"var(--rp-text)"},".cm-tooltip.cm-tooltip-autocomplete > ul":{fontFamily:"var(--rp-font-mono)",fontVariantLigatures:"none"},".cm-panels":{backgroundColor:"var(--rp-surface)",color:"var(--rp-text)"},".cm-panels-bottom":{borderTop:"1px solid var(--rp-hl-med)"},".cm-textfield":{border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-sm)",backgroundColor:"var(--rp-base)",color:"var(--rp-text)"},".cm-button":{border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-sm)",backgroundImage:"none",backgroundColor:"var(--rp-overlay)",color:"var(--rp-text)"}}),ke=Q.define([{tag:Y.comment,color:"var(--rp-code-comment)"},{tag:Y.keyword,color:"var(--rp-code-keyword)",fontWeight:"700"},{tag:Y.string,color:"var(--rp-code-string)"},{tag:Y.number,color:"var(--rp-code-number)"},{tag:Y.propertyName,color:"var(--rp-code-propertyName)"},{tag:Y.variableName,color:"var(--rp-code-variableName)"},{tag:Y.operator,color:"var(--rp-code-operator)"},{tag:Y.punctuation,color:"var(--rp-code-punctuation)"}]),we=K.of((e,r)=>{const t=e.lineAt(r,-1),o=t.from>0?e.lineAt(t.from-1,-1):null;if(!o)return 0;const n=/^\s*/.exec(o.text)[0].length,a=/\{\s*(#.*)?$/.test(o.text),c=/^\s*\}/.test(t.text);return Math.max(0,n+(a?2:0)-(c?2:0))}),je=X.define(),Ce={error:H.line({class:"cm-diag-line cm-diag-line-error"}),warning:H.line({class:"cm-diag-line cm-diag-line-warning"}),info:H.line({class:"cm-diag-line cm-diag-line-info"})},Re=G.define({create:()=>H.none,update(e,r){let t=e.map(r.changes);for(const o of r.effects){if(!o.is(je))continue;const e=new z,n={error:0,warning:1,info:2},a=new Map;for(const t of o.value){if(t.line<1||t.line>r.state.doc.lines)continue;const e=a.get(t.line);(!e||n[t.level]e-r)){const o=r.state.doc.line(t).from;e.add(o,o,Ce[a.get(t).level])}t=e.finish()}return t},provide:e=>g.decorations.from(e)}),Ae=[{id:"undo",label:"cm.undo",run:T},{id:"redo",label:"cm.redo",run:V},{id:"comment",label:"cm.toggleComment",run:O}],Le=[],Ee=J.define(),Me=X.define(),Oe=H.line({class:"cm-focusLine"}),De=G.define({create:()=>H.none,update(e,r){let t=e.map(r.changes);for(const o of r.effects)o.is(Me)&&(t=H.set(Oe.range(r.state.doc.line(o.value).from)));return t},provide:e=>g.decorations.from(e)}),Fe=e=>[v.readOnly.of(e),g.editable.of(!e),e?De:[U(),W(),P()]];function Ne({value:t,onChange:o,readOnly:n=!1,marks:u=Le,focusLine:f,label:T,names:V,onSave:G,onReadOnlyAttempt:H,compact:z,actions:K=[],focusKey:U,banner:W}){const P=e.useRef(null),J=a(P,`${n} ${!!o} ${T}`),X=e.useRef(null);e.useLayoutEffect(()=>{J&&P.current?.contains(document.activeElement)&&X.current?.querySelector("button")?.focus()},[J]);const Q=e.useRef(null),{isFocusVisible:Y}=c({isTextInput:!0}),Z=e.useRef(null),ee=e.useRef(null),re=e.useRef(o),ce=e.useRef(V),se=e.useRef(G),ie=e.useRef(H);e.useEffect(()=>{re.current=o,ce.current=V,se.current=G,ie.current=H});const le=e.useRef(new b),de=s(),pe=e.useRef(new b),me=e.useRef(new b),ue=e.useRef(new b);e.useLayoutEffect(()=>{const e=new g({parent:Q.current,state:v.create({doc:t,extensions:[h(),x(),g.scrollMargins.of(e=>{const r=Z.current?.getBoundingClientRect().bottom;return void 0===r?null:{top:Math.min(r,Math.max(0,r-e.scrollDOM.getBoundingClientRect().top))}}),y(),ue.current.of(k()),w(),Re,j(),C(),R(),A.of(" "),L(),we,be(()=>ce.current?.()??{groups:[],upstreams:[]}),ae,E(ke),ye,M.of([{key:"Mod-s",run:()=>(se.current?.(),!0)},{key:"Mod-/",run:O},{key:"Mod-g",run:D},...F,...N,...S,...$,...B,q]),le.current.of(Fe(n)),pe.current.of(xe(de)),me.current.of(g.contentAttributes.of({"aria-label":T,tabindex:"0"})),ve(()=>ie.current?.()),g.updateListener.of(e=>{e.docChanged&&!e.transactions.some(e=>e.annotation(Ee))&&re.current?.(e.state.doc.toString())})]})});return ee.current=e,()=>{e.destroy(),ee.current=null}},[]),e.useEffect(()=>{const e=ee.current;e&&e.dispatch({effects:le.current.reconfigure(Fe(n))})},[n]),e.useEffect(()=>{ee.current?.dispatch({effects:pe.current.reconfigure(xe(de))})},[de]),e.useEffect(()=>{ee.current?.dispatch({effects:me.current.reconfigure(g.contentAttributes.of({"aria-label":T,tabindex:"0"}))})},[T]),e.useEffect(()=>{const e=ee.current;e&&e.state.doc.toString()!==t&&(e.dispatch({changes:{from:0,to:e.state.doc.length,insert:t},annotations:Ee.of(!0),effects:ue.current.reconfigure([])}),e.dispatch({effects:ue.current.reconfigure(k())}))},[t]),e.useEffect(()=>{const e=ee.current;if(!e)return;const r=I(e.state,function(e,r){return r.filter(r=>r.line>=1&&r.line<=e.doc.lines).map(r=>{const t=e.doc.line(r.line),o=Math.max(0,(r.column??1)-1);let n=0;for(let e=0;no)break;e+=a,n+=r>65535?2:1}return{from:t.from+n,to:t.to,severity:r.level,message:r.message}})}(e.state,u)),t=Array.isArray(r.effects)?r.effects:r.effects?[r.effects]:[];e.dispatch({...r,effects:[...t,je.of(u)]})},[u]),e.useEffect(()=>{const e=ee.current;if(!e||!f||f<1||f>e.state.doc.lines)return;const r=e.state.doc.line(f);e.dispatch({selection:{anchor:r.from},effects:[Me.of(f),g.scrollIntoView(r.from,{y:"center"})]}),e.focus()},[f,U]);const fe=e=>{ee.current&&e(ee.current)},ge=J&&r.jsx("div",{className:"rp-editor-overflow",ref:X,children:r.jsx(oe,{actions:[{id:"find",label:de(n?"cm.find":"cm.findReplace"),onAction:()=>requestAnimationFrame(()=>fe(_))},{id:"line",label:de("cm.gotoLine"),onAction:()=>requestAnimationFrame(()=>fe(D))},...o?Ae.map(e=>({id:e.id,label:de(e.label),isDisabled:n,onAction:()=>requestAnimationFrame(()=>fe(e.run))})):[]]})});return r.jsxs(r.Fragment,{children:[!z&&r.jsxs("div",{className:"rp-editor-head",ref:Z,children:[r.jsxs("div",{className:"rp-editor-toolbar",children:[K.length>0&&r.jsxs(i,{children:[r.jsx(l,{children:r.jsx(ne,{actions:K,overflowMode:"wrap"})}),ge]}),r.jsxs("div",{className:"rp-editor-actions","data-collapsed":J||void 0,"data-merged":J&&K.length>0||void 0,children:[r.jsxs(i,{ref:P,children:[r.jsx(d,{onPress:()=>fe(_),children:de(n?"cm.find":"cm.findReplace")}),r.jsx(d,{onPress:()=>fe(D),children:de("cm.gotoLine")}),o&&r.jsx(te,{label:de("cm.commands"),isDisabled:n,content:r.jsx(p,{"aria-label":de("cm.commands"),onAction:e=>{const r=Ae.find(r=>r.id===e);r&&fe(r.run)},children:Ae.map(e=>r.jsx(m,{id:e.id,className:"rp-item plain",textValue:de(e.label),children:de(e.label)},e.id))}),children:de("cm.commands")})]}),0===K.length&&ge]})]}),W]}),r.jsx("div",{className:z?"rp-editor compact":"rp-editor",ref:Q,"data-keyboard":Y||void 0})]})}export{Ne as CodeEditor};
+import{r as e,j as r}from"./vendor-react-64fcanlc.js";import{bX as t,gP as o,bW as n,fA as a,bA as c,u as s,co as i,dI as l,B as d,cE as p,cH as m}from"./index-C06va4Yw.js";import{S as u,a as f,E as g,C as b,b as v,l as h,c as x,h as y,d as k,r as w,e as j,f as C,g as R,i as A,j as E,s as L,k as M,t as F,m as N,n as O,o as S,p as $,q as B,u as D,v as q,w as I,x as T,y as H,z as V,D as W,R as K,A as P,B as z,F as G,G as U,H as J,I as X,J as Z,K as _,L as Q}from"./vendor-editor-50h2cCk6.js";import{d as Y,s as ee}from"./daeTokens-BVtuNnWZ.js";import{s as re}from"./nodes-oXccX15o.js";import{M as te}from"./AppearanceControls-CEVO9-aR.js";import{n as oe,A as ne}from"./logs-BtAlqVqe.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./index-DUM-iwa2.js";import"./ItemText-D6SGBgOi.js";import"./Select-hQ95uOjm.js";const ae=u.define({name:"dae",languageData:{commentTokens:{line:"#"},closeBrackets:{brackets:["(","{","'",'"']}},startState:ee,token:Y}),ce=["global","subscription","node","group","dns","routing"].map(e=>({label:e,type:"keyword"})),se=n.map(e=>({label:e,type:"property",apply:e+": "})),ie=["domain","dip","sip","dport","sport","l4proto","ipversion","pname","mac","dscp","qname","qtype","upstream"].map(e=>({label:e,type:"function",apply:e+"("})),le=["geosite","geoip","suffix","full","keyword","regex"].map(e=>({label:e,type:"constant",apply:e+":"})),de=o.map(e=>({label:e,type:"constant"})),pe=t.map(e=>({label:e,type:"keyword"})),me=["asis","reject"].map(e=>({label:e,type:"keyword"})),ue=["accept","reject"].map(e=>({label:e,type:"keyword"})),fe=[{label:"fallback",type:"keyword",apply:"fallback: "},{label:"include",type:"keyword",apply:"include "}],ge=e=>e.map(e=>({label:e.name,apply:e.written,type:"variable"}));function be(e){return f({override:[r=>function(e,r){const t=e.matchBefore(/[\w.-]*/);if(!t)return null;const o=e.state.doc.lineAt(e.pos),n=o.text.slice(0,e.pos-o.from),a=/->\s*[\w.-]*$/.test(n)||/^\s*fallback:\s*[\w.-]*$/.test(n);if(t.from===t.to&&!e.explicit&&!a)return null;const c=e.state.doc.sliceString(0,e.pos),{blocks:s,tokens:i}=re(c),l=i.at(-1);if(l?.to===e.pos&&("quoted"===l.kind||"comment"===l.kind))return null;const d=[],p=r=>r.close===e.pos;for(let f=s.find(p);f;f=f.children.find(p))d.push(f.name);const m=d[0];let u;if(a){const{groups:e,upstreams:t}=r();u="dns"!==m?[...ge(e),...pe]:[...ge(t),...d.includes("response")?ue:me]}else if(/\b(domain|dip|sip|qname)\(\s*[\w.-]*$/.test(n))u=le;else if(void 0===m)u=ce.map(e=>({...e,apply:(r,t,o,n)=>{const a=e.label+" {\n \n}";r.dispatch({changes:{from:o,to:n,insert:a},selection:{anchor:o+e.label.length+4}})}}));else if("routing"===m||"dns"===m)u=[...ie,...fe];else if("global"===m)u=se;else{if("group"!==m)return null;u=/\bpolicy\s*:\s*[\w.-]*$/.test(n)?de:[...de.map(e=>({...e,apply:"policy: "+e.label})),{label:"filter",type:"property",apply:"filter: "}]}return{from:t.from,options:u,validFor:/^[\w.-]*$/}}(r,e)]})}function ve(e){let r=!1;const t=r=>(r.state.readOnly&&e(),!1);return g.domEventHandlers({keydown:(e,r)=>function(e){return"Backspace"===e.key||"Delete"===e.key||"Enter"===e.key||1===[...e.key].length&&!e.ctrlKey&&!e.metaKey}(e)&&t(r),paste:(e,r)=>t(r),cut:(e,r)=>t(r),pointerdown:e=>(r="touch"===e.pointerType,!1),click:(e,o)=>r&&t(o)})}const he=[["Completions","cm.completions"],["Find","cm.find"],["Replace","cm.replace"],["next","cm.next"],["previous","cm.previous"],["all","cm.all"],["match case","cm.matchCase"],["regexp","cm.regexp"],["by word","cm.byWord"],["replace","cm.replaceOne"],["replace all","cm.replaceAll"],["close","ui.close"],["Go to line","cm.gotoLine"],["go","cm.go"],["current match","cm.currentMatch"],["replaced $ matches","cm.replacedMatches"],["replaced match on line $","cm.replacedOnLine"],["on line","cm.onLine"],["Selection deleted","cm.selectionDeleted"],["Control character","cm.controlCharacter"]],xe=e=>v.phrases.of(Object.fromEntries(he.map(([r,t])=>[r,e(t)]))),ye=g.theme({"&":{backgroundColor:"var(--rp-base)",color:"var(--rp-text)",border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-md)",fontSize:"var(--rp-text-sm)"},"&.cm-focused":{outline:"none",borderColor:"var(--rp-text)"},".cm-scroller":{fontFamily:"var(--rp-font-mono)",lineHeight:"var(--rp-line-body)",fontVariantLigatures:"none",borderRadius:"calc(var(--rp-r-md) - 1px)"},".cm-content":{padding:"var(--rp-space-2) 0",caretColor:"var(--rp-text)"},".cm-line":{padding:"0 var(--rp-space-3)"},".cm-gutters":{backgroundColor:"var(--rp-base)",color:"var(--rp-muted)",border:"none"},".cm-lineNumbers .cm-gutterElement":{padding:"0 var(--rp-space-2) 0 var(--rp-space-3)",minWidth:"40px"},".cm-activeLine, .cm-focusLine":{backgroundColor:"color-mix(in srgb, var(--rp-hl-med) 60%, transparent)"},".cm-activeLineGutter":{backgroundColor:"transparent",color:"var(--rp-text)"},".cm-selectionBackground, &.cm-focused .cm-selectionBackground, ::selection":{backgroundColor:"var(--rp-hl-high)"},".cm-cursor":{borderLeftColor:"var(--rp-text)"},".cm-matchingBracket":{backgroundColor:"color-mix(in srgb, var(--rp-accent) 20%, transparent)",outline:"none"},".cm-selectionMatch":{backgroundColor:"color-mix(in srgb, var(--rp-notice) 25%, transparent)"},".cm-gutter-lint":{width:"12px"},".cm-gutter-lint .cm-gutterElement":{padding:"0"},".cm-lint-marker":{width:"8px",height:"8px",margin:"6px 2px",borderRadius:"50%"},".cm-lint-marker-error":{content:"none",backgroundColor:"var(--rp-negative)"},".cm-lint-marker-warning":{content:"none",backgroundColor:"var(--rp-notice)"},".cm-lint-marker-info":{content:"none",backgroundColor:"var(--rp-foam)"},".cm-tooltip.cm-tooltip-lint":{backgroundColor:"var(--rp-text)",color:"var(--rp-on-text)",border:"none",borderRadius:"var(--rp-r-sm)",padding:"var(--rp-space-half) 0"},".cm-tooltip-lint .cm-diagnostic":{border:"none",padding:"var(--rp-space-half) var(--rp-space-2)",fontSize:"var(--rp-text-xs)",lineHeight:"16px",fontFamily:"inherit"},".cm-tooltip-lint .cm-diagnosticText":{color:"inherit"},".cm-diag-line-error":{backgroundColor:"color-mix(in srgb, var(--rp-negative) 14%, transparent)"},".cm-diag-line-warning":{backgroundColor:"color-mix(in srgb, var(--rp-notice) 16%, transparent)"},".cm-diag-line-info":{backgroundColor:"color-mix(in srgb, var(--rp-foam) 14%, transparent)"},".cm-lintRange-error":{backgroundImage:"none",textDecoration:"underline wavy var(--rp-negative)",textUnderlineOffset:"3px"},".cm-lintRange-warning":{backgroundImage:"none",textDecoration:"underline wavy var(--rp-notice)",textUnderlineOffset:"3px"},".cm-lintRange-info":{backgroundImage:"none",textDecoration:"underline dotted var(--rp-foam)",textUnderlineOffset:"3px"},".cm-tooltip":{backgroundColor:"var(--rp-surface)",border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-md)",color:"var(--rp-text)"},".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]":{backgroundColor:"var(--rp-selected)",color:"var(--rp-text)"},".cm-tooltip.cm-tooltip-autocomplete > ul":{fontFamily:"var(--rp-font-mono)",fontVariantLigatures:"none"},".cm-panels":{backgroundColor:"var(--rp-surface)",color:"var(--rp-text)"},".cm-panels-bottom":{borderTop:"1px solid var(--rp-hl-med)"},".cm-textfield":{border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-sm)",backgroundColor:"var(--rp-base)",color:"var(--rp-text)"},".cm-button":{border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-sm)",backgroundImage:"none",backgroundColor:"var(--rp-overlay)",color:"var(--rp-text)"}}),ke=_.define([{tag:Q.comment,color:"var(--rp-code-comment)"},{tag:Q.keyword,color:"var(--rp-code-keyword)",fontWeight:"700"},{tag:Q.string,color:"var(--rp-code-string)"},{tag:Q.number,color:"var(--rp-code-number)"},{tag:Q.propertyName,color:"var(--rp-code-propertyName)"},{tag:Q.variableName,color:"var(--rp-code-variableName)"},{tag:Q.operator,color:"var(--rp-code-operator)"},{tag:Q.punctuation,color:"var(--rp-code-punctuation)"}]),we=P.of((e,r)=>{const t=e.lineAt(r,-1),o=t.from>0?e.lineAt(t.from-1,-1):null;if(!o)return 0;const n=/^\s*/.exec(o.text)[0].length,a=/\{\s*(#.*)?$/.test(o.text),c=/^\s*\}/.test(t.text);return Math.max(0,n+(a?2:0)-(c?2:0))}),je=X.define(),Ce={error:W.line({class:"cm-diag-line cm-diag-line-error"}),warning:W.line({class:"cm-diag-line cm-diag-line-warning"}),info:W.line({class:"cm-diag-line cm-diag-line-info"})},Re=V.define({create:()=>W.none,update(e,r){let t=e.map(r.changes);for(const o of r.effects){if(!o.is(je))continue;const e=new K,n={error:0,warning:1,info:2},a=new Map;for(const t of o.value){if(t.line<1||t.line>r.state.doc.lines)continue;const e=a.get(t.line);(!e||n[t.level]e-r)){const o=r.state.doc.line(t).from;e.add(o,o,Ce[a.get(t).level])}t=e.finish()}return t},provide:e=>g.decorations.from(e)}),Ae=[{id:"undo",label:"cm.undo",run:T},{id:"redo",label:"cm.redo",run:H},{id:"comment",label:"cm.toggleComment",run:F}],Ee=[],Le=J.define(),Me=X.define(),Fe=W.line({class:"cm-focusLine"}),Ne=V.define({create:()=>W.none,update(e,r){let t=e.map(r.changes);for(const o of r.effects)o.is(Me)&&(t=W.set(Fe.range(r.state.doc.line(o.value).from)));return t},provide:e=>g.decorations.from(e)}),Oe=e=>[v.readOnly.of(e),g.editable.of(!e),e?Ne:[z(),G(),U()]];function Se({value:t,onChange:o,readOnly:n=!1,marks:u=Ee,focusLine:f,label:T,names:H,onSave:V,onReadOnlyAttempt:W,compact:K,actions:P=[],focusKey:z,banner:G}){const U=e.useRef(null),J=a(U,`${n} ${!!o} ${T}`),X=e.useRef(null);e.useLayoutEffect(()=>{J&&U.current?.contains(document.activeElement)&&X.current?.querySelector("button")?.focus()},[J]);const _=e.useRef(null),{isFocusVisible:Q}=c({isTextInput:!0}),Y=e.useRef(null),ee=e.useRef(null),re=e.useRef(o),ce=e.useRef(H),se=e.useRef(V),ie=e.useRef(W);e.useEffect(()=>{re.current=o,ce.current=H,se.current=V,ie.current=W});const le=e.useRef(new b),de=s(),pe=e.useRef(new b),me=e.useRef(new b),ue=e.useRef(new b);e.useLayoutEffect(()=>{const e=new g({parent:_.current,state:v.create({doc:t,extensions:[h(),x(),g.scrollMargins.of(e=>{const r=Y.current?.getBoundingClientRect().bottom;return void 0===r?null:{top:Math.min(r,Math.max(0,r-e.scrollDOM.getBoundingClientRect().top))}}),y(),ue.current.of(k()),w(),Re,j(),C(),R(),A.of(" "),E(),we,be(()=>ce.current?.()??{groups:[],upstreams:[]}),ae,L(ke),ye,M.of([{key:"Mod-s",run:()=>(se.current?.(),!0)},{key:"Mod-/",run:F},{key:"Mod-g",run:N},...O,...S,...$,...B,...D,q]),le.current.of(Oe(n)),pe.current.of(xe(de)),me.current.of(g.contentAttributes.of({"aria-label":T,tabindex:"0"})),ve(()=>ie.current?.()),g.updateListener.of(e=>{e.docChanged&&!e.transactions.some(e=>e.annotation(Le))&&re.current?.(e.state.doc.toString())})]})});return ee.current=e,()=>{e.destroy(),ee.current=null}},[]),e.useEffect(()=>{const e=ee.current;e&&e.dispatch({effects:le.current.reconfigure(Oe(n))})},[n]),e.useEffect(()=>{ee.current?.dispatch({effects:pe.current.reconfigure(xe(de))})},[de]),e.useEffect(()=>{ee.current?.dispatch({effects:me.current.reconfigure(g.contentAttributes.of({"aria-label":T,tabindex:"0"}))})},[T]),e.useEffect(()=>{const e=ee.current;e&&e.state.doc.toString()!==t&&(e.dispatch({changes:{from:0,to:e.state.doc.length,insert:t},annotations:Le.of(!0),effects:ue.current.reconfigure([])}),e.dispatch({effects:ue.current.reconfigure(k())}))},[t]),e.useEffect(()=>{const e=ee.current;if(!e)return;const r=I(e.state,function(e,r){return r.filter(r=>r.line>=1&&r.line<=e.doc.lines).map(r=>{const t=e.doc.line(r.line),o=Math.max(0,(r.column??1)-1);let n=0;for(let e=0;no)break;e+=a,n+=r>65535?2:1}return{from:t.from+n,to:t.to,severity:r.level,message:r.message}})}(e.state,u)),t=Array.isArray(r.effects)?r.effects:r.effects?[r.effects]:[];e.dispatch({...r,effects:[...t,je.of(u)]})},[u]),e.useEffect(()=>{const e=ee.current;if(!e||!f||f<1||f>e.state.doc.lines)return;const r=e.state.doc.line(f);e.dispatch({selection:{anchor:r.from},effects:[Me.of(f),g.scrollIntoView(r.from,{y:"center"})]}),e.focus()},[f,z]);const fe=e=>{ee.current&&e(ee.current)},ge=J&&r.jsx("div",{className:"rp-editor-overflow",ref:X,children:r.jsx(oe,{actions:[{id:"find",label:de(n?"cm.find":"cm.findReplace"),onAction:()=>requestAnimationFrame(()=>fe(Z))},{id:"line",label:de("cm.gotoLine"),onAction:()=>requestAnimationFrame(()=>fe(N))},...o?Ae.map(e=>({id:e.id,label:de(e.label),isDisabled:n,onAction:()=>requestAnimationFrame(()=>fe(e.run))})):[]]})});return r.jsxs(r.Fragment,{children:[!K&&r.jsxs("div",{className:"rp-editor-head",ref:Y,children:[r.jsxs("div",{className:"rp-editor-toolbar",children:[P.length>0&&r.jsxs(i,{children:[r.jsx(l,{children:r.jsx(ne,{actions:P,overflowMode:"wrap"})}),ge]}),r.jsxs("div",{className:"rp-editor-actions","data-collapsed":J||void 0,"data-merged":J&&P.length>0||void 0,children:[r.jsxs(i,{ref:U,children:[r.jsx(d,{onPress:()=>fe(Z),children:de(n?"cm.find":"cm.findReplace")}),r.jsx(d,{onPress:()=>fe(N),children:de("cm.gotoLine")}),o&&r.jsx(te,{label:de("cm.commands"),isDisabled:n,content:r.jsx(p,{"aria-label":de("cm.commands"),onAction:e=>{const r=Ae.find(r=>r.id===e);r&&fe(r.run)},children:Ae.map(e=>r.jsx(m,{id:e.id,className:"rp-item plain",textValue:de(e.label),children:de(e.label)},e.id))}),children:de("cm.commands")})]}),0===P.length&&ge]})]}),G]}),r.jsx("div",{className:K?"rp-editor compact":"rp-editor",ref:_,"data-keyboard":Q||void 0})]})}export{Se as CodeEditor};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Config-DqTXXH6g.js b/luci-app-honk/root/etc/honk/doona/assets/Config-DPN1ciCe.js
similarity index 62%
rename from luci-app-honk/root/etc/honk/doona/assets/Config-DqTXXH6g.js
rename to luci-app-honk/root/etc/honk/doona/assets/Config-DPN1ciCe.js
index cb21d6771..72e7d06d2 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Config-DqTXXH6g.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Config-DPN1ciCe.js
@@ -1,2 +1,2 @@
-const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./CodeEditor-DCw5LkC0.js","./vendor-react-64fcanlc.js","./_commonjsHelpers-CXUWDbkB.js","./index-CUHkLMAp.js","./index-DhY2A0CV.css","./vendor-editor-50h2cCk6.js","./index-DUM-iwa2.js","./daeTokens-BVtuNnWZ.js","./nodes-BYMoo8M1.js","./AppearanceControls-E-VPhjIz.js","./ItemText-CnEXu0-f.js","./logs-C6Kb44nw.js","./Select-BA0NS1_z.js"])))=>i.map(i=>d[i]);
-import{r as e,j as n}from"./vendor-react-64fcanlc.js";import{h as i,u as s,as as a,at as r,r as t,t as o,F as l,ar as c,ch as d,w as u,cj as g,a3 as f,J as p,aQ as m,cf as h,cQ as b,dN as x,dO as v,a7 as j,a6 as y,af as w,aq as k,H as N,cP as S,v as C,A as D,aX as P,B as O,aG as T,E as _,bo as R,al as E,b9 as M,cK as H,m as A,C as F,c as L,bH as I,dP as q,bO as U,cn as W,bP as $,aD as K,dG as V,a as B,b as z,x as Q,z as G,cM as J,aJ as X,c4 as Y,aN as Z,p as ee,_ as ne,T as ie,dQ as se,dR as ae,dS as re}from"./index-CUHkLMAp.js";import{a as te,u as oe,x as le,c as ce,J as de,O as ue,B as ge,K as fe,D as pe,p as me,P as he,S as be,L as xe}from"./logs-C6Kb44nw.js";import{T as ve}from"./Tabs-DiTlqyjA.js";import{aN as je,a4 as ye,ac as we,aO as ke,z as Ne,aP as Se,aQ as Ce,aa as De,D as Pe,a as Oe,aR as Te}from"./activity-B3PmJo_X.js";import{s as _e,U as Re,S as Ee,g as Me,r as He,al as Ae,am as Fe,an as Le,ao as Ie,Q as qe,ap as Ue}from"./nodes-BYMoo8M1.js";import{s as We,c as $e,r as Ke,a as Ve,b as Be,d as ze,e as Qe,f as Ge,g as Je,h as Xe,v as Ye,i as Ze,j as en,k as nn,l as sn,m as an,n as rn,o as tn,w as on}from"./nav-Dn-_mMqu.js";import{u as ln,c as cn}from"./flows-DS-lcTPn.js";import{d as dn}from"./files-Dt8K7QfP.js";import{c as un}from"./limitHint-nHl9AqvH.js";import{D as gn}from"./Table-DX856nrS.js";import{T as fn}from"./TimeCell-N-r54xmV.js";import{N as pn,t as mn}from"./NumberField-C_bakFfF.js";import{A as hn}from"./AddCircle-D2cMd6zF.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./Select-BA0NS1_z.js";import"./ItemText-CnEXu0-f.js";import"./AppearanceControls-E-VPhjIz.js";import"./useGridSelectionCheckbox-CTBMGgmQ.js";import"./Virtualizer-UMC7L0o2.js";import"./Checkbox-8Iqnc6T1.js";function bn(e,n,s,a="main"){if(!s.daeText)return[];const{blocks:r,tokens:t}=_e(e),o=s.globalSettings;return r.flatMap(s=>{if(s.name===o?.name){const a=r.filter(e=>e.name===o.name).indexOf(s),l=Re(e,s,t);return l.filter(e=>1===l.filter(n=>n.name===e.name).length&&o.fields.some(n=>n.key===e.name)).map(r=>({kind:s.name,from:r.from,to:r.to,label:r.name,line:e.slice(0,r.from).split("\n").length,href:i("config",{tab:"global",source:n,section:String(a),field:r.name})}))}const l=We[s.name];return"subscription"===s.name?"main"!==a?[]:Ee(e).filter(e=>e.from>s.open&&e.to<=s.close).map(e=>({kind:s.name,from:e.from,to:e.to,label:e.tag,line:e.line,href:i("nodes",{editSubscriptionTag:e.tag})})):"dns"===s.name?s.children.filter(e=>"routing"===e.name).flatMap(e=>e.children.filter(e=>"request"===e.name||"response"===e.name).map(e=>({kind:s.name,from:e.from,to:e.to,label:e.name,line:e.line+1,href:l}))):l?[{kind:s.name,from:s.from,to:s.to,label:s.name,line:s.line+1,href:l}]:[]})}const xn=()=>{};const vn=new Map;function jn({go:n,query:i}){const h=s(),b=a(),x=r[b],v=t(),j=v.data?.resources,y=oe(o(j,"config",{whileLoading:!0})),w=function(n){const i=s(),a=te(n),r=e.useMemo(()=>{const e=we(a.error);return e?e.diagnostics??[]:null},[a.error]);return e.useEffect(()=>{if(a.error)if(r){const e=ke(r);p("negative",e?i("config.writeRestart",{n:e}):i("ui.writeInvalid",{n:r.filter(e=>"error"===e.level).length}))}else m(a.error,i,i("ui.writeFailed"))},[a.error,r,i]),{...a,diagnostics:r}}(y.refetch),k=e.useMemo(()=>new URLSearchParams(i),[i]),N=e.useMemo(()=>y.data?.sources??[],[y.data]),S=N.find(e=>"main"===e.kind)??null,C=N.find(e=>e.id===k.get("source"))??N[0]??null,D=C?.id??null,P=(e,s)=>n("config",u(i,{tab:"source",source:e,line:null===s?null:String(s)})),O=Number(k.get("line"))||null,T=y.data?.diagnostics??[],_=e.useMemo(()=>{const e=y.data?.diagnostics??[];return{error:e.filter(e=>"error"===e.level).length,warning:e.filter(e=>"warning"===e.level).length}},[y.data]),R=o(j,"config_validate",{whileLoading:!1})&&(j?.config_validate.modes??[]).includes("full"),E=!0===j?.config.writable,M=le(N),H=l().data,A=e.useMemo(()=>Me(H),[H]),F=$e(!!A.globalSettings,c(H),v.data),L=v.data&&un("config",v.data,H,h,b),I=C?Ke(C,E,M(C),A,h,L):null,q=!!C&&!I,[U,W]=e.useState(vn),[$,K]=e.useState(null),V=$??_.error,B=k.has("source")||y.data&&void 0===S?.content?"source":"modules",z=d("validate"===k.get("tab")?u(i,{tab:"source"}):i,F.map(e=>e.id),B),Q=C?{source:C,sources:N,open:P,diagnostics:T,canValidate:R&&("main"===C.kind||"include"===C.kind),canWrite:q,readOnly:I,isComplete:M,editor:w,focusLine:O,generation:y.data?.generation_id??"",focusDiagnostics:"validate"===k.get("tab"),diagnosticsChoice:U.get(C.id)??null,chooseDiagnostics:e=>W(n=>new Map(n).set(C.id,e)),reportErrors:K}:null,G=!0===j?.config.create&&!0===j.config.writable?{sources:N,refetch:y.refetch,open:e=>P(e,null)}:null;return{error:v.error??y.error,reload:()=>{v.refetch(),y.refetch()},loading:y.loading&&!y.data,ready:!!y.data,tabsReady:!!y.data||F.some(e=>"history"===e.id),metadata:y.data?Be(y.data.revision,h):[],redacted:!!y.data?.secrets_redacted,tabs:F.map(e=>({id:e.id,label:"source"===e.id&&V?h("ui.aside",{text:h(e.titleKey),note:f(V,x)}):h(e.titleKey)})),tab:z,setTab:e=>n("config",u(g(i,e,null),{field:null})),selectedId:D??"",select:e=>n("config",u(i,{source:e,line:null})),sourceProps:Q,newSourceProps:G,modulesProps:y.data?{config:y.data}:null,sourceModel:C?{...Ve(C,x,h),readOnly:I}:null,sourceOptions:N.map(e=>{const n=Ve(e,x,h);return{id:n.id,label:n.label,desc:n.kind}}),exportSource:()=>{C&&dn(ye(C),C.content,"text/plain;charset=utf-8")},summaryTone:_.error?"err":_.warning?"warn":"ok",summaryText:_.error?h("config.errors",{n:_.error}):_.warning?h("config.warnings",{n:_.warning}):h("config.clean")}}function yn({source:n,sources:o,diagnostics:c,canValidate:d,canWrite:u,readOnly:g,isComplete:f,editor:m,focusLine:j,generation:y,open:w,diagnosticsChoice:k,chooseDiagnostics:N,reportErrors:S}){const C=s(),D=r[a()],P=Me(l().data),O=t().data?.resources,T=ln(!!j&&!0===O?.rules.available).data,_=cn(!!j&&!0===O?.dns_rules.available).data,R=ce(!!j&&!0===O?.groups.available).data,E=j?He(n.content).find(e=>e.from=j-1):void 0,M=E&&Ne(R,E.name),H=T?.rules.find(e=>e.source?.source_id===n.id&&e.source.line===j),A=_?.request.some(e=>e.source?.source_id===n.id&&e.source.line===j)?"request":"response",F=_?.[A].find(e=>e.source?.source_id===n.id&&e.source.line===j),[L,I]=e.useState(null),[q,U]=e.useState(null),[W,$]=e.useState(null),K=u&&!0===f(n),V=e.useRef(!1),B=m.errorSource===n.id?m.diagnostics:null,z=e.useMemo(()=>B??q??(L?[]:c),[B,q,L,c]);h(y,()=>U(null));const Q=e.useMemo(()=>ze(z,n.id,C),[z,n.id,C]),G=L?.text??n.content??"",J={id:n.id,content:G},[X,Y]=e.useState(null),Z=e.useRef(0),ee=e=>Y(null===e?null:{line:e,key:++Z.current});h(j,()=>Y(null));const ne=null!==L&&L.text!==n.content,ie=ne&&L.origin.content_sha256!==n.content_sha256,se=b(ne,()=>{I(null),U(null)},"config.draftConfig");e.useEffect(()=>m.cancel,[m.cancel,se.revision]);const ae=L?.text,re=function(n,i,s){const a=s?.id,r=s?.content;return e.useMemo(()=>{const e=n.filter(e=>"main"===e.kind||"include"===e.kind);return e.some(e=>void 0===i(e))?null:je(e.filter(e=>i(e)),void 0!==a&&void 0!==r?{id:a,content:r}:void 0)},[n,i,a,r])}(o,f,{id:n.id,content:G});!function(n,i){const{validate:s,cancel:a}=te(xn);e.useEffect(()=>{if(!n)return;let e=!0;const r=setTimeout(()=>{s({sources:n,mode:"full"}).then(n=>{e&&n&&i(n.diagnostics)})},600);return()=>{e=!1,clearTimeout(r),a()}},[n,s,a,i])}(d&&void 0!==ae?re:null,U);const oe=(e,i=!0)=>{U(e.diagnostics);const s=e.diagnostics.find(e=>e.source_id===n.id&&"error"===e.level&&null!==e.line);ee(s?s.line:null);const a=ke(e.diagnostics);return e.valid?i&&p("positive",C("config.valid")):p("negative",a?C("config.writeRestart",{n:a}):C("config.invalid",{n:e.diagnostics.filter(e=>"error"===e.level).length})),e.valid},le=()=>{m.cancel(),I(null),U(null),$(null)},de=g?()=>{V.current||(V.current=!0,p("info",C("config.readOnlyAttempt"),{detail:g.note}))}:void 0,ue=Ve(n,D,C),ge=null!==q||null!==B,fe=e.useMemo(()=>Qe(z,o,D,C,n.id),[z,o,D,C,n.id]),pe=Ge(fe),[me,he]=e.useState("all"),be=Je(fe,me),xe=ne&&!ge;return e.useEffect(()=>S(xe?null:pe.errors),[S,xe,pe.errors]),e.useEffect(()=>()=>S(null),[S]),{writable:K,links:M?[{from:0,to:0,line:j,label:E.name,href:x("policies",M)}]:H||F?[{from:0,to:0,line:j,label:H?.expression??F.expression,href:i("rules",{tab:H?"list":"dns",view:H?"advanced":null,edit:H?.rule_id??F.rule_id,list:H?null:A})}]:bn(G,n.id,P,n.kind),note:g?.note??C(d?"config.editNoteValidate":"config.editNote"),refused:de,diagnostics:{rows:be.rows,errors:pe.errors,warnings:pe.warnings,level:be.level,setLevel:e=>he(e),levels:[["all",C("ui.allCount",{n:pe.errors+pe.warnings+pe.infos})],["error",C("config.levelErrors",{n:pe.errors})],["warning",C("config.levelWarnings",{n:pe.warnings})],["info",C("config.levelInfo",{n:pe.infos})]],scope:ne?C("config.draftDiagnostics"):ge?C("config.fileDiagnostics"):C("config.acceptedDiagnostics",{generation:y}),scopeHelp:ne||ge?void 0:{title:C("ui.generation"),text:C("ui.generationHelp")},quiet:xe?C("config.draftPending"):fe.length?null:C("config.clean"),open:en(pe.errorKeys,k),setOpen:e=>N({open:e,errorKeys:pe.errorKeys}),go:e=>{"jump"===e.action?ee(e.line):"open"===e.action&&w(e.sourceId,e.line)}},restart:ne?Se(B??W??[]):[],restartCommand:P.restartCommand,marks:Q,text:G,names:()=>({groups:De(o,J),upstreams:Ce(o,J)}),focus:X?.line??j,focusKey:X?.key??0,dirty:ne,conflict:ie?C("config.changedOnDisk"):null,keep:()=>I(e=>e&&{...e,origin:n}),validate:async()=>{if(!re)return!1;const e=await m.validate({sources:re,mode:"full"});return!!e&&oe(e)},save:async()=>{if(null===L||m.busy||!K||ie)return;$(null);const e=await m.apply(L.origin,L.text);if(U(null),e){if(e.diagnostics)return $(e.diagnostics),void oe({valid:!1,diagnostics:e.diagnostics},!1);p("positive",C("config.saved",{path:Ve(n,D,C).label})),se.clear(),I(null)}},cancel:le,change:e=>{m.cancel(),e===n.content?le():(U(null),$(null),I(i=>({text:e,origin:i?.origin??n})))},view:ue,busy:!!m.busy,validating:"validate"===m.busy,saving:"save"===m.busy,saveButton:ie?{disabled:!0,tip:C("config.changedOnDisk")}:Ze(m.busy,K,g?.note??null,v,C),validateDisabled:!!m.busy||!re,reason:ne?!K&&g?g.note:"validate"===m.busy?C("config.saveValidating"):Xe({busy:!!m.busy,conflict:!!ie},C):d&&!m.busy?Ye(re,o,f,C):null}}function wn(){const n=s(),i=r[a()],o=w(),d=t().data,u=c(l().data),g=k(u,d),h=oe(!0===d?.resources.config.available),b=de(u,g.revisions),x=ue(u),v=N(),O=S();e.useEffect(()=>()=>O.next(),[O]);const[T,_]=e.useState(null),[R,E]=e.useState(null),M=R&&{...R,...x.pending},[H,A]=e.useState(null),[F,L]=e.useState([]),I=function(e,n,i,s,a,r){const t=!1===n?.recorded;return{unrecorded:t,headNumber:null==r?void 0:f(r,s),rows:(e?.revisions??[]).map(n=>({...n,id:String(n.revision),number:f(n.revision,s),head:n.revision===e?.active,canRestore:i&&(n.revision!==e?.active||t),originText:"import"===n.origin?a("config.revisions.origin.import"):"write"===n.origin?a("config.revisions.origin.write"):"activate"===n.origin?a("config.revisions.origin.activate"):n.origin,size:y(n.bytes,s),metadata:[[a("config.revisions.revision"),f(n.revision,s)],[a("config.revisions.createdAt"),j(n.created_at,s)],[a("config.revisions.parent"),null===n.parent?"—":f(n.parent,s)],[a("config.revisions.principal"),n.principal],[a("config.revisions.hash"),n.content_sha256]]}))}}(b.data,u?.store(h.data),g.canActivate,i,n,M?.head),q=I.rows.find(e=>e.id===T),U=I.rows.find(e=>e.revision===M?.revision),W=()=>{O.next(),E(null)},$=async(e=!1)=>{if(!M||x.busy||(e?!x.pending:x.pending))return;const i=O.start();A(null),L([]);try{const s=e?await x.reread():await x.apply(M.revision,g.replaceRequired,M.head);if(w()!==o||!s)return;if("changed"in s)return void(i()&&(E({revision:M.revision,head:s.changed}),A({id:Date.now(),text:n("config.revisions.changed")})));p("positive",n(null===M.revision?"config.backup.imported":"config.revisions.restored")),i()&&W()}catch(s){if(w()!==o)return;if(m(s,n,n("ui.writeFailed")),i()){if(s instanceof C&&"ui.operationUnknown"===s.key)return;const e=(s instanceof D||s instanceof C?s.details:null)?.diagnostics;L(e??[]);const i=ke(e??[]);A({id:Date.now(),text:i?n("config.writeRestart",{n:i}):P(s,n)})}}};return{management:g,list:b,view:I,detail:q,selected:T,setSelected:_,confirmation:M,target:U,problem:H,diagnostics:Qe(F,[],i,n),busy:!!x.busy,confirmDisabled:!!M?.operation||(null===M?.revision?!g.import:!U?.canRestore),show:e=>{O.next(),A(null),L([]),E(x.pending?{revision:x.pending.revision,head:x.pending.head}:{revision:e,head:b.error?void 0:b.data?.active})},close:W,submit:()=>$(),reread:()=>$(!0),exporting:!!v.busy,exportError:v.error,export:async()=>{if(!u)return;const e=await v.run("export",e=>o.exportConfig(u,e));e&&w()===o&&dn(e.filename,e.content,e.contentType)}}}function kn(){const e=s(),i=wn();return n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"rp-cluster",children:[i.management.export&&n.jsxs(O,{onPress:()=>{i.export()},isPending:i.exporting,children:[n.jsx(Pe,{}),e("config.backup.export")]}),i.management.import&&n.jsx(O,{onPress:()=>i.show(null),children:e("config.backup.import")}),(i.management.export||i.list.data)&&n.jsx(T,{title:e("config.tabHistory"),text:[...i.management.export?[e("config.backup.exportHelp")]:[],...i.list.data?[e("config.revisions.retention",{n:i.list.data.max_revisions})]:[]]})]}),n.jsx(_,{error:i.exportError,message:n=>e("config.backup.exportFailed",{error:n})}),i.view.unrecorded&&n.jsx(R,{tone:"informative",children:e("config.revisions.unrecorded")}),i.management.revisions&&n.jsxs(n.Fragment,{children:[n.jsx(_,{error:i.list.error,onRetry:i.list.refetch}),(i.list.data||i.list.loading)&&n.jsx(n.Fragment,{children:i.view.rows.length||!i.list.data?n.jsx(gn,{label:e("config.tabHistory"),rows:i.view.rows,fit:!0,loading:i.list.loading,selected:i.selected,onSelect:i.setSelected,rowDetail:!0,cols:[{id:"revision",label:e("config.revisions.revision"),minWidth:160,isRowHeader:!0,render:i=>n.jsxs("span",{className:"rp-cluster",children:[i.number,i.head&&n.jsx(ge,{children:e("config.revisions.head")})]})},{id:"created",label:e("config.revisions.createdAt"),minWidth:150,render:e=>n.jsx(fn,{at:e.created_at})},{id:"origin",label:e("config.revisions.origin"),minWidth:110,render:e=>e.originText},{id:"size",label:e("config.revisions.bytes"),minWidth:100,render:e=>e.size}]}):n.jsx(E,{children:e("config.revisions.empty")})})]}),n.jsx(M,{title:e("config.revisions.details"),isOpen:!!i.detail,onOpenChange:e=>{e||i.setSelected(null)},scrollBody:!0,footer:s=>n.jsxs(n.Fragment,{children:[n.jsx(O,{onPress:s,children:e("ui.close")}),i.management.canActivate&&n.jsx(O,{isDisabled:!i.detail?.canRestore,onPress:()=>{i.show(i.detail.revision),i.setSelected(null)},children:e("config.revisions.restore")})]}),children:i.detail&&n.jsxs(n.Fragment,{children:[n.jsx(fe,{items:i.detail.metadata}),n.jsx(H,{title:e("config.revisions.sources"),children:i.detail.sources.map((i,s)=>n.jsx(fe,{items:[[e("config.source"),i.path],[e("config.revisions.hash"),i.sha256]]},s))})]})}),n.jsxs(A,{title:null===i.confirmation?.revision?e("config.backup.importTitle"):e("config.revisions.restoreTitle",{revision:i.target?.number??""}),isOpen:!!i.confirmation,onCancel:i.close,onConfirm:()=>{i.submit()},isPending:i.busy,isDisabled:i.confirmDisabled,confirmLabel:e(null===i.confirmation?.revision?"config.backup.import":"config.revisions.restore"),error:i.problem,scrollBody:!0,children:[n.jsx("p",{children:null===i.confirmation?.revision?e("config.backup.importHelp"):e("config.revisions.restoreHelp")}),i.target&&n.jsx(fe,{items:i.target.metadata.slice(0,2)}),void 0!==i.view.headNumber&&n.jsx(fe,{items:[[e("config.revisions.head"),i.view.headNumber]]}),i.confirmation?.operation&&!i.busy&&n.jsxs(R,{tone:"informative",children:[n.jsx("p",{children:e("ui.operationUnknown")}),n.jsx(O,{onPress:()=>{i.reread()},children:e("ui.refresh")})]}),i.diagnostics.length>0&&n.jsx(gn,{label:e("config.diagnostics"),rows:i.diagnostics,fit:!0,cols:[{id:"message",isRowHeader:!0,label:e("config.diagnostics"),minWidth:220,text:"wrap",render:i=>n.jsxs("span",{children:[i.text,i.backend&&i.backend!==i.message&&n.jsx(pe,{flush:!0,title:e("config.backendText"),children:n.jsx("code",{children:i.backend})})]})}]})]})]})}function Nn({config:i}){const a=s(),r=l().data,t=e.useMemo(()=>Me(r),[r]);return n.jsx("div",{className:"rp-page",children:nn(i.sources,t,a).map(e=>n.jsxs(F,{"aria-label":e.kind,children:[n.jsxs("div",{className:"rp-row",children:[n.jsxs("span",{className:"rp-cluster",children:[n.jsx("h2",{className:"rp-h3 rp-code",children:e.kind}),n.jsx("span",{className:"rp-label rp-code",children:e.range})]}),e.href&&n.jsx(L,{appearance:"button",href:e.href,children:a("config.moduleOpen")})]}),n.jsx("span",{className:"rp-label",children:e.note??e.summary})]},e.id))})}function Sn({settings:e,sources:i,command:r}){const t=s(),o=a();return n.jsx(R,{takeFocus:!0,title:t("config.restart.title",{n:e.length}),action:n.jsxs(n.Fragment,{children:[n.jsx("span",{children:t("config.restart.planned")}),e.map(({key:e,sourceId:s,line:a},r)=>{const o=i.find(e=>e.id===s);return n.jsxs("span",{children:[e&&n.jsx("code",{className:"rp-code",children:e})," ",t("config.restart.effect"),null!==a&&o&&n.jsxs("span",{className:"rp-label",children:[" ",`${ye(o)}:${a}`]})]},r)}),n.jsx("span",{children:t("config.restart.next")}),r&&n.jsxs("span",{className:"rp-cluster",children:[n.jsx("code",{className:"rp-code rp-limit-snippet",children:r}),n.jsx(O,{small:!0,onPress:()=>{(async e=>{const n=await q(e);p(n?"positive":"negative",t(n?"config.restart.copied":"config.restart.copyFailed"))})(r)},children:t("config.restart.copy")})]}),n.jsxs(L,{appearance:"link",external:!0,href:I(o,"reload-and-restart"),children:[t("config.restart.docs"),n.jsx("span",{"aria-hidden":"true",children:"↗"})]})]}),children:t("config.restart.body")})}function Cn({groups:e}){const i=s();return n.jsx("div",{className:"rp-page",children:n.jsxs(B,{children:[n.jsx(W,{page:!0,children:n.jsx("span",{className:"rp-cluster nowrap rp-source-pick",children:n.jsx(z,{width:240})})}),n.jsx("span",{className:"rp-label",children:i("config.globalNote")}),e.map(e=>n.jsx(F,{title:e.title,children:n.jsx(W,{className:"top rp-fieldgrid",children:e.fields.map(e=>n.jsxs("div",{className:"rp-field",inert:!0,"aria-hidden":"true",children:[n.jsx("span",{className:"lbl",children:e.label}),n.jsx(z,{}),n.jsx("span",{className:"rp-label rp-code",children:e.key}),e.hint&&n.jsx("span",{className:"rp-label",children:e.hint})]},e.key))})},e.id)),n.jsx(W,{page:!0,children:n.jsx(z,{width:96})})]})})}function Dn(i){const a=s(),r=function({query:n,go:i}){const a=s(),r=t().data?.resources,c=o(r,"config",{whileLoading:!1}),d=oe(c),g=l().data,f=Me(g),m=f.globalSettings,h=e.useMemo(()=>d.data?.sources??[],[d.data?.sources]),x=le(h),v=e.useMemo(()=>new URLSearchParams(n),[n]),j=h.filter(e=>"main"===e.kind||"include"===e.kind).flatMap(e=>{const n=_e(e.content).blocks.filter(e=>e.name===m?.name);return(n.length?n:"main"===e.kind?[null]:[]).map((n,i)=>({id:`${e.id}:${i}`,source:e,block:n,index:i,label:`${ye(e)}:${n?n.line+1:1}`}))}),y=j.find(e=>e.source.id===v.get("source")&&e.index===Number(v.get("section")??0))??j[0],w=y?.source,k=te(d.refetch),[N,S]=e.useState(null),[D,P]=e.useState(null),O=b(!!N,()=>{S(null),P(null)},"config.draftConfig");e.useEffect(()=>k.cancel,[k.cancel,O.revision]);const T=N?.patch??{},_=N?.source.content??w?.content??"",R=_e(_),E=R.blocks.filter(e=>e.name===m?.name)[y?.index??0],M=E?Re(_,E,R.tokens):[],H=a("ui.listSeparator"),A=(m?.fields??[]).map(e=>{const n=M.filter(n=>n.name===e.key),i=n[0]?sn(e,n[0].value):"",s=T[e.key]??i,r="boolean"===e.type||!!e.choices&&"integer"!==e.type,t="boolean"===e.type?["true","false"]:e.choices??[];return{key:e.key,group:e.group,label:a(e.label),hint:(o=e,"list"===o.type?a("config.globalList"):o.choices&&"integer"===o.type?a("config.globalChoice",{choices:o.choices.join(H)}):o.max&&"18446744073709551615"!==o.max?a("config.globalRange",{max:o.max}):o.units?a("config.globalUnits",{units:o.units.filter(Boolean).join(H)}):void 0),items:r?[{id:"",label:a("config.globalUnset")},...[...t,...s&&!t.includes(s)?[s]:[]].map(e=>({id:e,label:e}))]:null,value:s,number:rn(e)&&/^\d*$/.test(i)?{max:Number(e.max),value:""===s?NaN:Number(s)}:null,duplicate:n.length>1,invalid:null===an(e,s),change:n=>{if(!w||k.busy)return;k.cancel(),P(null);const s={...T,[e.key]:n};n===i&&delete s[e.key],S(Object.keys(s).length?{source:N?.source??w,id:y.id,patch:s}:null)}};var o}),F=!!N&&(N.source.content_sha256!==w?.content_sha256||N.id!==y?.id),L=c&&!d.error&&!!w&&!0===r?.config.writable&&w.writable&&!0===x(w)&&!f.holdsCredentials(w),I=!!k.busy,q=!N||!L||F||A.some(e=>e.key in T&&e.invalid),U=we(k.error)?.diagnostics??null,W=k.error instanceof C&&"ui.writtenNotRead"===k.error.key,$=D??U??null,K=N&&Array.isArray($)?Se($):[],V="global"===v.get("tab")?v.get("field"):null;return Oe(V,()=>{const e=document.getElementById("config-global-form");return e&&V?Te(e,V):null}),{available:c&&!!m,loading:!!d.loading&&!d.data,fields:A,groups:Object.entries(tn).map(([e,n])=>({id:e,title:a(n),fields:A.filter(n=>n.group===e)})).filter(e=>e.fields.length>0),source:w,busy:I,blocked:q,writable:L,dirty:!!N,conflict:F,failure:Array.isArray($)?K.length?null:a("config.invalid",{n:$.filter(e=>"error"===e.level).length}):$,restart:K,restartCommand:f.restartCommand,sources:h,unread:W?a("ui.writtenNotRead"):null,error:(U||W?null:k.error)??d.error,retry:d.refetch,save:async()=>{if(q||I||!m||!y)return;const e=on(N.source.content,m,y.index,T),n=je(h.filter(e=>x(e)),{id:w.id,content:e});if(r?.config_validate.available&&r.config_validate.modes?.includes("full")){if(!n)return void P(a("config.incomplete"));const e=await k.validate({sources:n,mode:"full"});if(!e)return;if(!e.valid)return void P(e.diagnostics)}const i=await k.apply(N.source,e);i&&(i.diagnostics?P(i.diagnostics):(O.clear(),S(null),p("positive",a("config.globalSaved"))))},cancel:()=>{k.cancel(),O.clear(),S(null),P(null)},choices:j.map(({id:e,label:n})=>({id:e,label:n})),selected:y?.id??"",select:e=>{const s=j.find(n=>n.id===e);s&&i("config",u(n,{tab:"global",source:s.source.id,section:String(s.index),field:null}))}}}(i);return r.available?r.loading?n.jsx(Cn,{groups:r.groups}):n.jsxs(U,{id:"config-global-form",className:"rp-page",onSubmit:e=>{e.preventDefault(),r.save()},children:[n.jsx(W,{page:!0,children:n.jsx("span",{className:"rp-cluster nowrap rp-source-pick",children:n.jsx(me,{side:!0,cut:"path",label:a("config.source"),value:r.selected,items:r.choices,onChange:r.select,isDisabled:r.busy||!r.source})})}),n.jsx("span",{className:"rp-label",children:a("config.globalNote")}),r.unread&&n.jsx(R,{tone:"informative",children:r.unread}),n.jsx(_,{error:r.error,onRetry:r.retry}),r.failure&&n.jsx(R,{children:r.failure}),r.restart.length>0&&n.jsx(Sn,{settings:r.restart,sources:r.sources,command:r.restartCommand}),r.conflict&&n.jsx(R,{children:a("config.changedOnDisk")}),r.source&&!r.writable&&n.jsx(R,{tone:"informative",children:a("config.readOnly")}),r.groups.map(e=>n.jsx(F,{title:e.title,children:n.jsx(W,{className:"top rp-fieldgrid",children:e.fields.map(e=>n.jsxs("div",{className:"rp-field","data-setting":e.key,children:[e.items?n.jsx(me,{label:e.label,value:e.value,isDisabled:!r.writable||r.busy||e.duplicate,onChange:e.change,items:e.items}):e.number?n.jsx(pn,{label:e.label,name:e.key,value:e.number.value,onChange:n=>e.change(mn(n)),step:1,isDisabled:!r.writable||r.busy||e.duplicate,placeholder:a("config.globalUnset"),error:e.invalid?a("config.globalRange",{max:e.number.max}):void 0,"aria-describedby":e.hint?`config-global-${e.key}`:void 0}):n.jsx($,{label:e.label,name:e.key,value:e.value,onChange:e.change,isDisabled:!r.writable||r.busy||e.duplicate,placeholder:a("config.globalUnset"),error:e.invalid?a("config.globalInvalid"):void 0,"aria-describedby":e.hint?`config-global-${e.key}`:void 0}),n.jsx(K,{help:"so_mark_from_dae"===e.key?{title:e.label,text:a("config.socketMarkHelp")}:null,children:n.jsx("span",{className:"rp-label rp-code",children:e.key})}),e.hint&&n.jsx("span",{id:`config-global-${e.key}`,className:"rp-label",children:e.hint}),e.duplicate&&n.jsx("span",{className:"rp-label",children:a("config.globalDuplicate")})]},e.key))})},e.id)),n.jsx(W,{page:!0,children:n.jsxs(V,{children:[n.jsx(O,{accent:!0,type:"submit",isPending:r.busy,isDisabled:r.blocked,children:a("config.globalSave")}),r.dirty&&n.jsx(O,{onPress:r.cancel,isDisabled:r.busy,children:a("config.discard")})]})})]}):null}const Pn="config-new-source-form";function On(i){const a=s(),r=function({sources:n,refetch:i,open:a}){const r=s(),t=n.find(e=>"main"===e.kind),o=e.useMemo(()=>t?Ae(t.content):null,[t]),l=e.useMemo(()=>Fe(o??[]),[o]),c=e.useMemo(()=>Le(n),[n]),[d,u]=e.useState(null),[g,f]=e.useState(null),{busy:h,create:b}=he(i),x=S(),v=d?.text??"",j=l.find(e=>e.pattern===d?.pattern)??null,y=j?j.prefix+v+j.suffix:v,w=v?j?Ie(v,j):qe(v):null;return{isOpen:null!==d,show:()=>{x.next(),f(null),u({text:l.length?"":Ue(o??[]),pattern:l[0]?.pattern??""})},hide:()=>{x.next(),u(null)},choices:l,choice:j,setChoice:e=>u(n=>n&&{...n,pattern:e}),text:v,setText:e=>u(n=>n&&{...n,text:e}),error:w?r(w):void 0,unmatched:!!v&&!w&&null!==c&&!c(y),problem:g,busy:h,canSubmit:!!v&&!w&&!h,submit:async e=>{if(!v||w||h)return;const n=x.start();try{const i=await b(y);if(!i)return;if(p("positive",r("config.newSourceCreated",{path:y})),!n())return;e(),i.id&&a(i.id)}catch(i){const e=r("config.newSourceFailed",{path:y});if(n()){const n=Q(i,r,e);f(e=>({id:(e?.id??0)+1,text:G(n,r),kind:n.kind}))}else m(i,r,e)}}}}(i);return n.jsxs(n.Fragment,{children:[n.jsxs(O,{onPress:r.show,children:[n.jsx(hn,{}),a("config.newSource")]}),n.jsxs(M,{title:a("config.newSourceTitle"),narrow:!0,isOpen:r.isOpen,onOpenChange:e=>{e||r.hide()},footer:e=>n.jsxs(n.Fragment,{children:[n.jsx(O,{onPress:e,children:a("ui.cancel")}),n.jsx(O,{accent:!0,type:"submit",form:Pn,isDisabled:!r.canSubmit,isPending:r.busy,children:a("config.newSourceCreate")})]}),children:[r.problem&&n.jsx(J,{problem:r.problem},r.problem.id),n.jsxs(U,{id:Pn,className:"rp-list",onSubmit:e=>{e.preventDefault(),r.submit(r.hide)},children:[n.jsx("span",{className:"rp-label",children:a(r.choice?"config.newSourceNameHelp":"config.newSourceHelp")}),r.choices.length>1&&n.jsx(me,{label:a("config.newSourcePattern"),items:r.choices.map(e=>({id:e.pattern,label:e.pattern})),value:r.choice?.pattern??"",onChange:r.setChoice,isDisabled:r.busy}),r.choice?n.jsx($,{isDisabled:r.busy,label:a("ui.name"),value:r.text,prefix:r.choice.prefix,suffix:r.choice.suffix,placeholder:"extra",spellCheck:!1,error:r.error,onChange:r.setText}):n.jsx($,{isDisabled:r.busy,label:a("config.newSourcePath"),value:r.text,placeholder:"config.d/extra.dae",spellCheck:!1,error:r.error,onChange:r.setText}),r.unmatched&&n.jsx(R,{tone:"informative",children:a("config.newSourceUnmatched")})]})]})]})}function Tn({message:e,busy:i,keep:a,discard:r}){const t=s();return n.jsx(R,{action:(a||r)&&n.jsx(W,{children:n.jsxs(V,{children:[a&&n.jsx(O,{isDisabled:i,onPress:a,children:t("config.keepChanges")}),r&&n.jsx(O,{isDisabled:i,onPress:r,children:t("config.discard")})]})}),children:e})}const _n=ee(()=>ne(()=>import("./CodeEditor-DCw5LkC0.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12]),import.meta.url).then(e=>({default:e.CodeEditor}))),Rn=[{block:560}];function En(i){const{canValidate:r}=i,t=s(),o=a(),{writable:l,links:c,diagnostics:d,note:u,refused:g,restart:f,restartCommand:p,marks:m,text:h,names:b,focus:x,focusKey:v,dirty:j,conflict:y,keep:w,validate:k,save:N,cancel:S,change:C,view:D,busy:P,validating:_,saving:R,saveButton:E,validateDisabled:M,reason:H}=yn(i),A=e.useRef(null),q=e.useRef(!1),U=()=>{q.current&&A.current&&(q.current=!1,A.current.focus(),A.current.scrollIntoView({block:"nearest"}))};e.useEffect(()=>{q.current=!!i.focusDiagnostics,U()},[i.focusDiagnostics,i.focusLine,i.source.id]);const $=function(e,n,i){return e.filter(e=>e.line===n||n&&e.line<=n&&i.slice(0,e.to).split("\n").length>=n)}(c,x,h),K=$.length?$:c,V=n.jsx(W,{"aria-label":t("config.forms"),children:K.map(e=>n.jsx(L,{appearance:"button",href:e.href,children:e.label},e.from))}),B=n.jsx("div",{ref:A,tabIndex:-1,role:"region","aria-label":t("config.diagnostics"),className:"rp-config-diagnostics",children:d.quiet?n.jsx("span",{className:"rp-config-diagnostics-quiet rp-label",children:d.quiet}):n.jsxs(pe,{aside:d.scopeHelp&&n.jsx(T,{...d.scopeHelp}),isExpanded:d.open,onExpandedChange:d.setOpen,title:n.jsxs("span",{className:"rp-config-diagnostics-summary",children:[n.jsx(ge,{tone:d.errors?"negative":void 0,children:t("config.levelErrors",{n:d.errors})}),n.jsx(ge,{tone:d.warnings?"warn":void 0,children:t("config.levelWarnings",{n:d.warnings})}),n.jsx("span",{className:"rp-label",children:d.scope})]}),children:[n.jsx("div",{className:"rp-config-diagnostic-filter",children:n.jsx(be,{label:t("config.level"),value:d.level,onChange:d.setLevel,items:d.levels})}),n.jsx("div",{className:"rp-config-diagnostic-list",role:"list","aria-label":t("config.diagnostics"),children:d.rows.map(e=>n.jsxs("div",{className:"rp-config-diagnostic",role:"listitem",children:[n.jsxs(xe,{small:!0,tone:e.tone,children:[n.jsx(X,{children:`${e.levelText} `}),e.text]}),e.backend&&n.jsx(pe,{flush:!0,title:t("config.backendText"),children:n.jsx("code",{children:e.backend})}),e.offline&&n.jsx(Y,{link:{href:I(o,"offline-dependency"),text:t("ov.lim.docsOffline"),external:!0}}),e.action&&n.jsx(O,{small:!0,className:"rp-config-diagnostic-go",label:"jump"===e.action?t("config.jumpToLine",{line:e.line}):t("config.openSourceAt",{where:e.where}),onPress:()=>d.go(e),children:t("jump"===e.action?"cm.go":"config.openSource")})]},e.id))})]})}),z=[...r?[{id:"validate",label:t("config.validate"),isPending:_,isDisabled:M,reason:H??void 0,onAction:()=>{k()}}]:[],...j?[{id:"cancel",label:t("ui.cancel"),isDisabled:P,onAction:S},{id:"save",label:t("config.save"),accent:!0,isPending:R,isDisabled:E.disabled,reason:E.tip??H??void 0,onAction:()=>{N()}}]:[]];return n.jsxs(F,{title:t("config.editor"),className:"rp-source-card","aria-label":D.label,help:l?{title:t("config.editor"),text:t("config.writeHelp")}:void 0,reason:H,children:[n.jsx("div",{className:"rp-row rp-source-note",children:n.jsx("span",{className:"rp-cluster",children:j?n.jsxs(n.Fragment,{children:[n.jsx(ge,{tone:"warn",children:t("config.unsaved")}),n.jsx("span",{className:"rp-label",children:t("config.unsavedHint")})]}):n.jsx("span",{className:"rp-label",children:u})})}),y&&n.jsx(Tn,{message:y,busy:P,keep:w}),f.length>0&&n.jsx(Sn,{settings:f,sources:i.sources,command:p}),$.length?V:c.length>0&&n.jsx(pe,{title:t("config.forms"),children:V}),n.jsxs(e.Suspense,{fallback:n.jsx(Z,{panel:!0,shape:Rn}),children:[n.jsx(_n.Component,{actions:z,label:D.label,value:h,readOnly:!l||P,onChange:C,onReadOnlyAttempt:g,marks:m,focusLine:x,focusKey:v,banner:B,names:b,onSave:j&&!P?()=>{N()}:void 0}),n.jsx(Mn,{run:U})]})]})}function Mn({run:n}){const i=e.useRef(n);return e.useEffect(()=>i.current(),[]),null}const Hn=[{toolbar:1,height:16},...Rn];function An(i){const a=s(),{error:r,reload:t,loading:o,ready:l,tabsReady:c,metadata:d,redacted:u,tabs:g,tab:f,setTab:p,selectedId:m,select:h,sourceProps:b,newSourceProps:x,modulesProps:v,sourceModel:j,sourceOptions:y,exportSource:w,summaryTone:k,summaryText:N}=jn(i);e.useEffect(()=>{"source"===f&&_n.preload().catch(()=>{})},[f]);const S={history:n.jsx(kn,{}),modules:v?n.jsx(Nn,{...v}):o&&n.jsx(Z,{panel:!0,shape:se}),global:n.jsx(Dn,{...i}),source:n.jsxs(n.Fragment,{children:[n.jsxs(W,{page:!0,children:[n.jsxs("span",{className:"rp-cluster nowrap rp-source-pick",children:[n.jsx(me,{side:!0,cut:"path",label:a("config.source"),value:m,onChange:h,items:y}),j&&n.jsxs(n.Fragment,{children:[j.readOnly&&n.jsx(K,{help:j.readOnly.help,children:n.jsx(ge,{children:j.readOnly.label})}),n.jsx(ie,{className:"rp-label",text:j.loaded,children:j.facts})]})]}),(x||j)&&n.jsxs("span",{className:"rp-cluster nowrap",children:[x&&n.jsx(On,{...x}),j&&n.jsxs(O,{onPress:w,children:[n.jsx(Pe,{}),a("config.export")]})]})]}),j&&n.jsx("span",{className:"rp-label",children:a("config.exportWarning")}),b?n.jsx(En,{...b},j.id):o&&n.jsx(Z,{panel:!0,shape:Hn})]})};return n.jsxs("div",{className:"rp-page",children:[n.jsx(_,{error:r,onRetry:t}),o&&n.jsx(Z,{shape:c?ae:re}),l&&n.jsxs(W,{page:!0,children:[n.jsx(fe,{row:!0,items:d}),n.jsx(xe,{small:!0,tone:k,children:N}),u&&n.jsx(xe,{small:!0,tone:"muted",children:a("config.redacted")})]}),c&&n.jsx(ve,{page:!0,label:a("nav.config"),value:f,onChange:p,items:g.map(e=>({...e,content:S[e.id]}))})]})}export{An as Config};
+const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./CodeEditor-9GVA7w36.js","./vendor-react-64fcanlc.js","./_commonjsHelpers-CXUWDbkB.js","./index-C06va4Yw.js","./index-DdIDwpAM.css","./vendor-editor-50h2cCk6.js","./index-DUM-iwa2.js","./daeTokens-BVtuNnWZ.js","./nodes-oXccX15o.js","./AppearanceControls-CEVO9-aR.js","./ItemText-D6SGBgOi.js","./logs-BtAlqVqe.js","./Select-hQ95uOjm.js"])))=>i.map(i=>d[i]);
+import{r as e,j as n}from"./vendor-react-64fcanlc.js";import{h as i,u as s,as as a,at as r,r as t,t as o,F as l,ar as c,ci as d,w as u,ck as g,a3 as f,J as p,aQ as m,cg as h,cS as b,dP as x,dQ as v,a7 as j,a6 as y,af as w,aq as k,H as N,cR as S,v as C,A as D,aX as P,B as T,aG as O,E as R,bp as _,al as E,ba as M,cL as A,m as F,C as H,c as L,bI as I,dR as q,bP as W,co as $,bQ as U,aD as K,dI as V,a as B,b as z,x as Q,z as J,cN as G,aJ as X,c5 as Y,aN as Z,p as ee,_ as ne,T as ie,dS as se,dT as ae,dU as re}from"./index-C06va4Yw.js";import{a as te,u as oe,x as le,c as ce,J as de,O as ue,B as ge,K as fe,D as pe,p as me,P as he,S as be,L as xe}from"./logs-BtAlqVqe.js";import{T as ve}from"./Tabs-PDr10lJU.js";import{aM as je,a3 as ye,ab as we,aN as ke,z as Ne,aO as Se,aP as Ce,a9 as De,D as Pe,a as Te,aQ as Oe}from"./activity-BoXvjA12.js";import{s as Re,S as _e,R as Ee,g as Me,r as Ae,ak as Fe,al as He,am as Le,an as Ie,P as qe,ao as We}from"./nodes-oXccX15o.js";import{s as $e,c as Ue,r as Ke,a as Ve,b as Be,d as ze,e as Qe,f as Je,g as Ge,h as Xe,v as Ye,i as Ze,j as en,k as nn,l as sn,m as an,n as rn,o as tn,w as on}from"./nav-BvgMebTJ.js";import{u as ln,c as cn}from"./flows-C0jcpIhs.js";import{d as dn}from"./files-Dt8K7QfP.js";import{c as un}from"./limitHint-Cb7NYoro.js";import{D as gn}from"./Table-Cc5T3jJO.js";import{T as fn}from"./TimeCell-DSeESBN3.js";import{N as pn,t as mn}from"./NumberField-C8qnuOCX.js";import{A as hn}from"./AddCircle-6b-rL1eo.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./Select-hQ95uOjm.js";import"./ItemText-D6SGBgOi.js";import"./AppearanceControls-CEVO9-aR.js";import"./useGridSelectionCheckbox-inhSeUkV.js";import"./Virtualizer-9R4wsZhf.js";import"./Checkbox-CsFZSc5N.js";function bn(e,n,s,a="main"){if(!s.daeText)return[];const{blocks:r,tokens:t}=Re(e),o=s.globalSettings;return r.flatMap(s=>{if(s.name===o?.name){const a=r.filter(e=>e.name===o.name).indexOf(s),l=_e(e,s,t);return l.filter(e=>1===l.filter(n=>n.name===e.name).length&&o.fields.some(n=>n.key===e.name)).map(r=>({kind:s.name,from:r.from,to:r.to,label:r.name,line:e.slice(0,r.from).split("\n").length,href:i("config",{tab:"global",source:n,section:String(a),field:r.name})}))}const l=$e[s.name];return"subscription"===s.name?"main"!==a?[]:Ee(e).filter(e=>e.from>s.open&&e.to<=s.close).map(e=>({kind:s.name,from:e.from,to:e.to,label:e.tag,line:e.line,href:i("nodes",{editSubscriptionTag:e.tag})})):"dns"===s.name?s.children.filter(e=>"routing"===e.name).flatMap(e=>e.children.filter(e=>"request"===e.name||"response"===e.name).map(e=>({kind:s.name,from:e.from,to:e.to,label:e.name,line:e.line+1,href:l}))):l?[{kind:s.name,from:s.from,to:s.to,label:s.name,line:s.line+1,href:l}]:[]})}const xn=()=>{};const vn=new Map;function jn({go:n,query:i}){const h=s(),b=a(),x=r[b],v=t(),j=v.data?.resources,y=oe(o(j,"config",{whileLoading:!0})),w=function(n){const i=s(),a=te(n),r=e.useMemo(()=>{const e=we(a.error);return e?e.diagnostics??[]:null},[a.error]);return e.useEffect(()=>{if(a.error)if(r){const e=ke(r);p("negative",e?i("config.writeRestart",{n:e}):i("ui.writeInvalid",{n:r.filter(e=>"error"===e.level).length}))}else m(a.error,i,i("ui.writeFailed"))},[a.error,r,i]),{...a,diagnostics:r}}(y.refetch),k=e.useMemo(()=>new URLSearchParams(i),[i]),N=e.useMemo(()=>y.data?.sources??[],[y.data]),S=N.find(e=>"main"===e.kind)??null,C=N.find(e=>e.id===k.get("source"))??N[0]??null,D=C?.id??null,P=(e,s)=>n("config",u(i,{tab:"source",source:e,line:null===s?null:String(s)})),T=Number(k.get("line"))||null,O=y.data?.diagnostics??[],R=e.useMemo(()=>{const e=y.data?.diagnostics??[];return{error:e.filter(e=>"error"===e.level).length,warning:e.filter(e=>"warning"===e.level).length}},[y.data]),_=o(j,"config_validate",{whileLoading:!1})&&(j?.config_validate.modes??[]).includes("full"),E=!0===j?.config.writable,M=le(N),A=l().data,F=e.useMemo(()=>Me(A),[A]),H=Ue(!!F.globalSettings,c(A),v.data),L=v.data&&un("config",v.data,A,h,b),I=C?Ke(C,E,M(C),F,h,L):null,q=!!C&&!I,[W,$]=e.useState(vn),[U,K]=e.useState(null),V=U??R.error,B=k.has("source")||y.data&&void 0===S?.content?"source":"modules",z=d("validate"===k.get("tab")?u(i,{tab:"source"}):i,H.map(e=>e.id),B),Q=C?{source:C,sources:N,open:P,diagnostics:O,canValidate:_&&("main"===C.kind||"include"===C.kind),canWrite:q,readOnly:I,isComplete:M,editor:w,focusLine:T,generation:y.data?.generation_id??"",focusDiagnostics:"validate"===k.get("tab"),diagnosticsChoice:W.get(C.id)??null,chooseDiagnostics:e=>$(n=>new Map(n).set(C.id,e)),reportErrors:K}:null,J=!0===j?.config.create&&!0===j.config.writable?{sources:N,refetch:y.refetch,open:e=>P(e,null)}:null;return{error:v.error??y.error,reload:()=>{v.refetch(),y.refetch()},loading:y.loading&&!y.data,ready:!!y.data,tabsReady:!!y.data||H.some(e=>"history"===e.id),metadata:y.data?Be(y.data.revision,h):[],redacted:!!y.data?.secrets_redacted,tabs:H.map(e=>({id:e.id,label:"source"===e.id&&V?h("ui.aside",{text:h(e.titleKey),note:f(V,x)}):h(e.titleKey)})),tab:z,setTab:e=>n("config",u(g(i,e,null),{field:null})),selectedId:D??"",select:e=>n("config",u(i,{source:e,line:null})),sourceProps:Q,newSourceProps:J,modulesProps:y.data?{config:y.data}:null,sourceModel:C?{...Ve(C,x,h),readOnly:I}:null,sourceOptions:N.map(e=>{const n=Ve(e,x,h);return{id:n.id,label:n.label,desc:n.kind}}),exportSource:()=>{C&&dn(ye(C),C.content,"text/plain;charset=utf-8")},summaryTone:R.error?"err":R.warning?"warn":"ok",summaryText:R.error?h("config.errors",{n:R.error}):R.warning?h("config.warnings",{n:R.warning}):h("config.clean")}}function yn({source:n,sources:o,diagnostics:c,canValidate:d,canWrite:u,readOnly:g,isComplete:f,editor:m,focusLine:j,generation:y,open:w,diagnosticsChoice:k,chooseDiagnostics:N,reportErrors:S}){const C=s(),D=r[a()],P=Me(l().data),T=t().data?.resources,O=ln(!!j&&!0===T?.rules.available).data,R=cn(!!j&&!0===T?.dns_rules.available).data,_=ce(!!j&&!0===T?.groups.available).data,E=j?Ae(n.content).find(e=>e.from=j-1):void 0,M=E&&Ne(_,E.name),A=O?.rules.find(e=>e.source?.source_id===n.id&&e.source.line===j),F=R?.request.some(e=>e.source?.source_id===n.id&&e.source.line===j)?"request":"response",H=R?.[F].find(e=>e.source?.source_id===n.id&&e.source.line===j),[L,I]=e.useState(null),[q,W]=e.useState(null),[$,U]=e.useState(null),K=u&&!0===f(n),V=e.useRef(!1),B=m.errorSource===n.id?m.diagnostics:null,z=e.useMemo(()=>B??q??(L?[]:c),[B,q,L,c]);h(y,()=>W(null));const Q=e.useMemo(()=>ze(z,n.id,C),[z,n.id,C]),J=L?.text??n.content??"",G={id:n.id,content:J},[X,Y]=e.useState(null),Z=e.useRef(0),ee=e=>Y(null===e?null:{line:e,key:++Z.current});h(j,()=>Y(null));const ne=null!==L&&L.text!==n.content,ie=ne&&L.origin.content_sha256!==n.content_sha256,se=b(ne,()=>{I(null),W(null)},"config.draftConfig");e.useEffect(()=>m.cancel,[m.cancel,se.revision]);const ae=L?.text,re=function(n,i,s){const a=s?.id,r=s?.content;return e.useMemo(()=>{const e=n.filter(e=>"main"===e.kind||"include"===e.kind);return e.some(e=>void 0===i(e))?null:je(e.filter(e=>i(e)),void 0!==a&&void 0!==r?{id:a,content:r}:void 0)},[n,i,a,r])}(o,f,{id:n.id,content:J});!function(n,i){const{validate:s,cancel:a}=te(xn);e.useEffect(()=>{if(!n)return;let e=!0;const r=setTimeout(()=>{s({sources:n,mode:"full"}).then(n=>{e&&n&&i(n.diagnostics)})},600);return()=>{e=!1,clearTimeout(r),a()}},[n,s,a,i])}(d&&void 0!==ae?re:null,W);const oe=(e,i=!0)=>{W(e.diagnostics);const s=e.diagnostics.find(e=>e.source_id===n.id&&"error"===e.level&&null!==e.line);ee(s?s.line:null);const a=ke(e.diagnostics);return e.valid?i&&p("positive",C("config.valid")):p("negative",a?C("config.writeRestart",{n:a}):C("config.invalid",{n:e.diagnostics.filter(e=>"error"===e.level).length})),e.valid},le=()=>{m.cancel(),I(null),W(null),U(null)},de=g?()=>{V.current||(V.current=!0,p("info",C("config.readOnlyAttempt"),{detail:g.note}))}:void 0,ue=Ve(n,D,C),ge=null!==q||null!==B,fe=e.useMemo(()=>Qe(z,o,D,C,n.id),[z,o,D,C,n.id]),pe=Je(fe),[me,he]=e.useState("all"),be=Ge(fe,me),xe=ne&&!ge;return e.useEffect(()=>S(xe?null:pe.errors),[S,xe,pe.errors]),e.useEffect(()=>()=>S(null),[S]),{writable:K,links:M?[{from:0,to:0,line:j,label:E.name,href:x("policies",M)}]:A||H?[{from:0,to:0,line:j,label:A?.expression??H.expression,href:i("rules",{tab:A?"list":"dns",view:A?"advanced":null,edit:A?.rule_id??H.rule_id,list:A?null:F})}]:bn(J,n.id,P,n.kind),note:g?.note??C(d?"config.editNoteValidate":"config.editNote"),refused:de,diagnostics:{rows:be.rows,errors:pe.errors,warnings:pe.warnings,level:be.level,setLevel:e=>he(e),levels:[["all",C("ui.allCount",{n:pe.errors+pe.warnings+pe.infos})],["error",C("config.levelErrors",{n:pe.errors})],["warning",C("config.levelWarnings",{n:pe.warnings})],["info",C("config.levelInfo",{n:pe.infos})]],scope:ne?C("config.draftDiagnostics"):ge?C("config.fileDiagnostics"):C("config.acceptedDiagnostics",{generation:y}),scopeHelp:ne||ge?void 0:{title:C("ui.generation"),text:C("ui.generationHelp")},quiet:xe?C("config.draftPending"):fe.length?null:C("config.clean"),open:en(pe.errorKeys,k),setOpen:e=>N({open:e,errorKeys:pe.errorKeys}),go:e=>{"jump"===e.action?ee(e.line):"open"===e.action&&w(e.sourceId,e.line)}},restart:ne?Se(B??$??[]):[],restartCommand:P.restartCommand,marks:Q,text:J,names:()=>({groups:De(o,G),upstreams:Ce(o,G)}),focus:X?.line??j,focusKey:X?.key??0,dirty:ne,conflict:ie?C("config.changedOnDisk"):null,keep:()=>I(e=>e&&{...e,origin:n}),validate:async()=>{if(!re)return!1;const e=await m.validate({sources:re,mode:"full"});return!!e&&oe(e)},save:async()=>{if(null===L||m.busy||!K||ie)return;U(null);const e=await m.apply(L.origin,L.text);if(W(null),e){if(e.diagnostics)return U(e.diagnostics),void oe({valid:!1,diagnostics:e.diagnostics},!1);p("positive",C("config.saved",{path:Ve(n,D,C).label})),se.clear(),I(null)}},cancel:le,change:e=>{m.cancel(),e===n.content?le():(W(null),U(null),I(i=>({text:e,origin:i?.origin??n})))},view:ue,busy:!!m.busy,validating:"validate"===m.busy,saving:"save"===m.busy,saveButton:ie?{disabled:!0,tip:C("config.changedOnDisk")}:Ze(m.busy,K,g?.note??null,v,C),validateDisabled:!!m.busy||!re,reason:ne?!K&&g?g.note:"validate"===m.busy?C("config.saveValidating"):Xe({busy:!!m.busy,conflict:!!ie},C):d&&!m.busy?Ye(re,o,f,C):null}}function wn(){const n=s(),i=r[a()],o=w(),d=t().data,u=c(l().data),g=k(u,d),h=oe(!0===d?.resources.config.available),b=de(u,g.revisions),x=ue(u),v=N(),T=S();e.useEffect(()=>()=>T.next(),[T]);const[O,R]=e.useState(null),[_,E]=e.useState(null),M=_&&{..._,...x.pending},[A,F]=e.useState(null),[H,L]=e.useState([]),I=function(e,n,i,s,a,r){const t=!1===n?.recorded;return{unrecorded:t,headNumber:null==r?void 0:f(r,s),rows:(e?.revisions??[]).map(n=>({...n,id:String(n.revision),number:f(n.revision,s),head:n.revision===e?.active,canRestore:i&&(n.revision!==e?.active||t),originText:"import"===n.origin?a("config.revisions.origin.import"):"write"===n.origin?a("config.revisions.origin.write"):"activate"===n.origin?a("config.revisions.origin.activate"):n.origin,size:y(n.bytes,s),metadata:[[a("config.revisions.revision"),f(n.revision,s)],[a("config.revisions.createdAt"),j(n.created_at,s)],[a("config.revisions.parent"),null===n.parent?"—":f(n.parent,s)],[a("config.revisions.principal"),n.principal],[a("config.revisions.hash"),n.content_sha256]]}))}}(b.data,u?.store(h.data),g.canActivate,i,n,M?.head),q=I.rows.find(e=>e.id===O),W=I.rows.find(e=>e.revision===M?.revision),$=()=>{T.next(),E(null)},U=async(e=!1)=>{if(!M||x.busy||(e?!x.pending:x.pending))return;const i=T.start();F(null),L([]);try{const s=e?await x.reread():await x.apply(M.revision,g.replaceRequired,M.head);if(w()!==o||!s)return;if("changed"in s)return void(i()&&(E({revision:M.revision,head:s.changed}),F({id:Date.now(),text:n("config.revisions.changed")})));p("positive",n(null===M.revision?"config.backup.imported":"config.revisions.restored")),i()&&$()}catch(s){if(w()!==o)return;if(m(s,n,n("ui.writeFailed")),i()){if(s instanceof C&&"ui.operationUnknown"===s.key)return;const e=(s instanceof D||s instanceof C?s.details:null)?.diagnostics;L(e??[]);const i=ke(e??[]);F({id:Date.now(),text:i?n("config.writeRestart",{n:i}):P(s,n)})}}};return{management:g,list:b,view:I,detail:q,selected:O,setSelected:R,confirmation:M,target:W,problem:A,diagnostics:Qe(H,[],i,n),busy:!!x.busy,confirmDisabled:!!M?.operation||(null===M?.revision?!g.import:!W?.canRestore),show:e=>{T.next(),F(null),L([]),E(x.pending?{revision:x.pending.revision,head:x.pending.head}:{revision:e,head:b.error?void 0:b.data?.active})},close:$,submit:()=>U(),reread:()=>U(!0),exporting:!!v.busy,exportError:v.error,export:async()=>{if(!u)return;const e=await v.run("export",e=>o.exportConfig(u,e));e&&w()===o&&dn(e.filename,e.content,e.contentType)}}}function kn(){const e=s(),i=wn();return n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"rp-cluster",children:[i.management.export&&n.jsxs(T,{onPress:()=>{i.export()},isPending:i.exporting,children:[n.jsx(Pe,{}),e("config.backup.export")]}),i.management.import&&n.jsx(T,{onPress:()=>i.show(null),children:e("config.backup.import")}),(i.management.export||i.list.data)&&n.jsx(O,{title:e("config.tabHistory"),text:[...i.management.export?[e("config.backup.exportHelp")]:[],...i.list.data?[e("config.revisions.retention",{n:i.list.data.max_revisions})]:[]]})]}),n.jsx(R,{error:i.exportError,message:n=>e("config.backup.exportFailed",{error:n})}),i.view.unrecorded&&n.jsx(_,{tone:"informative",children:e("config.revisions.unrecorded")}),i.management.revisions&&n.jsxs(n.Fragment,{children:[n.jsx(R,{error:i.list.error,onRetry:i.list.refetch}),(i.list.data||i.list.loading)&&n.jsx(n.Fragment,{children:i.view.rows.length||!i.list.data?n.jsx(gn,{label:e("config.tabHistory"),rows:i.view.rows,fit:!0,loading:i.list.loading,selected:i.selected,onSelect:i.setSelected,rowDetail:!0,cols:[{id:"revision",label:e("config.revisions.revision"),minWidth:160,isRowHeader:!0,render:i=>n.jsxs("span",{className:"rp-cluster",children:[i.number,i.head&&n.jsx(ge,{children:e("config.revisions.head")})]})},{id:"created",label:e("config.revisions.createdAt"),minWidth:150,render:e=>n.jsx(fn,{at:e.created_at})},{id:"origin",label:e("config.revisions.origin"),minWidth:110,render:e=>e.originText},{id:"size",label:e("config.revisions.bytes"),minWidth:100,render:e=>e.size}]}):n.jsx(E,{children:e("config.revisions.empty")})})]}),n.jsx(M,{title:e("config.revisions.details"),isOpen:!!i.detail,onOpenChange:e=>{e||i.setSelected(null)},scrollBody:!0,footer:s=>n.jsxs(n.Fragment,{children:[n.jsx(T,{onPress:s,children:e("ui.close")}),i.management.canActivate&&n.jsx(T,{isDisabled:!i.detail?.canRestore,onPress:()=>{i.show(i.detail.revision),i.setSelected(null)},children:e("config.revisions.restore")})]}),children:i.detail&&n.jsxs(n.Fragment,{children:[n.jsx(fe,{items:i.detail.metadata}),n.jsx(A,{title:e("config.revisions.sources"),children:i.detail.sources.map((i,s)=>n.jsx(fe,{items:[[e("config.source"),i.path],[e("config.revisions.hash"),i.sha256]]},s))})]})}),n.jsxs(F,{title:null===i.confirmation?.revision?e("config.backup.importTitle"):e("config.revisions.restoreTitle",{revision:i.target?.number??""}),isOpen:!!i.confirmation,onCancel:i.close,onConfirm:()=>{i.submit()},isPending:i.busy,isDisabled:i.confirmDisabled,confirmLabel:e(null===i.confirmation?.revision?"config.backup.import":"config.revisions.restore"),error:i.problem,scrollBody:!0,children:[n.jsx("p",{children:null===i.confirmation?.revision?e("config.backup.importHelp"):e("config.revisions.restoreHelp")}),i.target&&n.jsx(fe,{items:i.target.metadata.slice(0,2)}),void 0!==i.view.headNumber&&n.jsx(fe,{items:[[e("config.revisions.head"),i.view.headNumber]]}),i.confirmation?.operation&&!i.busy&&n.jsxs(_,{tone:"informative",children:[n.jsx("p",{children:e("ui.operationUnknown")}),n.jsx(T,{onPress:()=>{i.reread()},children:e("ui.refresh")})]}),i.diagnostics.length>0&&n.jsx(gn,{label:e("config.diagnostics"),rows:i.diagnostics,fit:!0,cols:[{id:"message",isRowHeader:!0,label:e("config.diagnostics"),minWidth:220,text:"wrap",render:i=>n.jsxs("span",{children:[i.text,i.backend&&i.backend!==i.message&&n.jsx(pe,{flush:!0,title:e("config.backendText"),children:n.jsx("code",{children:i.backend})})]})}]})]})]})}function Nn({config:i}){const a=s(),r=l().data,t=e.useMemo(()=>Me(r),[r]);return n.jsx("div",{className:"rp-page",children:nn(i.sources,t,a).map(e=>n.jsxs(H,{"aria-label":e.kind,children:[n.jsxs("div",{className:"rp-row",children:[n.jsxs("span",{className:"rp-cluster",children:[n.jsx("h2",{className:"rp-h3 rp-code",children:e.kind}),n.jsx("span",{className:"rp-label rp-code",children:e.range})]}),e.href&&n.jsx(L,{appearance:"button",href:e.href,children:a("config.moduleOpen")})]}),n.jsx("span",{className:"rp-label",children:e.note??e.summary})]},e.id))})}function Sn({settings:e,sources:i,command:r}){const t=s(),o=a();return n.jsx(_,{takeFocus:!0,title:t("config.restart.title",{n:e.length}),action:n.jsxs(n.Fragment,{children:[n.jsx("span",{children:t("config.restart.planned")}),e.map(({key:e,sourceId:s,line:a},r)=>{const o=i.find(e=>e.id===s);return n.jsxs("span",{children:[e&&n.jsx("code",{className:"rp-code",children:e})," ",t("config.restart.effect"),null!==a&&o&&n.jsxs("span",{className:"rp-label",children:[" ",`${ye(o)}:${a}`]})]},r)}),n.jsx("span",{children:t("config.restart.next")}),r&&n.jsxs("span",{className:"rp-cluster",children:[n.jsx("code",{className:"rp-code rp-limit-snippet",children:r}),n.jsx(T,{small:!0,onPress:()=>{(async e=>{const n=await q(e);p(n?"positive":"negative",t(n?"config.restart.copied":"config.restart.copyFailed"))})(r)},children:t("config.restart.copy")})]}),n.jsxs(L,{appearance:"link",external:!0,href:I(o,"reload-and-restart"),children:[t("config.restart.docs"),n.jsx("span",{"aria-hidden":"true",children:"↗"})]})]}),children:t("config.restart.body")})}function Cn({groups:e}){const i=s();return n.jsx("div",{className:"rp-page",children:n.jsxs(B,{children:[n.jsx($,{page:!0,children:n.jsx("span",{className:"rp-cluster nowrap rp-source-pick",children:n.jsx(z,{width:240})})}),n.jsx("span",{className:"rp-label",children:i("config.globalNote")}),e.map(e=>n.jsx(H,{title:e.title,children:n.jsx($,{className:"top rp-fieldgrid",children:e.fields.map(e=>n.jsxs("div",{className:"rp-field",inert:!0,"aria-hidden":"true",children:[n.jsx("span",{className:"lbl",children:e.label}),n.jsx(z,{}),n.jsx("span",{className:"rp-label rp-code",children:e.key}),e.hint&&n.jsx("span",{className:"rp-label",children:e.hint})]},e.key))})},e.id)),n.jsx($,{page:!0,children:n.jsx(z,{width:96})})]})})}function Dn(i){const a=s(),r=function({query:n,go:i}){const a=s(),r=t().data?.resources,c=o(r,"config",{whileLoading:!1}),d=oe(c),g=l().data,f=Me(g),m=f.globalSettings,h=e.useMemo(()=>d.data?.sources??[],[d.data?.sources]),x=le(h),v=e.useMemo(()=>new URLSearchParams(n),[n]),j=h.filter(e=>"main"===e.kind||"include"===e.kind).flatMap(e=>{const n=Re(e.content).blocks.filter(e=>e.name===m?.name);return(n.length?n:"main"===e.kind?[null]:[]).map((n,i)=>({id:`${e.id}:${i}`,source:e,block:n,index:i,label:`${ye(e)}:${n?n.line+1:1}`}))}),y=j.find(e=>e.source.id===v.get("source")&&e.index===Number(v.get("section")??0))??j[0],w=y?.source,k=te(d.refetch),[N,S]=e.useState(null),[D,P]=e.useState(null),T=b(!!N,()=>{S(null),P(null)},"config.draftConfig");e.useEffect(()=>k.cancel,[k.cancel,T.revision]);const O=N?.patch??{},R=N?.source.content??w?.content??"",_=Re(R),E=_.blocks.filter(e=>e.name===m?.name)[y?.index??0],M=E?_e(R,E,_.tokens):[],A=a("ui.listSeparator"),F=(m?.fields??[]).map(e=>{const n=M.filter(n=>n.name===e.key),i=n[0]?sn(e,n[0].value):"",s=O[e.key]??i,r="boolean"===e.type||!!e.choices&&"integer"!==e.type,t="boolean"===e.type?["true","false"]:e.choices??[];return{key:e.key,group:e.group,label:a(e.label),hint:(o=e,"list"===o.type?a("config.globalList"):o.choices&&"integer"===o.type?a("config.globalChoice",{choices:o.choices.join(A)}):o.max&&"18446744073709551615"!==o.max?a("config.globalRange",{max:o.max}):o.units?a("config.globalUnits",{units:o.units.filter(Boolean).join(A)}):void 0),items:r?[{id:"",label:a("config.globalUnset")},...[...t,...s&&!t.includes(s)?[s]:[]].map(e=>({id:e,label:e}))]:null,value:s,number:rn(e)&&/^\d*$/.test(i)?{max:Number(e.max),value:""===s?NaN:Number(s)}:null,duplicate:n.length>1,invalid:null===an(e,s),change:n=>{if(!w||k.busy)return;k.cancel(),P(null);const s={...O,[e.key]:n};n===i&&delete s[e.key],S(Object.keys(s).length?{source:N?.source??w,id:y.id,patch:s}:null)}};var o}),H=!!N&&(N.source.content_sha256!==w?.content_sha256||N.id!==y?.id),L=c&&!d.error&&!!w&&!0===r?.config.writable&&w.writable&&!0===x(w)&&!f.holdsCredentials(w),I=!!k.busy,q=!N||!L||H||F.some(e=>e.key in O&&e.invalid),W=we(k.error)?.diagnostics??null,$=k.error instanceof C&&"ui.writtenNotRead"===k.error.key,U=D??W??null,K=N&&Array.isArray(U)?Se(U):[],V="global"===v.get("tab")?v.get("field"):null;return Te(V,()=>{const e=document.getElementById("config-global-form");return e&&V?Oe(e,V):null}),{available:c&&!!m,loading:!!d.loading&&!d.data,fields:F,groups:Object.entries(tn).map(([e,n])=>({id:e,title:a(n),fields:F.filter(n=>n.group===e)})).filter(e=>e.fields.length>0),source:w,busy:I,blocked:q,writable:L,dirty:!!N,conflict:H,failure:Array.isArray(U)?K.length?null:a("config.invalid",{n:U.filter(e=>"error"===e.level).length}):U,restart:K,restartCommand:f.restartCommand,sources:h,unread:$?a("ui.writtenNotRead"):null,error:(W||$?null:k.error)??d.error,retry:d.refetch,save:async()=>{if(q||I||!m||!y)return;const e=on(N.source.content,m,y.index,O),n=je(h.filter(e=>x(e)),{id:w.id,content:e});if(r?.config_validate.available&&r.config_validate.modes?.includes("full")){if(!n)return void P(a("config.incomplete"));const e=await k.validate({sources:n,mode:"full"});if(!e)return;if(!e.valid)return void P(e.diagnostics)}const i=await k.apply(N.source,e);i&&(i.diagnostics?P(i.diagnostics):(T.clear(),S(null),p("positive",a("config.globalSaved"))))},cancel:()=>{k.cancel(),T.clear(),S(null),P(null)},choices:j.map(({id:e,label:n})=>({id:e,label:n})),selected:y?.id??"",select:e=>{const s=j.find(n=>n.id===e);s&&i("config",u(n,{tab:"global",source:s.source.id,section:String(s.index),field:null}))}}}(i);return r.available?r.loading?n.jsx(Cn,{groups:r.groups}):n.jsxs(W,{id:"config-global-form",className:"rp-page",onSubmit:e=>{e.preventDefault(),r.save()},children:[n.jsx($,{page:!0,children:n.jsx("span",{className:"rp-cluster nowrap rp-source-pick",children:n.jsx(me,{side:!0,cut:"path",label:a("config.source"),value:r.selected,items:r.choices,onChange:r.select,isDisabled:r.busy||!r.source})})}),n.jsx("span",{className:"rp-label",children:a("config.globalNote")}),r.unread&&n.jsx(_,{tone:"informative",children:r.unread}),n.jsx(R,{error:r.error,onRetry:r.retry}),r.failure&&n.jsx(_,{children:r.failure}),r.restart.length>0&&n.jsx(Sn,{settings:r.restart,sources:r.sources,command:r.restartCommand}),r.conflict&&n.jsx(_,{children:a("config.changedOnDisk")}),r.source&&!r.writable&&n.jsx(_,{tone:"informative",children:a("config.readOnly")}),r.groups.map(e=>n.jsx(H,{title:e.title,children:n.jsx($,{className:"top rp-fieldgrid",children:e.fields.map(e=>n.jsxs("div",{className:"rp-field","data-setting":e.key,children:[e.items?n.jsx(me,{label:e.label,value:e.value,isDisabled:!r.writable||r.busy||e.duplicate,onChange:e.change,items:e.items}):e.number?n.jsx(pn,{label:e.label,name:e.key,value:e.number.value,onChange:n=>e.change(mn(n)),step:1,isDisabled:!r.writable||r.busy||e.duplicate,placeholder:a("config.globalUnset"),error:e.invalid?a("config.globalRange",{max:e.number.max}):void 0,"aria-describedby":e.hint?`config-global-${e.key}`:void 0}):n.jsx(U,{label:e.label,name:e.key,value:e.value,onChange:e.change,isDisabled:!r.writable||r.busy||e.duplicate,placeholder:a("config.globalUnset"),error:e.invalid?a("config.globalInvalid"):void 0,"aria-describedby":e.hint?`config-global-${e.key}`:void 0}),n.jsx(K,{help:"so_mark_from_dae"===e.key?{title:e.label,text:a("config.socketMarkHelp")}:null,children:n.jsx("span",{className:"rp-label rp-code",children:e.key})}),e.hint&&n.jsx("span",{id:`config-global-${e.key}`,className:"rp-label",children:e.hint}),e.duplicate&&n.jsx("span",{className:"rp-label",children:a("config.globalDuplicate")})]},e.key))})},e.id)),n.jsx($,{page:!0,children:n.jsxs(V,{children:[n.jsx(T,{accent:!0,type:"submit",isPending:r.busy,isDisabled:r.blocked,children:a("config.globalSave")}),r.dirty&&n.jsx(T,{onPress:r.cancel,isDisabled:r.busy,children:a("config.discard")})]})})]}):null}const Pn="config-new-source-form";function Tn(i){const a=s(),r=function({sources:n,refetch:i,open:a}){const r=s(),t=n.find(e=>"main"===e.kind),o=e.useMemo(()=>t?Fe(t.content):null,[t]),l=e.useMemo(()=>He(o??[]),[o]),c=e.useMemo(()=>Le(n),[n]),[d,u]=e.useState(null),[g,f]=e.useState(null),{busy:h,create:b}=he(i),x=S(),v=d?.text??"",j=l.find(e=>e.pattern===d?.pattern)??null,y=j?j.prefix+v+j.suffix:v,w=v?j?Ie(v,j):qe(v):null;return{isOpen:null!==d,show:()=>{x.next(),f(null),u({text:l.length?"":We(o??[]),pattern:l[0]?.pattern??""})},hide:()=>{x.next(),u(null)},choices:l,choice:j,setChoice:e=>u(n=>n&&{...n,pattern:e}),text:v,setText:e=>u(n=>n&&{...n,text:e}),error:w?r(w):void 0,unmatched:!!v&&!w&&null!==c&&!c(y),problem:g,busy:h,canSubmit:!!v&&!w&&!h,submit:async e=>{if(!v||w||h)return;const n=x.start();try{const i=await b(y);if(!i)return;if(p("positive",r("config.newSourceCreated",{path:y})),!n())return;e(),i.id&&a(i.id)}catch(i){const e=r("config.newSourceFailed",{path:y});if(n()){const n=Q(i,r,e);f(e=>({id:(e?.id??0)+1,text:J(n,r),kind:n.kind}))}else m(i,r,e)}}}}(i);return n.jsxs(n.Fragment,{children:[n.jsxs(T,{onPress:r.show,children:[n.jsx(hn,{}),a("config.newSource")]}),n.jsxs(M,{title:a("config.newSourceTitle"),narrow:!0,isOpen:r.isOpen,onOpenChange:e=>{e||r.hide()},footer:e=>n.jsxs(n.Fragment,{children:[n.jsx(T,{onPress:e,children:a("ui.cancel")}),n.jsx(T,{accent:!0,type:"submit",form:Pn,isDisabled:!r.canSubmit,isPending:r.busy,children:a("config.newSourceCreate")})]}),children:[r.problem&&n.jsx(G,{problem:r.problem},r.problem.id),n.jsxs(W,{id:Pn,className:"rp-list",onSubmit:e=>{e.preventDefault(),r.submit(r.hide)},children:[n.jsx("span",{className:"rp-label",children:a(r.choice?"config.newSourceNameHelp":"config.newSourceHelp")}),r.choices.length>1&&n.jsx(me,{label:a("config.newSourcePattern"),items:r.choices.map(e=>({id:e.pattern,label:e.pattern})),value:r.choice?.pattern??"",onChange:r.setChoice,isDisabled:r.busy}),r.choice?n.jsx(U,{isDisabled:r.busy,label:a("ui.name"),value:r.text,prefix:r.choice.prefix,suffix:r.choice.suffix,placeholder:"extra",spellCheck:!1,error:r.error,onChange:r.setText}):n.jsx(U,{isDisabled:r.busy,label:a("config.newSourcePath"),value:r.text,placeholder:"config.d/extra.dae",spellCheck:!1,error:r.error,onChange:r.setText}),r.unmatched&&n.jsx(_,{tone:"informative",children:a("config.newSourceUnmatched")})]})]})]})}function On({message:e,busy:i,keep:a,discard:r}){const t=s();return n.jsx(_,{action:(a||r)&&n.jsx($,{children:n.jsxs(V,{children:[a&&n.jsx(T,{isDisabled:i,onPress:a,children:t("config.keepChanges")}),r&&n.jsx(T,{isDisabled:i,onPress:r,children:t("config.discard")})]})}),children:e})}const Rn=ee(()=>ne(()=>import("./CodeEditor-9GVA7w36.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12]),import.meta.url).then(e=>({default:e.CodeEditor}))),_n=[{block:560}];function En(i){const{canValidate:r}=i,t=s(),o=a(),{writable:l,links:c,diagnostics:d,note:u,refused:g,restart:f,restartCommand:p,marks:m,text:h,names:b,focus:x,focusKey:v,dirty:j,conflict:y,keep:w,validate:k,save:N,cancel:S,change:C,view:D,busy:P,validating:R,saving:_,saveButton:E,validateDisabled:M,reason:A}=yn(i),F=e.useRef(null),q=e.useRef(!1),W=()=>{q.current&&F.current&&(q.current=!1,F.current.focus(),F.current.scrollIntoView({block:"nearest"}))};e.useEffect(()=>{q.current=!!i.focusDiagnostics,W()},[i.focusDiagnostics,i.focusLine,i.source.id]);const U=function(e,n,i){return e.filter(e=>e.line===n||n&&e.line<=n&&i.slice(0,e.to).split("\n").length>=n)}(c,x,h),K=U.length?U:c,V=n.jsx($,{"aria-label":t("config.forms"),children:K.map(e=>n.jsx(L,{appearance:"button",href:e.href,children:e.label},e.from))}),B=n.jsx("div",{ref:F,tabIndex:-1,role:"region","aria-label":t("config.diagnostics"),className:"rp-config-diagnostics",children:d.quiet?n.jsx("span",{className:"rp-config-diagnostics-quiet rp-label",children:d.quiet}):n.jsxs(pe,{aside:d.scopeHelp&&n.jsx(O,{...d.scopeHelp}),isExpanded:d.open,onExpandedChange:d.setOpen,title:n.jsxs("span",{className:"rp-config-diagnostics-summary",children:[n.jsx(ge,{tone:d.errors?"negative":void 0,children:t("config.levelErrors",{n:d.errors})}),n.jsx(ge,{tone:d.warnings?"warn":void 0,children:t("config.levelWarnings",{n:d.warnings})}),n.jsx("span",{className:"rp-label",children:d.scope})]}),children:[n.jsx("div",{className:"rp-config-diagnostic-filter",children:n.jsx(be,{label:t("config.level"),value:d.level,onChange:d.setLevel,items:d.levels})}),n.jsx("div",{className:"rp-config-diagnostic-list",role:"list","aria-label":t("config.diagnostics"),children:d.rows.map(e=>n.jsxs("div",{className:"rp-config-diagnostic",role:"listitem",children:[n.jsxs(xe,{small:!0,tone:e.tone,children:[n.jsx(X,{children:`${e.levelText} `}),e.text]}),e.backend&&n.jsx(pe,{flush:!0,title:t("config.backendText"),children:n.jsx("code",{children:e.backend})}),e.offline&&n.jsx(Y,{link:{href:I(o,"offline-dependency"),text:t("ov.lim.docsOffline"),external:!0}}),e.action&&n.jsx(T,{small:!0,className:"rp-config-diagnostic-go",label:"jump"===e.action?t("config.jumpToLine",{line:e.line}):t("config.openSourceAt",{where:e.where}),onPress:()=>d.go(e),children:t("jump"===e.action?"cm.go":"config.openSource")})]},e.id))})]})}),z=[...r?[{id:"validate",label:t("config.validate"),isPending:R,isDisabled:M,reason:A??void 0,onAction:()=>{k()}}]:[],...j?[{id:"cancel",label:t("ui.cancel"),isDisabled:P,onAction:S},{id:"save",label:t("config.save"),accent:!0,isPending:_,isDisabled:E.disabled,reason:E.tip??A??void 0,onAction:()=>{N()}}]:[]];return n.jsxs(H,{title:t("config.editor"),className:"rp-source-card","aria-label":D.label,help:l?{title:t("config.editor"),text:t("config.writeHelp")}:void 0,reason:A,children:[n.jsx("div",{className:"rp-row rp-source-note",children:n.jsx("span",{className:"rp-cluster",children:j?n.jsxs(n.Fragment,{children:[n.jsx(ge,{tone:"warn",children:t("config.unsaved")}),n.jsx("span",{className:"rp-label",children:t("config.unsavedHint")})]}):n.jsx("span",{className:"rp-label",children:u})})}),y&&n.jsx(On,{message:y,busy:P,keep:w}),f.length>0&&n.jsx(Sn,{settings:f,sources:i.sources,command:p}),U.length?V:c.length>0&&n.jsx(pe,{title:t("config.forms"),children:V}),n.jsxs(e.Suspense,{fallback:n.jsx(Z,{panel:!0,shape:_n}),children:[n.jsx(Rn.Component,{actions:z,label:D.label,value:h,readOnly:!l||P,onChange:C,onReadOnlyAttempt:g,marks:m,focusLine:x,focusKey:v,banner:B,names:b,onSave:j&&!P?()=>{N()}:void 0}),n.jsx(Mn,{run:W})]})]})}function Mn({run:n}){const i=e.useRef(n);return e.useEffect(()=>i.current(),[]),null}const An=[{toolbar:1,height:16},..._n];function Fn(i){const a=s(),{error:r,reload:t,loading:o,ready:l,tabsReady:c,metadata:d,redacted:u,tabs:g,tab:f,setTab:p,selectedId:m,select:h,sourceProps:b,newSourceProps:x,modulesProps:v,sourceModel:j,sourceOptions:y,exportSource:w,summaryTone:k,summaryText:N}=jn(i);e.useEffect(()=>{"source"===f&&Rn.preload().catch(()=>{})},[f]);const S={history:n.jsx(kn,{}),modules:v?n.jsx(Nn,{...v}):o&&n.jsx(Z,{panel:!0,shape:se}),global:n.jsx(Dn,{...i}),source:n.jsxs(n.Fragment,{children:[n.jsxs($,{page:!0,children:[n.jsxs("span",{className:"rp-cluster nowrap rp-source-pick",children:[n.jsx(me,{side:!0,cut:"path",label:a("config.source"),value:m,onChange:h,items:y}),j&&n.jsxs(n.Fragment,{children:[j.readOnly&&n.jsx(K,{help:j.readOnly.help,children:n.jsx(ge,{children:j.readOnly.label})}),n.jsx(ie,{className:"rp-label",text:j.loaded,children:j.facts})]})]}),(x||j)&&n.jsxs("span",{className:"rp-cluster nowrap",children:[x&&n.jsx(Tn,{...x}),j&&n.jsxs(T,{onPress:w,children:[n.jsx(Pe,{}),a("config.export")]})]})]}),j&&n.jsx("span",{className:"rp-label",children:a("config.exportWarning")}),b?n.jsx(En,{...b},j.id):o&&n.jsx(Z,{panel:!0,shape:An})]})};return n.jsxs("div",{className:"rp-page",children:[n.jsx(R,{error:r,onRetry:t}),o&&n.jsx(Z,{shape:c?ae:re}),l&&n.jsxs($,{page:!0,children:[n.jsx(fe,{row:!0,items:d}),n.jsx(xe,{small:!0,tone:k,children:N}),u&&n.jsx(xe,{small:!0,tone:"muted",children:a("config.redacted")})]}),c&&n.jsx(ve,{page:!0,label:a("nav.config"),value:f,onChange:p,items:g.map(e=>({...e,content:S[e.id]}))})]})}export{Fn as Config};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Connections-6ME7y64q.js b/luci-app-honk/root/etc/honk/doona/assets/Connections-BPMOPt05.js
similarity index 82%
rename from luci-app-honk/root/etc/honk/doona/assets/Connections-6ME7y64q.js
rename to luci-app-honk/root/etc/honk/doona/assets/Connections-BPMOPt05.js
index 96a5f54f1..fbf9b0077 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Connections-6ME7y64q.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Connections-BPMOPt05.js
@@ -1 +1 @@
-import{r as e,j as n}from"./vendor-react-64fcanlc.js";import{i as t,I as o,a as s}from"./ipLookup-CY9MTfz2.js";import{N as l,O as a}from"./NodePath-BtHMV14P.js";import{aW as i,u as r,at as c,as as u,a6 as d,o as p,aH as m,aN as h,c6 as b,C as g,E as f,a3 as w,ae as v,s as x,W as y,c7 as j,T as k,bZ as _,w as C,c8 as S,Z as A,c9 as L,ca as N,a4 as T,a7 as M,r as R,t as P,X as F,cb as O,ac as W,cc as U,an as q,O as D,cd as E,b7 as H,ce as I,b8 as V,cf as B,c0 as Q,cg as J,ch as K,ci as G,V as X,au as Z,cj as z,J as Y,ck as $,aX as ee,A as ne,cl as te,cm as oe,cn as se,bP as le,B as ae,co as ie,bF as re,aD as ce}from"./index-CUHkLMAp.js";import{R as ue,B as de,u as pe,h as me,o as he,g as be,c as ge,S as fe,p as we,L as ve,n as xe,K as ye}from"./logs-C6Kb44nw.js";import{C as je}from"./AppearanceControls-E-VPhjIz.js";import{T as ke}from"./Tabs-DiTlqyjA.js";import{b as _e,D as Ce,U as Se,F as Ae,S as Le,d as Ne,B as Te,L as Me,t as Re,r as Pe,f as Fe,g as Oe,p as We,o as Ue,k as qe,h as De}from"./activity-B3PmJo_X.js";import{S as Ee}from"./SearchSelect-Fy-2ASgN.js";import{D as He}from"./Table-DX856nrS.js";import{T as Ie}from"./TimeCell-N-r54xmV.js";import{Q as Ve,u as Be,R as Qe}from"./useQuickRule-Cd5z6aFL.js";import{u as Je}from"./outbounds-CUiHWeth.js";import{c as Ke,d as Ge,e as Xe}from"./files-Dt8K7QfP.js";import{w as Ze}from"./labels-D8xxfRTQ.js";import{u as ze}from"./flows-DS-lcTPn.js";import{r as Ye}from"./rule-D4-Og0AG.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./LinkOut-B2JdPfjI.js";import"./Tag-4SaGY8GT.js";import"./Select-BA0NS1_z.js";import"./ItemText-CnEXu0-f.js";import"./nodes-BYMoo8M1.js";import"./useGridSelectionCheckbox-CTBMGgmQ.js";import"./SearchList-DMvmI1K7.js";import"./Virtualizer-UMC7L0o2.js";import"./Checkbox-8Iqnc6T1.js";import"./DaeCode-DEjXqvav.js";import"./daeTokens-BVtuNnWZ.js";import"./AddCircle-D2cMd6zF.js";import"./BackendText-Dtw6qhij.js";const $e=[0,2,3,1,4,5,6,7],en=e.memo(function({records:t,outbounds:o,latency:s,latencyError:l,retryLatency:a,truncated:w,uncounted:v,onSelect:x,loading:y}){const j=r(),k=_e(),_=c[u()],C=e.useCallback(e=>d(e,_),[_]),S=e.useMemo(()=>function(e,n){const t=new Map;let o,s=0,l=-1n;for(const a of e){if(null===a.upload_bytes||null===a.download_bytes){s++;continue}const e={id:a.id,up:Number(a.upload_bytes),down:Number(a.download_bytes),name:a.domain||a.dst||a.id},n=t.get(a.outbound);n?n.push(e):t.set(a.outbound,[e]);const i=BigInt(a.upload_bytes)+BigInt(a.download_bytes);i>l&&(l=i,o={...e,outbound:a.outbound})}return{series:[...t].map(([e,n])=>({outbound:e,points:n})).sort((e,t)=>i(n)(e.outbound??"",t.outbound??"")),unknown:s,heaviest:o,placed:e.length-s}}(t,_),[t,_]),A=e.useMemo(()=>{const e=o.filter(e=>"block"!==e);return S.series.map(n=>{return{id:n.outbound??"",label:p(n.outbound,j),color:(t=n.outbound,"block"===t?k.negative:k.cat[$e[Math.max(0,e.indexOf(t))%$e.length]]),points:n.points.map(e=>({id:e.id,x:e.up,y:e.down,name:e.name,detail:j("conn.chart.point",{download:C(e.down),upload:C(e.up)})}))};var t})},[S,o,k,j,C]),L=S.heaviest?[{label:j("conn.chart.busiest"),icon:n.jsx(m,{}),tint:"c3",value:S.heaviest.name,caption:p(S.heaviest.outbound,j)},{label:j("ui.download"),value:C(S.heaviest.down),icon:n.jsx(Ce,{}),tint:"c1"},{label:j("ui.upload"),value:C(S.heaviest.up),icon:n.jsx(Se,{}),tint:"c4"}]:[];if(y)return n.jsx(h,{panel:!0,shape:b});const N=S.unknown?j("conn.chart.sampleUnknown",{n:t.length,unknown:S.unknown}):j("conn.chart.sample",{n:t.length});return n.jsxs("div",{className:"rp-chart-page",children:[n.jsx(Ae,{facts:L,lead:!0}),n.jsxs(g,{title:j("conn.chart.title"),help:v?{title:j("conn.chart.title"),text:j("ui.trafficUncounted")}:void 0,note:N,children:[w&&n.jsx("p",{className:"rp-note",children:j("conn.truncated")}),S.placed>0&&n.jsxs(n.Fragment,{children:[n.jsx(Le,{label:j("conn.chart.title"),series:A,fmt:C,onSelect:x,regions:{above:j("conn.chart.moreDown"),below:j("conn.chart.moreUp")}}),n.jsx(Ne,{series:A}),n.jsx("p",{className:"rp-note",children:j("conn.chart.hint")})]})]}),s?n.jsx(nn,{latency:s}):l&&n.jsx(g,{title:j("ui.nodeLatency"),children:n.jsx(f,{error:l,onRetry:a})})]})});function nn({latency:e}){const t=r(),o=_e(),s=e=>v(e,t),l=c[u()],a=n=>!e.chains||n?o.cat[0]:o.muted;return n.jsx(g,{title:t("ui.nodeLatency"),note:t("conn.latency.sample",{n:e.samples.length,missing:e.missing}),children:e.samples.length?n.jsxs(n.Fragment,{children:[n.jsx("p",{className:"rp-note",children:t("conn.latency.percentiles",{p50:s(e.p50),p90:s(e.p90)})}),null!==e.weightedP50&&n.jsx("p",{className:"rp-note",children:e.unplaced?t("conn.latency.weightedUnplaced",{p50:s(e.weightedP50),n:e.unplaced}):t("conn.latency.weighted",{p50:s(e.weightedP50)})}),n.jsx(Te,{label:t("ui.nodeLatency"),points:e.samples.map(e=>({id:e.node,nodeName:!0,value:e.value,color:a(e.connections>0),lines:[e.name,s(e.value),...e.connections?[t("conn.chart.sample",{n:e.connections})]:[]]})),fmt:s}),e.chains&&n.jsxs("div",{className:"rp-legend",children:[n.jsx(Me,{swatch:a(!0),label:t("conn.latency.inUse"),value:w(e.used,l)}),n.jsx(Me,{swatch:a(!1),label:t("conn.latency.others"),value:w(e.samples.length-e.used,l)})]}),n.jsx("p",{className:"rp-note",children:t("conn.latency.hint")})]}):n.jsx("p",{className:"rp-note",children:t("conn.latency.pending")})})}const tn=[{id:"dst",label:"ui.target",minWidth:200,sortable:!0},{id:"src",label:"ui.device",minWidth:128,sortable:!0,drop:5},{id:"node",label:"nodes.node",minWidth:120,drop:3},{id:"rule",label:"ui.rule",minWidth:220,drop:2},{id:"state",label:"ui.state",minWidth:112,sortable:!0,drop:7},{id:"down",label:"ui.download",minWidth:96,sortable:!0,drop:4},{id:"downRate",label:"conn.f.downloadRate",minWidth:128,sortable:!0,drop:1},{id:"age",label:"ui.started",minWidth:132,sortable:!0,drop:6}],on=x.connectionsView,sn=e=>({allCollapsed:e,exceptions:new Set}),ln=(e,n)=>e.allCollapsed!==e.exceptions.has(n);function an(e,n){const t=new Set(e.exceptions);return t.delete(n)||t.add(n),{allCollapsed:e.allCollapsed,exceptions:t}}const rn=(e,n)=>"source"===n?y(e.src??void 0)??e.src??"—":e.outbound??"unknown",cn=(e,n,t)=>"source"===n?e:p(e,t),un=e=>"g:"+e,dn=e=>e.startsWith("g:")||e.startsWith("\\")?"\\"+e:e;function pn(e){const n={hidden:[],sort:null,group:"source"};try{const t=JSON.parse(e??"null");if(!t||"object"!=typeof t)return n;const o=Array.isArray(t.hidden)?t.hidden.map(e=>"chain"===e?"node":e):[],s=tn.filter(e=>o.includes(e.id)).map(e=>e.id),l=t.sort;return{hidden:s.length===tn.length?[]:s,sort:l&&tn.some(e=>e.sortable&&e.id===l.column)&&["ascending","descending"].includes(l.direction)?{column:l.column,direction:l.direction}:null,group:"none"===t.group||"outbound"===t.group?t.group:"source"}}catch{return n}}const mn=e=>e.target;function hn({collection:t,view:o,collapse:s,onToggleGroup:a,loading:i,selected:c,onSelect:u,selectOnFocus:d,onSort:p,rule:m}){const h=r(),[b,g]=j(442),f=e.useRef(m);e.useLayoutEffect(()=>{f.current=m});const w=e.useMemo(()=>{const e={dst:e=>n.jsx(k,{children:e.target}),src:e=>n.jsx(k,{className:"rp-code",children:e.source}),node:e=>n.jsx(l,{row:e}),rule:e=>n.jsxs("span",{className:"rp-rule",children:[n.jsx(ue,{...e.rule}),e.recomputed&&n.jsx(de,{tip:h("rule.sourceHelp.recomputed"),children:e.recomputed})]}),state:e=>e.state,down:e=>e.download,downRate:e=>e.downloadRate,age:e=>n.jsx(Ie,{at:e.startedAt})};return[...tn.filter(e=>!o.hidden.includes(e.id)).map(n=>({...n,label:h(n.label),grow:1,render:e[n.id]})),{id:"actions",actions:!0,label:h("ui.actions"),minWidth:88,grow:0,render:e=>{const t=f.current,o=!t.canAdd(e.seed);return n.jsx(Ve,{label:t.label(e.target),disabled:o,tip:t.noTarget,onPress:()=>f.current.open(e.seed)})}}]},[o.hidden,h]),v=e.useMemo(()=>t.map(e=>"connection"in e?e.connection:e),[t]),x=e.useMemo(()=>({grouped:"none"!==o.group,collapsed:e=>ln(s,e),onToggle:a}),[o.group,s,a]);return n.jsx("div",{ref:b,children:n.jsx(He,{label:h("nav.connections"),rowDetail:!0,cols:w,rows:v,height:g,selected:c&&dn(c),onSelect:u&&(e=>u(e&&(e=>e.startsWith("\\")?e.slice(1):e)(e))),selectOnFocus:d,reveal:!0,empty:h("conn.empty"),loading:i,sort:o.sort&&{column:String(o.sort.column),direction:o.sort.direction},onSort:p,getTextValue:mn,stream:!0,tree:x})})}const bn={userspace:"ov.v.userspace",ebpf:"ov.v.ebpf",mixed:"conn.observed.mixed"},gn={evaluation:"conn.chainSource.evaluation",reconstructed:"conn.chainSource.reconstructed",unknown:"ui.unknown"};function fn(e,n){const o=e.dst??"—",s=y(e.dst),l=s&&t(s)?{ip:s,address:o}:o,a=e.chain_source?[["conn.f.chainSource",gn[e.chain_source]?{key:gn[e.chain_source]}:e.chain_source]]:[];return[["ui.device",e.src??"—"],["conn.f.dst",l],["ui.domain",e.domain??"—"],["conn.f.ingress",Ze(e.ingress)],["conn.f.domainSource",Ze(e.domain_source)],...a,["ui.process",e.pname??"—"],["conn.f.observedBy",bn[e.observed_by]?{key:bn[e.observed_by]}:e.observed_by],["ui.upload",d(e.upload_bytes,n)],["ui.download",d(e.download_bytes,n)],["conn.f.uploadRate",T(e.upload_bytes_per_second,n)],["conn.f.downloadRate",T(e.download_bytes_per_second,n)],["conn.f.started",M(e.started_at,n)]]}const wn={observed:["conn.state.observed","conn.stateHelp.observed"],routing:["conn.state.routing","conn.stateHelp.routing"],dialing:["conn.state.dialing","conn.stateHelp.dialing"]};function vn(e,n){return Object.hasOwn(wn,e)?{title:n("ui.state"),text:Object.values(wn).map(([e,t])=>n("ui.valuePair",{label:n(e),value:n(t)}))}:null}const xn=e=>({domain:e.domain??null,dip:y(e.dst)??null,sip:y(e.src)??null,outbound:e.outbound,matched:e.rule_id&&"unknown"!==e.rule_source?{id:e.rule_id,expression:e.rule_expression}:null});const yn=new WeakMap;function jn(e,n,t,o,s,l){const a=e=>{const n=yn.get(e);if(n&&n.locale===t&&n.names===o&&n.rulesListed===s&&n.t===l)return n.row;const a={id:dn(e.id),target:e.domain||e.dst||"—",seed:xn(e),source:e.src??"—",node:U(e,l,o),nodeName:!W(e.outbound)&&e.chain.length>0,path:O(e,l,o),rule:{expression:e.rule_expression,href:Pe(e.rule_id,s)},recomputed:"recomputed"===e.rule_source?l("conn.recomputed"):null,state:A(L,e.state,l),download:d(e.download_bytes,t),downloadRate:T(e.download_bytes_per_second,t),startedAt:e.started_at};return yn.set(e,{locale:t,names:o,rulesListed:s,t:l,row:a}),a};return function(e,n,t,o){let s=e;if(n.sort){const{column:r,direction:c}=n.sort,u=i(t);l=e=>{switch(r){case"dst":return e.domain||e.dst;case"src":return e.src;case"state":return A(L,e.state,o);case"down":return q(e.download_bytes);case"downRate":return q(e.download_bytes_per_second);case"age":return e.started_at?Date.parse(e.started_at):null;default:return null}},a=(e,n)=>{if(null==e)return null==n?0:1;if(null==n)return-1;const t="string"==typeof e&&"string"==typeof n?u(e,n):en?1:0;return"descending"===c?-t:t},s=e.map(e=>({item:e,key:l(e)})).sort((e,n)=>a(e.key,n.key)).map(e=>e.item)}var l,a;if("none"===n.group)return s.map(e=>({id:dn(e.id),connection:e}));const r=new Map;for(const i of s){const e=rn(i,n.group),t=r.get(e);t?t.push(i):r.set(e,[i])}return[...r].map(([e,n])=>({id:un(e),group:e,children:n,active:n.filter(e=>"active"===e.state).length,download:F(...n.map(e=>e.download_bytes))}))}(e,n,t,l).map(e=>"connection"in e?{id:e.id,connection:a(e.connection)}:{id:e.id,group:e.group,children:e.children.map(a),label:l("conn.groupCount",{name:cn(e.group,n.group,l),n:e.children.length}),totals:{down:d(e.download,t),state:l("conn.activeCount",{n:e.active})}})}const kn=oe().map(e=>e.id),_n=e=>{const n=new URLSearchParams(e);return["id","src","network","out","rule","q"].some(e=>n.has(e))?"list":"traffic"},Cn=(e,n)=>C(e,"list"===_n(e)?{tab:K(e,kn,"list"),...n}:n);function Sn({go:n,query:t}){const o=r(),s=c[u()],[l,a]=e.useState(()=>{try{return pn(localStorage.getItem(on))}catch{return pn(null)}}),d=H(I),m=H(V),[h,b]=e.useState(()=>sn(!1)),g=e.useCallback(e=>b(n=>an(n,e)),[]),f=e=>{const n={...l,...e};n.group!==l.group&&b(sn(!1)),a(n);try{localStorage.setItem(on,JSON.stringify(n))}catch{}},v=e.useMemo(()=>new URLSearchParams(t),[t]),[x,j]=e.useState(v.get("q")??""),k=v.get("network")??"all",T=v.get("out")??"all",M=v.get("rule")??"all",F=(e,o)=>n("connections",Cn(t,{[e]:"all"===o?null:o})),O=v.get("id"),[W,U]=e.useState(null);B(v.get("q"),e=>j(e??""));const q=e.useRef(t);e.useEffect(()=>{q.current=t});const oe=e=>n("connections",Cn(q.current,{id:e})),se=e.useDeferredValue(x),le=Q(v.get("src")??""),ae=me(le),ie=R(),re=!0===ie.data?.resources.connections.can_close,ce=P(ie.data?.resources,"rules",{whileLoading:!1}),ue=P(ie.data?.resources,"flows",{whileLoading:!1});J(ie.data?.resources);const de=Je(),fe=he(ae.refetch),we=_n(t),ve=K(t,kn,we),xe=G(ae.data,"list"===ve),ye=G(ae.data,"traffic"===ve),je=e.useMemo(()=>X(xe),[xe]),ke=e.useMemo(()=>X(ye),[ye]),_e=P(ie.data?.resources,"nodes",{whileLoading:!1}),Ce=be(_e),Se=G(Ce.data,"traffic"===ve),Ae=e.useMemo(()=>_e&&Se?function(e,n,t){if(!n.some(e=>e.health?.length))return null;const o=[];let s=0;for(const i of n){const e=D(E(i.health??[]));void 0===e?s++:o.push({node:i.id,name:i.name,value:e,connections:0})}o.sort((e,n)=>e.value-n.value||i(t)(e.name,n.name));const l=new Map(o.map(e=>[e.node,e])),a=e.some(e=>e.chain?.length);let r=0;for(const i of e){const e=i.chain?.at(-1);if(void 0===e)continue;const n=l.get(e);n?n.connections++:r++}const c=o.reduce((e,n)=>e+n.connections,0);let u=0;const d=o.find(e=>(u+=e.connections)>=Math.max(1,Math.ceil(c/2))),p=o.map(e=>e.value);return{samples:o,chains:a,missing:s,unplaced:r,used:o.filter(e=>e.connections).length,p50:We(p,50),p90:We(p,90),weightedP50:c?d.value:null}}(ke,Se,s):null,[_e,Se,ke,s]),Le=Z("traffic"===ve&&P(ie.data?.resources,"runtime",{whileLoading:!1})),Ne=_e&&!Ce.data?Ce.error:null,Te=e.useMemo(()=>[...new Set(ke.map(e=>e.outbound))].sort((e,n)=>i(s)(e??"",n??"")),[ke,s]),Me=se.trim().toLowerCase(),Ee=e.useMemo(()=>je.filter(e=>("all"===k||e.network===k)&&("all"===T||e.outbound===T)&&("all"===M||e.rule_expression===M)&&(!Me||[e.dst,e.domain,e.src,e.pname,p(e.outbound,o),N(e.chain,de).join(" "),e.rule_expression].join(" ").toLowerCase().includes(Me))),[je,k,T,M,Me,de,o]),He=O?je.find(e=>e.id===O):void 0,[Ie,Ve]=e.useState(null);O||null===Ie||Ve(null);const Qe=function(e,n){if(!e||"none"===n)return null;const t=rn(e,n);return{group:t,token:JSON.stringify([e.id,n,t])}}(He,l.group);var Ze,$e;Qe&&Ie!==Qe.token&&(Ve(Qe.token),b((Ze=h,$e=Qe.group,ln(Ze,$e)?an(Ze,$e):Ze)));const en=function(e,n){const t=r(),o=R().data?.resources,s=Be(n),l=P(o,"rules",{whileLoading:!1})&&P(o,"config",{whileLoading:!1})&&!0===o?.config.writable?e?.rule_id??null:null,a=ze(!!l),i=pe(!!l),c=e&&xn(e);return{canAdd:!!c&&s.canAdd(c),row:{canAdd:s.canAdd,open:s.open,label:e=>t("conn.addRuleFor",{target:e}),noTarget:t("conn.ruleNoTarget")},canShow:P(o,"rules",{whileLoading:!1})&&!!e?.rule_id,canEdit:!!l&&Ye(a.data?.rules.find(e=>e.rule_id===l),i.data?.sources??[]),openAdd:()=>{c&&s.open(c)},dialog:s.dialog}}(He,n),nn=e.useMemo(()=>function(e,n,t,o,s,l,a){const i=new Set(e.flatMap(e=>e.outbound?[e.outbound]:[]));"all"!==s&&i.add(s);const r=e=>{const n=e.flatMap(e=>e?[e]:[]);return Oe(n,1/0).top},c=[{id:"all",label:a("conn.allOutbounds")},...[...i].map(e=>({id:e,label:p(e,a)}))];return{networks:[["all",a("ui.allCount",{n:e.length})],["tcp",a("ui.tcp")],["udp",a("ui.udp")]],outbounds:c,outboundSections:[{id:"outbounds",items:c}],picks:[{title:a("ui.device"),value:Fe("src",t??""),items:r(e.map(e=>y(e.src))).map(({key:e,count:n})=>({id:Fe("src",e),label:e,desc:w(n,l)}))},{title:a("ui.rule"),value:Fe("rule",o),items:r(e.map(e=>e.rule_expression)).map(({key:e,count:n})=>({id:Fe("rule",e),label:e,desc:w(n,l)}))}],visibility:n&&"full"!==n.visibility?a("none"===n.visibility?"conn.visibilityNone":"conn.visibilityPartial"):null}}(je,xe,le,M,T,s,o),[je,xe,le,M,T,s,o]),cn=ge(P(ie.data?.resources,"groups",{whileLoading:!1})).data,un=e.useMemo(()=>{const e=function(e,n,t,o,s){return e?{id:e.id,title:e.domain||e.dst||e.id,tone:"blocked"===e.state||"failed"===e.state?"err":"active"===e.state?"ok":"info",status:t("ui.aside",{text:A(L,e.state,t),note:e.network.toUpperCase()}),chain:S(e,t,o),outbound:e.outbound,rule:{expression:e.rule_expression,href:Pe(e.rule_id,s)},fields:fn(e,n).map(([e,n])=>[t(e),"string"==typeof n||"ip"in n?n:t(n.key,n.params)]),flowQuery:C("",{tab:"records",...e.flow_id?{id:e.flow_id}:{connection_id:e.id}}),traceQuery:e.domain||y(e.dst)?Re({network:"udp"===e.network?"udp":"tcp",domain:e.domain??"",dst_ip:y(e.dst),dst_port:_(e.dst),src_ip:y(e.src),src_port:_(e.src),pname:e.pname??""}):null,source:e.src?y(e.src)??e.src:null,closable:"active"===e.state||"dialing"===e.state||"routing"===e.state,closeReason:"ebpf"===e.observed_by?t("conn.notClosable"):null,stateHelp:vn(e.state,t)}:null}(He,s,o,de,ce);return e&&{...e,outboundTag:Ue(e.outbound,cn,o)}},[He,s,o,de,ce,cn]),dn={...nn,detail:un},mn=e.useMemo(()=>jn(Ee,l,s,de,ce,o),[Ee,l,s,de,ce,o]),hn=e=>{const o=De(String(e),["src","rule"]);"src"===o?.kind?(j(""),n("connections",Cn(t,{src:o.value&&le!==o.value?o.value:null,q:null}))):"rule"===o?.kind&&F("rule",M===o.value?"all":o.value)},bn=function(e,n,t){const[o,s]=e.picks,l=(e,n,t,o,s)=>({filter:e,label:n,sections:[{title:n,items:t,value:o}],searchLabel:s});return{active:["all"!==n.network,"all"!==n.out,!!n.src,"all"!==n.rule].filter(Boolean).length,submenus:[l("network",t("ui.network"),e.networks.map(([e,n])=>({id:e,label:n})),n.network),l("out",t("ui.outbound"),e.outbounds,n.out,t("ui.filterOutbounds")),l("src",o.title,[{id:Fe("src",""),label:t("conn.allDevices")},...o.items],o.value,t("ui.filterDevices")),l("rule",s.title,[{id:Fe("rule","all"),label:t("conn.allRules")},...s.items],s.value,t("ui.filterRules"))]}}(nn,{network:k,out:T,src:le,rule:M},o),gn={network:e=>F("network",e),out:e=>F("out",e),src:hn,rule:hn},wn={active:bn.active,submenus:bn.submenus.map(({filter:e,...n})=>({...n,sections:n.sections.map(n=>({...n,onChange:gn[e]}))}))},yn=e.useCallback(e=>n("connections",C(t,{tab:"list",id:e})),[n,t]);return{...dn,tab:ve,setTab:e=>n("connections",z(t,e,"traffic"===we?we:null)),openInList:yn,trafficUncounted:qe(Le.data),view:l,updateView:f,collapse:h,toggleCollapse:g,toggleCollapseAll:()=>b(sn(!h.allCollapsed)),wide:d,text:x,setText:j,network:k,out:T,sel:O,select:oe,collection:mn,rows:ke,outboundKeys:Te,latency:Ae,latencyError:Ne,retryLatency:Ce.refetch,setNetwork:e=>F("network",e),setOut:e=>F("out",e),pick:hn,compact:m,filterMenu:wn,columns:tn.map(e=>({id:e.id,label:o(e.label)})),visibleColumns:tn.filter(e=>!l.hidden.includes(e.id)).map(e=>e.id),toggleColumn:e=>{const n=String(e),t=l.hidden.includes(n)?l.hidden.filter(e=>e!==n):[...l.hidden,n];t.length{j(""),n("connections",Cn(t,{network:null,out:null,rule:null,q:null,src:null}))},error:ae.error,retry:ae.refetch,loading:ae.loading&&!ae.data,truncated:!!ae.data?.truncated,canClose:re,canViewFlow:ue,closeAll:{confirmationText:W?.query?o("all"===W.query.type?"conn.closeAllLive":"tcp"===W.query.type?"conn.closeAllLiveTcp":"conn.closeAllLiveUdp",le?{n:W.count??W.ids.length,source:le}:{n:W.count??W.ids.length,source:o("conn.anySource")}):o("conn.closeAllHelp",{n:W?.ids.length??0}),open:!!W,setOpen:e=>U(e?"all"!==v.get("scope")||"all"!==k||le||"all"!==T||"all"!==M||Me?function(e,n){const t=e.map(e=>e.id),o=null!=n.bulkLimit&&t.length>n.bulkLimit;return n.narrowed||n.truncated||o?{ids:t}:{ids:t,query:{type:n.network,src:n.src,all:!0}}}(Ee,{network:k,src:le,narrowed:"all"!==T||"all"!==M||!!Me,truncated:!!ae.data?.truncated,bulkLimit:ie.data?.resources.connections.max_bulk_close}):{ids:[],query:{type:"all",all:!0},count:(ae.data?.total_tcp??0)+(ae.data?.total_udp??0)}:null),isDisabled:!Ee.length||!!fe.busy||x!==se,isPending:"all"===fe.busy,onConfirm:async()=>{if(W)try{const e=await fe.closeAll(W);if(!e)return;oe(null),Y($(e),o("conn.closedAll",{closed:e.closed,skipped:e.skipped}))}catch(e){return o("ui.valuePair",{label:o("conn.closeFailed"),value:ee(e,o)})}},onAbort:fe.cancel},close:{pending:fe.busy===He?.id,disabled:!!fe.busy,run:()=>{(async()=>{if(!dn.detail)return;const{id:e}=dn.detail;try{if(!(await fe.close(e)))return;new URLSearchParams(q.current).get("id")===e&&oe(null),Y("positive",o("conn.closed",{name:dn.detail.title}))}catch(n){n instanceof ne&&"state_conflict"===n.code?Y("negative",o("conn.notClosable"),{error:n}):Y("negative",o("conn.closeFailed"),te(n,o))}})()}},ruleAction:en,showRule:(e=!1)=>{He?.rule_id&&n("rules",C("",{tab:"list",rule:He.rule_id,edit:e?He.rule_id:null}))},canTrace:P(ie.data?.resources,"routing_trace",{whileLoading:!1})&&!!dn.detail?.traceQuery,traceConnection:()=>{dn.detail?.traceQuery&&n("rules",dn.detail.traceQuery)},showFlow:()=>{dn.detail&&ue&&n("flows",dn.detail.flowQuery)},onlyClient:()=>{dn.detail?.source&&(j(""),n("connections",Cn(t,{src:dn.detail.source,q:null})))},canExport:Ee.length>0,export:()=>Ge(Xe("connections","csv"),function(e,n){return[Ke(["id","target","domain","source","network","state","outbound","chain","rule","upload_bytes","download_bytes","started_at"]),...e.map(e=>Ke([e.id,e.dst,e.domain,e.src,e.network,e.state,e.outbound,N(e.chain,n).join(" > "),e.rule_expression,e.upload_bytes,e.download_bytes,e.started_at]))].join("\n")+"\n"}(Ee,de),"text/csv;charset=utf-8"),detailTitle:dn.detail?.title??"",notInSnapshot:!!O&&!He&&!!ae.data}}function An(e){const t=r(),l=Sn(e),i=l.detail,c={list:n.jsxs(n.Fragment,{children:[n.jsxs(se,{page:!0,children:[l.compact?n.jsxs("span",{className:"rp-filter-row",children:[n.jsx(le,{search:!0,label:t("ui.filter"),value:l.text,onChange:l.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),n.jsx(je,{label:l.filterMenu.active?t("conn.filtersActive",{n:l.filterMenu.active}):t("conn.filters"),count:l.filterMenu.active,submenus:l.filterMenu.submenus,children:t("conn.filters")})]}):n.jsxs(n.Fragment,{children:[n.jsx(le,{search:!0,label:t("ui.filter"),value:l.text,onChange:l.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),n.jsx(fe,{label:t("ui.network"),value:l.network,onChange:l.setNetwork,items:l.networks}),n.jsx(Ee,{side:!0,label:t("ui.outbound"),searchLabel:t("ui.filterOutbounds"),value:l.out,onChange:l.setOut,sections:l.outboundSections}),n.jsx(je,{label:t("conn.pick"),sections:l.picks,onAction:l.pick,searchLabel:t("conn.filterPick"),children:t("conn.pick")})]}),n.jsx(we,{label:t("conn.group"),side:!0,value:l.view.group,onChange:e=>l.updateView({group:e}),items:[{id:"source",label:t("conn.byClient")},{id:"outbound",label:t("ui.outbound")},{id:"none",label:t("conn.ungrouped")}]}),"none"!==l.view.group&&n.jsx(ae,{onPress:l.toggleCollapseAll,children:t(l.collapse.allCollapsed?"conn.expandAll":"conn.collapseAll")}),n.jsx(je,{label:t("conn.columns"),selectionMode:"multiple",items:l.columns,value:l.visibleColumns,onAction:l.toggleColumn,children:t("conn.columns")}),l.filtered&&n.jsx(ae,{quiet:!0,onPress:l.clear,children:t("ui.clearFilters")}),l.truncated&&n.jsx(de,{tone:"warn",children:t("conn.truncated")}),l.visibility&&n.jsx(k,{text:t("conn.visibilityNote"),children:n.jsx(de,{children:l.visibility})}),n.jsx("span",{className:"rp-grow"}),l.canClose&&n.jsx(ie,{label:t("conn.closeAll"),...l.closeAll}),n.jsxs(ae,{isDisabled:!l.canExport,onPress:l.export,children:[n.jsx(Ce,{}),t("conn.export")]})]}),n.jsxs("div",{className:"rp-with-panel","data-open":i?"":void 0,children:[n.jsx(hn,{collection:l.collection,loading:l.loading,selected:l.sel,onSelect:l.select,selectOnFocus:l.wide,view:l.view,collapse:l.collapse,onToggleGroup:l.toggleCollapse,onSort:e=>l.updateView({sort:e}),rule:l.ruleAction.row}),n.jsx(re,{open:!!i,title:l.detailTitle,onClose:()=>l.select(null),children:i&&n.jsxs(n.Fragment,{children:[n.jsx(ce,{help:i.stateHelp,children:n.jsx(ve,{small:!0,tone:i.tone,children:i.status})}),n.jsxs("div",{className:"rp-cluster",children:[l.ruleAction.canAdd&&n.jsx(ae,{onPress:l.ruleAction.openAdd,children:t("rule.add")}),n.jsx(xe,{actions:[...l.ruleAction.canShow?[{id:"show-rule",label:t("conn.showRule"),onAction:()=>l.showRule()}]:[],...l.ruleAction.canEdit?[{id:"edit-rule",label:t("conn.editRule"),onAction:()=>l.showRule(!0)}]:[],...l.canViewFlow?[{id:"view-flow",label:t("conn.viewFlow"),onAction:l.showFlow}]:[],...l.canTrace?[{id:"trace",label:t("conn.trace"),onAction:l.traceConnection}]:[],...i.source?[{id:"only-client",label:t("conn.onlyThisClient"),onAction:l.onlyClient}]:[],...l.canClose&&i.closable?[{id:"close",label:t("conn.close"),negative:!0,isPending:l.close.pending,isDisabled:l.close.disabled||!!i.closeReason,reason:i.closeReason??void 0,onAction:l.close.run}]:[]]})]}),n.jsx(ye,{items:i.fields.map(([e,t])=>[e,"string"==typeof t?t:n.jsx(o,{ip:t.ip,address:t.address,sites:s(t.ip)})])}),n.jsx(ye,{items:[[t("ui.outbound"),n.jsx(a,{...i.outboundTag})],[t("conn.chain"),i.chain]]}),n.jsxs("div",{className:"rp-list",children:[n.jsx("span",{className:"rp-label",children:t("ui.rule")}),n.jsx(ue,{...i.rule})]})]})})]}),l.notInSnapshot&&n.jsx("span",{className:"rp-label",children:t("conn.notInSnapshot")}),n.jsx(Qe,{dialog:l.ruleAction.dialog})]}),traffic:n.jsx(en,{records:l.rows,outbounds:l.outboundKeys,latency:l.latency,latencyError:l.latencyError,retryLatency:l.retryLatency,truncated:l.truncated,uncounted:l.trafficUncounted,onSelect:l.openInList,loading:l.loading})};return n.jsxs("div",{className:"rp-page",children:[l.error&&n.jsx(f,{error:l.error,onRetry:l.retry}),n.jsx(ke,{page:!0,keepMounted:!0,label:t("nav.connections"),value:l.tab,onChange:l.setTab,items:oe().map(e=>({id:e.id,label:t(e.titleKey),content:c[e.id]}))})]})}export{An as Connections};
+import{r as e,j as n}from"./vendor-react-64fcanlc.js";import{i as t,I as o,a as s}from"./ipLookup-CdclczzV.js";import{N as l,O as a}from"./NodePath-DbG_-_A4.js";import{aW as i,u as r,at as c,as as u,a6 as d,o as p,aH as m,aN as h,c7 as b,C as g,E as f,a3 as w,ae as v,s as x,W as y,c8 as j,T as k,b_ as _,w as C,c9 as S,Z as A,ca as L,cb as N,a4 as T,a7 as M,r as R,t as O,X as P,cc as F,ac as W,cd as U,an as q,O as D,ce as E,b8 as H,cf as I,b9 as V,cg as Q,c1 as B,ch as G,ci as J,cj as K,V as X,au as Z,ck as z,J as Y,cl as $,aX as ee,A as ne,cm as te,cn as oe,co as se,bQ as le,B as ae,cp as ie,bG as re,aD as ce}from"./index-C06va4Yw.js";import{R as ue,B as de,u as pe,h as me,o as he,g as be,c as ge,S as fe,p as we,L as ve,n as xe,K as ye}from"./logs-BtAlqVqe.js";import{C as je}from"./AppearanceControls-CEVO9-aR.js";import{T as ke}from"./Tabs-PDr10lJU.js";import{b as _e,D as Ce,U as Se,F as Ae,S as Le,d as Ne,B as Te,L as Me,t as Re,r as Oe,f as Pe,g as Fe,p as We,o as Ue,k as qe,h as De}from"./activity-BoXvjA12.js";import{S as Ee}from"./SearchSelect-q5tbOYXk.js";import{D as He}from"./Table-Cc5T3jJO.js";import{T as Ie}from"./TimeCell-DSeESBN3.js";import{Q as Ve,u as Qe,R as Be}from"./useQuickRule-CCpuINzQ.js";import{u as Ge}from"./outbounds-ynHeqeCa.js";import{c as Je,d as Ke,e as Xe}from"./files-Dt8K7QfP.js";import{w as Ze}from"./labels-D8xxfRTQ.js";import{u as ze}from"./flows-C0jcpIhs.js";import{r as Ye}from"./rule-C_M_c6EN.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./LinkOut-BYZWxkzu.js";import"./Tag-D4suq1U_.js";import"./Select-hQ95uOjm.js";import"./ItemText-D6SGBgOi.js";import"./nodes-oXccX15o.js";import"./useGridSelectionCheckbox-inhSeUkV.js";import"./SearchList-LS4kpJXT.js";import"./Virtualizer-9R4wsZhf.js";import"./Checkbox-CsFZSc5N.js";import"./DaeCode-DEjXqvav.js";import"./daeTokens-BVtuNnWZ.js";import"./AddCircle-6b-rL1eo.js";import"./BackendText-DK5RWFKi.js";const $e=[0,2,3,1,4,5,6,7],en=e.memo(function({records:t,outbounds:o,latency:s,latencyError:l,retryLatency:a,truncated:w,uncounted:v,onSelect:x,loading:y}){const j=r(),k=_e(),_=c[u()],C=e.useCallback(e=>d(e,_),[_]),S=e.useMemo(()=>function(e,n){const t=new Map;let o,s=0,l=-1n;for(const a of e){if(null===a.upload_bytes||null===a.download_bytes){s++;continue}const e={id:a.id,up:Number(a.upload_bytes),down:Number(a.download_bytes),name:a.domain||a.dst||a.id},n=t.get(a.outbound);n?n.push(e):t.set(a.outbound,[e]);const i=BigInt(a.upload_bytes)+BigInt(a.download_bytes);i>l&&(l=i,o={...e,outbound:a.outbound})}return{series:[...t].map(([e,n])=>({outbound:e,points:n})).sort((e,t)=>i(n)(e.outbound??"",t.outbound??"")),unknown:s,heaviest:o,placed:e.length-s}}(t,_),[t,_]),A=e.useMemo(()=>{const e=o.filter(e=>"block"!==e);return S.series.map(n=>{return{id:n.outbound??"",label:p(n.outbound,j),color:(t=n.outbound,"block"===t?k.negative:k.cat[$e[Math.max(0,e.indexOf(t))%$e.length]]),points:n.points.map(e=>({id:e.id,x:e.up,y:e.down,name:e.name,detail:j("conn.chart.point",{download:C(e.down),upload:C(e.up)})}))};var t})},[S,o,k,j,C]),L=S.heaviest?[{label:j("conn.chart.busiest"),icon:n.jsx(m,{}),tint:"c3",value:S.heaviest.name,caption:p(S.heaviest.outbound,j)},{label:j("ui.download"),value:C(S.heaviest.down),icon:n.jsx(Ce,{}),tint:"c1"},{label:j("ui.upload"),value:C(S.heaviest.up),icon:n.jsx(Se,{}),tint:"c4"}]:[];if(y)return n.jsx(h,{panel:!0,shape:b});const N=S.unknown?j("conn.chart.sampleUnknown",{n:t.length,unknown:S.unknown}):j("conn.chart.sample",{n:t.length});return n.jsxs("div",{className:"rp-chart-page",children:[n.jsx(Ae,{facts:L,lead:!0}),n.jsxs(g,{title:j("conn.chart.title"),help:v?{title:j("conn.chart.title"),text:j("ui.trafficUncounted")}:void 0,note:N,children:[w&&n.jsx("p",{className:"rp-note",children:j("conn.truncated")}),S.placed>0&&n.jsxs(n.Fragment,{children:[n.jsx(Le,{label:j("conn.chart.title"),series:A,fmt:C,onSelect:x,regions:{above:j("conn.chart.moreDown"),below:j("conn.chart.moreUp")}}),n.jsx(Ne,{series:A}),n.jsx("p",{className:"rp-note",children:j("conn.chart.hint")})]})]}),s?n.jsx(nn,{latency:s}):l&&n.jsx(g,{title:j("ui.nodeLatency"),children:n.jsx(f,{error:l,onRetry:a})})]})});function nn({latency:e}){const t=r(),o=_e(),s=e=>v(e,t),l=c[u()],a=n=>!e.chains||n?o.cat[0]:o.muted;return n.jsx(g,{title:t("ui.nodeLatency"),note:t("conn.latency.sample",{n:e.samples.length,missing:e.missing}),children:e.samples.length?n.jsxs(n.Fragment,{children:[n.jsx("p",{className:"rp-note",children:t("conn.latency.percentiles",{p50:s(e.p50),p90:s(e.p90)})}),null!==e.weightedP50&&n.jsx("p",{className:"rp-note",children:e.unplaced?t("conn.latency.weightedUnplaced",{p50:s(e.weightedP50),n:e.unplaced}):t("conn.latency.weighted",{p50:s(e.weightedP50)})}),n.jsx(Te,{label:t("ui.nodeLatency"),points:e.samples.map(e=>({id:e.node,nodeName:!0,value:e.value,color:a(e.connections>0),lines:[e.name,s(e.value),...e.connections?[t("conn.chart.sample",{n:e.connections})]:[]]})),fmt:s}),e.chains&&n.jsxs("div",{className:"rp-legend",children:[n.jsx(Me,{swatch:a(!0),label:t("conn.latency.inUse"),value:w(e.used,l)}),n.jsx(Me,{swatch:a(!1),label:t("conn.latency.others"),value:w(e.samples.length-e.used,l)})]}),n.jsx("p",{className:"rp-note",children:t("conn.latency.hint")})]}):n.jsx("p",{className:"rp-note",children:t("conn.latency.pending")})})}const tn=[{id:"dst",label:"ui.target",minWidth:200,sortable:!0},{id:"src",label:"ui.device",minWidth:128,sortable:!0,drop:5},{id:"node",label:"nodes.node",minWidth:120,drop:3},{id:"rule",label:"ui.rule",minWidth:220,drop:2},{id:"state",label:"ui.state",minWidth:112,sortable:!0,drop:7},{id:"down",label:"ui.download",minWidth:96,sortable:!0,drop:4},{id:"downRate",label:"conn.f.downloadRate",minWidth:128,sortable:!0,drop:1},{id:"age",label:"ui.started",minWidth:132,sortable:!0,drop:6}],on=x.connectionsView,sn=e=>({allCollapsed:e,exceptions:new Set}),ln=(e,n)=>e.allCollapsed!==e.exceptions.has(n);function an(e,n){const t=new Set(e.exceptions);return t.delete(n)||t.add(n),{allCollapsed:e.allCollapsed,exceptions:t}}const rn=(e,n)=>"source"===n?y(e.src??void 0)??e.src??"—":e.outbound??"unknown",cn=(e,n,t)=>"source"===n?e:p(e,t),un=e=>"g:"+e,dn=e=>e.startsWith("g:")||e.startsWith("\\")?"\\"+e:e;function pn(e){const n={hidden:[],sort:null,group:"source"};try{const t=JSON.parse(e??"null");if(!t||"object"!=typeof t)return n;const o=Array.isArray(t.hidden)?t.hidden.map(e=>"chain"===e?"node":e):[],s=tn.filter(e=>o.includes(e.id)).map(e=>e.id),l=t.sort;return{hidden:s.length===tn.length?[]:s,sort:l&&tn.some(e=>e.sortable&&e.id===l.column)&&["ascending","descending"].includes(l.direction)?{column:l.column,direction:l.direction}:null,group:"none"===t.group||"outbound"===t.group?t.group:"source"}}catch{return n}}const mn=e=>e.target;function hn({collection:t,view:o,collapse:s,onToggleGroup:a,loading:i,selected:c,onSelect:u,selectOnFocus:d,onSort:p,rule:m}){const h=r(),[b,g]=j(442),f=e.useRef(m);e.useLayoutEffect(()=>{f.current=m});const w=e.useMemo(()=>{const e={dst:e=>n.jsx(k,{children:e.target}),src:e=>n.jsx(k,{className:"rp-code",children:e.source}),node:e=>n.jsx(l,{row:e}),rule:e=>n.jsxs("span",{className:"rp-rule",children:[n.jsx(ue,{...e.rule}),e.recomputed&&n.jsx(de,{tip:h("rule.sourceHelp.recomputed"),children:e.recomputed})]}),state:e=>e.state,down:e=>e.download,downRate:e=>e.downloadRate,age:e=>n.jsx(Ie,{at:e.startedAt})};return[...tn.filter(e=>!o.hidden.includes(e.id)).map(n=>({...n,label:h(n.label),grow:1,render:e[n.id]})),{id:"actions",actions:!0,label:h("ui.actions"),minWidth:88,grow:0,render:e=>{const t=f.current,o=!t.canAdd(e.seed);return n.jsx(Ve,{label:t.label(e.target),disabled:o,tip:t.noTarget,onPress:()=>f.current.open(e.seed)})}}]},[o.hidden,h]),v=e.useMemo(()=>t.map(e=>"connection"in e?e.connection:e),[t]),x=e.useMemo(()=>({grouped:"none"!==o.group,collapsed:e=>ln(s,e),onToggle:a}),[o.group,s,a]);return n.jsx("div",{ref:b,children:n.jsx(He,{label:h("nav.connections"),rowDetail:!0,cols:w,rows:v,height:g,selected:c&&dn(c),onSelect:u&&(e=>u(e&&(e=>e.startsWith("\\")?e.slice(1):e)(e))),selectOnFocus:d,reveal:!0,empty:h("conn.empty"),loading:i,sort:o.sort&&{column:String(o.sort.column),direction:o.sort.direction},onSort:p,getTextValue:mn,stream:!0,tree:x})})}const bn={userspace:"ov.v.userspace",ebpf:"ov.v.ebpf",mixed:"conn.observed.mixed"},gn={evaluation:"conn.chainSource.evaluation",reconstructed:"conn.chainSource.reconstructed",unknown:"ui.unknown"};function fn(e,n){const o=e.dst??"—",s=y(e.dst),l=s&&t(s)?{ip:s,address:o}:o,a=e.chain_source?[["conn.f.chainSource",gn[e.chain_source]?{key:gn[e.chain_source]}:e.chain_source]]:[];return[["ui.device",e.src??"—"],["conn.f.dst",l],["ui.domain",e.domain??"—"],["conn.f.ingress",Ze(e.ingress)],["conn.f.domainSource",Ze(e.domain_source)],...a,["ui.process",e.pname??"—"],["conn.f.observedBy",bn[e.observed_by]?{key:bn[e.observed_by]}:e.observed_by],["ui.upload",d(e.upload_bytes,n)],["ui.download",d(e.download_bytes,n)],["conn.f.uploadRate",T(e.upload_bytes_per_second,n)],["conn.f.downloadRate",T(e.download_bytes_per_second,n)],["conn.f.started",M(e.started_at,n)]]}const wn={observed:["conn.state.observed","conn.stateHelp.observed"],routing:["conn.state.routing","conn.stateHelp.routing"],dialing:["conn.state.dialing","conn.stateHelp.dialing"]};function vn(e,n){return Object.hasOwn(wn,e)?{title:n("ui.state"),text:Object.values(wn).map(([e,t])=>n("ui.valuePair",{label:n(e),value:n(t)}))}:null}const xn=e=>({domain:e.domain??null,dip:y(e.dst)??null,sip:y(e.src)??null,outbound:e.outbound,matched:e.rule_id&&"unknown"!==e.rule_source?{id:e.rule_id,expression:e.rule_expression}:null});const yn=new WeakMap;function jn(e,n,t,o,s,l){const a=e=>{const n=yn.get(e);if(n&&n.locale===t&&n.names===o&&n.rulesListed===s&&n.t===l)return n.row;const a={id:dn(e.id),target:e.domain||e.dst||"—",seed:xn(e),source:e.src??"—",node:U(e,l,o),nodeName:!W(e.outbound)&&e.chain.length>0,path:F(e,l,o),rule:{expression:e.rule_expression,href:Oe(e.rule_id,s)},recomputed:"recomputed"===e.rule_source?l("conn.recomputed"):null,state:A(L,e.state,l),download:d(e.download_bytes,t),downloadRate:T(e.download_bytes_per_second,t),startedAt:e.started_at};return yn.set(e,{locale:t,names:o,rulesListed:s,t:l,row:a}),a};return function(e,n,t,o){let s=e;if(n.sort){const{column:r,direction:c}=n.sort,u=i(t);l=e=>{switch(r){case"dst":return e.domain||e.dst;case"src":return e.src;case"state":return A(L,e.state,o);case"down":return q(e.download_bytes);case"downRate":return q(e.download_bytes_per_second);case"age":return e.started_at?Date.parse(e.started_at):null;default:return null}},a=(e,n)=>{if(null==e)return null==n?0:1;if(null==n)return-1;const t="string"==typeof e&&"string"==typeof n?u(e,n):en?1:0;return"descending"===c?-t:t},s=e.map(e=>({item:e,key:l(e)})).sort((e,n)=>a(e.key,n.key)).map(e=>e.item)}var l,a;if("none"===n.group)return s.map(e=>({id:dn(e.id),connection:e}));const r=new Map;for(const i of s){const e=rn(i,n.group),t=r.get(e);t?t.push(i):r.set(e,[i])}return[...r].map(([e,n])=>({id:un(e),group:e,children:n,active:n.filter(e=>"active"===e.state).length,download:P(...n.map(e=>e.download_bytes))}))}(e,n,t,l).map(e=>"connection"in e?{id:e.id,connection:a(e.connection)}:{id:e.id,group:e.group,children:e.children.map(a),label:l("conn.groupCount",{name:cn(e.group,n.group,l),n:e.children.length}),totals:{down:d(e.download,t),state:l("conn.activeCount",{n:e.active})}})}const kn=oe().map(e=>e.id),_n=e=>{const n=new URLSearchParams(e);return["id","src","network","out","rule","q"].some(e=>n.has(e))?"list":"traffic"},Cn=(e,n)=>C(e,"list"===_n(e)?{tab:J(e,kn,"list"),...n}:n);function Sn({go:n,query:t}){const o=r(),s=c[u()],[l,a]=e.useState(()=>{try{return pn(localStorage.getItem(on))}catch{return pn(null)}}),d=H(I),m=H(V),[h,b]=e.useState(()=>sn(!1)),g=e.useCallback(e=>b(n=>an(n,e)),[]),f=e=>{const n={...l,...e};n.group!==l.group&&b(sn(!1)),a(n);try{localStorage.setItem(on,JSON.stringify(n))}catch{}},v=e.useMemo(()=>new URLSearchParams(t),[t]),[x,j]=e.useState(v.get("q")??""),k=v.get("network")??"all",T=v.get("out")??"all",M=v.get("rule")??"all",P=(e,o)=>n("connections",Cn(t,{[e]:"all"===o?null:o})),F=v.get("id"),[W,U]=e.useState(null);Q(v.get("q"),e=>j(e??""));const q=e.useRef(t);e.useEffect(()=>{q.current=t});const oe=e=>n("connections",Cn(q.current,{id:e})),se=e.useDeferredValue(x),le=B(v.get("src")??""),ae=me(le),ie=R(),re=!0===ie.data?.resources.connections.can_close,ce=O(ie.data?.resources,"rules",{whileLoading:!1}),ue=O(ie.data?.resources,"flows",{whileLoading:!1});G(ie.data?.resources);const de=Ge(),fe=he(ae.refetch),we=_n(t),ve=J(t,kn,we),xe=K(ae.data,"list"===ve),ye=K(ae.data,"traffic"===ve),je=e.useMemo(()=>X(xe),[xe]),ke=e.useMemo(()=>X(ye),[ye]),_e=O(ie.data?.resources,"nodes",{whileLoading:!1}),Ce=be(_e),Se=K(Ce.data,"traffic"===ve),Ae=e.useMemo(()=>_e&&Se?function(e,n,t){if(!n.some(e=>e.health?.length))return null;const o=[];let s=0;for(const i of n){const e=D(E(i.health??[]));void 0===e?s++:o.push({node:i.id,name:i.name,value:e,connections:0})}o.sort((e,n)=>e.value-n.value||i(t)(e.name,n.name));const l=new Map(o.map(e=>[e.node,e])),a=e.some(e=>e.chain?.length);let r=0;for(const i of e){const e=i.chain?.at(-1);if(void 0===e)continue;const n=l.get(e);n?n.connections++:r++}const c=o.reduce((e,n)=>e+n.connections,0);let u=0;const d=o.find(e=>(u+=e.connections)>=Math.max(1,Math.ceil(c/2))),p=o.map(e=>e.value);return{samples:o,chains:a,missing:s,unplaced:r,used:o.filter(e=>e.connections).length,p50:We(p,50),p90:We(p,90),weightedP50:c?d.value:null}}(ke,Se,s):null,[_e,Se,ke,s]),Le=Z("traffic"===ve&&O(ie.data?.resources,"runtime",{whileLoading:!1})),Ne=_e&&!Ce.data?Ce.error:null,Te=e.useMemo(()=>[...new Set(ke.map(e=>e.outbound))].sort((e,n)=>i(s)(e??"",n??"")),[ke,s]),Me=se.trim().toLowerCase(),Ee=e.useMemo(()=>je.filter(e=>("all"===k||e.network===k)&&("all"===T||e.outbound===T)&&("all"===M||e.rule_expression===M)&&(!Me||[e.dst,e.domain,e.src,e.pname,p(e.outbound,o),N(e.chain,de).join(" "),e.rule_expression].join(" ").toLowerCase().includes(Me))),[je,k,T,M,Me,de,o]),He=F?je.find(e=>e.id===F):void 0,[Ie,Ve]=e.useState(null);F||null===Ie||Ve(null);const Be=function(e,n){if(!e||"none"===n)return null;const t=rn(e,n);return{group:t,token:JSON.stringify([e.id,n,t])}}(He,l.group);var Ze,$e;Be&&Ie!==Be.token&&(Ve(Be.token),b((Ze=h,$e=Be.group,ln(Ze,$e)?an(Ze,$e):Ze)));const en=function(e,n){const t=r(),o=R().data?.resources,s=Qe(n),l=O(o,"rules",{whileLoading:!1})&&O(o,"config",{whileLoading:!1})&&!0===o?.config.writable?e?.rule_id??null:null,a=ze(!!l),i=pe(!!l),c=e&&xn(e);return{canAdd:!!c&&s.canAdd(c),row:{canAdd:s.canAdd,open:s.open,label:e=>t("conn.addRuleFor",{target:e}),noTarget:t("conn.ruleNoTarget")},canShow:O(o,"rules",{whileLoading:!1})&&!!e?.rule_id,canEdit:!!l&&Ye(a.data?.rules.find(e=>e.rule_id===l),i.data?.sources??[]),openAdd:()=>{c&&s.open(c)},dialog:s.dialog}}(He,n),nn=e.useMemo(()=>function(e,n,t,o,s,l,a){const i=new Set(e.flatMap(e=>e.outbound?[e.outbound]:[]));"all"!==s&&i.add(s);const r=e=>{const n=e.flatMap(e=>e?[e]:[]);return Fe(n,1/0).top},c=[{id:"all",label:a("conn.allOutbounds")},...[...i].map(e=>({id:e,label:p(e,a)}))];return{networks:[["all",a("ui.allCount",{n:e.length})],["tcp",a("ui.tcp")],["udp",a("ui.udp")]],outbounds:c,outboundSections:[{id:"outbounds",items:c}],picks:[{title:a("ui.device"),value:Pe("src",t??""),items:r(e.map(e=>y(e.src))).map(({key:e,count:n})=>({id:Pe("src",e),label:e,desc:w(n,l)}))},{title:a("ui.rule"),value:Pe("rule",o),items:r(e.map(e=>e.rule_expression)).map(({key:e,count:n})=>({id:Pe("rule",e),label:e,desc:w(n,l)}))}],visibility:n&&"full"!==n.visibility?a("none"===n.visibility?"conn.visibilityNone":"conn.visibilityPartial"):null}}(je,xe,le,M,T,s,o),[je,xe,le,M,T,s,o]),cn=ge(O(ie.data?.resources,"groups",{whileLoading:!1})).data,un=e.useMemo(()=>{const e=function(e,n,t,o,s){return e?{id:e.id,title:e.domain||e.dst||e.id,tone:"blocked"===e.state||"failed"===e.state?"err":"active"===e.state?"ok":"info",status:t("ui.aside",{text:A(L,e.state,t),note:e.network.toUpperCase()}),chain:S(e,t,o),outbound:e.outbound,rule:{expression:e.rule_expression,href:Oe(e.rule_id,s)},fields:fn(e,n).map(([e,n])=>[t(e),"string"==typeof n||"ip"in n?n:t(n.key,n.params)]),flowQuery:C("",{tab:"records",...e.flow_id?{id:e.flow_id}:{connection_id:e.id}}),traceQuery:e.domain||y(e.dst)?Re({network:"udp"===e.network?"udp":"tcp",domain:e.domain??"",dst_ip:y(e.dst),dst_port:_(e.dst),src_ip:y(e.src),src_port:_(e.src),pname:e.pname??""}):null,source:e.src?y(e.src)??e.src:null,closable:"active"===e.state||"dialing"===e.state||"routing"===e.state,closeReason:"ebpf"===e.observed_by?t("conn.notClosable"):null,stateHelp:vn(e.state,t)}:null}(He,s,o,de,ce);return e&&{...e,outboundTag:Ue(e.outbound,cn,o)}},[He,s,o,de,ce,cn]),dn={...nn,detail:un},mn=e.useMemo(()=>jn(Ee,l,s,de,ce,o),[Ee,l,s,de,ce,o]),hn=e=>{const o=De(String(e),["src","rule"]);"src"===o?.kind?(j(""),n("connections",Cn(t,{src:o.value&&le!==o.value?o.value:null,q:null}))):"rule"===o?.kind&&P("rule",M===o.value?"all":o.value)},bn=function(e,n,t){const[o,s]=e.picks,l=(e,n,t,o,s)=>({filter:e,label:n,sections:[{title:n,items:t,value:o}],searchLabel:s});return{active:["all"!==n.network,"all"!==n.out,!!n.src,"all"!==n.rule].filter(Boolean).length,submenus:[l("network",t("ui.network"),e.networks.map(([e,n])=>({id:e,label:n})),n.network),l("out",t("ui.outbound"),e.outbounds,n.out,t("ui.filterOutbounds")),l("src",o.title,[{id:Pe("src",""),label:t("conn.allDevices")},...o.items],o.value,t("ui.filterDevices")),l("rule",s.title,[{id:Pe("rule","all"),label:t("conn.allRules")},...s.items],s.value,t("ui.filterRules"))]}}(nn,{network:k,out:T,src:le,rule:M},o),gn={network:e=>P("network",e),out:e=>P("out",e),src:hn,rule:hn},wn={active:bn.active,submenus:bn.submenus.map(({filter:e,...n})=>({...n,sections:n.sections.map(n=>({...n,onChange:gn[e]}))}))},yn=e.useCallback(e=>n("connections",C(t,{tab:"list",id:e})),[n,t]);return{...dn,tab:ve,setTab:e=>n("connections",z(t,e,"traffic"===we?we:null)),openInList:yn,trafficUncounted:qe(Le.data),view:l,updateView:f,collapse:h,toggleCollapse:g,toggleCollapseAll:()=>b(sn(!h.allCollapsed)),wide:d,text:x,setText:j,network:k,out:T,sel:F,select:oe,collection:mn,rows:ke,outboundKeys:Te,latency:Ae,latencyError:Ne,retryLatency:Ce.refetch,setNetwork:e=>P("network",e),setOut:e=>P("out",e),pick:hn,compact:m,filterMenu:wn,columns:tn.map(e=>({id:e.id,label:o(e.label)})),visibleColumns:tn.filter(e=>!l.hidden.includes(e.id)).map(e=>e.id),toggleColumn:e=>{const n=String(e),t=l.hidden.includes(n)?l.hidden.filter(e=>e!==n):[...l.hidden,n];t.length{j(""),n("connections",Cn(t,{network:null,out:null,rule:null,q:null,src:null}))},error:ae.error,retry:ae.refetch,loading:ae.loading&&!ae.data,truncated:!!ae.data?.truncated,canClose:re,canViewFlow:ue,closeAll:{confirmationText:W?.query?o("all"===W.query.type?"conn.closeAllLive":"tcp"===W.query.type?"conn.closeAllLiveTcp":"conn.closeAllLiveUdp",le?{n:W.count??W.ids.length,source:le}:{n:W.count??W.ids.length,source:o("conn.anySource")}):o("conn.closeAllHelp",{n:W?.ids.length??0}),open:!!W,setOpen:e=>U(e?"all"!==v.get("scope")||"all"!==k||le||"all"!==T||"all"!==M||Me?function(e,n){const t=e.map(e=>e.id),o=null!=n.bulkLimit&&t.length>n.bulkLimit;return n.narrowed||n.truncated||o?{ids:t}:{ids:t,query:{type:n.network,src:n.src,all:!0}}}(Ee,{network:k,src:le,narrowed:"all"!==T||"all"!==M||!!Me,truncated:!!ae.data?.truncated,bulkLimit:ie.data?.resources.connections.max_bulk_close}):{ids:[],query:{type:"all",all:!0},count:(ae.data?.total_tcp??0)+(ae.data?.total_udp??0)}:null),isDisabled:!Ee.length||!!fe.busy||x!==se,isPending:"all"===fe.busy,onConfirm:async()=>{if(W)try{const e=await fe.closeAll(W);if(!e)return;oe(null),Y($(e),o("conn.closedAll",{closed:e.closed,skipped:e.skipped}))}catch(e){return o("ui.valuePair",{label:o("conn.closeFailed"),value:ee(e,o)})}},onAbort:fe.cancel},close:{pending:fe.busy===He?.id,disabled:!!fe.busy,run:()=>{(async()=>{if(!dn.detail)return;const{id:e}=dn.detail;try{if(!(await fe.close(e)))return;new URLSearchParams(q.current).get("id")===e&&oe(null),Y("positive",o("conn.closed",{name:dn.detail.title}))}catch(n){n instanceof ne&&"state_conflict"===n.code?Y("negative",o("conn.notClosable"),{error:n}):Y("negative",o("conn.closeFailed"),te(n,o))}})()}},ruleAction:en,showRule:(e=!1)=>{He?.rule_id&&n("rules",C("",{tab:"list",rule:He.rule_id,edit:e?He.rule_id:null}))},canTrace:O(ie.data?.resources,"routing_trace",{whileLoading:!1})&&!!dn.detail?.traceQuery,traceConnection:()=>{dn.detail?.traceQuery&&n("rules",dn.detail.traceQuery)},showFlow:()=>{dn.detail&&ue&&n("flows",dn.detail.flowQuery)},onlyClient:()=>{dn.detail?.source&&(j(""),n("connections",Cn(t,{src:dn.detail.source,q:null})))},canExport:Ee.length>0,export:()=>Ke(Xe("connections","csv"),function(e,n){return[Je(["id","target","domain","source","network","state","outbound","chain","rule","upload_bytes","download_bytes","started_at"]),...e.map(e=>Je([e.id,e.dst,e.domain,e.src,e.network,e.state,e.outbound,N(e.chain,n).join(" > "),e.rule_expression,e.upload_bytes,e.download_bytes,e.started_at]))].join("\n")+"\n"}(Ee,de),"text/csv;charset=utf-8"),detailTitle:dn.detail?.title??"",notInSnapshot:!!F&&!He&&!!ae.data}}function An(e){const t=r(),l=Sn(e),i=l.detail,c={list:n.jsxs(n.Fragment,{children:[n.jsxs(se,{page:!0,children:[l.compact?n.jsxs("span",{className:"rp-filter-row",children:[n.jsx(le,{search:!0,label:t("ui.filter"),value:l.text,onChange:l.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),n.jsx(je,{label:l.filterMenu.active?t("conn.filtersActive",{n:l.filterMenu.active}):t("conn.filters"),count:l.filterMenu.active,submenus:l.filterMenu.submenus,children:t("conn.filters")})]}):n.jsxs(n.Fragment,{children:[n.jsx(le,{search:!0,label:t("ui.filter"),value:l.text,onChange:l.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),n.jsx(fe,{label:t("ui.network"),value:l.network,onChange:l.setNetwork,items:l.networks}),n.jsx(Ee,{side:!0,label:t("ui.outbound"),searchLabel:t("ui.filterOutbounds"),value:l.out,onChange:l.setOut,sections:l.outboundSections}),n.jsx(je,{label:t("conn.pick"),sections:l.picks,onAction:l.pick,searchLabel:t("conn.filterPick"),children:t("conn.pick")})]}),n.jsx(we,{label:t("conn.group"),side:!0,value:l.view.group,onChange:e=>l.updateView({group:e}),items:[{id:"source",label:t("conn.byClient")},{id:"outbound",label:t("ui.outbound")},{id:"none",label:t("conn.ungrouped")}]}),"none"!==l.view.group&&n.jsx(ae,{onPress:l.toggleCollapseAll,children:t(l.collapse.allCollapsed?"conn.expandAll":"conn.collapseAll")}),n.jsx(je,{label:t("conn.columns"),selectionMode:"multiple",items:l.columns,value:l.visibleColumns,onAction:l.toggleColumn,children:t("conn.columns")}),l.filtered&&n.jsx(ae,{quiet:!0,onPress:l.clear,children:t("ui.clearFilters")}),l.truncated&&n.jsx(de,{tone:"warn",children:t("conn.truncated")}),l.visibility&&n.jsx(k,{text:t("conn.visibilityNote"),children:n.jsx(de,{children:l.visibility})}),n.jsx("span",{className:"rp-grow"}),l.canClose&&n.jsx(ie,{label:t("conn.closeAll"),...l.closeAll}),n.jsxs(ae,{isDisabled:!l.canExport,onPress:l.export,children:[n.jsx(Ce,{}),t("conn.export")]})]}),n.jsxs("div",{className:"rp-with-panel","data-open":i?"":void 0,children:[n.jsx(hn,{collection:l.collection,loading:l.loading,selected:l.sel,onSelect:l.select,selectOnFocus:l.wide,view:l.view,collapse:l.collapse,onToggleGroup:l.toggleCollapse,onSort:e=>l.updateView({sort:e}),rule:l.ruleAction.row}),n.jsx(re,{open:!!i,title:l.detailTitle,onClose:()=>l.select(null),children:i&&n.jsxs(n.Fragment,{children:[n.jsx(ce,{help:i.stateHelp,children:n.jsx(ve,{small:!0,tone:i.tone,children:i.status})}),n.jsxs("div",{className:"rp-cluster",children:[l.ruleAction.canAdd&&n.jsx(ae,{onPress:l.ruleAction.openAdd,children:t("rule.add")}),n.jsx(xe,{actions:[...l.ruleAction.canShow?[{id:"show-rule",label:t("conn.showRule"),onAction:()=>l.showRule()}]:[],...l.ruleAction.canEdit?[{id:"edit-rule",label:t("conn.editRule"),onAction:()=>l.showRule(!0)}]:[],...l.canViewFlow?[{id:"view-flow",label:t("conn.viewFlow"),onAction:l.showFlow}]:[],...l.canTrace?[{id:"trace",label:t("conn.trace"),onAction:l.traceConnection}]:[],...i.source?[{id:"only-client",label:t("conn.onlyThisClient"),onAction:l.onlyClient}]:[],...l.canClose&&i.closable?[{id:"close",label:t("conn.close"),negative:!0,isPending:l.close.pending,isDisabled:l.close.disabled||!!i.closeReason,reason:i.closeReason??void 0,onAction:l.close.run}]:[]]})]}),n.jsx(ye,{items:i.fields.map(([e,t])=>[e,"string"==typeof t?t:n.jsx(o,{ip:t.ip,address:t.address,sites:s(t.ip)})])}),n.jsx(ye,{items:[[t("ui.outbound"),n.jsx(a,{...i.outboundTag})],[t("conn.chain"),i.chain]]}),n.jsxs("div",{className:"rp-list",children:[n.jsx("span",{className:"rp-label",children:t("ui.rule")}),n.jsx(ue,{...i.rule})]})]})})]}),l.notInSnapshot&&n.jsx("span",{className:"rp-label",children:t("conn.notInSnapshot")}),n.jsx(Be,{dialog:l.ruleAction.dialog})]}),traffic:n.jsx(en,{records:l.rows,outbounds:l.outboundKeys,latency:l.latency,latencyError:l.latencyError,retryLatency:l.retryLatency,truncated:l.truncated,uncounted:l.trafficUncounted,onSelect:l.openInList,loading:l.loading})};return n.jsxs("div",{className:"rp-page",children:[l.error&&n.jsx(f,{error:l.error,onRetry:l.retry}),n.jsx(ke,{page:!0,keepMounted:!0,label:t("nav.connections"),value:l.tab,onChange:l.setTab,items:oe().map(e=>({id:e.id,label:t(e.titleKey),content:c[e.id]}))})]})}export{An as Connections};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Copy-CO66tox2.js b/luci-app-honk/root/etc/honk/doona/assets/Copy-Dw2ag2LB.js
similarity index 96%
rename from luci-app-honk/root/etc/honk/doona/assets/Copy-CO66tox2.js
rename to luci-app-honk/root/etc/honk/doona/assets/Copy-Dw2ag2LB.js
index cbb80cd2f..8af6ccecb 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Copy-CO66tox2.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Copy-Dw2ag2LB.js
@@ -1 +1 @@
-import{r as c,j as r}from"./vendor-react-64fcanlc.js";import{u as s,dP as o,J as l,I as t}from"./index-CUHkLMAp.js";function a(){const r=s();return c.useCallback(async c=>{const s=await o(c);l(s?"positive":"negative",r(s?"ui.recordCopied":"ui.recordCopyFailed"))},[r])}function e(c){return r.jsxs(t,{...c,children:[r.jsx("path",{fill:"currentColor",d:"m11.75,18h-7.5c-1.24023,0-2.25-1.00977-2.25-2.25v-7.5c0-1.24023,1.00977-2.25,2.25-2.25.41406,0,.75.33594.75.75s-.33594.75-.75.75c-.41309,0-.75.33691-.75.75v7.5c0,.41309.33691.75.75.75h7.5c.41309,0,.75-.33691.75-.75,0-.41406.33594-.75.75-.75s.75.33594.75.75c0,1.24023-1.00977,2.25-2.25,2.25Z"}),r.jsx("path",{fill:"currentColor",d:"m6.75,5c-.41406,0-.75-.33594-.75-.75,0-1.24023,1.00977-2.25,2.25-2.25.41406,0,.75.33594.75.75s-.33594.75-.75.75c-.41309,0-.75.33691-.75.75,0,.41406-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m13,3.5h-2c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75h2c.41406,0,.75.33594.75.75s-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m13,14h-2c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75h2c.41406,0,.75.33594.75.75s-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m15.75,14c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75c.41309,0,.75-.33691.75-.75,0-.41406.33594-.75.75-.75s.75.33594.75.75c0,1.24023-1.00977,2.25-2.25,2.25Z"}),r.jsx("path",{fill:"currentColor",d:"m17.25,5c-.41406,0-.75-.33594-.75-.75,0-.41309-.33691-.75-.75-.75-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75c1.24023,0,2.25,1.00977,2.25,2.25,0,.41406-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m17.25,9.75c-.41406,0-.75-.33594-.75-.75v-2c0-.41406.33594-.75.75-.75s.75.33594.75.75v2c0,.41406-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m6.75,9.75c-.41406,0-.75-.33594-.75-.75v-2c0-.41406.33594-.75.75-.75s.75.33594.75.75v2c0,.41406-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m8.25,14c-1.24023,0-2.25-1.00977-2.25-2.25,0-.41406.33594-.75.75-.75s.75.33594.75.75c0,.41309.33691.75.75.75.41406,0,.75.33594.75.75s-.33594.75-.75.75Z"})]})}export{e as C,a as u};
+import{r as c,j as r}from"./vendor-react-64fcanlc.js";import{u as s,dR as o,J as l,I as t}from"./index-C06va4Yw.js";function a(){const r=s();return c.useCallback(async c=>{const s=await o(c);l(s?"positive":"negative",r(s?"ui.recordCopied":"ui.recordCopyFailed"))},[r])}function e(c){return r.jsxs(t,{...c,children:[r.jsx("path",{fill:"currentColor",d:"m11.75,18h-7.5c-1.24023,0-2.25-1.00977-2.25-2.25v-7.5c0-1.24023,1.00977-2.25,2.25-2.25.41406,0,.75.33594.75.75s-.33594.75-.75.75c-.41309,0-.75.33691-.75.75v7.5c0,.41309.33691.75.75.75h7.5c.41309,0,.75-.33691.75-.75,0-.41406.33594-.75.75-.75s.75.33594.75.75c0,1.24023-1.00977,2.25-2.25,2.25Z"}),r.jsx("path",{fill:"currentColor",d:"m6.75,5c-.41406,0-.75-.33594-.75-.75,0-1.24023,1.00977-2.25,2.25-2.25.41406,0,.75.33594.75.75s-.33594.75-.75.75c-.41309,0-.75.33691-.75.75,0,.41406-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m13,3.5h-2c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75h2c.41406,0,.75.33594.75.75s-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m13,14h-2c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75h2c.41406,0,.75.33594.75.75s-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m15.75,14c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75c.41309,0,.75-.33691.75-.75,0-.41406.33594-.75.75-.75s.75.33594.75.75c0,1.24023-1.00977,2.25-2.25,2.25Z"}),r.jsx("path",{fill:"currentColor",d:"m17.25,5c-.41406,0-.75-.33594-.75-.75,0-.41309-.33691-.75-.75-.75-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75c1.24023,0,2.25,1.00977,2.25,2.25,0,.41406-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m17.25,9.75c-.41406,0-.75-.33594-.75-.75v-2c0-.41406.33594-.75.75-.75s.75.33594.75.75v2c0,.41406-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m6.75,9.75c-.41406,0-.75-.33594-.75-.75v-2c0-.41406.33594-.75.75-.75s.75.33594.75.75v2c0,.41406-.33594.75-.75.75Z"}),r.jsx("path",{fill:"currentColor",d:"m8.25,14c-1.24023,0-2.25-1.00977-2.25-2.25,0-.41406.33594-.75.75-.75s.75.33594.75.75c0,.41309.33691.75.75.75.41406,0,.75.33594.75.75s-.33594.75-.75.75Z"})]})}export{e as C,a as u};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Coverage-BJRxyviT.js b/luci-app-honk/root/etc/honk/doona/assets/Coverage-CsDZglAg.js
similarity index 81%
rename from luci-app-honk/root/etc/honk/doona/assets/Coverage-BJRxyviT.js
rename to luci-app-honk/root/etc/honk/doona/assets/Coverage-CsDZglAg.js
index 4e3d02fb2..460668915 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Coverage-BJRxyviT.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Coverage-CsDZglAg.js
@@ -1 +1 @@
-import{an as e,b3 as l,Z as r,u as s,T as a}from"./index-CUHkLMAp.js";import{j as n}from"./vendor-react-64fcanlc.js";import{L as o}from"./logs-C6Kb44nw.js";const t={userspace_tcp:"flow.userspaceTcp",userspace_udp:"flow.userspaceUdp",kernel_direct:"flow.kernelDirect",kernel_block:"flow.kernelBlock",dns_intercept:"flow.dnsIntercept",kernel_bypass:"flow.kernelBypass"},c={full:"flow.full",partial:"flow.partialVisibility",none:"ui.none"};function p(s,a,n){const o=Object.entries(s.coverage).filter(([,e])=>"full"!==e),p=e(s.dropped_records),i=p?a("flow.dropped",{n:p}):null;return o.length||i?{summary:o.length?a("flow.coverageSummary",{n:o.length}):null,detail:l(n,o.map(([e,l])=>a("ui.valuePair",{label:r(t,e,a),value:r(c,l,a)}))),dropped:i}:null}function i({view:e}){const l=s();return n.jsxs("div",{className:"rp-cluster",role:"group","aria-label":l("flow.coverage"),children:[e.summary&&n.jsx(a,{text:e.detail,children:n.jsx(o,{small:!0,tone:"warn",children:e.summary})}),e.dropped&&n.jsx(o,{small:!0,tone:"warn",children:e.dropped})]})}export{i as C,p as c};
+import{an as e,b3 as l,Z as r,u as s,T as a}from"./index-C06va4Yw.js";import{j as n}from"./vendor-react-64fcanlc.js";import{L as o}from"./logs-BtAlqVqe.js";const t={userspace_tcp:"flow.userspaceTcp",userspace_udp:"flow.userspaceUdp",kernel_direct:"flow.kernelDirect",kernel_block:"flow.kernelBlock",dns_intercept:"flow.dnsIntercept",kernel_bypass:"flow.kernelBypass"},c={full:"flow.full",partial:"flow.partialVisibility",none:"ui.none"};function p(s,a,n){const o=Object.entries(s.coverage).filter(([,e])=>"full"!==e),p=e(s.dropped_records),i=p?a("flow.dropped",{n:p}):null;return o.length||i?{summary:o.length?a("flow.coverageSummary",{n:o.length}):null,detail:l(n,o.map(([e,l])=>a("ui.valuePair",{label:r(t,e,a),value:r(c,l,a)}))),dropped:i}:null}function i({view:e}){const l=s();return n.jsxs("div",{className:"rp-cluster",role:"group","aria-label":l("flow.coverage"),children:[e.summary&&n.jsx(a,{text:e.detail,children:n.jsx(o,{small:!0,tone:"warn",children:e.summary})}),e.dropped&&n.jsx(o,{small:!0,tone:"warn",children:e.dropped})]})}export{i as C,p as c};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Delete-D-jw0Qv4.js b/luci-app-honk/root/etc/honk/doona/assets/Delete-DqJAS65M.js
similarity index 92%
rename from luci-app-honk/root/etc/honk/doona/assets/Delete-D-jw0Qv4.js
rename to luci-app-honk/root/etc/honk/doona/assets/Delete-DqJAS65M.js
index bf3b733c3..acdb41c64 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Delete-D-jw0Qv4.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Delete-DqJAS65M.js
@@ -1 +1 @@
-import{j as c}from"./vendor-react-64fcanlc.js";import{I as r}from"./index-CUHkLMAp.js";function l(l){return c.jsxs(r,{...l,children:[c.jsx("path",{fill:"currentColor",d:"M8.249 15.021c-.4 0-.733-.317-.748-.72l-.25-6.5c-.017-.414.307-.763.72-.779H8c.4 0 .733.317.748.72l.25 6.5c.017.414-.307.763-.72.778zM11.751 15.021h-.03c-.413-.016-.737-.365-.72-.779l.25-6.5c.015-.403.348-.72.748-.72h.03c.413.016.737.365.72.779l-.25 6.5c-.015.403-.348.72-.748.72"}),c.jsx("path",{fill:"currentColor",d:"M17 4h-3.5v-.75C13.5 2.01 12.49 1 11.25 1h-2.5C7.51 1 6.5 2.01 6.5 3.25V4H3c-.414 0-.75.336-.75.75s.336.75.75.75h.52l.422 10.342C3.99 17.052 4.98 18 6.19 18h7.62c1.211 0 2.2-.948 2.248-2.158L16.48 5.5H17c.414 0 .75-.336.75-.75S17.414 4 17 4m-9-.75c0-.413.337-.75.75-.75h2.5c.413 0 .75.337.75.75V4H8zm6.56 12.531c-.017.404-.346.719-.75.719H6.19c-.404 0-.733-.315-.75-.719L5.02 5.5h9.96z"})]})}export{l as D};
+import{j as c}from"./vendor-react-64fcanlc.js";import{I as r}from"./index-C06va4Yw.js";function l(l){return c.jsxs(r,{...l,children:[c.jsx("path",{fill:"currentColor",d:"M8.249 15.021c-.4 0-.733-.317-.748-.72l-.25-6.5c-.017-.414.307-.763.72-.779H8c.4 0 .733.317.748.72l.25 6.5c.017.414-.307.763-.72.778zM11.751 15.021h-.03c-.413-.016-.737-.365-.72-.779l.25-6.5c.015-.403.348-.72.748-.72h.03c.413.016.737.365.72.779l-.25 6.5c-.015.403-.348.72-.748.72"}),c.jsx("path",{fill:"currentColor",d:"M17 4h-3.5v-.75C13.5 2.01 12.49 1 11.25 1h-2.5C7.51 1 6.5 2.01 6.5 3.25V4H3c-.414 0-.75.336-.75.75s.336.75.75.75h.52l.422 10.342C3.99 17.052 4.98 18 6.19 18h7.62c1.211 0 2.2-.948 2.248-2.158L16.48 5.5H17c.414 0 .75-.336.75-.75S17.414 4 17 4m-9-.75c0-.413.337-.75.75-.75h2.5c.413 0 .75.337.75.75V4H8zm6.56 12.531c-.017.404-.346.719-.75.719H6.19c-.404 0-.733-.315-.75-.719L5.02 5.5h9.96z"})]})}export{l as D};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Dns-BoEQQlrw.js b/luci-app-honk/root/etc/honk/doona/assets/Dns-fSskIZZh.js
similarity index 77%
rename from luci-app-honk/root/etc/honk/doona/assets/Dns-BoEQQlrw.js
rename to luci-app-honk/root/etc/honk/doona/assets/Dns-fSskIZZh.js
index 9f2dc156c..4d21315e1 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Dns-BoEQQlrw.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Dns-fSskIZZh.js
@@ -1 +1 @@
-import{r as e,j as s}from"./vendor-react-64fcanlc.js";import{cq as a,W as t,c0 as n,Z as r,ae as l,a7 as i,a3 as d,Y as c,an as o,A as u,u as m,af as h,r as p,cf as x,H as g,ch as y,t as f,w as b,h as j,cj as v,at as w,as as _,cr as N,cs as k,b7 as S,ce as C,J as T,cl as q,aX as M,ct as R,b$ as L,aF as A,al as F,E,cu as D,bl as P,cv as W,C as O,c as B,S as U,ak as H,T as K,bO as I,cw as $,cn as Q,bP as J,cx as V,B as X,cy as Y,aD as z,bF as G,co as Z}from"./index-CUHkLMAp.js";import{D as ee}from"./Delete-D-jw0Qv4.js";import{s as se,l as ae,b as te,m as ne,C as re,F as le,B as ie,L as de,W as ce,n as oe,q as ue,D as me}from"./activity-B3PmJo_X.js";import{i as he,I as pe,a as xe}from"./ipLookup-CY9MTfz2.js";import{u as ge,s as ye,k as fe,t as be,v as je,i as ve,S as we,j as _e,p as Ne,B as ke,K as Se,L as Ce,A as Te}from"./logs-C6Kb44nw.js";import{T as qe}from"./Tabs-DiTlqyjA.js";import{D as Me}from"./Table-DX856nrS.js";import{T as Re}from"./TimeCell-N-r54xmV.js";import{c as Le,d as Ae,e as Fe}from"./files-Dt8K7QfP.js";import{a as Ee}from"./rule-D4-Og0AG.js";import{d as De,u as Pe}from"./nodes-BYMoo8M1.js";import{u as We,R as Oe,Q as Be}from"./useQuickRule-Cd5z6aFL.js";/* empty css */import"./_commonjsHelpers-CXUWDbkB.js";import"./ItemText-CnEXu0-f.js";import"./AppearanceControls-E-VPhjIz.js";import"./LinkOut-B2JdPfjI.js";import"./Select-BA0NS1_z.js";import"./useGridSelectionCheckbox-CTBMGgmQ.js";import"./Virtualizer-UMC7L0o2.js";import"./Checkbox-8Iqnc6T1.js";import"./DaeCode-DEjXqvav.js";import"./daeTokens-BVtuNnWZ.js";import"./AddCircle-D2cMd6zF.js";import"./SearchSelect-Fy-2ASgN.js";import"./SearchList-DMvmI1K7.js";import"./BackendText-Dtw6qhij.js";import"./flows-DS-lcTPn.js";function Ue(e,s,a,n,r){return{domain:e,dip:null,sip:(r&&t(r))??null,outbound:null,matched:null,dns:{type:s,answers:Ee(a),upstream:n,query:{name:e,type:s}}}}const He=(e,s,a)=>({domain:null,dip:e,sip:null,outbound:null,matched:null,dns:{type:a,answers:[e],upstream:null,query:{name:s,type:a}}}),Ke={forced:"dns.route.forced","dns.routing":"dns.route.rules",default:"dns.route.default"};function Ie(e,s,a){return{fields:[[a("ui.state"),e.status],[a("ui.upstream"),e.upstream??"—"],[a("dns.routeSource"),r(Ke,e.route.source,a)],[a("dns.routeRule"),e.route.rule??"—"],[a("ui.elapsed"),l(e.elapsed_ms,a)]],answers:(e.answers??[]).map(e=>{const t=Ee([e])[0],r=t?n(t):void 0;return{data:e.data,name:(l=e.name,i=s,l.replace(/\.$/,"").toLowerCase()===i.replace(/\.$/,"").toLowerCase()?null:e.name),type:e.type,ttl:a("dns.ttl",{ttl:e.ttl}),lookup:r&&he(r)?r:null};var l,i}),cacheText:a(e.cached?"dns.hit":"dns.miss"),cacheTone:e.cached?void 0:"warn"}}function $e(e,s,a){return e?a instanceof u&&503===a.status?"unavailable":s?"ready":a?"error":"loading":"unlisted"}const Qe=[{id:"full",label:"rule.kind.domain"},{id:"suffix",label:"rule.kind.domainSuffix"},{id:"keyword",label:"rule.kind.domainKeyword"},{id:"regex",label:"dns.matchRegex"}],Je=e=>e.trim().toLowerCase().replace(/\.$/,"");function Ve(e,s){if(!s.trim())return()=>!0;if("regex"===e){const e=function(e){try{return new RegExp(e,"iu")}catch{return null}}(s);return e&&(s=>e.test(Je(s)))}if("keyword"===e){const e=s.trim().toLowerCase();return s=>Je(s).includes(e)}const a=Je(s),t="suffix"===e&&a.startsWith("."),n=t?a.slice(1):a;return n?"full"===e?e=>Je(e)===n:e=>{const s=Je(e);return s.endsWith("."+n)||!t&&s===n}:null}function Xe({go:s,query:t}){const n=m(),r=h(),l=p(),i=e.useMemo(()=>new URLSearchParams(t),[t]),[d,c]=e.useState(i.get("domain")??""),[o,u]=e.useState(i.get("type")??"A"),[w,_]=e.useState(!1);x(i.get("domain"),e=>c(e??"")),x(i.get("type"),e=>u(e??"A"));const[N,k]=e.useState(null),{busy:S,error:C,run:T}=g({rethrow:!0}),q=l.data?.resources,M=e.useMemo(()=>function(e,s,t,n,r,l){const i=s?.dns_query.record_types??[],d="all"===t?i.length>0:i.includes(t);return{types:i,choices:[...i.map(e=>({id:e,label:e})),{id:"all",label:l("dns.allTypes")}],disabled:r||!s?.dns_query.available||!d||!n.trim(),reason:!s||r?null:s.dns_query.available?d?null:l("all"===t?"dns.noTypes":"dns.typeUnsupported"):l("dns.queryUnavailable"),showCache:!!s?.dns_cache.available,cards:e?.results.map(s=>({id:s.type,title:`${e.domain} ${s.type}`,...Ie(s,e.domain,l),seed:Ue(e.domain,s.type,s.answers??[],s.upstream,null),answerSeeds:(s.answers??[]).map(a=>Ee([a]).length?{address:a.data,seed:He(a.data,e.domain,s.type)}:null)}))??[],tabs:a(s).map(e=>({id:e.id,label:l(e.titleKey)}))}}(N,q,o,d,!!S,n),[N,q,o,d,S,n]),R=M.tabs.map(e=>e.id),L=i.has("domain")||i.has("device"),A=R.includes("log")?L?"log":"stats":R.includes("query")?"query":R[0]??"query",F=y(t,R,A),E=f(q,"config",{whileLoading:!1}),D=ge("query"===F&&E&&f(q,"dns_query",{whileLoading:!1})),P=e.useMemo(()=>E?function(e,s){const a=[...new Set((e??[]).flatMap(e=>e.content?De(e.content).map(Pe):[]))];return a.length?[{id:"",label:s("dns.upstreamAuto")},...a.map(e=>({id:e,label:e}))]:[]}(D.data?.sources,n):[],[E,D.data,n]),[W,O]=e.useState(""),B=P.some(e=>e.id===W)?W:"";D.data&&W&&!B&&O("");const U=async(e={domain:d,type:o})=>{try{await T("query",async s=>{const a=await ye(r.dnsQuery,e.domain.trim(),"all"===e.type?M.types:[e.type],q?.dns_query.limits?.max_types_per_request??1,s,w?"bypass":"normal",B||void 0);return s.aborted||k(a),a})}catch{}},H=f(q,"dns_query",{whileLoading:!1})&&M.types.length>0,K=We(s,{queryAgain:H?e=>{const a=M.types.includes(e.type)?e.type:"all";s("dns",b("",{tab:"query",domain:e.name.replace(/\.$/,""),type:a,run:"1"}))}:void 0}),I=i.has("run")&&q?t:null,$=e.useEffectEvent(e=>{const a=new URLSearchParams(e);s("dns",b(e,{run:null}),{replace:!0}),U({domain:a.get("domain")??"",type:a.get("type")??"A"})});return e.useEffect(()=>{null!==I&&$(I)},[I]),{...M,rule:{...K,label:e=>n(f(q,"dns_rules",{whileLoading:!1})?"dns.addRequestRuleFor":"dns.addRoutingRuleFor",{domain:e})},domain:d,setDomain:c,type:o,setType:u,bypassCache:w,setBypassCache:_,upstreams:P,upstream:B,setUpstream:O,pending:"query"===S,queryError:C,submit:()=>{U()},setTab:e=>s("dns",v(t,e,q&&!L?A:null)),tab:F,filterDomain:i.get("domain")??"",filterDevice:i.get("device")??"",cacheHref:R.includes("cache")?j("dns",{tab:"cache"}):null,logHref:(e,s)=>j("dns",{tab:"log",[e]:s}),logLinks:[...f(q,"dns_rules",{whileLoading:!1})?[{id:"rules",label:n("rule.dnsTitle"),onAction:()=>s("rules","tab=dns")}]:[],...q?.runtime_settings.available?[{id:"recording",label:n("ui.recordingSettings"),onAction:()=>s("settings","card=runtime")}]:[]],logEnabled:q?.dns_log.available,viewCache:()=>s("dns",b(t,{tab:"cache",domain:N?.domain??""})),clearCacheFilter:()=>s("dns",b(t,{tab:"cache",domain:null}))}}function Ye(s){const a=m(),t=w[_()],[n,r]=e.useState(!1),l=be(!k(),n),[i,c]=e.useState(s?"keyword":"suffix"),[o,u]=e.useState(s),[h,p]=e.useState("all");x(s,e=>{u(e),c(e?"keyword":"suffix"),p("all")});const g=[...new Set([...l.capabilities.data?.resources.dns_query.record_types??[],...(l.cache.data?.entries??[]).map(e=>e.type)])],y=e.useMemo(()=>({kind:i,text:o}),[i,o]),f=N(y,250),b=f!==y,j=l.cache.data?.entries,{matches:v,error:S,pending:C}=function(s,a,t){const n=e.useMemo(()=>(s??[]).filter(e=>"all"===t||e.type===t),[s,t]),r="regex"===a.kind&&!!a.text.trim(),[l,i]=e.useState(null);e.useEffect(()=>{if(!r)return;const e=new Worker(new URL(""+new URL("match.worker-B2aIccpg.js",import.meta.url).href,import.meta.url),{type:"module"});let s,t=!0;const l=(r,l)=>{t&&(t=!1,clearTimeout(s),e.terminate(),i({candidates:n,pattern:a,matches:r?.map(e=>n[e])??[],error:l??(null===r?"dns.invalidRegex":void 0)}))};return e.onmessage=r=>{t&&("ready"===r.data?(s=window.setTimeout(()=>l([],"dns.regexTimeout"),1e3),e.postMessage({text:a.text,names:n.map(e=>e.domain)})):l(r.data))},e.onerror=e=>{e.preventDefault(),l([],"dns.matchFailed")},()=>{t=!1,clearTimeout(s),e.terminate()}},[r,n,a]);const d=e.useMemo(()=>{if(r)return null;const e=Ve(a.kind,a.text);return{matches:e?n.filter(s=>e(s.domain)):[],error:e?void 0:"dns.invalidName"}},[r,n,a]);if(d)return{...d,pending:!1};const c=l?.candidates===n&&l.pattern===a;return{matches:c?l.matches:[],error:c?l.error:void 0,pending:!c}}(j,f,h),R=!!o.trim()||"all"!==h||!!s,L=e.useMemo(()=>function(e,s,a,t,n,r=e?.entries??[],l=!1){const i=s?.dns_cache;return{readable:!!i?.available&&!0===i.read,fields:[[n("dns.entries"),e?d(e.total,t):"—"]],coverage:e?["positive","negative","persistent"].filter(s=>!e.coverage[s]).map(e=>({id:e,text:"persistent"===e?n("dns.memoryOnly"):n("ui.valuePair",{label:n("positive"===e?"dns.positive":"dns.negative"),value:n("dns.notCovered")})})):[],deleteBy:{name:!!i?.available&&!0===i.delete_name,entry:!!i?.available&&!0===i.delete_entry},confirmationText:e?n("dns.flushConfirm",{n:e.total}):n("dns.flushConfirmAll"),flushDisabled:!!a||!s?.dns_cache.available||!s.dns_cache.flush,flushReason:!i||a||i.available&&i.flush?null:n("dns.flushUnsupported"),deleteReason:!(i&&!a&&r.length>0)||i.available&&i.delete_entry?null:n("dns.deleteUnsupported"),empty:n(s?.dns_cache.available&&s.dns_cache.read?l?"dns.emptyFiltered":"dns.empty":"dns.cacheUnavailable"),rows:r.map(e=>({id:e.entry_id,domain:e.domain,type:e.type,status:e.status,expiresAt:e.expires_at,staleUntil:e.stale_until,deleteLabel:n("dns.deleteEntry",{domain:e.domain,type:e.type}),seed:Ue(e.domain,e.type,[],null,null),pending:a===e.entry_id,disabled:!!a||!s?.dns_cache.available||!s.dns_cache.delete_entry}))}}(l.cache.data,l.capabilities.data?.resources,l.busy,t,a,b?[]:v,R),[l.cache.data,l.capabilities.data,l.busy,t,a,b,v,R]),A="full"===i&&!!o.trim()&&L.deleteBy.name,{remove:F}=l,E=e.useCallback(e=>{F(e).then(e=>e&&T("positive",a("dns.deleted",{n:e.deleted})),e=>T("negative",a("dns.deleteFailed"),q(e,a)))},[F,a]);return{...L,includeExpired:n,setIncludeExpired:r,matchKind:i,matchText:o,matchType:h,matchAvailable:L.readable||L.deleteBy.name||L.deleteBy.entry,filtered:R,clearMatches:()=>{u(""),p("all"),c("suffix")},setMatchType:p,setMatchKind:c,setMatchText:e=>{const s=function(e,s){return s.startsWith("*.")?{kind:"suffix",text:s.slice(2)}:{kind:e,text:s}}(i,e);c(s.kind),u(s.text)},matchKinds:Qe.map(e=>({id:e.id,label:a(e.label)})),matchTypes:[{id:"all",label:a("dns.allTypes")},...g.map(e=>({id:e,label:e}))],matchError:S?a(S):void 0,matchReason:L.deleteBy.entry||!L.deleteBy.name||A||l.busy?null:a("dns.matchNameOnly"),matchPending:"delete-match"===l.busy,matchDisabled:!!l.busy||b||C||!!S||!A&&!v.length||!o.trim()&&"all"===h||!(L.deleteBy.entry||A),matchConfirmation:A?a("dns.deleteNameConfirm",{name:o.trim(),type:"all"===h?a("dns.allTypes"):h}):a("dns.deleteMatchingConfirm",{n:v.length}),matchListed:v.slice(0,100),matchMore:v.length>100?a("dns.matchMore",{n:v.length-100}):null,removeMatching:async()=>{try{if(A){const e=await l.removeName({name:o.trim(),type:"all"===h?void 0:[h]});return void(e&&T("positive",a("dns.deleted",{n:e.deleted})))}const e=await l.removeMany(v.map(e=>e.entry_id));if(!e)return;e.failed?e.deleted?T("negative",a("dns.deletePartial",{deleted:e.deleted,n:e.failed})):T("negative",a("dns.deleteAllFailed",{n:e.failed})):T("positive",a("dns.deleted",{n:e.deleted}))}catch(e){return a("dns.deleteMatchingFailed",{error:M(e,a)})}},error:l.cache.error,retry:l.cache.refetch,loading:(l.cache.loading||l.capabilities.loading)&&!l.cache.data||b||C,flushPending:"flush"===l.busy,remove:E,flush:async()=>{try{const e=await l.flush();e&&T("positive",a("dns.flushed",{matched:e.matched,deleted:e.deleted}))}catch(e){return a("dns.flushFailed",{error:M(e,a)})}},abortFlush:()=>{l.cancel(),l.cache.refetch()}}}function ze(s){const a=m(),t=w[_()],[n,r]=A(),[l,i]=e.useState(!1),u=je(s,!r&&l);u.data&&!l&&i(!0);const h=e.useMemo(()=>function(e,s,a){if(!e)return null;const{usage:t,coverage:n}=e,r=e=>{const a=o(e);return null===a?"—":d(a,s)},l=t?.entry_capacity??null,i=t&&null!==l?c(t.entries,l):null;return{note:t?null===l?a("dns.chart.usageFacts",{entries:r(t.entries)}):void 0:a("dns.chart.cacheNote",{n:e.total}),usage:t&&null!==l&&null!==i?{meter:o(l)?{value:i,valueLabel:i>0&&i<.5?"<"+a("ui.percent",{n:1}):a("ui.percent",{n:Math.round(i)})}:null,facts:[{label:a("dns.chart.entries"),value:r(t.entries)},{label:a("dns.chart.capacity"),value:r(l)}]}:null,coverage:a("dns.chart.coverage",{kinds:[n.positive&&a("dns.chart.positive"),n.negative&&a("dns.chart.negative")].filter(Boolean).join(a("ui.listSeparator")),persistent:a(n.persistent?"dns.chart.persistent":"dns.chart.memoryOnly")})}}(u.data,t,a),[u.data,t,a]);return{ref:n,card:h,state:$e(s,!!h,u.error),error:u.error,retry:u.refetch}}function Ge(s,a,t){const r=m(),d=w[_()],[c,o]=e.useState(a);x(a,o);const[y,f]=e.useState("all"),[b,j]=e.useState(t);x(t,j);const v=h(),q=p(),M=N(b),A=n(M),F=""!==M.trim()&&!A,[E,D]=e.useState(A);F||A===E||D(A);const P={name:N(c),type:y,src:F?E:A},W=JSON.stringify(P),O=fe(P,!0===s,!k()),[B,U]=e.useState(null),[H,K]=e.useState(!1),I=g({scope:W});x(W,()=>U(null));const{data:$,newerWaiting:Q}=e.useMemo(()=>function(e,s){const a=s&&new Set(s.records.map(e=>e.id));return{data:s??e,newerWaiting:!!a&&!!e?.records.some(e=>!a.has(e.id))}}(O.data,B),[O.data,B]),J=()=>{I.run("older",async e=>{if(!$?.next_cursor)return;let s;U($);try{s=await v.dnsLog({name:P.name.trim()||void 0,type:"all"===y?void 0:y,src:P.src,cursor:$.next_cursor,limit:$.limit},e)}catch(a){if(!(a instanceof u)||e.aborted)throw a;const s=R(a);if(!(410===a.status&&"snapshot_expired"===a.code||400===a.status&&"invalid_request"===a.code)&&!s)throw a;return s&&await L(a.retryAfter,e),U(null),O.refetch(),void T("info",r("dns.olderExpired"))}e.aborted||U(function(e,s){const a=new Set(e.records.map(e=>e.id));return{...e,records:[...e.records,...s.records.filter(e=>!a.has(e.id))],next_cursor:s.next_cursor}}($,s))})},V=()=>{I.cancel(),U(null);const e=O.refetch();e&&(K(!0),e.finally(()=>K(!1)))},[X,Y]=e.useState(null),z=S(C),G=q.data?.resources.dns_query.record_types,Z=e.useMemo(()=>function(e,s,a,t=[]){const n=e?.records??[];return{choices:[{id:"all",label:a("dns.allTypes")},...[...new Set([...t,...n.map(e=>e.question.type)])].map(e=>({id:e,label:e}))],total:e?a("dns.logTotal",{n:e.total}):"",totalHelp:e?{title:a("dns.logTotal",{n:e.total}),text:a("dns.logTotalHelp")}:null,loaded:e?.next_cursor?a("dns.logLoaded",{n:n.length}):"",empty:a(void 0===s?"ui.loading":s?"dns.logEmpty":"dns.logUnavailable"),rows:n.map(e=>({id:e.id,observedAt:e.observed_at,name:e.question.name,type:e.question.type,seed:Ue(e.question.name,e.question.type,e.answers,e.upstream,e.src),source:e.src??"—",resultError:"NOERROR"!==e.status,result:"NOERROR"!==e.status?e.status:e.answers.map(e=>e.data).join(", ")||"—",cached:e.cached,upstream:e.cached?a("dns.hit"):e.upstream??"—",elapsed:l(e.elapsed_ms,a)}))}}($,s,r,G),[$,s,r,G]),ee=e.useMemo(()=>function(e,s,a,t){const n=e?.records.find(e=>e.id===s);if(!n)return null;const r=Ie(n,n.question.name,t);return{id:n.id,title:n.question.name,answers:r.answers,fields:[[t("ui.type"),n.question.type],[t("ui.device"),n.src??"—"],r.fields[0],[t("ui.cache"),r.cacheText],...r.fields.slice(1),[t("ui.time"),i(n.observed_at,a)]]}}($,X,d,r),[$,X,d,r]);return{...Z,detail:ee,detailTitle:ee?.title??"",name:c,newerWaiting:Q,setName:o,type:y,setType:f,src:b,setSrc:j,srcError:F?r("ui.invalidIp"):void 0,selected:ee?X:null,setSelected:Y,wide:z,error:I.error??O.error,loading:O.loading&&!$,hasOlder:!!$?.next_cursor,loadingOlder:!!I.busy,loadOlder:J,refreshing:H,refresh:V,retry:I.error?J:V,export:()=>{return Ae(Fe("dns-log","csv"),(e=$?.records??[],[Le(["id","observed_at","src","name","type","status","cached","upstream","route_source","route_rule","elapsed_ms","answers"]),...e.map(e=>Le([e.id,e.observed_at,e.src,e.question.name,e.question.type,e.status,e.cached?"true":"false",e.upstream,e.route.source,e.route.rule,e.elapsed_ms,e.answers.map(e=>e.data).join(" ")]))].join("\n")+"\n"),"text/csv;charset=utf-8");var e}}}const Ze={cached:"dns.outcome.cached",answered:"dns.outcome.answered",nxdomain:"dns.outcome.nxdomain",failed:"dns.outcome.failed"};function es({enabled:a,links:t}){const n=m(),{log:r,cacheListed:l,configHref:i}=function(s){const a=fe({},!0===s,!k()),t=p().data?.resources,n=f(t,"config",{whileLoading:!1}),r=ge(!0===s&&n),l=r.data?.sources,i=e.useMemo(()=>n&&l?se(l,"dns"):null,[n,l]);return{log:a,cacheListed:f(t,"dns_cache",{whileLoading:!1})&&!0===t?.dns_cache.read,configHref:i}}(a);if(!1===a)return s.jsx(F,{children:n("dns.logUnavailable")});if(void 0===a)return null;const d=r.error,c=r.data?null:!d||s.jsx(F,{children:n("dns.chart.noLog")}),o=d?s.jsx(E,{error:d,onRetry:r.refetch}):ae(r.data,r.limit)?s.jsx("p",{className:"rp-note",children:n("dns.chart.shortPage",{n:r.data.records.length,limit:r.limit})}):null;return s.jsx(as,{records:r.data?.records??ss,pending:c,notice:o,cacheListed:l,links:{...t,config:i}})}const ss=[];function as({records:a,pending:t,notice:n,cacheListed:r,links:i}){const d=m(),c=te(),o=w[_()],u=e.useMemo(()=>ne(a,o),[a,o]),h={cached:c.positive,answered:c.cat[2],nxdomain:c.notice,failed:c.negative},p=e=>d("ui.percent",{n:null===e?0:Math.round(100*e)}),x=(e,s)=>{const a=s?e/s:0;return e>0&&a<.005?"<"+d("ui.percent",{n:1}):e.995?">"+d("ui.percent",{n:99}):p(a)},g=e=>({id:e.id,value:e.value,color:h[e.outcome],lines:[e.name,l(e.value,d),d(Ze[e.outcome])]}),y=!0===t,f=e=>y?"bars"===e?s.jsx(U,{shape:"bars",count:7,typical:!0}):s.jsx(H,{holds:"swarm",children:s.jsx(U,{shape:"block",typical:!0})}):t??(u.total<5?s.jsx(F,{children:d("dns.chart.tooFew")}):null),b=f("block"),j=[{label:d("dns.chart.median"),value:l(u.typical,d),icon:s.jsx(D,{}),tint:"c1"},{label:d("dns.chart.p95"),value:l(u.slowest,d),icon:s.jsx(re,{}),tint:"c4"},{label:d("dns.chart.cacheRate"),value:p(u.cacheRate),icon:s.jsx(P,{}),tint:"c2"},{label:d("dns.chart.failureRate"),value:p(u.failureRate),icon:s.jsx(W,{}),tint:"c5",tone:u.counts.failed?"negative":void 0}];return s.jsxs("div",{className:"rp-chart-page",children:[n,(y||!b)&&s.jsx(le,{facts:j,loading:y}),s.jsxs("div",{className:"rp-g21",children:[s.jsx(O,{title:d("dns.chart.speed",{n:u.samples.length}),note:b?void 0:d("dns.chart.sample",{n:u.total,uncached:u.uncached,upstream:u.samples.length}),aside:i.config&&s.jsx(B,{appearance:"link",href:i.config,children:d("dns.openConfig")}),children:b??s.jsxs(s.Fragment,{children:[s.jsx(ie,{label:d("dns.chart.speed",{n:u.samples.length}),points:u.samples.map(g),marks:null!==u.typical&&null!==u.slowest?[{value:u.typical,label:d("dns.chart.typical",{value:l(u.typical,d)})},{value:u.slowest,label:d("dns.chart.slowest",{value:l(u.slowest,d)})}]:[],rows:u.upstreams.map(e=>({id:e.upstream,label:e.upstream,detail:d("dns.chart.upstream",{n:e.samples.length,median:l(e.median,d)}),points:e.samples.map(g),mark:e.median})),fmt:e=>l(e,d)}),s.jsxs("div",{className:"rp-legend",children:[["answered","nxdomain","failed"].map(e=>s.jsx(de,{swatch:h[e],label:d(Ze[e])},e)),s.jsx(de,{swatch:s.jsx("i",{className:"rp-median-key","aria-hidden":"true"}),label:d("dns.chart.medianKey")})]})]})}),s.jsx(O,{title:d("dns.chart.outcomes"),children:b??s.jsx(ce,{label:d("dns.chart.outcomes"),shares:oe.map(e=>({id:e,label:d(Ze[e]),count:u.counts[e],color:h[e],text:d("dns.chart.share",{n:u.counts[e],share:x(u.counts[e],u.total)})}))})})]}),s.jsxs("div",{className:"rp-g21",children:[s.jsx(ns,{analysis:u,standIn:f("bars"),logHref:i.log}),s.jsx(ts,{listed:r,href:i.cache})]})]})}function ts({listed:e,href:a}){const t=m(),{ref:n,...r}=ze(e);return s.jsx(O,{ref:n,title:t("dns.chart.cache"),note:"ready"===r.state?r.card?.note:void 0,aside:e&&a&&s.jsx(B,{appearance:"link",href:a,children:t("dns.viewCache")}),children:"unlisted"===r.state?s.jsx(F,{children:t("dns.cacheUnavailable")}):"unavailable"===r.state?s.jsx(F,{children:t("dns.cacheBusy")}):"error"===r.state?s.jsx(E,{error:r.error,onRetry:r.retry}):r.card?s.jsxs(s.Fragment,{children:[r.card.usage&&s.jsxs("div",{className:"rp-form",children:[r.card.usage.meter&&s.jsx(_e,{label:t("dns.chart.usage"),...r.card.usage.meter}),s.jsx(le,{facts:r.card.usage.facts})]}),s.jsx("p",{className:"rp-note",children:r.card.coverage})]}):s.jsx(U,{shape:"rows",typical:!0})})}function ns({analysis:a,standIn:t,logHref:n}){const r=m(),l=te(),[i,d]=e.useState("device"),c="device"===i?a.devices:a.domains,o=c.top[0]?.count??1;return s.jsx(O,{title:r("dns.chart.ranking"),aside:!t&&s.jsx(we,{label:r("dns.chart.ranking"),value:i,onChange:d,items:[["device",r("dns.chart.byDevice")],["domain",r("dns.chart.byDomain")]]}),children:t??s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"rp-list",children:c.top.map(e=>s.jsx(ve,{label:null===e.key?r("dns.chart.resolver"):s.jsx(B,{appearance:"link",href:n("device"===i?"device":"domain",e.key),children:s.jsx(K,{children:e.key})}),value:r("dns.chart.count",{n:e.count}),pct:e.count/o*100,color:"device"===i?l.cat[0]:l.cat[3]},e.key??""))}),c.rest>0&&s.jsx("p",{className:"rp-note",children:r("dns.chart.rest",{n:c.rest})})]})})}function rs({answer:e,children:a}){return s.jsxs("div",{className:"rp-dns-answer",children:[s.jsx("span",{className:"rp-code",children:e.lookup?s.jsx(pe,{ip:e.lookup,address:e.data,sites:xe(e.lookup)}):e.data}),s.jsxs("span",{className:"meta",children:[e.name&&s.jsx("span",{children:e.name}),s.jsx("span",{children:e.type}),s.jsx("span",{children:e.ttl})]}),a]})}function ls(e){const a=m(),t=Xe(e),n=s.jsxs(s.Fragment,{children:[t.queryError&&s.jsx(E,{error:t.queryError,onRetry:t.submit,message:e=>a("dns.queryFailed",{error:e})}),s.jsx(I,{className:Y(),onSubmit:e=>{e.preventDefault(),t.submit()},children:s.jsx($,{reason:t.reason,children:s.jsxs(Q,{children:[s.jsx(J,{side:!0,label:a("ui.domain"),value:t.domain,onChange:t.setDomain,width:280,placeholder:"example.com"}),s.jsx(Ne,{label:a("ui.type"),side:!0,value:t.type,onChange:t.setType,items:t.choices}),t.upstreams.length>0&&s.jsx(Ne,{label:a("ui.upstream"),side:!0,value:t.upstream,onChange:t.setUpstream,items:t.upstreams}),s.jsx(V,{isSelected:t.bypassCache,onChange:t.setBypassCache,children:a("dns.bypassCache")}),s.jsx(X,{accent:!0,type:"submit",isPending:t.pending,isDisabled:t.disabled,children:a("dns.query")})]})})}),!t.cards.length&&!t.queryError&&s.jsx(F,{children:a("dns.queryIntro")}),t.cards.length>0&&s.jsx("div",{className:"rp-col",children:t.cards.map(e=>s.jsxs(O,{className:"rp-col",children:[s.jsxs("div",{className:"rp-row",children:[s.jsxs("div",{className:"rp-cluster",children:[s.jsx("h2",{className:"rp-h3",children:e.title}),s.jsx(ke,{tone:e.cacheTone,children:e.cacheText})]}),s.jsxs("div",{className:"rp-cluster",children:[t.rule.canAdd(e.seed)&&s.jsx(X,{quiet:!0,small:!0,onPress:()=>t.rule.open(e.seed),children:a("rule.add")}),t.showCache&&s.jsx(X,{quiet:!0,small:!0,onPress:t.viewCache,children:a("dns.viewCache")})]})]}),s.jsx(Se,{inline:!0,items:e.fields}),e.answers.length?s.jsx("div",{className:"rp-list",children:e.answers.map((n,r)=>{const l=e.answerSeeds[r];return s.jsx(rs,{answer:n,children:l&&t.rule.canAdd(l.seed)&&s.jsx(X,{quiet:!0,small:!0,label:a("dns.addRuleFor",{value:l.address}),onPress:()=>t.rule.open(l.seed),children:a("rule.add")})},r)})}):s.jsx(F,{children:a("dns.noAnswers")})]},e.id))})]}),r={stats:s.jsx(es,{enabled:t.logEnabled,links:{cache:t.cacheHref,log:t.logHref}}),query:n,cache:s.jsx(is,{domain:t.filterDomain,clearFilter:t.clearCacheFilter,rule:t.rule}),log:s.jsx(ds,{enabled:t.logEnabled,initialName:t.filterDomain,initialSrc:t.filterDevice,links:t.logLinks,rule:t.rule})};return s.jsxs("div",{className:"rp-page",children:[s.jsx(qe,{page:!0,keepMounted:!0,label:a("nav.dns"),items:t.tabs.map(e=>({...e,content:r[e.id]})),value:t.tab,onChange:t.setTab}),s.jsx(Oe,{dialog:t.rule.dialog})]})}function is({domain:a,clearFilter:t,rule:n}){const r=m(),l=Ye(a),{remove:i}=l,d=e.useMemo(()=>[{id:"q",label:r("ui.domain"),text:"wrap",minWidth:320,isRowHeader:!0,render:e=>s.jsx("span",{className:"rp-code",children:e.domain})},{id:"t",label:r("ui.type"),minWidth:88,grow:0,drop:3,render:e=>e.type},{id:"s",label:r("ui.state"),minWidth:128,grow:0,render:e=>e.status},{id:"e",label:r("dns.expires"),minWidth:128,drop:2,render:e=>s.jsx(Re,{at:e.expiresAt})},{id:"st",label:r("dns.staleUntil"),minWidth:128,drop:1,render:e=>s.jsx(Re,{at:e.staleUntil})},{id:"a",actions:!0,label:r("ui.actions"),minWidth:104,grow:0,render:e=>s.jsxs("div",{className:"rp-cluster nowrap",children:[s.jsx(Be,{label:n.label(e.domain),disabled:!n.canAdd(e.seed),onPress:()=>n.open(e.seed)}),s.jsx(X,{quiet:!0,icon:!0,small:!0,label:e.deleteLabel,isPending:e.pending,isDisabled:e.disabled,onPress:()=>i(e.id),children:s.jsx(ee,{})})]})}],[r,i,n]);return s.jsxs(s.Fragment,{children:[l.error&&s.jsx(E,{error:l.error,onRetry:l.retry}),s.jsxs(Q,{page:!0,className:"top",children:[s.jsx(Se,{row:!0,items:l.fields}),l.coverage.map(e=>s.jsx(ke,{tone:"warn",children:e.text},e.id)),l.filtered&&s.jsx(X,{onPress:()=>{l.clearMatches(),t()},children:r("ui.clearFilters")}),s.jsx(V,{isSelected:l.includeExpired,onChange:l.setIncludeExpired,children:r("dns.includeExpired")}),s.jsx("span",{className:"rp-grow"}),s.jsx("div",{className:"rp-col",children:s.jsx($,{reason:l.flushReason,children:s.jsx(Z,{label:r("dns.flushAll"),confirmationText:l.confirmationText,isPending:l.flushPending,isDisabled:l.flushPending||l.flushDisabled,onConfirm:l.flush,onAbort:l.abortFlush})})})]}),l.matchAvailable&&s.jsx($,{reason:l.matchReason,children:s.jsxs(Q,{page:!0,children:[s.jsx(Ne,{side:!0,label:r("rule.kind"),value:l.matchKind,onChange:e=>l.setMatchKind(e),items:l.matchKinds}),s.jsx(J,{side:!0,label:r("dns.pattern"),value:l.matchText,onChange:l.setMatchText,error:l.matchError,help:"regex"===l.matchKind?{title:r("dns.pattern"),text:r("dns.regexHelp")}:void 0,width:280,placeholder:"example.com"}),s.jsx(Ne,{side:!0,label:r("ui.type"),value:l.matchType,onChange:l.setMatchType,items:l.matchTypes}),(l.deleteBy.name||l.deleteBy.entry)&&s.jsx(Z,{label:r("dns.deleteMatching"),confirmationText:l.matchConfirmation,details:s.jsxs("ul",{className:"rp-impact",children:[l.matchListed.map(e=>s.jsx("li",{children:s.jsxs("span",{className:"rp-cluster nowrap",children:[s.jsx(K,{className:"rp-code",children:e.domain}),s.jsx("span",{className:"rp-note",children:e.type})]})},e.entry_id)),l.matchMore&&s.jsx("li",{className:"rp-note",children:l.matchMore})]}),isPending:l.matchPending,isDisabled:l.matchDisabled,onConfirm:l.removeMatching,onAbort:l.abortFlush})]})}),s.jsx($,{reason:l.deleteReason,children:s.jsx(Me,{label:r("ui.cache"),height:442,fit:!0,rows:l.rows,loading:l.loading,empty:l.empty,cols:d})})]})}function ds({enabled:a,initialName:t,initialSrc:n,links:r,rule:l}){const i=m(),d=Ge(a,t,n),c=e.useMemo(()=>[{id:"t",label:i("ui.time"),minWidth:140,grow:0,render:e=>s.jsx(Re,{at:e.observedAt})},{id:"q",label:i("ui.domain"),minWidth:200,grow:2,isRowHeader:!0,render:e=>s.jsx(K,{children:e.name})},{id:"ty",label:i("ui.type"),minWidth:88,grow:0,drop:3,render:e=>e.type},{id:"s",label:i("ui.device"),minWidth:128,drop:2,render:e=>s.jsx(K,{className:"rp-code",children:e.source})},{id:"r",label:i("dns.result"),minWidth:160,grow:2,render:e=>e.resultError?s.jsx(Ce,{small:!0,tone:"err",children:e.result}):s.jsx(K,{className:"rp-code",children:e.result})},{id:"u",label:i("ui.upstream"),minWidth:128,drop:1,render:e=>e.cached?s.jsx(Ce,{small:!0,tone:"ok",children:e.upstream}):s.jsx(K,{children:e.upstream})},{id:"e",label:i("ui.elapsed"),minWidth:88,grow:0,drop:4,render:e=>e.elapsed},{id:"a",actions:!0,label:i("ui.actions"),minWidth:88,grow:0,render:e=>s.jsx(Be,{label:l.label(e.name),disabled:!l.canAdd(e.seed),onPress:()=>l.open(e.seed)})}],[i,l]);return s.jsxs(s.Fragment,{children:[s.jsxs(Q,{page:!0,children:[s.jsx(J,{search:!0,label:i("ui.domain"),value:d.name,onChange:d.setName,placeholder:i("dns.logFilterHint"),width:240}),s.jsx(Ne,{label:i("ui.type"),side:!0,value:d.type,onChange:d.setType,items:d.choices}),s.jsx(J,{side:!0,label:i("ui.device"),value:d.src,onChange:d.setSrc,error:d.srcError,placeholder:"10.0.0.12",width:200})]}),s.jsxs(Q,{page:!0,children:[s.jsxs("span",{className:"rp-cluster",children:[d.total&&s.jsx(z,{help:d.totalHelp,children:s.jsx("span",{className:"rp-label",children:d.total})}),d.loaded&&s.jsx("span",{className:"rp-label",children:d.loaded})]}),s.jsx("span",{className:"rp-grow"}),s.jsx("span",{className:"rp-cluster nowrap",children:s.jsx(Te,{actions:[{id:"refresh",label:i("ui.refresh"),icon:s.jsx(ue,{className:"rp-spin-on-press"}),isPending:d.refreshing,onAction:d.refresh},{id:"export",label:i("dns.exportLog"),icon:s.jsx(me,{}),isDisabled:!d.rows.length,onAction:d.export},...r,...d.hasOlder?[{id:"older",label:i("dns.loadOlder"),isPending:d.loadingOlder,onAction:d.loadOlder}]:[]]})})]}),d.error&&s.jsx(E,{error:d.error,onRetry:d.retry}),d.newerWaiting&&s.jsx("p",{className:"rp-note",children:i("dns.newerWaiting")}),s.jsxs("div",{className:"rp-with-panel","data-open":d.detail?"":void 0,children:[s.jsx(Me,{label:i("dns.log"),rowDetail:!0,height:520,rows:d.rows,selected:d.selected,onSelect:d.setSelected,selectOnFocus:d.wide,loading:d.loading,empty:d.empty,cols:c}),s.jsx(G,{open:!!d.detail,title:d.detailTitle,onClose:()=>d.setSelected(null),children:d.detail&&s.jsxs(s.Fragment,{children:[s.jsx(Se,{inline:!0,items:d.detail.fields}),d.detail.answers.length?s.jsx("div",{className:"rp-list",children:d.detail.answers.map((e,a)=>s.jsx(rs,{answer:e},a))}):s.jsx(F,{children:i("dns.noAnswers")})]})})]}),d.hasOlder&&s.jsx("div",{className:"rp-narrow-only",children:s.jsx("div",{className:"rp-cluster",children:s.jsx(X,{small:!0,isPending:d.loadingOlder,onPress:d.loadOlder,children:i("dns.loadOlder")})})})]})}export{ls as Dns};
+import{r as e,j as s}from"./vendor-react-64fcanlc.js";import{cr as a,W as t,c1 as n,Z as r,ae as l,a7 as i,a3 as d,Y as c,an as o,A as u,u as m,af as p,r as h,cg as x,H as g,ci as y,t as f,w as b,h as j,ck as v,at as w,as as _,cs as N,ct as k,b8 as S,cf as C,J as T,cm as q,aX as R,cu as M,c0 as L,aF as A,al as F,E,cv as D,bm as P,cw as W,C as O,c as B,S as U,ak as H,T as K,bP as I,cx as $,co as Q,bQ as z,cy as G,B as J,cz as V,aD as X,bG as Y,cp as Z}from"./index-C06va4Yw.js";import{D as ee}from"./Delete-DqJAS65M.js";import{s as se,l as ae,b as te,m as ne,C as re,F as le,B as ie,L as de,W as ce,n as oe,q as ue,D as me}from"./activity-BoXvjA12.js";import{i as pe,I as he,a as xe}from"./ipLookup-CdclczzV.js";import{u as ge,s as ye,k as fe,t as be,v as je,i as ve,S as we,j as _e,p as Ne,B as ke,K as Se,L as Ce,A as Te}from"./logs-BtAlqVqe.js";import{T as qe}from"./Tabs-PDr10lJU.js";import{D as Re}from"./Table-Cc5T3jJO.js";import{T as Me}from"./TimeCell-DSeESBN3.js";import{c as Le,d as Ae,e as Fe}from"./files-Dt8K7QfP.js";import{a as Ee}from"./rule-C_M_c6EN.js";import{d as De,u as Pe}from"./nodes-oXccX15o.js";import{u as We,R as Oe,Q as Be}from"./useQuickRule-CCpuINzQ.js";/* empty css */import"./_commonjsHelpers-CXUWDbkB.js";import"./ItemText-D6SGBgOi.js";import"./AppearanceControls-CEVO9-aR.js";import"./LinkOut-BYZWxkzu.js";import"./Select-hQ95uOjm.js";import"./useGridSelectionCheckbox-inhSeUkV.js";import"./Virtualizer-9R4wsZhf.js";import"./Checkbox-CsFZSc5N.js";import"./DaeCode-DEjXqvav.js";import"./daeTokens-BVtuNnWZ.js";import"./AddCircle-6b-rL1eo.js";import"./SearchSelect-q5tbOYXk.js";import"./SearchList-LS4kpJXT.js";import"./BackendText-DK5RWFKi.js";import"./flows-C0jcpIhs.js";function Ue(e,s,a,n,r){return{domain:e,dip:null,sip:(r&&t(r))??null,outbound:null,matched:null,dns:{type:s,answers:Ee(a),upstream:n,query:{name:e,type:s}}}}const He=(e,s,a)=>({domain:null,dip:e,sip:null,outbound:null,matched:null,dns:{type:a,answers:[e],upstream:null,query:{name:s,type:a}}}),Ke={forced:"dns.route.forced","dns.routing":"dns.route.rules",default:"dns.route.default"};function Ie(e,s,a){return{fields:[[a("ui.state"),e.status],[a("ui.upstream"),e.upstream??"—"],[a("dns.routeSource"),r(Ke,e.route.source,a)],[a("dns.routeRule"),e.route.rule??"—"],[a("ui.elapsed"),l(e.elapsed_ms,a)]],answers:(e.answers??[]).map(e=>{const t=Ee([e])[0],r=t?n(t):void 0;return{data:e.data,name:(l=e.name,i=s,l.replace(/\.$/,"").toLowerCase()===i.replace(/\.$/,"").toLowerCase()?null:e.name),type:e.type,ttl:a("dns.ttl",{ttl:e.ttl}),lookup:r&&pe(r)?r:null};var l,i}),cacheText:a(e.cached?"dns.hit":"dns.miss"),cacheTone:e.cached?void 0:"warn"}}function $e(e,s,a){return e?a instanceof u&&503===a.status?"unavailable":s?"ready":a?"error":"loading":"unlisted"}const Qe=[{id:"full",label:"rule.kind.domain"},{id:"suffix",label:"rule.kind.domainSuffix"},{id:"keyword",label:"rule.kind.domainKeyword"},{id:"regex",label:"dns.matchRegex"}],ze=e=>e.trim().toLowerCase().replace(/\.$/,"");function Ge(e,s){if(!s.trim())return()=>!0;if("regex"===e){const e=function(e){try{return new RegExp(e,"iu")}catch{return null}}(s);return e&&(s=>e.test(ze(s)))}if("keyword"===e){const e=s.trim().toLowerCase();return s=>ze(s).includes(e)}const a=ze(s),t="suffix"===e&&a.startsWith("."),n=t?a.slice(1):a;return n?"full"===e?e=>ze(e)===n:e=>{const s=ze(e);return s.endsWith("."+n)||!t&&s===n}:null}function Je({go:s,query:t}){const n=m(),r=p(),l=h(),i=e.useMemo(()=>new URLSearchParams(t),[t]),[d,c]=e.useState(i.get("domain")??""),[o,u]=e.useState(i.get("type")??"A"),[w,_]=e.useState(!1);x(i.get("domain"),e=>c(e??"")),x(i.get("type"),e=>u(e??"A"));const[N,k]=e.useState(null),{busy:S,error:C,run:T}=g({rethrow:!0}),q=l.data?.resources,R=e.useMemo(()=>function(e,s,t,n,r,l){const i=s?.dns_query.record_types??[],d="all"===t?i.length>0:i.includes(t);return{types:i,choices:[...i.map(e=>({id:e,label:e})),{id:"all",label:l("dns.allTypes")}],disabled:r||!s?.dns_query.available||!d||!n.trim(),reason:!s||r?null:s.dns_query.available?d?null:l("all"===t?"dns.noTypes":"dns.typeUnsupported"):l("dns.queryUnavailable"),showCache:!!s?.dns_cache.available,cards:e?.results.map(s=>({id:s.type,title:`${e.domain} ${s.type}`,...Ie(s,e.domain,l),seed:Ue(e.domain,s.type,s.answers??[],s.upstream,null),answerSeeds:(s.answers??[]).map(a=>Ee([a]).length?{address:a.data,seed:He(a.data,e.domain,s.type)}:null)}))??[],tabs:a(s).map(e=>({id:e.id,label:l(e.titleKey)}))}}(N,q,o,d,!!S,n),[N,q,o,d,S,n]),M=R.tabs.map(e=>e.id),L=i.has("domain")||i.has("device"),A=M.includes("log")?L?"log":"stats":M.includes("query")?"query":M[0]??"query",F=y(t,M,A),E=f(q,"config",{whileLoading:!1}),D=ge("query"===F&&E&&f(q,"dns_query",{whileLoading:!1})),P=e.useMemo(()=>E?function(e,s){const a=[...new Set((e??[]).flatMap(e=>e.content?De(e.content).map(Pe):[]))];return a.length?[{id:"",label:s("dns.upstreamAuto")},...a.map(e=>({id:e,label:e}))]:[]}(D.data?.sources,n):[],[E,D.data,n]),[W,O]=e.useState(""),B=P.some(e=>e.id===W)?W:"";D.data&&W&&!B&&O("");const U=async(e={domain:d,type:o})=>{try{await T("query",async s=>{const a=await ye(r.dnsQuery,e.domain.trim(),"all"===e.type?R.types:[e.type],q?.dns_query.limits?.max_types_per_request??1,s,w?"bypass":"normal",B||void 0);return s.aborted||k(a),a})}catch{}},H=f(q,"dns_query",{whileLoading:!1})&&R.types.length>0,K=We(s,{queryAgain:H?e=>{const a=R.types.includes(e.type)?e.type:"all";s("dns",b("",{tab:"query",domain:e.name.replace(/\.$/,""),type:a,run:"1"}))}:void 0}),I=i.has("run")&&q?t:null,$=e.useEffectEvent(e=>{const a=new URLSearchParams(e);s("dns",b(e,{run:null}),{replace:!0}),U({domain:a.get("domain")??"",type:a.get("type")??"A"})});return e.useEffect(()=>{null!==I&&$(I)},[I]),{...R,rule:{...K,label:e=>n(f(q,"dns_rules",{whileLoading:!1})?"dns.addRequestRuleFor":"dns.addRoutingRuleFor",{domain:e})},domain:d,setDomain:c,type:o,setType:u,bypassCache:w,setBypassCache:_,upstreams:P,upstream:B,setUpstream:O,pending:"query"===S,queryError:C,submit:()=>{U()},setTab:e=>s("dns",v(t,e,q&&!L?A:null)),tab:F,filterDomain:i.get("domain")??"",filterDevice:i.get("device")??"",cacheHref:M.includes("cache")?j("dns",{tab:"cache"}):null,logHref:(e,s)=>j("dns",{tab:"log",[e]:s}),logLinks:[...f(q,"dns_rules",{whileLoading:!1})?[{id:"rules",label:n("rule.dnsTitle"),onAction:()=>s("rules","tab=dns")}]:[],...q?.runtime_settings.available?[{id:"recording",label:n("ui.recordingSettings"),onAction:()=>s("settings","card=runtime")}]:[]],logEnabled:q?.dns_log.available,viewCache:()=>s("dns",b(t,{tab:"cache",domain:N?.domain??""})),clearCacheFilter:()=>s("dns",b(t,{tab:"cache",domain:null}))}}function Ve(s){const a=m(),t=w[_()],[n,r]=e.useState(!1),l=be(!k(),n),[i,c]=e.useState(s?"keyword":"suffix"),[o,u]=e.useState(s),[p,h]=e.useState("all");x(s,e=>{u(e),c(e?"keyword":"suffix"),h("all")});const g=[...new Set([...l.capabilities.data?.resources.dns_query.record_types??[],...(l.cache.data?.entries??[]).map(e=>e.type)])],y=e.useMemo(()=>({kind:i,text:o}),[i,o]),f=N(y,250),b=f!==y,j=l.cache.data?.entries,{matches:v,error:S,pending:C}=function(s,a,t){const n=e.useMemo(()=>(s??[]).filter(e=>"all"===t||e.type===t),[s,t]),r="regex"===a.kind&&!!a.text.trim(),[l,i]=e.useState(null);e.useEffect(()=>{if(!r)return;const e=new Worker(new URL(""+new URL("match.worker-B2aIccpg.js",import.meta.url).href,import.meta.url),{type:"module"});let s,t=!0;const l=(r,l)=>{t&&(t=!1,clearTimeout(s),e.terminate(),i({candidates:n,pattern:a,matches:r?.map(e=>n[e])??[],error:l??(null===r?"dns.invalidRegex":void 0)}))};return e.onmessage=r=>{t&&("ready"===r.data?(s=window.setTimeout(()=>l([],"dns.regexTimeout"),1e3),e.postMessage({text:a.text,names:n.map(e=>e.domain)})):l(r.data))},e.onerror=e=>{e.preventDefault(),l([],"dns.matchFailed")},()=>{t=!1,clearTimeout(s),e.terminate()}},[r,n,a]);const d=e.useMemo(()=>{if(r)return null;const e=Ge(a.kind,a.text);return{matches:e?n.filter(s=>e(s.domain)):[],error:e?void 0:"dns.invalidName"}},[r,n,a]);if(d)return{...d,pending:!1};const c=l?.candidates===n&&l.pattern===a;return{matches:c?l.matches:[],error:c?l.error:void 0,pending:!c}}(j,f,p),M=!!o.trim()||"all"!==p||!!s,L=e.useMemo(()=>function(e,s,a,t,n,r=e?.entries??[],l=!1){const i=s?.dns_cache;return{readable:!!i?.available&&!0===i.read,fields:[[n("dns.entries"),e?d(e.total,t):"—"]],coverage:e?["positive","negative","persistent"].filter(s=>!e.coverage[s]).map(e=>({id:e,text:"persistent"===e?n("dns.memoryOnly"):n("ui.valuePair",{label:n("positive"===e?"dns.positive":"dns.negative"),value:n("dns.notCovered")})})):[],deleteBy:{name:!!i?.available&&!0===i.delete_name,entry:!!i?.available&&!0===i.delete_entry},confirmationText:e?n("dns.flushConfirm",{n:e.total}):n("dns.flushConfirmAll"),flushDisabled:!!a||!s?.dns_cache.available||!s.dns_cache.flush,flushReason:!i||a||i.available&&i.flush?null:n("dns.flushUnsupported"),deleteReason:!(i&&!a&&r.length>0)||i.available&&i.delete_entry?null:n("dns.deleteUnsupported"),empty:n(s?.dns_cache.available&&s.dns_cache.read?l?"dns.emptyFiltered":"dns.empty":"dns.cacheUnavailable"),rows:r.map(e=>({id:e.entry_id,domain:e.domain,type:e.type,status:e.status,expiresAt:e.expires_at,staleUntil:e.stale_until,deleteLabel:n("dns.deleteEntry",{domain:e.domain,type:e.type}),seed:Ue(e.domain,e.type,[],null,null),pending:a===e.entry_id,disabled:!!a||!s?.dns_cache.available||!s.dns_cache.delete_entry}))}}(l.cache.data,l.capabilities.data?.resources,l.busy,t,a,b?[]:v,M),[l.cache.data,l.capabilities.data,l.busy,t,a,b,v,M]),A="full"===i&&!!o.trim()&&L.deleteBy.name,{remove:F}=l,E=e.useCallback(e=>{F(e).then(e=>e&&T("positive",a("dns.deleted",{n:e.deleted})),e=>T("negative",a("dns.deleteFailed"),q(e,a)))},[F,a]);return{...L,includeExpired:n,setIncludeExpired:r,matchKind:i,matchText:o,matchType:p,matchAvailable:L.readable||L.deleteBy.name||L.deleteBy.entry,filtered:M,clearMatches:()=>{u(""),h("all"),c("suffix")},setMatchType:h,setMatchKind:c,setMatchText:e=>{const s=function(e,s){return s.startsWith("*.")?{kind:"suffix",text:s.slice(2)}:{kind:e,text:s}}(i,e);c(s.kind),u(s.text)},matchKinds:Qe.map(e=>({id:e.id,label:a(e.label)})),matchTypes:[{id:"all",label:a("dns.allTypes")},...g.map(e=>({id:e,label:e}))],matchError:S?a(S):void 0,matchReason:L.deleteBy.entry||!L.deleteBy.name||A||l.busy?null:a("dns.matchNameOnly"),matchPending:"delete-match"===l.busy,matchDisabled:!!l.busy||b||C||!!S||!A&&!v.length||!o.trim()&&"all"===p||!(L.deleteBy.entry||A),matchConfirmation:A?a("dns.deleteNameConfirm",{name:o.trim(),type:"all"===p?a("dns.allTypes"):p}):a("dns.deleteMatchingConfirm",{n:v.length}),matchListed:v.slice(0,100),matchMore:v.length>100?a("dns.matchMore",{n:v.length-100}):null,removeMatching:async()=>{try{if(A){const e=await l.removeName({name:o.trim(),type:"all"===p?void 0:[p]});return void(e&&T("positive",a("dns.deleted",{n:e.deleted})))}const e=await l.removeMany(v.map(e=>e.entry_id));if(!e)return;e.failed?e.deleted?T("negative",a("dns.deletePartial",{deleted:e.deleted,n:e.failed})):T("negative",a("dns.deleteAllFailed",{n:e.failed})):T("positive",a("dns.deleted",{n:e.deleted}))}catch(e){return a("dns.deleteMatchingFailed",{error:R(e,a)})}},error:l.cache.error,retry:l.cache.refetch,loading:(l.cache.loading||l.capabilities.loading)&&!l.cache.data||b||C,flushPending:"flush"===l.busy,remove:E,flush:async()=>{try{const e=await l.flush();e&&T("positive",a("dns.flushed",{matched:e.matched,deleted:e.deleted}))}catch(e){return a("dns.flushFailed",{error:R(e,a)})}},abortFlush:()=>{l.cancel(),l.cache.refetch()}}}function Xe(s){const a=m(),t=w[_()],[n,r]=A(),[l,i]=e.useState(!1),u=je(s,!r&&l);u.data&&!l&&i(!0);const p=e.useMemo(()=>function(e,s,a){if(!e)return null;const{usage:t,coverage:n}=e,r=e=>{const a=o(e);return null===a?"—":d(a,s)},l=t?.entry_capacity??null,i=t&&null!==l?c(t.entries,l):null;return{note:t?null===l?a("dns.chart.usageFacts",{entries:r(t.entries)}):void 0:a("dns.chart.cacheNote",{n:e.total}),usage:t&&null!==l&&null!==i?{meter:o(l)?{value:i,valueLabel:i>0&&i<.5?"<"+a("ui.percent",{n:1}):a("ui.percent",{n:Math.round(i)})}:null,facts:[{label:a("dns.chart.entries"),value:r(t.entries)},{label:a("dns.chart.capacity"),value:r(l)}]}:null,coverage:a("dns.chart.coverage",{kinds:[n.positive&&a("dns.chart.positive"),n.negative&&a("dns.chart.negative")].filter(Boolean).join(a("ui.listSeparator")),persistent:a(n.persistent?"dns.chart.persistent":"dns.chart.memoryOnly")})}}(u.data,t,a),[u.data,t,a]);return{ref:n,card:p,state:$e(s,!!p,u.error),error:u.error,retry:u.refetch}}function Ye(s,a,t){const r=m(),d=w[_()],[c,o]=e.useState(a);x(a,o);const[y,f]=e.useState("all"),[b,j]=e.useState(t);x(t,j);const v=p(),q=h(),R=N(b),A=n(R),F=""!==R.trim()&&!A,[E,D]=e.useState(A);F||A===E||D(A);const P={name:N(c),type:y,src:F?E:A},W=JSON.stringify(P),O=fe(P,!0===s,!k()),[B,U]=e.useState(null),[H,K]=e.useState(!1),I=g({scope:W});x(W,()=>U(null));const{data:$,newerWaiting:Q}=e.useMemo(()=>function(e,s){const a=s&&new Set(s.records.map(e=>e.id));return{data:s??e,newerWaiting:!!a&&!!e?.records.some(e=>!a.has(e.id))}}(O.data,B),[O.data,B]),z=()=>{I.run("older",async e=>{if(!$?.next_cursor)return;let s;U($);try{s=await v.dnsLog({name:P.name.trim()||void 0,type:"all"===y?void 0:y,src:P.src,cursor:$.next_cursor,limit:$.limit},e)}catch(a){if(!(a instanceof u)||e.aborted)throw a;const s=M(a);if(!(410===a.status&&"snapshot_expired"===a.code||400===a.status&&"invalid_request"===a.code)&&!s)throw a;return s&&await L(a.retryAfter,e),U(null),O.refetch(),void T("info",r("dns.olderExpired"))}e.aborted||U(function(e,s){const a=new Set(e.records.map(e=>e.id));return{...e,records:[...e.records,...s.records.filter(e=>!a.has(e.id))],next_cursor:s.next_cursor}}($,s))})},G=()=>{I.cancel(),U(null);const e=O.refetch();e&&(K(!0),e.finally(()=>K(!1)))},[J,V]=e.useState(null),X=S(C),Y=q.data?.resources.dns_query.record_types,Z=e.useMemo(()=>function(e,s,a,t=[]){const n=e?.records??[];return{choices:[{id:"all",label:a("dns.allTypes")},...[...new Set([...t,...n.map(e=>e.question.type)])].map(e=>({id:e,label:e}))],total:e?a("dns.logTotal",{n:e.total}):"",totalHelp:e?{title:a("dns.logTotal",{n:e.total}),text:a("dns.logTotalHelp")}:null,loaded:e?.next_cursor?a("dns.logLoaded",{n:n.length}):"",empty:a(void 0===s?"ui.loading":s?"dns.logEmpty":"dns.logUnavailable"),rows:n.map(e=>({id:e.id,observedAt:e.observed_at,name:e.question.name,type:e.question.type,seed:Ue(e.question.name,e.question.type,e.answers,e.upstream,e.src),source:e.src??"—",resultError:"NOERROR"!==e.status,result:"NOERROR"!==e.status?e.status:e.answers.map(e=>e.data).join(", ")||"—",cached:e.cached,upstream:e.cached?a("dns.hit"):e.upstream??"—",elapsed:l(e.elapsed_ms,a)}))}}($,s,r,Y),[$,s,r,Y]),ee=e.useMemo(()=>function(e,s,a,t){const n=e?.records.find(e=>e.id===s);if(!n)return null;const r=Ie(n,n.question.name,t);return{id:n.id,title:n.question.name,answers:r.answers,fields:[[t("ui.type"),n.question.type],[t("ui.device"),n.src??"—"],r.fields[0],[t("ui.cache"),r.cacheText],...r.fields.slice(1),[t("ui.time"),i(n.observed_at,a)]]}}($,J,d,r),[$,J,d,r]);return{...Z,detail:ee,detailTitle:ee?.title??"",name:c,newerWaiting:Q,setName:o,type:y,setType:f,src:b,setSrc:j,srcError:F?r("ui.invalidIp"):void 0,selected:ee?J:null,setSelected:V,wide:X,error:I.error??O.error,loading:O.loading&&!$,hasOlder:!!$?.next_cursor,loadingOlder:!!I.busy,loadOlder:z,refreshing:H,refresh:G,retry:I.error?z:G,export:()=>{return Ae(Fe("dns-log","csv"),(e=$?.records??[],[Le(["id","observed_at","src","name","type","status","cached","upstream","route_source","route_rule","elapsed_ms","answers"]),...e.map(e=>Le([e.id,e.observed_at,e.src,e.question.name,e.question.type,e.status,e.cached?"true":"false",e.upstream,e.route.source,e.route.rule,e.elapsed_ms,e.answers.map(e=>e.data).join(" ")]))].join("\n")+"\n"),"text/csv;charset=utf-8");var e}}}const Ze={cached:"dns.outcome.cached",answered:"dns.outcome.answered",nxdomain:"dns.outcome.nxdomain",failed:"dns.outcome.failed"};function es({enabled:a,links:t}){const n=m(),{log:r,cacheListed:l,configHref:i}=function(s){const a=fe({},!0===s,!k()),t=h().data?.resources,n=f(t,"config",{whileLoading:!1}),r=ge(!0===s&&n),l=r.data?.sources,i=e.useMemo(()=>n&&l?se(l,"dns"):null,[n,l]);return{log:a,cacheListed:f(t,"dns_cache",{whileLoading:!1})&&!0===t?.dns_cache.read,configHref:i}}(a);if(!1===a)return s.jsx(F,{children:n("dns.logUnavailable")});if(void 0===a)return null;const d=r.error,c=r.data?null:!d||s.jsx(F,{children:n("dns.chart.noLog")}),o=d?s.jsx(E,{error:d,onRetry:r.refetch}):ae(r.data,r.limit)?s.jsx("p",{className:"rp-note",children:n("dns.chart.shortPage",{n:r.data.records.length,limit:r.limit})}):null;return s.jsx(as,{records:r.data?.records??ss,pending:c,notice:o,cacheListed:l,links:{...t,config:i}})}const ss=[];function as({records:a,pending:t,notice:n,cacheListed:r,links:i}){const d=m(),c=te(),o=w[_()],u=e.useMemo(()=>ne(a,o),[a,o]),p={cached:c.positive,answered:c.cat[2],nxdomain:c.notice,failed:c.negative},h=e=>d("ui.percent",{n:null===e?0:Math.round(100*e)}),x=(e,s)=>{const a=s?e/s:0;return e>0&&a<.005?"<"+d("ui.percent",{n:1}):e.995?">"+d("ui.percent",{n:99}):h(a)},g=e=>({id:e.id,value:e.value,color:p[e.outcome],lines:[e.name,l(e.value,d),d(Ze[e.outcome])]}),y=!0===t,f=e=>y?"bars"===e?s.jsx(U,{shape:"bars",count:7,typical:!0}):s.jsx(H,{holds:"swarm",children:s.jsx(U,{shape:"block",typical:!0})}):t??(u.total<5?s.jsx(F,{children:d("dns.chart.tooFew")}):null),b=f("block"),j=[{label:d("dns.chart.median"),value:l(u.typical,d),icon:s.jsx(D,{}),tint:"c1"},{label:d("dns.chart.p95"),value:l(u.slowest,d),icon:s.jsx(re,{}),tint:"c4"},{label:d("dns.chart.cacheRate"),value:h(u.cacheRate),icon:s.jsx(P,{}),tint:"c2"},{label:d("dns.chart.failureRate"),value:h(u.failureRate),icon:s.jsx(W,{}),tint:"c5",tone:u.counts.failed?"negative":void 0}];return s.jsxs("div",{className:"rp-chart-page",children:[n,(y||!b)&&s.jsx(le,{facts:j,loading:y}),s.jsxs("div",{className:"rp-g21",children:[s.jsx(O,{title:d("dns.chart.speed",{n:u.samples.length}),note:b?void 0:d("dns.chart.sample",{n:u.total,uncached:u.uncached,upstream:u.samples.length}),aside:i.config&&s.jsx(B,{appearance:"link",href:i.config,children:d("dns.openConfig")}),children:b??s.jsxs(s.Fragment,{children:[s.jsx(ie,{label:d("dns.chart.speed",{n:u.samples.length}),points:u.samples.map(g),marks:null!==u.typical&&null!==u.slowest?[{value:u.typical,label:d("dns.chart.typical",{value:l(u.typical,d)})},{value:u.slowest,label:d("dns.chart.slowest",{value:l(u.slowest,d)})}]:[],rows:u.upstreams.map(e=>({id:e.upstream,label:e.upstream,detail:d("dns.chart.upstream",{n:e.samples.length,median:l(e.median,d)}),points:e.samples.map(g),mark:e.median})),fmt:e=>l(e,d)}),s.jsxs("div",{className:"rp-legend",children:[["answered","nxdomain","failed"].map(e=>s.jsx(de,{swatch:p[e],label:d(Ze[e])},e)),s.jsx(de,{swatch:s.jsx("i",{className:"rp-median-key","aria-hidden":"true"}),label:d("dns.chart.medianKey")})]})]})}),s.jsx(O,{title:d("dns.chart.outcomes"),children:b??s.jsx(ce,{label:d("dns.chart.outcomes"),shares:oe.map(e=>({id:e,label:d(Ze[e]),count:u.counts[e],color:p[e],text:d("dns.chart.share",{n:u.counts[e],share:x(u.counts[e],u.total)})}))})})]}),s.jsxs("div",{className:"rp-g21",children:[s.jsx(ns,{analysis:u,standIn:f("bars"),logHref:i.log}),s.jsx(ts,{listed:r,href:i.cache})]})]})}function ts({listed:e,href:a}){const t=m(),{ref:n,...r}=Xe(e);return s.jsx(O,{ref:n,title:t("dns.chart.cache"),note:"ready"===r.state?r.card?.note:void 0,aside:e&&a&&s.jsx(B,{appearance:"link",href:a,children:t("dns.viewCache")}),children:"unlisted"===r.state?s.jsx(F,{children:t("dns.cacheUnavailable")}):"unavailable"===r.state?s.jsx(F,{children:t("dns.cacheBusy")}):"error"===r.state?s.jsx(E,{error:r.error,onRetry:r.retry}):r.card?s.jsxs(s.Fragment,{children:[r.card.usage&&s.jsxs("div",{className:"rp-form",children:[r.card.usage.meter&&s.jsx(_e,{label:t("dns.chart.usage"),...r.card.usage.meter}),s.jsx(le,{facts:r.card.usage.facts})]}),s.jsx("p",{className:"rp-note",children:r.card.coverage})]}):s.jsx(U,{shape:"rows",typical:!0})})}function ns({analysis:a,standIn:t,logHref:n}){const r=m(),l=te(),[i,d]=e.useState("device"),c="device"===i?a.devices:a.domains,o=c.top[0]?.count??1;return s.jsx(O,{title:r("dns.chart.ranking"),aside:!t&&s.jsx(we,{label:r("dns.chart.ranking"),value:i,onChange:d,items:[["device",r("dns.chart.byDevice")],["domain",r("dns.chart.byDomain")]]}),children:t??s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"rp-list",children:c.top.map(e=>s.jsx(ve,{label:null===e.key?r("dns.chart.resolver"):s.jsx(B,{appearance:"link",href:n("device"===i?"device":"domain",e.key),children:s.jsx(K,{children:e.key})}),value:r("dns.chart.count",{n:e.count}),pct:e.count/o*100,color:"device"===i?l.cat[0]:l.cat[3]},e.key??""))}),c.rest>0&&s.jsx("p",{className:"rp-note",children:r("dns.chart.rest",{n:c.rest})})]})})}function rs({answer:e,children:a}){return s.jsxs("div",{className:"rp-dns-answer",children:[s.jsx("span",{className:"rp-code",children:e.lookup?s.jsx(he,{ip:e.lookup,address:e.data,sites:xe(e.lookup)}):e.data}),s.jsxs("span",{className:"meta",children:[e.name&&s.jsx("span",{children:e.name}),s.jsx("span",{children:e.type}),s.jsx("span",{children:e.ttl})]}),a]})}function ls(e){const a=m(),t=Je(e),n=s.jsxs(s.Fragment,{children:[t.queryError&&s.jsx(E,{error:t.queryError,onRetry:t.submit,message:e=>a("dns.queryFailed",{error:e})}),s.jsx(I,{className:V(),onSubmit:e=>{e.preventDefault(),t.submit()},children:s.jsx($,{reason:t.reason,children:s.jsxs(Q,{children:[s.jsx(z,{side:!0,label:a("ui.domain"),value:t.domain,onChange:t.setDomain,width:280,placeholder:"example.com"}),s.jsx(Ne,{label:a("ui.type"),side:!0,value:t.type,onChange:t.setType,items:t.choices}),t.upstreams.length>0&&s.jsx(Ne,{label:a("ui.upstream"),side:!0,value:t.upstream,onChange:t.setUpstream,items:t.upstreams}),s.jsx(G,{isSelected:t.bypassCache,onChange:t.setBypassCache,children:a("dns.bypassCache")}),s.jsx(J,{accent:!0,type:"submit",isPending:t.pending,isDisabled:t.disabled,children:a("dns.query")})]})})}),!t.cards.length&&!t.queryError&&s.jsx(F,{children:a("dns.queryIntro")}),t.cards.length>0&&s.jsx("div",{className:"rp-col",children:t.cards.map(e=>s.jsxs(O,{className:"rp-col",children:[s.jsxs("div",{className:"rp-row",children:[s.jsxs("div",{className:"rp-cluster",children:[s.jsx("h2",{className:"rp-h3",children:e.title}),s.jsx(ke,{tone:e.cacheTone,children:e.cacheText})]}),s.jsxs("div",{className:"rp-cluster",children:[t.rule.canAdd(e.seed)&&s.jsx(J,{quiet:!0,small:!0,onPress:()=>t.rule.open(e.seed),children:a("rule.add")}),t.showCache&&s.jsx(J,{quiet:!0,small:!0,onPress:t.viewCache,children:a("dns.viewCache")})]})]}),s.jsx(Se,{inline:!0,items:e.fields}),e.answers.length?s.jsx("div",{className:"rp-list",children:e.answers.map((n,r)=>{const l=e.answerSeeds[r];return s.jsx(rs,{answer:n,children:l&&t.rule.canAdd(l.seed)&&s.jsx(J,{quiet:!0,small:!0,label:a("dns.addRuleFor",{value:l.address}),onPress:()=>t.rule.open(l.seed),children:a("rule.add")})},r)})}):s.jsx(F,{children:a("dns.noAnswers")})]},e.id))})]}),r={stats:s.jsx(es,{enabled:t.logEnabled,links:{cache:t.cacheHref,log:t.logHref}}),query:n,cache:s.jsx(is,{domain:t.filterDomain,clearFilter:t.clearCacheFilter,rule:t.rule}),log:s.jsx(ds,{enabled:t.logEnabled,initialName:t.filterDomain,initialSrc:t.filterDevice,links:t.logLinks,rule:t.rule})};return s.jsxs("div",{className:"rp-page",children:[s.jsx(qe,{page:!0,keepMounted:!0,label:a("nav.dns"),items:t.tabs.map(e=>({...e,content:r[e.id]})),value:t.tab,onChange:t.setTab}),s.jsx(Oe,{dialog:t.rule.dialog})]})}function is({domain:a,clearFilter:t,rule:n}){const r=m(),l=Ve(a),{remove:i}=l,d=e.useMemo(()=>[{id:"q",label:r("ui.domain"),text:"wrap",minWidth:320,isRowHeader:!0,render:e=>s.jsx("span",{className:"rp-code",children:e.domain})},{id:"t",label:r("ui.type"),minWidth:88,grow:0,drop:3,render:e=>e.type},{id:"s",label:r("ui.state"),minWidth:128,grow:0,render:e=>e.status},{id:"e",label:r("dns.expires"),minWidth:128,drop:2,render:e=>s.jsx(Me,{at:e.expiresAt})},{id:"st",label:r("dns.staleUntil"),minWidth:128,drop:1,render:e=>s.jsx(Me,{at:e.staleUntil})},{id:"a",actions:!0,label:r("ui.actions"),minWidth:104,grow:0,render:e=>s.jsxs("div",{className:"rp-cluster nowrap",children:[s.jsx(Be,{label:n.label(e.domain),disabled:!n.canAdd(e.seed),onPress:()=>n.open(e.seed)}),s.jsx(J,{quiet:!0,icon:!0,small:!0,label:e.deleteLabel,isPending:e.pending,isDisabled:e.disabled,onPress:()=>i(e.id),children:s.jsx(ee,{})})]})}],[r,i,n]);return s.jsxs(s.Fragment,{children:[l.error&&s.jsx(E,{error:l.error,onRetry:l.retry}),s.jsxs(Q,{page:!0,className:"top",children:[s.jsx(Se,{row:!0,items:l.fields}),l.coverage.map(e=>s.jsx(ke,{tone:"warn",children:e.text},e.id)),l.filtered&&s.jsx(J,{onPress:()=>{l.clearMatches(),t()},children:r("ui.clearFilters")}),s.jsx(G,{isSelected:l.includeExpired,onChange:l.setIncludeExpired,children:r("dns.includeExpired")}),s.jsx("span",{className:"rp-grow"}),s.jsx("div",{className:"rp-col",children:s.jsx($,{reason:l.flushReason,children:s.jsx(Z,{label:r("dns.flushAll"),confirmationText:l.confirmationText,isPending:l.flushPending,isDisabled:l.flushPending||l.flushDisabled,onConfirm:l.flush,onAbort:l.abortFlush})})})]}),l.matchAvailable&&s.jsx($,{reason:l.matchReason,children:s.jsxs(Q,{page:!0,children:[s.jsx(Ne,{side:!0,label:r("rule.kind"),value:l.matchKind,onChange:e=>l.setMatchKind(e),items:l.matchKinds}),s.jsx(z,{side:!0,label:r("dns.pattern"),value:l.matchText,onChange:l.setMatchText,error:l.matchError,help:"regex"===l.matchKind?{title:r("dns.pattern"),text:r("dns.regexHelp")}:void 0,width:280,placeholder:"example.com"}),s.jsx(Ne,{side:!0,label:r("ui.type"),value:l.matchType,onChange:l.setMatchType,items:l.matchTypes}),(l.deleteBy.name||l.deleteBy.entry)&&s.jsx(Z,{label:r("dns.deleteMatching"),confirmationText:l.matchConfirmation,details:s.jsxs("ul",{className:"rp-impact",children:[l.matchListed.map(e=>s.jsx("li",{children:s.jsxs("span",{className:"rp-cluster nowrap",children:[s.jsx(K,{className:"rp-code",children:e.domain}),s.jsx("span",{className:"rp-note",children:e.type})]})},e.entry_id)),l.matchMore&&s.jsx("li",{className:"rp-note",children:l.matchMore})]}),isPending:l.matchPending,isDisabled:l.matchDisabled,onConfirm:l.removeMatching,onAbort:l.abortFlush})]})}),s.jsx($,{reason:l.deleteReason,children:s.jsx(Re,{label:r("ui.cache"),height:442,fit:!0,rows:l.rows,loading:l.loading,empty:l.empty,cols:d})})]})}function ds({enabled:a,initialName:t,initialSrc:n,links:r,rule:l}){const i=m(),d=Ye(a,t,n),c=e.useMemo(()=>[{id:"t",label:i("ui.time"),minWidth:140,grow:0,render:e=>s.jsx(Me,{at:e.observedAt})},{id:"q",label:i("ui.domain"),minWidth:200,grow:2,isRowHeader:!0,render:e=>s.jsx(K,{children:e.name})},{id:"ty",label:i("ui.type"),minWidth:88,grow:0,drop:3,render:e=>e.type},{id:"s",label:i("ui.device"),minWidth:128,drop:2,render:e=>s.jsx(K,{className:"rp-code",children:e.source})},{id:"r",label:i("dns.result"),minWidth:160,grow:2,render:e=>e.resultError?s.jsx(Ce,{small:!0,tone:"err",children:e.result}):s.jsx(K,{className:"rp-code",children:e.result})},{id:"u",label:i("ui.upstream"),minWidth:128,drop:1,render:e=>e.cached?s.jsx(Ce,{small:!0,tone:"ok",children:e.upstream}):s.jsx(K,{children:e.upstream})},{id:"e",label:i("ui.elapsed"),minWidth:88,grow:0,drop:4,render:e=>e.elapsed},{id:"a",actions:!0,label:i("ui.actions"),minWidth:88,grow:0,render:e=>s.jsx(Be,{label:l.label(e.name),disabled:!l.canAdd(e.seed),onPress:()=>l.open(e.seed)})}],[i,l]);return s.jsxs(s.Fragment,{children:[s.jsxs(Q,{page:!0,children:[s.jsx(z,{search:!0,label:i("ui.domain"),value:d.name,onChange:d.setName,placeholder:i("dns.logFilterHint"),width:240}),s.jsx(Ne,{label:i("ui.type"),side:!0,value:d.type,onChange:d.setType,items:d.choices}),s.jsx(z,{side:!0,label:i("ui.device"),value:d.src,onChange:d.setSrc,error:d.srcError,placeholder:"10.0.0.12",width:200})]}),s.jsxs(Q,{page:!0,children:[s.jsxs("span",{className:"rp-cluster",children:[d.total&&s.jsx(X,{help:d.totalHelp,children:s.jsx("span",{className:"rp-label",children:d.total})}),d.loaded&&s.jsx("span",{className:"rp-label",children:d.loaded})]}),s.jsx("span",{className:"rp-grow"}),s.jsx("span",{className:"rp-cluster nowrap",children:s.jsx(Te,{actions:[{id:"refresh",label:i("ui.refresh"),icon:s.jsx(ue,{className:"rp-spin-on-press"}),isPending:d.refreshing,onAction:d.refresh},{id:"export",label:i("dns.exportLog"),icon:s.jsx(me,{}),isDisabled:!d.rows.length,onAction:d.export},...r,...d.hasOlder?[{id:"older",label:i("dns.loadOlder"),isPending:d.loadingOlder,onAction:d.loadOlder}]:[]]})})]}),d.error&&s.jsx(E,{error:d.error,onRetry:d.retry}),d.newerWaiting&&s.jsx("p",{className:"rp-note",children:i("dns.newerWaiting")}),s.jsxs("div",{className:"rp-with-panel","data-open":d.detail?"":void 0,children:[s.jsx(Re,{label:i("dns.log"),rowDetail:!0,height:520,rows:d.rows,selected:d.selected,onSelect:d.setSelected,selectOnFocus:d.wide,loading:d.loading,empty:d.empty,cols:c}),s.jsx(Y,{open:!!d.detail,title:d.detailTitle,onClose:()=>d.setSelected(null),children:d.detail&&s.jsxs(s.Fragment,{children:[s.jsx(Se,{inline:!0,items:d.detail.fields}),d.detail.answers.length?s.jsx("div",{className:"rp-list",children:d.detail.answers.map((e,a)=>s.jsx(rs,{answer:e},a))}):s.jsx(F,{children:i("dns.noAnswers")})]})})]}),d.hasOlder&&s.jsx("div",{className:"rp-narrow-only",children:s.jsx("div",{className:"rp-cluster",children:s.jsx(J,{small:!0,isPending:d.loadingOlder,onPress:d.loadOlder,children:i("dns.loadOlder")})})})]})}export{ls as Dns};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Donut-CaWe91EB.js b/luci-app-honk/root/etc/honk/doona/assets/Donut-D4QPrxiw.js
similarity index 54%
rename from luci-app-honk/root/etc/honk/doona/assets/Donut-CaWe91EB.js
rename to luci-app-honk/root/etc/honk/doona/assets/Donut-D4QPrxiw.js
index 47603aa9d..5b86b2497 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Donut-CaWe91EB.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Donut-D4QPrxiw.js
@@ -1 +1 @@
-import{r as n,j as t}from"./vendor-react-64fcanlc.js";import{u as e,g as r}from"./index-CUHkLMAp.js";import{a_ as o,b7 as a,b2 as i,b4 as l}from"./activity-B3PmJo_X.js";import{w as u,c,a as s}from"./array-C0VuvQyb.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./nodes-BYMoo8M1.js";import"./logs-C6Kb44nw.js";import"./Select-BA0NS1_z.js";import"./ItemText-CnEXu0-f.js";import"./AppearanceControls-E-VPhjIz.js";const f=Math.abs,h=Math.atan2,y=Math.cos,p=Math.max,d=Math.min,x=Math.sin,g=Math.sqrt,v=1e-12,m=Math.PI,M=m/2,A=2*m;function j(n){return n>=1?M:n<=-1?-M:Math.asin(n)}function w(n){return n.innerRadius}function b(n){return n.outerRadius}function P(n){return n.startAngle}function T(n){return n.endAngle}function R(n){return n&&n.padAngle}function L(n,t,e,r,o,a,i){var l=n-e,u=t-r,c=(i?a:-a)/g(l*l+u*u),s=c*u,f=-c*l,h=n+s,y=t+f,d=e+s,x=r+f,v=(h+d)/2,m=(y+x)/2,M=d-h,A=x-y,j=M*M+A*A,w=o-a,b=h*x-d*y,P=(A<0?-1:1)*g(p(0,w*w*j-b*b)),T=(b*A-M*P)/j,R=(-b*M-A*P)/j,L=(b*A+M*P)/j,I=(-b*M+A*P)/j,$=T-v,B=R-m,N=L-v,S=I-m;return $*$+B*B>N*N+S*S&&(T=L,R=I),{cx:T,cy:R,x01:-s,y01:-f,x11:T*(o/w-1),y11:R*(o/w-1)}}function I(){var n=w,t=b,e=c(0),r=null,o=P,a=T,i=R,l=null,s=u(p);function p(){var u,c,p,w=+n.apply(this,arguments),b=+t.apply(this,arguments),P=o.apply(this,arguments)-M,T=a.apply(this,arguments)-M,R=f(T-P),I=T>P;if(l||(l=u=s()),bv)if(R>A-v)l.moveTo(b*y(P),b*x(P)),l.arc(0,0,b,P,T,!I),w>v&&(l.moveTo(w*y(T),w*x(T)),l.arc(0,0,w,T,P,I));else{var $,B,N=P,S=T,k=P,D=T,E=R,F=R,K=i.apply(this,arguments)/2,_=K>v&&(r?+r.apply(this,arguments):g(w*w+b*b)),q=d(f(b-w)/2,+e.apply(this,arguments)),C=q,H=q;if(_>v){var U=j(_/w*x(K)),V=j(_/b*x(K));(E-=2*U)>v?(k+=U*=I?1:-1,D-=U):(E=0,k=D=(P+T)/2),(F-=2*V)>v?(N+=V*=I?1:-1,S-=V):(F=0,N=S=(P+T)/2)}var z=b*y(N),G=b*x(N),J=w*y(D),O=w*x(D);if(q>v){var Q,W=b*y(S),X=b*x(S),Y=w*y(k),Z=w*x(k);if(R1?0:p<-1?m:Math.acos(p))/2),an=g(Q[0]*Q[0]+Q[1]*Q[1]);C=d(q,(w-an)/(on-1)),H=d(q,(b-an)/(on+1))}else C=H=0}F>v?H>v?($=L(Y,Z,z,G,b,H,I),B=L(W,X,J,O,b,H,I),l.moveTo($.cx+$.x01,$.cy+$.y01),Hv&&E>v?C>v?($=L(J,O,W,X,w,-C,I),B=L(z,G,Y,Z,w,-C,I),l.lineTo($.cx+$.x01,$.cy+$.y01),Cn?1:t>=n?0:NaN}function B(n){return n}function N({label:u,rows:f}){const h=e(),[y,p]=r(Math.round,120),{tip:d,showAt:x,hide:g}=o(),[v,m]=n.useState(null),M=f.filter(n=>null!==n.value&&n.value>0),j=p?.width??0,w=p?.height??0,b=a(M.map(n=>n.value)),P=function(){var n=B,t=$,e=null,r=c(0),o=c(A),a=c(0);function i(i){var l,u,c,f,h,y=(i=s(i)).length,p=0,d=new Array(y),x=new Array(y),g=+r.apply(this,arguments),v=Math.min(A,Math.max(-A,o.apply(this,arguments)-g)),m=Math.min(Math.abs(v)/y,a.apply(this,arguments)),M=m*(v<0?-1:1);for(l=0;l0&&(p+=h);for(null!=t?d.sort(function(n,e){return t(x[n],x[e])}):null!=e&&d.sort(function(n,t){return e(i[n],i[t])}),l=0,c=p?(v-y*M)/p:0;l0?h*c:0)+M,x[u]={data:i[u],index:l,value:h,startAngle:g,endAngle:f,padAngle:m};return x}return i.value=function(t){return arguments.length?(n="function"==typeof t?t:c(+t),i):n},i.sortValues=function(n){return arguments.length?(t=n,e=null,i):t},i.sort=function(n){return arguments.length?(e=n,t=null,i):e},i.startAngle=function(n){return arguments.length?(r="function"==typeof n?n:c(+n),i):r},i.endAngle=function(n){return arguments.length?(o="function"==typeof n?n:c(+n),i):o},i.padAngle=function(n){return arguments.length?(a="function"==typeof n?n:c(+n),i):a},i}().sort(null).value((n,t)=>b[t])(M),T=Math.min(j,w)/2,R=I().innerRadius(T*(44/56)).outerRadius(T).digits(3),L=n=>m(n);n.useLayoutEffect(()=>{const n=null===v?void 0:P[v];if(!n||null===v)return void g();const t=M[v],[e,r]=R.centroid(n);x({x:Math.round(1e4*(j/2+e))/1e4,y:Math.round(1e4*(w/2+r))/1e4,width:j,bounds:{x:0,y:0,width:j,height:w},lines:[h("ui.valuePair",{label:t.name,value:h("ui.share",{bytes:t.text,percent:String(t.value)})})]})});const N=i(M.length,L,()=>{m(null),g()});return t.jsxs("div",{ref:y,style:{height:"100%",width:"100%",position:"relative"},onPointerLeave:N.onPointerLeave,children:[t.jsx(l,{tip:d}),p&&t.jsx("svg",{className:"rp-activity-surface",width:j,height:w,viewBox:`0 0 ${j} ${w}`,style:{display:"block"},role:M.length?"application":"img","aria-label":u,tabIndex:M.length?0:void 0,onFocus:M.length?N.onFocus:void 0,onBlur:N.onBlur,onKeyDown:M.length?N.onKeyDown:void 0,children:t.jsx("g",{transform:`translate(${j/2},${w/2})`,children:P.map((n,e)=>t.jsx("path",{d:R({...n,endAngle:Math.min(n.endAngle,n.startAngle+359.999*Math.PI/180)})??void 0,fill:M[e].color,stroke:"none",onPointerEnter:()=>L(e),onPointerLeave:N.onPointerLeave},M[e].name))})})]})}export{N as DonutPlot};
+import{r as n,j as t}from"./vendor-react-64fcanlc.js";import{u as e,g as r}from"./index-C06va4Yw.js";import{aZ as o,b6 as a,b1 as i,b3 as l}from"./activity-BoXvjA12.js";import{w as u,c,a as s}from"./array-C0VuvQyb.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./nodes-oXccX15o.js";import"./logs-BtAlqVqe.js";import"./Select-hQ95uOjm.js";import"./ItemText-D6SGBgOi.js";import"./AppearanceControls-CEVO9-aR.js";const f=Math.abs,h=Math.atan2,y=Math.cos,p=Math.max,d=Math.min,x=Math.sin,g=Math.sqrt,v=1e-12,m=Math.PI,M=m/2,A=2*m;function j(n){return n>=1?M:n<=-1?-M:Math.asin(n)}function b(n){return n.innerRadius}function w(n){return n.outerRadius}function P(n){return n.startAngle}function T(n){return n.endAngle}function R(n){return n&&n.padAngle}function L(n,t,e,r,o,a,i){var l=n-e,u=t-r,c=(i?a:-a)/g(l*l+u*u),s=c*u,f=-c*l,h=n+s,y=t+f,d=e+s,x=r+f,v=(h+d)/2,m=(y+x)/2,M=d-h,A=x-y,j=M*M+A*A,b=o-a,w=h*x-d*y,P=(A<0?-1:1)*g(p(0,b*b*j-w*w)),T=(w*A-M*P)/j,R=(-w*M-A*P)/j,L=(w*A+M*P)/j,I=(-w*M+A*P)/j,$=T-v,B=R-m,N=L-v,S=I-m;return $*$+B*B>N*N+S*S&&(T=L,R=I),{cx:T,cy:R,x01:-s,y01:-f,x11:T*(o/b-1),y11:R*(o/b-1)}}function I(){var n=b,t=w,e=c(0),r=null,o=P,a=T,i=R,l=null,s=u(p);function p(){var u,c,p,b=+n.apply(this,arguments),w=+t.apply(this,arguments),P=o.apply(this,arguments)-M,T=a.apply(this,arguments)-M,R=f(T-P),I=T>P;if(l||(l=u=s()),wv)if(R>A-v)l.moveTo(w*y(P),w*x(P)),l.arc(0,0,w,P,T,!I),b>v&&(l.moveTo(b*y(T),b*x(T)),l.arc(0,0,b,T,P,I));else{var $,B,N=P,S=T,k=P,D=T,E=R,F=R,K=i.apply(this,arguments)/2,q=K>v&&(r?+r.apply(this,arguments):g(b*b+w*w)),C=d(f(w-b)/2,+e.apply(this,arguments)),H=C,V=C;if(q>v){var W=j(q/b*x(K)),Z=j(q/w*x(K));(E-=2*W)>v?(k+=W*=I?1:-1,D-=W):(E=0,k=D=(P+T)/2),(F-=2*Z)>v?(N+=Z*=I?1:-1,S-=Z):(F=0,N=S=(P+T)/2)}var _=w*y(N),z=w*x(N),G=b*y(D),J=b*x(D);if(C>v){var O,Q=w*y(S),U=w*x(S),X=b*y(k),Y=b*x(k);if(R1?0:p<-1?m:Math.acos(p))/2),an=g(O[0]*O[0]+O[1]*O[1]);H=d(C,(b-an)/(on-1)),V=d(C,(w-an)/(on+1))}else H=V=0}F>v?V>v?($=L(X,Y,_,z,w,V,I),B=L(Q,U,G,J,w,V,I),l.moveTo($.cx+$.x01,$.cy+$.y01),Vv&&E>v?H>v?($=L(G,J,Q,U,b,-H,I),B=L(_,z,X,Y,b,-H,I),l.lineTo($.cx+$.x01,$.cy+$.y01),Hn?1:t>=n?0:NaN}function B(n){return n}function N({label:u,rows:f}){const h=e(),[y,p]=r(Math.round,120),{tip:d,showAt:x,hide:g}=o(),[v,m]=n.useState(null),M=f.filter(n=>null!==n.value&&n.value>0),j=p?.width??0,b=p?.height??0,w=a(M.map(n=>n.value)),P=function(){var n=B,t=$,e=null,r=c(0),o=c(A),a=c(0);function i(i){var l,u,c,f,h,y=(i=s(i)).length,p=0,d=new Array(y),x=new Array(y),g=+r.apply(this,arguments),v=Math.min(A,Math.max(-A,o.apply(this,arguments)-g)),m=Math.min(Math.abs(v)/y,a.apply(this,arguments)),M=m*(v<0?-1:1);for(l=0;l0&&(p+=h);for(null!=t?d.sort(function(n,e){return t(x[n],x[e])}):null!=e&&d.sort(function(n,t){return e(i[n],i[t])}),l=0,c=p?(v-y*M)/p:0;l0?h*c:0)+M,x[u]={data:i[u],index:l,value:h,startAngle:g,endAngle:f,padAngle:m};return x}return i.value=function(t){return arguments.length?(n="function"==typeof t?t:c(+t),i):n},i.sortValues=function(n){return arguments.length?(t=n,e=null,i):t},i.sort=function(n){return arguments.length?(e=n,t=null,i):e},i.startAngle=function(n){return arguments.length?(r="function"==typeof n?n:c(+n),i):r},i.endAngle=function(n){return arguments.length?(o="function"==typeof n?n:c(+n),i):o},i.padAngle=function(n){return arguments.length?(a="function"==typeof n?n:c(+n),i):a},i}().sort(null).value((n,t)=>w[t])(M),T=Math.min(j,b)/2,R=I().innerRadius(T*(44/56)).outerRadius(T).digits(3),L=n=>m(n);n.useLayoutEffect(()=>{const n=null===v?void 0:P[v];if(!n||null===v)return void g();const t=M[v],[e,r]=R.centroid(n);x({x:Math.round(1e4*(j/2+e))/1e4,y:Math.round(1e4*(b/2+r))/1e4,width:j,bounds:{x:0,y:0,width:j,height:b},lines:[h("ui.valuePair",{label:t.name,value:h("ui.share",{bytes:t.text,percent:String(t.value)})})]})});const N=i(M.length,L,()=>{m(null),g()});return t.jsxs("div",{ref:y,style:{height:"100%",width:"100%",position:"relative"},onPointerLeave:N.onPointerLeave,children:[t.jsx(l,{tip:d}),p&&t.jsx("svg",{className:"rp-activity-surface",width:j,height:b,viewBox:`0 0 ${j} ${b}`,style:{display:"block"},role:M.length?"application":"img","aria-label":u,tabIndex:M.length?0:void 0,onFocus:M.length?N.onFocus:void 0,onBlur:N.onBlur,onKeyDown:M.length?N.onKeyDown:void 0,children:t.jsx("g",{transform:`translate(${j/2},${b/2})`,children:P.map((n,e)=>t.jsx("path",{d:R({...n,endAngle:Math.min(n.endAngle,n.startAngle+359.999*Math.PI/180)})??void 0,fill:M[e].color,stroke:"none",onPointerEnter:()=>L(e),onPointerLeave:N.onPointerLeave},M[e].name))})})]})}export{N as DonutPlot};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Editors-DF8AauI-.js b/luci-app-honk/root/etc/honk/doona/assets/Editors-BlMhsZNx.js
similarity index 94%
rename from luci-app-honk/root/etc/honk/doona/assets/Editors-DF8AauI-.js
rename to luci-app-honk/root/etc/honk/doona/assets/Editors-BlMhsZNx.js
index 9e3fd053d..2866a30cb 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Editors-DF8AauI-.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Editors-BlMhsZNx.js
@@ -1 +1 @@
-import{r as e,$ as t,a as r,j as n}from"./vendor-react-64fcanlc.js";import{e_ as o,gF as i,eP as a,eL as s,d6 as l,gG as d,gH as c,gI as p,eR as u,eM as g,eN as f,eO as m,e$ as h,fa as y,gJ as D,gK as v,fb as b,eW as w,gL as x,gm as T,ga as k,by as E,d3 as P,cX as K,fo as O,I as S,aJ as C,cB as I,fh as j,aF as A,bB as R,B as M,g as B,u as L,R as F,cx as $,r as z,dm as N,bT as V,cQ as H,dG as X,b9 as Y,m as U,gM as q,P as J,gN as G,J as _}from"./index-CUHkLMAp.js";import{b8 as W,b9 as Q,ba as Z,bb as ee,bc as te,bd as re,be as ne,bf as oe,bg as ie,bh as ae,bi as se,bj as le,bk as de,bl as ce,bm as pe,bn as ue,bo as ge,bp as fe,bq as me,br as he,bs as ye,bt as De,bu as ve,bv as be,bw as we,bx as xe,by as Te,bz as ke,bA as Ee,bB as Pe,bC as Ke,bD as Oe,bE as Se,bF as Ce,bG as Ie,bH as je,bI as Ae}from"./activity-B3PmJo_X.js";import{$ as Re,a as Me}from"./GridList-CQPDUasC.js";import{m as Be}from"./Select-BA0NS1_z.js";import{D as Le}from"./Delete-D-jw0Qv4.js";import{S as Fe,c as $e,$ as ze}from"./logs-C6Kb44nw.js";import{C as Ne}from"./AppearanceControls-E-VPhjIz.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./nodes-BYMoo8M1.js";import"./ItemText-CnEXu0-f.js";import"./useGridSelectionCheckbox-CTBMGgmQ.js";var Ve=function(e){return e[e.none=0]="none",e[e.cancel=0]="cancel",e[e.move=1]="move",e[e.copy=2]="copy",e[e.link=4]="link",e[e.all=7]="all",e}({});const He={...Ve,copyMove:3,copyLink:6,linkMove:5,all:7,uninitialized:7},Xe=qe(He);Xe[7]="all";const Ye={none:"cancel",link:"link",copy:"copy",move:"move"},Ue=qe(Ye);function qe(e){let t={};for(let r in e)t[e[r]]=r;return t}const Je=new Set(["text/plain","text/uri-list","text/html"]),Ge="application/vnd.react-aria.items+json",_e="application/octet-stream",We=new WeakMap,Qe=Symbol();function Ze(e){let t=new Set;for(let r of e)for(let e of Object.keys(r))t.add(e);return t}function et(e){return e||(e="virtual"),"pointer"===e&&(e="virtual"),"virtual"===e&&"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia("(pointer: coarse)").matches&&(e="touch"),e}function tt(){return et(o())}function rt(){return et(i())}class nt{constructor(e){this.types=new Set;let t=!1;for(let r of e.items)r.type!==Ge&&("file"===r.kind&&(t=!0),r.type?this.types.add(r.type):this.types.add(_e));this.includesUnknownTypes=!t&&e.types.includes("Files")}has(e){if(Array.isArray(e))return e.some(e=>this.has(e));if(this.includesUnknownTypes||e===Qe&&this.types.has(_e)||"*/*"===e)return!0;if("string"==typeof e){if(e.endsWith("/*")){for(let t of this.types)if(t.startsWith(e.slice(0,-2)))return!0;return!1}return this.types.has(e)}return!1}}function ot(e){if(!e)throw new Error("No file provided");return{kind:"file",type:e.type||_e,name:e.name,getText:()=>{return"function"==typeof(t=e).text?t.text():new Promise((e,r)=>{let n=new FileReader;n.onload=()=>{e(n.result)},n.onerror=r,n.readAsText(t)});var t},getFile:()=>Promise.resolve(e)}}function it(e){return{kind:"directory",name:e.name,getEntries:()=>async function*(e){let t,r=e.createReader();do{t=await new Promise((e,t)=>{r.readEntries(e,t)});for(let e of t)if(e.isFile){let t=await at(e);yield ot(t)}else e.isDirectory&&(yield it(e))}while(t.length>0)}(e)}}function at(e){return new Promise((t,r)=>e.file(t,r))}let st,lt={draggingKeys:new Set};function dt(e){lt.dropCollectionRef=e}function ct(){lt={draggingKeys:new Set}}function pt(e){let{draggingCollectionRef:t,dropCollectionRef:r}=lt;return null!=t?.current&&t.current===(e?.current||r?.current)}function ut(e){st=e}let gt=Ve.none;function ft(e){gt=e}let mt=new Map,ht=new Map,yt=null,Dt=new Set;function vt(e){return mt.set(e.element,e),yt?.updateValidDropTargets(),()=>{mt.delete(e.element),yt?.updateValidDropTargets()}}function bt(){let[t,r]=e.useState(yt);return e.useEffect(()=>{let e=()=>r(yt);return Dt.add(e),()=>{Dt.delete(e)}},[]),t}function wt(){return!!yt}const xt=["pointerdown","pointermove","pointerenter","pointerleave","pointerover","pointerout","pointerup","mousedown","mousemove","mouseenter","mouseleave","mouseover","mouseout","mouseup","touchstart","touchmove","touchend","focusin","focusout"],Tt=["pointerup","mouseup","touchend"],kt={keyboard:"dragStartedKeyboard",touch:"dragStartedTouch",virtual:"dragStartedVirtual"};class Et{constructor(e,t){this.validDropTargets=[],this.currentDropTarget=null,this.currentDropItem=null,this.dropOperation=null,this.mutationObserver=null,this.restoreAriaHidden=null,this.isVirtualClick=!1,this.dragTarget=e,this.stringFormatter=t,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onFocus=this.onFocus.bind(this),this.onBlur=this.onBlur.bind(this),this.onClick=this.onClick.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.cancelEvent=this.cancelEvent.bind(this),this.initialFocused=!1}setup(){document.addEventListener("keydown",this.onKeyDown,!0),document.addEventListener("keyup",this.onKeyUp,!0),window.addEventListener("focus",this.onFocus,!0),window.addEventListener("blur",this.onBlur,!0),document.addEventListener("click",this.onClick,!0),document.addEventListener("pointerdown",this.onPointerDown,!0);for(let e of xt)document.addEventListener(e,this.cancelEvent,!0);this.mutationObserver=new MutationObserver(()=>this.updateValidDropTargets()),this.updateValidDropTargets(),a(this.stringFormatter.format(kt[rt()]))}teardown(){document.removeEventListener("keydown",this.onKeyDown,!0),document.removeEventListener("keyup",this.onKeyUp,!0),window.removeEventListener("focus",this.onFocus,!0),window.removeEventListener("blur",this.onBlur,!0),document.removeEventListener("click",this.onClick,!0),document.removeEventListener("pointerdown",this.onPointerDown,!0);for(let e of xt)document.removeEventListener(e,this.cancelEvent,!0);this.mutationObserver?.disconnect(),this.restoreAriaHidden?.()}onKeyDown(e){this.cancelEvent(e),"Escape"!==e.key?("Tab"!==e.key||e.metaKey||e.altKey||e.ctrlKey||(e.shiftKey?this.previous():this.next()),"function"==typeof this.currentDropTarget?.onKeyDown&&this.currentDropTarget.onKeyDown(e,this.dragTarget)):this.cancel()}onKeyUp(e){this.cancelEvent(e),"Enter"===e.key&&(e.altKey||s(this.getCurrentActivateButton(),l(e))?this.activate(this.currentDropTarget,this.currentDropItem):this.drop())}getCurrentActivateButton(){return this.currentDropItem?.activateButtonRef?.current??this.currentDropTarget?.activateButtonRef?.current??null}onFocus(e){let t=this.getCurrentActivateButton(),r=l(e);if(r===t)return void this.cancelEvent(e);if(r!==this.dragTarget.element&&this.cancelEvent(e),!(r instanceof HTMLElement)||r===this.dragTarget.element)return;let n=this.validDropTargets.find(e=>e.element===r)||this.validDropTargets.find(e=>s(e.element,r));if(!n)return void(this.currentDropTarget?this.currentDropTarget.element.focus():this.dragTarget.element.focus());let o=ht.get(r);n&&this.setCurrentDropTarget(n,o)}onBlur(e){let t=this.getCurrentActivateButton();t&&e.relatedTarget===t?this.cancelEvent(e):(l(e)!==this.dragTarget.element&&this.cancelEvent(e),e.relatedTarget&&e.relatedTarget instanceof HTMLElement||(this.currentDropTarget?this.currentDropTarget.element.focus():this.dragTarget.element.focus()))}onClick(e){if(this.cancelEvent(e),d(e)||this.isVirtualClick){let t=ht.values(),r=l(e),n=[...t].find(e=>e.element===r||s(e.activateButtonRef?.current,r)),o=this.validDropTargets.find(e=>s(e.element,r));if(s(n?.activateButtonRef?.current??o?.activateButtonRef?.current,r)&&o)return void this.activate(o,n);if(l(e)===this.dragTarget.element)return void this.cancel();o&&(this.setCurrentDropTarget(o,n),this.drop(n))}}onPointerDown(e){this.cancelEvent(e),this.isVirtualClick=c(e)}cancelEvent(e){let t=l(e);("focusin"!==e.type&&"focusout"!==e.type||t!==this.dragTarget?.element&&t!==this.getCurrentActivateButton())&&(Tt.includes(e.type)||e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation())}updateValidDropTargets(){if(!this.mutationObserver)return;if(this.mutationObserver.disconnect(),this.restoreAriaHidden&&this.restoreAriaHidden(),this.validDropTargets=function(e){let t=Ze(e.items);return[...mt.values()].filter(r=>!r.element.closest('[aria-hidden="true"], [inert]')&&("function"!=typeof r.getDropOperation||"cancel"!==r.getDropOperation(t,e.allowedDropOperations)))}(this.dragTarget),this.validDropTargets.length>0){let e=this.findNearestDropTarget();this.validDropTargets=[...this.validDropTargets.slice(e),...this.validDropTargets.slice(0,e)]}this.currentDropTarget&&!this.validDropTargets.includes(this.currentDropTarget)&&this.setCurrentDropTarget(this.validDropTargets[0]);let e=Ze(this.dragTarget.items),t=[...ht.values()].filter(t=>"function"!=typeof t.getDropOperation||"cancel"!==t.getDropOperation(e,this.dragTarget.allowedDropOperations)),r=this.validDropTargets.filter(e=>!t.some(t=>s(e.element,t.element)));this.restoreAriaHidden=p([this.dragTarget.element,...t.flatMap(e=>e.activateButtonRef?.current?[e.element,e.activateButtonRef?.current]:[e.element]),...r.flatMap(e=>e.activateButtonRef?.current?[e.element,e.activateButtonRef?.current]:[e.element])],{shouldUseInert:!0}),this.mutationObserver.observe(document.body,{subtree:!0,attributes:!0,attributeFilter:["aria-hidden","inert"]})}next(){if(!this.currentDropTarget)return void this.setCurrentDropTarget(this.validDropTargets[0]);let e=this.validDropTargets.indexOf(this.currentDropTarget);e<0?this.setCurrentDropTarget(this.validDropTargets[0]):e===this.validDropTargets.length-1?this.dragTarget.element.closest('[aria-hidden="true"], [inert]')?this.setCurrentDropTarget(this.validDropTargets[0]):(this.setCurrentDropTarget(null),this.dragTarget.element.focus()):this.setCurrentDropTarget(this.validDropTargets[e+1])}previous(){if(!this.currentDropTarget)return void this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]);let e=this.validDropTargets.indexOf(this.currentDropTarget);e<0?this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]):0===e?this.dragTarget.element.closest('[aria-hidden="true"], [inert]')?this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]):(this.setCurrentDropTarget(null),this.dragTarget.element.focus()):this.setCurrentDropTarget(this.validDropTargets[e-1])}findNearestDropTarget(){let e=this.dragTarget.element.getBoundingClientRect(),t=1/0,r=-1,n=-1;for(let o=0;o=0?n:r}setCurrentDropTarget(e,t){if(e!==this.currentDropTarget){if(this.currentDropTarget&&"function"==typeof this.currentDropTarget.onDropExit){let e=this.currentDropTarget.element.getBoundingClientRect();this.currentDropTarget.onDropExit({type:"dropexit",x:e.left+e.width/2,y:e.top+e.height/2})}if(this.currentDropTarget=e,e){if("function"==typeof e.onDropEnter){let t=e.element.getBoundingClientRect();e.onDropEnter({type:"dropenter",x:t.left+t.width/2,y:t.top+t.height/2},this.dragTarget)}t||e?.element.focus()}}if(null!=t&&t!==this.currentDropItem&&(this.currentDropTarget&&"function"==typeof this.currentDropTarget.onDropTargetEnter&&this.currentDropTarget.onDropTargetEnter(t.target),t.element.focus(),this.currentDropItem=t,!this.initialFocused)){let e=t?.element.getAttribute("aria-label");e&&a(e,"polite"),this.initialFocused=!0}}end(){if(this.teardown(),function(){yt=null;for(let e of Dt)e()}(),"function"==typeof this.dragTarget.onDragEnd){let e=(this.currentDropTarget&&"cancel"!==this.dropOperation?this.currentDropTarget:this.dragTarget).element.getBoundingClientRect();this.dragTarget.onDragEnd({type:"dragend",x:e.x+e.width/2,y:e.y+e.height/2,dropOperation:this.dropOperation||"cancel"})}this.currentDropTarget&&!this.currentDropTarget.preventFocusOnDrop&&u()?.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),this.setCurrentDropTarget(null)}cancel(){this.setCurrentDropTarget(null),this.end(),this.dragTarget.element.closest('[aria-hidden="true"], [inert]')||this.dragTarget.element.focus(),u()?.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),a(this.stringFormatter.format("dropCanceled"))}drop(e){if(this.currentDropTarget){if("function"==typeof e?.getDropOperation){let t=Ze(this.dragTarget.items);this.dropOperation=e.getDropOperation(t,this.dragTarget.allowedDropOperations)}else if("function"==typeof this.currentDropTarget.getDropOperation){let e=Ze(this.dragTarget.items);this.dropOperation=this.currentDropTarget.getDropOperation(e,this.dragTarget.allowedDropOperations)}else this.dropOperation=this.dragTarget.allowedDropOperations[0];if("function"==typeof this.currentDropTarget.onDrop){let t=this.dragTarget.items.map(e=>({kind:"text",types:new Set(Object.keys(e)),getText:t=>Promise.resolve(e[t])})),r=this.currentDropTarget.element.getBoundingClientRect();this.currentDropTarget.onDrop({type:"drop",x:r.left+r.width/2,y:r.top+r.height/2,items:t,dropOperation:this.dropOperation},e?.target??null)}this.end(),a(this.stringFormatter.format("dropComplete"))}else this.cancel()}activate(e,t){if(e&&"function"==typeof e.onDropActivate){let r=t?.target??null,n=e.element.getBoundingClientRect();e.onDropActivate({type:"dropactivate",x:n.left+n.width/2,y:n.top+n.height/2},r)}}}var Pt;Pt={"ar-AE":g,"bg-BG":g,"cs-CZ":g,"da-DK":g,"de-DE":g,"el-GR":g,"en-US":{dragItem:e=>`Drag ${e.itemText}`,dragSelectedItems:(e,t)=>`Drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}`,dragDescriptionKeyboard:"Press Enter to start dragging.",dragDescriptionKeyboardAlt:"Press Alt + Enter to start dragging.",dragDescriptionTouch:"Double tap to start dragging.",dragDescriptionVirtual:"Click to start dragging.",dragDescriptionLongPress:"Long press to start dragging.",dragSelectedKeyboard:(e,t)=>`Press Enter to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragSelectedKeyboardAlt:(e,t)=>`Press Alt + Enter to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragSelectedLongPress:(e,t)=>`Long press to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragStartedKeyboard:"Started dragging. Press Tab to navigate to a drop target, then press Enter to drop, or press Escape to cancel.",dragStartedTouch:"Started dragging. Navigate to a drop target, then double tap to drop.",dragStartedVirtual:"Started dragging. Navigate to a drop target, then click or press Enter to drop.",endDragKeyboard:"Dragging. Press Enter to cancel drag.",endDragTouch:"Dragging. Double tap to cancel drag.",endDragVirtual:"Dragging. Click to cancel drag.",dropDescriptionKeyboard:"Press Enter to drop. Press Escape to cancel drag.",dropDescriptionTouch:"Double tap to drop.",dropDescriptionVirtual:"Click to drop.",dropCanceled:"Drop canceled.",dropComplete:"Drop complete.",dropIndicator:"drop indicator",dropOnRoot:"Drop on",dropOnItem:e=>`Drop on ${e.itemText}`,insertBefore:e=>`Insert before ${e.itemText}`,insertBetween:e=>`Insert between ${e.beforeItemText} and ${e.afterItemText}`,insertAfter:e=>`Insert after ${e.itemText}`},"es-ES":g,"et-EE":g,"fi-FI":g,"fr-FR":g,"he-IL":g,"hr-HR":g,"hu-HU":g,"it-IT":g,"ja-JP":g,"ko-KR":g,"lt-LT":g,"lv-LV":g,"nb-NO":g,"nl-NL":g,"pl-PL":g,"pt-BR":g,"pt-PT":g,"ro-RO":g,"ru-RU":g,"sk-SK":g,"sl-SI":g,"sr-SP":g,"sv-SE":g,"tr-TR":g,"uk-UA":g,"zh-CN":{dragDescriptionKeyboard:"按 Enter 开始拖动。",dragDescriptionKeyboardAlt:"按 Alt + Enter 开始拖动。",dragDescriptionLongPress:"长按以开始拖动。",dragDescriptionTouch:"双击开始拖动。",dragDescriptionVirtual:"单击开始拖动。",dragItem:e=>`拖动 ${e.itemText}`,dragSelectedItems:(e,t)=>`拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 选中项目`,other:()=>`${t.number(e.count)} 选中项目`})}`,dragSelectedKeyboard:(e,t)=>`按 Enter 以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragSelectedKeyboardAlt:(e,t)=>`按 Alt + Enter 以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragSelectedLongPress:(e,t)=>`长按以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragStartedKeyboard:"已开始拖动。按 Tab 导航到放置目标,然后按 Enter 放置或按 Escape 取消。",dragStartedTouch:"已开始拖动。导航到放置目标,然后双击放置。",dragStartedVirtual:"已开始拖动。导航到放置目标,然后单击或按 Enter 放置。",dropCanceled:"放置已取消。",dropComplete:"放置已完成。",dropDescriptionKeyboard:"按 Enter 放置。按 Escape 取消拖动。",dropDescriptionTouch:"双击放置。",dropDescriptionVirtual:"单击放置。",dropIndicator:"放置标记",dropOnItem:e=>`放置于 ${e.itemText}`,dropOnRoot:"放置于",endDragKeyboard:"正在拖动。按 Enter 取消拖动。",endDragTouch:"正在拖动。双击取消拖动。",endDragVirtual:"正在拖动。单击取消拖动。",insertAfter:e=>`插入到 ${e.itemText} 之后`,insertBefore:e=>`插入到 ${e.itemText} 之前`,insertBetween:e=>`插入到 ${e.beforeItemText} 和 ${e.afterItemText} 之间`},"zh-TW":{dragDescriptionKeyboard:"按 Enter 鍵以開始拖曳。",dragDescriptionKeyboardAlt:"按 Alt+Enter 鍵以開始拖曳。",dragDescriptionLongPress:"長按以開始拖曳。",dragDescriptionTouch:"輕點兩下以開始拖曳。",dragDescriptionVirtual:"按一下滑鼠以開始拖曳。",dragItem:e=>`拖曳「${e.itemText}」`,dragSelectedItems:(e,t)=>`拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}`,dragSelectedKeyboard:(e,t)=>`按 Enter 鍵以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragSelectedKeyboardAlt:(e,t)=>`按 Alt+Enter 鍵以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragSelectedLongPress:(e,t)=>`長按以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragStartedKeyboard:"已開始拖曳。按 Tab 鍵以瀏覽至放置目標,然後按 Enter 鍵以放置,或按 Escape 鍵以取消。",dragStartedTouch:"已開始拖曳。瀏覽至放置目標,然後輕點兩下以放置。",dragStartedVirtual:"已開始拖曳。瀏覽至放置目標,然後按一下滑鼠或按 Enter 鍵以放置。",dropCanceled:"放置已取消。",dropComplete:"放置已完成。",dropDescriptionKeyboard:"按 Enter 鍵以放置。按 Escape 鍵以取消拖曳。",dropDescriptionTouch:"輕點兩下以放置。",dropDescriptionVirtual:"按一下滑鼠以放置。",dropIndicator:"放置指示器",dropOnItem:e=>`放置在「${e.itemText}」上`,dropOnRoot:"放置在",endDragKeyboard:"拖曳中。按 Enter 鍵以取消拖曳。",endDragTouch:"拖曳中。輕點兩下以取消拖曳。",endDragVirtual:"拖曳中。按一下滑鼠以取消拖曳。",insertAfter:e=>`插入至「${e.itemText}」之後`,insertBefore:e=>`插入至「${e.itemText}」之前`,insertBetween:e=>`插入至「${e.beforeItemText}」和「${e.afterItemText}」之間`}};const Kt={keyboard:"dropDescriptionKeyboard",touch:"dropDescriptionTouch",virtual:"dropDescriptionVirtual"};function Ot(){let e=f((t=Pt)&&t.__esModule?t.default:t,"@react-aria/dnd");var t;let r=tt(),n=bt();return{dropProps:{...m(n?e.format(Kt[r]):""),onClick:()=>{}}}}function St(t){let{hasDropButton:r,isDisabled:n}=t,[o,i]=e.useState(!1),a=e.useRef({x:0,y:0,dragOverElements:new Set,dropEffect:"none",allowedOperations:Ve.all,dropActivateTimer:void 0}).current,d=e=>{if(i(!0),"function"==typeof t.onDropEnter){let r=e.currentTarget.getBoundingClientRect();t.onDropEnter({type:"dropenter",x:e.clientX-r.x,y:e.clientY-r.y})}},c=e=>{if(i(!1),"function"==typeof t.onDropExit){let r=e.currentTarget.getBoundingClientRect();t.onDropExit({type:"dropexit",x:e.clientX-r.x,y:e.clientY-r.y})}},p=h(e=>{"function"==typeof t.onDropEnter&&t.onDropEnter(e)}),u=h(e=>{"function"==typeof t.onDropExit&&t.onDropExit(e)}),g=h(e=>{"function"==typeof t.onDropActivate&&t.onDropActivate(e)}),f=h(e=>{"function"==typeof t.onDrop&&t.onDrop(e)}),m=h((e,r)=>t.getDropOperation?t.getDropOperation(e,r):r[0]),{ref:D}=t;y(()=>{if(!n&&D.current)return vt({element:D.current,getDropOperation:m,onDropEnter(e){i(!0),p(e)},onDropExit(e){i(!1),u(e)},onDrop:f,onDropActivate:g})},[n,D]);let{dropProps:v}=Ot();return n?{dropProps:{},dropButtonProps:{isDisabled:!0},isDropTarget:!1}:{dropProps:{...!r&&v,onDragEnter:e=>{if(e.preventDefault(),e.stopPropagation(),a.dragOverElements.add(l(e)),a.dragOverElements.size>1)return;let r=Ct(e),n=It(r),o=n[0];if("function"==typeof t.getDropOperation){let i=new nt(e.dataTransfer);o=jt(r,t.getDropOperation(i,n))}if("function"==typeof t.getDropOperationForPoint){let i=new nt(e.dataTransfer),a=e.currentTarget.getBoundingClientRect();o=jt(r,t.getDropOperationForPoint(i,n,e.clientX-a.x,e.clientY-a.y))}a.x=e.clientX,a.y=e.clientY,a.allowedOperations=r,a.dropEffect=Ue[o]||"none",e.dataTransfer.dropEffect=a.dropEffect,"cancel"!==o&&d(e)},onDragOver:e=>{e.preventDefault(),e.stopPropagation();let r=Ct(e);if(e.clientX===a.x&&e.clientY===a.y&&r===a.allowedOperations)return void(e.dataTransfer.dropEffect=a.dropEffect);a.x=e.clientX,a.y=e.clientY;let n=a.dropEffect;if(r!==a.allowedOperations){let n=It(r),o=n[0];if("function"==typeof t.getDropOperation){let i=new nt(e.dataTransfer);o=jt(r,t.getDropOperation(i,n))}a.dropEffect=Ue[o]||"none"}if("function"==typeof t.getDropOperationForPoint){let n=new nt(e.dataTransfer),o=e.currentTarget.getBoundingClientRect(),i=jt(r,t.getDropOperationForPoint(n,It(r),a.x-o.x,a.y-o.y));a.dropEffect=Ue[i]||"none"}if(a.allowedOperations=r,e.dataTransfer.dropEffect=a.dropEffect,"none"===a.dropEffect&&"none"!==n?c(e):"none"!==a.dropEffect&&"none"===n&&d(e),"function"==typeof t.onDropMove&&"none"!==a.dropEffect){let r=e.currentTarget.getBoundingClientRect();t.onDropMove({type:"dropmove",x:a.x-r.x,y:a.y-r.y})}if(clearTimeout(a.dropActivateTimer),t.onDropActivate&&"function"==typeof t.onDropActivate&&"none"!==a.dropEffect){let r=t.onDropActivate,n=e.currentTarget.getBoundingClientRect();a.dropActivateTimer=setTimeout(()=>{r({type:"dropactivate",x:a.x-n.x,y:a.y-n.y})},800)}},onDragLeave:e=>{e.preventDefault(),e.stopPropagation();let t=l(e);if(a.dragOverElements.delete(t),t===e.currentTarget)for(let r of a.dragOverElements)s(e.currentTarget,r)||a.dragOverElements.delete(r);a.dragOverElements.size>0||("none"!==a.dropEffect&&c(e),clearTimeout(a.dropActivateTimer))},onDrop:e=>{if(e.preventDefault(),e.stopPropagation(),ut(a.dropEffect),"function"==typeof t.onDrop){let r=Ye[a.dropEffect],n=function(e){let t=[];if(!e)return t;let r=!1;if(e.types.includes(Ge))try{let n=e.getData(Ge),o=JSON.parse(n);for(let e of o)t.push({kind:"text",types:new Set(Object.keys(e)),getText:t=>Promise.resolve(e[t])});r=!0}catch{}if(!r){let r=new Map;for(let n of e.items)if("string"===n.kind)r.set(n.type||_e,e.getData(n.type));else if("file"===n.kind)if("function"==typeof n.webkitGetAsEntry){let e=n.webkitGetAsEntry();if(!e)continue;e.isFile?t.push(ot(n.getAsFile())):e.isDirectory&&t.push(it(e))}else t.push(ot(n.getAsFile()));r.size>0&&t.push({kind:"text",types:new Set(r.keys()),getText:e=>Promise.resolve(r.get(e))})}return t}(e.dataTransfer),o=e.currentTarget.getBoundingClientRect(),i={type:"drop",x:e.clientX-o.x,y:e.clientY-o.y,items:n,dropOperation:r};t.onDrop(i)}let r={...lt};a.dragOverElements.clear(),c(e),clearTimeout(a.dropActivateTimer),null==r.draggingCollectionRef?ut(void 0):function(e){lt=e}(r)}},dropButtonProps:{...r&&v},isDropTarget:o}}function Ct(e){let t=He[e.dataTransfer.effectAllowed];gt&&(t&=gt);let r=Ve.none;return D()?(e.altKey&&(r|=Ve.copy),e.ctrlKey&&!v()&&(r|=Ve.link),e.metaKey&&(r|=Ve.move)):(e.altKey&&(r|=Ve.link),e.shiftKey&&(r|=Ve.move),e.ctrlKey&&(r|=Ve.copy)),r?t&r:t}function It(e){let t=[];return e&Ve.move&&t.push("move"),e&Ve.copy&&t.push("copy"),e&Ve.link&&t.push("link"),t}function jt(e,t){return e&Ve[t]?t:"cancel"}function At(e,t,r,n=!1,o=null){if(!r)return{type:"root"};if("root"===r.type){let t=e.getFirstKey?.()??null;return null!=t?{type:"item",key:t,dropPosition:"before"}:null}if("item"===r.type){let n=null;n=o?"right"===o?e.getKeyRightOf?.(r.key,{includeDisabled:!0}):e.getKeyLeftOf?.(r.key,{includeDisabled:!0}):e.getKeyBelow?.(r.key,{includeDisabled:!0});let i=Bt(t,r.key,e=>t.getKeyAfter(e));if(null!=n&&n!==i)return{type:"item",key:n,dropPosition:r.dropPosition};switch(r.dropPosition){case"before":return{type:"item",key:r.key,dropPosition:"on"};case"on":{let e=t.getItem(r.key),o=null!=n?t.getItem(n):null;return e&&o&&o.level>=e.level?{type:"item",key:o.key,dropPosition:"before"}:{type:"item",key:r.key,dropPosition:"after"}}case"after":{let e=t.getItem(r.key),n=null!=e?.nextKey?t.getItem(e.nextKey):null;for(;null!=n&&"item"!==n.type;)n=null!=n.nextKey?t.getItem(n.nextKey):null;if(e&&null==n&&null!=e.parentKey){let r=t.getItem(e.parentKey);const n=null!=r?.nextKey?t.getItem(r.nextKey):null;if("item"===n?.type)return{type:"item",key:n.key,dropPosition:"before"};if("item"===r?.type)return{type:"item",key:r.key,dropPosition:"after"}}if(n)return{type:"item",key:n.key,dropPosition:"on"}}}}return n?{type:"root"}:null}function Rt(e,t,r,n=!1,o=null){if(!r||n&&"root"===r.type){let r=null,n=e.getLastKey?.();for(;null!=n;){let e=t.getItem(n);if("item"!==e?.type)break;r=n,n=e?.parentKey}return null!=r?{type:"item",key:r,dropPosition:"after"}:null}if("item"===r.type){let n=null;n=o?"left"===o?e.getKeyLeftOf?.(r.key,{includeDisabled:!0}):e.getKeyRightOf?.(r.key,{includeDisabled:!0}):e.getKeyAbove?.(r.key,{includeDisabled:!0});let i=Bt(t,r.key,e=>t.getKeyBefore(e));if(null!=n&&n!==i)return{type:"item",key:n,dropPosition:r.dropPosition};switch(r.dropPosition){case"before":{let e=t.getItem(r.key);if(e&&null!=e.prevKey){let r=Mt(t,e.prevKey);if(r)return r}return null!=n?{type:"item",key:n,dropPosition:"on"}:{type:"root"}}case"on":return{type:"item",key:r.key,dropPosition:"before"};case"after":{let e=Mt(t,r.key);return e||{type:"item",key:r.key,dropPosition:"on"}}}}return"root"!==r.type?{type:"root"}:null}function Mt(e,t){let r=e.getItem(t),n=Bt(e,t,t=>e.getKeyAfter(t)),o=null!=n?e.getItem(n):null;if(r&&o&&o.level>r.level){let t=null;if("lastChildKey"in r)for(t=null!=r.lastChildKey?e.getItem(r.lastChildKey):null;t&&"item"!==t.type&&null!=t.prevKey;)t=e.getItem(t.prevKey);else t=Array.from(r.childNodes).findLast(e=>"item"===e.type)||null;if(t)return{type:"item",key:t.key,dropPosition:"after"}}return null}function Bt(e,t,r){let n=r(t),o=null!=n?e.getItem(n):null;for(;o&&"item"!==o.type;)n=r(o.key),o=null!=n?e.getItem(n):null;return n}function Lt(t,r,n){let o=e.useRef({props:t,state:r,nextTarget:null,dropOperation:null}).current;o.props=t,o.state=r;let i=e.useCallback(async e=>{let{onInsert:t,onRootDrop:r,onItemDrop:i,onReorder:a,onMove:s,acceptedDragTypes:l="all",shouldAcceptItemDrop:d}=o.props,{draggingKeys:c}=lt,p=pt(n),{target:u,dropOperation:g,items:f}=e,m=f;("all"!==l||d)&&(m=f.filter(e=>{let t;return t="directory"===e.kind?new Set([Qe]):"file"===e.kind?new Set([e.type]):e.types,!("all"!==l&&!l.some(e=>t.has(e)))&&("item"!==u.type||"on"!==u.dropPosition||!d||d(u,t))})),m.length>0&&("root"===u.type&&r&&await r({items:m,dropOperation:g}),"item"===u.type&&("on"===u.dropPosition&&i&&await i({items:m,dropOperation:g,isInternal:p,target:u}),s&&p&&await s({keys:c,dropOperation:g,target:u}),"on"!==u.dropPosition&&(!p&&t&&await t({items:m,dropOperation:g,target:u}),p&&a&&await a({keys:c,dropOperation:g,target:u}))))},[o,n]),a=function(t){let r=e.useRef(null),n=e.useRef(!0),o=e.useRef(!0);e.useEffect(()=>{if(t.current){r.current=b(t.current)?t.current:w(t.current);let e=window.getComputedStyle(r.current);n.current=/(auto|scroll)/.test(e.overflowX),o.current=/(auto|scroll)/.test(e.overflowY)}},[t]);let i=e.useRef({timer:void 0,dx:0,dy:0}).current;e.useEffect(()=>()=>{i.timer&&(cancelAnimationFrame(i.timer),i.timer=void 0)},[i]);let a=e.useCallback(()=>{n.current&&r.current&&(r.current.scrollLeft+=i.dx),o.current&&r.current&&(r.current.scrollTop+=i.dy),i.timer&&(i.timer=requestAnimationFrame(a))},[r,i]);return{move(e,t){if(!x()||T()||!r.current)return;let n=r.current.getBoundingClientRect(),o=n.height-20,s=n.width-20;e<20||e>s||t<20||t>o?(e<20?i.dx=e-20:e>s&&(i.dx=e-s),t<20?i.dy=t-20:t>o&&(i.dy=t-o),i.timer||(i.timer=requestAnimationFrame(a))):this.stop()},stop(){i.timer&&(cancelAnimationFrame(i.timer),i.timer=void 0)}}}(n),{dropProps:s}=St({ref:n,onDropEnter(){null!=o.nextTarget&&r.setTarget(o.nextTarget)},onDropMove(e){null!=o.nextTarget&&r.setTarget(o.nextTarget),a.move(e.x,e.y)},getDropOperationForPoint(e,i,a,s){let{draggingKeys:l,dropCollectionRef:d}=lt,c=pt(n),p=t.dropTargetDelegate.getDropTargetFromPoint(a,s,t=>"cancel"!==r.getDropOperation({target:t,types:e,allowedOperations:i,isInternal:c,draggingKeys:l}));if(!p)return o.dropOperation="cancel",o.nextTarget=null,"cancel";if(o.dropOperation=r.getDropOperation({target:p,types:e,allowedOperations:i,isInternal:c,draggingKeys:l}),"cancel"===o.dropOperation){let t={type:"root"},n=r.getDropOperation({target:t,types:e,allowedOperations:i,isInternal:c,draggingKeys:l});"cancel"!==n&&(p=t,o.dropOperation=n)}return p&&"cancel"!==o.dropOperation&&n?.current!==d?.current&&dt(n),o.nextTarget="cancel"===o.dropOperation?null:p,o.dropOperation},onDropExit(){dt(void 0),r.setTarget(null),a.stop()},onDropActivate(e){"item"===r.target?.type&&"function"==typeof t.onDropActivate&&t.onDropActivate({type:"dropactivate",x:e.x,y:e.y,target:r.target})},onDrop(e){dt(n),r.target&&c(e,r.target);let{draggingCollectionRef:t}=lt;null==t&&ct()}}),l=e.useRef(null),d=e.useCallback(()=>{let{state:e}=o;if(l.current){let{target:t,collection:r,selectedKeys:n,focusedKey:o,isInternal:i,draggingKeys:a}=l.current;if(e.collection.size>r.size&&e.selectionManager.isSelectionEqual(n)){let t=new Set,n=e.collection.getFirstKey();for(;null!=n;){let o=e.collection.getItem(n);"item"!==o?.type||r.getItem(o.key)||t.add(o.key),n=o?.hasChildNodes&&"item"===e.collection.getItem(o.lastChildKey)?.type?o.firstChildKey:e.collection.getKeyAfter(n)}if(e.selectionManager.setSelectedKeys(t),e.selectionManager.focusedKey===o){let r=t.keys().next().value;if(null!=r){let t=e.collection.getItem(r),n=l.current.target,o=!!e.collection.expandedKeys&&e.collection.expandedKeys.has(t?.parentKey);t&&("cell"===t?.type||"item"===n.type&&"on"===n.dropPosition&&!o)&&(r=t.parentKey),null!=r&&e.selectionManager.setFocusedKey(r),"none"===e.selectionManager.selectionMode&&k("keyboard")}}}else null!=o&&e.selectionManager.focusedKey===o&&i&&"item"===t.type&&"on"!==t.dropPosition&&a.has(e.collection.getItem(o)?.parentKey)?(e.selectionManager.setFocusedKey(e.collection.getItem(o)?.parentKey??null),k("keyboard")):e.selectionManager.focusedKey===o&&"item"===t.type&&"on"===t.dropPosition&&null!=e.collection.getItem(t.key)?(e.selectionManager.setFocusedKey(t.key),k("keyboard")):null==e.selectionManager.focusedKey||e.selectionManager.isSelected(e.selectionManager.focusedKey)||k("keyboard");e.selectionManager.setFocused(!0)}},[o]),c=e.useCallback((e,t)=>{let{state:r}=o;l.current={timeout:void 0,focusedKey:r.selectionManager.focusedKey,collection:r.collection,selectedKeys:r.selectionManager.selectedKeys,draggingKeys:lt.draggingKeys,isInternal:pt(n),target:t},(o.props.onDrop||i)({type:"drop",x:e.x,y:e.y,target:t,items:e.items,dropOperation:e.dropOperation}),l.current.timeout=setTimeout(()=>{d(),l.current=null},50)},[o,i,n,d]);e.useEffect(()=>()=>{l.current&&clearTimeout(l.current.timeout)},[]),y(()=>{l.current&&r.collection!==l.current.collection&&d()});let{direction:p}=E();e.useEffect(()=>{if(!n.current)return;let e=(e,t=!0,r="down")=>function(e,t,r,n,o=!1,i=!1){switch(n){case"left":return o?At(e,t,r,i,"left"):Rt(e,t,r,i,"left");case"right":return o?Rt(e,t,r,i,"right"):At(e,t,r,i,"right");case"up":return Rt(e,t,r,i);case"down":return At(e,t,r,i)}}(o.props.keyboardDelegate,o.state.collection,e,r,"rtl"===p,t),t=(t,r=!0)=>e(t,r,"up"),r=(e,t,r,i,a=!0)=>{let s,l=0,{draggingKeys:d}=lt,c=pt(n);do{let n=i(e,a);if(!n)return null;e=n,s=o.state.getDropOperation({target:n,types:t,allowedOperations:r,isInternal:c,draggingKeys:d}),"root"===e.type&&l++}while("cancel"===s&&!o.state.isDropTarget(e)&&l<2);return"cancel"===s?null:e};return vt({element:n.current,preventFocusOnDrop:!0,getDropOperation(t,i){if(o.state.target){let{draggingKeys:e}=lt,r=pt(n);return o.state.getDropOperation({target:o.state.target,types:t,allowedOperations:i,isInternal:r,draggingKeys:e})}return r(null,t,i,e)?"move":"cancel"},onDropEnter(i,a){let s=Ze(a.items),l=o.state.selectionManager,d=null;dt(n);let c=l.focusedKey,p="after",u=null!=c?o.state.collection.getItem(c):null;if("cell"===u?.type&&(c=u.parentKey),null!=c&&l.isSelected(c)&&(l.selectedKeys.size>1&&l.firstSelectedKey===c?p="before":c=l.lastSelectedKey),null!=c){d={type:"item",key:c,dropPosition:p};let{draggingKeys:i}=lt,l=pt(n);"cancel"===o.state.getDropOperation({target:d,types:s,allowedOperations:a.allowedDropOperations,isInternal:l,draggingKeys:i})&&(d=r(d,s,a.allowedDropOperations,e,!1)??r(d,s,a.allowedDropOperations,t,!1))}d||(d=r(null,s,a.allowedDropOperations,e)),o.state.setTarget(d)},onDropExit(){dt(void 0),o.state.setTarget(null)},onDropTargetEnter(e){o.state.setTarget(e)},onDropActivate(e,t){"item"===t?.type&&"on"===t?.dropPosition&&"function"==typeof o.props.onDropActivate&&o.props.onDropActivate({type:"dropactivate",x:e.x,y:e.y,target:t})},onDrop(e,t){dt(n),o.state.target&&c(e,t||o.state.target)},onKeyDown(i,a){let{keyboardDelegate:s}=o.props,l=Ze(a.items);switch(i.key){case"ArrowDown":if(s.getKeyBelow){let t=r(o.state.target,l,a.allowedDropOperations,(t,r)=>e(t,r,"down"));o.state.setTarget(t)}break;case"ArrowUp":if(s.getKeyAbove){let t=r(o.state.target,l,a.allowedDropOperations,(t,r)=>e(t,r,"up"));o.state.setTarget(t)}break;case"ArrowLeft":if(s.getKeyLeftOf){let t=r(o.state.target,l,a.allowedDropOperations,(t,r)=>e(t,r,"left"));o.state.setTarget(t)}break;case"ArrowRight":if(s.getKeyRightOf){let t=r(o.state.target,l,a.allowedDropOperations,(t,r)=>e(t,r,"right"));o.state.setTarget(t)}break;case"Home":if(s.getFirstKey){let t=r(null,l,a.allowedDropOperations,e);o.state.setTarget(t)}break;case"End":if(s.getLastKey){let e=r(null,l,a.allowedDropOperations,t);o.state.setTarget(e)}break;case"PageDown":if(s.getKeyPageBelow){let i=o.state.target;if(i){let d=s.getFirstKey?.();"item"===i.type&&(d=i.key);let c=null;null!=d&&(c=s.getKeyPageBelow(d));let p="item"===i.type?i.dropPosition:"after";if((null==c||"item"===i.type&&i.key===s.getLastKey?.())&&(c=s.getLastKey?.()??null,p="after"),null==c)break;i={type:"item",key:c,dropPosition:p};let{draggingCollectionRef:u,draggingKeys:g}=lt,f=u?.current===n?.current;"cancel"===o.state.getDropOperation({target:i,types:l,allowedOperations:a.allowedDropOperations,isInternal:f,draggingKeys:g})&&(i=r(i,l,a.allowedDropOperations,e,!1)??r(i,l,a.allowedDropOperations,t,!1))}else i=r(null,l,a.allowedDropOperations,e);o.state.setTarget(i??o.state.target)}break;case"PageUp":{if(!s.getKeyPageAbove)break;let i=o.state.target;if(i){if("item"===i.type){if(i.key===s.getFirstKey?.())i={type:"root"};else{let e=s.getKeyPageAbove(i.key),t=i.dropPosition;if(null==e&&(e=s.getFirstKey?.(),t="before"),null==e)break;i={type:"item",key:e,dropPosition:t}}let{draggingKeys:d}=lt,c=pt(n);"cancel"===o.state.getDropOperation({target:i,types:l,allowedOperations:a.allowedDropOperations,isInternal:c,draggingKeys:d})&&(i=r(i,l,a.allowedDropOperations,t,!1)??r(i,l,a.allowedDropOperations,e,!1))}}else i=r(null,l,a.allowedDropOperations,t);o.state.setTarget(i??o.state.target);break}}o.props.onKeyDown?.(i)}})},[o,n,c,p]);let u=P();return We.set(r,{id:u,ref:n}),{collectionProps:K(s,{id:u,"aria-describedby":null})}}function Ft(t,r,n){let{dropProps:o}=Ot(),i=function(e){let{ref:t}=We.get(e)||{};if(!t)throw new Error("Droppable item outside a droppable collection");return t}(r);e.useEffect(()=>{if(n.current)return e={element:n.current,target:t.target,getDropOperation(e,n){let{draggingKeys:o}=lt,a=pt(i);return r.getDropOperation({target:t.target,types:e,allowedOperations:n,isInternal:a,draggingKeys:o})},activateButtonRef:t.activateButtonRef},ht.set(e.element,e),()=>{ht.delete(e.element)};var e},[n,t.target,r,i,t.activateButtonRef]);let a=bt(),{draggingKeys:s}=lt,l=pt(i),d=a&&"cancel"!==r.getDropOperation({target:t.target,types:Ze(a.dragTarget.items),allowedOperations:a.dragTarget.allowedDropOperations,isInternal:l,draggingKeys:s}),c=r.isDropTarget(t.target);return e.useEffect(()=>{a&&c&&n.current&&n.current.focus()},[c,a,n]),{dropProps:{...o,"aria-hidden":!a||d?void 0:"true"},isDropTarget:c}}function $t(e,t,r){let{target:n}=e,{collection:o}=t,i=f((a=Pt)&&a.__esModule?a.default:a,"@react-aria/dnd");var a;let s,l=bt(),{dropProps:d}=Ft(e,t,r),c=P(),p=e=>null==e?"":o.getTextValue?.(e)??o.getItem(e)?.textValue??"",u="";if("root"===n.type)u=i.format("dropOnRoot"),s=`${c} ${function(e){let{id:t}=We.get(e)||{};if(!t)throw new Error("Droppable item outside a droppable collection");return t}(t)}`;else if("on"===n.dropPosition)u=i.format("dropOnItem",{itemText:p(n.key)});else{let e,t;if("before"===n.dropPosition){let t=o.getItem(n.key)?.prevKey,r=null!=t?o.getItem(t):null;e="item"===r?.type?r.key:null}else e=n.key;if("after"===n.dropPosition){let e=o.getItem(n.key)?.nextKey,r=null!=e?o.getItem(e):null;t="item"===r?.type?r.key:null}else t=n.key;null!=e&&null!=t?u=i.format("insertBetween",{beforeItemText:p(e),afterItemText:p(t)}):null!=e?u=i.format("insertAfter",{itemText:p(e)}):null!=t&&(u=i.format("insertBefore",{itemText:p(t)}))}let g=t.isDropTarget(n),m=l?d["aria-hidden"]:"true";return{dropIndicatorProps:{...d,id:c,"aria-roledescription":i.format("dropIndicator"),"aria-label":u,"aria-labelledby":s,"aria-hidden":m,tabIndex:-1},isDropTarget:g,isHidden:!g&&!!m}}const zt={keyboard:{start:"dragDescriptionKeyboard",end:"endDragKeyboard"},touch:{start:"dragDescriptionTouch",end:"endDragTouch"},virtual:{start:"dragDescriptionVirtual",end:"endDragVirtual"}};function Nt(t){let{hasDragButton:r,isDisabled:n}=t,o=f((i=Pt)&&i.__esModule?i.default:i,"@react-aria/dnd");var i;let a=e.useRef({options:t,x:0,y:0}).current;a.options=t;let s=e.useRef(null),[p,u]=e.useState(!1),g=e=>{s.current=e,u(!!e)},{addGlobalListener:h,removeAllGlobalListeners:y}=O(),D=e.useRef(null);e.useEffect(()=>()=>{if(s.current&&(!s.current.isConnected||parseInt(e.version,10)<17)){if("function"==typeof a.options.onDragEnd){let e={type:"dragend",x:0,y:0,dropOperation:Ye[st||"none"]};a.options.onDragEnd(e)}g(null),ft(Ve.none),ut(void 0)}},[a]);let v=e=>{if("function"==typeof a.options.onDragStart){let t=e.getBoundingClientRect();a.options.onDragStart({type:"dragstart",x:t.x+t.width/2,y:t.y+t.height/2})}!function(e,t){if(yt)throw new Error("Cannot begin dragging while already dragging");yt=new Et(e,t),requestAnimationFrame(()=>{yt&&(yt.setup(),"keyboard"===rt()&&yt.next())});for(let r of Dt)r()}({element:e,items:a.options.getItems(),allowedDropOperations:"function"==typeof a.options.getAllowedDropOperations?a.options.getAllowedDropOperations():["move","copy","link"],onDragEnd(e){g(null),"function"==typeof a.options.onDragEnd&&a.options.onDragEnd(e)}},o),g(e)},b=tt(),w=p?zt[b].end:zt[b].start,k=m(o.format(w)),E={};return r||(E={...k,onPointerDown(e){if(D.current=c(e.nativeEvent)?"virtual":e.pointerType,e.width<1&&e.height<1&&T()&&x())D.current="virtual";else{let t=e.currentTarget.getBoundingClientRect(),r=e.clientX-t.x,n=e.clientY-t.y,o=t.width/2,i=t.height/2;Math.abs(r-o)<=.5&&Math.abs(n-i)<=.5?D.current="virtual":D.current=e.pointerType}},onKeyDownCapture(e){l(e)===e.currentTarget&&"Enter"===e.key&&(e.preventDefault(),e.stopPropagation())},onKeyUpCapture(e){l(e)===e.currentTarget&&"Enter"===e.key&&(e.preventDefault(),e.stopPropagation(),v(l(e)))},onClick(e){(d(e.nativeEvent)||"virtual"===D.current)&&(e.preventDefault(),e.stopPropagation(),v(l(e)))}}),n?{dragProps:{draggable:"false"},dragButtonProps:{},isDragging:!1}:{dragProps:{...E,draggable:"true",onDragStart:e=>{if(e.defaultPrevented)return;if(e.stopPropagation(),"virtual"===D.current)return e.preventDefault(),v(l(e)),void(D.current=null);"function"==typeof t.onDragStart&&t.onDragStart({type:"dragstart",x:e.clientX,y:e.clientY});let r=t.getItems();e.dataTransfer.clearData?.(),function(e,t){let r=new Map,n=!1,o=[];for(let i of t){let e=Object.keys(i);e.length>1&&(n=!0);let t={};for(let o of e){let e=r.get(o);e?n=!0:(e=[],r.set(o,e));let a=i[o];t[o]=a,e.push(a)}o.push(t)}for(let[i,a]of r)if(Je.has(i)){let t=a.join("\n");e.items.add(t,i)}else e.items.add(a[0],i);if(n){let t=JSON.stringify(o);e.items.add(t,Ge)}}(e.dataTransfer,r);let n=Ve.all;if("function"==typeof t.getAllowedDropOperations){let e=t.getAllowedDropOperations();n=Ve.none;for(let t of e)n|=Ve[t]||Ve.none}ft(n);let o=Xe[n]||"none";e.dataTransfer.effectAllowed="cancel"===o?"none":o,"function"==typeof t.preview?.current&&t.preview.current(r,(t,r,n)=>{if(!t)return;let o=t.getBoundingClientRect(),i=e.currentTarget.getBoundingClientRect(),a=e.clientX-i.x,s=e.clientY-i.y;(a>o.width||s>o.height)&&(a=o.width/2,s=o.height/2);let l=a,d=s;"number"==typeof r&&"number"==typeof n&&(l=r,d=n),l=Math.max(0,Math.min(l,o.width)),d=Math.max(0,Math.min(d,o.height));let c=2*Math.round(o.height/2);t.style.height=`${c}px`,e.dataTransfer.setDragImage(t,l,d)}),h(window,"drop",e=>{e.preventDefault(),e.stopPropagation(),console.warn("Drags initiated from the React Aria useDrag hook may only be dropped on a target created with useDrop. This ensures that a keyboard and screen reader accessible alternative is available.")},{once:!0}),a.x=e.clientX,a.y=e.clientY;let i=l(e);requestAnimationFrame(()=>{g(i)})},onDrag:e=>{e.stopPropagation(),e.clientX===a.x&&e.clientY===a.y||("function"==typeof t.onDragMove&&t.onDragMove({type:"dragmove",x:e.clientX,y:e.clientY}),a.x=e.clientX,a.y=e.clientY)},onDragEnd:e=>{if(e.stopPropagation(),"function"==typeof t.onDragEnd){let r={type:"dragend",x:e.clientX,y:e.clientY,dropOperation:Ye[e.dataTransfer.dropEffect]};st&&(r.dropOperation=Ye[st]),t.onDragEnd(r)}g(null),y(),ft(Ve.none),ut(void 0)}},dragButtonProps:{...k,onPress:e=>{"keyboard"!==e.pointerType&&"virtual"!==e.pointerType||v(e.target)}},isDragging:p}}const Vt={keyboard:{selected:"dragSelectedKeyboard",notSelected:"dragDescriptionKeyboard"},touch:{selected:"dragSelectedLongPress",notSelected:"dragDescriptionLongPress"},virtual:{selected:"dragDescriptionVirtual",notSelected:"dragDescriptionVirtual"}};function Ht(e,t){let r=f((n=Pt)&&n.__esModule?n.default:n,"@react-aria/dnd");var n;let o,i,a=t.isDisabled||t.selectionManager.isDisabled(e.key),{dragProps:s,dragButtonProps:l}=Nt({getItems:()=>t.getItems(e.key),preview:t.preview,getAllowedDropOperations:t.getAllowedDropOperations,hasDragButton:e.hasDragButton,onDragStart(r){var n;t.startDrag(e.key,r),n=t.draggingKeys,lt.draggingKeys=n},onDragMove(e){t.moveDrag(e)},onDragEnd(e){let{dropOperation:r}=e,n="cancel"!==r&&pt();t.endDrag({...e,keys:t.draggingKeys,isInternal:n}),ct()}}),d=t.collection.getItem(e.key),c=t.getKeysForDrag(e.key).size,p=c>1&&t.selectionManager.isSelected(e.key),u=tt();if(e.hasDragButton||"none"===t.selectionManager.selectionMode)if(p)o=r.format("dragSelectedItems",{count:c});else{let n=t.collection.getTextValue?.(e.key)??d?.textValue??"";o=r.format("dragItem",{itemText:n})}else{let t=Vt[u][p?"selected":"notSelected"];e.hasAction&&"keyboard"===u&&(t+="Alt"),i=p?r.format(t,{count:c}):r.format(t),delete s.onClick}let g=m(i);if(i&&Object.assign(s,g),!e.hasDragButton&&e.hasAction){let{onKeyDownCapture:e,onKeyUpCapture:t}=s;"touch"===u&&delete s["aria-describedby"],s.onKeyDownCapture=t=>{t.altKey&&e?.(t)},s.onKeyUpCapture=e=>{e.altKey&&t?.(e)}}return{dragProps:a?{}:s,dragButtonProps:{...l,isDisabled:a,"aria-label":o}}}function Xt(e,t,r){let{draggingCollectionRef:n}=lt;t.draggingKeys.size>0&&n?.current!==r.current&&function(e){lt.draggingCollectionRef=e}(r)}const Yt=t.forwardRef(function(n,o){let i=n.children,[a,s]=e.useState(null),l=e.useRef(null),d=e.useRef(void 0);return e.useImperativeHandle(o,()=>(e,t)=>{let n,o,a,c=i(e);c&&"object"==typeof c&&"element"in c?(n=c.element,o=c.x,a=c.y):n=c,r.flushSync(()=>{s(n)}),t(l.current,o,a),d.current=requestAnimationFrame(()=>{s(null)})},[i]),e.useEffect(()=>()=>{d.current&&cancelAnimationFrame(d.current)},[]),a?t.createElement("div",{style:{zIndex:-100,position:"fixed",top:0,left:-1e5},ref:l},a):null});function Ut(e,t){if(!e)return!t;switch(e.type){case"root":return"root"===t?.type;case"item":return"item"===t?.type&&t?.key===e.key&&t?.dropPosition===e.dropPosition}}class qt{constructor(e,t,r){this.collection=e,this.ref=t,this.layout=r?.layout||"stack",this.orientation=r?.orientation||"vertical",this.direction=r?.direction||"ltr"}getPrimaryStart(e){return"horizontal"===this.orientation?e.left:e.top}getPrimaryEnd(e){return"horizontal"===this.orientation?e.right:e.bottom}getSecondaryStart(e){return"horizontal"===this.orientation?e.top:e.left}getSecondaryEnd(e){return"horizontal"===this.orientation?e.bottom:e.right}getFlowStart(e){return"stack"===this.layout?this.getPrimaryStart(e):this.getSecondaryStart(e)}getFlowEnd(e){return"stack"===this.layout?this.getPrimaryEnd(e):this.getSecondaryEnd(e)}getFlowSize(e){return this.getFlowEnd(e)-this.getFlowStart(e)}getDropTargetFromPoint(e,t,r){if(this.collection[Symbol.iterator]().next().done||!this.ref.current)return{type:"root"};let n=this.ref.current.getBoundingClientRect(),o="horizontal"===this.orientation?e:t,i="horizontal"===this.orientation?t:e;o+=this.getPrimaryStart(n),i+=this.getSecondaryStart(n);let a="stack"===this.layout?o:i,s="horizontal"===this.orientation&&"rtl"===this.direction,l="grid"===this.layout&&"vertical"===this.orientation&&"rtl"===this.direction,d="stack"===this.layout?s:l,c=this.ref.current?.dataset.collection,p=this.ref.current.querySelectorAll(c?`[data-collection="${CSS.escape(c)}"]`:"[data-key]"),u=new Map;for(let D of p)D instanceof HTMLElement&&null!=D.dataset.key&&u.set(D.dataset.key,D);let g=[...this.collection].filter(e=>"item"===e.type);if(g.length<1)return{type:"root"};let f=0,m=g.length;for(;f{t?f=e+1:m=e};if(othis.getPrimaryEnd(c))p(!s);else if(ithis.getSecondaryEnd(c))){let e={type:"item",key:t.key,dropPosition:"on"};if(r(e))a<=this.getFlowStart(c)+5&&r({...e,dropPosition:"before"})?e.dropPosition=d?"after":"before":a>=this.getFlowEnd(c)-5&&r({...e,dropPosition:"after"})&&(e.dropPosition=d?"before":"after");else{let t=this.getFlowStart(c)+this.getFlowSize(c)/2;a<=t&&r({...e,dropPosition:"before"})?e.dropPosition=d?"after":"before":a>=t&&r({...e,dropPosition:"after"})&&(e.dropPosition=d?"before":"after")}return e}p(!l)}}let h=g[Math.min(f,g.length-1)],y=u.get(String(h.key));return n=y?.getBoundingClientRect(),n&&(o{let{onDrop:r,onInsert:n,onItemDrop:o,onReorder:i,onMove:a,onRootDrop:s,getItems:l,renderDragPreview:d,renderDropIndicator:c,dropTargetDelegate:p}=t,u=!!(r||n||o||i||a||s),g={};return!!l&&(g.useDraggableCollectionState=function(r){return function(t){let{getItems:r,isDisabled:n,collection:o,selectionManager:i,onDragStart:a,onDragMove:s,onDragEnd:l,preview:d,getAllowedDropOperations:c}=t,[,p]=e.useState(!1),u=e.useRef(new Set),g=e.useRef(null),f=e=>{let t=new Set;if(i.isSelected(e))for(let r of i.selectedKeys){let e=o.getItem(r);if(e){let n=!1,a=e.parentKey;for(;null!=a;){if(i.selectedKeys.has(a)){n=!0;break}let e=o.getItem(a);a=e?e.parentKey:null}n||t.add(r)}}else t.add(e);return t};return{collection:o,selectionManager:i,get draggedKey(){return g.current},get draggingKeys(){return u.current},isDragging:e=>u.current.has(e),getKeysForDrag:f,getItems(e){let t=f(e),n=[];for(let r of t){let e=o.getItem(r)?.value;null!=e&&n.push(e)}return r(f(e),n)},isDisabled:n,preview:d,getAllowedDropOperations:c,startDrag(e,t){let r=f(e);u.current=r,g.current=e,i.setFocused(!1),p(!0),"function"==typeof a&&a({...t,keys:r})},moveDrag(e){"function"==typeof s&&s({...e,keys:u.current})},endDrag(e){let{isInternal:t}=e;"function"==typeof l&&l({...e,keys:u.current,isInternal:t}),u.current=new Set,g.current=null,p(!1)}}}({...r,...t})},g.useDraggableCollection=Xt,g.useDraggableItem=Ht,g.DragPreview=Yt,g.renderDragPreview=d,g.isVirtualDragging=wt),u&&(g.useDroppableCollectionState=function(r){return function(t){let{acceptedDragTypes:r="all",isDisabled:n,onInsert:o,onRootDrop:i,onItemDrop:a,onReorder:s,onMove:l,shouldAcceptItemDrop:d,collection:c,selectionManager:p,onDropEnter:u,getDropOperation:g,onDrop:f}=t,[m,h]=e.useState(null),y=e.useRef(null),D=e=>{if("before"===e.dropPosition){let t=c.getItem(e.key);return t&&null!=t.prevKey?{type:"item",key:t.prevKey,dropPosition:"after"}:null}if("after"===e.dropPosition){let t=c.getItem(e.key);return t&&null!=t.nextKey?{type:"item",key:t.nextKey,dropPosition:"before"}:null}return null},v=e.useCallback(e=>{let{target:t,types:p,allowedOperations:u,isInternal:m,draggingKeys:h}=e;if(n||!t)return"cancel";if("all"===r||r.some(e=>p.has(e))){let e=o&&"item"===t.type&&!m&&("before"===t.dropPosition||"after"===t.dropPosition),r=s&&"item"===t.type&&m&&("before"===t.dropPosition||"after"===t.dropPosition)&&function(e,t,r){let n=e.getItem(t.key);for(let o of r){let t=e.getItem(o);if(t?.parentKey!==n?.parentKey)return!1}return!0}(c,t,h),n="item"!==t.type||"on"!==t.dropPosition||!d||d(t,p),y=l&&"item"===t.type&&m&&n,D=i&&"root"===t.type&&!m,v=a&&"item"===t.type&&"on"===t.dropPosition&&!(m&&null!=t.key&&h.has(t.key))&&n;if(f||e||r||y||D||v)return g?g(t,p,u):u[0]}return"cancel"},[n,c,r,g,o,i,a,d,s,l,f]);return{collection:c,selectionManager:p,isDisabled:n,target:m,setTarget(e){if(this.isDropTarget(e))return;let r=y.current;r&&"function"==typeof t.onDropExit&&t.onDropExit({type:"dropexit",x:0,y:0,target:r}),e&&"function"==typeof u&&u({type:"dropenter",x:0,y:0,target:e}),y.current=e??null,h(e??null)},isDropTarget(e){let t=y.current;return!(!t||!e)&&(!!Ut(e,t)||"item"===e?.type&&"item"===t?.type&&e.key!==t.key&&e.dropPosition!==t.dropPosition&&"on"!==e.dropPosition&&"on"!==t.dropPosition&&(Ut(D(e),t)||Ut(e,D(t))))},getDropOperation(e){let{target:t,isInternal:r,draggingKeys:n}=e;if(r&&"item"===t.type&&n.size>0){if(n.has(t.key)&&"on"===t.dropPosition)return"cancel";let e=t.key;for(;null!=e;){let t=c.getItem(e),r=t?.parentKey;if(null!=r&&n.has(r))return"cancel";e=r??null}}return v(e)}}}({...r,...t})},g.useDroppableItem=Ft,g.useDroppableCollection=function(e,r,n){return Lt({...e,...t},r,n)},g.useDropIndicator=$t,g.renderDropIndicator=c,g.dropTargetDelegate=p,g.ListDropTargetDelegate=qt),g},[t])}}const Gt="application/x-doona-card";function _t(e){return n.jsx(S,{viewBox:"0 0 12 12",...e,children:[1.6,6,10.4].flatMap(e=>[3.8,8.2].map(t=>n.jsx("circle",{cx:t,cy:e,r:1.1,fill:"currentColor"},`${t}-${e}`)))})}const Wt={},Qt=new Map,Zt=new Set,er=e=>{if(Wt.card=e,Qt.clear(),void 0===e)for(const t of Zt)t()},tr=e=>[...document.querySelectorAll(".rp-dashboard-cell")].find(t=>t.dataset.instance===e);function rr(e){let t=[1,1];for(let r=1;r<=12;r++){const n=Math.round(e*r);n>0&&Math.abs(e-n/r){const e=t.current;if(!e)return;const r=()=>{const t=e.parentElement.getBoundingClientRect(),r=getComputedStyle(e),n=Number.parseFloat(r.getPropertyValue("--rp-dash-gap"))||0,o=function(e,t,r,n){const o=n?e.map(e=>({...e,left:t-e.right,right:t-e.left})):e,i=new Map;for(const a of o)i.set(Math.round(a.top),[...i.get(Math.round(a.top))??[],a]);return[...i.values()].flatMap(e=>{const i=e[0].top,a=Math.max(...e.map(e=>e.bottom)),s=Math.max(...e.map(e=>e.right))+r;let l=t;for(const t of o)!e.includes(t)&&t.topi+.5&&t.right>s&&(l=Math.min(l,t.left-r));return(l-s+r)/(t+r)<1/6-.01?[]:[{after:e.at(-1).id,left:n?t-l:s,top:i,width:l-s,height:a-i}]})}([...e.querySelectorAll(":scope > .rp-dashboard-cell")].map(e=>{const r=e.getBoundingClientRect();return{id:e.dataset.instance,left:r.left-t.left,right:r.right-t.left,top:r.top-t.top,bottom:r.bottom-t.top}}),t.width,n,"rtl"===r.direction).map(e=>({...e,share:rr((e.width+n)/(t.width+n))}));s(e=>JSON.stringify(e)===JSON.stringify(o)?e:o)};return r(),e.addEventListener("rp-packed",r),()=>e.removeEventListener("rp-packed",r)},[t]),a.map(e=>n.jsx(or,{section:t,gap:e,label:r(e.share),refusal:o,onPlace:i},e.after))}function or({section:t,gap:r,label:o,refusal:i,onPlace:a}){const s=e.useRef(null),[l,d]=e.useState(!1),c=(e=Wt.card)=>{const n=t.current;if(void 0===e||!n)return!1;const o=[e,r.after,r.width].join("\n");return Qt.has(o)||Qt.set(o,(function(e,t,r){const n=tr(t),o=tr(r);if(!n||o?.parentElement!==e)return;const i=document.createElement("div");i.className="rp-dashboard-cell",i.style.visibility="hidden";for(const d of["data-module","data-size","data-foot","data-width","data-height"]){const e=n.getAttribute(d);null!==e&&i.setAttribute(d,e)}const a=e.dataset.grid;i.dataset.width&&(e.dataset.grid="fraction");const s=n.parentElement===e;s&&n.classList.remove("rp-dashboard-cell"),o.after(i);const l=i.getBoundingClientRect().width;return i.remove(),s&&n.classList.add("rp-dashboard-cell"),void 0===a?delete e.dataset.grid:e.dataset.grid=a,l}(n,e,r.after)??1/0)<=r.width+1),Qt.get(o)},{dropProps:p,isDropTarget:u}=St({ref:s,getDropOperation:e=>e.has(Gt)&&c()?"move":"cancel",onDrop:async e=>{for(const t of e.items){if("text"!==t.kind||!t.types.has(Gt))continue;const e=await t.getText(Gt);c(e)&&a(e,{target:r.after,after:!0})}}}),g={onDragEnter:()=>d(void 0!==Wt.card&&!c()),onDragLeave:()=>d(!1),onDrop:()=>d(!1)};return e.useEffect(()=>{const e=()=>d(!1);return Zt.add(e),()=>{Zt.delete(e)}},[]),n.jsxs("div",{...K(p,g),ref:s,className:"rp-dashboard-gap rp-label","data-drop-target":u||void 0,"data-refused":l||void 0,style:{left:r.left,top:r.top,width:r.width,height:r.height},children:[o,n.jsx(C,{children:n.jsx("span",{role:"status",children:l?i:""})})]})}const ir={current:null};let ar;function sr({label:t,profile:r,items:o,textValue:i,dragLabel:a,tools:s,resize:l,gapLabel:d,refusal:c,rearm:p,children:u,onPlace:g,...f}){const m=e.useRef(null);W(r?m:ir),e.useEffect(()=>{!p?.focus||document.activeElement&&document.activeElement!==document.body||m.current?.querySelector(`[data-key="${CSS.escape(p.focus)}"]`)?.focus()},[p]);const h=async e=>{for(const t of e.items)if("text"===t.kind&&t.types.has(Gt))return t.getText(Gt)},{dragAndDropHooks:y}=function(t){const{dragAndDropHooks:r}=Jt(t);return{dragAndDropHooks:e.useMemo(()=>function(e){const{useDraggableItem:t,isVirtualDragging:r}=e;return t&&r?{...e,useDraggableItem:(e,n)=>{const o=t(e,n),i=o.dragButtonProps.onPress;return{...o,dragButtonProps:{...o.dragButtonProps,onPress:e=>{r()||i?.(e)}}}}}:e}(r),[r])}}({getItems:e=>[...e].map(e=>({[Gt]:String(e),"text/plain":i(o.find(t=>t.id===e))})),getAllowedDropOperations:()=>["move"],acceptedDragTypes:[Gt],getDropOperation:()=>"move",onDragStart:e=>er(String([...e.keys][0])),onDragEnd:()=>{er(void 0),function(){ar?.();const e=()=>{document.removeEventListener("pointerdown",e,!0),document.removeEventListener("mousedown",t,!0),ar=void 0},t=t=>{e();const{clientX:r,clientY:n,screenX:o,screenY:i,button:a,buttons:s,ctrlKey:l,shiftKey:d,altKey:c,metaKey:p}=t;t.target?.dispatchEvent(new PointerEvent("pointerdown",{bubbles:!0,cancelable:!0,composed:!0,pointerId:1,pointerType:"mouse",isPrimary:!0,clientX:r,clientY:n,screenX:o,screenY:i,button:a,buttons:s,ctrlKey:l,shiftKey:d,altKey:c,metaKey:p}))};ar=e,document.addEventListener("pointerdown",e,!0),document.addEventListener("mousedown",t,!0)}()},renderDropIndicator:e=>n.jsx(Be,{target:e,className:"rp-canvas-drop"}),onReorder:e=>{for(const t of e.keys)g(String(t),{target:String(e.target.key),after:"after"===e.target.dropPosition})},onInsert:async e=>{const t=await h(e);t&&g(t,{target:String(e.target.key),after:"after"===e.target.dropPosition})},onRootDrop:async e=>{const t=await h(e);t&&g(t,{})}}),D=n.jsx(Re,{...f,ref:m,"aria-label":t,layout:"grid",className:r?"rp-dash-section":"rp-widget-grid rp-sortable-grid","data-profile":r,"data-grid":r?te(o):void 0,items:o,dragAndDropHooks:y,dependencies:[u,s,l],children:e=>n.jsxs(Me,{id:e.id,textValue:i(e),className:r?"rp-dashboard-cell":"rp-widget-cell rp-sortable-row",...r?Z(e):{"data-size":ee(e.size),"data-module":e.module},children:[n.jsxs("div",{className:"rp-dashboard-tools",children:[n.jsx(I,{slot:"drag",className:j({quiet:!0,icon:!0,small:!r}),"aria-label":a(e),children:n.jsx(_t,{})}),s?.(e)]}),n.jsx(Q,{children:u(e)}),l?.(e)]})});return r?n.jsxs("div",{className:"rp-dashboard-canvas","data-rearm":p?"":void 0,children:[D,d&&n.jsx(nr,{section:m,label:d,refusal:c,onPlace:g})]}):D}function lr({id:t,label:r,added:o,addLabel:i,count:a,onAdd:s,presets:l,row:d,children:c}){const[p,u]=A(void 0,200),[g,f]=e.useState(!1);return u&&!g&&f(!0),n.jsxs("section",{ref:p,className:"rp-widget-gallery-tile","data-added":o||void 0,"data-module":t,"aria-label":r,children:[n.jsx("h3",{className:"rp-h3",children:r}),l&&d?n.jsx(dr,{presets:l,row:d,loaded:g,disabled:o}):n.jsx("div",{className:"rp-widget-gallery-frame",inert:!0,children:n.jsx(R,{value:!1,children:g&&c})}),n.jsxs("div",{className:"rp-cluster",children:[n.jsx(M,{isDisabled:o,label:`${i} ${r}`,onPress:s,children:i}),n.jsx("span",{className:"rp-label",children:a})]})]})}function dr({presets:e,row:t,loaded:r,disabled:o}){const[i,a]=B(Math.round),s=a?a.width/t.width:0;return n.jsx("div",{ref:i,className:"rp-widget-gallery-presets",style:{"--rp-preset-gap":t.gap*s+"px"},children:r&&s>0&&e.map(e=>n.jsx(cr,{preset:e,width:e.share*(t.width+t.gap)-t.gap,scale:s,disabled:o},e.key))})}function cr({preset:e,width:t,scale:r,disabled:o}){const[i,a]=B(Math.round);return n.jsxs("div",{className:"rp-widget-gallery-preset",style:{inlineSize:t*r},children:[n.jsxs("div",{className:"rp-widget-gallery-thumb",style:{blockSize:(a?.height??0)*r},children:[n.jsx("div",{ref:i,className:"rp-widget-gallery-thumb-card",style:{inlineSize:t,scale:String(r)},inert:!0,children:n.jsx(R,{value:!1,children:e.preview})}),n.jsx(I,{className:"rp-widget-gallery-thumb-add","aria-label":e.addLabel,isDisabled:o,onPress:e.onAdd})]}),n.jsx("span",{className:"rp-label",children:e.label})]})}function pr({label:e,children:t}){return n.jsxs("div",{className:"rp-module-option",children:[n.jsx("span",{className:"rp-label",children:e}),t]})}function ur(){const e=document.querySelector(".rp-dashboard-canvas"),t=e&&getComputedStyle(e.querySelector(".rp-dash-section")??e);return{width:e?.getBoundingClientRect().width||1152,gap:Number.parseFloat(t?.getPropertyValue("--rp-dash-gap")??"")||12,snap:Number.parseFloat(t?.getPropertyValue("--rp-dash-snap")??"")||12}}function gr({items:t,add:r,surface:o="panel"}){const i=L(),[a]=e.useState(ur),s="dashboard"===o?re(ne()):[];return Object.keys(oe).filter(e=>"panel"===o||!ie(e)).map(e=>{const l=t.filter(t=>t.id===e).length,d=s.find(t=>t.id===e)??ae(e),c=e=>{const t=we(e.width);return a.snap>=12?t:Math.ceil(t*a.snap-1e-6)/a.snap};return n.jsx(lr,{id:e,label:i(oe[e].label),added:l>=me,addLabel:i("widgets.add"),count:i("widgets.placedCount",{n:l,max:me}),onAdd:()=>r(e),row:a,presets:"dashboard"===o?le(d,de(d)).map(t=>{const o=ce(d,t),a=pe(t,i);return{key:a,label:a,addLabel:i("widgets.addPreset",{name:i(oe[e].label),size:a}),share:c(t),onAdd:()=>r(e,t),preview:n.jsx(ue,{id:e,children:n.jsx(F,{value:!0,children:n.jsx("div",{className:"rp-dashboard-cell",...Z(fe(o)),"data-tile":"tall"===o.height?"stacked":void 0,children:n.jsx(ge,{item:o,preview:!0})})})})}}):void 0,children:"panel"===o&&n.jsx(se,{item:ae(e),preview:!0,sample:!0})},e)})}const fr={area:"dashboard.form.area",sparkline:"dashboard.form.sparkline",donut:"dashboard.form.donut",waffle:"dashboard.form.waffle",dots:"dashboard.form.dots",ranked:"dashboard.form.ranked",kv:"dashboard.form.kv",facts:"dashboard.form.facts"},mr={small:"widgets.small",medium:"widgets.medium",large:"widgets.large",wide:"dashboard.wide"};function hr({active:e,items:t,sizes:r=[],surface:o,update:i,move:a,remove:s}){const l=L();if(!e)return n.jsx("p",{className:"rp-label",children:l("widgets.select")});const d=oe[e.id].groupChoice;return n.jsxs(n.Fragment,{children:["dashboard"===o&&Object.values(he(e,de(e),l)).map(e=>e&&n.jsx(pr,{label:e.label,children:n.jsx(Fe,{label:e.label,value:e.value,onChange:t=>i(e.set(t)),items:e.options.map(e=>[e.value,e.label])})},e.label)),r.length>1&&n.jsx(pr,{label:l("widgets.size"),children:n.jsx(Fe,{label:l("widgets.size"),value:e.size,onChange:t=>i({...e,size:t,form:"panel"===o&&"small"===t&&ye(e.id,o).includes("kv")?"kv":e.form}),items:r.map(e=>[e,l(mr[e])])})}),ye(e.id,o).length>1&&!("small"===e.size&&!e.width&&ye(e.id,o).includes("sparkline"))&&n.jsx(pr,{label:l("widgets.form"),children:n.jsx(Fe,{label:l("widgets.form"),value:ve(e,o),onChange:t=>i({...e,form:t,size:"large"!==e.size||De(e.id,t,o).includes("large")?e.size:"medium"}),items:ye(e.id,o).map(e=>[e,l(fr[e])])})}),"ranking"===e.id&&n.jsx(pr,{label:l("widgets.rankBy"),children:n.jsx(Fe,{label:l("widgets.rankBy"),value:e.by??"dev",onChange:t=>i({...e,by:"domain"===t?"domain":"dev"}),items:[["dev",l("act.devices")],["domain",l("act.domains")]]})}),"speed"===e.id&&"small"!==e.size&&"sparkline"===ve(e,o)&&n.jsx($,{isSelected:!e.split,onChange:t=>i({...e,split:!t||void 0}),children:l("widgets.combineRates")}),d&&n.jsx(yr,{item:e,automatic:d,update:i}),n.jsxs("div",{className:"rp-cluster rp-module-actions",children:[n.jsx(M,{isDisabled:be(t[0])===be(e),onPress:()=>a(-1),children:l("widgets.up")}),n.jsx(M,{isDisabled:be(t.at(-1))===be(e),onPress:()=>a(1),children:l("widgets.down")}),n.jsx(M,{negative:!0,onPress:s,children:l("widgets.remove")})]})]})}function yr({item:e,automatic:t,update:r}){const o=z(),i=$e(!0===o.data?.resources.groups.available),a=L(),s=a(t);return n.jsx(pr,{label:a("ui.group"),children:n.jsx(Ne,{label:a("ui.group"),value:e.group??"",items:[{id:"",label:s},...(i.data??[]).map(e=>({id:e.id,label:e.name}))],onChange:t=>r({...e,group:t}),children:i.data?.find(t=>t.id===e.group)?.name??s})})}function Dr(e,t,r){const n=re(e).find(e=>be(e)===t);if(!n||r.target===t)return e;const o=e.sections.map(e=>({...e,items:e.items.filter(e=>be(e)!==t)})),i=o.find(e=>e.id===r.section);if(!i)return e;const a=void 0===r.target?-1:i.items.findIndex(e=>be(e)===r.target);return i.items.splice(a<0?i.items.length:a+(r.after?1:0),0,n),{...e,sections:o}}function vr({width:e,height:t}){return n.jsxs(n.Fragment,{children:[n.jsx(Er,{axis:e,edge:"width"}),t&&n.jsx(Er,{axis:t,edge:"height"})]})}const br=e=>{const[t,r=1]=e.split("/").map(Number);return t/r||0};function wr(e,t){const r=e.closest(".rp-dash-section"),n=getComputedStyle(r),o=getComputedStyle(e),i=Number.parseFloat(n.getPropertyValue("--rp-dash-snap"))||12,a=Number.parseFloat(n.getPropertyValue("--rp-dash-gap"))||0,s=r.getBoundingClientRect().width+Math.min(0,Number.parseFloat(n.marginInlineStart)||0),l=Number.parseFloat(o.getPropertyValue("--rp-span"))||420,d=br(o.getPropertyValue("--rp-shift"))-br(o.getPropertyValue("--rp-trim"));return t.map(t=>{if(void 0===t.fraction)return e.dataset.width?l/420*(s+a)-a+d*a:e.getBoundingClientRect().width;return(i>=12?t.fraction:Math.ceil(t.fraction*i-1e-6)/i)*(s+a)-a})}const xr=(e,t,r)=>t.reduce((n,o,i)=>{const a=Math.abs(o-r)-Math.abs(t[n]-r);return a<-.5||a<=.5&&void 0===e[n].fraction&&void 0!==e[i].fraction?i:n},0),Tr=new Map,kr=e=>e.target&&Tr.get(e.target)?.(e);function Er({axis:t,edge:r}){const o=e.useRef(null),i=e.useRef(null),{focusProps:a,isFocusVisible:s}=N(),l=()=>o.current.closest(".rp-dashboard-cell"),d=()=>"rtl"===getComputedStyle(o.current).direction,c=Math.max(0,t.options.findIndex(e=>e.value===t.value)),p=e=>{i.current&&(i.current.index=e),t.options[e].value!==t.value&&t.onChange(t.options[e])},{moveProps:u}=ze({onMoveStart:()=>{const e=l().getBoundingClientRect(),n=Number.parseFloat(getComputedStyle(l()).getPropertyValue("--rp-space-16"))||1,o="width"===r?wr(l(),t.options):[];i.current={start:c,size:"width"===r?e.width:e.height,travel:0,sizes:o,step:n,index:c},l().dataset.resizing=""},onMove:({deltaX:e,deltaY:n,pointerType:o})=>{const a=i.current;if(!a||"keyboard"===o)return;a.travel+="width"===r?e*(d()?-1:1):n;const s="width"===r?xr(t.options,a.sizes,a.size+a.travel):Math.max(0,Math.min(t.options.length-1,a.start+Math.round(a.travel/a.step)));s!==a.index&&p(s)},onMoveEnd:()=>{i.current=null,delete l().dataset.resizing}}),g=e.useRef(e=>{});return e.useLayoutEffect(()=>{g.current=e=>{const n="width"===r?d()?"ArrowLeft":"ArrowRight":"ArrowDown",o="width"===r?d()?"ArrowRight":"ArrowLeft":"ArrowUp";e.key!==n&&e.key!==o||(e.preventDefault(),e.stopPropagation(),p((e=>{if("width"===r&&void 0===t.options[c].fraction){if(!e)return c;const r=l().getBoundingClientRect().width,n=wr(l(),t.options).findIndex((e,n)=>void 0!==t.options[n].fraction&&e>r+1);return n<0?t.options.length-1:n}return Math.max(0,Math.min(t.options.length-1,c+(e?1:-1)))})(e.key===n)))}}),e.useEffect(()=>{return e=o.current,t=e=>g.current(e),Tr.size||addEventListener("keydown",kr,!0),Tr.set(e,t),()=>{Tr.delete(e),Tr.size||removeEventListener("keydown",kr,!0)};var e,t},[]),n.jsx("div",{ref:o,role:"slider",tabIndex:0,...a,...u,onPointerDown:e=>{e.preventDefault(),e.stopPropagation(),u.onPointerDown?.(e)},className:"rp-dashboard-resize rp-grip","data-edge":r,"data-focus-visible":s||void 0,"aria-label":t.label,"aria-orientation":"width"===r?"horizontal":"vertical","aria-valuemin":0,"aria-valuemax":t.options.length-1,"aria-valuenow":c,"aria-valuetext":t.options[c]?.label})}const Pr=(e,t)=>e.filter(e=>e.id===t).lengthbe(e)===t)?{instance:V()}:{}}:null;function Kr({draft:t,setDraft:r,render:o}){const i=L(),[a,s]=e.useState({text:"",serial:0}),l=re(t),d=e=>s(t=>({text:e,serial:t.serial+1})),c=e.useRef([]);e.useEffect(()=>()=>c.current.forEach(e=>q(e.key)),[]),e.useEffect(()=>{c.current=c.current.filter(e=>!!e.restorable(t)||(q(e.key),!1))},[t]);const[p,u]=e.useState(null),g=e.useRef({x:Number.NaN,y:Number.NaN});e.useEffect(()=>{const e=e=>{g.current={x:e.clientX,y:e.clientY}};return document.addEventListener("pointerdown",e,!0),document.addEventListener("pointermove",e,!0),()=>{document.removeEventListener("pointerdown",e,!0),document.removeEventListener("pointermove",e,!0)}},[]),e.useEffect(()=>{if(!p)return;const{x:e,y:t}=g.current,r=r=>{r instanceof PointerEvent&&r.clientX===e&&r.clientY===t||u(null)};return document.addEventListener("pointermove",r,!0),document.addEventListener("keydown",r,!0),()=>{document.removeEventListener("pointermove",r,!0),document.removeEventListener("keydown",r,!0)}},[p]);const f=e=>{const{layout:n,restore:o,restorable:a}=function(e,t){const r=e.sections.find(e=>e.items.some(e=>be(e)===t));if(!r)return{layout:e,restore:e=>e,restorable:()=>!1};const n=r.items.findIndex(e=>be(e)===t),o=r.items[n],i=e=>{const r=re(e);return!r.some(e=>be(e)===t)&&r.filter(e=>e.id===o.id).lengthe===r?{...e,items:e.items.filter(e=>e!==o)}:e)},restore:e=>i(e)?{...e,sections:e.sections.map(e=>e.id===r.id?{...e,items:[...e.items.slice(0,n),o,...e.items.slice(n)]}:e)}:e,restorable:i}}(t,be(e)),s=l.findIndex(t=>be(t)===be(e)),d=l[s+1]??l[s-1];u({focus:d&&be(d)}),r(n);const p=_("neutral",i("widgets.removed",{name:i(oe[e.id].label)}),{id:`removed:${be(e)}`,action:{label:i("ui.undo"),onAction:()=>r(e=>e&&o(e)),closeOnAction:!0}});c.current.push({key:p,restorable:a})};return n.jsxs(n.Fragment,{children:[t.sections.map(e=>n.jsx(sr,{label:i("widgets.order"),profile:e.id,items:e.items.map(e=>({...fe(e),item:e})),textValue:({item:e})=>i(oe[e.id].label),dragLabel:({item:e})=>i("widgets.drag",{name:i(oe[e.id].label)}),gapLabel:e=>i("dashboard.remaining",{space:e}),refusal:i("dashboard.noRoom"),rearm:p,resize:({item:e})=>{const o=he(e,de(e),i),a=(e,n)=>e&&{label:n,value:e.value,options:e.options,onChange:n=>{r(Te(t,Ae(e.set(n.value)))),d(`${e.label}: ${n.label}`)}};return n.jsx(vr,{width:a(o.width,i("dashboard.resizeWidth")),height:a(o.height,i("dashboard.resizeHeight"))})},onPlace:(n,o)=>{r(Dr(t,n,{section:e.id,...o})),d(i("widgets.reordered"))},tools:({item:e})=>n.jsxs(n.Fragment,{children:[n.jsx(J,{title:i(oe[e.id].label),placement:"bottom end",trigger:n.jsx(M,{quiet:!0,icon:!0,label:i("widgets.inspector"),children:n.jsx(G,{})}),children:()=>n.jsx("div",{className:"rp-module-inspector",children:n.jsx(hr,{active:e,items:l,surface:"dashboard",update:e=>r(Te(t,Ae(e))),move:n=>{r(function(e,t,r){const n=e.sections.findIndex(e=>e.items.some(e=>be(e)===t));if(n<0)return e;const o=e.sections[n].items,i=o.findIndex(e=>be(e)===t),a=o[i+r];if(a)return Dr(e,t,{section:e.sections[n].id,target:be(a),after:r>0});const s=e.sections[n+r];if(!s)return e;const l=r>0?s.items[0]:s.items.at(-1);return Dr(e,t,{section:s.id,...l?{target:be(l),after:r<0}:{}})}(t,be(e),n)),d(i("widgets.reordered"))},remove:()=>f(e)})})}),n.jsx(M,{quiet:!0,icon:!0,label:i("widgets.removeName",{name:i(oe[e.id].label)}),onPress:()=>f(e),children:n.jsx(Le,{})})]}),children:({item:e})=>o(e)},e.id)),n.jsx(C,{children:n.jsx("span",{role:"status",children:n.jsx("span",{children:a.text},a.serial)})})]})}function Or({draft:t,saved:r,setDraft:o,onClose:i}){const a=L(),[s,l]=e.useState(!1),d=e.useMemo(()=>JSON.stringify(t)!==JSON.stringify(r),[t,r]);return H(d,i),n.jsxs(X,{children:[n.jsx(Y,{title:a("widgets.gallery"),size:"wide",scrollBody:!0,trigger:n.jsx(M,{children:a("widgets.gallery")}),footer:e=>n.jsx(M,{onPress:e,children:a("ui.close")}),children:n.jsx("div",{className:"rp-widget-gallery-grid",children:n.jsx(gr,{items:re(t),add:(e,r)=>o(function(e,t,r){const n=Pr(re(e),t);if(!n)return e;const o=r?ce(n,r):n;return{...e,sections:e.sections.map(e=>"extensions"===e.id?{...e,items:[...e.items,o]}:e)}}(t,e,r)),surface:"dashboard"})})}),n.jsx(M,{onPress:()=>o(ne()),children:a("widgets.reset")}),n.jsx(M,{onPress:()=>d?l(!0):i(),children:a("ui.cancel")}),n.jsx(M,{accent:!0,onPress:()=>{xe(t),i()},children:a("ui.done")}),n.jsx(U,{title:a("config.discardTitle"),isOpen:s,onCancel:()=>l(!1),confirmLabel:a("config.discard"),onConfirm:i,children:n.jsx("p",{children:a("widgets.discardHelp")})})]})}function Sr({onClose:t,backend:r}){const o=L(),[i]=e.useState(ke),a=i.items,[s,l]=e.useState(a),[d,c]=e.useState(!1),[p]=e.useState(()=>i.docked?document.querySelector(".rp-side-dock")?.offsetWidth:void 0),u=i.size?.width??Ee,[g,f]=e.useState(u),[m,h]=e.useState(!1),y=g!==(d?Ee:u),[D,v]=e.useState(null),[b,w]=e.useState(!1),[x,T]=e.useState({text:"",serial:0}),k=e=>T(t=>({text:e,serial:t.serial+1})),E=d&&Pe(ke()),P=e.useMemo(()=>JSON.stringify(a)!==JSON.stringify(s),[a,s])||E||y;H(P,t);const K=()=>P?w(!0):t(),O=s.find(e=>be(e)===D);return n.jsxs(n.Fragment,{children:[n.jsxs(Y,{title:o("widgets.edit"),size:"wide",scrollBody:!0,isOpen:!0,onOpenChange:e=>{e||K()},footer:()=>n.jsxs(n.Fragment,{children:[n.jsx(M,{onPress:()=>{l(Se().items),c(!0),f(Ee),v(null)},children:o("widgets.reset")}),n.jsx(M,{onPress:K,children:o("ui.cancel")}),n.jsx(M,{accent:!0,onPress:()=>{Ce(e=>({...e,version:4,items:s,...d&&je,...y&&{size:{width:g,height:(d?void 0:e.size?.height)??Ie}}})),t()},children:o("settings.save")})]}),children:[n.jsx(Ke,{panelWidth:(d||m?void 0:p)??g,onPanelWidth:e=>{h(!0),f(e)},resizeLabel:o("widgets.resizePreview"),header:n.jsx(Oe,{backend:r,preview:!0}),galleryLabel:o("widgets.gallery"),canvasLabel:o("widgets.canvas"),inspectorLabel:o(O?oe[O.id].label:"widgets.inspector"),gallery:n.jsx(gr,{items:s,add:e=>{const t=Pr(s,e);t&&(l([...s,t]),v(be(t)),k(o("widgets.addedName",{name:o(oe[e].label)})))}}),canvas:n.jsx(sr,{label:o("widgets.order"),items:s.map(e=>({item:e,module:e.id,id:be(e),size:e.size})),textValue:({item:e})=>o(oe[e.id].label),selectionMode:"single",selectedKeys:D?new Set([D]):new Set,onSelectionChange:e=>{"all"!==e&&v(String([...e][0]))},dragLabel:({item:e})=>o("widgets.drag",{name:o(oe[e.id].label)}),onPlace:(e,{target:t,after:r})=>{t&&(l(n=>{const o=function(e,t,r,n){if(t.has(r))return e;const o=e.filter(e=>!t.has(e)),i=o.indexOf(r);return i<0?e:(o.splice(i+("after"===n?1:0),0,...e.filter(e=>t.has(e))),o)}(n.map(be),new Set([e]),t,r?"after":"before");return o.flatMap(e=>n.find(t=>be(t)===e)??[])}),k(o("widgets.reordered")))},children:({item:e})=>n.jsx(se,{item:e,preview:!0})}),inspector:n.jsx(hr,{active:O,items:s,sizes:O?De(O.id,ve(O,"panel"),"panel"):[],surface:"panel",update:e=>l(t=>t.map(Ae(e))),move:e=>{O&&l(function(e,t,r){const n=e.findIndex(e=>be(e)===t),o=n+r;if(n<0||o<0||o>=e.length)return e;const i=[...e];return i.splice(o,0,...i.splice(n,1)),i}(s,be(O),e)),k(o("widgets.reordered"))},remove:()=>{O&&(e=>{const t=be(e);l(e=>e.filter(e=>be(e)!==t)),v(null),k(o("widgets.removed",{name:o(oe[e.id].label)}))})(O)}})}),n.jsx(C,{children:n.jsx("span",{role:"status",children:n.jsx("span",{children:x.text},x.serial)})})]}),n.jsx(U,{title:o("config.discardTitle"),isOpen:b,onCancel:()=>w(!1),confirmLabel:o("config.discard"),onConfirm:t,children:n.jsx("p",{children:o("widgets.discardHelp")})})]})}export{Or as DashboardActions,Kr as DashboardEditor,Sr as WidgetEditor};
+import{r as e,$ as t,a as r,j as n}from"./vendor-react-64fcanlc.js";import{f0 as o,gG as i,eR as a,eN as s,d8 as l,gH as d,gI as c,gJ as p,eT as u,eO as g,eP as f,eQ as m,f1 as h,fc as y,gK as D,gL as v,fd as b,eY as w,gM as x,go as T,gc as k,bz as E,d5 as P,cZ as K,fq as O,I as S,aJ as C,cC as I,fj as j,aF as A,bC as R,B as M,g as B,u as L,R as F,cy as $,r as z,dp as N,bU as V,cS as H,dI as Y,ba as X,m as U,gN as q,P as J,gO as G,J as W}from"./index-C06va4Yw.js";import{b7 as _,b8 as Z,b9 as Q,ba as ee,bb as te,bc as re,bd as ne,be as oe,bf as ie,bg as ae,bh as se,bi as le,bj as de,bk as ce,bl as pe,bm as ue,bn as ge,bo as fe,bp as me,bq as he,br as ye,bs as De,bt as ve,bu as be,bv as we,bw as xe,bx as Te,by as ke,bz as Ee,bA as Pe,bB as Ke,bC as Oe,bD as Se,bE as Ce,bF as Ie,bG as je,bH as Ae}from"./activity-BoXvjA12.js";import{$ as Re,a as Me}from"./GridList-Dgo5IXUg.js";import{m as Be}from"./Select-hQ95uOjm.js";import{D as Le}from"./Delete-DqJAS65M.js";import{S as Fe,c as $e,$ as ze}from"./logs-BtAlqVqe.js";import{C as Ne}from"./AppearanceControls-CEVO9-aR.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./nodes-oXccX15o.js";import"./ItemText-D6SGBgOi.js";import"./useGridSelectionCheckbox-inhSeUkV.js";var Ve=function(e){return e[e.none=0]="none",e[e.cancel=0]="cancel",e[e.move=1]="move",e[e.copy=2]="copy",e[e.link=4]="link",e[e.all=7]="all",e}({});const He={...Ve,copyMove:3,copyLink:6,linkMove:5,all:7,uninitialized:7},Ye=qe(He);Ye[7]="all";const Xe={none:"cancel",link:"link",copy:"copy",move:"move"},Ue=qe(Xe);function qe(e){let t={};for(let r in e)t[e[r]]=r;return t}const Je=new Set(["text/plain","text/uri-list","text/html"]),Ge="application/vnd.react-aria.items+json",We="application/octet-stream",_e=new WeakMap,Ze=Symbol();function Qe(e){let t=new Set;for(let r of e)for(let e of Object.keys(r))t.add(e);return t}function et(e){return e||(e="virtual"),"pointer"===e&&(e="virtual"),"virtual"===e&&"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia("(pointer: coarse)").matches&&(e="touch"),e}function tt(){return et(o())}function rt(){return et(i())}class nt{constructor(e){this.types=new Set;let t=!1;for(let r of e.items)r.type!==Ge&&("file"===r.kind&&(t=!0),r.type?this.types.add(r.type):this.types.add(We));this.includesUnknownTypes=!t&&e.types.includes("Files")}has(e){if(Array.isArray(e))return e.some(e=>this.has(e));if(this.includesUnknownTypes||e===Ze&&this.types.has(We)||"*/*"===e)return!0;if("string"==typeof e){if(e.endsWith("/*")){for(let t of this.types)if(t.startsWith(e.slice(0,-2)))return!0;return!1}return this.types.has(e)}return!1}}function ot(e){if(!e)throw new Error("No file provided");return{kind:"file",type:e.type||We,name:e.name,getText:()=>{return"function"==typeof(t=e).text?t.text():new Promise((e,r)=>{let n=new FileReader;n.onload=()=>{e(n.result)},n.onerror=r,n.readAsText(t)});var t},getFile:()=>Promise.resolve(e)}}function it(e){return{kind:"directory",name:e.name,getEntries:()=>async function*(e){let t,r=e.createReader();do{t=await new Promise((e,t)=>{r.readEntries(e,t)});for(let e of t)if(e.isFile){let t=await at(e);yield ot(t)}else e.isDirectory&&(yield it(e))}while(t.length>0)}(e)}}function at(e){return new Promise((t,r)=>e.file(t,r))}let st,lt={draggingKeys:new Set};function dt(e){lt.dropCollectionRef=e}function ct(){lt={draggingKeys:new Set}}function pt(e){let{draggingCollectionRef:t,dropCollectionRef:r}=lt;return null!=t?.current&&t.current===(e?.current||r?.current)}function ut(e){st=e}let gt=Ve.none;function ft(e){gt=e}let mt=new Map,ht=new Map,yt=null,Dt=new Set;function vt(e){return mt.set(e.element,e),yt?.updateValidDropTargets(),()=>{mt.delete(e.element),yt?.updateValidDropTargets()}}function bt(){let[t,r]=e.useState(yt);return e.useEffect(()=>{let e=()=>r(yt);return Dt.add(e),()=>{Dt.delete(e)}},[]),t}function wt(){return!!yt}const xt=["pointerdown","pointermove","pointerenter","pointerleave","pointerover","pointerout","pointerup","mousedown","mousemove","mouseenter","mouseleave","mouseover","mouseout","mouseup","touchstart","touchmove","touchend","focusin","focusout"],Tt=["pointerup","mouseup","touchend"],kt={keyboard:"dragStartedKeyboard",touch:"dragStartedTouch",virtual:"dragStartedVirtual"};class Et{constructor(e,t){this.validDropTargets=[],this.currentDropTarget=null,this.currentDropItem=null,this.dropOperation=null,this.mutationObserver=null,this.restoreAriaHidden=null,this.isVirtualClick=!1,this.dragTarget=e,this.stringFormatter=t,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onFocus=this.onFocus.bind(this),this.onBlur=this.onBlur.bind(this),this.onClick=this.onClick.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.cancelEvent=this.cancelEvent.bind(this),this.initialFocused=!1}setup(){document.addEventListener("keydown",this.onKeyDown,!0),document.addEventListener("keyup",this.onKeyUp,!0),window.addEventListener("focus",this.onFocus,!0),window.addEventListener("blur",this.onBlur,!0),document.addEventListener("click",this.onClick,!0),document.addEventListener("pointerdown",this.onPointerDown,!0);for(let e of xt)document.addEventListener(e,this.cancelEvent,!0);this.mutationObserver=new MutationObserver(()=>this.updateValidDropTargets()),this.updateValidDropTargets(),a(this.stringFormatter.format(kt[rt()]))}teardown(){document.removeEventListener("keydown",this.onKeyDown,!0),document.removeEventListener("keyup",this.onKeyUp,!0),window.removeEventListener("focus",this.onFocus,!0),window.removeEventListener("blur",this.onBlur,!0),document.removeEventListener("click",this.onClick,!0),document.removeEventListener("pointerdown",this.onPointerDown,!0);for(let e of xt)document.removeEventListener(e,this.cancelEvent,!0);this.mutationObserver?.disconnect(),this.restoreAriaHidden?.()}onKeyDown(e){this.cancelEvent(e),"Escape"!==e.key?("Tab"!==e.key||e.metaKey||e.altKey||e.ctrlKey||(e.shiftKey?this.previous():this.next()),"function"==typeof this.currentDropTarget?.onKeyDown&&this.currentDropTarget.onKeyDown(e,this.dragTarget)):this.cancel()}onKeyUp(e){this.cancelEvent(e),"Enter"===e.key&&(e.altKey||s(this.getCurrentActivateButton(),l(e))?this.activate(this.currentDropTarget,this.currentDropItem):this.drop())}getCurrentActivateButton(){return this.currentDropItem?.activateButtonRef?.current??this.currentDropTarget?.activateButtonRef?.current??null}onFocus(e){let t=this.getCurrentActivateButton(),r=l(e);if(r===t)return void this.cancelEvent(e);if(r!==this.dragTarget.element&&this.cancelEvent(e),!(r instanceof HTMLElement)||r===this.dragTarget.element)return;let n=this.validDropTargets.find(e=>e.element===r)||this.validDropTargets.find(e=>s(e.element,r));if(!n)return void(this.currentDropTarget?this.currentDropTarget.element.focus():this.dragTarget.element.focus());let o=ht.get(r);n&&this.setCurrentDropTarget(n,o)}onBlur(e){let t=this.getCurrentActivateButton();t&&e.relatedTarget===t?this.cancelEvent(e):(l(e)!==this.dragTarget.element&&this.cancelEvent(e),e.relatedTarget&&e.relatedTarget instanceof HTMLElement||(this.currentDropTarget?this.currentDropTarget.element.focus():this.dragTarget.element.focus()))}onClick(e){if(this.cancelEvent(e),d(e)||this.isVirtualClick){let t=ht.values(),r=l(e),n=[...t].find(e=>e.element===r||s(e.activateButtonRef?.current,r)),o=this.validDropTargets.find(e=>s(e.element,r));if(s(n?.activateButtonRef?.current??o?.activateButtonRef?.current,r)&&o)return void this.activate(o,n);if(l(e)===this.dragTarget.element)return void this.cancel();o&&(this.setCurrentDropTarget(o,n),this.drop(n))}}onPointerDown(e){this.cancelEvent(e),this.isVirtualClick=c(e)}cancelEvent(e){let t=l(e);("focusin"!==e.type&&"focusout"!==e.type||t!==this.dragTarget?.element&&t!==this.getCurrentActivateButton())&&(Tt.includes(e.type)||e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation())}updateValidDropTargets(){if(!this.mutationObserver)return;if(this.mutationObserver.disconnect(),this.restoreAriaHidden&&this.restoreAriaHidden(),this.validDropTargets=function(e){let t=Qe(e.items);return[...mt.values()].filter(r=>!r.element.closest('[aria-hidden="true"], [inert]')&&("function"!=typeof r.getDropOperation||"cancel"!==r.getDropOperation(t,e.allowedDropOperations)))}(this.dragTarget),this.validDropTargets.length>0){let e=this.findNearestDropTarget();this.validDropTargets=[...this.validDropTargets.slice(e),...this.validDropTargets.slice(0,e)]}this.currentDropTarget&&!this.validDropTargets.includes(this.currentDropTarget)&&this.setCurrentDropTarget(this.validDropTargets[0]);let e=Qe(this.dragTarget.items),t=[...ht.values()].filter(t=>"function"!=typeof t.getDropOperation||"cancel"!==t.getDropOperation(e,this.dragTarget.allowedDropOperations)),r=this.validDropTargets.filter(e=>!t.some(t=>s(e.element,t.element)));this.restoreAriaHidden=p([this.dragTarget.element,...t.flatMap(e=>e.activateButtonRef?.current?[e.element,e.activateButtonRef?.current]:[e.element]),...r.flatMap(e=>e.activateButtonRef?.current?[e.element,e.activateButtonRef?.current]:[e.element])],{shouldUseInert:!0}),this.mutationObserver.observe(document.body,{subtree:!0,attributes:!0,attributeFilter:["aria-hidden","inert"]})}next(){if(!this.currentDropTarget)return void this.setCurrentDropTarget(this.validDropTargets[0]);let e=this.validDropTargets.indexOf(this.currentDropTarget);e<0?this.setCurrentDropTarget(this.validDropTargets[0]):e===this.validDropTargets.length-1?this.dragTarget.element.closest('[aria-hidden="true"], [inert]')?this.setCurrentDropTarget(this.validDropTargets[0]):(this.setCurrentDropTarget(null),this.dragTarget.element.focus()):this.setCurrentDropTarget(this.validDropTargets[e+1])}previous(){if(!this.currentDropTarget)return void this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]);let e=this.validDropTargets.indexOf(this.currentDropTarget);e<0?this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]):0===e?this.dragTarget.element.closest('[aria-hidden="true"], [inert]')?this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]):(this.setCurrentDropTarget(null),this.dragTarget.element.focus()):this.setCurrentDropTarget(this.validDropTargets[e-1])}findNearestDropTarget(){let e=this.dragTarget.element.getBoundingClientRect(),t=1/0,r=-1,n=-1;for(let o=0;o=0?n:r}setCurrentDropTarget(e,t){if(e!==this.currentDropTarget){if(this.currentDropTarget&&"function"==typeof this.currentDropTarget.onDropExit){let e=this.currentDropTarget.element.getBoundingClientRect();this.currentDropTarget.onDropExit({type:"dropexit",x:e.left+e.width/2,y:e.top+e.height/2})}if(this.currentDropTarget=e,e){if("function"==typeof e.onDropEnter){let t=e.element.getBoundingClientRect();e.onDropEnter({type:"dropenter",x:t.left+t.width/2,y:t.top+t.height/2},this.dragTarget)}t||e?.element.focus()}}if(null!=t&&t!==this.currentDropItem&&(this.currentDropTarget&&"function"==typeof this.currentDropTarget.onDropTargetEnter&&this.currentDropTarget.onDropTargetEnter(t.target),t.element.focus(),this.currentDropItem=t,!this.initialFocused)){let e=t?.element.getAttribute("aria-label");e&&a(e,"polite"),this.initialFocused=!0}}end(){if(this.teardown(),function(){yt=null;for(let e of Dt)e()}(),"function"==typeof this.dragTarget.onDragEnd){let e=(this.currentDropTarget&&"cancel"!==this.dropOperation?this.currentDropTarget:this.dragTarget).element.getBoundingClientRect();this.dragTarget.onDragEnd({type:"dragend",x:e.x+e.width/2,y:e.y+e.height/2,dropOperation:this.dropOperation||"cancel"})}this.currentDropTarget&&!this.currentDropTarget.preventFocusOnDrop&&u()?.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),this.setCurrentDropTarget(null)}cancel(){this.setCurrentDropTarget(null),this.end(),this.dragTarget.element.closest('[aria-hidden="true"], [inert]')||this.dragTarget.element.focus(),u()?.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),a(this.stringFormatter.format("dropCanceled"))}drop(e){if(this.currentDropTarget){if("function"==typeof e?.getDropOperation){let t=Qe(this.dragTarget.items);this.dropOperation=e.getDropOperation(t,this.dragTarget.allowedDropOperations)}else if("function"==typeof this.currentDropTarget.getDropOperation){let e=Qe(this.dragTarget.items);this.dropOperation=this.currentDropTarget.getDropOperation(e,this.dragTarget.allowedDropOperations)}else this.dropOperation=this.dragTarget.allowedDropOperations[0];if("function"==typeof this.currentDropTarget.onDrop){let t=this.dragTarget.items.map(e=>({kind:"text",types:new Set(Object.keys(e)),getText:t=>Promise.resolve(e[t])})),r=this.currentDropTarget.element.getBoundingClientRect();this.currentDropTarget.onDrop({type:"drop",x:r.left+r.width/2,y:r.top+r.height/2,items:t,dropOperation:this.dropOperation},e?.target??null)}this.end(),a(this.stringFormatter.format("dropComplete"))}else this.cancel()}activate(e,t){if(e&&"function"==typeof e.onDropActivate){let r=t?.target??null,n=e.element.getBoundingClientRect();e.onDropActivate({type:"dropactivate",x:n.left+n.width/2,y:n.top+n.height/2},r)}}}var Pt;Pt={"ar-AE":g,"bg-BG":g,"cs-CZ":g,"da-DK":g,"de-DE":g,"el-GR":g,"en-US":{dragItem:e=>`Drag ${e.itemText}`,dragSelectedItems:(e,t)=>`Drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}`,dragDescriptionKeyboard:"Press Enter to start dragging.",dragDescriptionKeyboardAlt:"Press Alt + Enter to start dragging.",dragDescriptionTouch:"Double tap to start dragging.",dragDescriptionVirtual:"Click to start dragging.",dragDescriptionLongPress:"Long press to start dragging.",dragSelectedKeyboard:(e,t)=>`Press Enter to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragSelectedKeyboardAlt:(e,t)=>`Press Alt + Enter to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragSelectedLongPress:(e,t)=>`Long press to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragStartedKeyboard:"Started dragging. Press Tab to navigate to a drop target, then press Enter to drop, or press Escape to cancel.",dragStartedTouch:"Started dragging. Navigate to a drop target, then double tap to drop.",dragStartedVirtual:"Started dragging. Navigate to a drop target, then click or press Enter to drop.",endDragKeyboard:"Dragging. Press Enter to cancel drag.",endDragTouch:"Dragging. Double tap to cancel drag.",endDragVirtual:"Dragging. Click to cancel drag.",dropDescriptionKeyboard:"Press Enter to drop. Press Escape to cancel drag.",dropDescriptionTouch:"Double tap to drop.",dropDescriptionVirtual:"Click to drop.",dropCanceled:"Drop canceled.",dropComplete:"Drop complete.",dropIndicator:"drop indicator",dropOnRoot:"Drop on",dropOnItem:e=>`Drop on ${e.itemText}`,insertBefore:e=>`Insert before ${e.itemText}`,insertBetween:e=>`Insert between ${e.beforeItemText} and ${e.afterItemText}`,insertAfter:e=>`Insert after ${e.itemText}`},"es-ES":g,"et-EE":g,"fi-FI":g,"fr-FR":g,"he-IL":g,"hr-HR":g,"hu-HU":g,"it-IT":g,"ja-JP":g,"ko-KR":g,"lt-LT":g,"lv-LV":g,"nb-NO":g,"nl-NL":g,"pl-PL":g,"pt-BR":g,"pt-PT":g,"ro-RO":g,"ru-RU":g,"sk-SK":g,"sl-SI":g,"sr-SP":g,"sv-SE":g,"tr-TR":g,"uk-UA":g,"zh-CN":{dragDescriptionKeyboard:"按 Enter 开始拖动。",dragDescriptionKeyboardAlt:"按 Alt + Enter 开始拖动。",dragDescriptionLongPress:"长按以开始拖动。",dragDescriptionTouch:"双击开始拖动。",dragDescriptionVirtual:"单击开始拖动。",dragItem:e=>`拖动 ${e.itemText}`,dragSelectedItems:(e,t)=>`拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 选中项目`,other:()=>`${t.number(e.count)} 选中项目`})}`,dragSelectedKeyboard:(e,t)=>`按 Enter 以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragSelectedKeyboardAlt:(e,t)=>`按 Alt + Enter 以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragSelectedLongPress:(e,t)=>`长按以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragStartedKeyboard:"已开始拖动。按 Tab 导航到放置目标,然后按 Enter 放置或按 Escape 取消。",dragStartedTouch:"已开始拖动。导航到放置目标,然后双击放置。",dragStartedVirtual:"已开始拖动。导航到放置目标,然后单击或按 Enter 放置。",dropCanceled:"放置已取消。",dropComplete:"放置已完成。",dropDescriptionKeyboard:"按 Enter 放置。按 Escape 取消拖动。",dropDescriptionTouch:"双击放置。",dropDescriptionVirtual:"单击放置。",dropIndicator:"放置标记",dropOnItem:e=>`放置于 ${e.itemText}`,dropOnRoot:"放置于",endDragKeyboard:"正在拖动。按 Enter 取消拖动。",endDragTouch:"正在拖动。双击取消拖动。",endDragVirtual:"正在拖动。单击取消拖动。",insertAfter:e=>`插入到 ${e.itemText} 之后`,insertBefore:e=>`插入到 ${e.itemText} 之前`,insertBetween:e=>`插入到 ${e.beforeItemText} 和 ${e.afterItemText} 之间`},"zh-TW":{dragDescriptionKeyboard:"按 Enter 鍵以開始拖曳。",dragDescriptionKeyboardAlt:"按 Alt+Enter 鍵以開始拖曳。",dragDescriptionLongPress:"長按以開始拖曳。",dragDescriptionTouch:"輕點兩下以開始拖曳。",dragDescriptionVirtual:"按一下滑鼠以開始拖曳。",dragItem:e=>`拖曳「${e.itemText}」`,dragSelectedItems:(e,t)=>`拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}`,dragSelectedKeyboard:(e,t)=>`按 Enter 鍵以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragSelectedKeyboardAlt:(e,t)=>`按 Alt+Enter 鍵以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragSelectedLongPress:(e,t)=>`長按以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragStartedKeyboard:"已開始拖曳。按 Tab 鍵以瀏覽至放置目標,然後按 Enter 鍵以放置,或按 Escape 鍵以取消。",dragStartedTouch:"已開始拖曳。瀏覽至放置目標,然後輕點兩下以放置。",dragStartedVirtual:"已開始拖曳。瀏覽至放置目標,然後按一下滑鼠或按 Enter 鍵以放置。",dropCanceled:"放置已取消。",dropComplete:"放置已完成。",dropDescriptionKeyboard:"按 Enter 鍵以放置。按 Escape 鍵以取消拖曳。",dropDescriptionTouch:"輕點兩下以放置。",dropDescriptionVirtual:"按一下滑鼠以放置。",dropIndicator:"放置指示器",dropOnItem:e=>`放置在「${e.itemText}」上`,dropOnRoot:"放置在",endDragKeyboard:"拖曳中。按 Enter 鍵以取消拖曳。",endDragTouch:"拖曳中。輕點兩下以取消拖曳。",endDragVirtual:"拖曳中。按一下滑鼠以取消拖曳。",insertAfter:e=>`插入至「${e.itemText}」之後`,insertBefore:e=>`插入至「${e.itemText}」之前`,insertBetween:e=>`插入至「${e.beforeItemText}」和「${e.afterItemText}」之間`}};const Kt={keyboard:"dropDescriptionKeyboard",touch:"dropDescriptionTouch",virtual:"dropDescriptionVirtual"};function Ot(){let e=f((t=Pt)&&t.__esModule?t.default:t,"@react-aria/dnd");var t;let r=tt(),n=bt();return{dropProps:{...m(n?e.format(Kt[r]):""),onClick:()=>{}}}}function St(t){let{hasDropButton:r,isDisabled:n}=t,[o,i]=e.useState(!1),a=e.useRef({x:0,y:0,dragOverElements:new Set,dropEffect:"none",allowedOperations:Ve.all,dropActivateTimer:void 0}).current,d=e=>{if(i(!0),"function"==typeof t.onDropEnter){let r=e.currentTarget.getBoundingClientRect();t.onDropEnter({type:"dropenter",x:e.clientX-r.x,y:e.clientY-r.y})}},c=e=>{if(i(!1),"function"==typeof t.onDropExit){let r=e.currentTarget.getBoundingClientRect();t.onDropExit({type:"dropexit",x:e.clientX-r.x,y:e.clientY-r.y})}},p=h(e=>{"function"==typeof t.onDropEnter&&t.onDropEnter(e)}),u=h(e=>{"function"==typeof t.onDropExit&&t.onDropExit(e)}),g=h(e=>{"function"==typeof t.onDropActivate&&t.onDropActivate(e)}),f=h(e=>{"function"==typeof t.onDrop&&t.onDrop(e)}),m=h((e,r)=>t.getDropOperation?t.getDropOperation(e,r):r[0]),{ref:D}=t;y(()=>{if(!n&&D.current)return vt({element:D.current,getDropOperation:m,onDropEnter(e){i(!0),p(e)},onDropExit(e){i(!1),u(e)},onDrop:f,onDropActivate:g})},[n,D]);let{dropProps:v}=Ot();return n?{dropProps:{},dropButtonProps:{isDisabled:!0},isDropTarget:!1}:{dropProps:{...!r&&v,onDragEnter:e=>{if(e.preventDefault(),e.stopPropagation(),a.dragOverElements.add(l(e)),a.dragOverElements.size>1)return;let r=Ct(e),n=It(r),o=n[0];if("function"==typeof t.getDropOperation){let i=new nt(e.dataTransfer);o=jt(r,t.getDropOperation(i,n))}if("function"==typeof t.getDropOperationForPoint){let i=new nt(e.dataTransfer),a=e.currentTarget.getBoundingClientRect();o=jt(r,t.getDropOperationForPoint(i,n,e.clientX-a.x,e.clientY-a.y))}a.x=e.clientX,a.y=e.clientY,a.allowedOperations=r,a.dropEffect=Ue[o]||"none",e.dataTransfer.dropEffect=a.dropEffect,"cancel"!==o&&d(e)},onDragOver:e=>{e.preventDefault(),e.stopPropagation();let r=Ct(e);if(e.clientX===a.x&&e.clientY===a.y&&r===a.allowedOperations)return void(e.dataTransfer.dropEffect=a.dropEffect);a.x=e.clientX,a.y=e.clientY;let n=a.dropEffect;if(r!==a.allowedOperations){let n=It(r),o=n[0];if("function"==typeof t.getDropOperation){let i=new nt(e.dataTransfer);o=jt(r,t.getDropOperation(i,n))}a.dropEffect=Ue[o]||"none"}if("function"==typeof t.getDropOperationForPoint){let n=new nt(e.dataTransfer),o=e.currentTarget.getBoundingClientRect(),i=jt(r,t.getDropOperationForPoint(n,It(r),a.x-o.x,a.y-o.y));a.dropEffect=Ue[i]||"none"}if(a.allowedOperations=r,e.dataTransfer.dropEffect=a.dropEffect,"none"===a.dropEffect&&"none"!==n?c(e):"none"!==a.dropEffect&&"none"===n&&d(e),"function"==typeof t.onDropMove&&"none"!==a.dropEffect){let r=e.currentTarget.getBoundingClientRect();t.onDropMove({type:"dropmove",x:a.x-r.x,y:a.y-r.y})}if(clearTimeout(a.dropActivateTimer),t.onDropActivate&&"function"==typeof t.onDropActivate&&"none"!==a.dropEffect){let r=t.onDropActivate,n=e.currentTarget.getBoundingClientRect();a.dropActivateTimer=setTimeout(()=>{r({type:"dropactivate",x:a.x-n.x,y:a.y-n.y})},800)}},onDragLeave:e=>{e.preventDefault(),e.stopPropagation();let t=l(e);if(a.dragOverElements.delete(t),t===e.currentTarget)for(let r of a.dragOverElements)s(e.currentTarget,r)||a.dragOverElements.delete(r);a.dragOverElements.size>0||("none"!==a.dropEffect&&c(e),clearTimeout(a.dropActivateTimer))},onDrop:e=>{if(e.preventDefault(),e.stopPropagation(),ut(a.dropEffect),"function"==typeof t.onDrop){let r=Xe[a.dropEffect],n=function(e){let t=[];if(!e)return t;let r=!1;if(e.types.includes(Ge))try{let n=e.getData(Ge),o=JSON.parse(n);for(let e of o)t.push({kind:"text",types:new Set(Object.keys(e)),getText:t=>Promise.resolve(e[t])});r=!0}catch{}if(!r){let r=new Map;for(let n of e.items)if("string"===n.kind)r.set(n.type||We,e.getData(n.type));else if("file"===n.kind)if("function"==typeof n.webkitGetAsEntry){let e=n.webkitGetAsEntry();if(!e)continue;e.isFile?t.push(ot(n.getAsFile())):e.isDirectory&&t.push(it(e))}else t.push(ot(n.getAsFile()));r.size>0&&t.push({kind:"text",types:new Set(r.keys()),getText:e=>Promise.resolve(r.get(e))})}return t}(e.dataTransfer),o=e.currentTarget.getBoundingClientRect(),i={type:"drop",x:e.clientX-o.x,y:e.clientY-o.y,items:n,dropOperation:r};t.onDrop(i)}let r={...lt};a.dragOverElements.clear(),c(e),clearTimeout(a.dropActivateTimer),null==r.draggingCollectionRef?ut(void 0):function(e){lt=e}(r)}},dropButtonProps:{...r&&v},isDropTarget:o}}function Ct(e){let t=He[e.dataTransfer.effectAllowed];gt&&(t&=gt);let r=Ve.none;return D()?(e.altKey&&(r|=Ve.copy),e.ctrlKey&&!v()&&(r|=Ve.link),e.metaKey&&(r|=Ve.move)):(e.altKey&&(r|=Ve.link),e.shiftKey&&(r|=Ve.move),e.ctrlKey&&(r|=Ve.copy)),r?t&r:t}function It(e){let t=[];return e&Ve.move&&t.push("move"),e&Ve.copy&&t.push("copy"),e&Ve.link&&t.push("link"),t}function jt(e,t){return e&Ve[t]?t:"cancel"}function At(e,t,r,n=!1,o=null){if(!r)return{type:"root"};if("root"===r.type){let t=e.getFirstKey?.()??null;return null!=t?{type:"item",key:t,dropPosition:"before"}:null}if("item"===r.type){let n=null;n=o?"right"===o?e.getKeyRightOf?.(r.key,{includeDisabled:!0}):e.getKeyLeftOf?.(r.key,{includeDisabled:!0}):e.getKeyBelow?.(r.key,{includeDisabled:!0});let i=Bt(t,r.key,e=>t.getKeyAfter(e));if(null!=n&&n!==i)return{type:"item",key:n,dropPosition:r.dropPosition};switch(r.dropPosition){case"before":return{type:"item",key:r.key,dropPosition:"on"};case"on":{let e=t.getItem(r.key),o=null!=n?t.getItem(n):null;return e&&o&&o.level>=e.level?{type:"item",key:o.key,dropPosition:"before"}:{type:"item",key:r.key,dropPosition:"after"}}case"after":{let e=t.getItem(r.key),n=null!=e?.nextKey?t.getItem(e.nextKey):null;for(;null!=n&&"item"!==n.type;)n=null!=n.nextKey?t.getItem(n.nextKey):null;if(e&&null==n&&null!=e.parentKey){let r=t.getItem(e.parentKey);const n=null!=r?.nextKey?t.getItem(r.nextKey):null;if("item"===n?.type)return{type:"item",key:n.key,dropPosition:"before"};if("item"===r?.type)return{type:"item",key:r.key,dropPosition:"after"}}if(n)return{type:"item",key:n.key,dropPosition:"on"}}}}return n?{type:"root"}:null}function Rt(e,t,r,n=!1,o=null){if(!r||n&&"root"===r.type){let r=null,n=e.getLastKey?.();for(;null!=n;){let e=t.getItem(n);if("item"!==e?.type)break;r=n,n=e?.parentKey}return null!=r?{type:"item",key:r,dropPosition:"after"}:null}if("item"===r.type){let n=null;n=o?"left"===o?e.getKeyLeftOf?.(r.key,{includeDisabled:!0}):e.getKeyRightOf?.(r.key,{includeDisabled:!0}):e.getKeyAbove?.(r.key,{includeDisabled:!0});let i=Bt(t,r.key,e=>t.getKeyBefore(e));if(null!=n&&n!==i)return{type:"item",key:n,dropPosition:r.dropPosition};switch(r.dropPosition){case"before":{let e=t.getItem(r.key);if(e&&null!=e.prevKey){let r=Mt(t,e.prevKey);if(r)return r}return null!=n?{type:"item",key:n,dropPosition:"on"}:{type:"root"}}case"on":return{type:"item",key:r.key,dropPosition:"before"};case"after":{let e=Mt(t,r.key);return e||{type:"item",key:r.key,dropPosition:"on"}}}}return"root"!==r.type?{type:"root"}:null}function Mt(e,t){let r=e.getItem(t),n=Bt(e,t,t=>e.getKeyAfter(t)),o=null!=n?e.getItem(n):null;if(r&&o&&o.level>r.level){let t=null;if("lastChildKey"in r)for(t=null!=r.lastChildKey?e.getItem(r.lastChildKey):null;t&&"item"!==t.type&&null!=t.prevKey;)t=e.getItem(t.prevKey);else t=Array.from(r.childNodes).findLast(e=>"item"===e.type)||null;if(t)return{type:"item",key:t.key,dropPosition:"after"}}return null}function Bt(e,t,r){let n=r(t),o=null!=n?e.getItem(n):null;for(;o&&"item"!==o.type;)n=r(o.key),o=null!=n?e.getItem(n):null;return n}function Lt(t,r,n){let o=e.useRef({props:t,state:r,nextTarget:null,dropOperation:null}).current;o.props=t,o.state=r;let i=e.useCallback(async e=>{let{onInsert:t,onRootDrop:r,onItemDrop:i,onReorder:a,onMove:s,acceptedDragTypes:l="all",shouldAcceptItemDrop:d}=o.props,{draggingKeys:c}=lt,p=pt(n),{target:u,dropOperation:g,items:f}=e,m=f;("all"!==l||d)&&(m=f.filter(e=>{let t;return t="directory"===e.kind?new Set([Ze]):"file"===e.kind?new Set([e.type]):e.types,!("all"!==l&&!l.some(e=>t.has(e)))&&("item"!==u.type||"on"!==u.dropPosition||!d||d(u,t))})),m.length>0&&("root"===u.type&&r&&await r({items:m,dropOperation:g}),"item"===u.type&&("on"===u.dropPosition&&i&&await i({items:m,dropOperation:g,isInternal:p,target:u}),s&&p&&await s({keys:c,dropOperation:g,target:u}),"on"!==u.dropPosition&&(!p&&t&&await t({items:m,dropOperation:g,target:u}),p&&a&&await a({keys:c,dropOperation:g,target:u}))))},[o,n]),a=function(t){let r=e.useRef(null),n=e.useRef(!0),o=e.useRef(!0);e.useEffect(()=>{if(t.current){r.current=b(t.current)?t.current:w(t.current);let e=window.getComputedStyle(r.current);n.current=/(auto|scroll)/.test(e.overflowX),o.current=/(auto|scroll)/.test(e.overflowY)}},[t]);let i=e.useRef({timer:void 0,dx:0,dy:0}).current;e.useEffect(()=>()=>{i.timer&&(cancelAnimationFrame(i.timer),i.timer=void 0)},[i]);let a=e.useCallback(()=>{n.current&&r.current&&(r.current.scrollLeft+=i.dx),o.current&&r.current&&(r.current.scrollTop+=i.dy),i.timer&&(i.timer=requestAnimationFrame(a))},[r,i]);return{move(e,t){if(!x()||T()||!r.current)return;let n=r.current.getBoundingClientRect(),o=n.height-20,s=n.width-20;e<20||e>s||t<20||t>o?(e<20?i.dx=e-20:e>s&&(i.dx=e-s),t<20?i.dy=t-20:t>o&&(i.dy=t-o),i.timer||(i.timer=requestAnimationFrame(a))):this.stop()},stop(){i.timer&&(cancelAnimationFrame(i.timer),i.timer=void 0)}}}(n),{dropProps:s}=St({ref:n,onDropEnter(){null!=o.nextTarget&&r.setTarget(o.nextTarget)},onDropMove(e){null!=o.nextTarget&&r.setTarget(o.nextTarget),a.move(e.x,e.y)},getDropOperationForPoint(e,i,a,s){let{draggingKeys:l,dropCollectionRef:d}=lt,c=pt(n),p=t.dropTargetDelegate.getDropTargetFromPoint(a,s,t=>"cancel"!==r.getDropOperation({target:t,types:e,allowedOperations:i,isInternal:c,draggingKeys:l}));if(!p)return o.dropOperation="cancel",o.nextTarget=null,"cancel";if(o.dropOperation=r.getDropOperation({target:p,types:e,allowedOperations:i,isInternal:c,draggingKeys:l}),"cancel"===o.dropOperation){let t={type:"root"},n=r.getDropOperation({target:t,types:e,allowedOperations:i,isInternal:c,draggingKeys:l});"cancel"!==n&&(p=t,o.dropOperation=n)}return p&&"cancel"!==o.dropOperation&&n?.current!==d?.current&&dt(n),o.nextTarget="cancel"===o.dropOperation?null:p,o.dropOperation},onDropExit(){dt(void 0),r.setTarget(null),a.stop()},onDropActivate(e){"item"===r.target?.type&&"function"==typeof t.onDropActivate&&t.onDropActivate({type:"dropactivate",x:e.x,y:e.y,target:r.target})},onDrop(e){dt(n),r.target&&c(e,r.target);let{draggingCollectionRef:t}=lt;null==t&&ct()}}),l=e.useRef(null),d=e.useCallback(()=>{let{state:e}=o;if(l.current){let{target:t,collection:r,selectedKeys:n,focusedKey:o,isInternal:i,draggingKeys:a}=l.current;if(e.collection.size>r.size&&e.selectionManager.isSelectionEqual(n)){let t=new Set,n=e.collection.getFirstKey();for(;null!=n;){let o=e.collection.getItem(n);"item"!==o?.type||r.getItem(o.key)||t.add(o.key),n=o?.hasChildNodes&&"item"===e.collection.getItem(o.lastChildKey)?.type?o.firstChildKey:e.collection.getKeyAfter(n)}if(e.selectionManager.setSelectedKeys(t),e.selectionManager.focusedKey===o){let r=t.keys().next().value;if(null!=r){let t=e.collection.getItem(r),n=l.current.target,o=!!e.collection.expandedKeys&&e.collection.expandedKeys.has(t?.parentKey);t&&("cell"===t?.type||"item"===n.type&&"on"===n.dropPosition&&!o)&&(r=t.parentKey),null!=r&&e.selectionManager.setFocusedKey(r),"none"===e.selectionManager.selectionMode&&k("keyboard")}}}else null!=o&&e.selectionManager.focusedKey===o&&i&&"item"===t.type&&"on"!==t.dropPosition&&a.has(e.collection.getItem(o)?.parentKey)?(e.selectionManager.setFocusedKey(e.collection.getItem(o)?.parentKey??null),k("keyboard")):e.selectionManager.focusedKey===o&&"item"===t.type&&"on"===t.dropPosition&&null!=e.collection.getItem(t.key)?(e.selectionManager.setFocusedKey(t.key),k("keyboard")):null==e.selectionManager.focusedKey||e.selectionManager.isSelected(e.selectionManager.focusedKey)||k("keyboard");e.selectionManager.setFocused(!0)}},[o]),c=e.useCallback((e,t)=>{let{state:r}=o;l.current={timeout:void 0,focusedKey:r.selectionManager.focusedKey,collection:r.collection,selectedKeys:r.selectionManager.selectedKeys,draggingKeys:lt.draggingKeys,isInternal:pt(n),target:t},(o.props.onDrop||i)({type:"drop",x:e.x,y:e.y,target:t,items:e.items,dropOperation:e.dropOperation}),l.current.timeout=setTimeout(()=>{d(),l.current=null},50)},[o,i,n,d]);e.useEffect(()=>()=>{l.current&&clearTimeout(l.current.timeout)},[]),y(()=>{l.current&&r.collection!==l.current.collection&&d()});let{direction:p}=E();e.useEffect(()=>{if(!n.current)return;let e=(e,t=!0,r="down")=>function(e,t,r,n,o=!1,i=!1){switch(n){case"left":return o?At(e,t,r,i,"left"):Rt(e,t,r,i,"left");case"right":return o?Rt(e,t,r,i,"right"):At(e,t,r,i,"right");case"up":return Rt(e,t,r,i);case"down":return At(e,t,r,i)}}(o.props.keyboardDelegate,o.state.collection,e,r,"rtl"===p,t),t=(t,r=!0)=>e(t,r,"up"),r=(e,t,r,i,a=!0)=>{let s,l=0,{draggingKeys:d}=lt,c=pt(n);do{let n=i(e,a);if(!n)return null;e=n,s=o.state.getDropOperation({target:n,types:t,allowedOperations:r,isInternal:c,draggingKeys:d}),"root"===e.type&&l++}while("cancel"===s&&!o.state.isDropTarget(e)&&l<2);return"cancel"===s?null:e};return vt({element:n.current,preventFocusOnDrop:!0,getDropOperation(t,i){if(o.state.target){let{draggingKeys:e}=lt,r=pt(n);return o.state.getDropOperation({target:o.state.target,types:t,allowedOperations:i,isInternal:r,draggingKeys:e})}return r(null,t,i,e)?"move":"cancel"},onDropEnter(i,a){let s=Qe(a.items),l=o.state.selectionManager,d=null;dt(n);let c=l.focusedKey,p="after",u=null!=c?o.state.collection.getItem(c):null;if("cell"===u?.type&&(c=u.parentKey),null!=c&&l.isSelected(c)&&(l.selectedKeys.size>1&&l.firstSelectedKey===c?p="before":c=l.lastSelectedKey),null!=c){d={type:"item",key:c,dropPosition:p};let{draggingKeys:i}=lt,l=pt(n);"cancel"===o.state.getDropOperation({target:d,types:s,allowedOperations:a.allowedDropOperations,isInternal:l,draggingKeys:i})&&(d=r(d,s,a.allowedDropOperations,e,!1)??r(d,s,a.allowedDropOperations,t,!1))}d||(d=r(null,s,a.allowedDropOperations,e)),o.state.setTarget(d)},onDropExit(){dt(void 0),o.state.setTarget(null)},onDropTargetEnter(e){o.state.setTarget(e)},onDropActivate(e,t){"item"===t?.type&&"on"===t?.dropPosition&&"function"==typeof o.props.onDropActivate&&o.props.onDropActivate({type:"dropactivate",x:e.x,y:e.y,target:t})},onDrop(e,t){dt(n),o.state.target&&c(e,t||o.state.target)},onKeyDown(i,a){let{keyboardDelegate:s}=o.props,l=Qe(a.items);switch(i.key){case"ArrowDown":if(s.getKeyBelow){let t=r(o.state.target,l,a.allowedDropOperations,(t,r)=>e(t,r,"down"));o.state.setTarget(t)}break;case"ArrowUp":if(s.getKeyAbove){let t=r(o.state.target,l,a.allowedDropOperations,(t,r)=>e(t,r,"up"));o.state.setTarget(t)}break;case"ArrowLeft":if(s.getKeyLeftOf){let t=r(o.state.target,l,a.allowedDropOperations,(t,r)=>e(t,r,"left"));o.state.setTarget(t)}break;case"ArrowRight":if(s.getKeyRightOf){let t=r(o.state.target,l,a.allowedDropOperations,(t,r)=>e(t,r,"right"));o.state.setTarget(t)}break;case"Home":if(s.getFirstKey){let t=r(null,l,a.allowedDropOperations,e);o.state.setTarget(t)}break;case"End":if(s.getLastKey){let e=r(null,l,a.allowedDropOperations,t);o.state.setTarget(e)}break;case"PageDown":if(s.getKeyPageBelow){let i=o.state.target;if(i){let d=s.getFirstKey?.();"item"===i.type&&(d=i.key);let c=null;null!=d&&(c=s.getKeyPageBelow(d));let p="item"===i.type?i.dropPosition:"after";if((null==c||"item"===i.type&&i.key===s.getLastKey?.())&&(c=s.getLastKey?.()??null,p="after"),null==c)break;i={type:"item",key:c,dropPosition:p};let{draggingCollectionRef:u,draggingKeys:g}=lt,f=u?.current===n?.current;"cancel"===o.state.getDropOperation({target:i,types:l,allowedOperations:a.allowedDropOperations,isInternal:f,draggingKeys:g})&&(i=r(i,l,a.allowedDropOperations,e,!1)??r(i,l,a.allowedDropOperations,t,!1))}else i=r(null,l,a.allowedDropOperations,e);o.state.setTarget(i??o.state.target)}break;case"PageUp":{if(!s.getKeyPageAbove)break;let i=o.state.target;if(i){if("item"===i.type){if(i.key===s.getFirstKey?.())i={type:"root"};else{let e=s.getKeyPageAbove(i.key),t=i.dropPosition;if(null==e&&(e=s.getFirstKey?.(),t="before"),null==e)break;i={type:"item",key:e,dropPosition:t}}let{draggingKeys:d}=lt,c=pt(n);"cancel"===o.state.getDropOperation({target:i,types:l,allowedOperations:a.allowedDropOperations,isInternal:c,draggingKeys:d})&&(i=r(i,l,a.allowedDropOperations,t,!1)??r(i,l,a.allowedDropOperations,e,!1))}}else i=r(null,l,a.allowedDropOperations,t);o.state.setTarget(i??o.state.target);break}}o.props.onKeyDown?.(i)}})},[o,n,c,p]);let u=P();return _e.set(r,{id:u,ref:n}),{collectionProps:K(s,{id:u,"aria-describedby":null})}}function Ft(t,r,n){let{dropProps:o}=Ot(),i=function(e){let{ref:t}=_e.get(e)||{};if(!t)throw new Error("Droppable item outside a droppable collection");return t}(r);e.useEffect(()=>{if(n.current)return e={element:n.current,target:t.target,getDropOperation(e,n){let{draggingKeys:o}=lt,a=pt(i);return r.getDropOperation({target:t.target,types:e,allowedOperations:n,isInternal:a,draggingKeys:o})},activateButtonRef:t.activateButtonRef},ht.set(e.element,e),()=>{ht.delete(e.element)};var e},[n,t.target,r,i,t.activateButtonRef]);let a=bt(),{draggingKeys:s}=lt,l=pt(i),d=a&&"cancel"!==r.getDropOperation({target:t.target,types:Qe(a.dragTarget.items),allowedOperations:a.dragTarget.allowedDropOperations,isInternal:l,draggingKeys:s}),c=r.isDropTarget(t.target);return e.useEffect(()=>{a&&c&&n.current&&n.current.focus()},[c,a,n]),{dropProps:{...o,"aria-hidden":!a||d?void 0:"true"},isDropTarget:c}}function $t(e,t,r){let{target:n}=e,{collection:o}=t,i=f((a=Pt)&&a.__esModule?a.default:a,"@react-aria/dnd");var a;let s,l=bt(),{dropProps:d}=Ft(e,t,r),c=P(),p=e=>null==e?"":o.getTextValue?.(e)??o.getItem(e)?.textValue??"",u="";if("root"===n.type)u=i.format("dropOnRoot"),s=`${c} ${function(e){let{id:t}=_e.get(e)||{};if(!t)throw new Error("Droppable item outside a droppable collection");return t}(t)}`;else if("on"===n.dropPosition)u=i.format("dropOnItem",{itemText:p(n.key)});else{let e,t;if("before"===n.dropPosition){let t=o.getItem(n.key)?.prevKey,r=null!=t?o.getItem(t):null;e="item"===r?.type?r.key:null}else e=n.key;if("after"===n.dropPosition){let e=o.getItem(n.key)?.nextKey,r=null!=e?o.getItem(e):null;t="item"===r?.type?r.key:null}else t=n.key;null!=e&&null!=t?u=i.format("insertBetween",{beforeItemText:p(e),afterItemText:p(t)}):null!=e?u=i.format("insertAfter",{itemText:p(e)}):null!=t&&(u=i.format("insertBefore",{itemText:p(t)}))}let g=t.isDropTarget(n),m=l?d["aria-hidden"]:"true";return{dropIndicatorProps:{...d,id:c,"aria-roledescription":i.format("dropIndicator"),"aria-label":u,"aria-labelledby":s,"aria-hidden":m,tabIndex:-1},isDropTarget:g,isHidden:!g&&!!m}}const zt={keyboard:{start:"dragDescriptionKeyboard",end:"endDragKeyboard"},touch:{start:"dragDescriptionTouch",end:"endDragTouch"},virtual:{start:"dragDescriptionVirtual",end:"endDragVirtual"}};function Nt(t){let{hasDragButton:r,isDisabled:n}=t,o=f((i=Pt)&&i.__esModule?i.default:i,"@react-aria/dnd");var i;let a=e.useRef({options:t,x:0,y:0}).current;a.options=t;let s=e.useRef(null),[p,u]=e.useState(!1),g=e=>{s.current=e,u(!!e)},{addGlobalListener:h,removeAllGlobalListeners:y}=O(),D=e.useRef(null);e.useEffect(()=>()=>{if(s.current&&(!s.current.isConnected||parseInt(e.version,10)<17)){if("function"==typeof a.options.onDragEnd){let e={type:"dragend",x:0,y:0,dropOperation:Xe[st||"none"]};a.options.onDragEnd(e)}g(null),ft(Ve.none),ut(void 0)}},[a]);let v=e=>{if("function"==typeof a.options.onDragStart){let t=e.getBoundingClientRect();a.options.onDragStart({type:"dragstart",x:t.x+t.width/2,y:t.y+t.height/2})}!function(e,t){if(yt)throw new Error("Cannot begin dragging while already dragging");yt=new Et(e,t),requestAnimationFrame(()=>{yt&&(yt.setup(),"keyboard"===rt()&&yt.next())});for(let r of Dt)r()}({element:e,items:a.options.getItems(),allowedDropOperations:"function"==typeof a.options.getAllowedDropOperations?a.options.getAllowedDropOperations():["move","copy","link"],onDragEnd(e){g(null),"function"==typeof a.options.onDragEnd&&a.options.onDragEnd(e)}},o),g(e)},b=tt(),w=p?zt[b].end:zt[b].start,k=m(o.format(w)),E={};return r||(E={...k,onPointerDown(e){if(D.current=c(e.nativeEvent)?"virtual":e.pointerType,e.width<1&&e.height<1&&T()&&x())D.current="virtual";else{let t=e.currentTarget.getBoundingClientRect(),r=e.clientX-t.x,n=e.clientY-t.y,o=t.width/2,i=t.height/2;Math.abs(r-o)<=.5&&Math.abs(n-i)<=.5?D.current="virtual":D.current=e.pointerType}},onKeyDownCapture(e){l(e)===e.currentTarget&&"Enter"===e.key&&(e.preventDefault(),e.stopPropagation())},onKeyUpCapture(e){l(e)===e.currentTarget&&"Enter"===e.key&&(e.preventDefault(),e.stopPropagation(),v(l(e)))},onClick(e){(d(e.nativeEvent)||"virtual"===D.current)&&(e.preventDefault(),e.stopPropagation(),v(l(e)))}}),n?{dragProps:{draggable:"false"},dragButtonProps:{},isDragging:!1}:{dragProps:{...E,draggable:"true",onDragStart:e=>{if(e.defaultPrevented)return;if(e.stopPropagation(),"virtual"===D.current)return e.preventDefault(),v(l(e)),void(D.current=null);"function"==typeof t.onDragStart&&t.onDragStart({type:"dragstart",x:e.clientX,y:e.clientY});let r=t.getItems();e.dataTransfer.clearData?.(),function(e,t){let r=new Map,n=!1,o=[];for(let i of t){let e=Object.keys(i);e.length>1&&(n=!0);let t={};for(let o of e){let e=r.get(o);e?n=!0:(e=[],r.set(o,e));let a=i[o];t[o]=a,e.push(a)}o.push(t)}for(let[i,a]of r)if(Je.has(i)){let t=a.join("\n");e.items.add(t,i)}else e.items.add(a[0],i);if(n){let t=JSON.stringify(o);e.items.add(t,Ge)}}(e.dataTransfer,r);let n=Ve.all;if("function"==typeof t.getAllowedDropOperations){let e=t.getAllowedDropOperations();n=Ve.none;for(let t of e)n|=Ve[t]||Ve.none}ft(n);let o=Ye[n]||"none";e.dataTransfer.effectAllowed="cancel"===o?"none":o,"function"==typeof t.preview?.current&&t.preview.current(r,(t,r,n)=>{if(!t)return;let o=t.getBoundingClientRect(),i=e.currentTarget.getBoundingClientRect(),a=e.clientX-i.x,s=e.clientY-i.y;(a>o.width||s>o.height)&&(a=o.width/2,s=o.height/2);let l=a,d=s;"number"==typeof r&&"number"==typeof n&&(l=r,d=n),l=Math.max(0,Math.min(l,o.width)),d=Math.max(0,Math.min(d,o.height));let c=2*Math.round(o.height/2);t.style.height=`${c}px`,e.dataTransfer.setDragImage(t,l,d)}),h(window,"drop",e=>{e.preventDefault(),e.stopPropagation(),console.warn("Drags initiated from the React Aria useDrag hook may only be dropped on a target created with useDrop. This ensures that a keyboard and screen reader accessible alternative is available.")},{once:!0}),a.x=e.clientX,a.y=e.clientY;let i=l(e);requestAnimationFrame(()=>{g(i)})},onDrag:e=>{e.stopPropagation(),e.clientX===a.x&&e.clientY===a.y||("function"==typeof t.onDragMove&&t.onDragMove({type:"dragmove",x:e.clientX,y:e.clientY}),a.x=e.clientX,a.y=e.clientY)},onDragEnd:e=>{if(e.stopPropagation(),"function"==typeof t.onDragEnd){let r={type:"dragend",x:e.clientX,y:e.clientY,dropOperation:Xe[e.dataTransfer.dropEffect]};st&&(r.dropOperation=Xe[st]),t.onDragEnd(r)}g(null),y(),ft(Ve.none),ut(void 0)}},dragButtonProps:{...k,onPress:e=>{"keyboard"!==e.pointerType&&"virtual"!==e.pointerType||v(e.target)}},isDragging:p}}const Vt={keyboard:{selected:"dragSelectedKeyboard",notSelected:"dragDescriptionKeyboard"},touch:{selected:"dragSelectedLongPress",notSelected:"dragDescriptionLongPress"},virtual:{selected:"dragDescriptionVirtual",notSelected:"dragDescriptionVirtual"}};function Ht(e,t){let r=f((n=Pt)&&n.__esModule?n.default:n,"@react-aria/dnd");var n;let o,i,a=t.isDisabled||t.selectionManager.isDisabled(e.key),{dragProps:s,dragButtonProps:l}=Nt({getItems:()=>t.getItems(e.key),preview:t.preview,getAllowedDropOperations:t.getAllowedDropOperations,hasDragButton:e.hasDragButton,onDragStart(r){var n;t.startDrag(e.key,r),n=t.draggingKeys,lt.draggingKeys=n},onDragMove(e){t.moveDrag(e)},onDragEnd(e){let{dropOperation:r}=e,n="cancel"!==r&&pt();t.endDrag({...e,keys:t.draggingKeys,isInternal:n}),ct()}}),d=t.collection.getItem(e.key),c=t.getKeysForDrag(e.key).size,p=c>1&&t.selectionManager.isSelected(e.key),u=tt();if(e.hasDragButton||"none"===t.selectionManager.selectionMode)if(p)o=r.format("dragSelectedItems",{count:c});else{let n=t.collection.getTextValue?.(e.key)??d?.textValue??"";o=r.format("dragItem",{itemText:n})}else{let t=Vt[u][p?"selected":"notSelected"];e.hasAction&&"keyboard"===u&&(t+="Alt"),i=p?r.format(t,{count:c}):r.format(t),delete s.onClick}let g=m(i);if(i&&Object.assign(s,g),!e.hasDragButton&&e.hasAction){let{onKeyDownCapture:e,onKeyUpCapture:t}=s;"touch"===u&&delete s["aria-describedby"],s.onKeyDownCapture=t=>{t.altKey&&e?.(t)},s.onKeyUpCapture=e=>{e.altKey&&t?.(e)}}return{dragProps:a?{}:s,dragButtonProps:{...l,isDisabled:a,"aria-label":o}}}function Yt(e,t,r){let{draggingCollectionRef:n}=lt;t.draggingKeys.size>0&&n?.current!==r.current&&function(e){lt.draggingCollectionRef=e}(r)}const Xt=t.forwardRef(function(n,o){let i=n.children,[a,s]=e.useState(null),l=e.useRef(null),d=e.useRef(void 0);return e.useImperativeHandle(o,()=>(e,t)=>{let n,o,a,c=i(e);c&&"object"==typeof c&&"element"in c?(n=c.element,o=c.x,a=c.y):n=c,r.flushSync(()=>{s(n)}),t(l.current,o,a),d.current=requestAnimationFrame(()=>{s(null)})},[i]),e.useEffect(()=>()=>{d.current&&cancelAnimationFrame(d.current)},[]),a?t.createElement("div",{style:{zIndex:-100,position:"fixed",top:0,left:-1e5},ref:l},a):null});function Ut(e,t){if(!e)return!t;switch(e.type){case"root":return"root"===t?.type;case"item":return"item"===t?.type&&t?.key===e.key&&t?.dropPosition===e.dropPosition}}class qt{constructor(e,t,r){this.collection=e,this.ref=t,this.layout=r?.layout||"stack",this.orientation=r?.orientation||"vertical",this.direction=r?.direction||"ltr"}getPrimaryStart(e){return"horizontal"===this.orientation?e.left:e.top}getPrimaryEnd(e){return"horizontal"===this.orientation?e.right:e.bottom}getSecondaryStart(e){return"horizontal"===this.orientation?e.top:e.left}getSecondaryEnd(e){return"horizontal"===this.orientation?e.bottom:e.right}getFlowStart(e){return"stack"===this.layout?this.getPrimaryStart(e):this.getSecondaryStart(e)}getFlowEnd(e){return"stack"===this.layout?this.getPrimaryEnd(e):this.getSecondaryEnd(e)}getFlowSize(e){return this.getFlowEnd(e)-this.getFlowStart(e)}getDropTargetFromPoint(e,t,r){if(this.collection[Symbol.iterator]().next().done||!this.ref.current)return{type:"root"};let n=this.ref.current.getBoundingClientRect(),o="horizontal"===this.orientation?e:t,i="horizontal"===this.orientation?t:e;o+=this.getPrimaryStart(n),i+=this.getSecondaryStart(n);let a="stack"===this.layout?o:i,s="horizontal"===this.orientation&&"rtl"===this.direction,l="grid"===this.layout&&"vertical"===this.orientation&&"rtl"===this.direction,d="stack"===this.layout?s:l,c=this.ref.current?.dataset.collection,p=this.ref.current.querySelectorAll(c?`[data-collection="${CSS.escape(c)}"]`:"[data-key]"),u=new Map;for(let D of p)D instanceof HTMLElement&&null!=D.dataset.key&&u.set(D.dataset.key,D);let g=[...this.collection].filter(e=>"item"===e.type);if(g.length<1)return{type:"root"};let f=0,m=g.length;for(;f{t?f=e+1:m=e};if(othis.getPrimaryEnd(c))p(!s);else if(ithis.getSecondaryEnd(c))){let e={type:"item",key:t.key,dropPosition:"on"};if(r(e))a<=this.getFlowStart(c)+5&&r({...e,dropPosition:"before"})?e.dropPosition=d?"after":"before":a>=this.getFlowEnd(c)-5&&r({...e,dropPosition:"after"})&&(e.dropPosition=d?"before":"after");else{let t=this.getFlowStart(c)+this.getFlowSize(c)/2;a<=t&&r({...e,dropPosition:"before"})?e.dropPosition=d?"after":"before":a>=t&&r({...e,dropPosition:"after"})&&(e.dropPosition=d?"before":"after")}return e}p(!l)}}let h=g[Math.min(f,g.length-1)],y=u.get(String(h.key));return n=y?.getBoundingClientRect(),n&&(o{let{onDrop:r,onInsert:n,onItemDrop:o,onReorder:i,onMove:a,onRootDrop:s,getItems:l,renderDragPreview:d,renderDropIndicator:c,dropTargetDelegate:p}=t,u=!!(r||n||o||i||a||s),g={};return!!l&&(g.useDraggableCollectionState=function(r){return function(t){let{getItems:r,isDisabled:n,collection:o,selectionManager:i,onDragStart:a,onDragMove:s,onDragEnd:l,preview:d,getAllowedDropOperations:c}=t,[,p]=e.useState(!1),u=e.useRef(new Set),g=e.useRef(null),f=e=>{let t=new Set;if(i.isSelected(e))for(let r of i.selectedKeys){let e=o.getItem(r);if(e){let n=!1,a=e.parentKey;for(;null!=a;){if(i.selectedKeys.has(a)){n=!0;break}let e=o.getItem(a);a=e?e.parentKey:null}n||t.add(r)}}else t.add(e);return t};return{collection:o,selectionManager:i,get draggedKey(){return g.current},get draggingKeys(){return u.current},isDragging:e=>u.current.has(e),getKeysForDrag:f,getItems(e){let t=f(e),n=[];for(let r of t){let e=o.getItem(r)?.value;null!=e&&n.push(e)}return r(f(e),n)},isDisabled:n,preview:d,getAllowedDropOperations:c,startDrag(e,t){let r=f(e);u.current=r,g.current=e,i.setFocused(!1),p(!0),"function"==typeof a&&a({...t,keys:r})},moveDrag(e){"function"==typeof s&&s({...e,keys:u.current})},endDrag(e){let{isInternal:t}=e;"function"==typeof l&&l({...e,keys:u.current,isInternal:t}),u.current=new Set,g.current=null,p(!1)}}}({...r,...t})},g.useDraggableCollection=Yt,g.useDraggableItem=Ht,g.DragPreview=Xt,g.renderDragPreview=d,g.isVirtualDragging=wt),u&&(g.useDroppableCollectionState=function(r){return function(t){let{acceptedDragTypes:r="all",isDisabled:n,onInsert:o,onRootDrop:i,onItemDrop:a,onReorder:s,onMove:l,shouldAcceptItemDrop:d,collection:c,selectionManager:p,onDropEnter:u,getDropOperation:g,onDrop:f}=t,[m,h]=e.useState(null),y=e.useRef(null),D=e=>{if("before"===e.dropPosition){let t=c.getItem(e.key);return t&&null!=t.prevKey?{type:"item",key:t.prevKey,dropPosition:"after"}:null}if("after"===e.dropPosition){let t=c.getItem(e.key);return t&&null!=t.nextKey?{type:"item",key:t.nextKey,dropPosition:"before"}:null}return null},v=e.useCallback(e=>{let{target:t,types:p,allowedOperations:u,isInternal:m,draggingKeys:h}=e;if(n||!t)return"cancel";if("all"===r||r.some(e=>p.has(e))){let e=o&&"item"===t.type&&!m&&("before"===t.dropPosition||"after"===t.dropPosition),r=s&&"item"===t.type&&m&&("before"===t.dropPosition||"after"===t.dropPosition)&&function(e,t,r){let n=e.getItem(t.key);for(let o of r){let t=e.getItem(o);if(t?.parentKey!==n?.parentKey)return!1}return!0}(c,t,h),n="item"!==t.type||"on"!==t.dropPosition||!d||d(t,p),y=l&&"item"===t.type&&m&&n,D=i&&"root"===t.type&&!m,v=a&&"item"===t.type&&"on"===t.dropPosition&&!(m&&null!=t.key&&h.has(t.key))&&n;if(f||e||r||y||D||v)return g?g(t,p,u):u[0]}return"cancel"},[n,c,r,g,o,i,a,d,s,l,f]);return{collection:c,selectionManager:p,isDisabled:n,target:m,setTarget(e){if(this.isDropTarget(e))return;let r=y.current;r&&"function"==typeof t.onDropExit&&t.onDropExit({type:"dropexit",x:0,y:0,target:r}),e&&"function"==typeof u&&u({type:"dropenter",x:0,y:0,target:e}),y.current=e??null,h(e??null)},isDropTarget(e){let t=y.current;return!(!t||!e)&&(!!Ut(e,t)||"item"===e?.type&&"item"===t?.type&&e.key!==t.key&&e.dropPosition!==t.dropPosition&&"on"!==e.dropPosition&&"on"!==t.dropPosition&&(Ut(D(e),t)||Ut(e,D(t))))},getDropOperation(e){let{target:t,isInternal:r,draggingKeys:n}=e;if(r&&"item"===t.type&&n.size>0){if(n.has(t.key)&&"on"===t.dropPosition)return"cancel";let e=t.key;for(;null!=e;){let t=c.getItem(e),r=t?.parentKey;if(null!=r&&n.has(r))return"cancel";e=r??null}}return v(e)}}}({...r,...t})},g.useDroppableItem=Ft,g.useDroppableCollection=function(e,r,n){return Lt({...e,...t},r,n)},g.useDropIndicator=$t,g.renderDropIndicator=c,g.dropTargetDelegate=p,g.ListDropTargetDelegate=qt),g},[t])}}const Gt="application/x-doona-card";function Wt(e){return n.jsx(S,{viewBox:"0 0 12 12",...e,children:[1.6,6,10.4].flatMap(e=>[3.8,8.2].map(t=>n.jsx("circle",{cx:t,cy:e,r:1.1,fill:"currentColor"},`${t}-${e}`)))})}const _t={},Zt=new Map,Qt=new Set,er=e=>{if(_t.card=e,Zt.clear(),void 0===e)for(const t of Qt)t()},tr=e=>[...document.querySelectorAll(".rp-dashboard-cell")].find(t=>t.dataset.instance===e);function rr(e){let t=[1,1];for(let r=1;r<=12;r++){const n=Math.round(e*r);n>0&&Math.abs(e-n/r){const e=t.current;if(!e)return;const r=()=>{const t=e.parentElement.getBoundingClientRect(),r=getComputedStyle(e),n=Number.parseFloat(r.getPropertyValue("--rp-dash-gap"))||0,o=function(e,t,r,n){const o=n?e.map(e=>({...e,left:t-e.right,right:t-e.left})):e,i=new Map;for(const a of o)i.set(Math.round(a.top),[...i.get(Math.round(a.top))??[],a]);return[...i.values()].flatMap(e=>{const i=e[0].top,a=Math.max(...e.map(e=>e.bottom)),s=Math.max(...e.map(e=>e.right))+r;let l=t;for(const t of o)!e.includes(t)&&t.topi+.5&&t.right>s&&(l=Math.min(l,t.left-r));return(l-s+r)/(t+r)<1/6-.01?[]:[{after:e.at(-1).id,left:n?t-l:s,top:i,width:l-s,height:a-i}]})}([...e.querySelectorAll(":scope > .rp-dashboard-cell")].map(e=>{const r=e.getBoundingClientRect();return{id:e.dataset.instance,left:r.left-t.left,right:r.right-t.left,top:r.top-t.top,bottom:r.bottom-t.top}}),t.width,n,"rtl"===r.direction).map(e=>({...e,share:rr((e.width+n)/(t.width+n))}));s(e=>JSON.stringify(e)===JSON.stringify(o)?e:o)};return r(),e.addEventListener("rp-packed",r),()=>e.removeEventListener("rp-packed",r)},[t]),a.map(e=>n.jsx(or,{section:t,gap:e,label:r(e.share),refusal:o,onPlace:i},e.after))}function or({section:t,gap:r,label:o,refusal:i,onPlace:a}){const s=e.useRef(null),[l,d]=e.useState(!1),c=(e=_t.card)=>{const n=t.current;if(void 0===e||!n)return!1;const o=[e,r.after,r.width].join("\n");return Zt.has(o)||Zt.set(o,(function(e,t,r){const n=tr(t),o=tr(r);if(!n||o?.parentElement!==e)return;const i=document.createElement("div");i.className="rp-dashboard-cell",i.style.visibility="hidden";for(const d of["data-module","data-size","data-foot","data-width","data-height"]){const e=n.getAttribute(d);null!==e&&i.setAttribute(d,e)}const a=e.dataset.grid;i.dataset.width&&(e.dataset.grid="fraction");const s=n.parentElement===e;s&&n.classList.remove("rp-dashboard-cell"),o.after(i);const l=i.getBoundingClientRect().width;return i.remove(),s&&n.classList.add("rp-dashboard-cell"),void 0===a?delete e.dataset.grid:e.dataset.grid=a,l}(n,e,r.after)??1/0)<=r.width+1),Zt.get(o)},{dropProps:p,isDropTarget:u}=St({ref:s,getDropOperation:e=>e.has(Gt)&&c()?"move":"cancel",onDrop:async e=>{for(const t of e.items){if("text"!==t.kind||!t.types.has(Gt))continue;const e=await t.getText(Gt);c(e)&&a(e,{target:r.after,after:!0})}}}),g={onDragEnter:()=>d(void 0!==_t.card&&!c()),onDragLeave:()=>d(!1),onDrop:()=>d(!1)};return e.useEffect(()=>{const e=()=>d(!1);return Qt.add(e),()=>{Qt.delete(e)}},[]),n.jsxs("div",{...K(p,g),ref:s,className:"rp-dashboard-gap rp-label","data-drop-target":u||void 0,"data-refused":l||void 0,style:{left:r.left,top:r.top,width:r.width,height:r.height},children:[o,n.jsx(C,{children:n.jsx("span",{role:"status",children:l?i:""})})]})}const ir={current:null};let ar;function sr({label:t,profile:r,items:o,textValue:i,dragLabel:a,tools:s,resize:l,gapLabel:d,refusal:c,rearm:p,children:u,onPlace:g,...f}){const m=e.useRef(null);_(r?m:ir),e.useEffect(()=>{!p?.focus||document.activeElement&&document.activeElement!==document.body||m.current?.querySelector(`[data-key="${CSS.escape(p.focus)}"]`)?.focus()},[p]);const h=async e=>{for(const t of e.items)if("text"===t.kind&&t.types.has(Gt))return t.getText(Gt)},{dragAndDropHooks:y}=function(t){const{dragAndDropHooks:r}=Jt(t);return{dragAndDropHooks:e.useMemo(()=>function(e){const{useDraggableItem:t,isVirtualDragging:r}=e;return t&&r?{...e,useDraggableItem:(e,n)=>{const o=t(e,n),i=o.dragButtonProps.onPress;return{...o,dragButtonProps:{...o.dragButtonProps,onPress:e=>{r()||i?.(e)}}}}}:e}(r),[r])}}({getItems:e=>[...e].map(e=>({[Gt]:String(e),"text/plain":i(o.find(t=>t.id===e))})),getAllowedDropOperations:()=>["move"],acceptedDragTypes:[Gt],getDropOperation:()=>"move",onDragStart:e=>er(String([...e.keys][0])),onDragEnd:()=>{er(void 0),function(){ar?.();const e=()=>{document.removeEventListener("pointerdown",e,!0),document.removeEventListener("mousedown",t,!0),ar=void 0},t=t=>{e();const{clientX:r,clientY:n,screenX:o,screenY:i,button:a,buttons:s,ctrlKey:l,shiftKey:d,altKey:c,metaKey:p}=t;t.target?.dispatchEvent(new PointerEvent("pointerdown",{bubbles:!0,cancelable:!0,composed:!0,pointerId:1,pointerType:"mouse",isPrimary:!0,clientX:r,clientY:n,screenX:o,screenY:i,button:a,buttons:s,ctrlKey:l,shiftKey:d,altKey:c,metaKey:p}))};ar=e,document.addEventListener("pointerdown",e,!0),document.addEventListener("mousedown",t,!0)}()},renderDropIndicator:e=>n.jsx(Be,{target:e,className:"rp-canvas-drop"}),onReorder:e=>{for(const t of e.keys)g(String(t),{target:String(e.target.key),after:"after"===e.target.dropPosition})},onInsert:async e=>{const t=await h(e);t&&g(t,{target:String(e.target.key),after:"after"===e.target.dropPosition})},onRootDrop:async e=>{const t=await h(e);t&&g(t,{})}}),D=n.jsx(Re,{...f,ref:m,"aria-label":t,layout:"grid",className:r?"rp-dash-section":"rp-widget-grid rp-sortable-grid","data-profile":r,"data-grid":r?te(o):void 0,items:o,dragAndDropHooks:y,dependencies:[u,s,l],children:e=>n.jsxs(Me,{id:e.id,textValue:i(e),className:r?"rp-dashboard-cell":"rp-widget-cell rp-sortable-row",...r?Q(e):{"data-size":ee(e.size),"data-module":e.module},children:[n.jsxs("div",{className:"rp-dashboard-tools",children:[n.jsx(I,{slot:"drag",className:j({quiet:!0,icon:!0,small:!r}),"aria-label":a(e),children:n.jsx(Wt,{})}),s?.(e)]}),n.jsx(Z,{children:u(e)}),l?.(e)]})});return r?n.jsxs("div",{className:"rp-dashboard-canvas","data-rearm":p?"":void 0,children:[D,d&&n.jsx(nr,{section:m,label:d,refusal:c,onPlace:g})]}):D}function lr({id:t,label:r,added:o,addLabel:i,count:a,onAdd:s,presets:l,row:d,children:c}){const[p,u]=A(void 0,200),[g,f]=e.useState(!1);return u&&!g&&f(!0),n.jsxs("section",{ref:p,className:"rp-widget-gallery-tile","data-added":o||void 0,"data-module":t,"aria-label":r,children:[n.jsx("h3",{className:"rp-h3",children:r}),l&&d?n.jsx(dr,{presets:l,row:d,loaded:g,disabled:o}):n.jsx("div",{className:"rp-widget-gallery-frame",inert:!0,children:n.jsx(R,{value:!1,children:g&&c})}),n.jsxs("div",{className:"rp-cluster",children:[n.jsx(M,{isDisabled:o,label:`${i} ${r}`,onPress:s,children:i}),n.jsx("span",{className:"rp-label",children:a})]})]})}function dr({presets:e,row:t,loaded:r,disabled:o}){const[i,a]=B(Math.round),s=a?a.width/t.width:0;return n.jsx("div",{ref:i,className:"rp-widget-gallery-presets",style:{"--rp-preset-gap":t.gap*s+"px"},children:r&&s>0&&e.map(e=>n.jsx(cr,{preset:e,width:e.share*(t.width+t.gap)-t.gap,scale:s,disabled:o},e.key))})}function cr({preset:e,width:t,scale:r,disabled:o}){const[i,a]=B(Math.round);return n.jsxs("div",{className:"rp-widget-gallery-preset",style:{inlineSize:t*r},children:[n.jsxs("div",{className:"rp-widget-gallery-thumb",style:{blockSize:(a?.height??0)*r},children:[n.jsx("div",{ref:i,className:"rp-widget-gallery-thumb-card",style:{inlineSize:t,scale:String(r)},inert:!0,children:n.jsx(R,{value:!1,children:e.preview})}),n.jsx(I,{className:"rp-widget-gallery-thumb-add","aria-label":e.addLabel,isDisabled:o,onPress:e.onAdd})]}),n.jsx("span",{className:"rp-label",children:e.label})]})}function pr({label:e,children:t}){return n.jsxs("div",{className:"rp-module-option",children:[n.jsx("span",{className:"rp-label",children:e}),t]})}function ur(){const e=document.querySelector(".rp-dashboard-canvas"),t=e&&getComputedStyle(e.querySelector(".rp-dash-section")??e);return{width:e?.getBoundingClientRect().width||1152,gap:Number.parseFloat(t?.getPropertyValue("--rp-dash-gap")??"")||12,snap:Number.parseFloat(t?.getPropertyValue("--rp-dash-snap")??"")||12}}function gr({items:t,add:r,surface:o="panel"}){const i=L(),[a]=e.useState(ur),s="dashboard"===o?re(ne()):[];return Object.keys(oe).filter(e=>"panel"===o||!ie(e)).map(e=>{const l=t.filter(t=>t.id===e).length,d=s.find(t=>t.id===e)??ae(e),c=e=>{const t=we(e.width);return a.snap>=12?t:Math.ceil(t*a.snap-1e-6)/a.snap};return n.jsx(lr,{id:e,label:i(oe[e].label),added:l>=me,addLabel:i("widgets.add"),count:i("widgets.placedCount",{n:l,max:me}),onAdd:()=>r(e),row:a,presets:"dashboard"===o?le(d,de(d)).map(t=>{const o=ce(d,t),a=pe(t,i);return{key:a,label:a,addLabel:i("widgets.addPreset",{name:i(oe[e].label),size:a}),share:c(t),onAdd:()=>r(e,t),preview:n.jsx(ue,{id:e,children:n.jsx(F,{value:!0,children:n.jsx("div",{className:"rp-dashboard-cell",...Q(fe(o)),"data-tile":"tall"===o.height?"stacked":void 0,children:n.jsx(ge,{item:o,preview:!0})})})})}}):void 0,children:"panel"===o&&n.jsx(se,{item:ae(e),preview:!0,sample:!0})},e)})}const fr={area:"dashboard.form.area",sparkline:"dashboard.form.sparkline",donut:"dashboard.form.donut",waffle:"dashboard.form.waffle",dots:"dashboard.form.dots",ranked:"dashboard.form.ranked",kv:"dashboard.form.kv",facts:"dashboard.form.facts"},mr={small:"widgets.small",medium:"widgets.medium",large:"widgets.large",wide:"dashboard.wide"};function hr({active:e,items:t,sizes:r=[],surface:o,update:i,move:a,remove:s}){const l=L();if(!e)return n.jsx("p",{className:"rp-label",children:l("widgets.select")});const d=oe[e.id].groupChoice;return n.jsxs(n.Fragment,{children:["dashboard"===o&&Object.values(he(e,de(e),l)).map(e=>e&&n.jsx(pr,{label:e.label,children:n.jsx(Fe,{label:e.label,value:e.value,onChange:t=>i(e.set(t)),items:e.options.map(e=>[e.value,e.label])})},e.label)),r.length>1&&n.jsx(pr,{label:l("widgets.size"),children:n.jsx(Fe,{label:l("widgets.size"),value:e.size,onChange:t=>i({...e,size:t,form:"panel"===o&&"small"===t&&ye(e.id,o).includes("kv")?"kv":e.form}),items:r.map(e=>[e,l(mr[e])])})}),ye(e.id,o).length>1&&!("small"===e.size&&!e.width&&ye(e.id,o).includes("sparkline"))&&n.jsx(pr,{label:l("widgets.form"),children:n.jsx(Fe,{label:l("widgets.form"),value:ve(e,o),onChange:t=>i({...e,form:t,size:"large"!==e.size||De(e.id,t,o).includes("large")?e.size:"medium"}),items:ye(e.id,o).map(e=>[e,l(fr[e])])})}),"ranking"===e.id&&n.jsx(pr,{label:l("widgets.rankBy"),children:n.jsx(Fe,{label:l("widgets.rankBy"),value:e.by??"dev",onChange:t=>i({...e,by:"domain"===t?"domain":"dev"}),items:[["dev",l("act.devices")],["domain",l("act.domains")]]})}),"speed"===e.id&&"small"!==e.size&&"sparkline"===ve(e,o)&&n.jsx($,{isSelected:!e.split,onChange:t=>i({...e,split:!t||void 0}),children:l("widgets.combineRates")}),d&&n.jsx(yr,{item:e,automatic:d,update:i}),n.jsxs("div",{className:"rp-cluster rp-module-actions",children:[n.jsx(M,{isDisabled:be(t[0])===be(e),onPress:()=>a(-1),children:l("widgets.up")}),n.jsx(M,{isDisabled:be(t.at(-1))===be(e),onPress:()=>a(1),children:l("widgets.down")}),n.jsx(M,{negative:!0,onPress:s,children:l("widgets.remove")})]})]})}function yr({item:e,automatic:t,update:r}){const o=z(),i=$e(!0===o.data?.resources.groups.available),a=L(),s=a(t);return n.jsx(pr,{label:a("ui.group"),children:n.jsx(Ne,{label:a("ui.group"),value:e.group??"",items:[{id:"",label:s},...(i.data??[]).map(e=>({id:e.id,label:e.name}))],onChange:t=>r({...e,group:t}),children:i.data?.find(t=>t.id===e.group)?.name??s})})}function Dr(e,t,r){const n=re(e).find(e=>be(e)===t);if(!n||r.target===t)return e;const o=e.sections.map(e=>({...e,items:e.items.filter(e=>be(e)!==t)})),i=o.find(e=>e.id===r.section);if(!i)return e;const a=void 0===r.target?-1:i.items.findIndex(e=>be(e)===r.target);return i.items.splice(a<0?i.items.length:a+(r.after?1:0),0,n),{...e,sections:o}}function vr({width:e,height:t}){return n.jsxs(n.Fragment,{children:[n.jsx(Er,{axis:e,edge:"width"}),t&&n.jsx(Er,{axis:t,edge:"height"})]})}const br=e=>{const[t,r=1]=e.split("/").map(Number);return t/r||0};function wr(e,t){const r=e.closest(".rp-dash-section"),n=getComputedStyle(r),o=getComputedStyle(e),i=Number.parseFloat(n.getPropertyValue("--rp-dash-snap"))||12,a=Number.parseFloat(n.getPropertyValue("--rp-dash-gap"))||0,s=r.getBoundingClientRect().width+Math.min(0,Number.parseFloat(n.marginInlineStart)||0),l=Number.parseFloat(o.getPropertyValue("--rp-span"))||420,d=br(o.getPropertyValue("--rp-shift"))-br(o.getPropertyValue("--rp-trim"));return t.map(t=>{if(void 0===t.fraction)return e.dataset.width?l/420*(s+a)-a+d*a:e.getBoundingClientRect().width;return(i>=12?t.fraction:Math.ceil(t.fraction*i-1e-6)/i)*(s+a)-a})}const xr=(e,t,r)=>t.reduce((n,o,i)=>{const a=Math.abs(o-r)-Math.abs(t[n]-r);return a<-.5||a<=.5&&void 0===e[n].fraction&&void 0!==e[i].fraction?i:n},0),Tr=new Map,kr=e=>e.target&&Tr.get(e.target)?.(e);function Er({axis:t,edge:r}){const o=e.useRef(null),i=e.useRef(null),{focusProps:a,isFocusVisible:s}=N(),l=()=>o.current.closest(".rp-dashboard-cell"),d=()=>"rtl"===getComputedStyle(o.current).direction,c=Math.max(0,t.options.findIndex(e=>e.value===t.value)),p=e=>{i.current&&(i.current.index=e),t.options[e].value!==t.value&&t.onChange(t.options[e])},{moveProps:u}=ze({onMoveStart:()=>{const e=l().getBoundingClientRect(),n=Number.parseFloat(getComputedStyle(l()).getPropertyValue("--rp-space-16"))||1,o="width"===r?wr(l(),t.options):[];i.current={start:c,size:"width"===r?e.width:e.height,travel:0,sizes:o,step:n,index:c},l().dataset.resizing=""},onMove:({deltaX:e,deltaY:n,pointerType:o})=>{const a=i.current;if(!a||"keyboard"===o)return;a.travel+="width"===r?e*(d()?-1:1):n;const s="width"===r?xr(t.options,a.sizes,a.size+a.travel):Math.max(0,Math.min(t.options.length-1,a.start+Math.round(a.travel/a.step)));s!==a.index&&p(s)},onMoveEnd:()=>{i.current=null,delete l().dataset.resizing}}),g=e.useRef(e=>{});return e.useLayoutEffect(()=>{g.current=e=>{const n="width"===r?d()?"ArrowLeft":"ArrowRight":"ArrowDown",o="width"===r?d()?"ArrowRight":"ArrowLeft":"ArrowUp";e.key!==n&&e.key!==o||(e.preventDefault(),e.stopPropagation(),p((e=>{if("width"===r&&void 0===t.options[c].fraction){if(!e)return c;const r=l().getBoundingClientRect().width,n=wr(l(),t.options).findIndex((e,n)=>void 0!==t.options[n].fraction&&e>r+1);return n<0?t.options.length-1:n}return Math.max(0,Math.min(t.options.length-1,c+(e?1:-1)))})(e.key===n)))}}),e.useEffect(()=>{return e=o.current,t=e=>g.current(e),Tr.size||addEventListener("keydown",kr,!0),Tr.set(e,t),()=>{Tr.delete(e),Tr.size||removeEventListener("keydown",kr,!0)};var e,t},[]),n.jsx("div",{ref:o,role:"slider",tabIndex:0,...a,...u,onPointerDown:e=>{e.preventDefault(),e.stopPropagation(),u.onPointerDown?.(e)},className:"rp-dashboard-resize rp-grip","data-edge":r,"data-focus-visible":s||void 0,"aria-label":t.label,"aria-orientation":"width"===r?"horizontal":"vertical","aria-valuemin":0,"aria-valuemax":t.options.length-1,"aria-valuenow":c,"aria-valuetext":t.options[c]?.label})}const Pr=(e,t)=>e.filter(e=>e.id===t).lengthbe(e)===t)?{instance:V()}:{}}:null;function Kr({draft:t,setDraft:r,render:o}){const i=L(),[a,s]=e.useState({text:"",serial:0}),l=re(t),d=e=>s(t=>({text:e,serial:t.serial+1})),c=e.useRef([]);e.useEffect(()=>()=>c.current.forEach(e=>q(e.key)),[]),e.useEffect(()=>{c.current=c.current.filter(e=>!!e.restorable(t)||(q(e.key),!1))},[t]);const[p,u]=e.useState(null),g=e.useRef({x:Number.NaN,y:Number.NaN});e.useEffect(()=>{const e=e=>{g.current={x:e.clientX,y:e.clientY}};return document.addEventListener("pointerdown",e,!0),document.addEventListener("pointermove",e,!0),()=>{document.removeEventListener("pointerdown",e,!0),document.removeEventListener("pointermove",e,!0)}},[]),e.useEffect(()=>{if(!p)return;const{x:e,y:t}=g.current,r=r=>{r instanceof PointerEvent&&r.clientX===e&&r.clientY===t||u(null)};return document.addEventListener("pointermove",r,!0),document.addEventListener("keydown",r,!0),()=>{document.removeEventListener("pointermove",r,!0),document.removeEventListener("keydown",r,!0)}},[p]);const f=e=>{const{layout:n,restore:o,restorable:a}=function(e,t){const r=e.sections.find(e=>e.items.some(e=>be(e)===t));if(!r)return{layout:e,restore:e=>e,restorable:()=>!1};const n=r.items.findIndex(e=>be(e)===t),o=r.items[n],i=e=>{const r=re(e);return!r.some(e=>be(e)===t)&&r.filter(e=>e.id===o.id).lengthe===r?{...e,items:e.items.filter(e=>e!==o)}:e)},restore:e=>i(e)?{...e,sections:e.sections.map(e=>e.id===r.id?{...e,items:[...e.items.slice(0,n),o,...e.items.slice(n)]}:e)}:e,restorable:i}}(t,be(e)),s=l.findIndex(t=>be(t)===be(e)),d=l[s+1]??l[s-1];u({focus:d&&be(d)}),r(n);const p=W("neutral",i("widgets.removed",{name:i(oe[e.id].label)}),{id:`removed:${be(e)}`,action:{label:i("ui.undo"),onAction:()=>r(e=>e&&o(e)),closeOnAction:!0}});c.current.push({key:p,restorable:a})};return n.jsxs(n.Fragment,{children:[t.sections.map(e=>n.jsx(sr,{label:i("widgets.order"),profile:e.id,items:e.items.map(e=>({...fe(e),item:e})),textValue:({item:e})=>i(oe[e.id].label),dragLabel:({item:e})=>i("widgets.drag",{name:i(oe[e.id].label)}),gapLabel:e=>i("dashboard.remaining",{space:e}),refusal:i("dashboard.noRoom"),rearm:p,resize:({item:e})=>{const o=he(e,de(e),i),a=(e,n)=>e&&{label:n,value:e.value,options:e.options,onChange:n=>{r(Te(t,Ae(e.set(n.value)))),d(`${e.label}: ${n.label}`)}};return n.jsx(vr,{width:a(o.width,i("dashboard.resizeWidth")),height:a(o.height,i("dashboard.resizeHeight"))})},onPlace:(n,o)=>{r(Dr(t,n,{section:e.id,...o})),d(i("widgets.reordered"))},tools:({item:e})=>n.jsxs(n.Fragment,{children:[n.jsx(J,{title:i(oe[e.id].label),placement:"bottom end",trigger:n.jsx(M,{quiet:!0,icon:!0,label:i("widgets.inspector"),children:n.jsx(G,{})}),children:()=>n.jsx("div",{className:"rp-module-inspector",children:n.jsx(hr,{active:e,items:l,surface:"dashboard",update:e=>r(Te(t,Ae(e))),move:n=>{r(function(e,t,r){const n=e.sections.findIndex(e=>e.items.some(e=>be(e)===t));if(n<0)return e;const o=e.sections[n].items,i=o.findIndex(e=>be(e)===t),a=o[i+r];if(a)return Dr(e,t,{section:e.sections[n].id,target:be(a),after:r>0});const s=e.sections[n+r];if(!s)return e;const l=r>0?s.items[0]:s.items.at(-1);return Dr(e,t,{section:s.id,...l?{target:be(l),after:r<0}:{}})}(t,be(e),n)),d(i("widgets.reordered"))},remove:()=>f(e)})})}),n.jsx(M,{quiet:!0,icon:!0,label:i("widgets.removeName",{name:i(oe[e.id].label)}),onPress:()=>f(e),children:n.jsx(Le,{})})]}),children:({item:e})=>o(e)},e.id)),n.jsx(C,{children:n.jsx("span",{role:"status",children:n.jsx("span",{children:a.text},a.serial)})})]})}function Or({draft:t,saved:r,setDraft:o,onClose:i}){const a=L(),[s,l]=e.useState(!1),d=e.useMemo(()=>JSON.stringify(t)!==JSON.stringify(r),[t,r]);return H(d,i),n.jsxs(Y,{children:[n.jsx(X,{title:a("widgets.gallery"),size:"wide",scrollBody:!0,trigger:n.jsx(M,{children:a("widgets.gallery")}),footer:e=>n.jsx(M,{onPress:e,children:a("ui.close")}),children:n.jsx("div",{className:"rp-widget-gallery-grid",children:n.jsx(gr,{items:re(t),add:(e,r)=>o(function(e,t,r){const n=Pr(re(e),t);if(!n)return e;const o=r?ce(n,r):n;return{...e,sections:e.sections.map(e=>"extensions"===e.id?{...e,items:[...e.items,o]}:e)}}(t,e,r)),surface:"dashboard"})})}),n.jsx(M,{onPress:()=>o(ne()),children:a("widgets.reset")}),n.jsx(M,{onPress:()=>d?l(!0):i(),children:a("ui.cancel")}),n.jsx(M,{accent:!0,onPress:()=>{xe(t),i()},children:a("ui.done")}),n.jsx(U,{title:a("config.discardTitle"),isOpen:s,onCancel:()=>l(!1),confirmLabel:a("config.discard"),onConfirm:i,children:n.jsx("p",{children:a("widgets.discardHelp")})})]})}function Sr({onClose:t,backend:r}){const o=L(),[i]=e.useState(ke),a=i.items,[s,l]=e.useState(a),[d,c]=e.useState(!1),[p]=e.useState(()=>i.docked?document.querySelector(".rp-side-dock")?.offsetWidth:void 0),u=i.size?.width??Ee,[g,f]=e.useState(u),[m,h]=e.useState(!1),y=g!==(d?Ee:u),[D,v]=e.useState(null),[b,w]=e.useState(!1),[x,T]=e.useState({text:"",serial:0}),k=e=>T(t=>({text:e,serial:t.serial+1})),E=d&&Pe(ke()),P=e.useMemo(()=>JSON.stringify(a)!==JSON.stringify(s),[a,s])||E||y;H(P,t);const K=()=>P?w(!0):t(),O=s.find(e=>be(e)===D);return n.jsxs(n.Fragment,{children:[n.jsxs(X,{title:o("widgets.edit"),size:"wide",scrollBody:!0,isOpen:!0,onOpenChange:e=>{e||K()},footer:()=>n.jsxs(n.Fragment,{children:[n.jsx(M,{onPress:()=>{l(Se().items),c(!0),f(Ee),v(null)},children:o("widgets.reset")}),n.jsx(M,{onPress:K,children:o("ui.cancel")}),n.jsx(M,{accent:!0,onPress:()=>{Ce(e=>({...e,version:4,items:s,...d&&je,...y&&{size:{width:g,height:(d?void 0:e.size?.height)??Ie}}})),t()},children:o("settings.save")})]}),children:[n.jsx(Ke,{panelWidth:(d||m?void 0:p)??g,onPanelWidth:e=>{h(!0),f(e)},resizeLabel:o("widgets.resizePreview"),header:n.jsx(Oe,{backend:r,preview:!0}),galleryLabel:o("widgets.gallery"),canvasLabel:o("widgets.canvas"),inspectorLabel:o(O?oe[O.id].label:"widgets.inspector"),gallery:n.jsx(gr,{items:s,add:e=>{const t=Pr(s,e);t&&(l([...s,t]),v(be(t)),k(o("widgets.addedName",{name:o(oe[e].label)})))}}),canvas:n.jsx(sr,{label:o("widgets.order"),items:s.map(e=>({item:e,module:e.id,id:be(e),size:e.size})),textValue:({item:e})=>o(oe[e.id].label),selectionMode:"single",selectedKeys:D?new Set([D]):new Set,onSelectionChange:e=>{"all"!==e&&v(String([...e][0]))},dragLabel:({item:e})=>o("widgets.drag",{name:o(oe[e.id].label)}),onPlace:(e,{target:t,after:r})=>{t&&(l(n=>{const o=function(e,t,r,n){if(t.has(r))return e;const o=e.filter(e=>!t.has(e)),i=o.indexOf(r);return i<0?e:(o.splice(i+("after"===n?1:0),0,...e.filter(e=>t.has(e))),o)}(n.map(be),new Set([e]),t,r?"after":"before");return o.flatMap(e=>n.find(t=>be(t)===e)??[])}),k(o("widgets.reordered")))},children:({item:e})=>n.jsx(se,{item:e,preview:!0})}),inspector:n.jsx(hr,{active:O,items:s,sizes:O?De(O.id,ve(O,"panel"),"panel"):[],surface:"panel",update:e=>l(t=>t.map(Ae(e))),move:e=>{O&&l(function(e,t,r){const n=e.findIndex(e=>be(e)===t),o=n+r;if(n<0||o<0||o>=e.length)return e;const i=[...e];return i.splice(o,0,...i.splice(n,1)),i}(s,be(O),e)),k(o("widgets.reordered"))},remove:()=>{O&&(e=>{const t=be(e);l(e=>e.filter(e=>be(e)!==t)),v(null),k(o("widgets.removed",{name:o(oe[e.id].label)}))})(O)}})}),n.jsx(C,{children:n.jsx("span",{role:"status",children:n.jsx("span",{children:x.text},x.serial)})})]}),n.jsx(U,{title:o("config.discardTitle"),isOpen:b,onCancel:()=>w(!1),confirmLabel:o("config.discard"),onConfirm:t,children:n.jsx("p",{children:o("widgets.discardHelp")})})]})}export{Or as DashboardActions,Kr as DashboardEditor,Sr as WidgetEditor};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Events-C4f8u4ie.js b/luci-app-honk/root/etc/honk/doona/assets/Events-DwM4OJI7.js
similarity index 52%
rename from luci-app-honk/root/etc/honk/doona/assets/Events-C4f8u4ie.js
rename to luci-app-honk/root/etc/honk/doona/assets/Events-DwM4OJI7.js
index 95bd93edc..c088822cd 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Events-C4f8u4ie.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Events-DwM4OJI7.js
@@ -1 +1 @@
-import{r as e,j as t}from"./vendor-react-64fcanlc.js";import{Z as s,a8 as n,aa as r,a7 as a,h as i,af as o,u as l,at as d,as as c,r as m,cf as u,ah as p,ai as v,dT as h,dU as j,T as f,aD as x,B as b,c as g,cn as w,E as k}from"./index-CUHkLMAp.js";import{e as y,Q as T,K as C,p as N,L as _}from"./logs-C6Kb44nw.js";import{D as S}from"./Table-DX856nrS.js";import{d as W,e as H}from"./files-Dt8K7QfP.js";import{j as R,D}from"./activity-B3PmJo_X.js";import{u as K,C as O}from"./Copy-CO66tox2.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./Select-BA0NS1_z.js";import"./ItemText-CnEXu0-f.js";import"./AppearanceControls-E-VPhjIz.js";import"./nodes-BYMoo8M1.js";import"./useGridSelectionCheckbox-CTBMGgmQ.js";import"./Virtualizer-UMC7L0o2.js";import"./Checkbox-8Iqnc6T1.js";const M={buffer_overflow:["event.gap.overflow","event.gapHelp.overflow"],evicted:["event.gap.evicted","event.gapHelp.evicted"]};function P(e,t){const s="flow.gap"===e.event&&Object.hasOwn(M,e.data.reason)?M[e.data.reason]:void 0;return s&&{title:t(s[0]),text:t(s[1])}}function q(e,t,s){const n=e=>e?[{id:"flow",label:t("event.viewFlow"),href:i("flows",{tab:"records",id:e})}]:[];switch(e.event){case"flow.updated":return n(e.data.resource_id);case"flow.gap":return[...n(e.data.resource_id),...s?.runtime_settings.available?[{id:"recording",label:t("ui.recordingSettings"),href:R}]:[]];case"generation.changed":return s?.config.available?[{id:"config",label:t("event.viewConfig"),href:i("config")}]:[];default:return[]}}const F=new WeakMap;function J(e,t,i,o,l,d,c,m,u=!1,p=()=>!1,v){const h="without-runtime"===t||m.includes(t)?t:"all",j=e.filter(e=>"all"===h||("without-runtime"===h?"runtime.updated"!==e.event:e.event===h)).slice(0,l);return{kind:h,rows:j.map(e=>function(e,t,i,o,l){const d=F.get(e);if(d&&d.locale===t&&d.resources===l)return d.row;const c=o?{key:"event.lostHistory"}:r(e,i),m={id:y(e),timestamp:a(e.data.observed_at,t),iso:e.data.observed_at,kind:e.event,kindText:s(n,e.event,i),summary:i(c.key,c.params),help:P(e,i),links:q(e,i,l),event:e};return F.set(e,{locale:t,resources:l,row:m}),m}(e,d,c,p(e),v)),kinds:[{id:"without-runtime",label:c("event.withoutRuntime")},{id:"all",label:c("event.allKinds")},...m.map(e=>({id:e,label:s(n,e,c)}))],status:u&&!1!==o?{tone:"err",text:c("event.disconnected")}:{tone:i?"ok":null===o?"muted":"warn",text:c(!1===o?"event.unavailable":i?"event.connected":null===o?"ui.loading":"event.reconnecting")},limitText:c("event.limit",{n:l}),shown:j}}function L(){const t=o(),s=l(),n=d[c()],r=m(),a=r.data?.resources,i=a?.events.kinds,[f,x]=e.useState("without-runtime"),b="all"!==f&&"runtime.updated"!==f&&i?.includes(f),g=T("without-runtime"!==f&&!b),w=e.useMemo(()=>J(g.events,f,g.connected,g.available,j,n,s,i??[],!!g.error,h,a),[g.events,f,g.connected,g.available,g.error,n,s,i,a]);return u(w.kind,x),{...w,setKind:x,cursor:g.cursor,error:g.error,retry:()=>{p().then(()=>v(t))},loading:!g.error&&!g.connected&&!1!==g.available&&!g.events.length,export:()=>{return W(H("doona-events","json"),(e=w.shown,JSON.stringify(e,null,2)+"\n"),"application/json");var e}}}function U(){const s=l(),n=L(),r=K(),a=e.useMemo(()=>[{id:"t",label:s("ui.time"),minWidth:212,grow:0,drop:1,render:e=>t.jsx(f,{className:"rp-code",text:e.iso,children:e.timestamp})},{id:"k",label:s("event.kind"),minWidth:224,drop:2,render:e=>t.jsx(f,{text:e.kind,children:e.kindText})},{id:"m",label:s("event.summary"),minWidth:176,isRowHeader:!0,render:e=>t.jsx(x,{fill:!0,help:e.help,children:t.jsx(f,{children:e.summary})})},{id:"actions",actions:!0,label:s("ui.actions"),hideLabel:!0,minWidth:64,grow:0,render:e=>t.jsx(b,{small:!0,quiet:!0,icon:!0,label:s("ui.copyRecord"),onPress:()=>{r((e=>JSON.stringify(e,null,2))(e.event))},children:t.jsx(O,{})})}],[s,r]),i=e.useCallback(e=>t.jsxs(t.Fragment,{children:[t.jsx(C,{inline:!0,items:[[s("ui.time"),e.timestamp],[s("event.kind"),e.kindText],[s("event.summary"),e.summary]]}),e.links.length>0&&t.jsx("div",{className:"rp-cluster",children:e.links.map(e=>t.jsx(g,{appearance:"button",href:e.href,children:e.label},e.id))})]}),[s]);return t.jsxs("div",{className:"rp-page",children:[t.jsxs(w,{page:!0,children:[t.jsx(N,{label:s("event.kind"),side:!0,value:n.kind,onChange:n.setKind,items:n.kinds}),t.jsx(_,{small:!0,tone:n.status.tone,children:n.status.text}),n.cursor&&t.jsx(f,{text:n.cursor,children:t.jsx("span",{className:"rp-label",children:s("event.cursor")})}),t.jsx("span",{className:"rp-label",children:n.limitText}),t.jsx("span",{className:"rp-grow"}),t.jsxs(b,{isDisabled:!n.rows.length,onPress:n.export,children:[t.jsx(D,{}),s("event.export")]})]}),n.error&&t.jsx(k,{error:n.error,onRetry:n.retry}),t.jsx(S,{label:s("nav.events"),stream:!0,flow:!0,loading:n.loading,rows:n.rows,empty:s("event.empty"),cols:a,detail:i})]})}export{U as Events};
+import{r as e,j as t}from"./vendor-react-64fcanlc.js";import{Z as s,a8 as n,aa as r,a7 as a,h as i,af as o,u as l,at as d,as as c,r as m,cg as u,ah as p,ai as v,dV as h,dW as j,T as x,aD as f,B as g,c as b,co as w,E as k}from"./index-C06va4Yw.js";import{e as y,Q as T,K as C,p as N,L as W}from"./logs-BtAlqVqe.js";import{D as _}from"./Table-Cc5T3jJO.js";import{d as S,e as H}from"./files-Dt8K7QfP.js";import{j as R,D}from"./activity-BoXvjA12.js";import{u as K,C as O}from"./Copy-Dw2ag2LB.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./Select-hQ95uOjm.js";import"./ItemText-D6SGBgOi.js";import"./AppearanceControls-CEVO9-aR.js";import"./nodes-oXccX15o.js";import"./useGridSelectionCheckbox-inhSeUkV.js";import"./Virtualizer-9R4wsZhf.js";import"./Checkbox-CsFZSc5N.js";const M={buffer_overflow:["event.gap.overflow","event.gapHelp.overflow"],evicted:["event.gap.evicted","event.gapHelp.evicted"]};function V(e,t){const s="flow.gap"===e.event&&Object.hasOwn(M,e.data.reason)?M[e.data.reason]:void 0;return s&&{title:t(s[0]),text:t(s[1])}}function F(e,t,s){const n=e=>e?[{id:"flow",label:t("event.viewFlow"),href:i("flows",{tab:"records",id:e})}]:[];switch(e.event){case"flow.updated":return n(e.data.resource_id);case"flow.gap":return[...n(e.data.resource_id),...s?.runtime_settings.available?[{id:"recording",label:t("ui.recordingSettings"),href:R}]:[]];case"generation.changed":return s?.config.available?[{id:"config",label:t("event.viewConfig"),href:i("config")}]:[];default:return[]}}const J=new WeakMap;function L(e,t,i,o,l,d,c,m,u=!1,p=()=>!1,v){const h="without-runtime"===t||m.includes(t)?t:"all",j=e.filter(e=>"all"===h||("without-runtime"===h?"runtime.updated"!==e.event:e.event===h)).slice(0,l);return{kind:h,rows:j.map(e=>function(e,t,i,o,l){const d=J.get(e);if(d&&d.locale===t&&d.resources===l)return d.row;const c=o?{key:"event.lostHistory"}:r(e,i),m={id:y(e),timestamp:a(e.data.observed_at,t),iso:e.data.observed_at,kind:e.event,kindText:s(n,e.event,i),summary:i(c.key,c.params),help:V(e,i),links:F(e,i,l),event:e};return J.set(e,{locale:t,resources:l,row:m}),m}(e,d,c,p(e),v)),kinds:[{id:"without-runtime",label:c("event.withoutRuntime")},{id:"all",label:c("event.allKinds")},...m.map(e=>({id:e,label:s(n,e,c)}))],status:u&&!1!==o?{tone:"err",text:c("event.disconnected")}:{tone:i?"ok":null===o?"muted":"warn",text:c(!1===o?"event.unavailable":i?"event.connected":null===o?"ui.loading":"event.reconnecting")},limitText:c("event.limit",{n:l}),shown:j}}function P(){const t=o(),s=l(),n=d[c()],r=m(),a=r.data?.resources,i=a?.events.kinds,[x,f]=e.useState("without-runtime"),g="all"!==x&&"runtime.updated"!==x&&i?.includes(x),b=T("without-runtime"!==x&&!g),w=e.useMemo(()=>L(b.events,x,b.connected,b.available,j,n,s,i??[],!!b.error,h,a),[b.events,x,b.connected,b.available,b.error,n,s,i,a]);return u(w.kind,f),{...w,setKind:f,cursor:b.cursor,error:b.error,retry:()=>{p().then(()=>v(t))},loading:!b.error&&!b.connected&&!1!==b.available&&!b.events.length,export:()=>{return S(H("doona-events","json"),(e=w.shown,JSON.stringify(e,null,2)+"\n"),"application/json");var e}}}function q(){const s=l(),n=P(),r=K(),a=e.useMemo(()=>[{id:"t",label:s("ui.time"),minWidth:212,grow:0,drop:1,render:e=>t.jsx(x,{className:"rp-code",text:e.iso,children:e.timestamp})},{id:"k",label:s("event.kind"),minWidth:224,drop:2,render:e=>t.jsx(x,{text:e.kind,children:e.kindText})},{id:"m",label:s("event.summary"),minWidth:176,isRowHeader:!0,render:e=>t.jsx(f,{fill:!0,help:e.help,children:t.jsx(x,{children:e.summary})})},{id:"actions",actions:!0,label:s("ui.actions"),hideLabel:!0,minWidth:64,grow:0,render:e=>t.jsx(g,{small:!0,quiet:!0,icon:!0,label:s("ui.copyRecord"),onPress:()=>{r((e=>JSON.stringify(e,null,2))(e.event))},children:t.jsx(O,{})})}],[s,r]),i=e.useCallback(e=>t.jsxs(t.Fragment,{children:[t.jsx(C,{inline:!0,items:[[s("ui.time"),e.timestamp],[s("event.kind"),e.kindText],[s("event.summary"),e.summary]]}),e.links.length>0&&t.jsx("div",{className:"rp-cluster",children:e.links.map(e=>t.jsx(b,{appearance:"button",href:e.href,children:e.label},e.id))})]}),[s]);return t.jsxs("div",{className:"rp-page",children:[t.jsxs(w,{page:!0,children:[t.jsx(N,{label:s("event.kind"),side:!0,value:n.kind,onChange:n.setKind,items:n.kinds}),t.jsx(W,{small:!0,tone:n.status.tone,children:n.status.text}),n.cursor&&t.jsx(x,{text:n.cursor,children:t.jsx("span",{className:"rp-label",children:s("event.cursor")})}),t.jsx("span",{className:"rp-label",children:n.limitText}),t.jsx("span",{className:"rp-grow"}),t.jsxs(g,{isDisabled:!n.rows.length,onPress:n.export,children:[t.jsx(D,{}),s("event.export")]})]}),n.error&&t.jsx(k,{error:n.error,onRetry:n.retry}),t.jsx(_,{label:s("nav.events"),stream:!0,flow:!0,loading:n.loading,rows:n.rows,empty:s("event.empty"),cols:a,detail:i})]})}export{q as Events};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/FlagPicker-9QJIrYuT.js b/luci-app-honk/root/etc/honk/doona/assets/FlagPicker-9QJIrYuT.js
new file mode 100644
index 000000000..f87ac992a
--- /dev/null
+++ b/luci-app-honk/root/etc/honk/doona/assets/FlagPicker-9QJIrYuT.js
@@ -0,0 +1 @@
+import{r as e,j as a}from"./vendor-react-64fcanlc.js";import{u as s,as as t,cO as l,at as o,dJ as i,ba as n,B as r}from"./index-C06va4Yw.js";import{S as c}from"./SearchSelect-q5tbOYXk.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./Select-hQ95uOjm.js";import"./ItemText-D6SGBgOi.js";import"./SearchList-LS4kpJXT.js";import"./Virtualizer-9R4wsZhf.js";function m({name:n,value:r,automaticFlag:m,onChange:d}){const f=s(),g=t(),p=e.useMemo(()=>l(o[g]),[g]),j=i(n),u=p.find(e=>e.flag===m),h=u?f("flags.detected",{region:u.label}):f("flags.automatic");return a.jsx("div",{className:"rp-list",children:a.jsx(c,{label:f("flags.region"),description:f(j?"flags.embedded":"flags.help"),isDisabled:j,searchLabel:f("flags.search"),value:j?"automatic":r,onChange:d,sections:[{id:"flags",items:[{id:"automatic",label:h,flag:m},{id:"none",label:f("flags.none"),flag:null},...p]}]})})}function d({name:e,onClose:t,...l}){const o=s();return a.jsxs(n,{narrow:!0,title:o("flags.edit"),isOpen:!0,onOpenChange:e=>{e||t()},footer:()=>a.jsx(r,{onPress:t,children:o("ui.close")}),children:[a.jsx("p",{className:"rp-note",children:e}),a.jsx(m,{name:e,...l})]})}export{m as FlagField,d as FlagPicker};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/FlagPicker-BI-GnHgk.js b/luci-app-honk/root/etc/honk/doona/assets/FlagPicker-BI-GnHgk.js
deleted file mode 100644
index 674a8b2fc..000000000
--- a/luci-app-honk/root/etc/honk/doona/assets/FlagPicker-BI-GnHgk.js
+++ /dev/null
@@ -1 +0,0 @@
-import{r as e,j as s}from"./vendor-react-64fcanlc.js";import{u as a,as as t,cN as l,at as o,dH as i,b9 as n,B as r}from"./index-CUHkLMAp.js";import{S as c}from"./SearchSelect-Fy-2ASgN.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./Select-BA0NS1_z.js";import"./ItemText-CnEXu0-f.js";import"./SearchList-DMvmI1K7.js";import"./Virtualizer-UMC7L0o2.js";function m({name:n,value:r,automaticFlag:m,onChange:d}){const f=a(),g=t(),p=e.useMemo(()=>l(o[g]),[g]),j=i(n),u=p.find(e=>e.flag===m),h=u?f("flags.detected",{region:u.label}):f("flags.automatic");return s.jsx("div",{className:"rp-list",children:s.jsx(c,{label:f("flags.region"),description:f(j?"flags.embedded":"flags.help"),isDisabled:j,searchLabel:f("flags.search"),value:j?"automatic":r,onChange:d,sections:[{id:"flags",items:[{id:"automatic",label:h,flag:m},{id:"none",label:f("flags.none"),flag:null},...p]}]})})}function d({name:e,onClose:t,...l}){const o=a();return s.jsxs(n,{narrow:!0,title:o("flags.edit"),isOpen:!0,onOpenChange:e=>{e||t()},footer:()=>s.jsx(r,{onPress:t,children:o("ui.close")}),children:[s.jsx("p",{className:"rp-note",children:e}),s.jsx(m,{name:e,...l})]})}export{m as FlagField,d as FlagPicker};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/Flows-sA9EQ0Nt.js b/luci-app-honk/root/etc/honk/doona/assets/Flows-CN4scPGP.js
similarity index 85%
rename from luci-app-honk/root/etc/honk/doona/assets/Flows-sA9EQ0Nt.js
rename to luci-app-honk/root/etc/honk/doona/assets/Flows-CN4scPGP.js
index b212d4411..9c9f47e84 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/Flows-sA9EQ0Nt.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/Flows-CN4scPGP.js
@@ -1 +1 @@
-import{r as e,j as t}from"./vendor-react-64fcanlc.js";import{N as n,O as a}from"./NodePath-BtHMV14P.js";import{l as o,q as s,B as r,c as l,g as i,K as d,R as u,S as c,p}from"./logs-C6Kb44nw.js";import{ac as m,W as f,a9 as g,Q as w,O as h,cp as b,ch as j,cj as x,w as v,c9 as y,Z as k,cb as _,cc as M,at as N,a7 as S,h as L,b3 as C,o as T,ae as P,a3 as R,u as F,as as O,j as H,B as q,N as E,bb as W,r as $,t as D,b7 as I,ce as A,b8 as B,cg as U,S as V,al as K,aN as Q,E as z,T as G,cn as J,aK as Z,c as X,bF as Y,C as ee}from"./index-CUHkLMAp.js";import{h as te,f as ne,i as ae,o as oe,j as se,r as re}from"./activity-B3PmJo_X.js";import{w as le}from"./labels-D8xxfRTQ.js";import{c as ie,C as de}from"./Coverage-BJRxyviT.js";import{T as ue}from"./Tabs-DiTlqyjA.js";import{s as ce,D as pe}from"./Table-DX856nrS.js";import{T as me}from"./TimeCell-N-r54xmV.js";import{a as fe,u as ge,b as we}from"./flows-DS-lcTPn.js";import{u as he}from"./outbounds-CUiHWeth.js";import{u as be,Q as je,R as xe}from"./useQuickRule-Cd5z6aFL.js";import{$ as ve}from"./GridList-CQPDUasC.js";import{$ as ye,a as ke}from"./Virtualizer-UMC7L0o2.js";import{C as _e}from"./CardView-N7n2PJ-s.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./Tag-4SaGY8GT.js";import"./Select-BA0NS1_z.js";import"./ItemText-CnEXu0-f.js";import"./AppearanceControls-E-VPhjIz.js";import"./nodes-BYMoo8M1.js";import"./useGridSelectionCheckbox-CTBMGgmQ.js";import"./Checkbox-8Iqnc6T1.js";import"./DaeCode-DEjXqvav.js";import"./daeTokens-BVtuNnWZ.js";import"./AddCircle-D2cMd6zF.js";import"./SearchSelect-Fy-2ASgN.js";import"./SearchList-DMvmI1K7.js";import"./BackendText-Dtw6qhij.js";import"./rule-D4-Og0AG.js";const Me=["client","rule","outbound","node"];function Ne(e,t){if(e.rule_id)return null!==e.rule_generation_id&&e.rule_generation_id===t?e.rule_id:e.rule_id+"\0"+e.rule_expression}function Se(e,t,n,a){switch(t){case"client":{const t=f(e.input?.src??void 0);return{label:t??"unknown",unknown:!t}}case"rule":return e.rule_expression?{label:e.rule_expression,unknown:!1,key:Ne(e,a)}:{label:"unknown",unknown:!0};case"outbound":return e.outbound?{label:e.outbound,unknown:!1}:{label:"unknown",unknown:!0};case"node":{if(m(e.outbound))return null;const t=e.chain.at(-1)??null;return t?{label:n.get(t)??t,unknown:!1,key:t}:{label:"unknown",unknown:!0}}}}const Le=(e,t)=>ne(e,t.unknown?"":t.key??t.label),Ce=e=>te(e,Me)?.kind,Te=new Map;function Pe(e,t,n){const a=Ce(t);return a?e.filter(e=>{const o=Se(e,a,Te,n?.generation_id);return null!==o&&Le(a,o)===t}):[]}function Re(e,t,n,a){const o=te(e,Me);if(!o||""===o.value)return a(null);const{kind:s,value:r}=o;return"rule"===s?r.includes("\0")?r.slice(r.indexOf("\0")+1):t.find(e=>e.rule_id===r)?.expression??r:"node"===s?n.get(r)??r:"client"===s?r:a(r)}function Fe(e,t,n,a,o="rule"){const s=(e=>new Map(e.map(e=>[e.id,e.name])))(n),r=new Map(t.map(e=>[e.id,e])),l=new Map(t.map(e=>[e.name,e])),i=new Map(n.map(e=>[e.id,e])),d=new Map,u=new Map,c=new Map,p=new Map,f=(e,t)=>{const n=e+">"+t;let a=p.get(n);return a||p.set(n,a={source:e,target:t,count:0}),a},b=(e,t,n=!1)=>{const a=Le("node",{key:e,label:t,unknown:n});let o=c.get(a);if(!o){const s=n?void 0:i.get(e),r=s&&w(s);c.set(a,o={id:a,label:t,count:0,unknown:n||void 0,latency:h(r),unavailable:"unavailable"===r?.state})}return o},j=(e,t=!1)=>{const n=Le("outbound",{label:e,unknown:t});let a=u.get(n);if(a)return a;const o=t?void 0:l.get(e),d=t?{groups:[],member:null}:g(e,o?.selection.tcp_member_id?"tcp":"udp",l,r,i),c=d.groups.map(e=>({name:e.name,kind:e.policy.kind,policy:e.policy.native})),p=d.member;return a={id:n,label:e,count:0,unknown:t||void 0,kind:t?"unknown":m(e)?e:c.length?"group":"unknown",groups:c,node:p&&b(p,s.get(p)??p).id},u.set(n,a),a.node&&f(n,a.node),a},x=(e,t,n=!1)=>{let a=d.get(e);return a||d.set(e,a={id:e,label:t,count:0,unknown:n||void 0,outbound:null,must:!1}),a};if("rule"===o)for(const m of a?.rules??[]){const e=x(Le("rule",{key:m.rule_id,label:m.expression}),m.expression);e.must=m.must,m.outbound&&(e.outbound=j(m.outbound).id,f(e.id,e.outbound))}const v=[o,"outbound","node"];for(const m of e){let e;for(const t of v){const n=Se(m,t,s,a?.generation_id);if(!n)break;const o="outbound"===t?j(n.label,n.unknown):"node"===t?b(n.key??n.label,n.label,n.unknown):x(Le(t,n),n.label,n.unknown);o.count++,e&&f(e.id,o.id).count++,e=o}}for(const m of t)j(m.name);const y=new Set([...d.values()].map(e=>e.outbound)),k=new Set([...u.values()].flatMap(e=>e.groups.slice(1).map(e=>e.name))),_=[...u.values()].filter(e=>e.count||y.has(e.id)||!k.has(e.label)),M=new Set(_.map(e=>e.id)),N=[...p.values()].filter(e=>M.has(e.source)||M.has(e.target)),S=new Set(N.map(e=>e.target));return{by:o,leaves:[...d.values()],outbounds:_,nodes:[...c.values()].filter(e=>S.has(e.id)),links:N}}const Oe=new WeakMap;function He(e){const t=Oe.get(e);if(t)return t;const n=new Map,a=new Map,o=new Map;for(const l of e.links){for(const[e,t]of[[n,l.source],[a,l.target]]){let n=e.get(t);n||e.set(t,n=[]),n.push(l)}(!o.has(l.source)||o.get(l.source).countnull==e?"—":{key:e?"ui.yes":"ui.no"},$e=e=>e?[["ui.error",e]]:[];function De(e,t,n,a,o,s){return{tree:e,state:t?e.leaves.length||e.outbounds.length?"ready":"empty":n?"error":"loading",pinLabel:a?s("flow.viewPinned",{n:o}):null}}const Ie={input:"flow.stage.input",route:"flow.stage.route",dial_mode:"flow.stage.dialMode",dns:"nav.dns",outbound:"ui.outbound",connection:"flow.stage.connection",datapath:"ov.datapath",reroute:"flow.stage.reroute"},Ae={complete:"flow.status.complete",partial:"flow.status.partial",disabled:"flow.status.disabled"};function Be(e,t,n,a){if(!e)return null;const o=N[n];return{title:e.input.domain||e.input.dst||e.id,status:k(Ae,e.trace.status,t),tone:"complete"===e.trace.status?void 0:"warn",revision:t("flow.revision",{n:e.revision}),fields:[[t("ui.state"),k(y,e.state,t)],...a?[[t("nodes.node"),a.path??a.node]]:[],...a?.expression?[[t("ui.rule"),a.expression]]:[],...e.trace.missing.length?[[t("flow.missing"),C(n,e.trace.missing.map(e=>k(qe,e,t)))]]:[]],connectionHref:e.connection_id?L("connections",{id:e.connection_id}):null,steps:[...e.trace.steps].sort((e,t)=>e.seq-t.seq).map(e=>{const n=function(e){const t=e=>null==e?"—":"object"==typeof e?JSON.stringify(e):String(e);switch(e.stage){case"input":return Object.entries(e.data.values).filter(([,e])=>null!=e&&""!==e).map(([e,n])=>{const a=Ee[e];return[void 0!==a&&a.includes(".")?a:{key:"flow.f.input",params:{name:a??e}},"string"!=typeof n||"ingress"!==e&&"domain_source"!==e?t(n):le(n)]});case"route":return[["conn.chain",e.data.chain],["flow.f.plane",le(e.data.plane)],["ui.rule",e.data.rules.filter(e=>"matched"===e.result).map(e=>e.expression??e.rule_id).join(", ")||"—"],["ui.outbound",t(e.data.outbound)],["flow.f.must",We(e.data.must)]];case"dial_mode":return[["flow.f.dialTarget",e.data.configured+" → "+e.data.effective_target],["flow.f.verification",le(e.data.verification)]];case"dns":return[["ui.name",e.data.name],["rule.dns.kind.qtype",e.data.qtype],["ui.source",le(e.data.source)],["ui.cache",le(e.data.cache)],["ui.upstream",t(e.data.upstream)],["flow.f.selectedIp",t(e.data.selected_ip)],["ui.state",e.data.status],...$e(e.data.error)];case"outbound":return[["ui.outbound",t(e.data.routed_outbound)+" → "+t(e.data.effective_outbound)],["flow.f.selectionPath",e.data.selection_path.map(e=>e.group_id+" → "+t(e.member_name??e.member_id)).join(" / ")||"—"],["flow.f.leafNode",t(e.data.leaf_node_id)],["ui.target",t(e.data.target)],["ui.state",le(e.data.status)],...$e(e.data.error)];case"connection":return[["ui.state",Object.hasOwn(y,e.data.state)?{key:y[e.data.state]}:e.data.state],["flow.f.milestone",le(e.data.milestone)],["flow.f.reason",le(e.data.reason)],...$e(e.data.error)];case"datapath":return[["flow.f.plane",le(e.data.plane)],["flow.f.action",le(e.data.action)],["flow.f.reason",le(e.data.reason)],...$e(e.data.error)];case"reroute":return[["flow.f.performed",We(e.data.performed)],["flow.f.reason",le(e.data.reason)]];default:return null}}(e);return{id:e.seq,stage:k(Ie,e.stage,t),observed:S(e.observed_at,o),elapsed:null==e.elapsed_us?"—":t("ui.microseconds",{n:e.elapsed_us}),fields:n?.map(([e,n])=>["string"==typeof e?t(e):t(e.key,e.params),"string"==typeof n?n:t(n.key,n.params)])??null,raw:n?"":JSON.stringify(e.data,null,2)}})}}const Ue=30,Ve=[5,4,3],Ke={rule:0,client:0,outbound:1,node:2};function Qe(e,t,n,a){const s=null===t?void 0:Math.max(t,720),r=((s??0)-112)/Ve.reduce((e,t)=>e+t),l=e=>{const t=Ke[e];return{left:Ve.slice(0,t).reduce((e,t)=>e+t*r+56,0),width:Ve[t]*r}},i=function(e){const t=new Map;let n=0;const a=new Map,{parents:o}=He(e);for(const l of[...e.leaves,...e.outbounds]){const e=o.get(l.id);if(e){let t=a.get(e);t||a.set(e,t=[]),t.push(l.id)}}const s=e=>{const o=a.get(e)??[];if(o.length){for(const e of o)s(e);t.set(e,(t.get(o[0])+t.get(o[o.length-1]))/2)}else t.set(e,n++)},r=new Set;for(const l of e.outbounds)r.add(o.get(l.id)??l.id);for(const l of e.nodes)r.add(l.id);for(const l of e.leaves)o.has(l.id)||r.add(l.id);for(const l of r)s(l);return{rows:n,at:t}}(e),d=function(e,t,n){const a=(e,n)=>e.unknown?t("ui.unknown"):n,s=[...e.leaves.map(t=>({id:t.id,stage:e.by,name:a(t,t.label),badge:t.must?"must":void 0,notes:[],count:t.count})),...e.outbounds.map(e=>({id:e.id,stage:"outbound",name:a(e,T(e.label,t)),notes:[...e.groups.slice(1).map(e=>({text:"› "+e.name})),...e.groups.slice(-1).map(e=>({text:ae({kind:e.kind,native:e.policy},t).label})),..."group"!==e.kind||e.node?[]:[{text:t("flow.treeNoNode")}]],count:e.count})),...e.nodes.map(e=>({id:e.id,stage:"node",name:a(e,e.label),notes:null!=e.latency?[{text:P(e.latency,t),tone:o(e.latency)}]:e.unavailable?[{text:t("ui.unavailable"),tone:"err"}]:[],count:e.count}))],r=new Map(s.map(e=>[e.id,e.name])),{outgoing:l,incoming:i}=He(e);return s.map(e=>{const a=(l.get(e.id)??[]).map(e=>r.get(e.target)),o="node"===e.stage?(i.get(e.id)??[]).map(e=>r.get(e.source)):[],s=[e.name,...e.badge?[e.badge]:[],...e.notes.map(e=>e.text),t("flow.treeFlows",{n:e.count})];return o.length&&s.push(t("flow.treeFrom",{names:C(n,o)})),a.length&&s.push(t("flow.treeTo",{names:C(n,a)})),{...e,countText:R(e.count,N[n]),label:s.join(t("ui.separator"))}})}(e,n,a).map(e=>({view:e,style:{top:44*i.at.get(e.id),...l(e.stage)}})),u=new Map(e.outbounds.map(e=>[e.id,e])),c=e.links.flatMap(t=>{if(!i.at.has(t.source)||!i.at.has(t.target))return[];const n="outbound"===Ce(t.source)?"outbound":e.by,a=l(n),o=a.left+a.width,s=l("outbound"===n?"node":"outbound").left,r=44*i.at.get(t.source)+18,d=44*i.at.get(t.target)+18,c=(o+s)/2;return[{link:t,id:t.source+">"+t.target,path:`M${o},${r} C${c},${r} ${c},${d} ${s},${d}`,width:Math.min(8,1.5+1.25*Math.log2(1+t.count)),dash:t.count?void 0:"4 4",kind:"outbound"===n?"node":u.get(t.target)?.kind??"group"}]});return{width:s,height:44*i.rows-8,captions:[{stage:e.by,label:n("rule"===e.by?"ui.rule":"ui.device"),style:l(e.by)},{stage:"outbound",label:n("ui.outbound"),style:l("outbound")},{stage:"node",label:n("nodes.node"),style:l("node")}],placed:d,geometry:c}}function ze(t,n,a){const o=F(),s=O(),[r,l]=e.useState(Ue),[i,d]=e.useState(null),[u,c]=H(),p=e.useMemo(()=>He(t),[t]),m=e.useMemo(()=>function(e,t){return e.leaves.length<=t?e:{...e,leaves:e.leaves.slice(0,t)}}(t,r),[t,r]),f=e.useMemo(()=>Qe(m,c,o,s),[m,c,o,s]),g=e.useMemo(()=>new Set(f.placed.map(e=>e.view.id)),[f.placed]),w=e.useMemo(()=>new Set([...t.leaves,...t.outbounds,...t.nodes].map(e=>e.id)),[t]),h=i&&g.has(i)?i:n&&w.has(n)?n:null,b=e.useMemo(()=>h?function(e,t){const n=new Set([t]),a=new Set;for(const[o,s]of[[e.outgoing,"target"],[e.incoming,"source"]]){const e=[t];for(const t of e)for(const r of o.get(t)??[])a.has(r)||(a.add(r),n.has(r[s])||(n.add(r[s]),e.push(r[s])))}return{items:n,edges:a}}(p,h):null,[p,h]);e.useEffect(()=>{if(!n)return;const e=e=>{"Escape"===e.key&&a(null)};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[n,a]);const j=e.useRef(n);e.useLayoutEffect(()=>{j.current=n},[n]);const x=e.useCallback(e=>a(j.current===e?null:e),[a]);return{...f,ref:u,ready:void 0!==f.width,active:b,pinned:n,pin:x,hover:d,more:t.leaves.length>r?o("flow.treeShowMore",{n:Math.min(Ue,t.leaves.length-r)}):null,fewer:r>Ue?o("flow.treeFewer",{n:Ue}):null,showMore:()=>l(e=>Math.min(t.leaves.length,e+Ue)),showFewer:()=>l(Ue)}}const Ge=e.memo(function({view:e,style:n,dim:a,selected:o,pin:l,hover:i}){return t.jsxs(s,{"aria-label":e.label,className:W("rp-tree-tile",a&&"dim"),"data-id":e.id,"data-stage":e.stage,style:n,isSelected:o,onChange:()=>l(e.id),onHoverStart:()=>i(e.id),onHoverEnd:()=>i(null),onFocus:()=>i(e.id),onBlur:()=>i(null),children:[t.jsxs("span",{className:"l",children:["node"===e.stage?t.jsx("b",{children:t.jsx(E,{name:e.name})}):"rule"===e.stage||"client"===e.stage?e.name:t.jsx("b",{children:e.name}),e.notes.map((e,n)=>t.jsx("span",{className:W("s",e.tone),children:e.text},n))]}),e.badge&&t.jsx(r,{children:e.badge}),t.jsx("span",{className:"c",children:e.countText})]})});function Je({tree:e,pinned:n,onPin:a}){const{ref:o,...s}=ze(e,n,a);return t.jsxs("div",{className:"rp-tree",ref:o,children:[t.jsx("div",{className:"rp-tree-captions",style:{width:s.width},children:s.captions.map(e=>t.jsx("span",{className:"rp-label",style:e.style,children:e.label},e.stage))}),t.jsxs("div",{className:"rp-tree-canvas",style:{height:s.height,width:s.width},children:[s.ready&&t.jsx("svg",{className:"rp-tree-links",width:s.width,height:s.height,"aria-hidden":!0,children:s.geometry.map(e=>t.jsx("path",{d:e.path,strokeWidth:e.width,"data-kind":e.kind,"data-state":s.active?s.active.edges.has(e.link)?"active":"dim":void 0,strokeDasharray:e.dash},e.id))}),s.ready&&s.placed.map(({view:e,style:n})=>t.jsx(Ge,{view:e,style:n,dim:!!s.active&&!s.active.items.has(e.id),selected:s.pinned===e.id,pin:s.pin,hover:s.hover},e.id))]}),s.more&&t.jsx(q,{small:!0,quiet:!0,onPress:s.showMore,children:s.more}),s.fewer&&t.jsx(q,{small:!0,quiet:!0,onPress:s.showFewer,children:s.fewer})]})}function Ze({go:t,query:n}){const a=F(),o=O(),s=I(A),r=I(B),i=e.useMemo(()=>new URLSearchParams(n),[n]),d=i.get("network"),u="tcp"===d||"udp"===d?d:"all",c=i.get("state")??"",p=Object.hasOwn(y,c)?c:"all",g=i.get("connection_id")??void 0,w=$().data?.resources,h=fe({connection_id:g,network:u,state:p},D(w,"flows",{whileLoading:!0})),b=D(w,"rules",{whileLoading:!1}),j=ge(b),x=he(),N=i.get("id"),S=we(N),L=i.get("path"),C=e.useMemo(()=>{const e=h.data?.flows??[];return L?Pe(e,L,j.data):e},[h.data,L,j.data]),P=j.data?.generation_id,R=e.useMemo(()=>function(e,t,n,a,o,s){return{rows:e.map(e=>({id:e.id,target:e.input?.domain||e.input?.dst||e.id,node:M(e,o,a),nodeName:!m(e.outbound)&&e.chain.length>0,path:_(e,o,a),expression:e.rule_expression,ruleId:null!==e.rule_generation_id&&e.rule_generation_id===n?e.rule_id:null,recomputed:"recomputed"===e.rule_source,network:e.network.toUpperCase(),state:k(y,e.state,o),startedAt:e.started_at,seed:{domain:e.input?.domain??null,dip:f(e.input?.dst??void 0)??null,sip:f(e.input?.src??void 0)??null,outbound:e.outbound,matched:e.rule_id&&"unknown"!==e.rule_source?{id:e.rule_id,expression:e.rule_expression,generation:e.rule_generation_id}:null}})),coverage:t?ie(t,o,s):null,stateOptions:[{id:"all",label:o("flow.allStates")},...Object.entries(y).map(([e,t])=>({id:e,label:o(t)}))]}}(C,h.data,P,x,a,o),[C,h.data,P,x,a,o]),H=R.rows.find(e=>e.id===N),q=l(D(w,"groups",{whileLoading:!1})).data,E=e.useMemo(()=>{const e=Be(S.data??void 0,a,o,H);return e&&{...e,outboundTag:oe(S.data.outbound,q,a)}},[S.data,a,o,H,q]),W=be(t);return{...R,detail:E,rule:{canAdd:W.canAdd,open:W.open,label:e=>a("conn.addRuleFor",{target:e}),noTarget:a("flow.ruleNoTarget"),dialog:W.dialog},network:u,setNetwork:e=>t("flows",v(n,{network:"all"===e?null:e})),state:p,setState:e=>t("flows",v(n,{state:"all"===e?null:e})),wide:s,phone:r,id:N,rulesListed:b,error:h.error,retry:h.refetch,loading:h.loading&&!h.data,panelOpen:!!N&&(!!S.data||S.loading||!!S.error),panelTitle:E?.title??N??"",detailError:S.error,detailRetry:S.refetch,detailLoading:!S.data&&S.loading,select:e=>t("flows",v(n,{id:e}),{replace:null!==N}),pinLabel:L?a("flow.mapFilter",{label:Re(L,j.data?.rules??[],x,e=>null===e?a("ui.unknown"):T(e,a))}):null,clearPin:()=>t("flows",v(n,{path:null})),connectionLabel:g?a("flow.connectionFilter",{connectionId:g}):null,clearConnection:()=>t("flows",v(n,{connection_id:null})),recordingHref:w?.runtime_settings.available?se:null}}function Xe({go:e,query:t}){const n=F(),a=$(),o=function(e,t,n){const a=b(e).map(e=>({id:e.id,label:n(e.titleKey)})),o=a[0]?.id??"map";return{tabs:a,tab:j(t,a.map(e=>e.id),o),fallback:e?o:null}}(a.data?.resources,t,n);return U(a.data?.resources),{...o,loading:a.loading&&!a.data,error:a.error,retry:a.refetch,changeTab:n=>e("flows",function(e,t,n){return x(v(e,"map"===t?{id:null,connection_id:null}:{by:null}),t,n)}(t,n,o.fallback))}}function Ye({label:n,cols:a,rows:o,getTextValue:s,height:r=442,selected:l,onSelect:i,loading:d,empty:u}){const c=F(),p=e.useMemo(()=>l?new Set([l]):new Set,[l]);return d&&!o.length?t.jsx(V,{shape:"cards",count:2,height:196}):t.jsx(ye,{layout:ke,layoutOptions:{estimatedRowSize:196,gap:8},children:t.jsx(ve,{className:"rp-table-cards","aria-label":n,items:o,dependencies:[a],style:{maxHeight:r},selectionMode:i?"single":"none",selectionBehavior:"toggle",selectedKeys:p,onSelectionChange:e=>i?.(ce(e)),renderEmptyState:()=>t.jsx(K,{children:u??c("ui.empty")}),children:e=>t.jsx(et,{row:e,cols:a,title:s(e)})})})}function et({row:e,cols:n,title:a}){const o=n.find(e=>e.isRowHeader)??n[0],s=n.find(e=>e.actions),r=n.filter(e=>e!==o&&e!==s);return t.jsx(_e,{id:e.id,title:a,actions:s?.render(e),children:t.jsx(d,{items:r.map(t=>({label:t.label,value:t.render(e),wide:t.wide}))})})}function tt(e){const n=F(),a=Xe(e),o={map:t.jsx(nt,{...e}),records:t.jsx(at,{...e})};return a.loading?t.jsx(Q,{}):a.error?t.jsx(z,{error:a.error,onRetry:a.retry}):t.jsx("div",{className:"rp-page",children:t.jsx(ue,{page:!0,label:n("nav.flows"),items:a.tabs.map(e=>({...e,content:o[e.id]})),value:a.tab,onChange:a.changeTab})})}function nt(n){const a=F(),o=function({go:t,query:n}){const a=F(),o=new URLSearchParams(n),s=$().data?.resources,r=fe({},D(s,"flows",{whileLoading:!0})),d=l(D(s,"groups",{whileLoading:!1})),u=i(D(s,"nodes",{whileLoading:!1})),c=ge(D(s,"rules",{whileLoading:!1})),p="client"===o.get("by")?"client":"rule",m=e.useMemo(()=>Fe(r.data?.flows??[],d.data??[],u.data??[],c.data,p),[r.data,d.data,u.data,c.data,p]),f=o.get("path"),g=e.useRef(n);e.useLayoutEffect(()=>{g.current=n},[n]);const w=e.useCallback(e=>t("flows",v(g.current,{path:e})),[t]),h=e.useMemo(()=>f?Pe(r.data?.flows??[],f,c.data).length:0,[r.data,f,c.data]);return{...De(m,[r,c,d,u].every(e=>void 0!==e.data||e.error||!e.loading)&&!!(r.data||c.data||d.data),!!r.error,f,h,a),by:p,pinned:f,error:r.error??d.error??u.error??c.error,retry:()=>{r.refetch(),d.refetch(),u.refetch(),c.refetch()},pin:w,changeBy:e=>t("flows",v(n,{by:"client"===e?"client":null,path:null})),viewPinned:()=>t("flows",v(n,{tab:"records"}))}}(n);return t.jsxs("section",{className:"rp-col","aria-label":a("flow.map"),children:[t.jsxs(J,{page:!0,children:[o.pinLabel?t.jsx(q,{onPress:o.viewPinned,children:o.pinLabel}):t.jsx("span",{className:"rp-label",children:a("flow.mapFilterHint")}),t.jsx("span",{className:"rp-grow"}),t.jsx(q,{quiet:!0,isDisabled:!o.pinLabel,onPress:()=>o.pin(null),children:a("flow.clearMapFilter")})]}),t.jsx(z,{error:o.error,onRetry:o.retry}),t.jsxs(ee,{title:a("flow.topology"),note:a("flow.topologyNote"),className:"rp-topology",aside:t.jsx(c,{label:a("flow.topology"),value:o.by,onChange:o.changeBy,items:[["rule",a("flow.byRule")],["client",a("conn.byClient")]]}),children:["loading"===o.state&&t.jsx(V,{shape:"block",height:480,typical:!0}),"empty"===o.state&&t.jsx(K,{children:a("flow.mapEmpty")}),"ready"===o.state&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"rp-tree-hint",children:a("flow.treePanHint")}),t.jsx(Je,{tree:o.tree,pinned:o.pinned,onPin:o.pin})]})]})]})}function at(o){const s=F(),l=Ze(o),i=l.detail,m=e.useRef(l.rule);e.useLayoutEffect(()=>{m.current=l.rule});const f=e.useMemo(()=>[{id:"target",label:s("ui.target"),minWidth:128,grow:2,isRowHeader:!0,render:e=>t.jsx(G,{children:e.target})},{id:"node",label:s("nodes.node"),minWidth:96,drop:2,wide:!0,render:e=>t.jsx(n,{row:e})},{id:"rule",label:s("ui.rule"),minWidth:152,grow:3,drop:1,text:"wrap",wide:!0,render:e=>t.jsxs("span",{className:"rp-rule",children:[t.jsx(u,{expression:e.expression,href:re(e.ruleId,l.rulesListed)}),e.recomputed&&t.jsx(r,{tip:s("rule.sourceHelp.recomputed"),children:s("conn.recomputed")})]})},{id:"network",label:s("ui.protocol"),minWidth:96,grow:0,drop:3,render:e=>e.network},{id:"state",label:s("ui.state"),minWidth:112,grow:0,drop:5,render:e=>e.state},{id:"started",label:s("ui.started"),minWidth:140,grow:0,drop:4,render:e=>t.jsx(me,{at:e.startedAt})},{id:"actions",actions:!0,label:s("ui.actions"),minWidth:88,grow:0,render:e=>{const n=m.current,a=!n.canAdd(e.seed);return t.jsx(je,{label:n.label(e.target),disabled:a,tip:n.noTarget,onPress:()=>m.current.open(e.seed)})}}],[s,l.rulesListed]);return t.jsxs(t.Fragment,{children:[t.jsx(z,{error:l.error,onRetry:l.retry}),t.jsxs(J,{page:!0,children:[t.jsx(c,{label:s("ui.network"),value:l.network,onChange:l.setNetwork,items:[["all",s("ui.all")],["tcp",s("ui.tcp")],["udp",s("ui.udp")]]}),t.jsx(p,{label:s("ui.state"),side:!0,value:l.state,onChange:l.setState,items:l.stateOptions}),l.pinLabel&&t.jsxs(q,{label:s("ui.valuePair",{label:s("flow.clearMapFilter"),value:l.pinLabel}),onPress:l.clearPin,children:[l.pinLabel,t.jsx(Z,{})]}),l.connectionLabel&&t.jsxs(q,{label:s("ui.valuePair",{label:s("flow.clearConnectionFilter"),value:l.connectionLabel}),onPress:l.clearConnection,children:[l.connectionLabel,t.jsx(Z,{})]}),l.coverage&&t.jsx(de,{view:l.coverage}),l.recordingHref&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"rp-grow"}),t.jsx(X,{appearance:"button",quiet:!0,href:l.recordingHref,children:s("ui.recordingSettings")})]})]}),t.jsxs("div",{className:"rp-with-panel","data-open":l.panelOpen?"":void 0,children:[l.phone?t.jsx(Ye,{label:s("flow.records"),loading:l.loading,rows:l.rows,getTextValue:e=>e.target,selected:l.id,onSelect:l.select,empty:s("flow.empty"),cols:f}):t.jsx(pe,{label:s("flow.records"),rowDetail:!0,loading:l.loading,rows:l.rows,height:442,selected:l.id,onSelect:l.select,selectOnFocus:l.wide,empty:s("flow.empty"),cols:f}),t.jsxs(Y,{open:l.panelOpen,title:l.panelTitle,onClose:()=>l.select(null),children:[t.jsx(z,{error:l.detailError,onRetry:l.detailRetry}),l.detailLoading&&t.jsx(V,{shape:"rows",count:4,label:s("flow.detailLoading")}),i&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"rp-cluster",children:[t.jsx(r,{tone:i.tone,children:i.status}),t.jsx("span",{className:"rp-label",children:i.revision})]}),t.jsx(d,{inline:!0,items:[[s("ui.outbound"),t.jsx(a,{...i.outboundTag})],...i.fields]}),t.jsx("div",{className:"rp-cluster",children:i.connectionHref&&t.jsx(X,{appearance:"button",href:i.connectionHref,children:s("flow.viewConnection")})}),t.jsxs("div",{className:"rp-list",children:[!i.steps.length&&t.jsx(K,{children:s("ui.empty")}),i.steps.map(e=>t.jsxs("div",{className:"rp-col rp-step",children:[t.jsxs("div",{className:"rp-cluster",children:[t.jsx(r,{children:e.stage}),t.jsx(G,{text:e.observed,className:"rp-label",children:e.elapsed})]}),e.fields?t.jsx(d,{inline:!0,items:e.fields}):t.jsx("pre",{className:"rp-flow-raw rp-code",children:t.jsx("code",{children:e.raw})})]},e.id))]})]})]})]}),t.jsx(xe,{dialog:l.rule.dialog})]})}export{tt as Flows};
+import{r as e,j as t}from"./vendor-react-64fcanlc.js";import{N as n,O as a}from"./NodePath-DbG_-_A4.js";import{l as o,q as s,B as r,c as l,g as i,K as d,R as u,S as c,p}from"./logs-BtAlqVqe.js";import{ac as m,W as f,a9 as g,Q as w,O as h,cq as b,ci as j,ck as x,w as v,ca as y,Z as k,cc as _,cd as M,at as N,a7 as S,h as L,b3 as C,o as T,ae as P,a3 as O,u as R,as as F,j as H,B as q,N as E,bc as W,r as $,t as D,b8 as I,cf as A,b9 as B,ch as U,S as V,al as K,aN as G,E as Q,T as z,co as J,aK as Z,c as X,bG as Y,C as ee}from"./index-C06va4Yw.js";import{h as te,f as ne,i as ae,o as oe,j as se,r as re}from"./activity-BoXvjA12.js";import{w as le}from"./labels-D8xxfRTQ.js";import{c as ie,C as de}from"./Coverage-CsDZglAg.js";import{T as ue}from"./Tabs-PDr10lJU.js";import{s as ce,D as pe}from"./Table-Cc5T3jJO.js";import{T as me}from"./TimeCell-DSeESBN3.js";import{a as fe,u as ge,b as we}from"./flows-C0jcpIhs.js";import{u as he}from"./outbounds-ynHeqeCa.js";import{u as be,Q as je,R as xe}from"./useQuickRule-CCpuINzQ.js";import{$ as ve}from"./GridList-Dgo5IXUg.js";import{$ as ye,a as ke}from"./Virtualizer-9R4wsZhf.js";import{C as _e}from"./CardView-jh7SJ_si.js";import"./_commonjsHelpers-CXUWDbkB.js";import"./Tag-D4suq1U_.js";import"./Select-hQ95uOjm.js";import"./ItemText-D6SGBgOi.js";import"./AppearanceControls-CEVO9-aR.js";import"./nodes-oXccX15o.js";import"./useGridSelectionCheckbox-inhSeUkV.js";import"./Checkbox-CsFZSc5N.js";import"./DaeCode-DEjXqvav.js";import"./daeTokens-BVtuNnWZ.js";import"./AddCircle-6b-rL1eo.js";import"./SearchSelect-q5tbOYXk.js";import"./SearchList-LS4kpJXT.js";import"./BackendText-DK5RWFKi.js";import"./rule-C_M_c6EN.js";const Me=["client","rule","outbound","node"];function Ne(e,t){if(e.rule_id)return null!==e.rule_generation_id&&e.rule_generation_id===t?e.rule_id:e.rule_id+"\0"+e.rule_expression}function Se(e,t,n,a){switch(t){case"client":{const t=f(e.input?.src??void 0);return{label:t??"unknown",unknown:!t}}case"rule":return e.rule_expression?{label:e.rule_expression,unknown:!1,key:Ne(e,a)}:{label:"unknown",unknown:!0};case"outbound":return e.outbound?{label:e.outbound,unknown:!1}:{label:"unknown",unknown:!0};case"node":{if(m(e.outbound))return null;const t=e.chain.at(-1)??null;return t?{label:n.get(t)??t,unknown:!1,key:t}:{label:"unknown",unknown:!0}}}}const Le=(e,t)=>ne(e,t.unknown?"":t.key??t.label),Ce=e=>te(e,Me)?.kind,Te=new Map;function Pe(e,t,n){const a=Ce(t);return a?e.filter(e=>{const o=Se(e,a,Te,n?.generation_id);return null!==o&&Le(a,o)===t}):[]}function Oe(e,t,n,a){const o=te(e,Me);if(!o||""===o.value)return a(null);const{kind:s,value:r}=o;return"rule"===s?r.includes("\0")?r.slice(r.indexOf("\0")+1):t.find(e=>e.rule_id===r)?.expression??r:"node"===s?n.get(r)??r:"client"===s?r:a(r)}function Re(e,t,n,a,o="rule"){const s=(e=>new Map(e.map(e=>[e.id,e.name])))(n),r=new Map(t.map(e=>[e.id,e])),l=new Map(t.map(e=>[e.name,e])),i=new Map(n.map(e=>[e.id,e])),d=new Map,u=new Map,c=new Map,p=new Map,f=(e,t)=>{const n=e+">"+t;let a=p.get(n);return a||p.set(n,a={source:e,target:t,count:0}),a},b=(e,t,n=!1)=>{const a=Le("node",{key:e,label:t,unknown:n});let o=c.get(a);if(!o){const s=n?void 0:i.get(e),r=s&&w(s);c.set(a,o={id:a,label:t,count:0,unknown:n||void 0,latency:h(r),unavailable:"unavailable"===r?.state})}return o},j=(e,t=!1)=>{const n=Le("outbound",{label:e,unknown:t});let a=u.get(n);if(a)return a;const o=t?void 0:l.get(e),d=t?{groups:[],member:null}:g(e,o?.selection.tcp_member_id?"tcp":"udp",l,r,i),c=d.groups.map(e=>({name:e.name,kind:e.policy.kind,policy:e.policy.native})),p=d.member;return a={id:n,label:e,count:0,unknown:t||void 0,kind:t?"unknown":m(e)?e:c.length?"group":"unknown",groups:c,node:p&&b(p,s.get(p)??p).id},u.set(n,a),a.node&&f(n,a.node),a},x=(e,t,n=!1)=>{let a=d.get(e);return a||d.set(e,a={id:e,label:t,count:0,unknown:n||void 0,outbound:null,must:!1}),a};if("rule"===o)for(const m of a?.rules??[]){const e=x(Le("rule",{key:m.rule_id,label:m.expression}),m.expression);e.must=m.must,m.outbound&&(e.outbound=j(m.outbound).id,f(e.id,e.outbound))}const v=[o,"outbound","node"];for(const m of e){let e;for(const t of v){const n=Se(m,t,s,a?.generation_id);if(!n)break;const o="outbound"===t?j(n.label,n.unknown):"node"===t?b(n.key??n.label,n.label,n.unknown):x(Le(t,n),n.label,n.unknown);o.count++,e&&f(e.id,o.id).count++,e=o}}for(const m of t)j(m.name);const y=new Set([...d.values()].map(e=>e.outbound)),k=new Set([...u.values()].flatMap(e=>e.groups.slice(1).map(e=>e.name))),_=[...u.values()].filter(e=>e.count||y.has(e.id)||!k.has(e.label)),M=new Set(_.map(e=>e.id)),N=[...p.values()].filter(e=>M.has(e.source)||M.has(e.target)),S=new Set(N.map(e=>e.target));return{by:o,leaves:[...d.values()],outbounds:_,nodes:[...c.values()].filter(e=>S.has(e.id)),links:N}}const Fe=new WeakMap;function He(e){const t=Fe.get(e);if(t)return t;const n=new Map,a=new Map,o=new Map;for(const l of e.links){for(const[e,t]of[[n,l.source],[a,l.target]]){let n=e.get(t);n||e.set(t,n=[]),n.push(l)}(!o.has(l.source)||o.get(l.source).countnull==e?"—":{key:e?"ui.yes":"ui.no"},$e=e=>e?[["ui.error",e]]:[];function De(e,t,n,a,o,s){return{tree:e,state:t?e.leaves.length||e.outbounds.length?"ready":"empty":n?"error":"loading",pinLabel:a?s("flow.viewPinned",{n:o}):null}}const Ie={input:"flow.stage.input",route:"flow.stage.route",dial_mode:"flow.stage.dialMode",dns:"nav.dns",outbound:"ui.outbound",connection:"flow.stage.connection",datapath:"ov.datapath",reroute:"flow.stage.reroute"},Ae={complete:"flow.status.complete",partial:"flow.status.partial",disabled:"flow.status.disabled"};function Be(e,t,n,a){if(!e)return null;const o=N[n];return{title:e.input.domain||e.input.dst||e.id,status:k(Ae,e.trace.status,t),tone:"complete"===e.trace.status?void 0:"warn",revision:t("flow.revision",{n:e.revision}),fields:[[t("ui.state"),k(y,e.state,t)],...a?[[t("nodes.node"),a.path??a.node]]:[],...a?.expression?[[t("ui.rule"),a.expression]]:[],...e.trace.missing.length?[[t("flow.missing"),C(n,e.trace.missing.map(e=>k(qe,e,t)))]]:[]],connectionHref:e.connection_id?L("connections",{id:e.connection_id}):null,steps:[...e.trace.steps].sort((e,t)=>e.seq-t.seq).map(e=>{const n=function(e){const t=e=>null==e?"—":"object"==typeof e?JSON.stringify(e):String(e);switch(e.stage){case"input":return Object.entries(e.data.values).filter(([,e])=>null!=e&&""!==e).map(([e,n])=>{const a=Ee[e];return[void 0!==a&&a.includes(".")?a:{key:"flow.f.input",params:{name:a??e}},"string"!=typeof n||"ingress"!==e&&"domain_source"!==e?t(n):le(n)]});case"route":return[["conn.chain",e.data.chain],["flow.f.plane",le(e.data.plane)],["ui.rule",e.data.rules.filter(e=>"matched"===e.result).map(e=>e.expression??e.rule_id).join(", ")||"—"],["ui.outbound",t(e.data.outbound)],["flow.f.must",We(e.data.must)]];case"dial_mode":return[["flow.f.dialTarget",e.data.configured+" → "+e.data.effective_target],["flow.f.verification",le(e.data.verification)]];case"dns":return[["ui.name",e.data.name],["rule.dns.kind.qtype",e.data.qtype],["ui.source",le(e.data.source)],["ui.cache",le(e.data.cache)],["ui.upstream",t(e.data.upstream)],["flow.f.selectedIp",t(e.data.selected_ip)],["ui.state",e.data.status],...$e(e.data.error)];case"outbound":return[["ui.outbound",t(e.data.routed_outbound)+" → "+t(e.data.effective_outbound)],["flow.f.selectionPath",e.data.selection_path.map(e=>e.group_id+" → "+t(e.member_name??e.member_id)).join(" / ")||"—"],["flow.f.leafNode",t(e.data.leaf_node_id)],["ui.target",t(e.data.target)],["ui.state",le(e.data.status)],...$e(e.data.error)];case"connection":return[["ui.state",Object.hasOwn(y,e.data.state)?{key:y[e.data.state]}:e.data.state],["flow.f.milestone",le(e.data.milestone)],["flow.f.reason",le(e.data.reason)],...$e(e.data.error)];case"datapath":return[["flow.f.plane",le(e.data.plane)],["flow.f.action",le(e.data.action)],["flow.f.reason",le(e.data.reason)],...$e(e.data.error)];case"reroute":return[["flow.f.performed",We(e.data.performed)],["flow.f.reason",le(e.data.reason)]];default:return null}}(e);return{id:e.seq,stage:k(Ie,e.stage,t),observed:S(e.observed_at,o),elapsed:null==e.elapsed_us?"—":t("ui.microseconds",{n:e.elapsed_us}),fields:n?.map(([e,n])=>["string"==typeof e?t(e):t(e.key,e.params),"string"==typeof n?n:t(n.key,n.params)])??null,raw:n?"":JSON.stringify(e.data,null,2)}})}}const Ue=30,Ve=[5,4,3],Ke={rule:0,client:0,outbound:1,node:2};function Ge(e,t,n,a){const s=null===t?void 0:Math.max(t,720),r=((s??0)-112)/Ve.reduce((e,t)=>e+t),l=e=>{const t=Ke[e];return{left:Ve.slice(0,t).reduce((e,t)=>e+t*r+56,0),width:Ve[t]*r}},i=function(e){const t=new Map;let n=0;const a=new Map,{parents:o}=He(e);for(const l of[...e.leaves,...e.outbounds]){const e=o.get(l.id);if(e){let t=a.get(e);t||a.set(e,t=[]),t.push(l.id)}}const s=e=>{const o=a.get(e)??[];if(o.length){for(const e of o)s(e);t.set(e,(t.get(o[0])+t.get(o[o.length-1]))/2)}else t.set(e,n++)},r=new Set;for(const l of e.outbounds)r.add(o.get(l.id)??l.id);for(const l of e.nodes)r.add(l.id);for(const l of e.leaves)o.has(l.id)||r.add(l.id);for(const l of r)s(l);return{rows:n,at:t}}(e),d=function(e,t,n){const a=(e,n)=>e.unknown?t("ui.unknown"):n,s=[...e.leaves.map(t=>({id:t.id,stage:e.by,name:a(t,t.label),badge:t.must?"must":void 0,notes:[],count:t.count})),...e.outbounds.map(e=>({id:e.id,stage:"outbound",name:a(e,T(e.label,t)),notes:[...e.groups.slice(1).map(e=>({text:"› "+e.name})),...e.groups.slice(-1).map(e=>({text:ae({kind:e.kind,native:e.policy},t).label})),..."group"!==e.kind||e.node?[]:[{text:t("flow.treeNoNode")}]],count:e.count})),...e.nodes.map(e=>({id:e.id,stage:"node",name:a(e,e.label),notes:null!=e.latency?[{text:P(e.latency,t),tone:o(e.latency)}]:e.unavailable?[{text:t("ui.unavailable"),tone:"err"}]:[],count:e.count}))],r=new Map(s.map(e=>[e.id,e.name])),{outgoing:l,incoming:i}=He(e);return s.map(e=>{const a=(l.get(e.id)??[]).map(e=>r.get(e.target)),o="node"===e.stage?(i.get(e.id)??[]).map(e=>r.get(e.source)):[],s=[e.name,...e.badge?[e.badge]:[],...e.notes.map(e=>e.text),t("flow.treeFlows",{n:e.count})];return o.length&&s.push(t("flow.treeFrom",{names:C(n,o)})),a.length&&s.push(t("flow.treeTo",{names:C(n,a)})),{...e,countText:O(e.count,N[n]),label:s.join(t("ui.separator"))}})}(e,n,a).map(e=>({view:e,style:{top:44*i.at.get(e.id),...l(e.stage)}})),u=new Map(e.outbounds.map(e=>[e.id,e])),c=e.links.flatMap(t=>{if(!i.at.has(t.source)||!i.at.has(t.target))return[];const n="outbound"===Ce(t.source)?"outbound":e.by,a=l(n),o=a.left+a.width,s=l("outbound"===n?"node":"outbound").left,r=44*i.at.get(t.source)+18,d=44*i.at.get(t.target)+18,c=(o+s)/2;return[{link:t,id:t.source+">"+t.target,path:`M${o},${r} C${c},${r} ${c},${d} ${s},${d}`,width:Math.min(8,1.5+1.25*Math.log2(1+t.count)),dash:t.count?void 0:"4 4",kind:"outbound"===n?"node":u.get(t.target)?.kind??"group"}]});return{width:s,height:44*i.rows-8,captions:[{stage:e.by,label:n("rule"===e.by?"ui.rule":"ui.device"),style:l(e.by)},{stage:"outbound",label:n("ui.outbound"),style:l("outbound")},{stage:"node",label:n("nodes.node"),style:l("node")}],placed:d,geometry:c}}function Qe(t,n,a){const o=R(),s=F(),[r,l]=e.useState(Ue),[i,d]=e.useState(null),[u,c]=H(),p=e.useMemo(()=>He(t),[t]),m=e.useMemo(()=>function(e,t){return e.leaves.length<=t?e:{...e,leaves:e.leaves.slice(0,t)}}(t,r),[t,r]),f=e.useMemo(()=>Ge(m,c,o,s),[m,c,o,s]),g=e.useMemo(()=>new Set(f.placed.map(e=>e.view.id)),[f.placed]),w=e.useMemo(()=>new Set([...t.leaves,...t.outbounds,...t.nodes].map(e=>e.id)),[t]),h=i&&g.has(i)?i:n&&w.has(n)?n:null,b=e.useMemo(()=>h?function(e,t){const n=new Set([t]),a=new Set;for(const[o,s]of[[e.outgoing,"target"],[e.incoming,"source"]]){const e=[t];for(const t of e)for(const r of o.get(t)??[])a.has(r)||(a.add(r),n.has(r[s])||(n.add(r[s]),e.push(r[s])))}return{items:n,edges:a}}(p,h):null,[p,h]);e.useEffect(()=>{if(!n)return;const e=e=>{"Escape"===e.key&&a(null)};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[n,a]);const j=e.useRef(n);e.useLayoutEffect(()=>{j.current=n},[n]);const x=e.useCallback(e=>a(j.current===e?null:e),[a]);return{...f,ref:u,ready:void 0!==f.width,active:b,pinned:n,pin:x,hover:d,more:t.leaves.length>r?o("flow.treeShowMore",{n:Math.min(Ue,t.leaves.length-r)}):null,fewer:r>Ue?o("flow.treeFewer",{n:Ue}):null,showMore:()=>l(e=>Math.min(t.leaves.length,e+Ue)),showFewer:()=>l(Ue)}}const ze=e.memo(function({view:e,style:n,dim:a,selected:o,pin:l,hover:i}){return t.jsxs(s,{"aria-label":e.label,className:W("rp-tree-tile",a&&"dim"),"data-id":e.id,"data-stage":e.stage,style:n,isSelected:o,onChange:()=>l(e.id),onHoverStart:()=>i(e.id),onHoverEnd:()=>i(null),onFocus:()=>i(e.id),onBlur:()=>i(null),children:[t.jsxs("span",{className:"l",children:["node"===e.stage?t.jsx("b",{children:t.jsx(E,{name:e.name})}):"rule"===e.stage||"client"===e.stage?e.name:t.jsx("b",{children:e.name}),e.notes.map((e,n)=>t.jsx("span",{className:W("s",e.tone),children:e.text},n))]}),e.badge&&t.jsx(r,{children:e.badge}),t.jsx("span",{className:"c",children:e.countText})]})});function Je({tree:e,pinned:n,onPin:a}){const{ref:o,...s}=Qe(e,n,a);return t.jsxs("div",{className:"rp-tree",ref:o,children:[t.jsx("div",{className:"rp-tree-captions",style:{width:s.width},children:s.captions.map(e=>t.jsx("span",{className:"rp-label",style:e.style,children:e.label},e.stage))}),t.jsxs("div",{className:"rp-tree-canvas",style:{height:s.height,width:s.width},children:[s.ready&&t.jsx("svg",{className:"rp-tree-links",width:s.width,height:s.height,"aria-hidden":!0,children:s.geometry.map(e=>t.jsx("path",{d:e.path,strokeWidth:e.width,"data-kind":e.kind,"data-state":s.active?s.active.edges.has(e.link)?"active":"dim":void 0,strokeDasharray:e.dash},e.id))}),s.ready&&s.placed.map(({view:e,style:n})=>t.jsx(ze,{view:e,style:n,dim:!!s.active&&!s.active.items.has(e.id),selected:s.pinned===e.id,pin:s.pin,hover:s.hover},e.id))]}),s.more&&t.jsx(q,{small:!0,quiet:!0,onPress:s.showMore,children:s.more}),s.fewer&&t.jsx(q,{small:!0,quiet:!0,onPress:s.showFewer,children:s.fewer})]})}function Ze({go:t,query:n}){const a=R(),o=F(),s=I(A),r=I(B),i=e.useMemo(()=>new URLSearchParams(n),[n]),d=i.get("network"),u="tcp"===d||"udp"===d?d:"all",c=i.get("state")??"",p=Object.hasOwn(y,c)?c:"all",g=i.get("connection_id")??void 0,w=$().data?.resources,h=fe({connection_id:g,network:u,state:p},D(w,"flows",{whileLoading:!0})),b=D(w,"rules",{whileLoading:!1}),j=ge(b),x=he(),N=i.get("id"),S=we(N),L=i.get("path"),C=e.useMemo(()=>{const e=h.data?.flows??[];return L?Pe(e,L,j.data):e},[h.data,L,j.data]),P=j.data?.generation_id,O=e.useMemo(()=>function(e,t,n,a,o,s){return{rows:e.map(e=>({id:e.id,target:e.input?.domain||e.input?.dst||e.id,node:M(e,o,a),nodeName:!m(e.outbound)&&e.chain.length>0,path:_(e,o,a),expression:e.rule_expression,ruleId:null!==e.rule_generation_id&&e.rule_generation_id===n?e.rule_id:null,recomputed:"recomputed"===e.rule_source,network:e.network.toUpperCase(),state:k(y,e.state,o),startedAt:e.started_at,seed:{domain:e.input?.domain??null,dip:f(e.input?.dst??void 0)??null,sip:f(e.input?.src??void 0)??null,outbound:e.outbound,matched:e.rule_id&&"unknown"!==e.rule_source?{id:e.rule_id,expression:e.rule_expression,generation:e.rule_generation_id}:null}})),coverage:t?ie(t,o,s):null,stateOptions:[{id:"all",label:o("flow.allStates")},...Object.entries(y).map(([e,t])=>({id:e,label:o(t)}))]}}(C,h.data,P,x,a,o),[C,h.data,P,x,a,o]),H=O.rows.find(e=>e.id===N),q=l(D(w,"groups",{whileLoading:!1})).data,E=e.useMemo(()=>{const e=Be(S.data??void 0,a,o,H);return e&&{...e,outboundTag:oe(S.data.outbound,q,a)}},[S.data,a,o,H,q]),W=be(t);return{...O,detail:E,rule:{canAdd:W.canAdd,open:W.open,label:e=>a("conn.addRuleFor",{target:e}),noTarget:a("flow.ruleNoTarget"),dialog:W.dialog},network:u,setNetwork:e=>t("flows",v(n,{network:"all"===e?null:e})),state:p,setState:e=>t("flows",v(n,{state:"all"===e?null:e})),wide:s,phone:r,id:N,rulesListed:b,error:h.error,retry:h.refetch,loading:h.loading&&!h.data,panelOpen:!!N&&(!!S.data||S.loading||!!S.error),panelTitle:E?.title??N??"",detailError:S.error,detailRetry:S.refetch,detailLoading:!S.data&&S.loading,select:e=>t("flows",v(n,{id:e}),{replace:null!==N}),pinLabel:L?a("flow.mapFilter",{label:Oe(L,j.data?.rules??[],x,e=>null===e?a("ui.unknown"):T(e,a))}):null,clearPin:()=>t("flows",v(n,{path:null})),connectionLabel:g?a("flow.connectionFilter",{connectionId:g}):null,clearConnection:()=>t("flows",v(n,{connection_id:null})),recordingHref:w?.runtime_settings.available?se:null}}function Xe({go:e,query:t}){const n=R(),a=$(),o=function(e,t,n){const a=b(e).map(e=>({id:e.id,label:n(e.titleKey)})),o=a[0]?.id??"map";return{tabs:a,tab:j(t,a.map(e=>e.id),o),fallback:e?o:null}}(a.data?.resources,t,n);return U(a.data?.resources),{...o,loading:a.loading&&!a.data,error:a.error,retry:a.refetch,changeTab:n=>e("flows",function(e,t,n){return x(v(e,"map"===t?{id:null,connection_id:null}:{by:null}),t,n)}(t,n,o.fallback))}}function Ye({label:n,cols:a,rows:o,getTextValue:s,height:r=442,selected:l,onSelect:i,loading:d,empty:u}){const c=R(),p=e.useMemo(()=>l?new Set([l]):new Set,[l]);return d&&!o.length?t.jsx(V,{shape:"cards",count:2,height:196}):t.jsx(ye,{layout:ke,layoutOptions:{estimatedRowSize:196,gap:8},children:t.jsx(ve,{className:"rp-table-cards","aria-label":n,items:o,dependencies:[a],style:{maxHeight:r},selectionMode:i?"single":"none",selectionBehavior:"toggle",selectedKeys:p,onSelectionChange:e=>i?.(ce(e)),renderEmptyState:()=>t.jsx(K,{children:u??c("ui.empty")}),children:e=>t.jsx(et,{row:e,cols:a,title:s(e)})})})}function et({row:e,cols:n,title:a}){const o=n.find(e=>e.isRowHeader)??n[0],s=n.find(e=>e.actions),r=n.filter(e=>e!==o&&e!==s);return t.jsx(_e,{id:e.id,title:a,actions:s?.render(e),children:t.jsx(d,{items:r.map(t=>({label:t.label,value:t.render(e),wide:t.wide}))})})}function tt(e){const n=R(),a=Xe(e),o={map:t.jsx(nt,{...e}),records:t.jsx(at,{...e})};return a.loading?t.jsx(G,{}):a.error?t.jsx(Q,{error:a.error,onRetry:a.retry}):t.jsx("div",{className:"rp-page",children:t.jsx(ue,{page:!0,label:n("nav.flows"),items:a.tabs.map(e=>({...e,content:o[e.id]})),value:a.tab,onChange:a.changeTab})})}function nt(n){const a=R(),o=function({go:t,query:n}){const a=R(),o=new URLSearchParams(n),s=$().data?.resources,r=fe({},D(s,"flows",{whileLoading:!0})),d=l(D(s,"groups",{whileLoading:!1})),u=i(D(s,"nodes",{whileLoading:!1})),c=ge(D(s,"rules",{whileLoading:!1})),p="client"===o.get("by")?"client":"rule",m=e.useMemo(()=>Re(r.data?.flows??[],d.data??[],u.data??[],c.data,p),[r.data,d.data,u.data,c.data,p]),f=o.get("path"),g=e.useRef(n);e.useLayoutEffect(()=>{g.current=n},[n]);const w=e.useCallback(e=>t("flows",v(g.current,{path:e})),[t]),h=e.useMemo(()=>f?Pe(r.data?.flows??[],f,c.data).length:0,[r.data,f,c.data]);return{...De(m,[r,c,d,u].every(e=>void 0!==e.data||e.error||!e.loading)&&!!(r.data||c.data||d.data),!!r.error,f,h,a),by:p,pinned:f,error:r.error??d.error??u.error??c.error,retry:()=>{r.refetch(),d.refetch(),u.refetch(),c.refetch()},pin:w,changeBy:e=>t("flows",v(n,{by:"client"===e?"client":null,path:null})),viewPinned:()=>t("flows",v(n,{tab:"records"}))}}(n);return t.jsxs("section",{className:"rp-col","aria-label":a("flow.map"),children:[t.jsxs(J,{page:!0,children:[o.pinLabel?t.jsx(q,{onPress:o.viewPinned,children:o.pinLabel}):t.jsx("span",{className:"rp-label",children:a("flow.mapFilterHint")}),t.jsx("span",{className:"rp-grow"}),t.jsx(q,{quiet:!0,isDisabled:!o.pinLabel,onPress:()=>o.pin(null),children:a("flow.clearMapFilter")})]}),t.jsx(Q,{error:o.error,onRetry:o.retry}),t.jsxs(ee,{title:a("flow.topology"),note:a("flow.topologyNote"),className:"rp-topology",aside:t.jsx(c,{label:a("flow.topology"),value:o.by,onChange:o.changeBy,items:[["rule",a("flow.byRule")],["client",a("conn.byClient")]]}),children:["loading"===o.state&&t.jsx(V,{shape:"block",height:480,typical:!0}),"empty"===o.state&&t.jsx(K,{children:a("flow.mapEmpty")}),"ready"===o.state&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"rp-tree-hint",children:a("flow.treePanHint")}),t.jsx(Je,{tree:o.tree,pinned:o.pinned,onPin:o.pin})]})]})]})}function at(o){const s=R(),l=Ze(o),i=l.detail,m=e.useRef(l.rule);e.useLayoutEffect(()=>{m.current=l.rule});const f=e.useMemo(()=>[{id:"target",label:s("ui.target"),minWidth:128,grow:2,isRowHeader:!0,render:e=>t.jsx(z,{children:e.target})},{id:"node",label:s("nodes.node"),minWidth:96,drop:2,wide:!0,render:e=>t.jsx(n,{row:e})},{id:"rule",label:s("ui.rule"),minWidth:152,grow:3,drop:1,text:"wrap",wide:!0,render:e=>t.jsxs("span",{className:"rp-rule",children:[t.jsx(u,{expression:e.expression,href:re(e.ruleId,l.rulesListed)}),e.recomputed&&t.jsx(r,{tip:s("rule.sourceHelp.recomputed"),children:s("conn.recomputed")})]})},{id:"network",label:s("ui.protocol"),minWidth:96,grow:0,drop:3,render:e=>e.network},{id:"state",label:s("ui.state"),minWidth:112,grow:0,drop:5,render:e=>e.state},{id:"started",label:s("ui.started"),minWidth:140,grow:0,drop:4,render:e=>t.jsx(me,{at:e.startedAt})},{id:"actions",actions:!0,label:s("ui.actions"),minWidth:88,grow:0,render:e=>{const n=m.current,a=!n.canAdd(e.seed);return t.jsx(je,{label:n.label(e.target),disabled:a,tip:n.noTarget,onPress:()=>m.current.open(e.seed)})}}],[s,l.rulesListed]);return t.jsxs(t.Fragment,{children:[t.jsx(Q,{error:l.error,onRetry:l.retry}),t.jsxs(J,{page:!0,children:[t.jsx(c,{label:s("ui.network"),value:l.network,onChange:l.setNetwork,items:[["all",s("ui.all")],["tcp",s("ui.tcp")],["udp",s("ui.udp")]]}),t.jsx(p,{label:s("ui.state"),side:!0,value:l.state,onChange:l.setState,items:l.stateOptions}),l.pinLabel&&t.jsxs(q,{label:s("ui.valuePair",{label:s("flow.clearMapFilter"),value:l.pinLabel}),onPress:l.clearPin,children:[l.pinLabel,t.jsx(Z,{})]}),l.connectionLabel&&t.jsxs(q,{label:s("ui.valuePair",{label:s("flow.clearConnectionFilter"),value:l.connectionLabel}),onPress:l.clearConnection,children:[l.connectionLabel,t.jsx(Z,{})]}),l.coverage&&t.jsx(de,{view:l.coverage}),l.recordingHref&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"rp-grow"}),t.jsx(X,{appearance:"button",quiet:!0,href:l.recordingHref,children:s("ui.recordingSettings")})]})]}),t.jsxs("div",{className:"rp-with-panel","data-open":l.panelOpen?"":void 0,children:[l.phone?t.jsx(Ye,{label:s("flow.records"),loading:l.loading,rows:l.rows,getTextValue:e=>e.target,selected:l.id,onSelect:l.select,empty:s("flow.empty"),cols:f}):t.jsx(pe,{label:s("flow.records"),rowDetail:!0,loading:l.loading,rows:l.rows,height:442,selected:l.id,onSelect:l.select,selectOnFocus:l.wide,empty:s("flow.empty"),cols:f}),t.jsxs(Y,{open:l.panelOpen,title:l.panelTitle,onClose:()=>l.select(null),children:[t.jsx(Q,{error:l.detailError,onRetry:l.detailRetry}),l.detailLoading&&t.jsx(V,{shape:"rows",count:4,label:s("flow.detailLoading")}),i&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"rp-cluster",children:[t.jsx(r,{tone:i.tone,children:i.status}),t.jsx("span",{className:"rp-label",children:i.revision})]}),t.jsx(d,{inline:!0,items:[[s("ui.outbound"),t.jsx(a,{...i.outboundTag})],...i.fields]}),t.jsx("div",{className:"rp-cluster",children:i.connectionHref&&t.jsx(X,{appearance:"button",href:i.connectionHref,children:s("flow.viewConnection")})}),t.jsxs("div",{className:"rp-list",children:[!i.steps.length&&t.jsx(K,{children:s("ui.empty")}),i.steps.map(e=>t.jsxs("div",{className:"rp-col rp-step",children:[t.jsxs("div",{className:"rp-cluster",children:[t.jsx(r,{children:e.stage}),t.jsx(z,{text:e.observed,className:"rp-label",children:e.elapsed})]}),e.fields?t.jsx(d,{inline:!0,items:e.fields}):t.jsx("pre",{className:"rp-flow-raw rp-code",children:t.jsx("code",{children:e.raw})})]},e.id))]})]})]})]}),t.jsx(xe,{dialog:l.rule.dialog})]})}export{tt as Flows};
diff --git a/luci-app-honk/root/etc/honk/doona/assets/GridList-CQPDUasC.js b/luci-app-honk/root/etc/honk/doona/assets/GridList-Dgo5IXUg.js
similarity index 68%
rename from luci-app-honk/root/etc/honk/doona/assets/GridList-CQPDUasC.js
rename to luci-app-honk/root/etc/honk/doona/assets/GridList-Dgo5IXUg.js
index 035b629c3..783cc052c 100644
--- a/luci-app-honk/root/etc/honk/doona/assets/GridList-CQPDUasC.js
+++ b/luci-app-honk/root/etc/honk/doona/assets/GridList-Dgo5IXUg.js
@@ -1 +1 @@
-import{f_ as e,d3 as t,cY as r,cX as o,by as a,g0 as i,ek as l,eY as n,eZ as s,eQ as d,eR as c,eS as u,d4 as p,eT as g,eV as f,eW as y,d6 as v,eU as h,eL as b,ep as m,g3 as k,dk as D,eu as w,dn as E,dm as P,f0 as M,dd as x,de as S,df as A,f8 as K,dh as C,ez as T,f2 as N,f4 as B,eq as I,f9 as R,d9 as F,er as V,eo as L,eK as H,f3 as U,f5 as z,dj as O,fe as $,ff as j,ey as G}from"./index-CUHkLMAp.js";import{a as W,$ as _,b as q,d as Y,e as Q,f as X}from"./useGridSelectionCheckbox-CTBMGgmQ.js";import{k as Z,f as J,e as ee,l as te,g as re,i as oe,h as ae}from"./Select-BA0NS1_z.js";import{r as ie,$ as le}from"./vendor-react-64fcanlc.js";const ne=new WeakMap;function se(e,t){let{id:r}=ne.get(e)??{};if(!r)throw new Error("Unknown list");return`${r}-${function(e){return"string"==typeof e?e.replace(/\s*/g,""):""+e}(t)}`}const de={ltr:"ArrowRight",rtl:"ArrowLeft"},ce={ltr:"ArrowLeft",rtl:"ArrowRight"};function ue(e,t,r){let{node:m,isVirtualized:k,focusMode:D="row",allowsArrowNavigation:w}=e,{direction:E}=a(),{onAction:P,linkBehavior:M,keyboardNavigationBehavior:x,shouldSelectOnPressUp:S}=ne.get(t),A=i(),K=ie.useRef(null),C=()=>{if(null!==r.current){if("child"===D){if(d(r.current)&&r.current!==c(u(r.current)))return;let e=p(r.current,{tabbable:!0}).firstChild();if(e)return g(e),void f(e,{containingElement:y(e)})}(null!=K.current&&m.key!==K.current||!d(r.current))&&g(r.current)}},T={},N=e.hasChildItems,B=t.selectionManager.isLink(m.key);if(null!=m&&"expandedKeys"in t){let e=t.collection.getChildren?.(m.key);N=N||[...e??[]].length>1,null==P&&!B&&"none"===t.selectionManager.selectionMode&&N&&(P=()=>t.toggleKey(m.key));let r=N?t.expandedKeys.has(m.key):void 0,o=1,a=m.index;if(m.level>=0&&null!=m?.parentKey){let e=t.collection.getItem(m.parentKey);if(e){let r=function(e,t){let r=t.getChildren?.(e.key),o=r?Array.from(r):[],a=o.length>0?o[0]:null,i=[];for(;a;)i.push(a),a=null!=a.nextKey?t.getItem(a.nextKey):null;return i}(e,t.collection);o=[...r].filter(e=>"item"===e.type).length,a>0&&"item"!==r[0].type&&(a-=1)}}else o=[...t.collection].filter(e=>0===e.level&&"item"===e.type).length;T={"aria-expanded":r,"aria-level":m.level+1,"aria-posinset":a+1,"aria-setsize":o}}let{itemProps:I,...R}=l({selectionManager:t.selectionManager,key:m.key,ref:r,isVirtualized:k,shouldSelectOnPressUp:e.shouldSelectOnPressUp||S,onAction:P||m.props?.onAction?n(m.props?.onAction,P?()=>P(m.key):void 0):void 0,focus:C,linkBehavior:M}),F=s(m.props),V=R.hasAction?F:{},L=o(I,V,{role:"row",onKeyDownCapture:"arrow"===x||w?e=>{let o=c(u(r.current));if(!b(e.currentTarget,v(e))||!r.current||!o)return;let a=p(r.current);if(a.currentNode=o,!pe(e,t,m,N,E,o,r.current,w))switch(e.key){case"ArrowLeft":if("arrow"===x){let t="rtl"===E?a.nextNode():a.previousNode();if(t)e.preventDefault(),e.stopPropagation(),g(t),f(t,{containingElement:y(r.current)});else if(e.preventDefault(),e.stopPropagation(),"rtl"===E)g(r.current),f(r.current,{containingElement:y(r.current)});else{a.currentNode=r.current;let e=ge(a);e&&(g(e),f(e,{containingElement:y(r.current)}))}}break;case"ArrowRight":if("arrow"===x){let t="rtl"===E?a.previousNode():a.nextNode();if(t)e.preventDefault(),e.stopPropagation(),g(t),f(t,{containingElement:y(r.current)});else if(e.preventDefault(),e.stopPropagation(),"ltr"===E)g(r.current),f(r.current,{containingElement:y(r.current)});else{a.currentNode=r.current;let e=ge(a);e&&(g(e),f(e,{containingElement:y(r.current)}))}}break;case"ArrowUp":case"ArrowDown":!e.altKey&&b(r.current,v(e))&&(e.stopPropagation(),e.preventDefault(),r.current.parentElement?.dispatchEvent(new KeyboardEvent(e.nativeEvent.type,e.nativeEvent)))}}:void 0,onFocus:e=>{K.current=m.key,v(e)===r.current?"child"===D&&e.relatedTarget&&b(r.current,e.relatedTarget)||requestAnimationFrame(()=>{"child"===D&&c(u(r.current))===r.current&&C()}):h()||t.selectionManager.setFocusedKey(m.key)},"aria-label":m["aria-label"]||m.textValue||void 0,"aria-selected":t.selectionManager.canSelectItem(m.key)?t.selectionManager.isSelected(m.key):void 0,"aria-disabled":t.selectionManager.isDisabled(m.key)||void 0,"aria-labelledby":A&&(m["aria-label"]||m.textValue)?`${se(t,m.key)} ${A}`:void 0,id:se(t,m.key)});"child"===D&&w&&"tab"===x&&(L.tabIndex=-1);let H=L.onKeyDown;if(L.onKeyDown=e=>{(e=>{let o=c(u(r.current));if(b(e.currentTarget,v(e))&&r.current&&o){if("tab"===x){if(v(e)!==r.current&&"Tab"!==e.key)return void e.stopPropagation();if(pe(e,t,m,N,E,o,r.current,w))return}if("Tab"===e.key&&"tab"===x){let t=p(r.current,{tabbable:!0});t.currentNode=o,(e.shiftKey?t.previousNode():t.nextNode())&&e.stopPropagation()}}})(e),e.isPropagationStopped()||H?.(e)},k){let{collection:e}=t,r=[...e];L["aria-rowindex"]=r.find(e=>"section"===e.type)?[...e.getKeys()].filter(t=>"section"!==e.getItem(t)?.type).findIndex(e=>e===m.key)+1:m.index+1}return{rowProps:{...o(L,T)},gridCellProps:{role:"gridcell","aria-colindex":1},descriptionProps:{id:A},...R}}function pe(e,t,r,o,a,i,l,n){if(!("expandedKeys"in t)||!n&&i!==l)return!1;if(e.key===de[a]&&t.selectionManager.focusedKey===r.key&&o&&!t.expandedKeys.has(r.key))return t.toggleKey(r.key),e.stopPropagation(),!0;if(e.key===ce[a]&&t.selectionManager.focusedKey===r.key){if(o&&t.expandedKeys.has(r.key))return t.toggleKey(r.key),e.stopPropagation(),!0;if(!t.expandedKeys.has(r.key)&&r.parentKey&&"item"===t.collection.getItem(r.parentKey)?.type)return t.selectionManager.setFocusedKey(r.parentKey),e.stopPropagation(),!0}return!1}function ge(e){let t=null,r=null;do{r=e.lastChild(),r&&(t=r)}while(r);return t}const fe=ie.createContext(null),ye=ie.forwardRef(function(e,t){return[e,t]=F(e,t,fe),le.createElement(V,{content:le.createElement(L,e)},r=>le.createElement(ve,{props:e,collection:r,gridListRef:t}))});function ve({props:i,collection:l,gridListRef:n}){[i,n]=F(i,n,N);let s,d,c,{shouldUseVirtualFocus:u,filter:p,disallowTypeAhead:g,UNSTABLE_focusOnEntry:f,...y}=i,{dragAndDropHooks:v,keyboardNavigationBehavior:h="arrow",layout:b="stack",orientation:m="vertical"}=i,{CollectionRoot:k,isVirtualized:D,layoutDelegate:E,dropTargetDelegate:M}=ie.useContext(w),K=ee({...y,collection:l,children:void 0,layoutDelegate:E}),C=te(K,p),T=H({usage:"search",sensitivity:"base"}),{disabledBehavior:B,disabledKeys:I}=C.selectionManager,{direction:R}=a(),V=ie.useMemo(()=>new U({collection:C.collection,collator:T,ref:n,disabledKeys:I,disabledBehavior:B,layoutDelegate:E,layout:b,orientation:m,direction:R}),[C.collection,n,b,m,I,B,E,T,R]),{gridProps:L}=function(a,i,l){let{isVirtualized:n,keyboardDelegate:s,layoutDelegate:d,onAction:c,disallowTypeAhead:u,linkBehavior:p="action",keyboardNavigationBehavior:g="arrow",escapeKeyBehavior:f="clearSelection",shouldSelectOnPressUp:y}=a;a["aria-label"]||a["aria-labelledby"]||console.warn("An aria-label or aria-labelledby prop is required for accessibility.");let{listProps:v}=e({selectionManager:i.selectionManager,collection:i.collection,disabledKeys:i.disabledKeys,ref:l,keyboardDelegate:s,layoutDelegate:d,isVirtualized:n,selectOnFocus:"replace"===i.selectionManager.selectionBehavior,shouldFocusWrap:a.shouldFocusWrap,linkBehavior:p,disallowTypeAhead:u,autoFocus:a.autoFocus,escapeKeyBehavior:f,UNSTABLE_focusOnEntry:a.UNSTABLE_focusOnEntry}),h=t(a.id);ne.set(i,{id:h,onAction:c,linkBehavior:p,keyboardNavigationBehavior:g,shouldSelectOnPressUp:y});let b=W({selectionManager:i.selectionManager,hasItemActions:!!c}),m=_(l,{isDisabled:0!==i.collection.size}),k=r(a,{labelable:!0}),D=o(k,{role:"grid",id:h,"aria-multiselectable":"multiple"===i.selectionManager.selectionMode?"true":void 0},0===i.collection.size?{tabIndex:m?-1:0}:v,b);return n&&(D["aria-rowcount"]=i.collection.size,D["aria-colcount"]=1),q({},i),{gridProps:D}}({...y,keyboardDelegate:V,keyboardNavigationBehavior:"grid"===b?"tab":h,isVirtualized:D,shouldSelectOnPressUp:i.shouldSelectOnPressUp,disallowTypeAhead:g,UNSTABLE_focusOnEntry:f},C,n),$=C.selectionManager,j=!!v?.useDraggableCollectionState,G=!!v?.useDroppableCollectionState;ie.useRef(j),ie.useRef(G),ie.useEffect(()=>{},[j,G]);let Y=!1,Q=null,X=ie.useRef(null);if(j&&v){s=v.useDraggableCollectionState({collection:C.collection,selectionManager:$,preview:v.renderDragPreview?X:void 0}),v.useDraggableCollection({},s,n);let e=v.DragPreview;Q=v.renderDragPreview?le.createElement(e,{ref:X},v.renderDragPreview):null}if(G&&v){d=v.useDroppableCollectionState({collection:C.collection,selectionManager:$});let e=v.dropTargetDelegate||M||new v.ListDropTargetDelegate(l,n,{layout:b,direction:R,orientation:m});c=v.useDroppableCollection({keyboardDelegate:V,dropTargetDelegate:e},d,n),Y=d.isDropTarget({type:"root"})}let{focusProps:se,isFocused:de,isFocusVisible:ce}=P(),ue=0===C.collection.size,pe={isDropTarget:Y,orientation:m,isEmpty:ue,isFocused:de,isFocusVisible:ce,layout:b,state:C},ge=x({...i,children:void 0,defaultClassName:"react-aria-GridList",values:pe}),fe=null;if(ue&&i.renderEmptyState){let e=i.renderEmptyState(pe);fe=le.createElement("div",{role:"row","aria-rowindex":1,style:{display:"contents"}},le.createElement("div",{role:"gridcell",style:{display:"contents"}},e))}let ye=r(i,{global:!0});return le.createElement(z,null,le.createElement(S.div,{...o(ye,ge,L,se,c?.collectionProps,null),ref:n,slot:i.slot||void 0,onScroll:i.onScroll,"data-drop-target":Y||void 0,"data-empty":ue||void 0,"data-focused":de||void 0,"data-focus-visible":ce||void 0,"data-layout":b,"data-orientation":m},le.createElement(A,{values:[[Z,C],[J,{dragAndDropHooks:v,dragState:s,dropState:d}],[re,{render:be}]]},G&&le.createElement(De,null),le.createElement(O,null,le.createElement(k,{collection:C.collection,scrollRef:n,persistedKeys:ae($,v,d),renderDropIndicator:oe(v,d)}))),fe,Q))}const he=m(k,function(e,t,a){let i=ie.useContext(Z),{dragAndDropHooks:l,dragState:n,dropState:s}=ie.useContext(J),d=D(t),{isVirtualized:c}=ie.useContext(w),u=n&&!(n.isDisabled||n.selectionManager.isDisabled(a.key)),{rowProps:p,gridCellProps:g,descriptionProps:f,...y}=ue({node:a,shouldSelectOnPressUp:!!n,isVirtualized:c,focusMode:e.focusMode,allowsArrowNavigation:e.allowsArrowNavigation},i,d),{hoverProps:v,isHovered:h}=E({isDisabled:!y.allowsSelection&&!y.hasAction&&!u,onHoverStart:a.props.onHoverStart,onHoverChange:a.props.onHoverChange,onHoverEnd:a.props.onHoverEnd}),{isFocusVisible:b,focusProps:m}=P(),{isFocusVisible:k,focusProps:F}=P({within:!0}),{checkboxProps:V}=function(e,t){let{key:r}=e;const{checkboxProps:o}=Y(e,t);return{checkboxProps:{...o,"aria-labelledby":`${o.id} ${se(t,r)}`}}}({key:a.key},i),L="all"===i.selectionManager.disabledBehavior&&y.isDisabled?{isDisabled:!0}:{},H=null;n&&l&&(H=l.useDraggableItem({key:a.key,hasDragButton:!0},n));let U=null,z=ie.useRef(null),{visuallyHiddenProps:O}=M();s&&l&&(U=l.useDropIndicator({target:{type:"item",key:a.key,dropPosition:"on"}},s,z));let $=n&&n.isDragging(a.key),j=x({...e,id:void 0,children:a.rendered,defaultClassName:"react-aria-GridListItem",values:{...y,isHovered:h,isFocusVisible:b,isFocusVisibleWithin:k,selectionMode:i.selectionManager.selectionMode,selectionBehavior:i.selectionManager.selectionBehavior,allowsDragging:!!n,isDragging:$,isDropTarget:U?.isDropTarget,id:a.key,state:i}}),G=ie.useRef(null);ie.useEffect(()=>{n&&!G.current&&console.warn('Draggable items in a GridList must contain a