⛅ Sync 2026-05-03 20:20:03
@ -17,12 +17,12 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-amlogic
|
||||
PKG_VERSION:=3.1.290
|
||||
PKG_RELEASE:=5
|
||||
PKG_RELEASE:=6
|
||||
|
||||
PKG_LICENSE:=GPL-2.0 License
|
||||
PKG_MAINTAINER:=ophub <https://github.com/ophub/luci-app-amlogic>
|
||||
|
||||
LUCI_TITLE:=LuCI support for Amlogic, Allwinner and Rockchip related boxs
|
||||
LUCI_TITLE:=LuCI support for custom TV boxes
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:= \
|
||||
@(aarch64||arm) +bash +blkid +block-mount +curl +dosfstools +e2fsprogs \
|
||||
|
||||
@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-mosdns
|
||||
PKG_VERSION:=1.7.2
|
||||
PKG_RELEASE:=7
|
||||
PKG_RELEASE:=8
|
||||
|
||||
LUCI_TITLE:=LuCI Support for mosdns
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
var callServiceList = rpc.declare({
|
||||
const callServiceList = rpc.declare({
|
||||
object: 'service',
|
||||
method: 'list',
|
||||
params: ['name'],
|
||||
@ -15,8 +15,8 @@ var callServiceList = rpc.declare({
|
||||
});
|
||||
|
||||
function getServiceStatus() {
|
||||
return L.resolveDefault(callServiceList('mosdns'), {}).then(function (res) {
|
||||
var isRunning = false;
|
||||
return L.resolveDefault(callServiceList('mosdns'), {}).then(res => {
|
||||
let isRunning = false;
|
||||
try {
|
||||
isRunning = res['mosdns']['instances']['mosdns']['running'];
|
||||
} catch (e) { }
|
||||
@ -25,8 +25,8 @@ function getServiceStatus() {
|
||||
}
|
||||
|
||||
function renderStatus(isRunning) {
|
||||
var spanTemp = '<em><span style="color:%s"><strong>%s %s</strong></span></em>';
|
||||
var renderHTML;
|
||||
const spanTemp = '<em><span style="color:%s"><strong>%s %s</strong></span></em>';
|
||||
let renderHTML;
|
||||
if (isRunning) {
|
||||
renderHTML = spanTemp.format('green', _('MosDNS'), _('RUNNING'));
|
||||
} else {
|
||||
@ -70,27 +70,27 @@ async function loadCodeMirrorResources() {
|
||||
await loadScripts();
|
||||
}
|
||||
|
||||
var callMosdns = rpc.declare({
|
||||
const callMosdns = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'get_version',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
var callFlushCache = rpc.declare({
|
||||
const callFlushCache = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'flush_cache',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
load: function () {
|
||||
load() {
|
||||
return Promise.all([
|
||||
L.resolveDefault(callMosdns(), null),
|
||||
]);
|
||||
},
|
||||
|
||||
handleFlushCache: function () {
|
||||
return callFlushCache().then(function(res) {
|
||||
handleFlushCache() {
|
||||
return callFlushCache().then(res => {
|
||||
if (res.success) {
|
||||
ui.addNotification(null, E('p', _('Flushing DNS Cache Success.')), 'info');
|
||||
} else {
|
||||
@ -99,24 +99,20 @@ return view.extend({
|
||||
});
|
||||
},
|
||||
|
||||
render: function (data) {
|
||||
var m, s, o, v;
|
||||
v = '';
|
||||
render(data) {
|
||||
let m, s, o;
|
||||
|
||||
var version = (data[0] && data[0].version) ? data[0].version : null;
|
||||
if (version) {
|
||||
v = version;
|
||||
}
|
||||
m = new form.Map('mosdns', _('MosDNS') + ' ' + v,
|
||||
const version = (data[0] && data[0].version) ? data[0].version : '';
|
||||
m = new form.Map('mosdns', _('MosDNS') + ' ' + version,
|
||||
_('MosDNS is a plugin-based DNS forwarder/traffic splitter.'));
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
s.anonymous = true;
|
||||
s.render = function () {
|
||||
setTimeout(function () {
|
||||
poll.add(function () {
|
||||
return L.resolveDefault(getServiceStatus()).then(function (res) {
|
||||
var view = document.getElementById('service_status');
|
||||
s.render = () => {
|
||||
setTimeout(() => {
|
||||
poll.add(() => {
|
||||
return L.resolveDefault(getServiceStatus()).then(res => {
|
||||
const view = document.getElementById('service_status');
|
||||
if (view) {
|
||||
view.innerHTML = renderStatus(res);
|
||||
} else {
|
||||
@ -132,14 +128,14 @@ return view.extend({
|
||||
return E('div', { class: 'cbi-section', id: 'status_bar' }, [
|
||||
E('p', { id: 'service_status' }, _('Collecting data...'))
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
s = m.section(form.NamedSection, 'config', 'mosdns');
|
||||
|
||||
s.tab('basic', _('Basic Options'));
|
||||
s.tab("advanced", _("Advanced Options"));
|
||||
s.tab("cloudflare", _("Cloudflare Options"));
|
||||
s.tab("api", _("API Options"));
|
||||
s.tab('advanced', _('Advanced Options'));
|
||||
s.tab('cloudflare', _('Cloudflare Options'));
|
||||
s.tab('api', _('API Options'));
|
||||
s.tab('geodata', _('GeoData Export'));
|
||||
|
||||
/* basic */
|
||||
@ -271,13 +267,13 @@ return view.extend({
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'idle_timeout', _('Idle Timeout'),
|
||||
_('DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)'))
|
||||
_('DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)'));
|
||||
o.datatype = 'and(uinteger,min(1))';
|
||||
o.default = '30';
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'enable_pipeline', _('TCP/DoT Connection Multiplexing'),
|
||||
_('Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode'))
|
||||
_('Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode'));
|
||||
o.rmempty = false;
|
||||
o.default = false;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
@ -362,9 +358,9 @@ return view.extend({
|
||||
o.depends('adblock', '1');
|
||||
o.default = 'geosite.dat';
|
||||
o.value('geosite.dat', 'v2ray-geosite');
|
||||
o.value('https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt', 'anti-AD')
|
||||
o.value('https://raw.githubusercontent.com/Cats-Team/AdRules/main/mosdns_adrules.txt', 'Cats-Team/AdRules')
|
||||
o.value('https://raw.githubusercontent.com/neodevpro/neodevhost/master/domain', 'NEO DEV HOST')
|
||||
o.value('https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt', 'anti-AD');
|
||||
o.value('https://raw.githubusercontent.com/Cats-Team/AdRules/main/mosdns_adrules.txt', 'Cats-Team/AdRules');
|
||||
o.value('https://raw.githubusercontent.com/neodevpro/neodevhost/master/domain', 'NEO DEV HOST');
|
||||
|
||||
/* cloudflare */
|
||||
o = s.taboption('cloudflare', form.Flag, 'cloudflare', _('Enabled'),
|
||||
@ -383,12 +379,10 @@ return view.extend({
|
||||
_('IPv4 CIDR: <a href="https://www.cloudflare.com/ips-v4" target="_blank">https://www.cloudflare.com/ips-v4</a> <br /> IPv6 CIDR: <a href="https://www.cloudflare.com/ips-v6" target="_blank">https://www.cloudflare.com/ips-v6</a>'));
|
||||
o.rows = 15;
|
||||
o.depends('configfile', '/var/etc/mosdns.json');
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/cloudflare-cidr.txt');
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/cloudflare-cidr.txt');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/cloudflare-cidr.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n');
|
||||
@ -410,9 +404,9 @@ return view.extend({
|
||||
o.depends('cache', '1');
|
||||
|
||||
/* configuration */
|
||||
var configeditor = null;
|
||||
setTimeout(function () {
|
||||
var textarea = document.getElementById('widget.cbid.mosdns.config._custom');
|
||||
let configeditor = null;
|
||||
setTimeout(() => {
|
||||
const textarea = document.getElementById('widget.cbid.mosdns.config._custom');
|
||||
if (textarea) {
|
||||
configeditor = CodeMirror.fromTextArea(textarea, {
|
||||
autoRefresh: true,
|
||||
@ -421,9 +415,9 @@ return view.extend({
|
||||
lint: true,
|
||||
gutters: ['CodeMirror-lint-markers'],
|
||||
matchBrackets: true,
|
||||
mode: "text/yaml",
|
||||
mode: 'text/yaml',
|
||||
styleActiveLine: true,
|
||||
theme: "dracula"
|
||||
theme: 'dracula'
|
||||
});
|
||||
}
|
||||
}, 600);
|
||||
@ -432,23 +426,17 @@ return view.extend({
|
||||
Only accepts configuration content in yaml format.'));
|
||||
o.rows = 25;
|
||||
o.depends('configfile', '/etc/mosdns/config_custom.yaml');
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/config_custom.yaml');
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/config_custom.yaml');
|
||||
o.write = function(section_id, formvalue) {
|
||||
if (configeditor) {
|
||||
var editorContent = configeditor.getValue();
|
||||
const editorContent = configeditor.getValue();
|
||||
if (editorContent === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/config_custom.yaml', editorContent.trim().replace(/\r\n/g, '\n') + '\n')
|
||||
.then(function (i) {
|
||||
return fs.exec('/etc/init.d/mosdns', ['restart']);
|
||||
})
|
||||
.then(function () {
|
||||
return window.location.reload();
|
||||
})
|
||||
.catch(function (e) {
|
||||
.then(i => fs.exec('/etc/init.d/mosdns', ['restart']))
|
||||
.then(() => window.location.reload())
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,24 +6,24 @@
|
||||
'require rpc';
|
||||
'require ui';
|
||||
|
||||
var callPrintLog = rpc.declare({
|
||||
const callPrintLog = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'print_log',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
var callCleanLog = rpc.declare({
|
||||
const callCleanLog = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'clean_log',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
var scrollPosition = 0;
|
||||
var userScrolled = false;
|
||||
var logTextarea;
|
||||
let scrollPosition = 0;
|
||||
let userScrolled = false;
|
||||
let logTextarea;
|
||||
|
||||
function pollLog() {
|
||||
return callPrintLog().then(function (res) {
|
||||
return callPrintLog().then(res => {
|
||||
logTextarea.value = res.log || _('No log data.');
|
||||
|
||||
if (!userScrolled) {
|
||||
@ -32,20 +32,20 @@ function pollLog() {
|
||||
logTextarea.scrollTop = scrollPosition;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
handleCleanLogs: function () {
|
||||
return callCleanLog().then(function(res) {
|
||||
handleCleanLogs() {
|
||||
return callCleanLog().then(res => {
|
||||
if (res.success) {
|
||||
logTextarea.value = ''; // Clear textarea on success
|
||||
} else {
|
||||
ui.addNotification(null, E('p', _('Failed to clean logs.') + (res.error ? ': ' + res.error : '')), 'error');
|
||||
}
|
||||
}).catch(function (e) { ui.addNotification(null, E('p', e.message)) });
|
||||
}).catch(e => ui.addNotification(null, E('p', e.message)));
|
||||
},
|
||||
|
||||
render: function () {
|
||||
render() {
|
||||
logTextarea = E('textarea', {
|
||||
'class': 'cbi-input-textarea',
|
||||
'wrap': 'off',
|
||||
@ -53,16 +53,16 @@ return view.extend({
|
||||
'style': 'width: calc(100% - 20px);height: 535px;margin: 10px;overflow-y: scroll;',
|
||||
});
|
||||
|
||||
logTextarea.addEventListener('scroll', function () {
|
||||
logTextarea.addEventListener('scroll', () => {
|
||||
userScrolled = true;
|
||||
scrollPosition = logTextarea.scrollTop;
|
||||
});
|
||||
|
||||
var log_textarea_wrapper = E('div', { 'id': 'log_textarea' }, logTextarea);
|
||||
const log_textarea_wrapper = E('div', { 'id': 'log_textarea' }, logTextarea);
|
||||
|
||||
poll.add(pollLog);
|
||||
|
||||
var clear_logs_button = E('input', { 'class': 'btn cbi-button-action', 'type': 'button', 'style': 'margin-left: 10px; margin-top: 10px;', 'value': _('Clear logs') });
|
||||
const clear_logs_button = E('input', { 'class': 'btn cbi-button-action', 'type': 'button', 'style': 'margin-left: 10px; margin-top: 10px;', 'value': _('Clear logs') });
|
||||
clear_logs_button.addEventListener('click', this.handleCleanLogs.bind(this));
|
||||
|
||||
return E([
|
||||
|
||||
@ -5,10 +5,10 @@
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
render: function () {
|
||||
var m, s, o;
|
||||
render() {
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map("mosdns", _("Rule Settings"),
|
||||
m = new form.Map('mosdns', _('Rule Settings'),
|
||||
_('The list of rules only apply to \'Default Config\' profiles.'));
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
@ -32,27 +32,21 @@ return view.extend({
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/whitelist.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/whitelist.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/whitelist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(function (e) {
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = function (section_id) {
|
||||
return fs.write('/etc/mosdns/rule/whitelist.txt', '').catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/whitelist.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Block Lists ---
|
||||
o = s.taboption('blocklist', form.TextValue, '_blocklist',
|
||||
@ -62,27 +56,21 @@ return view.extend({
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/blocklist.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/blocklist.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/blocklist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(function (e) {
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = function (section_id) {
|
||||
return fs.write('/etc/mosdns/rule/blocklist.txt', '').catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/blocklist.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Grey Lists ---
|
||||
o = s.taboption('greylist', form.TextValue, '_greylist',
|
||||
@ -92,27 +80,21 @@ return view.extend({
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/greylist.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/greylist.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/greylist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(function (e) {
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = function (section_id) {
|
||||
return fs.write('/etc/mosdns/rule/greylist.txt', '').catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/greylist.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- DDNS Lists ---
|
||||
o = s.taboption('ddnslist', form.TextValue, '_ddnslist',
|
||||
@ -122,27 +104,21 @@ return view.extend({
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/ddnslist.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/ddnslist.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/ddnslist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(function (e) {
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = function (section_id) {
|
||||
return fs.write('/etc/mosdns/rule/ddnslist.txt', '').catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/ddnslist.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Hosts ---
|
||||
o = s.taboption('hostslist', form.TextValue, '_hostslist',
|
||||
@ -152,27 +128,21 @@ return view.extend({
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/hosts.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/hosts.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/hosts.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(function (e) {
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = function (section_id) {
|
||||
return fs.write('/etc/mosdns/rule/hosts.txt', '').catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/hosts.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Redirect ---
|
||||
o = s.taboption('redirectlist', form.TextValue, '_redirectlist',
|
||||
@ -182,27 +152,21 @@ return view.extend({
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/redirect.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/redirect.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/redirect.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(function (e) {
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = function (section_id) {
|
||||
return fs.write('/etc/mosdns/rule/redirect.txt', '').catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/redirect.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Block PTR ---
|
||||
o = s.taboption('localptrlist', form.TextValue, '_localptrlist',
|
||||
@ -212,27 +176,21 @@ return view.extend({
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/local-ptr.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/local-ptr.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/local-ptr.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(function (e) {
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = function (section_id) {
|
||||
return fs.write('/etc/mosdns/rule/local-ptr.txt', '').catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/local-ptr.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
// --- Streaming Media ---
|
||||
o = s.taboption('streamingmedialist', form.TextValue, '_streamingmedialist',
|
||||
@ -242,35 +200,30 @@ return view.extend({
|
||||
+ '</font>'
|
||||
);
|
||||
o.rows = 25;
|
||||
o.cfgvalue = function (section_id) {
|
||||
return fs.trimmed('/etc/mosdns/rule/streaming.txt').catch(function (e) {
|
||||
return "";
|
||||
});
|
||||
};
|
||||
o.write = function (section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(function (value) {
|
||||
if (value == formvalue) {
|
||||
o.cfgvalue = section_id => fs.trimmed('/etc/mosdns/rule/streaming.txt').catch(e => '');
|
||||
o.write = function(section_id, formvalue) {
|
||||
return this.cfgvalue(section_id).then(value => {
|
||||
if (value === formvalue) {
|
||||
return;
|
||||
}
|
||||
return fs.write('/etc/mosdns/rule/streaming.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
|
||||
.catch(function (e) {
|
||||
.catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
});
|
||||
};
|
||||
o.remove = function (section_id) {
|
||||
return fs.write('/etc/mosdns/rule/streaming.txt', '').catch(function (e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
};
|
||||
o.remove = section_id => fs.write('/etc/mosdns/rule/streaming.txt', '').catch(e => {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
|
||||
return m.render();
|
||||
},
|
||||
|
||||
handleSaveApply: function (ev) {
|
||||
return this.handleSave(ev).then(function() {
|
||||
handleSaveApply(ev) {
|
||||
return this.handleSave(ev).then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
},
|
||||
|
||||
handleReset: null
|
||||
});
|
||||
|
||||
@ -5,28 +5,28 @@
|
||||
'require view';
|
||||
'require rpc';
|
||||
|
||||
var callStartUpdate = rpc.declare({
|
||||
const callStartUpdate = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'start_update',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
var callGetUpdateLog = rpc.declare({
|
||||
const callGetUpdateLog = rpc.declare({
|
||||
object: 'luci.mosdns',
|
||||
method: 'get_update_log',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
handleUpdate: function () {
|
||||
var logTextarea = E('textarea', {
|
||||
handleUpdate() {
|
||||
const logTextarea = E('textarea', {
|
||||
'class': 'cbi-input-textarea',
|
||||
'readonly': 'readonly',
|
||||
'style': 'width: 100%; height: 300px; font-family: monospace; font-size: 12px; margin-top: 10px;',
|
||||
'placeholder': _('Starting update...')
|
||||
});
|
||||
|
||||
var closeButton = E('button', {
|
||||
const closeButton = E('button', {
|
||||
'class': 'btn',
|
||||
'style': 'display: none;',
|
||||
'click': ui.hideModal
|
||||
@ -38,8 +38,8 @@ return view.extend({
|
||||
E('div', { 'class': 'right' }, [ closeButton ])
|
||||
]);
|
||||
|
||||
var pollLog = function() {
|
||||
return callGetUpdateLog().then(function(res) {
|
||||
const pollLog = () => {
|
||||
return callGetUpdateLog().then(res => {
|
||||
if (res && res.log) {
|
||||
logTextarea.value = res.log;
|
||||
logTextarea.scrollTop = logTextarea.scrollHeight;
|
||||
@ -60,10 +60,10 @@ return view.extend({
|
||||
});
|
||||
};
|
||||
|
||||
return callStartUpdate().then(function(res) {
|
||||
return callStartUpdate().then(res => {
|
||||
if (res.success) {
|
||||
var interval = window.setInterval(function() {
|
||||
pollLog().then(function(continuePolling) {
|
||||
const interval = window.setInterval(() => {
|
||||
pollLog().then(continuePolling => {
|
||||
if (!continuePolling) {
|
||||
window.clearInterval(interval);
|
||||
}
|
||||
@ -73,14 +73,14 @@ return view.extend({
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', res.error || _('Failed to start update.')), 'error');
|
||||
}
|
||||
}).catch(function(e) {
|
||||
}).catch(e => {
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', _('Update failed: %s').format(e.message)), 'error');
|
||||
});
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var m, s, o;
|
||||
render() {
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('mosdns', _('Update GeoIP & GeoSite databases'),
|
||||
_('Automatically update GeoIP and GeoSite databases as well as ad filtering rules through scheduled tasks.'));
|
||||
@ -105,14 +105,14 @@ return view.extend({
|
||||
o = s.option(form.ListValue, 'geo_update_day_time', _('Update Time'));
|
||||
for (let t = 0; t < 24; t++) {
|
||||
o.value(t, t + ':00');
|
||||
};
|
||||
}
|
||||
o.default = 3;
|
||||
|
||||
o = s.option(form.ListValue, 'geoip_type', _('GeoIP Type'),
|
||||
_('Little: only include Mainland China and Private IP addresses.') +
|
||||
'<br>' +
|
||||
_('Full: includes all Countries and Private IP addresses.')
|
||||
);
|
||||
);
|
||||
o.value('geoip', _('Full'));
|
||||
o.value('geoip-only-cn-private', _('Little'));
|
||||
o.rmempty = false;
|
||||
@ -129,7 +129,7 @@ return view.extend({
|
||||
o.title = _('Database Update');
|
||||
o.inputtitle = _('Check And Update');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(this.handleUpdate, this);
|
||||
o.onclick = () => this.handleUpdate();
|
||||
|
||||
return m.render();
|
||||
}
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:219
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:215
|
||||
msgid "360 Public DNS (DNS over HTTPS)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:358
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:354
|
||||
msgid "ADblock Source"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:399
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:393
|
||||
msgid "API Listen port"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:142
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:138
|
||||
msgid "API Options"
|
||||
msgstr ""
|
||||
|
||||
@ -23,54 +23,54 @@ msgid ""
|
||||
"highest priority (one domain per line, supports domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:121
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:103
|
||||
msgid ""
|
||||
"Added domain names will always use 'Local DNS' for resolution, with a forced "
|
||||
"TTL of 5 seconds, and results will not be cached (one domain per line, "
|
||||
"supports domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:91
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:79
|
||||
msgid ""
|
||||
"Added domain names will always use 'Remote DNS' for resolution (one domain "
|
||||
"per line, supports domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:61
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:55
|
||||
msgid ""
|
||||
"Added domain names will block DNS resolution (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:175
|
||||
msgid ""
|
||||
"Added domain names will block PTR requests (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:140
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:136
|
||||
msgid "Advanced Options"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:208
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:256
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:204
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:252
|
||||
msgid "Aliyun Public DNS (223.5.5.5)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:209
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:257
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:205
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:253
|
||||
msgid "Aliyun Public DNS (223.6.6.6)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:218
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:214
|
||||
msgid "Aliyun Public DNS (DNS over HTTP/3)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:217
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:213
|
||||
msgid "Aliyun Public DNS (DNS over HTTPS)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:216
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:212
|
||||
msgid "Aliyun Public DNS (DNS over QUIC)"
|
||||
msgstr ""
|
||||
|
||||
@ -78,11 +78,11 @@ msgstr ""
|
||||
msgid "Another update is already in progress."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:200
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:196
|
||||
msgid "Apple domains optimization"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:332
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:328
|
||||
msgid "Auto Save Cache Interval"
|
||||
msgstr ""
|
||||
|
||||
@ -92,12 +92,12 @@ msgid ""
|
||||
"rules through scheduled tasks."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:214
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:260
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:210
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:256
|
||||
msgid "Baidu Public DNS (180.76.76.76)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:139
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:135
|
||||
msgid "Basic Options"
|
||||
msgstr ""
|
||||
|
||||
@ -105,7 +105,7 @@ msgstr ""
|
||||
msgid "Basic Setting"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:350
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:346
|
||||
msgid ""
|
||||
"Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force "
|
||||
"using only A/AAAA records."
|
||||
@ -119,17 +119,17 @@ msgstr ""
|
||||
msgid "Block PTR"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:252
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:248
|
||||
msgid "Bootstrap DNS servers"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:253
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:249
|
||||
msgid ""
|
||||
"Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT "
|
||||
"resolvers you specify as upstreams"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:325
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:321
|
||||
msgid "Cache Dump"
|
||||
msgstr ""
|
||||
|
||||
@ -141,21 +141,21 @@ msgstr ""
|
||||
msgid "Check And Update GeoData."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:186
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:182
|
||||
msgid "China DNS prefer IPv4"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:205
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:201
|
||||
msgid "China DNS server"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:231
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:248
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:227
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:244
|
||||
msgid "Cisco Public DNS (208.67.220.220)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:230
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:247
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:226
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:243
|
||||
msgid "Cisco Public DNS (208.67.222.222)"
|
||||
msgstr ""
|
||||
|
||||
@ -167,60 +167,60 @@ msgstr ""
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:225
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:242
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:221
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:238
|
||||
msgid "CloudFlare Public DNS (1.0.0.1)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:224
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:241
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:262
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:220
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:237
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:258
|
||||
msgid "CloudFlare Public DNS (1.1.1.1)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:382
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:378
|
||||
msgid "Cloudflare IP Ranges"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:141
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:137
|
||||
msgid "Cloudflare Options"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:133
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:129
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:267
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:263
|
||||
msgid "Concurrent"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:150
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:146
|
||||
msgid "Config File"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:430
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:424
|
||||
msgid "Configuration Editor"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:196
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:192
|
||||
msgid "Custom China DNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:152
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:148
|
||||
msgid "Custom Config"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:151
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:127
|
||||
msgid ""
|
||||
"Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, "
|
||||
"supports domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:377
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:373
|
||||
msgid "Custom IP"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:235
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:231
|
||||
msgid "Custom Stream Media DNS"
|
||||
msgstr ""
|
||||
|
||||
@ -228,21 +228,21 @@ msgstr ""
|
||||
msgid "DDNS Lists"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:314
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:310
|
||||
msgid "DNS Cache Size"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:177
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:173
|
||||
msgid "DNS Forward"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:268
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:264
|
||||
msgid ""
|
||||
"DNS query request concurrency, The number of upstream DNS servers that are "
|
||||
"allowed to initiate requests at the same time"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:181
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:177
|
||||
msgid "DNS redirect"
|
||||
msgstr ""
|
||||
|
||||
@ -250,29 +250,29 @@ msgstr ""
|
||||
msgid "Database Update"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:165
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:161
|
||||
msgid "Debug"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:151
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:147
|
||||
msgid "Default Config"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:349
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:345
|
||||
msgid "Disable RR Type 65 (HTTPS/SVCB)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:285
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:281
|
||||
msgid "Disable TLS Certificate"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:286
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:282
|
||||
msgid ""
|
||||
"Disable TLS Servers certificate validation, Can be useful if system CA "
|
||||
"certificate expires or the system time is out of order"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:274
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:270
|
||||
msgid "DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"
|
||||
msgstr ""
|
||||
|
||||
@ -280,41 +280,41 @@ msgstr ""
|
||||
msgid "Enable Auto Database Update"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:354
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:350
|
||||
msgid "Enable DNS ADblock"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:309
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:305
|
||||
msgid "Enable DNS Cache"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:292
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:288
|
||||
msgid "Enable EDNS client subnet"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:280
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:276
|
||||
msgid ""
|
||||
"Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:304
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:300
|
||||
msgid "Enable this option fallback policy forces forwarding to remote DNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:146
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:370
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:142
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:366
|
||||
msgid "Enabled"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:463
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:451
|
||||
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:458
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:446
|
||||
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:168
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:164
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
@ -350,8 +350,8 @@ msgstr ""
|
||||
msgid "Every Wednesday"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:459
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:464
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:447
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:452
|
||||
msgid "Export directory: /var/mosdns"
|
||||
msgstr ""
|
||||
|
||||
@ -363,7 +363,7 @@ msgstr ""
|
||||
msgid "Failed to start update."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:407
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:401
|
||||
msgid "Flush DNS Cache"
|
||||
msgstr ""
|
||||
|
||||
@ -375,27 +375,27 @@ msgstr ""
|
||||
msgid "Flushing DNS Cache Success."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:405
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:399
|
||||
msgid ""
|
||||
"Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS "
|
||||
"cache."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:196
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:192
|
||||
msgid "Follow WAN interface DNS if not enabled"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:201
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:197
|
||||
msgid ""
|
||||
"For Apple domains equipped with Chinese mainland CDN, always responsive to "
|
||||
"Chinese CDN IP addresses"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:181
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:177
|
||||
msgid "Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:177
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:173
|
||||
msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS"
|
||||
msgstr ""
|
||||
|
||||
@ -407,11 +407,11 @@ msgstr ""
|
||||
msgid "Full: includes all Countries and Private IP addresses."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:143
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:139
|
||||
msgid "GeoData Export"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:462
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:450
|
||||
msgid "GeoIP Tags"
|
||||
msgstr ""
|
||||
|
||||
@ -419,7 +419,7 @@ msgstr ""
|
||||
msgid "GeoIP Type"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:457
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:445
|
||||
msgid "GeoSite Tags"
|
||||
msgstr ""
|
||||
|
||||
@ -431,14 +431,14 @@ msgstr ""
|
||||
msgid "GitHub Proxy"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:227
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:244
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:223
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:240
|
||||
msgid "Google Public DNS (8.8.4.4)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:226
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:243
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:261
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:222
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:239
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:257
|
||||
msgid "Google Public DNS (8.8.8.8)"
|
||||
msgstr ""
|
||||
|
||||
@ -454,11 +454,11 @@ msgstr ""
|
||||
msgid "Hosts"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:297
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:293
|
||||
msgid "IP Address"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:383
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:379
|
||||
msgid ""
|
||||
"IPv4 CIDR: <a href=\"https://www.cloudflare.com/ips-v4\" target=\"_blank"
|
||||
"\">https://www.cloudflare.com/ips-v4</a> <br /> IPv6 CIDR: <a href=\"https://"
|
||||
@ -466,40 +466,40 @@ msgid ""
|
||||
"v6</a>"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:187
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:183
|
||||
msgid ""
|
||||
"IPv4 is preferred for China DNS resolution of dual-stack addresses, and is "
|
||||
"not affected when the destination is IPv6 only"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:192
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:188
|
||||
msgid ""
|
||||
"IPv4 is preferred for Remote / Streaming Media DNS resolution of dual-stack "
|
||||
"addresses, and is not affected when the destination is IPv6 only"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:273
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:269
|
||||
msgid "Idle Timeout"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:166
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:162
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:319
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:315
|
||||
msgid "Lazy Cache TTL"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:320
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:316
|
||||
msgid ""
|
||||
"Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:160
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:156
|
||||
msgid "Listen Address"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:155
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:151
|
||||
msgid "Listen Port"
|
||||
msgstr ""
|
||||
|
||||
@ -515,11 +515,11 @@ msgstr ""
|
||||
msgid "Log Data"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:172
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:168
|
||||
msgid "Log File"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:164
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:160
|
||||
msgid "Log Level"
|
||||
msgstr ""
|
||||
|
||||
@ -527,28 +527,28 @@ msgstr ""
|
||||
msgid "Logs"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:371
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:367
|
||||
msgid ""
|
||||
"Match the parsing result with the Cloudflare IP ranges, and when there is a "
|
||||
"successful match, use the 'Custom IP' as the parsing result (experimental "
|
||||
"feature)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:343
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:339
|
||||
msgid "Maximum TTL"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:337
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:333
|
||||
msgid "Minimum TTL"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:344
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:340
|
||||
msgid ""
|
||||
"Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating "
|
||||
"no modification"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:338
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:334
|
||||
msgid ""
|
||||
"Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating "
|
||||
"no modification"
|
||||
@ -556,13 +556,13 @@ msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:31
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:33
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:110
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:106
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:70
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:3
|
||||
msgid "MosDNS"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:111
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:107
|
||||
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
|
||||
msgstr ""
|
||||
|
||||
@ -570,7 +570,7 @@ msgstr ""
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:236
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:232
|
||||
msgid "Netflix, Disney+, Hulu and streaming media rules list will use this DNS"
|
||||
msgstr ""
|
||||
|
||||
@ -578,7 +578,7 @@ msgstr ""
|
||||
msgid "No log data."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:298
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:294
|
||||
msgid ""
|
||||
"Please provide the IP address you use when accessing foreign websites. This "
|
||||
"IP subnet (0/24) will be used as the ECS address for Remote / Streaming "
|
||||
@ -589,17 +589,17 @@ msgstr ""
|
||||
msgid "Please wait, this may take a few moments..."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:303
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:299
|
||||
msgid "Prevent DNS Leaks"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:229
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:246
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:225
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:242
|
||||
msgid "Quad9 Public DNS (149.112.112.112)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:228
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:245
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:224
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:241
|
||||
msgid "Quad9 Public DNS (9.9.9.9)"
|
||||
msgstr ""
|
||||
|
||||
@ -611,7 +611,7 @@ msgstr ""
|
||||
msgid "Redirect"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:181
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:151
|
||||
msgid ""
|
||||
"Redirecting requests for domain names. Request domain A, but return records "
|
||||
"for domain B, for example: baidu.com qq.com (one rule per line)."
|
||||
@ -621,11 +621,11 @@ msgstr ""
|
||||
msgid "Refresh every %s seconds."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:191
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:187
|
||||
msgid "Remote DNS prefer IPv4"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:223
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:219
|
||||
msgid "Remote DNS server"
|
||||
msgstr ""
|
||||
|
||||
@ -637,7 +637,7 @@ msgstr ""
|
||||
msgid "Rules"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:326
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:322
|
||||
msgid "Save the cache locally and reload the cache dump on the next startup"
|
||||
msgstr ""
|
||||
|
||||
@ -649,29 +649,29 @@ msgstr ""
|
||||
msgid "Streaming Media"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:240
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:236
|
||||
msgid "Streaming Media DNS server"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:361
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:357
|
||||
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:279
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:275
|
||||
msgid "TCP/DoT Connection Multiplexing"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:207
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:255
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:203
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:251
|
||||
msgid "Tencent Public DNS (119.28.28.28)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:206
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:254
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:202
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:250
|
||||
msgid "Tencent Public DNS (119.29.29.29)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:215
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:211
|
||||
msgid "Tencent Public DNS (DNS over HTTPS)"
|
||||
msgstr ""
|
||||
|
||||
@ -679,45 +679,45 @@ msgstr ""
|
||||
msgid "The list of rules only apply to 'Default Config' profiles."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:299
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:295
|
||||
msgid ""
|
||||
"This feature is typically used when using a self-built DNS server as an "
|
||||
"Remote / Streaming Media DNS upstream (requires support from the upstream "
|
||||
"server)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:431
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:425
|
||||
msgid ""
|
||||
"This is the content of the file '/etc/mosdns/config_custom.yaml' from which "
|
||||
"your MosDNS configuration will be generated. Only accepts configuration "
|
||||
"content in yaml format."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:210
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:206
|
||||
msgid "TrafficRoute Public DNS (180.184.1.1)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:207
|
||||
msgid "TrafficRoute Public DNS (180.184.2.2)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:452
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:47
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:53
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:77
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:83
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:107
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:113
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:137
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:143
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:167
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:173
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:197
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:203
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:227
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:233
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:257
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:263
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:440
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:43
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:48
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:67
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:72
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:91
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:96
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:115
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:120
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:139
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:144
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:163
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:168
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:187
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:192
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:216
|
||||
msgid "Unable to save contents: %s"
|
||||
msgstr ""
|
||||
|
||||
@ -750,18 +750,18 @@ msgstr ""
|
||||
msgid "Updating Database..."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:167
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:163
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:241
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:199
|
||||
msgid ""
|
||||
"When enabling 'Custom Stream Media DNS', added domains will always use the "
|
||||
"'Streaming Media DNS server' for resolution (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:359
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:355
|
||||
msgid ""
|
||||
"When using custom rule sources, please use rule types supported by MosDNS "
|
||||
"(domain list or AdGuardHome rules)."
|
||||
@ -771,13 +771,13 @@ msgstr ""
|
||||
msgid "White Lists"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:212
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:258
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:208
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:254
|
||||
msgid "Xinfeng Public DNS (114.114.114.114)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:213
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:259
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:209
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:255
|
||||
msgid "Xinfeng Public DNS (114.114.115.115)"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@ -11,19 +11,19 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:219
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:215
|
||||
msgid "360 Public DNS (DNS over HTTPS)"
|
||||
msgstr "360 安全 DNS(DNS over HTTPS)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:358
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:354
|
||||
msgid "ADblock Source"
|
||||
msgstr "广告过滤规则来源"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:399
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:393
|
||||
msgid "API Listen port"
|
||||
msgstr "API 监听端口"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:142
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:138
|
||||
msgid "API Options"
|
||||
msgstr "API 选项"
|
||||
|
||||
@ -35,7 +35,7 @@ msgstr ""
|
||||
"加入的域名始终允许使用 “本地 DNS” 进行解析,且优先级最高(每个域名一行,支持"
|
||||
"域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:121
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:103
|
||||
msgid ""
|
||||
"Added domain names will always use 'Local DNS' for resolution, with a forced "
|
||||
"TTL of 5 seconds, and results will not be cached (one domain per line, "
|
||||
@ -44,48 +44,48 @@ msgstr ""
|
||||
"加入的域名始终使用 “本地 DNS” 进行解析,并且强制 TTL 5 秒,解析结果不会进入缓"
|
||||
"存(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:91
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:79
|
||||
msgid ""
|
||||
"Added domain names will always use 'Remote DNS' for resolution (one domain "
|
||||
"per line, supports domain matching rules)."
|
||||
msgstr ""
|
||||
"加入的域名始终使用 “远程 DNS” 进行解析(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:61
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:55
|
||||
msgid ""
|
||||
"Added domain names will block DNS resolution (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr "加入的域名将屏蔽 DNS 解析(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:175
|
||||
msgid ""
|
||||
"Added domain names will block PTR requests (one domain per line, supports "
|
||||
"domain matching rules)."
|
||||
msgstr "加入的域名将阻止 PTR 请求(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:140
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:136
|
||||
msgid "Advanced Options"
|
||||
msgstr "高级选项"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:208
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:256
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:204
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:252
|
||||
msgid "Aliyun Public DNS (223.5.5.5)"
|
||||
msgstr "阿里云公共 DNS(223.5.5.5)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:209
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:257
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:205
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:253
|
||||
msgid "Aliyun Public DNS (223.6.6.6)"
|
||||
msgstr "阿里云公共 DNS(223.6.6.6)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:218
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:214
|
||||
msgid "Aliyun Public DNS (DNS over HTTP/3)"
|
||||
msgstr "阿里云公共 DNS(DNS over HTTP/3)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:217
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:213
|
||||
msgid "Aliyun Public DNS (DNS over HTTPS)"
|
||||
msgstr "阿里云公共 DNS(DNS over HTTPS)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:216
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:212
|
||||
msgid "Aliyun Public DNS (DNS over QUIC)"
|
||||
msgstr "阿里云公共 DNS(DNS over QUIC)"
|
||||
|
||||
@ -93,11 +93,11 @@ msgstr "阿里云公共 DNS(DNS over QUIC)"
|
||||
msgid "Another update is already in progress."
|
||||
msgstr "另一个更新正在进行中。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:200
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:196
|
||||
msgid "Apple domains optimization"
|
||||
msgstr "Apple 域名解析优化"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:332
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:328
|
||||
msgid "Auto Save Cache Interval"
|
||||
msgstr "自动保存缓存间隔(秒)"
|
||||
|
||||
@ -107,12 +107,12 @@ msgid ""
|
||||
"rules through scheduled tasks."
|
||||
msgstr "通过定时任务自动更新 GeoIP 和 GeoSite 数据库以及广告过滤规则。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:214
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:260
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:210
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:256
|
||||
msgid "Baidu Public DNS (180.76.76.76)"
|
||||
msgstr "百度公共 DNS(180.76.76.76)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:139
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:135
|
||||
msgid "Basic Options"
|
||||
msgstr "基本选项"
|
||||
|
||||
@ -120,7 +120,7 @@ msgstr "基本选项"
|
||||
msgid "Basic Setting"
|
||||
msgstr "基本设置"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:350
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:346
|
||||
msgid ""
|
||||
"Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force "
|
||||
"using only A/AAAA records."
|
||||
@ -136,17 +136,17 @@ msgstr "黑名单"
|
||||
msgid "Block PTR"
|
||||
msgstr "PTR 黑名单"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:252
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:248
|
||||
msgid "Bootstrap DNS servers"
|
||||
msgstr "Bootstrap DNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:253
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:249
|
||||
msgid ""
|
||||
"Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT "
|
||||
"resolvers you specify as upstreams"
|
||||
msgstr "Bootstrap DNS 服务器用于解析您指定为上游的 DoH / DoT 解析器的 IP 地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:325
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:321
|
||||
msgid "Cache Dump"
|
||||
msgstr "自动保存缓存"
|
||||
|
||||
@ -158,21 +158,21 @@ msgstr "检查并更新"
|
||||
msgid "Check And Update GeoData."
|
||||
msgstr "检查并更新 GeoData 数据库。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:186
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:182
|
||||
msgid "China DNS prefer IPv4"
|
||||
msgstr "国内 DNS 首选 IPv4"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:205
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:201
|
||||
msgid "China DNS server"
|
||||
msgstr "国内 DNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:231
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:248
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:227
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:244
|
||||
msgid "Cisco Public DNS (208.67.220.220)"
|
||||
msgstr "思科公共 DNS(208.67.220.220)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:230
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:247
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:226
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:243
|
||||
msgid "Cisco Public DNS (208.67.222.222)"
|
||||
msgstr "思科公共 DNS(208.67.222.222)"
|
||||
|
||||
@ -184,61 +184,61 @@ msgstr "清空日志"
|
||||
msgid "Close"
|
||||
msgstr "关闭"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:225
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:242
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:221
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:238
|
||||
msgid "CloudFlare Public DNS (1.0.0.1)"
|
||||
msgstr "CloudFlare 公共 DNS(1.0.0.1)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:224
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:241
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:262
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:220
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:237
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:258
|
||||
msgid "CloudFlare Public DNS (1.1.1.1)"
|
||||
msgstr "CloudFlare 公共 DNS(1.1.1.1)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:382
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:378
|
||||
msgid "Cloudflare IP Ranges"
|
||||
msgstr "Cloudflare IP 范围"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:141
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:137
|
||||
msgid "Cloudflare Options"
|
||||
msgstr "Cloudflare 选项"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:133
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:129
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:267
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:263
|
||||
msgid "Concurrent"
|
||||
msgstr "DNS 服务器并发数(默认 2)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:150
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:146
|
||||
msgid "Config File"
|
||||
msgstr "配置文件"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:430
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:424
|
||||
msgid "Configuration Editor"
|
||||
msgstr "配置编辑器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:196
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:192
|
||||
msgid "Custom China DNS"
|
||||
msgstr "自定义国内 DNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:152
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:148
|
||||
msgid "Custom Config"
|
||||
msgstr "自定义"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:151
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:127
|
||||
msgid ""
|
||||
"Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, "
|
||||
"supports domain matching rules)."
|
||||
msgstr ""
|
||||
"自定义 Hosts 重写,如:baidu.com 10.0.0.1(每个规则一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:377
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:373
|
||||
msgid "Custom IP"
|
||||
msgstr "自选 IP"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:235
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:231
|
||||
msgid "Custom Stream Media DNS"
|
||||
msgstr "自定义流媒体 DNS"
|
||||
|
||||
@ -246,21 +246,21 @@ msgstr "自定义流媒体 DNS"
|
||||
msgid "DDNS Lists"
|
||||
msgstr "DDNS 域名"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:314
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:310
|
||||
msgid "DNS Cache Size"
|
||||
msgstr "DNS 缓存大小"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:177
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:173
|
||||
msgid "DNS Forward"
|
||||
msgstr "DNS 转发"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:268
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:264
|
||||
msgid ""
|
||||
"DNS query request concurrency, The number of upstream DNS servers that are "
|
||||
"allowed to initiate requests at the same time"
|
||||
msgstr "DNS 查询请求并发数,允许同时发起请求的上游 DNS 服务器数量"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:181
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:177
|
||||
msgid "DNS redirect"
|
||||
msgstr "DNS 重定向"
|
||||
|
||||
@ -268,30 +268,30 @@ msgstr "DNS 重定向"
|
||||
msgid "Database Update"
|
||||
msgstr "数据库更新"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:165
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:161
|
||||
msgid "Debug"
|
||||
msgstr "调试"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:151
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:147
|
||||
msgid "Default Config"
|
||||
msgstr "内置预设"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:349
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:345
|
||||
msgid "Disable RR Type 65 (HTTPS/SVCB)"
|
||||
msgstr "禁用 RR Type 65 (HTTPS/SVCB)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:285
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:281
|
||||
msgid "Disable TLS Certificate"
|
||||
msgstr "禁用 TLS 证书"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:286
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:282
|
||||
msgid ""
|
||||
"Disable TLS Servers certificate validation, Can be useful if system CA "
|
||||
"certificate expires or the system time is out of order"
|
||||
msgstr ""
|
||||
"禁用 TLS 服务器证书验证,当系统 CA 证书过期或系统时间错乱时,本选项可能会有用"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:274
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:270
|
||||
msgid "DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"
|
||||
msgstr "DoH/TCP/DoT 连接复用空闲保持时间(默认 30 秒)"
|
||||
|
||||
@ -299,41 +299,41 @@ msgstr "DoH/TCP/DoT 连接复用空闲保持时间(默认 30 秒)"
|
||||
msgid "Enable Auto Database Update"
|
||||
msgstr "启用自动更新"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:354
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:350
|
||||
msgid "Enable DNS ADblock"
|
||||
msgstr "启用 DNS 广告过滤"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:309
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:305
|
||||
msgid "Enable DNS Cache"
|
||||
msgstr "启用 DNS 缓存"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:292
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:288
|
||||
msgid "Enable EDNS client subnet"
|
||||
msgstr "启用 EDNS 客户端子网"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:280
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:276
|
||||
msgid ""
|
||||
"Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"
|
||||
msgstr "启用 TCP/DoT RFC 7766 新型 Query Pipelining 连接复用模式"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:304
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:300
|
||||
msgid "Enable this option fallback policy forces forwarding to remote DNS"
|
||||
msgstr "启用此选项 fallback 策略会强制转发到远程 DNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:146
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:370
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:142
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:366
|
||||
msgid "Enabled"
|
||||
msgstr "启用"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:463
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:451
|
||||
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
|
||||
msgstr "输入需要导出的 GeoIP.dat 类别条目,允许添加多个标签"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:458
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:446
|
||||
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
|
||||
msgstr "填写需要导出的 GeoSite.dat 类别条目,允许添加多个标签"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:168
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:164
|
||||
msgid "Error"
|
||||
msgstr "错误"
|
||||
|
||||
@ -369,8 +369,8 @@ msgstr "每周二"
|
||||
msgid "Every Wednesday"
|
||||
msgstr "每周三"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:459
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:464
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:447
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:452
|
||||
msgid "Export directory: /var/mosdns"
|
||||
msgstr "导出目录:/var/mosdns"
|
||||
|
||||
@ -382,7 +382,7 @@ msgstr "清理日志失败:%s"
|
||||
msgid "Failed to start update."
|
||||
msgstr "启动更新失败"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:407
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:401
|
||||
msgid "Flush DNS Cache"
|
||||
msgstr "刷新 DNS 缓存"
|
||||
|
||||
@ -394,27 +394,27 @@ msgstr "刷新 DNS 缓存失败,请检查 MosDNS 状态是否在运行中。"
|
||||
msgid "Flushing DNS Cache Success."
|
||||
msgstr "刷新 DNS 缓存成功"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:405
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:399
|
||||
msgid ""
|
||||
"Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS "
|
||||
"cache."
|
||||
msgstr "刷新 DNS 缓存会清空 MosDNS 所有 IP 地址和 DNS 解析缓存。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:196
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:192
|
||||
msgid "Follow WAN interface DNS if not enabled"
|
||||
msgstr "不启用则使用 WAN 接口 DNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:201
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:197
|
||||
msgid ""
|
||||
"For Apple domains equipped with Chinese mainland CDN, always responsive to "
|
||||
"Chinese CDN IP addresses"
|
||||
msgstr "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:181
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:177
|
||||
msgid "Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking"
|
||||
msgstr "强制将所有本地 DNS 查询重定向到 MosDNS,即 DNS 劫持。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:177
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:173
|
||||
msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS"
|
||||
msgstr "将 Dnsmasq 域名解析请求转发到 MosDNS 服务器"
|
||||
|
||||
@ -426,11 +426,11 @@ msgstr "全量"
|
||||
msgid "Full: includes all Countries and Private IP addresses."
|
||||
msgstr "全量:包含所有国家和私有 IP 地址。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:143
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:139
|
||||
msgid "GeoData Export"
|
||||
msgstr "GeoData 导出"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:462
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:450
|
||||
msgid "GeoIP Tags"
|
||||
msgstr "GeoIP 标签"
|
||||
|
||||
@ -438,7 +438,7 @@ msgstr "GeoIP 标签"
|
||||
msgid "GeoIP Type"
|
||||
msgstr "GeoIP 类型"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:457
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:445
|
||||
msgid "GeoSite Tags"
|
||||
msgstr "GeoSite 标签"
|
||||
|
||||
@ -450,14 +450,14 @@ msgstr "更新数据库"
|
||||
msgid "GitHub Proxy"
|
||||
msgstr "GitHub 代理"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:227
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:244
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:223
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:240
|
||||
msgid "Google Public DNS (8.8.4.4)"
|
||||
msgstr "谷歌公共 DNS(8.8.4.4)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:226
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:243
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:261
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:222
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:239
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:257
|
||||
msgid "Google Public DNS (8.8.8.8)"
|
||||
msgstr "谷歌公共 DNS(8.8.8.8)"
|
||||
|
||||
@ -473,11 +473,11 @@ msgstr "灰名单"
|
||||
msgid "Hosts"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:297
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:293
|
||||
msgid "IP Address"
|
||||
msgstr "IP 地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:383
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:379
|
||||
msgid ""
|
||||
"IPv4 CIDR: <a href=\"https://www.cloudflare.com/ips-v4\" target=\"_blank"
|
||||
"\">https://www.cloudflare.com/ips-v4</a> <br /> IPv6 CIDR: <a href=\"https://"
|
||||
@ -485,40 +485,40 @@ msgid ""
|
||||
"v6</a>"
|
||||
msgstr ""
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:187
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:183
|
||||
msgid ""
|
||||
"IPv4 is preferred for China DNS resolution of dual-stack addresses, and is "
|
||||
"not affected when the destination is IPv6 only"
|
||||
msgstr "国内 DNS 解析双栈地址时首选 IPv4,目标仅 IPv6 时不受影响"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:192
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:188
|
||||
msgid ""
|
||||
"IPv4 is preferred for Remote / Streaming Media DNS resolution of dual-stack "
|
||||
"addresses, and is not affected when the destination is IPv6 only"
|
||||
msgstr "远程 / 流媒体 DNS 解析双栈地址时首选 IPv4,目标仅 IPv6 时不受影响"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:273
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:269
|
||||
msgid "Idle Timeout"
|
||||
msgstr "空闲超时"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:166
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:162
|
||||
msgid "Info"
|
||||
msgstr "信息"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:319
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:315
|
||||
msgid "Lazy Cache TTL"
|
||||
msgstr "乐观缓存 TTL"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:320
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:316
|
||||
msgid ""
|
||||
"Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."
|
||||
msgstr "乐观缓存生存时间(单位:秒),要禁用乐观缓存,请设置为 0"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:160
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:156
|
||||
msgid "Listen Address"
|
||||
msgstr "监听地址"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:155
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:151
|
||||
msgid "Listen Port"
|
||||
msgstr "监听端口"
|
||||
|
||||
@ -534,11 +534,11 @@ msgstr "轻量:仅包含中国大陆和私有 IP 地址。"
|
||||
msgid "Log Data"
|
||||
msgstr "日志数据"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:172
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:168
|
||||
msgid "Log File"
|
||||
msgstr "日志文件"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:164
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:160
|
||||
msgid "Log Level"
|
||||
msgstr "日志等级"
|
||||
|
||||
@ -546,7 +546,7 @@ msgstr "日志等级"
|
||||
msgid "Logs"
|
||||
msgstr "日志"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:371
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:367
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Match the parsing result with the Cloudflare IP ranges, and when there is a "
|
||||
@ -556,21 +556,21 @@ msgstr ""
|
||||
"将解析结果与 Cloudflare IP 范围进行匹配,当匹配成功时,使用 “自选 IP” 作为解"
|
||||
"析结果(实验性功能)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:343
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:339
|
||||
msgid "Maximum TTL"
|
||||
msgstr "覆盖最大 TTL 值(默认 0)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:337
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:333
|
||||
msgid "Minimum TTL"
|
||||
msgstr "覆盖最小 TTL 值(默认 0)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:344
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:340
|
||||
msgid ""
|
||||
"Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating "
|
||||
"no modification"
|
||||
msgstr "修改 DNS 应答结果的最大 TTL 值(秒),0 表示不修改"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:338
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:334
|
||||
msgid ""
|
||||
"Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating "
|
||||
"no modification"
|
||||
@ -578,13 +578,13 @@ msgstr "修改 DNS 应答结果的最小 TTL 值 (秒),0 表示不修改"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:31
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:33
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:110
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:106
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js:70
|
||||
#: luci-app-mosdns/root/usr/share/luci/menu.d/luci-app-mosdns.json:3
|
||||
msgid "MosDNS"
|
||||
msgstr "MosDNS"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:111
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:107
|
||||
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
|
||||
msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。"
|
||||
|
||||
@ -592,7 +592,7 @@ msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。"
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:236
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:232
|
||||
msgid "Netflix, Disney+, Hulu and streaming media rules list will use this DNS"
|
||||
msgstr "自定义 Netflix、Disney+、Hulu 以及 “流媒体” 规则列表的 DNS 服务器"
|
||||
|
||||
@ -600,7 +600,7 @@ msgstr "自定义 Netflix、Disney+、Hulu 以及 “流媒体” 规则列表
|
||||
msgid "No log data."
|
||||
msgstr "无日志数据。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:298
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:294
|
||||
msgid ""
|
||||
"Please provide the IP address you use when accessing foreign websites. This "
|
||||
"IP subnet (0/24) will be used as the ECS address for Remote / Streaming "
|
||||
@ -613,17 +613,17 @@ msgstr ""
|
||||
msgid "Please wait, this may take a few moments..."
|
||||
msgstr "请稍候,这可能需要一点时间..."
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:303
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:299
|
||||
msgid "Prevent DNS Leaks"
|
||||
msgstr "防止 DNS 泄漏"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:229
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:246
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:225
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:242
|
||||
msgid "Quad9 Public DNS (149.112.112.112)"
|
||||
msgstr "Quad9 公共 DNS(149.112.112.112)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:228
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:245
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:224
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:241
|
||||
msgid "Quad9 Public DNS (9.9.9.9)"
|
||||
msgstr "Quad9 公共 DNS(9.9.9.9)"
|
||||
|
||||
@ -635,7 +635,7 @@ msgstr "运行中"
|
||||
msgid "Redirect"
|
||||
msgstr "重定向"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:181
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:151
|
||||
msgid ""
|
||||
"Redirecting requests for domain names. Request domain A, but return records "
|
||||
"for domain B, for example: baidu.com qq.com (one rule per line)."
|
||||
@ -647,11 +647,11 @@ msgstr ""
|
||||
msgid "Refresh every %s seconds."
|
||||
msgstr "每 %s 秒刷新。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:191
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:187
|
||||
msgid "Remote DNS prefer IPv4"
|
||||
msgstr "远程 DNS 首选 IPv4"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:223
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:219
|
||||
msgid "Remote DNS server"
|
||||
msgstr "远程 DNS 服务器"
|
||||
|
||||
@ -663,7 +663,7 @@ msgstr "自定义规则列表"
|
||||
msgid "Rules"
|
||||
msgstr "规则列表"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:326
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:322
|
||||
msgid "Save the cache locally and reload the cache dump on the next startup"
|
||||
msgstr "保存缓存到本地文件,以供下次启动时重新载入使用"
|
||||
|
||||
@ -675,29 +675,29 @@ msgstr ""
|
||||
msgid "Streaming Media"
|
||||
msgstr "流媒体"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:240
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:236
|
||||
msgid "Streaming Media DNS server"
|
||||
msgstr "流媒体 DNS 服务器"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:361
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:357
|
||||
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
|
||||
msgstr "支持本地文件,例如:file:///var/mosdns/example.txt"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:279
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:275
|
||||
msgid "TCP/DoT Connection Multiplexing"
|
||||
msgstr "TCP/DoT 连接复用"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:207
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:255
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:203
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:251
|
||||
msgid "Tencent Public DNS (119.28.28.28)"
|
||||
msgstr "腾讯公共 DNS(119.28.28.28)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:206
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:254
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:202
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:250
|
||||
msgid "Tencent Public DNS (119.29.29.29)"
|
||||
msgstr "腾讯公共 DNS(119.29.29.29)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:215
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:211
|
||||
msgid "Tencent Public DNS (DNS over HTTPS)"
|
||||
msgstr "腾讯公共 DNS(DNS over HTTPS)"
|
||||
|
||||
@ -705,7 +705,7 @@ msgstr "腾讯公共 DNS(DNS over HTTPS)"
|
||||
msgid "The list of rules only apply to 'Default Config' profiles."
|
||||
msgstr "规则列表仅适用于 “内置预设” 配置文件。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:299
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:295
|
||||
msgid ""
|
||||
"This feature is typically used when using a self-built DNS server as an "
|
||||
"Remote / Streaming Media DNS upstream (requires support from the upstream "
|
||||
@ -714,7 +714,7 @@ msgstr ""
|
||||
"此功能通常在使用自建 DNS 服务器作为 远程 / 流媒体 DNS 上游时使用(需要上游服"
|
||||
"务器的支持)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:431
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:425
|
||||
msgid ""
|
||||
"This is the content of the file '/etc/mosdns/config_custom.yaml' from which "
|
||||
"your MosDNS configuration will be generated. Only accepts configuration "
|
||||
@ -723,31 +723,31 @@ msgstr ""
|
||||
"这是文件 “/etc/mosdns/config_custom.yaml” 的内容,您的 MosDNS 配置将从此文件"
|
||||
"生成。仅接受 yaml 格式的配置内容。"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:210
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:206
|
||||
msgid "TrafficRoute Public DNS (180.184.1.1)"
|
||||
msgstr "火山引擎公共 DNS(180.184.1.1)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:207
|
||||
msgid "TrafficRoute Public DNS (180.184.2.2)"
|
||||
msgstr "火山引擎公共 DNS(180.184.2.2)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:452
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:47
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:53
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:77
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:83
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:107
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:113
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:137
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:143
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:167
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:173
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:197
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:203
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:227
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:233
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:257
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:263
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:440
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:43
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:48
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:67
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:72
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:91
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:96
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:115
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:120
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:139
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:144
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:163
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:168
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:187
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:192
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:211
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:216
|
||||
msgid "Unable to save contents: %s"
|
||||
msgstr "无法保存内容:%s"
|
||||
|
||||
@ -780,11 +780,11 @@ msgstr "更新成功"
|
||||
msgid "Updating Database..."
|
||||
msgstr "更新数据库..."
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:167
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:163
|
||||
msgid "Warning"
|
||||
msgstr "警告"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:241
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:199
|
||||
msgid ""
|
||||
"When enabling 'Custom Stream Media DNS', added domains will always use the "
|
||||
"'Streaming Media DNS server' for resolution (one domain per line, supports "
|
||||
@ -793,7 +793,7 @@ msgstr ""
|
||||
"启用 “自定义流媒体 DNS” 时,加入的域名始终使用 “流媒体 DNS 服务器” 进行解析"
|
||||
"(每个域名一行,支持域名匹配规则)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:359
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:355
|
||||
msgid ""
|
||||
"When using custom rule sources, please use rule types supported by MosDNS "
|
||||
"(domain list or AdGuardHome rules)."
|
||||
@ -805,13 +805,13 @@ msgstr ""
|
||||
msgid "White Lists"
|
||||
msgstr "白名单"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:212
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:258
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:208
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:254
|
||||
msgid "Xinfeng Public DNS (114.114.114.114)"
|
||||
msgstr "信风公共 DNS(114.114.114.114)"
|
||||
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:213
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:259
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:209
|
||||
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:255
|
||||
msgid "Xinfeng Public DNS (114.114.115.115)"
|
||||
msgstr "信风公共 DNS(114.114.115.115)"
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=26.4.15
|
||||
PKG_RELEASE:=108
|
||||
PKG_RELEASE:=109
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@ -48,7 +48,7 @@ function gen_config(var)
|
||||
local local_http_username = var["local_http_username"]
|
||||
local local_http_password = var["local_http_password"]
|
||||
local tcp_proxy_way = var["tcp_proxy_way"]
|
||||
local server_host = var["server_host"] or node.address
|
||||
local server_host = var["server_host"] or (node.address or ""):lower()
|
||||
local server_port = var["server_port"] or node.port
|
||||
|
||||
if api.is_ipv6(server_host) then
|
||||
|
||||
@ -13,7 +13,7 @@ function gen_config(var)
|
||||
local run_type = var["run_type"]
|
||||
local local_addr = var["local_addr"]
|
||||
local local_port = var["local_port"]
|
||||
local server_host = var["server_host"] or node.address
|
||||
local server_host = var["server_host"] or (node.address or ""):lower()
|
||||
local server_port = var["server_port"] or node.port
|
||||
|
||||
if api.is_ipv6(server_host) then
|
||||
|
||||
@ -37,7 +37,7 @@ function gen_config(var)
|
||||
return
|
||||
end
|
||||
local node = uci:get_all("passwall", node_id)
|
||||
local server_host = var["server_host"] or node.address
|
||||
local server_host = var["server_host"] or (node.address or ""):lower()
|
||||
local server_port = var["server_port"] or node.port
|
||||
local local_addr = var["local_addr"]
|
||||
local local_port = var["local_port"]
|
||||
|
||||
@ -145,6 +145,8 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
tag = tag .. ":" .. remarks
|
||||
end
|
||||
|
||||
node.address = (node.address or ""):lower()
|
||||
|
||||
result = {
|
||||
_id = node_id,
|
||||
_flag = flag,
|
||||
@ -1268,7 +1270,7 @@ function gen_config(var)
|
||||
end
|
||||
if #ut_nodes == 0 then return nil end
|
||||
local valid_nodes = {}
|
||||
for i = 1, #ut_nodes do
|
||||
for i = 1, #(ut_nodes or {}) do
|
||||
local ut_node_id = ut_nodes[i]
|
||||
local ut_node_tag = "ut-" .. ut_node_id
|
||||
local is_new_ut_node = true
|
||||
@ -1823,6 +1825,7 @@ function gen_config(var)
|
||||
local domain = {}
|
||||
local nodes_domain_text = sys.exec([[uci show passwall | sed -n "s/.*\.address='\([^']*\)'/\1/p" | sort -u]])
|
||||
string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w)
|
||||
w = (w or ""):lower()
|
||||
if not api.vps_domain_exclude(w) and api.datatypes.hostname(w) and not GLOBAL.VPS_EXCLUDE[w] then
|
||||
table.insert(domain, w)
|
||||
end
|
||||
|
||||
@ -50,7 +50,7 @@ function gen_config(var)
|
||||
local run_type = var["run_type"]
|
||||
local local_addr = var["local_addr"]
|
||||
local local_port = var["local_port"]
|
||||
local server_host = var["server_host"] or node.address
|
||||
local server_host = var["server_host"] or (node.address or ""):lower()
|
||||
local server_port = var["server_port"] or node.port
|
||||
local loglevel = var["loglevel"] or 2
|
||||
local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
|
||||
|
||||
@ -12,7 +12,7 @@ function gen_config(var)
|
||||
local node = uci:get_all("passwall", node_id)
|
||||
local local_addr = var["local_addr"]
|
||||
local local_port = var["local_port"]
|
||||
local server_host = var["server_host"] or node.address
|
||||
local server_host = var["server_host"] or (node.address or ""):lower()
|
||||
local server_port = var["server_port"] or node.port
|
||||
local loglevel = var["loglevel"] or "warn"
|
||||
|
||||
|
||||
@ -124,6 +124,8 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
tag = tag .. ":" .. remarks
|
||||
end
|
||||
|
||||
node.address = (node.address or ""):lower()
|
||||
|
||||
result = {
|
||||
_id = node_id,
|
||||
_flag = flag,
|
||||
@ -1007,7 +1009,7 @@ function gen_config(var)
|
||||
blc_nodes = _node.balancing_node
|
||||
end
|
||||
local valid_nodes = {}
|
||||
for i = 1, #blc_nodes do
|
||||
for i = 1, #(blc_nodes or {}) do
|
||||
local blc_node_id = blc_nodes[i]
|
||||
local blc_node_tag = "blc-" .. blc_node_id
|
||||
local is_new_blc_node = true
|
||||
@ -1539,6 +1541,7 @@ function gen_config(var)
|
||||
local domain = {}
|
||||
local nodes_domain_text = sys.exec([[uci show passwall | sed -n "s/.*\.\(address\|download_address\)='\([^']*\)'/\2/p" | sort -u]])
|
||||
string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w)
|
||||
w = (w or ""):lower()
|
||||
if not api.vps_domain_exclude(w) and api.datatypes.hostname(w) and not GLOBAL.VPS_EXCLUDE[w] then
|
||||
table.insert(domain, "full:" .. w)
|
||||
end
|
||||
|
||||
@ -173,6 +173,7 @@ if not is_file_nonzero(file_vpslist) then
|
||||
local f_out = io.open(file_vpslist, "w")
|
||||
local written_domains = {}
|
||||
local function process_address(address)
|
||||
address = (address or ""):lower()
|
||||
if api.vps_domain_exclude(address) then return end
|
||||
if datatypes.hostname(address) and not written_domains[address] then
|
||||
f_out:write(address .. "\n")
|
||||
|
||||
@ -376,6 +376,7 @@ function add_rule(var)
|
||||
setflag_6 .. "passwall_vps6"
|
||||
}
|
||||
local function process_address(address)
|
||||
address = (address or ""):lower()
|
||||
if api.vps_domain_exclude(address) then return end
|
||||
if datatypes.hostname(address) then
|
||||
set_domain_dns(address, fwd_dns)
|
||||
|
||||
@ -333,6 +333,7 @@ if not is_file_nonzero(file_vpslist) then
|
||||
local f_out = io.open(file_vpslist, "w")
|
||||
local written_domains = {}
|
||||
local function process_address(address)
|
||||
address = (address or ""):lower()
|
||||
if api.vps_domain_exclude(address) then return end
|
||||
if datatypes.hostname(address) and not written_domains[address] then
|
||||
f_out:write(address .. "\n")
|
||||
|
||||
@ -6,10 +6,8 @@
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Material3 Theme
|
||||
LUCI_DEPENDS:=
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=1
|
||||
LUCI_TITLE:=Material3 Theme (default)
|
||||
LUCI_DEPENDS:=+luci-base
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
||||
@ -17,17 +15,10 @@ define Package/luci-theme-material3/postrm
|
||||
#!/bin/sh
|
||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||
uci -q delete luci.themes.Material3
|
||||
uci -q delete luci.themes.Material3Blue
|
||||
uci -q delete luci.themes.Material3Green
|
||||
uci -q delete luci.themes.Material3Red
|
||||
uci set luci.main.mediaurlbase='/luci-static/bootstrap'
|
||||
# uci -q delete luci.themes.Material3Dark
|
||||
# uci -q delete luci.themes.Material3Light
|
||||
uci commit luci
|
||||
}
|
||||
endef
|
||||
LUCI_MINIFY_CSS:=0
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# luci-theme-material3
|
||||
A Material Design 3 theme for OpenWrt Luci.
|
||||
|
||||
This is a personal project based on the LuCI Bootstrap theme, imitating the Material Design 3 style. Since I'm not very familiar with web theme design, the CSS code might be a bit messy. Some of the project code was completed with the assistance of Cursor AI.
|
||||
This is a personal project based on the LuCI Bootstrap theme, imitating the Material Design 3 style.
|
||||
|
||||
**Nice to initiate an issue or PR!**
|
||||
## ✨ Preview
|
||||
@ -11,31 +11,50 @@ This is a personal project based on the LuCI Bootstrap theme, imitating the Mate
|
||||
<th>📱 Mobile</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="imgs/md3-desktop-overview.jpg" style="max-height: 600px;" /></td>
|
||||
<td><img src="imgs/md3-mobile-overview.jpg" style="max-height: 600px;" /></td>
|
||||
<td><img src="imgs/desktop.png" style="max-height: 600px;" /></td>
|
||||
<td><img src="imgs/mobile.png" style="max-height: 600px;" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### 🎨 All color schemes
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="imgs/md3-mobile-default.jpg" /></td>
|
||||
<td><img src="imgs/md3-mobile-blue.jpg" /></td>
|
||||
<td><img src="imgs/md3-mobile-green.jpg" /></td>
|
||||
<td><img src="imgs/md3-mobile-red.jpg" /></td>
|
||||
<th>Baseline Purple</th>
|
||||
<th>Trust Blue</th>
|
||||
<th>Growth Green</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="imgs/baseline.jpg" /></td>
|
||||
<td><img src="imgs/blue.jpg" /></td>
|
||||
<td><img src="imgs/green.jpg" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Calm Teal</th>
|
||||
<th>Warm Orange</th>
|
||||
<th>Vivid Orange</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="imgs/teal.jpg" /></td>
|
||||
<td><img src="imgs/orange.jpg" /></td>
|
||||
<td><img src="imgs/vivid-orange.jpg" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Sakura Red</th>
|
||||
<th>Expressive Rose</th>
|
||||
<th>Monochrome Gray</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="imgs/sakura.jpg" /></td>
|
||||
<td><img src="imgs/rose.jpg" /></td>
|
||||
<td><img src="imgs/gray.jpg" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 📝 ToDo
|
||||
- [X] Dark themes
|
||||
- [ ] Fix some style issues
|
||||
- [ ] Add more color schemes
|
||||
- [ ] Improve to be closer to MD3 principles
|
||||
- [ ] Optimize CSS...
|
||||
|
||||
## 🙏 Credits
|
||||
- [OpenWrt Luci](https://github.com/openwrt/luci)
|
||||
- [Cursor](https://www.cursor.com/)
|
||||
- [OpenAI Codex](https://openai.com/codex/)
|
||||
- [MDUI](https://www.mdui.org/zh-cn/)
|
||||
- [Fluent UI System Icons](https://github.com/microsoft/fluentui-system-icons)
|
||||
- [Material Design 3](https://m3.material.io/)
|
||||
- [Reddit - LuCI theme bootstrap: Some modifications using userstyle](https://www.reddit.com/r/openwrt/comments/qmtmpf/lucithemebootstrap_some_modifications_using/)
|
||||
- [Reddit - LuCI theme bootstrap: Some modifications using userstyle](https://www.reddit.com/r/openwrt/comments/qmtmpf/lucithemebootstrap_some_modifications_using/)
|
||||
@ -1 +0,0 @@
|
||||
material3
|
||||
@ -1 +0,0 @@
|
||||
material3
|
||||
@ -1 +0,0 @@
|
||||
material3
|
||||
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||
<path d="M11.414 3.635a.5.5 0 0 0 0-.707L9.293.807a.5.5 0 0 0-.707.707l.997.997a7.48 7.48 0 0 0-4.886 2.185 7.5 7.5 0 0 0 0 10.607c.257.256.528.491.811.703a.5.5 0 0 0 .6-.8 6.516 6.516 0 0 1-.704-.611 6.5 6.5 0 0 1 4.662-11.096.506.506 0 0 0 .074-.004L8.586 5.049a.5.5 0 0 0 .707.707l2.121-2.121Zm-2.828 12.728a.5.5 0 0 0 0 .707l2.121 2.121a.5.5 0 0 0 .707-.707l-.997-.997a7.48 7.48 0 0 0 4.886-2.185 7.5 7.5 0 0 0 0-10.607 7.436 7.436 0 0 0-.811-.703.5.5 0 0 0-.6.8c.245.184.48.387.704.611a6.5 6.5 0 0 1-4.662 11.096.506.506 0 0 0-.074.004l1.554-1.554a.5.5 0 0 0-.707-.707l-2.121 2.121Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 680 B |
@ -1,3 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
|
||||
<path d="M9 3h2v9H9V3zm0 11h2v2H9v-2z" />
|
||||
</svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.0004 2.00195C9.86006 2.00195 8.125 3.73701 8.125 5.87732C8.125 8.79606 9.33243 12.4289 9.93776 14.0759C10.2606 14.9542 11.097 15.4995 12.0025 15.4995C12.9057 15.4995 13.7409 14.957 14.0646 14.0809C14.6705 12.4412 15.8757 8.827 15.8757 5.87732C15.8757 3.73701 14.1407 2.00195 12.0004 2.00195ZM9.625 5.87732C9.625 4.56544 10.6885 3.50195 12.0004 3.50195C13.3122 3.50195 14.3757 4.56544 14.3757 5.87732C14.3757 8.53153 13.2639 11.9202 12.6576 13.561C12.5621 13.8194 12.3089 13.9995 12.0025 13.9995C11.6954 13.9995 11.4412 13.8184 11.3457 13.5585C10.7387 11.9069 9.625 8.50056 9.625 5.87732ZM12.0011 17.001C10.6198 17.001 9.5 18.1208 9.5 19.5021C9.5 20.8834 10.6198 22.0032 12.0011 22.0032C13.3825 22.0032 14.5022 20.8834 14.5022 19.5021C14.5022 18.1208 13.3825 17.001 12.0011 17.001ZM11 19.5021C11 18.9492 11.4482 18.501 12.0011 18.501C12.554 18.501 13.0022 18.9492 13.0022 19.5021C13.0022 20.055 12.554 20.5032 12.0011 20.5032C11.4482 20.5032 11 20.055 11 19.5021Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 136 B After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.5495 2.53189C11.3874 1.82531 12.6126 1.82531 13.4505 2.5319L20.2005 8.224C20.7074 8.65152 21 9.2809 21 9.94406L21 19.2539C21 20.2204 20.2165 21.0039 19.25 21.0039H15.75C14.7835 21.0039 14 20.2204 14 19.2539L14 14.2468C14 14.1088 13.8881 13.9968 13.75 13.9968H10.25C10.1119 13.9968 9.99999 14.1088 9.99999 14.2468L9.99999 19.2539C9.99999 20.2204 9.2165 21.0039 8.25 21.0039H4.75C3.7835 21.0039 3 20.2204 3 19.2539V9.94406C3 9.2809 3.29255 8.65152 3.79952 8.224L10.5495 2.53189ZM12.4835 3.6786C12.2042 3.44307 11.7958 3.44307 11.5165 3.6786L4.76651 9.37071C4.59752 9.51321 4.5 9.72301 4.5 9.94406L4.5 19.2539C4.5 19.392 4.61193 19.5039 4.75 19.5039H8.25C8.38807 19.5039 8.49999 19.392 8.49999 19.2539L8.49999 14.2468C8.49999 13.2803 9.2835 12.4968 10.25 12.4968H13.75C14.7165 12.4968 15.5 13.2803 15.5 14.2468L15.5 19.2539C15.5 19.392 15.6119 19.5039 15.75 19.5039H19.25C19.3881 19.5039 19.5 19.392 19.5 19.2539L19.5 9.94406C19.5 9.72301 19.4025 9.51321 19.2335 9.37071L12.4835 3.6786Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -1,4 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#5f6368"
|
||||
d="M12.996 11.34h-2.1V9.45h2.1v1.9-.01zm0-6.53h-2.1v1.95h2.1V4.81zm2.5 4.64h-2.11v1.9h2.11v-1.9zm-5-2.3h-2.1v1.92h2.11V7.15h-.01zm2.5 0h-2.1v1.92h2.1V7.15zm8.88 3.2c-.45-.32-1.54-.42-2.34-.26-.1-.76-.55-1.44-1.32-2.05l-.44-.28-.3.44c-.57.9-.73 2.37-.12 3.34-.29.16-.83.35-1.54.35H1.846a6.7 6.7 0 0 0 1.41 5.19c1.19 1.4 2.98 2.11 5.29 2.11 5.03 0 8.78-2.3 10.5-6.53.68 0 2.19 0 2.92-1.44.03-.07.23-.42.26-.55l-.35-.32zm-16.38-.9h-2.11v1.9h2.12v-1.9h-.01zm2.5 0h-2.12v1.9h2.12v-1.9zm2.5 0h-2.12v1.9h2.11v-1.9h.01zm-2.5-2.3h-2.12v1.92h2.12V7.15z" />
|
||||
</svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.04873 7.98306C6.19566 7.59578 6.62872 7.40094 7.016 7.54788L12 9.43876L16.9839 7.54788C17.3712 7.40094 17.8043 7.59578 17.9512 7.98306C18.0981 8.37034 17.9033 8.8034 17.516 8.95033L12.75 10.7585V16.2491C12.75 16.6634 12.4142 16.9991 12 16.9991C11.5858 16.9991 11.25 16.6634 11.25 16.2491V10.7586L6.48392 8.95033C6.09664 8.8034 5.9018 8.37034 6.04873 7.98306ZM10.5911 2.51106C11.4947 2.14475 12.5053 2.14475 13.4089 2.51106L20.9075 5.55102C21.5679 5.81876 22 6.4602 22 7.17282V16.8255C22 17.5381 21.5679 18.1796 20.9075 18.4473L13.4089 21.4873C12.5053 21.8536 11.4947 21.8536 10.5911 21.4873L3.09252 18.4473C2.43211 18.1796 2 17.5381 2 16.8255V7.17282C2 6.4602 2.43211 5.81876 3.09252 5.55102L10.5911 2.51106ZM12.8453 3.90116C12.3032 3.68138 11.6968 3.68138 11.1547 3.90116L3.65607 6.94113C3.56173 6.97938 3.5 7.07102 3.5 7.17282V16.8255C3.5 16.9273 3.56173 17.019 3.65607 17.0572L11.1547 20.0972C11.6968 20.317 12.3032 20.317 12.8453 20.0972L20.3439 17.0572C20.4383 17.019 20.5 16.9273 20.5 16.8255V7.17282C20.5 7.07102 20.4383 6.97938 20.3439 6.94113L12.8453 3.90116Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 647 B After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.21967 2.21967C1.9534 2.48594 1.9292 2.9026 2.14705 3.19621L2.21967 3.28033L6.25424 7.3149C4.33225 8.66437 2.89577 10.6799 2.29888 13.0644C2.1983 13.4662 2.4425 13.8735 2.84431 13.9741C3.24613 14.0746 3.6534 13.8305 3.75399 13.4286C4.28346 11.3135 5.59112 9.53947 7.33416 8.39452L9.14379 10.2043C8.43628 10.9258 8 11.9143 8 13.0046C8 15.2138 9.79086 17.0046 12 17.0046C13.0904 17.0046 14.0788 16.5683 14.8004 15.8608L20.7197 21.7803C21.0126 22.0732 21.4874 22.0732 21.7803 21.7803C22.0466 21.5141 22.0708 21.0974 21.8529 20.8038L21.7803 20.7197L15.6668 14.6055L15.668 14.604L14.4679 13.4061L11.598 10.5368L11.6 10.536L8.71877 7.65782L8.72 7.656L7.58672 6.52549L3.28033 2.21967C2.98744 1.92678 2.51256 1.92678 2.21967 2.21967ZM10.2041 11.2655L13.7392 14.8006C13.2892 15.2364 12.6759 15.5046 12 15.5046C10.6193 15.5046 9.5 14.3853 9.5 13.0046C9.5 12.3287 9.76824 11.7154 10.2041 11.2655ZM12 5.5C10.9997 5.5 10.0291 5.64807 9.11109 5.925L10.3481 7.16119C10.8839 7.05532 11.4364 7 12 7C15.9231 7 19.3099 9.68026 20.2471 13.4332C20.3475 13.835 20.7546 14.0794 21.1565 13.9791C21.5584 13.8787 21.8028 13.4716 21.7024 13.0697C20.5994 8.65272 16.6155 5.5 12 5.5ZM12.1947 9.00928L15.996 12.81C15.8942 10.7531 14.2472 9.10764 12.1947 9.00928Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.9999 9.00462C14.209 9.00462 15.9999 10.7955 15.9999 13.0046C15.9999 15.2138 14.209 17.0046 11.9999 17.0046C9.79073 17.0046 7.99987 15.2138 7.99987 13.0046C7.99987 10.7955 9.79073 9.00462 11.9999 9.00462ZM11.9999 10.5046C10.6192 10.5046 9.49987 11.6239 9.49987 13.0046C9.49987 14.3853 10.6192 15.5046 11.9999 15.5046C13.3806 15.5046 14.4999 14.3853 14.4999 13.0046C14.4999 11.6239 13.3806 10.5046 11.9999 10.5046ZM11.9999 5.5C16.6134 5.5 20.596 8.65001 21.701 13.0644C21.8016 13.4662 21.5574 13.8735 21.1556 13.9741C20.7537 14.0746 20.3465 13.8305 20.2459 13.4286C19.307 9.67796 15.9212 7 11.9999 7C8.07681 7 4.68997 9.68026 3.75273 13.4332C3.65237 13.835 3.24523 14.0794 2.84336 13.9791C2.44149 13.8787 2.19707 13.4716 2.29743 13.0697C3.40052 8.65272 7.38436 5.5 11.9999 5.5Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 910 B |
@ -1,4 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#5f6368"
|
||||
d="m10 15.6 1.5 1.4 5-5-5-5-1.4 1.4 2.6 2.6H3v2h9.7L10 15.6zM19 3H5a2 2 0 0 0-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z" />
|
||||
</svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.50215 11.4995C9.05562 11.4995 9.5043 11.9482 9.5043 12.5017C9.5043 13.0552 9.05562 13.5038 8.50215 13.5038C7.94868 13.5038 7.5 13.0552 7.5 12.5017C7.5 11.9482 7.94868 11.4995 8.50215 11.4995ZM12 4.3537V10.4995L12.0005 11.0045L19.442 11.0035L17.7196 9.27977C17.4534 9.01346 17.4292 8.59679 17.6471 8.30321L17.7198 8.21911C17.9861 7.95289 18.4027 7.92875 18.6963 8.14666L18.7804 8.21929L21.777 11.2169C22.043 11.483 22.0674 11.8992 21.85 12.1928L21.7775 12.2769L18.7809 15.2803C18.4884 15.5736 18.0135 15.5741 17.7203 15.2816C17.4537 15.0156 17.429 14.599 17.6465 14.3051L17.7191 14.2209L19.432 12.5035L12.0005 12.5045L12 19.2495C12 19.7159 11.5788 20.0692 11.1196 19.9881L2.61955 18.4868C2.26121 18.4235 2 18.1121 2 17.7482V5.74953C2 5.38222 2.26601 5.06896 2.62847 5.00944L11.1285 3.61361C11.5851 3.53863 12 3.89097 12 4.3537ZM10.5 5.2369L3.5 6.38641V17.1191L10.5 18.3555V5.2369ZM13 18.5008L13.7652 18.501L13.867 18.4941C14.2335 18.4443 14.5158 18.1299 14.5152 17.7497L14.508 13.4995H13V18.5008ZM13.002 9.99953L13 8.72487V4.99952L13.7453 4.99953C14.1245 4.99953 14.4381 5.28105 14.4883 5.64664L14.4953 5.74829L14.502 9.99953H13.002Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 1.2 KiB |
@ -1 +1,3 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1761042005281" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8444" width="16" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M817.834667 627.643733h-272.725334v-80.554666a93.661867 93.661867 0 0 0-33.109333-181.248 93.661867 93.661867 0 0 0-33.109333 181.248v80.554666H206.165333c-49.493333 0-89.770667 40.277333-89.770666 89.770667v114.688c0 49.493333 40.277333 89.429333 89.770666 89.429333h611.669334c49.493333 0 89.770667-39.936 89.770666-89.429333v-114.688c0-49.493333-40.277333-89.770667-89.770666-89.770667z m-598.698667 181.248a34.0992 34.0992 0 0 1-34.474667-34.133333c0-18.773333 15.36-34.133333 34.474667-34.133333 18.773333 0 33.792 15.36 33.792 34.133333 0 19.114667-15.018667 34.133333-33.792 34.133333z m136.533333 0a34.0992 34.0992 0 0 1-34.474666-34.133333c0-18.773333 15.36-34.133333 34.474666-34.133333 18.773333 0 33.792 15.36 33.792 34.133333 0 19.114667-15.018667 34.133333-33.792 34.133333z m136.533334 0a34.0992 34.0992 0 0 1-34.474667-34.133333c0-18.773333 15.36-34.133333 34.474667-34.133333 18.773333 0 33.792 15.36 33.792 34.133333 0 19.114667-15.018667 34.133333-33.792 34.133333z" p-id="8445"></path><path d="M190.293333 508.791467a32.9728 32.9728 0 0 0 31.300267-34.542934A292.181333 292.181333 0 0 1 306.176 253.508267c113.595733-113.5616 298.325333-113.5616 411.8528 0a291.7376 291.7376 0 0 1 84.411733 220.706133 32.9728 32.9728 0 0 0 65.8432 3.310933c5.085867-101.034667-32.699733-199.68-103.6288-270.6432-139.264-139.195733-365.841067-139.264-505.105066 0a358.126933 358.126933 0 0 0-103.799467 270.609067 33.041067 33.041067 0 0 0 34.542933 31.300267z" p-id="8446"></path><path d="M352.768 300.1344c-46.523733 46.557867-69.973333 111.616-64.375467 178.517333 1.501867 18.090667 17.066667 31.880533 35.601067 30.037334a32.938667 32.938667 0 0 0 30.1056-35.601067c-3.9936-47.5136 12.4928-93.559467 45.294933-126.327467a159.573333 159.573333 0 0 1 225.416534-0.034133c32.768 32.733867 49.186133 78.813867 45.124266 126.327467a32.9728 32.9728 0 0 0 65.706667 5.597866c5.700267-66.935467-17.7152-132.027733-64.238933-178.517333a225.553067 225.553067 0 0 0-318.634667 0z" p-id="8447"></path></svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 3.5C7.85786 3.5 4.5 6.85786 4.5 11V11.25C4.5 11.6642 4.16421 12 3.75 12C3.33579 12 3 11.6642 3 11.25V11C3 6.02944 7.02944 2 12 2C16.9706 2 21 6.02944 21 11V11.25C21 11.6642 20.6642 12 20.25 12C19.8358 12 19.5 11.6642 19.5 11.25V11C19.5 6.85786 16.1421 3.5 12 3.5ZM12 6.5C9.51472 6.5 7.5 8.51472 7.5 11V11.25C7.5 11.6642 7.16421 12 6.75 12C6.33579 12 6 11.6642 6 11.25V11C6 7.68629 8.68629 5 12 5C15.3137 5 18 7.68629 18 11V11.25C18 11.6642 17.6642 12 17.25 12C16.8358 12 16.5 11.6642 16.5 11.25V11C16.5 8.51472 14.4853 6.5 12 6.5ZM12 8C10.3431 8 9 9.34315 9 11C9 12.3979 9.95608 13.5725 11.25 13.9055V16H6C4.34315 16 3 17.3431 3 19C3 20.6569 4.34315 22 6 22H18C19.6569 22 21 20.6569 21 19C21 17.3431 19.6569 16 18 16H12.75V13.9055C14.0439 13.5725 15 12.3979 15 11C15 9.34315 13.6569 8 12 8ZM10.5 11C10.5 10.1716 11.1716 9.5 12 9.5C12.8284 9.5 13.5 10.1716 13.5 11C13.5 11.8284 12.8284 12.5 12 12.5C11.1716 12.5 10.5 11.8284 10.5 11ZM6 17.5H18C18.8284 17.5 19.5 18.1716 19.5 19C19.5 19.8284 18.8284 20.5 18 20.5H6C5.17157 20.5 4.5 19.8284 4.5 19C4.5 18.1716 5.17157 17.5 6 17.5Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||
<path d="M15.493 13.497C13.565 16.836 9.296 17.98 5.957 16.052c-.757-.437-1.412-1-1.946-1.663 2.83-1.087 4.557-2.421 5.592-4.396 1.048-2 1.337-4.161.76-6.91.898.118 1.77.412 2.575.877 3.339 1.928 4.483 6.198 2.555 9.537Zm-10.036 3.421c3.817 2.204 8.698.896 10.902-2.921 2.204-3.818.896-8.699-2.921-10.903a7.97 7.97 0 0 0-3.557-1.059.575.575 0 0 0-.614.74c.688 2.819.434 4.876-.55 6.753-.934 1.784-2.544 3.031-5.55 4.107a.578.578 0 0 0-.292.903 7.98 7.98 0 0 0 2.582 2.38Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 564 B |
@ -1 +1,3 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1761041450663" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5826" width="16" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M888 128H170.4c-39.6 0-71.9 32.2-72 71.7-0.3 2.7-0.4 5.5-0.4 8.2v607.6c0 2.8 0.1 5.5 0.4 8.3 0.2 39.5 32.4 71.7 72 71.7h4.6c1 0 2 0.1 3 0.1h29c1 0 2 0 3-0.1h678c39.7 0 72-32.3 72-72V200c0-39.7-32.3-72-72-72z m-220 72v623.6H515.5V200H668zM192.5 447.1c-19.9 0-36-16.1-36-36s16.1-36 36-36 36 16.1 36 36-16.1 36-36 36z m0-118.3c-19.9 0-36-16.1-36-36s16.1-36 36-36 36 16.1 36 36-16.1 36-36 36zM286.6 200h157v623.6h-157c0.3-2.6 0.4-5.3 0.4-7.9V208c0-2.7-0.2-5.4-0.4-8zM888 823.6H740V200h148v623.6z" p-id="5827"></path><path d="M329.8 256.3h72v120h-72zM555.8 256.3h72v120h-72zM777.2 256.3h72v120h-72z" p-id="5828"></path></svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.41521 5.26999C5.791 4.49336 6.57779 4 7.44057 4H16.5594C17.4222 4 18.209 4.49336 18.5848 5.26999L21.6755 11.6575C21.8891 12.0988 22 12.5828 22 13.0731V16.75C22 17.9926 20.9926 19 19.75 19H4.25C3.00736 19 2 17.9926 2 16.75V13.0731C2 12.5828 2.11093 12.0988 2.32448 11.6575L5.41521 5.26999ZM17.2346 5.92333C17.1093 5.66445 16.847 5.5 16.5594 5.5H7.44057C7.15297 5.5 6.89071 5.66445 6.76545 5.92333L4.30899 11H19.691L17.2346 5.92333ZM3.5 13.25V16.75C3.5 17.1642 3.83579 17.5 4.25 17.5H19.75C20.1642 17.5 20.5 17.1642 20.5 16.75V13.25C20.5 12.8358 20.1642 12.5 19.75 12.5H4.25C3.83579 12.5 3.5 12.8358 3.5 13.25ZM18 16C18.5523 16 19 15.5523 19 15C19 14.4477 18.5523 14 18 14C17.4477 14 17 14.4477 17 15C17 15.5523 17.4477 16 18 16Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 951 B After Width: | Height: | Size: 861 B |
@ -1 +1,3 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1761042033823" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9763" width="16" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M911.6 645.7h-72.8V499.2H524.1V378.3h72.8c26.7 0 48.4-21.7 48.4-48.4v-97.2c0-26.7-21.7-48.4-48.4-48.4H427.1c-26.7 0-48.4 21.7-48.4 48.4v97.2c0 26.7 21.7 48.4 48.4 48.4h72.8v120.8H185.2v146.5h-72.8C85.7 645.6 64 667.3 64 694v97.2c0 26.7 21.7 48.4 48.4 48.4h169.8c26.7 0 48.4-21.7 48.4-48.4V694c0-26.7-21.7-48.4-48.4-48.4h-72.8V523.4h290.5v122.3h-72.8c-26.7 0-48.4 21.7-48.4 48.4v97.2c0 26.7 21.7 48.4 48.4 48.4h169.8c26.7 0 48.4-21.7 48.4-48.4v-97.2c0-26.7-21.7-48.4-48.4-48.4h-72.8V523.4h290.5v122.3h-72.8c-26.7 0-48.4 21.7-48.4 48.4v97.2c0 26.7 21.7 48.4 48.4 48.4h169.8c26.7 0 48.4-21.7 48.4-48.4v-97.2c0-26.8-21.7-48.4-48.4-48.4z" p-id="9764"></path></svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.0001 1.99805C17.5238 1.99805 22.0016 6.47589 22.0016 11.9996C22.0016 17.5233 17.5238 22.0011 12.0001 22.0011C6.47638 22.0011 1.99854 17.5233 1.99854 11.9996C1.99854 6.47589 6.47638 1.99805 12.0001 1.99805ZM14.939 16.4993H9.06118C9.71322 18.9135 10.8466 20.5011 12.0001 20.5011C13.1536 20.5011 14.2869 18.9135 14.939 16.4993ZM7.5084 16.4999L4.78591 16.4998C5.74425 18.0328 7.1777 19.2384 8.88008 19.9104C8.3578 19.0906 7.92681 18.0643 7.60981 16.8949L7.5084 16.4999ZM19.2143 16.4998L16.4918 16.4999C16.168 17.8337 15.7004 18.9995 15.119 19.9104C16.716 19.2804 18.0757 18.1814 19.0291 16.7833L19.2143 16.4998ZM7.09351 9.99895H3.7359L3.73115 10.0162C3.57906 10.6525 3.49854 11.3166 3.49854 11.9996C3.49854 13.0558 3.69112 14.0669 4.0431 14.9999L7.21626 14.9995C7.07396 14.0504 6.99854 13.0422 6.99854 11.9996C6.99854 11.3156 7.031 10.6464 7.09351 9.99895ZM15.397 9.99901H8.60316C8.53514 10.6393 8.49853 11.309 8.49853 11.9996C8.49853 13.0591 8.58468 14.0694 8.73827 14.9997H15.2619C15.4155 14.0694 15.5016 13.0591 15.5016 11.9996C15.5016 11.309 15.465 10.6393 15.397 9.99901ZM20.2647 9.99811L16.9067 9.99897C16.9692 10.6464 17.0016 11.3156 17.0016 11.9996C17.0016 13.0422 16.9262 14.0504 16.7839 14.9995L19.9571 14.9999C20.309 14.0669 20.5016 13.0558 20.5016 11.9996C20.5016 11.3102 20.4196 10.64 20.2647 9.99811ZM8.88114 4.08875L8.85823 4.09747C6.81092 4.91218 5.1549 6.49949 4.25023 8.49935L7.29835 8.49972C7.61171 6.74693 8.15855 5.221 8.88114 4.08875ZM12.0001 3.49805L11.8844 3.50335C10.619 3.6191 9.39651 5.62107 8.8288 8.4993H15.1714C14.6052 5.62914 13.388 3.63033 12.1264 3.50436L12.0001 3.49805ZM15.1201 4.08881L15.2269 4.2629C15.8961 5.37537 16.4043 6.83525 16.7018 8.49972L19.7499 8.49935C18.8853 6.58795 17.3343 5.05341 15.4113 4.21008L15.1201 4.08881Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 990 B After Width: | Height: | Size: 1.9 KiB |
@ -1,6 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
|
||||
<path fill="#5f6368"
|
||||
d="M4.74 2.25h3.82q2.48 0 2.48 2.49v3.82q0 2.48-2.48 2.48H4.74q-2.49 0-2.49-2.48V4.74q0-2.49 2.49-2.49zm10.13 0h3.82q2.48 0 2.48 2.49v3.82q0 2.48-2.48 2.48h-3.82q-2.49 0-2.49-2.48V4.74q0-2.49 2.49-2.49zM4.74 12.38h3.82q2.48 0 2.48 2.49v3.82q0 2.48-2.48 2.48H4.74q-2.49 0-2.49-2.48v-3.82q0-2.49 2.49-2.49z" />
|
||||
<path fill="#5f6368"
|
||||
d="m12.67 14.96 2.3-2.3q1.8-1.8 3.53 0l2.39 2.3q1.72 1.82 0 3.54l-2.4 2.39q-1.71 1.72-3.53 0l-2.3-2.4q-1.8-1.71 0-3.53z" />
|
||||
</svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18.4923 2.33088L21.671 5.50966C22.5497 6.38834 22.5497 7.81296 21.671 8.69164L19.0866 11.2756C20.1696 11.438 21 12.3723 21 13.5006V18.7506C21 19.9932 19.9926 21.0006 18.75 21.0006H5.25C4.00736 21.0006 3 19.9932 3 18.7506V5.25055C3 4.00791 4.00736 3.00055 5.25 3.00055H10.5C11.6289 3.00055 12.5637 3.83201 12.7253 4.91596L15.3103 2.33088C16.189 1.45221 17.6136 1.45221 18.4923 2.33088ZM4.5 18.7506C4.5 19.1648 4.83579 19.5006 5.25 19.5006L11.249 19.4999L11.25 12.7506L4.5 12.7499V18.7506ZM12.749 19.4999L18.75 19.5006C19.1642 19.5006 19.5 19.1648 19.5 18.7506V13.5006C19.5 13.0863 19.1642 12.7506 18.75 12.7506L12.749 12.7499V19.4999ZM10.5 4.50055H5.25C4.83579 4.50055 4.5 4.83634 4.5 5.25055V11.2499H11.25V5.25055C11.25 4.83634 10.9142 4.50055 10.5 4.50055ZM12.75 9.30988V11.2506L14.69 11.2499L12.75 9.30988ZM16.3709 3.39154L13.1922 6.57032C12.8993 6.86321 12.8993 7.33808 13.1922 7.63098L16.3709 10.8097C16.6638 11.1026 17.1387 11.1026 17.4316 10.8097L20.6104 7.63098C20.9033 7.33808 20.9033 6.86321 20.6104 6.57032L17.4316 3.39154C17.1387 3.09865 16.6638 3.09865 16.3709 3.39154Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 569 B After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M12 3C6.75 3 2.5 6.9 2.5 11.7C2.5 15.8 5.85 19.25 10.3 20.15C11.35 20.36 12.25 19.55 12.25 18.55V17.7C12.25 16.98 12.83 16.4 13.55 16.4H15.95C19.15 16.4 21.5 14.15 21.5 11.2C21.5 6.65 17.25 3 12 3ZM10.02 18.68C6.58 17.95 4 15.08 4 11.7C4 7.75 7.58 4.5 12 4.5C16.45 4.5 20 7.5 20 11.2C20 13.3 18.38 14.9 15.95 14.9H13.55C12.01 14.9 10.75 16.16 10.75 17.7V18.55C10.75 18.65 10.67 18.82 10.42 18.77C10.28 18.74 10.15 18.71 10.02 18.68Z" fill="currentColor"/>
|
||||
<path d="M7.25 11.25C8.08 11.25 8.75 10.58 8.75 9.75C8.75 8.92 8.08 8.25 7.25 8.25C6.42 8.25 5.75 8.92 5.75 9.75C5.75 10.58 6.42 11.25 7.25 11.25Z" fill="currentColor"/>
|
||||
<path d="M11 8.5C11.83 8.5 12.5 7.83 12.5 7C12.5 6.17 11.83 5.5 11 5.5C10.17 5.5 9.5 6.17 9.5 7C9.5 7.83 10.17 8.5 11 8.5Z" fill="currentColor"/>
|
||||
<path d="M15.5 9.25C16.33 9.25 17 8.58 17 7.75C17 6.92 16.33 6.25 15.5 6.25C14.67 6.25 14 6.92 14 7.75C14 8.58 14.67 9.25 15.5 9.25Z" fill="currentColor"/>
|
||||
<path d="M17.25 13.25C18.08 13.25 18.75 12.58 18.75 11.75C18.75 10.92 18.08 10.25 17.25 10.25C16.42 10.25 15.75 10.92 15.75 11.75C15.75 12.58 16.42 13.25 17.25 13.25Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.25 3C5.00736 3 4 4.00736 4 5.25V18.75C4 19.9926 5.00736 21 6.25 21H8.75C9.99264 21 11 19.9926 11 18.75V5.25C11 4.00736 9.99264 3 8.75 3H6.25ZM5.5 5.25C5.5 4.83579 5.83579 4.5 6.25 4.5H8.75C9.16421 4.5 9.5 4.83579 9.5 5.25V18.75C9.5 19.1642 9.16421 19.5 8.75 19.5H6.25C5.83579 19.5 5.5 19.1642 5.5 18.75V5.25ZM15.25 3C14.0074 3 13 4.00736 13 5.25V18.75C13 19.9926 14.0074 21 15.25 21H17.75C18.9926 21 20 19.9926 20 18.75V5.25C20 4.00736 18.9926 3 17.75 3H15.25ZM14.5 5.25C14.5 4.83579 14.8358 4.5 15.25 4.5H17.75C18.1642 4.5 18.5 4.83579 18.5 5.25V18.75C18.5 19.1642 18.1642 19.5 17.75 19.5H15.25C14.8358 19.5 14.5 19.1642 14.5 18.75V5.25Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 772 B |
@ -1,4 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path
|
||||
d='M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z' />
|
||||
</svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 4.5C7.85786 4.5 4.5 7.85786 4.5 12C4.5 16.1421 7.85786 19.5 12 19.5C16.1421 19.5 19.5 16.1421 19.5 12C19.5 11.6236 19.4723 11.2538 19.4188 10.8923C19.3515 10.4382 19.6839 10 20.1429 10C20.5138 10 20.839 10.2562 20.8953 10.6228C20.9642 11.0718 21 11.5317 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C14.3051 3 16.4077 3.86656 18 5.29168V4.25C18 3.83579 18.3358 3.5 18.75 3.5C19.1642 3.5 19.5 3.83579 19.5 4.25V7.25C19.5 7.66421 19.1642 8 18.75 8H15.75C15.3358 8 15 7.66421 15 7.25C15 6.83579 15.3358 6.5 15.75 6.5H17.0991C15.7609 5.25883 13.9691 4.5 12 4.5Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 731 B |
@ -1,4 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#5f6368"
|
||||
d="M20 13H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 19c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" />
|
||||
</svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.25 6C8.83579 6 8.5 6.33579 8.5 6.75C8.5 7.16421 8.83579 7.5 9.25 7.5H14.75C15.1642 7.5 15.5 7.16421 15.5 6.75C15.5 6.33579 15.1642 6 14.75 6H9.25ZM8.5 17.75C8.5 17.3358 8.83579 17 9.25 17H14.75C15.1642 17 15.5 17.3358 15.5 17.75C15.5 18.1642 15.1642 18.5 14.75 18.5H9.25C8.83579 18.5 8.5 18.1642 8.5 17.75ZM9.25 14C8.83579 14 8.5 14.3358 8.5 14.75C8.5 15.1642 8.83579 15.5 9.25 15.5H14.75C15.1642 15.5 15.5 15.1642 15.5 14.75C15.5 14.3358 15.1642 14 14.75 14H9.25ZM6 5C6 3.34315 7.34315 2 9 2H15C16.6569 2 18 3.34315 18 5V19C18 20.6569 16.6569 22 15 22H9C7.34315 22 6 20.6569 6 19V5ZM9 3.5C8.17157 3.5 7.5 4.17157 7.5 5V19C7.5 19.8284 8.17157 20.5 9 20.5H15C15.8284 20.5 16.5 19.8284 16.5 19V5C16.5 4.17157 15.8284 3.5 15 3.5H9Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 359 B After Width: | Height: | Size: 862 B |
@ -1,5 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#5f6368" d="M18.8 8.12a2.91 2.91 0 1 1 2.9-2.91 2.91 2.91 0 0 1-2.9 2.9z" />
|
||||
<path fill="#5f6368"
|
||||
d="M15.38 21.7H7.65a5.28 5.28 0 0 1-.74-.05l-.34-.05a4.62 4.62 0 0 1-4.17-4.17l-.05-.34c0-.12-.03-.23-.04-.34l-.02-.4V8.62a5.28 5.28 0 0 1 .06-.74l.05-.34a4.62 4.62 0 0 1 4.17-4.17l.34-.05c.12 0 .23-.03.34-.04l.4-.02h5.9a.96.96 0 0 1 .75.35.98.98 0 0 1 .2.82.13.13 0 0 1 0 .03.12.12 0 0 0 0 .03 2.09 2.09 0 0 0-.05.3 4.52 4.52 0 0 0 .07 1.29l.02.07a2.06 2.06 0 0 0 .07.25 3.34 3.34 0 0 0 .36.9 3.17 3.17 0 0 0 .17.28l.04.06a4.6 4.6 0 0 0 1.18 1.19l.06.03.28.17a3.35 3.35 0 0 0 .9.37 2.06 2.06 0 0 0 .25.07l.07.02a4.63 4.63 0 0 0 .9.08c.13 0 .26 0 .4-.02l.13-.02.17-.02a.13.13 0 0 0 .03 0 .13.13 0 0 1 .03 0 1.01 1.01 0 0 1 .19-.03.97.97 0 0 1 .97.97v5.9a5.23 5.23 0 0 1-.06.74l-.05.33a4.62 4.62 0 0 1-4.18 4.18l-.33.05c-.11 0-.23.03-.34.04l-.4.02zM6.9 16.38a.74.74 0 0 0-.72.73.73.73 0 0 0 .72.72h8.74a.73.73 0 0 0 0-1.45H6.9zm0-3.88a.73.73 0 0 0-.72.72.74.74 0 0 0 .72.73h4.86a.74.74 0 0 0 .73-.73.73.73 0 0 0-.73-.72H6.9z" />
|
||||
</svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.75 3C19.5449 3 21 4.45507 21 6.25V17.75C21 19.5449 19.5449 21 17.75 21H6.25C4.45507 21 3 19.5449 3 17.75V6.25C3 4.45507 4.45507 3 6.25 3H17.75ZM4.5 17.75C4.5 18.7165 5.2835 19.5 6.25 19.5H11.5V9.5H4.5V17.75ZM13 16V19.5H17.75C18.7165 19.5 19.5 18.7165 19.5 17.75V16H13ZM13 14.5H19.5V6.25C19.5 5.2835 18.7165 4.5 17.75 4.5H13V14.5ZM6.25 4.5C5.2835 4.5 4.5 5.2835 4.5 6.25V8H11.5V4.5H6.25Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 521 B |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||
<path d="M10 2C10.2761 2 10.5 2.22386 10.5 2.5V3.5C10.5 3.77614 10.2761 4 10 4C9.72386 4 9.5 3.77614 9.5 3.5V2.5C9.5 2.22386 9.72386 2 10 2ZM10 14C12.2091 14 14 12.2091 14 10C14 7.79086 12.2091 6 10 6C7.79086 6 6 7.79086 6 10C6 12.2091 7.79086 14 10 14ZM10 13C8.34315 13 7 11.6569 7 10C7 8.34315 8.34315 7 10 7C11.6569 7 13 8.34315 13 10C13 11.6569 11.6569 13 10 13ZM17.5 10.5C17.7761 10.5 18 10.2761 18 10C18 9.72386 17.7761 9.5 17.5 9.5H16.5C16.2239 9.5 16 9.72386 16 10C16 10.2761 16.2239 10.5 16.5 10.5H17.5ZM10 16C10.2761 16 10.5 16.2239 10.5 16.5V17.5C10.5 17.7761 10.2761 18 10 18C9.72386 18 9.5 17.7761 9.5 17.5V16.5C9.5 16.2239 9.72386 16 10 16ZM3.5 10.5C3.77614 10.5 4 10.2761 4 10C4 9.72386 3.77614 9.5 3.5 9.5H2.46289C2.18675 9.5 1.96289 9.72386 1.96289 10C1.96289 10.2761 2.18675 10.5 2.46289 10.5H3.5ZM4.14645 4.14645C4.34171 3.95118 4.65829 3.95118 4.85355 4.14645L5.85355 5.14645C6.04882 5.34171 6.04882 5.65829 5.85355 5.85355C5.65829 6.04882 5.34171 6.04882 5.14645 5.85355L4.14645 4.85355C3.95118 4.65829 3.95118 4.34171 4.14645 4.14645ZM4.85355 15.8536C4.65829 16.0488 4.34171 16.0488 4.14645 15.8536C3.95118 15.6583 3.95118 15.3417 4.14645 15.1464L5.14645 14.1464C5.34171 13.9512 5.65829 13.9512 5.85355 14.1464C6.04882 14.3417 6.04882 14.6583 5.85355 14.8536L4.85355 15.8536ZM15.8536 4.14645C15.6583 3.95118 15.3417 3.95118 15.1464 4.14645L14.1464 5.14645C13.9512 5.34171 13.9512 5.65829 14.1464 5.85355C14.3417 6.04882 14.6583 6.04882 14.8536 5.85355L15.8536 4.85355C16.0488 4.65829 16.0488 4.34171 15.8536 4.14645ZM15.1464 15.8536C15.3417 16.0488 15.6583 16.0488 15.8536 15.8536C16.0488 15.6583 16.0488 15.3417 15.8536 15.1464L14.8536 14.1464C14.6583 13.9512 14.3417 13.9512 14.1464 14.1464C13.9512 14.3417 13.9512 14.6583 14.1464 14.8536L15.1464 15.8536Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@ -1,4 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#5f6368"
|
||||
d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z" />
|
||||
</svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.0122 2.25C12.7462 2.25846 13.4773 2.34326 14.1937 2.50304C14.5064 2.57279 14.7403 2.83351 14.7758 3.15196L14.946 4.67881C15.0231 5.37986 15.615 5.91084 16.3206 5.91158C16.5103 5.91188 16.6979 5.87238 16.8732 5.79483L18.2738 5.17956C18.5651 5.05159 18.9055 5.12136 19.1229 5.35362C20.1351 6.43464 20.8889 7.73115 21.3277 9.14558C21.4223 9.45058 21.3134 9.78203 21.0564 9.9715L19.8149 10.8866C19.4607 11.1468 19.2516 11.56 19.2516 11.9995C19.2516 12.4389 19.4607 12.8521 19.8157 13.1129L21.0582 14.0283C21.3153 14.2177 21.4243 14.5492 21.3297 14.8543C20.8911 16.2685 20.1377 17.5649 19.1261 18.6461C18.9089 18.8783 18.5688 18.9483 18.2775 18.8206L16.8712 18.2045C16.4688 18.0284 16.0068 18.0542 15.6265 18.274C15.2463 18.4937 14.9933 18.8812 14.945 19.3177L14.7759 20.8444C14.741 21.1592 14.5122 21.4182 14.204 21.4915C12.7556 21.8361 11.2465 21.8361 9.79803 21.4915C9.48991 21.4182 9.26105 21.1592 9.22618 20.8444L9.05736 19.32C9.00777 18.8843 8.75434 18.498 8.37442 18.279C7.99451 18.06 7.5332 18.0343 7.1322 18.2094L5.72557 18.8256C5.43422 18.9533 5.09403 18.8833 4.87678 18.6509C3.86462 17.5685 3.11119 16.2705 2.6732 14.8548C2.57886 14.5499 2.68786 14.2186 2.94485 14.0293L4.18818 13.1133C4.54232 12.8531 4.75147 12.4399 4.75147 12.0005C4.75147 11.561 4.54232 11.1478 4.18771 10.8873L2.94516 9.97285C2.6878 9.78345 2.5787 9.45178 2.67337 9.14658C3.11212 7.73215 3.86594 6.43564 4.87813 5.35462C5.09559 5.12236 5.43594 5.05259 5.72724 5.18056L7.12762 5.79572C7.53056 5.97256 7.9938 5.94585 8.37577 5.72269C8.75609 5.50209 9.00929 5.11422 9.05817 4.67764L9.22824 3.15196C9.26376 2.83335 9.49786 2.57254 9.8108 2.50294C10.5281 2.34342 11.26 2.25865 12.0122 2.25ZM12.0124 3.7499C11.5583 3.75524 11.1056 3.79443 10.6578 3.86702L10.5489 4.84418C10.4471 5.75368 9.92003 6.56102 9.13042 7.01903C8.33597 7.48317 7.36736 7.53903 6.52458 7.16917L5.62629 6.77456C5.05436 7.46873 4.59914 8.25135 4.27852 9.09168L5.07632 9.67879C5.81513 10.2216 6.25147 11.0837 6.25147 12.0005C6.25147 12.9172 5.81513 13.7793 5.0771 14.3215L4.27805 14.9102C4.59839 15.752 5.05368 16.5361 5.626 17.2316L6.53113 16.8351C7.36923 16.4692 8.33124 16.5227 9.12353 16.9794C9.91581 17.4361 10.4443 18.2417 10.548 19.1526L10.657 20.1365C11.5466 20.2878 12.4555 20.2878 13.3451 20.1365L13.4541 19.1527C13.5549 18.2421 14.0828 17.4337 14.876 16.9753C15.6692 16.5168 16.6332 16.463 17.4728 16.8305L18.3772 17.2267C18.949 16.5323 19.4041 15.7495 19.7247 14.909L18.9267 14.3211C18.1879 13.7783 17.7516 12.9162 17.7516 11.9995C17.7516 11.0827 18.1879 10.2206 18.9258 9.67847L19.7227 9.09109C19.4021 8.25061 18.9468 7.46784 18.3748 6.77356L17.4783 7.16737C17.113 7.32901 16.7178 7.4122 16.3187 7.41158C14.849 7.41004 13.6155 6.30355 13.4551 4.84383L13.3462 3.8667C12.9007 3.7942 12.4526 3.75512 12.0124 3.7499ZM11.9997 8.24995C14.0708 8.24995 15.7497 9.92888 15.7497 12C15.7497 14.071 14.0708 15.75 11.9997 15.75C9.92863 15.75 8.2497 14.071 8.2497 12C8.2497 9.92888 9.92863 8.24995 11.9997 8.24995ZM11.9997 9.74995C10.7571 9.74995 9.7497 10.7573 9.7497 12C9.7497 13.2426 10.7571 14.25 11.9997 14.25C13.2423 14.25 14.2497 13.2426 14.2497 12C14.2497 10.7573 13.2423 9.74995 11.9997 9.74995Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 774 B After Width: | Height: | Size: 3.2 KiB |
@ -1 +1,3 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1761041980620" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7231" width="16" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M938.666667 170.666667 938.666667 149.333333C938.666667 89.6 891.733333 42.666667 832 42.666667 772.266667 42.666667 725.333333 89.6 725.333333 149.333333L725.333333 170.666667c-25.6 0-42.666667 17.066667-42.666667 42.666667l0 170.666667c0 25.6 17.066667 42.666667 42.666667 42.666667l213.333333 0c25.6 0 42.666667-17.066667 42.666667-42.666667L981.333333 213.333333C981.333333 187.733333 964.266667 170.666667 938.666667 170.666667zM904.533333 170.666667l-145.066667 0L759.466667 149.333333c0-38.4 34.133333-72.533333 72.533333-72.533333 38.4 0 72.533333 34.133333 72.533333 72.533333L904.533333 170.666667zM806.4 512c0 12.8 4.266667 29.866667 4.266667 42.666667 0 89.6-34.133333 170.666667-89.6 230.4-12.8-34.133333-42.666667-59.733333-81.066667-59.733333l-42.666667 0 0-128c0-25.6-17.066667-42.666667-42.666667-42.666667L298.666667 554.666667l0-85.333333 85.333333 0c25.6 0 42.666667-17.066667 42.666667-42.666667L426.666667 341.333333l85.333333 0c46.933333 0 85.333333-38.4 85.333333-85.333333L597.333333 149.333333C558.933333 136.533333 512 128 469.333333 128 234.666667 128 42.666667 320 42.666667 554.666667c0 234.666667 192 426.666667 426.666667 426.666667 234.666667 0 426.666667-192 426.666667-426.666667 0-12.8 0-29.866667-4.266667-42.666667L806.4 512zM426.666667 891.733333c-166.4-21.333333-298.666667-166.4-298.666667-337.066667 0-25.6 4.266667-51.2 8.533333-76.8L341.333333 682.666667l0 42.666667c0 46.933333 38.4 85.333333 85.333333 85.333333L426.666667 891.733333z" p-id="7232"></path></svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.9951 11C13.9951 11.8374 13.4804 12.5545 12.75 12.8523L12.75 15.25C12.75 15.6642 12.4142 16 12 16C11.5858 16 11.25 15.6642 11.25 15.25L11.25 12.8559C10.515 12.5603 9.99603 11.8408 9.99603 11C9.99603 9.89568 10.8913 9.00046 11.9956 9.00046C13.0999 9.00046 13.9951 9.89568 13.9951 11ZM3.75 5C3.33579 5 3 5.33579 3 5.75V11C3 16.0012 5.95756 19.6757 11.7251 21.9478C11.9018 22.0174 12.0982 22.0174 12.2749 21.9478C18.0424 19.6757 21 16.0012 21 11V5.75C21 5.33579 20.6642 5 20.25 5C17.5866 5 14.992 4.05652 12.45 2.15C12.1833 1.95 11.8167 1.95 11.55 2.15C9.00797 4.05652 6.41341 5 3.75 5ZM4.5 11V6.47793C7.07735 6.32585 9.58084 5.38829 12 3.67782C14.4192 5.38829 16.9227 6.32585 19.5 6.47793V11C19.5 15.2556 17.0466 18.3789 12 20.4419C6.95337 18.3789 4.5 15.2556 4.5 11Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 899 B |
@ -2,4 +2,4 @@
|
||||
<circle cx="50" cy="50" r="50" fill="#8391AE" stroke="null" />
|
||||
<path fill="#fff" stroke="null"
|
||||
d="M75.26 51.66H24.74a9.18 9.18 0 0 0-9.18 9.18v4.6a9.18 9.18 0 0 0 9.18 9.18h50.52a9.18 9.18 0 0 0 9.18-9.18v-4.6a9.18 9.18 0 0 0-9.18-9.18zM59.18 68.88a5.17 5.17 0 1 1 5.17-5.17 5.17 5.17 0 0 1-5.17 5.17zm13.2 0a5.17 5.17 0 1 1 5.17-5.17 5.17 5.17 0 0 1-5.16 5.17zM29.34 30.72c6.9-6.62 14.06-9.83 21.59-9.83s15.04 3.44 21.9 10.24a3.44 3.44 0 1 0 4.73-4.9C69.6 18.26 60.33 14 50.92 14s-18.33 4.06-26.18 11.78a3.44 3.44 0 0 0 4.6 4.94zm3.29 8.1a3.44 3.44 0 0 0 4.59 5.03c8.77-8.17 18.78-7.97 27.4.37a3.44 3.44 0 1 0 4.8-4.96 26.96 26.96 0 0 0-18.5-8.27 26.75 26.75 0 0 0-18.2 7.83h-.1z" />
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 786 B After Width: | Height: | Size: 787 B |
@ -1,99 +1,55 @@
|
||||
header .brand,
|
||||
header h3 a {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: auto;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.6rem
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width:854px) {
|
||||
|
||||
.menu-btn,
|
||||
.table,
|
||||
.tr,
|
||||
header .nav {
|
||||
display: flex
|
||||
}
|
||||
|
||||
.td.cbi-value-field,
|
||||
.td[data-title]~.td.cbi-section-actions {
|
||||
align-self: flex-start
|
||||
}
|
||||
|
||||
.td[data-title]::before,
|
||||
[data-name=bridge-vlan] .td[data-title]::before {
|
||||
content: attr(data-title)
|
||||
}
|
||||
|
||||
.dropdown-menu>li>a {
|
||||
padding: .8rem 1.5rem .8rem 3rem
|
||||
}
|
||||
|
||||
body {
|
||||
grid-template-areas: "header" "main" "footer";
|
||||
grid-template-columns: 1fr
|
||||
}
|
||||
|
||||
#maincontent {
|
||||
margin-left: 0
|
||||
}
|
||||
|
||||
footer {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem
|
||||
}
|
||||
footer {
|
||||
width: 100%;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
@media screen and (max-device-width: 600px) {
|
||||
.modal {
|
||||
margin: 1.5em auto;
|
||||
/* margin-top: 160px; */
|
||||
}
|
||||
|
||||
.modal.login {
|
||||
margin-top: 160px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2em;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.cbi-tabmenu,
|
||||
.tabs {
|
||||
.tabs,
|
||||
.cbi-tabmenu {
|
||||
background: var(--material3-card-background);
|
||||
border-radius: var(--material3-card-radius);
|
||||
margin: 1px 1px 10px;
|
||||
border-radius: 1rem
|
||||
}
|
||||
|
||||
.cbi-tabmenu>li,
|
||||
.tabs>li {
|
||||
height: 32px
|
||||
.tabs>li,
|
||||
.cbi-tabmenu>li {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.cbi-tabmenu>li>a,
|
||||
.tabs>li>a {
|
||||
line-height: 30px;
|
||||
border-radius: 1rem
|
||||
.tabs>li>a,
|
||||
.cbi-tabmenu>li>a {
|
||||
padding: 0 12px;
|
||||
line-height: 32px;
|
||||
border-radius: var(--material3-card-radius);
|
||||
}
|
||||
|
||||
.table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
padding: 5px 0
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.tr {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
border-top: 0 solid var(--border-color-medium);
|
||||
padding: 5px;
|
||||
margin: 0 -3px
|
||||
padding: 5px 0;
|
||||
margin: 0 -3px;
|
||||
}
|
||||
|
||||
.table .td,
|
||||
.table .th,
|
||||
.table .td,
|
||||
.table .tr::before {
|
||||
flex: 1 1 50%;
|
||||
align-self: flex-start;
|
||||
@ -103,107 +59,104 @@ header h3 a {
|
||||
display: inline-block;
|
||||
border-top: none;
|
||||
padding: 3px;
|
||||
box-sizing: border-box
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.table .td.cbi-dropdown-open {
|
||||
overflow: visible
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.col-1 {
|
||||
flex: 1 1 30px !important;
|
||||
-webkit-flex: 1 1 30px !important
|
||||
-webkit-flex: 1 1 30px !important;
|
||||
}
|
||||
|
||||
.col-2 {
|
||||
flex: 2 2 60px !important;
|
||||
-webkit-flex: 2 2 60px !important
|
||||
-webkit-flex: 2 2 60px !important;
|
||||
}
|
||||
|
||||
.col-3 {
|
||||
flex: 3 3 90px !important;
|
||||
-webkit-flex: 3 3 90px !important
|
||||
-webkit-flex: 3 3 90px !important;
|
||||
}
|
||||
|
||||
.col-4 {
|
||||
flex: 4 4 120px !important;
|
||||
-webkit-flex: 4 4 120px !important
|
||||
-webkit-flex: 4 4 120px !important;
|
||||
}
|
||||
|
||||
.col-5 {
|
||||
flex: 5 5 150px !important;
|
||||
-webkit-flex: 5 5 150px !important
|
||||
-webkit-flex: 5 5 150px !important;
|
||||
}
|
||||
|
||||
.col-6 {
|
||||
flex: 6 6 180px !important;
|
||||
-webkit-flex: 6 6 180px !important
|
||||
-webkit-flex: 6 6 180px !important;
|
||||
}
|
||||
|
||||
.col-7 {
|
||||
flex: 7 7 210px !important;
|
||||
-webkit-flex: 7 7 210px !important
|
||||
-webkit-flex: 7 7 210px !important;
|
||||
}
|
||||
|
||||
.col-8 {
|
||||
flex: 8 8 240px !important;
|
||||
-webkit-flex: 8 8 240px !important
|
||||
-webkit-flex: 8 8 240px !important;
|
||||
}
|
||||
|
||||
.col-9 {
|
||||
flex: 9 9 270px !important;
|
||||
-webkit-flex: 9 9 270px !important
|
||||
-webkit-flex: 9 9 270px !important;
|
||||
}
|
||||
|
||||
.col-10 {
|
||||
flex: 10 10 300px !important;
|
||||
-webkit-flex: 10 10 300px !important
|
||||
-webkit-flex: 10 10 300px !important;
|
||||
}
|
||||
|
||||
.td select {
|
||||
word-wrap: normal
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.td[data-widget=button],
|
||||
.td[data-widget=fvalue] {
|
||||
.td[data-widget="button"],
|
||||
.td[data-widget="fvalue"] {
|
||||
flex: 1 1 17%;
|
||||
text-align: left
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.td.cbi-value-field {
|
||||
align-self: flex-start;
|
||||
flex-basis: 100%;
|
||||
margin-bottom: .3em
|
||||
margin-bottom: .3em;
|
||||
}
|
||||
|
||||
.td.cbi-value-field .cbi-button {
|
||||
width: 100%
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table.cbi-section-table {
|
||||
border: none;
|
||||
/* background: 0 0; */
|
||||
margin: 0
|
||||
background: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cbi-section-table-descr,
|
||||
.cbi-section-table-titles,
|
||||
.cbi-value.hidden,
|
||||
.tr.table-titles,
|
||||
[data-page=admin-status-processes] .td[data-widget=button]::before,
|
||||
[data-page=admin-system-fstab] .td[data-widget=button]::before,
|
||||
[data-page=admin-system-startup] .td[data-widget=button]::before {
|
||||
display: none
|
||||
.cbi-section-table-titles,
|
||||
.cbi-section-table-descr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cbi-section-table-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 0 .5em
|
||||
margin: 0 0 .5em 0;
|
||||
}
|
||||
|
||||
.cbi-section-table+.cbi-section-create {
|
||||
/* padding-top: 0; */
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.tr[data-title]::before {
|
||||
@ -211,136 +164,160 @@ header h3 a {
|
||||
flex: 1 1 100%;
|
||||
background: var(--background-color-low) !important;
|
||||
font-size: 16px;
|
||||
border-bottom: 1px solid var(--border-color-medium)
|
||||
border-bottom: 1px solid var(--border-color-medium);
|
||||
}
|
||||
|
||||
.td[data-title]::before {
|
||||
font-weight: 700;
|
||||
content: attr(data-title);
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: pre-line
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.td[data-description]::after {
|
||||
display: block
|
||||
display: block;
|
||||
}
|
||||
|
||||
.td[data-title]~.td.cbi-section-actions {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.td.cbi-section-actions {
|
||||
overflow: initial;
|
||||
max-width: 100%;
|
||||
padding: 3px 2px;
|
||||
flex-basis: 100%
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.hide-sm,
|
||||
.hide-xs {
|
||||
display: none !important
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.td.cbi-value-field[data-widget="CBI.Button"],
|
||||
.td.cbi-value-field[data-widget="CBI.DummyValue"],
|
||||
.td.cbi-value-field[data-widget="CBI.Button"],
|
||||
.td.cbi-value-field[data-widget="CBI.FlagValue"],
|
||||
.td.cbi-value-field[data-widget=button],
|
||||
.td.cbi-value-field[data-widget=dvalue],
|
||||
.td.cbi-value-field[data-widget=fvalue] {
|
||||
.td.cbi-value-field[data-widget="dvalue"],
|
||||
.td.cbi-value-field[data-widget="button"],
|
||||
.td.cbi-value-field[data-widget="fvalue"] {
|
||||
flex-basis: 50%;
|
||||
text-align: left
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.cbi-section-table .tr:hover .td,
|
||||
.cbi-section-table .tr:hover .th,
|
||||
.cbi-section-table .tr:hover::before {
|
||||
background-color: transparent
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.cbi-tab-descr {
|
||||
margin: 0 0 .5em
|
||||
margin: 0 0 .5em 0;
|
||||
}
|
||||
|
||||
.cbi-value {
|
||||
padding-bottom: .5em;
|
||||
border-bottom: 1px solid var(--border-color-high);
|
||||
margin-bottom: .5em;
|
||||
display: block
|
||||
display: block;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.cbi-value.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cbi-value .cbi-value:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: inherit;
|
||||
margin-bottom: inherit
|
||||
margin-bottom: inherit;
|
||||
}
|
||||
|
||||
.cbi-value label.cbi-value-title {
|
||||
font-weight: 700
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.cbi-dropdown:not(.btn):not(.cbi-button),
|
||||
.cbi-dynlist,
|
||||
.cbi-value-field,
|
||||
.cbi-select,
|
||||
.cbi-value-field {
|
||||
.cbi-dynlist,
|
||||
.cbi-dropdown:not(.btn):not(.cbi-button) {
|
||||
width: 100%;
|
||||
margin: 0
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cbi-dynlist>.item {
|
||||
min-height: 30px;
|
||||
display: flex;
|
||||
align-items: center
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cbi-dropdown>ul>li,
|
||||
input,
|
||||
textarea,
|
||||
select,
|
||||
textarea {
|
||||
.cbi-dropdown>ul>li {
|
||||
font-size: 16px !important;
|
||||
height: auto
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.cbi-dropdown>ul>li input[type=text] {
|
||||
line-height: 28px
|
||||
.cbi-dropdown>ul>li input[type="text"] {
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.cbi-dropdown>ul>li input[type=text],
|
||||
.cbi-value-field .control-group,
|
||||
input[type=password],
|
||||
input[type=text],
|
||||
select {
|
||||
select,
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
.cbi-dropdown>ul>li input[type="text"],
|
||||
.cbi-value-field .control-group {
|
||||
width: 100%;
|
||||
height: 30px
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
input.cbi-input-password {
|
||||
width: calc(100% - 25px)
|
||||
width: calc(100% - 25px);
|
||||
}
|
||||
|
||||
input[type=password]+.cbi-button,
|
||||
input[type=text]+.cbi-button,
|
||||
input[type="text"]+.cbi-button,
|
||||
input[type="password"]+.cbi-button,
|
||||
select+.cbi-button {
|
||||
text-overflow: ellipsis
|
||||
/* overflow: hidden; */
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.cbi-value-field input[type=checkbox],
|
||||
.cbi-value-field input[type=radio] {
|
||||
margin: 0
|
||||
.cbi-value-field input[type="checkbox"],
|
||||
.cbi-value-field input[type="radio"] {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button,
|
||||
.btn,
|
||||
.cbi-button,
|
||||
button {
|
||||
.cbi-button {
|
||||
font-size: 14px !important;
|
||||
padding: 0 8px
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.actions,
|
||||
.cbi-page-actions {
|
||||
border-top: none;
|
||||
padding: 8px
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
[data-name=bridge-vlan] .td[data-title],
|
||||
[data-page=admin-status-overview] .td[width="33%"] {
|
||||
flex-basis: 33%
|
||||
[data-page="admin-status-overview"] .td[width="33%"] {
|
||||
flex-basis: 33%;
|
||||
}
|
||||
|
||||
[data-page="admin-status-overview"] .table {
|
||||
margin: 4px;
|
||||
width: calc(100% - 8px);
|
||||
}
|
||||
|
||||
[data-page="admin-status-overview"] .table,
|
||||
[data-page="admin-status-overview"] .tr,
|
||||
[data-page="admin-status-overview"] .td,
|
||||
[data-page="admin-status-overview"] .th,
|
||||
[data-page="admin-status-overview"] .tr[data-title]::before,
|
||||
[data-page="admin-status-overview"] .td[data-title]::before {
|
||||
border-top: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
header .pull-right .label {
|
||||
@ -348,139 +325,43 @@ header h3 a {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
line-height: 12px;
|
||||
margin: 1px 0
|
||||
margin: 1px 0;
|
||||
}
|
||||
|
||||
header>.fill {
|
||||
padding: 1px
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
header>.fill>.container {
|
||||
display: flex;
|
||||
flex-direction: row
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
header .nav {
|
||||
flex: 3 3 80%;
|
||||
margin: 2px 5px 2px 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
header .nav a {
|
||||
padding: 2px 6px
|
||||
padding: 2px 6px;
|
||||
}
|
||||
|
||||
header .pull-right {
|
||||
padding: 0 8px;
|
||||
margin: .2em 0 .2em auto;
|
||||
position: relative;
|
||||
z-index: 1
|
||||
}
|
||||
|
||||
.dropdown-menu,
|
||||
.menu-dropdown {
|
||||
top: 23px
|
||||
}
|
||||
|
||||
.cbi-optionals,
|
||||
.cbi-section-create {
|
||||
padding: 7px 0;
|
||||
}
|
||||
|
||||
header .menu-btn {
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
z-index: 1
|
||||
}
|
||||
|
||||
header .menu-btn:hover {
|
||||
background: rgba(0, 0, 0, .05);
|
||||
transition: .3s
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
transform: translateX(-100%);
|
||||
z-index: 900;
|
||||
border-radius: 0 1rem 1rem 0
|
||||
}
|
||||
|
||||
.sidebar.active {
|
||||
transform: translateX(0)
|
||||
}
|
||||
|
||||
.sidebar.active::after {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1
|
||||
}
|
||||
|
||||
#cbi-network-switch_vlan .td,
|
||||
#cbi-network-switch_vlan .th {
|
||||
flex-basis: 12%
|
||||
}
|
||||
|
||||
#cbi-network-switch_vlan .td.cbi-section-actions>* {
|
||||
width: auto;
|
||||
display: block
|
||||
}
|
||||
|
||||
#wifi_assoclist_table .td,
|
||||
[data-page=admin-status-processes] .td {
|
||||
flex-basis: 50% !important
|
||||
}
|
||||
|
||||
[data-page=admin-status-processes] .td[data-widget=button] {
|
||||
flex-basis: 33% !important
|
||||
}
|
||||
|
||||
[data-page=admin-status-processes] .td[data-name=PID],
|
||||
[data-page=admin-status-processes] .td[data-name=USER] {
|
||||
flex-basis: 25% !important
|
||||
}
|
||||
|
||||
[data-name=bridge-vlan]>div {
|
||||
overflow: visible !important
|
||||
}
|
||||
|
||||
[data-page=admin-network-network] .td[data-name="_ifacebox"] {
|
||||
flex-basis: 40%
|
||||
}
|
||||
|
||||
[data-page=admin-network-network] .td[data-name="_ifacestat"] {
|
||||
flex-basis: 60%
|
||||
}
|
||||
|
||||
[data-page^=admin-services-openclash] .cbi-value {
|
||||
overflow-x: auto
|
||||
}
|
||||
|
||||
/* [data-page^=admin-services-openclash] div#cbi-openclash {
|
||||
overflow-x: scroll
|
||||
} */
|
||||
|
||||
.sidebar-overlay {
|
||||
opacity: 0;
|
||||
visibility: hidden
|
||||
}
|
||||
|
||||
.sidebar-overlay.active {
|
||||
opacity: 1;
|
||||
visibility: visible
|
||||
}
|
||||
|
||||
header.with-shadow {
|
||||
background: var(--md-sys-color-card);
|
||||
box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%)
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 0;
|
||||
justify-content: flex-end;
|
||||
margin: .2em 5px .2em auto;
|
||||
}
|
||||
|
||||
header [data-indicator] {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
padding: 0;
|
||||
margin: 0 4px;
|
||||
font-size: 0;
|
||||
@ -488,11 +369,12 @@ header h3 a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
header [data-indicator="poll-status"]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
margin: auto;
|
||||
@ -501,92 +383,151 @@ header h3 a {
|
||||
}
|
||||
|
||||
header [data-indicator="uci-changes"]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
margin: auto;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width:330px) {
|
||||
|
||||
.cbi-page-actions button,
|
||||
.cbi-section-actions .cbi-button {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis
|
||||
.menu-dropdown,
|
||||
.dropdown-menu {
|
||||
top: 23px;
|
||||
}
|
||||
|
||||
.cbi-optionals,
|
||||
.cbi-section-create {
|
||||
padding: 0 0 14px 0;
|
||||
}
|
||||
|
||||
#cbi-network-switch_vlan .th,
|
||||
#cbi-network-switch_vlan .td {
|
||||
flex-basis: 12%;
|
||||
}
|
||||
|
||||
#cbi-network-switch_vlan .td.cbi-section-actions>* {
|
||||
width: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#wifi_assoclist_table .td,
|
||||
[data-page="admin-status-processes"] .td {
|
||||
flex-basis: 50% !important;
|
||||
}
|
||||
|
||||
[data-page="admin-status-processes"] .td[data-widget="button"] {
|
||||
flex-basis: 33% !important;
|
||||
}
|
||||
|
||||
[data-page="admin-status-processes"] .td[data-name="PID"],
|
||||
[data-page="admin-status-processes"] .td[data-name="USER"] {
|
||||
flex-basis: 25% !important;
|
||||
}
|
||||
|
||||
[data-page="admin-system-fstab"] .td[data-widget="button"]::before,
|
||||
[data-page="admin-system-startup"] .td[data-widget="button"]::before,
|
||||
[data-page="admin-status-processes"] .td[data-widget="button"]::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-name="bridge-vlan"]>div {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
[data-name="bridge-vlan"] .td[data-title] {
|
||||
flex-basis: 33%;
|
||||
}
|
||||
|
||||
[data-name="bridge-vlan"] .td[data-title]::before {
|
||||
content: attr(data-title);
|
||||
}
|
||||
|
||||
[data-page="admin-network-network"] .td[data-name="_ifacebox"] {
|
||||
flex-basis: 40%;
|
||||
}
|
||||
|
||||
[data-page="admin-network-network"] .td[data-name="_ifacestat"] {
|
||||
flex-basis: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-device-width: 375px) {
|
||||
.cbi-page-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0 -1px;
|
||||
padding: 0
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cbi-page-actions button {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.cbi-page-actions .cbi-button {
|
||||
flex: 1;
|
||||
margin: 1px !important;
|
||||
line-height: 2em
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.cbi-page-actions .cbi-button-apply,
|
||||
.cbi-page-actions .cbi-button-negative,
|
||||
.cbi-page-actions .cbi-button-primary {
|
||||
flex: 3
|
||||
.cbi-page-actions .cbi-button-primary,
|
||||
.cbi-page-actions .cbi-button-apply {
|
||||
flex: 3;
|
||||
}
|
||||
|
||||
.cbi-section-actions .cbi-button {
|
||||
margin: 1px !important
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 1px !important;
|
||||
}
|
||||
|
||||
body[data-page=admin-network-wireless] .td[data-name="_badge"] {
|
||||
body[data-page="admin-network-wireless"] .td[data-name="_badge"] {
|
||||
max-width: 50px;
|
||||
align-self: center
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
body[data-page=admin-network-wireless] .td[data-name="_badge"] .ifacebadge {
|
||||
body[data-page="admin-network-wireless"] .td[data-name="_badge"] .ifacebadge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
body[data-page=admin-network-wireless] .td[data-name="_stat"] {
|
||||
flex-basis: 60%
|
||||
body[data-page="admin-network-wireless"] .td[data-name="_stat"] {
|
||||
flex-basis: 60%;
|
||||
}
|
||||
|
||||
body[data-page=admin-network-network] .td.cbi-section-actions::before,
|
||||
body[data-page=admin-network-wireless] .td.cbi-section-actions::before {
|
||||
content: none !important
|
||||
body[data-page="admin-network-network"] .td.cbi-section-actions::before,
|
||||
body[data-page="admin-network-wireless"] .td.cbi-section-actions::before {
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
[data-page=admin-network-network] .td[data-name="_ifacebox"],
|
||||
[data-page=admin-network-network] .td[data-name="_ifacestat"] {
|
||||
flex-basis: 100%
|
||||
[data-page="admin-network-network"] .td[data-name="_ifacebox"],
|
||||
[data-page="admin-network-network"] .td[data-name="_ifacestat"] {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.td .ifacebox {
|
||||
width: 100%;
|
||||
margin: 0 !important;
|
||||
flex-direction: row
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.td .ifacebox .ifacebox-head {
|
||||
min-width: 25%;
|
||||
justify-content: space-around;
|
||||
border-radius: 1rem;
|
||||
border-radius: 11px 0 0 11px;
|
||||
}
|
||||
|
||||
.td .ifacebox .ifacebox-body,
|
||||
.td .ifacebox .ifacebox-head {
|
||||
.td .ifacebox .ifacebox-head,
|
||||
.td .ifacebox .ifacebox-body {
|
||||
display: flex;
|
||||
border-bottom: none;
|
||||
align-items: center
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ifacebox .ifacebox-body>*,
|
||||
.td .ifacebox .ifacebox-head>* {
|
||||
margin: .125em
|
||||
.td .ifacebox .ifacebox-head>*,
|
||||
.ifacebox .ifacebox-body>* {
|
||||
margin: .125em;
|
||||
}
|
||||
}
|
||||
@ -3,85 +3,125 @@
|
||||
'require ui';
|
||||
|
||||
return baseclass.extend({
|
||||
__init__: function () {
|
||||
ui.menu.load().then(L.bind(this.render, this));
|
||||
this.initMenuToggle();
|
||||
this.initRippleEffect();
|
||||
this.initHeaderShadow();
|
||||
__init__() {
|
||||
ui.menu.load().then((tree) => this.render(tree));
|
||||
this.initNavigationShell();
|
||||
},
|
||||
|
||||
createRipple: function (event, target) {
|
||||
// 移除已有的水波纹
|
||||
var oldRipple = target.querySelector('.ripple');
|
||||
if (oldRipple) {
|
||||
createRipple(ev, target) {
|
||||
const oldRipple = target.querySelector('.ripple');
|
||||
|
||||
if (oldRipple)
|
||||
oldRipple.remove();
|
||||
}
|
||||
|
||||
// 创建并设置水波纹
|
||||
var ripple = document.createElement('div');
|
||||
ripple.className = 'ripple';
|
||||
ripple.style.left = event.clientX - target.getBoundingClientRect().left + 'px';
|
||||
ripple.style.top = event.clientY - target.getBoundingClientRect().top + 'px';
|
||||
const rect = target.getBoundingClientRect();
|
||||
const ripple = E('span', { 'class': 'ripple' });
|
||||
|
||||
// 添加水波纹并设置自动移除
|
||||
ripple.style.left = '%dpx'.format(ev.clientX - rect.left);
|
||||
ripple.style.top = '%dpx'.format(ev.clientY - rect.top);
|
||||
target.appendChild(ripple);
|
||||
ripple.addEventListener('animationend', function () {
|
||||
ripple.remove();
|
||||
});
|
||||
ripple.addEventListener('animationend', () => ripple.remove());
|
||||
},
|
||||
|
||||
initMenuToggle: function () {
|
||||
var menuBtn = document.querySelector('.menu-btn');
|
||||
var sidebar = document.querySelector('.sidebar');
|
||||
var body = document.body;
|
||||
toggleDropdown(li) {
|
||||
const submenu = Array.prototype.find.call(li.children, child => child.classList.contains('dropdown-menu'));
|
||||
|
||||
// 创建遮罩层
|
||||
var overlay = document.createElement('div');
|
||||
overlay.className = 'sidebar-overlay';
|
||||
document.body.appendChild(overlay);
|
||||
if (!submenu)
|
||||
return;
|
||||
|
||||
if (menuBtn && sidebar) {
|
||||
// 点击菜单按钮
|
||||
menuBtn.addEventListener('click', function () {
|
||||
menuBtn.classList.toggle('active');
|
||||
sidebar.classList.toggle('active');
|
||||
overlay.classList.toggle('active');
|
||||
body.style.overflow = sidebar.classList.contains('active') ? 'hidden' : '';
|
||||
});
|
||||
|
||||
// 点击遮罩层关闭菜单
|
||||
overlay.addEventListener('click', function () {
|
||||
menuBtn.classList.remove('active');
|
||||
sidebar.classList.remove('active');
|
||||
overlay.classList.remove('active');
|
||||
body.style.overflow = '';
|
||||
});
|
||||
if (li.classList.contains('open')) {
|
||||
submenu.style.height = '%dpx'.format(submenu.scrollHeight);
|
||||
submenu.offsetHeight;
|
||||
li.classList.remove('open');
|
||||
submenu.style.height = '0px';
|
||||
}
|
||||
else {
|
||||
this.closeOtherMenus(li);
|
||||
li.classList.add('open');
|
||||
submenu.style.height = '%dpx'.format(submenu.scrollHeight);
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭其他展开的菜单
|
||||
closeOtherMenus: function (currentMenu) {
|
||||
var openMenus = document.querySelectorAll('#topmenu > li.open');
|
||||
closeOtherMenus(currentMenu) {
|
||||
document.querySelectorAll('#topmenu > li.open').forEach(menu => {
|
||||
if (menu === currentMenu)
|
||||
return;
|
||||
|
||||
openMenus.forEach(function (menu) {
|
||||
if (menu !== currentMenu) {
|
||||
var submenu = menu.querySelector('.dropdown-menu');
|
||||
if (submenu) {
|
||||
// 先设置实际高度,以便动画正常工作
|
||||
submenu.style.height = submenu.scrollHeight + 'px';
|
||||
// 强制重排
|
||||
submenu.offsetHeight;
|
||||
// 开始收起动画
|
||||
submenu.style.height = '0px';
|
||||
menu.classList.remove('open');
|
||||
}
|
||||
}
|
||||
const submenu = menu.querySelector('.dropdown-menu');
|
||||
|
||||
if (!submenu)
|
||||
return;
|
||||
|
||||
submenu.style.height = '%dpx'.format(submenu.scrollHeight);
|
||||
submenu.offsetHeight;
|
||||
submenu.style.height = '0px';
|
||||
menu.classList.remove('open');
|
||||
});
|
||||
},
|
||||
|
||||
render: function (tree) {
|
||||
var node = tree,
|
||||
url = '';
|
||||
initNavigationShell() {
|
||||
const button = document.querySelector('.menu-btn');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const overlay = document.querySelector('.sidebar-overlay');
|
||||
const header = document.querySelector('header');
|
||||
|
||||
if (header) {
|
||||
window.addEventListener('scroll', () => {
|
||||
header.classList.toggle('with-shadow', window.scrollY > 8);
|
||||
});
|
||||
}
|
||||
|
||||
if (!button || !sidebar || !overlay)
|
||||
return;
|
||||
|
||||
const close = () => {
|
||||
sidebar.classList.remove('active');
|
||||
overlay.classList.remove('active');
|
||||
button.classList.remove('active');
|
||||
document.body.style.overflow = '';
|
||||
button.setAttribute('aria-expanded', 'false');
|
||||
};
|
||||
|
||||
button.addEventListener('click', () => {
|
||||
sidebar.classList.toggle('active');
|
||||
overlay.classList.toggle('active');
|
||||
const isOpen = sidebar.classList.contains('active');
|
||||
|
||||
button.classList.toggle('active', isOpen);
|
||||
document.body.style.overflow = isOpen ? 'hidden' : '';
|
||||
button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
|
||||
});
|
||||
|
||||
overlay.addEventListener('click', close);
|
||||
|
||||
document.addEventListener('keydown', ev => {
|
||||
if (ev.key == 'Escape')
|
||||
close();
|
||||
});
|
||||
|
||||
sidebar.addEventListener('click', ev => {
|
||||
const link = ev.target.closest('a[href]');
|
||||
|
||||
if (!link)
|
||||
return;
|
||||
|
||||
this.createRipple(ev, link);
|
||||
|
||||
if (link.getAttribute('href') != '#')
|
||||
close();
|
||||
});
|
||||
|
||||
document.addEventListener('click', ev => {
|
||||
const target = ev.target.closest('.tabs > li, .cbi-tabmenu > li');
|
||||
|
||||
if (target)
|
||||
this.createRipple(ev, target);
|
||||
});
|
||||
},
|
||||
|
||||
render(tree) {
|
||||
let node = tree;
|
||||
let url = '';
|
||||
|
||||
this.renderModeMenu(tree);
|
||||
|
||||
@ -96,23 +136,23 @@ return baseclass.extend({
|
||||
}
|
||||
},
|
||||
|
||||
renderTabMenu: function (tree, url, level) {
|
||||
var container = document.querySelector('#tabmenu'),
|
||||
ul = E('ul', { 'class': 'tabs' }),
|
||||
children = ui.menu.getChildren(tree),
|
||||
activeNode = null;
|
||||
renderTabMenu(tree, url, level) {
|
||||
const container = document.querySelector('#tabmenu');
|
||||
const ul = E('ul', { 'class': 'tabs' });
|
||||
const children = ui.menu.getChildren(tree);
|
||||
let activeNode = null;
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var isActive = (L.env.dispatchpath[3 + (level || 0)] == children[i].name),
|
||||
activeClass = isActive ? ' active' : '',
|
||||
className = 'tabmenu-item-%s %s'.format(children[i].name, activeClass);
|
||||
children.forEach(child => {
|
||||
const isActive = (L.env.dispatchpath[3 + (level || 0)] == child.name);
|
||||
const activeClass = isActive ? ' active' : '';
|
||||
const className = 'tabmenu-item-%s %s'.format(child.name, activeClass);
|
||||
|
||||
ul.appendChild(E('li', { 'class': className }, [
|
||||
E('a', { 'href': L.url(url, children[i].name) }, [children[i].name === 'nas' ? 'NAS' : _(children[i].title)])]));
|
||||
E('a', { 'href': L.url(url, child.name) }, [ _(child.title) ] )]));
|
||||
|
||||
if (isActive)
|
||||
activeNode = children[i];
|
||||
}
|
||||
activeNode = child;
|
||||
});
|
||||
|
||||
if (ul.children.length == 0)
|
||||
return E([]);
|
||||
@ -126,128 +166,78 @@ return baseclass.extend({
|
||||
return ul;
|
||||
},
|
||||
|
||||
renderMainMenu: function (tree, url, level) {
|
||||
var self = this;
|
||||
var ul = level ? E('ul', { 'class': 'dropdown-menu' }) : document.querySelector('#topmenu'),
|
||||
children = ui.menu.getChildren(tree);
|
||||
renderMainMenu(tree, url, level) {
|
||||
const ul = level ? E('ul', { 'class': 'dropdown-menu' }) : document.querySelector('#topmenu');
|
||||
const children = ui.menu.getChildren(tree);
|
||||
|
||||
if (children.length == 0 || level > 1)
|
||||
return E([]);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var submenu = this.renderMainMenu(children[i], url + '/' + children[i].name, (level || 0) + 1),
|
||||
subclass = (!level && submenu.firstElementChild) ? 'dropdown' : null,
|
||||
linkclass = (!level && submenu.firstElementChild) ? 'menu' : null,
|
||||
linkurl = submenu.firstElementChild ? '#' : L.url(url, children[i].name);
|
||||
|
||||
var currentPath = L.env.requestpath.join('/');
|
||||
var itemPath = (url + '/' + children[i].name).replace(/^\/+/, '');
|
||||
var isActive = currentPath.startsWith(itemPath);
|
||||
|
||||
if (isActive && submenu.firstElementChild) {
|
||||
subclass = 'dropdown open active';
|
||||
// 直接设置展开状态
|
||||
submenu.style.display = 'block';
|
||||
submenu.style.height = 'auto';
|
||||
}
|
||||
else if (isActive) {
|
||||
subclass = 'active';
|
||||
}
|
||||
else if (submenu.firstElementChild) {
|
||||
subclass = 'dropdown';
|
||||
submenu.style.height = '0px';
|
||||
}
|
||||
|
||||
var li = E('li', {
|
||||
children.forEach(child => {
|
||||
const submenu = this.renderMainMenu(child, url + '/' + child.name, (level || 0) + 1);
|
||||
const itemPath = (url + '/' + child.name).replace(/^\/+/, '');
|
||||
const currentPath = L.env.requestpath.join('/');
|
||||
const isActive = currentPath == itemPath || currentPath.indexOf(itemPath + '/') == 0;
|
||||
const hasSubmenu = !!submenu.firstElementChild;
|
||||
const subclass = [
|
||||
hasSubmenu ? 'dropdown' : '',
|
||||
isActive ? 'active' : '',
|
||||
(!level && hasSubmenu && isActive) ? 'open' : ''
|
||||
].filter(Boolean).join(' ');
|
||||
const linkclass = (!level && hasSubmenu) ? 'menu' : '';
|
||||
const linkurl = hasSubmenu ? '#' : L.url(url, child.name);
|
||||
const attrs = {
|
||||
'class': subclass,
|
||||
'data-path': itemPath
|
||||
}, [
|
||||
E('a', {
|
||||
'class': linkclass,
|
||||
'href': linkurl,
|
||||
'click': (function (submenu, hasSubmenu, targetUrl, ev) {
|
||||
// 添加水波纹效果
|
||||
self.createRipple(ev, ev.currentTarget);
|
||||
};
|
||||
const linkAttrs = {
|
||||
'class': linkclass,
|
||||
'href': linkurl
|
||||
};
|
||||
|
||||
if (hasSubmenu) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
if (!level && hasSubmenu) {
|
||||
linkAttrs.click = ev => {
|
||||
ev.preventDefault();
|
||||
this.toggleDropdown(ev.currentTarget.parentNode);
|
||||
};
|
||||
}
|
||||
|
||||
var parentLi = ev.currentTarget.parentNode;
|
||||
var dropdownMenu = submenu;
|
||||
|
||||
if (parentLi.classList.contains('open')) {
|
||||
// 先获取当前高度
|
||||
dropdownMenu.style.height = dropdownMenu.scrollHeight + 'px';
|
||||
// 强制重排
|
||||
dropdownMenu.offsetHeight;
|
||||
// 开始收起动画
|
||||
parentLi.classList.remove('open');
|
||||
dropdownMenu.style.height = '0px';
|
||||
} else {
|
||||
self.closeOtherMenus(parentLi);
|
||||
parentLi.classList.add('open');
|
||||
// 移除auto和display设置,以便动画生效
|
||||
dropdownMenu.style.display = '';
|
||||
dropdownMenu.style.height = dropdownMenu.scrollHeight + 'px';
|
||||
}
|
||||
}
|
||||
else if (targetUrl) {
|
||||
location.href = targetUrl;
|
||||
}
|
||||
}).bind(null, submenu, !!submenu.firstElementChild, linkurl)
|
||||
}, [children[i].name === 'nas' ? 'NAS' : _(children[i].title)]),
|
||||
const li = E('li', attrs, [
|
||||
E('a', linkAttrs, [
|
||||
_(child.title),
|
||||
]),
|
||||
submenu
|
||||
]);
|
||||
|
||||
if (!level && hasSubmenu && isActive)
|
||||
submenu.style.height = 'auto';
|
||||
|
||||
ul.appendChild(li);
|
||||
}
|
||||
});
|
||||
|
||||
ul.style.display = '';
|
||||
|
||||
return ul;
|
||||
},
|
||||
|
||||
renderModeMenu: function (tree) {
|
||||
var ul = document.querySelector('#modemenu'),
|
||||
children = ui.menu.getChildren(tree);
|
||||
renderModeMenu(tree) {
|
||||
const ul = document.querySelector('#modemenu');
|
||||
const children = ui.menu.getChildren(tree);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[0] : i == 0);
|
||||
children.forEach((child, index) => {
|
||||
const isActive = L.env.requestpath.length
|
||||
? child.name === L.env.requestpath[0]
|
||||
: index === 0;
|
||||
|
||||
ul.appendChild(E('li', { 'class': isActive ? 'active' : null }, [
|
||||
E('a', { 'href': L.url(children[i].name) }, [children[i].name === 'nas' ? 'NAS' : _(children[i].title)])
|
||||
ul.appendChild(E('li', { 'class': isActive ? 'active' : '' }, [
|
||||
E('a', { 'href': L.url(child.name) }, [ _(child.title) ])
|
||||
]));
|
||||
|
||||
if (isActive)
|
||||
this.renderMainMenu(children[i], children[i].name);
|
||||
}
|
||||
this.renderMainMenu(child, child.name);
|
||||
});
|
||||
|
||||
if (ul.children.length > 1)
|
||||
ul.style.display = '';
|
||||
},
|
||||
|
||||
initRippleEffect: function () {
|
||||
var self = this;
|
||||
document.addEventListener('click', function (e) {
|
||||
// 排除一级菜单的点击,因为它们已经在自己的点击事件中处理了水波纹
|
||||
var target = e.target.closest('.dropdown-menu>li>a, .tabs>li, .cbi-tabmenu>li');
|
||||
if (!target) return;
|
||||
|
||||
self.createRipple(e, target);
|
||||
});
|
||||
},
|
||||
|
||||
initHeaderShadow: function () {
|
||||
var header = document.querySelector('header');
|
||||
var scrollThreshold = 10; // 滚动阈值
|
||||
|
||||
window.addEventListener('scroll', function () {
|
||||
if (window.scrollY > scrollThreshold) {
|
||||
header.classList.add('with-shadow');
|
||||
} else {
|
||||
header.classList.remove('with-shadow');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -3,26 +3,35 @@
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
render: function () {
|
||||
var form = document.querySelector('form'),
|
||||
btn = document.querySelector('button');
|
||||
render() {
|
||||
const form = document.querySelector('form');
|
||||
const btn = document.querySelector('button');
|
||||
|
||||
var dlg = ui.showModal(
|
||||
const dlg = ui.showModal(
|
||||
_('Authorization Required'),
|
||||
[].slice.call(document.querySelectorAll('section > *')),
|
||||
Array.from(document.querySelectorAll('section > *')),
|
||||
'login'
|
||||
);
|
||||
|
||||
form.addEventListener('keypress', function (ev) {
|
||||
if (ev.key == 'Enter')
|
||||
const overlay = document.getElementById('modal_overlay');
|
||||
|
||||
if (overlay)
|
||||
overlay.classList.add('login-overlay');
|
||||
|
||||
form.addEventListener('keypress', (ev) => {
|
||||
if (ev.key === 'Enter')
|
||||
btn.click();
|
||||
});
|
||||
|
||||
btn.addEventListener('click', function () {
|
||||
dlg.querySelectorAll('*').forEach(function (node) { node.style.display = 'none' });
|
||||
dlg.appendChild(E('div', { 'class': 'spinning' }, _('Logging in…')));
|
||||
btn.addEventListener('click', () => {
|
||||
dlg.querySelectorAll('*').forEach((node) => {
|
||||
node.style.display = 'none';
|
||||
});
|
||||
dlg.appendChild(E('div', {
|
||||
class: 'spinning'
|
||||
}, _('Logging in…')));
|
||||
|
||||
form.submit()
|
||||
form.submit();
|
||||
});
|
||||
|
||||
document.querySelector('input[type="password"]').focus();
|
||||
@ -30,5 +39,6 @@ return view.extend({
|
||||
return '';
|
||||
},
|
||||
|
||||
addFooter: function () { }
|
||||
addFooter() {},
|
||||
|
||||
});
|
||||
|
||||
BIN
luci-theme-material3/imgs/baseline.jpg
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
luci-theme-material3/imgs/blue.jpg
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
luci-theme-material3/imgs/desktop.png
Normal file
|
After Width: | Height: | Size: 179 KiB |
BIN
luci-theme-material3/imgs/gray.jpg
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
luci-theme-material3/imgs/green.jpg
Normal file
|
After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 198 KiB |
BIN
luci-theme-material3/imgs/mobile.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
luci-theme-material3/imgs/orange.jpg
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
luci-theme-material3/imgs/rose.jpg
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
luci-theme-material3/imgs/sakura.jpg
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
luci-theme-material3/imgs/teal.jpg
Normal file
|
After Width: | Height: | Size: 164 KiB |
BIN
luci-theme-material3/imgs/vivid-orange.jpg
Normal file
|
After Width: | Height: | Size: 102 KiB |
42
luci-theme-material3/root/etc/uci-defaults/30_luci-theme-material3
Normal file → Executable file
@ -1,15 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$PKG_UPGRADE" != 1 ]; then
|
||||
uci get luci.themes.Material3 >/dev/null 2>&1 || \
|
||||
uci batch <<-EOF
|
||||
set luci.themes.Material3=/luci-static/material3
|
||||
set luci.main.mediaurlbase=/luci-static/material3
|
||||
set luci.themes.Material3Blue=/luci-static/material3-blue
|
||||
set luci.themes.Material3Green=/luci-static/material3-green
|
||||
set luci.themes.Material3Red=/luci-static/material3-red
|
||||
commit luci
|
||||
EOF
|
||||
changed=0
|
||||
|
||||
set_opt() {
|
||||
local key=$1
|
||||
local val=$2
|
||||
|
||||
if ! uci -q get "luci.$key" 2>/dev/null; then
|
||||
uci set "luci.$key=$val"
|
||||
changed=1
|
||||
fi
|
||||
}
|
||||
|
||||
set_opt themes.Material3 /luci-static/material3
|
||||
|
||||
if uci -q get luci.themes.Material3Dark >/dev/null; then
|
||||
uci -q delete luci.themes.Material3Dark
|
||||
changed=1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
if uci -q get luci.themes.Material3Light >/dev/null; then
|
||||
uci -q delete luci.themes.Material3Light
|
||||
changed=1
|
||||
fi
|
||||
|
||||
if [ "$PKG_UPGRADE" != 1 ] && [ $changed = 1 ]; then
|
||||
set_opt main.mediaurlbase /luci-static/material3
|
||||
fi
|
||||
|
||||
if [ $changed = 1 ]; then
|
||||
uci commit luci
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
@ -1 +0,0 @@
|
||||
material3
|
||||
@ -1 +0,0 @@
|
||||
material3
|
||||
@ -1 +0,0 @@
|
||||
material3
|
||||
@ -9,26 +9,43 @@
|
||||
import { getuid, getspnam } from 'luci.core';
|
||||
|
||||
const boardinfo = ubus.call('system', 'board');
|
||||
const darkpref = uci.get('luci', 'main', 'darkmode') || 'auto';
|
||||
let themepref = null;
|
||||
switch (theme) {
|
||||
case 'material3-blue': themepref = 'blue'; break;
|
||||
case 'material3-green': themepref = 'green'; break;
|
||||
case 'material3-red': themepref = 'red'; break;
|
||||
}
|
||||
|
||||
http.prepare_content('text/html; charset=UTF-8');
|
||||
-%}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ dispatcher.lang }}" data-darkmode="{{ darkpref }}" {{ themepref ? `data-theme="${themepref}"` : '' }}>
|
||||
<html lang="{{ dispatcher.lang }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{ striptags(`${boardinfo.hostname ?? '?'}${node ? ` - ${node.title}` : ''}`) }} - LuCI</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<title>{{ striptags(`${boardinfo.hostname ?? '?'}${dispatched?.title ? ` | ${_(dispatched.title)}` : ''}`) }}</title>
|
||||
<script>
|
||||
(function() {
|
||||
var mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'),
|
||||
modeKey = 'material3-mode-debug',
|
||||
rootElement = document.querySelector(':root'),
|
||||
setDarkMode = function(match) {
|
||||
var mode = localStorage.getItem(modeKey);
|
||||
|
||||
if (mode == 'light' || mode == 'dark') {
|
||||
rootElement.setAttribute('data-mode', mode);
|
||||
rootElement.setAttribute('data-darkmode', mode == 'dark' ? 'true' : 'false');
|
||||
}
|
||||
else {
|
||||
rootElement.removeAttribute('data-mode');
|
||||
rootElement.setAttribute('data-darkmode', match.matches ? 'true' : 'false');
|
||||
}
|
||||
};
|
||||
|
||||
window.material3ApplyColorMode = setDarkMode;
|
||||
mediaQuery.addEventListener('change', setDarkMode);
|
||||
setDarkMode(mediaQuery);
|
||||
})();
|
||||
</script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="darkreader-lock">
|
||||
<link rel="stylesheet" href="{{ media }}/cascade.css">
|
||||
<link rel="stylesheet" media="screen and (max-width: 854px)" href="{{ media }}/mobile.css" />
|
||||
<link rel="icon" href="{{ media }}/logo.svg" sizes="any">
|
||||
<link rel="stylesheet" media="only screen and (max-device-width: 854px)" href="{{ media }}/mobile.css" />
|
||||
<link rel="icon" href="{{ media }}/logo.svg" sizes="any">
|
||||
{% if (node?.css): %}
|
||||
<link rel="stylesheet" href="{{ resource }}/{{ node.css }}">
|
||||
{% endif %}
|
||||
@ -37,277 +54,205 @@
|
||||
{% endif %}
|
||||
<script src="{{ dispatcher.build_url('admin/translations', dispatcher.lang) }}"></script>
|
||||
<script src="{{ resource }}/cbi.js"></script>
|
||||
|
||||
|
||||
<style title="darkmode-support">
|
||||
/* Dark mode toggle styles */
|
||||
:root {
|
||||
--transition-duration: 0.3s;
|
||||
--theme-switch-size: 42px;
|
||||
--theme-switch-height: 24px;
|
||||
--theme-switch-handle-size: 16px;
|
||||
<style>
|
||||
#material3-debug-switcher {
|
||||
position: fixed;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
z-index: 1200;
|
||||
font: 12px/1 var(--font-sans);
|
||||
}
|
||||
|
||||
.theme-switch-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-left: auto;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.header-controls {
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.theme-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: var(--theme-switch-size);
|
||||
height: var(--theme-switch-height);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.theme-switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
inset: 0;
|
||||
background-color: var(--switch-bg, #ccc);
|
||||
transition: all var(--transition-duration) cubic-bezier(0.4, 0, 0.2, 1);
|
||||
border-radius: var(--theme-switch-height);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: var(--theme-switch-handle-size);
|
||||
width: var(--theme-switch-handle-size);
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: var(--switch-handle, white);
|
||||
transition: all var(--transition-duration) cubic-bezier(0.4, 0, 0.2, 1);
|
||||
#material3-debug-switcher > button {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid var(--border-color-medium);
|
||||
background: var(--primary-color-high);
|
||||
color: var(--on-primary-color);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, .22);
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(18px);
|
||||
}
|
||||
|
||||
/* Theme transition */
|
||||
html {
|
||||
transition: background-color var(--transition-duration) ease,
|
||||
color var(--transition-duration) ease;
|
||||
}
|
||||
|
||||
/* Theme toggle icon styles */
|
||||
.theme-toggle {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
transition: all var(--transition-duration) cubic-bezier(0.4, 0, 0.2, 1);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.theme-toggle:hover {
|
||||
background-color: var(--md-sys-color-surface-variant);
|
||||
}
|
||||
|
||||
.theme-toggle .icon {
|
||||
position: absolute;
|
||||
transition: all var(--transition-duration) cubic-bezier(0.4, 0, 0.2, 1);
|
||||
fill: var(--md-sys-color-refresh-button);
|
||||
#material3-debug-switcher > button::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: auto;
|
||||
background: currentColor;
|
||||
-webkit-mask: url("{{ media }}/icons/palette.svg") center/contain no-repeat;
|
||||
mask: url("{{ media }}/icons/palette.svg") center/contain no-repeat;
|
||||
}
|
||||
|
||||
.theme-toggle .moon-icon {
|
||||
opacity: 1;
|
||||
transform: scale(1) rotate(0);
|
||||
#material3-debug-switcher > div {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 50px;
|
||||
display: none;
|
||||
grid-template-columns: repeat(3, 30px);
|
||||
gap: 8px;
|
||||
padding: 10px;
|
||||
border: 1px solid var(--border-color-medium);
|
||||
border-radius: 12px;
|
||||
background: var(--background-color-high);
|
||||
box-shadow: 0 4px 18px rgba(0, 0, 0, .22);
|
||||
}
|
||||
|
||||
.theme-toggle .sun-icon {
|
||||
opacity: 0;
|
||||
transform: scale(0.5) rotate(90deg);
|
||||
#material3-debug-switcher[open] > div {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
html[data-darkmode="true"] .theme-toggle .moon-icon {
|
||||
opacity: 0;
|
||||
transform: scale(0.5) rotate(-90deg);
|
||||
#material3-debug-switcher button[data-theme],
|
||||
#material3-debug-switcher button[data-mode] {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 1px solid var(--border-color-medium);
|
||||
border-radius: 50%;
|
||||
background: var(--debug-color, var(--background-color-low));
|
||||
color: var(--text-color-high);
|
||||
box-shadow: inset 0 0 0 3px var(--background-color-high);
|
||||
}
|
||||
|
||||
html[data-darkmode="true"] .theme-toggle .sun-icon {
|
||||
opacity: 1;
|
||||
transform: scale(1) rotate(0);
|
||||
#material3-debug-switcher button[aria-pressed="true"] {
|
||||
border-color: var(--primary-color-high);
|
||||
box-shadow: inset 0 0 0 3px var(--background-color-high), 0 0 0 3px color-mix(in srgb, var(--primary-color-high) 30%, transparent);
|
||||
}
|
||||
|
||||
.theme-toggle:hover .icon {
|
||||
transform: rotate(15deg) scale(1.1);
|
||||
#material3-debug-switcher button[data-mode] {
|
||||
position: relative;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
html[data-darkmode="true"] .theme-toggle:hover .icon {
|
||||
transform: rotate(-15deg) scale(1.1);
|
||||
#material3-debug-switcher button[data-mode]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: auto;
|
||||
background: currentColor;
|
||||
-webkit-mask: var(--debug-mode-icon) center/contain no-repeat;
|
||||
mask: var(--debug-mode-icon) center/contain no-repeat;
|
||||
}
|
||||
|
||||
/* 添加点击效果 */
|
||||
.theme-toggle:active .icon {
|
||||
transform: scale(0.95);
|
||||
#material3-debug-switcher button[data-mode="light"] {
|
||||
--debug-mode-icon: url("{{ media }}/icons/sun.svg");
|
||||
}
|
||||
|
||||
/* System preference detection */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html[data-darkmode="auto"] {
|
||||
--primary: #bb86fc;
|
||||
--surface-1: #121212;
|
||||
--surface-2: #1e1e1e;
|
||||
--on-surface: #ffffff;
|
||||
--on-surface-variant: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
#material3-debug-switcher button[data-mode="dark"] {
|
||||
--debug-mode-icon: url("{{ media }}/icons/moon.svg");
|
||||
}
|
||||
|
||||
#material3-debug-switcher button[data-mode="auto"] {
|
||||
--debug-mode-icon: url("{{ media }}/icons/auto.svg");
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
(function() {
|
||||
var root = document.documentElement,
|
||||
themeKey = 'material3-theme-debug',
|
||||
modeKey = 'material3-mode-debug',
|
||||
savedTheme = localStorage.getItem(themeKey);
|
||||
|
||||
if (savedTheme)
|
||||
root.setAttribute('data-theme', savedTheme);
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
if (!window.L || !L.env || L.env.requestpath.join('/') != 'admin/system/system')
|
||||
return;
|
||||
|
||||
var themes = [
|
||||
['baseline', '#6750A4'],
|
||||
['blue', '#0061A4'],
|
||||
['green', '#006D3A'],
|
||||
['teal', '#006A6A'],
|
||||
['orange', '#8F4C00'],
|
||||
['vivid-orange', '#E85D04'],
|
||||
['sakura', '#BB1614'],
|
||||
['rose', '#BA1A46'],
|
||||
['gray', '#3F3F46']
|
||||
];
|
||||
var switcher = document.createElement('div'),
|
||||
toggle = document.createElement('button'),
|
||||
panel = document.createElement('div');
|
||||
|
||||
switcher.id = 'material3-debug-switcher';
|
||||
toggle.type = 'button';
|
||||
toggle.title = 'Material3 debug switcher';
|
||||
toggle.setAttribute('aria-label', 'Material3 debug switcher');
|
||||
toggle.addEventListener('click', function() {
|
||||
switcher.toggleAttribute('open');
|
||||
});
|
||||
|
||||
function setPressed() {
|
||||
var theme = root.getAttribute('data-theme') || 'baseline',
|
||||
mode = localStorage.getItem(modeKey) || 'auto';
|
||||
|
||||
panel.querySelectorAll('[data-theme]').forEach(function(button) {
|
||||
button.setAttribute('aria-pressed', button.getAttribute('data-theme') == theme ? 'true' : 'false');
|
||||
});
|
||||
|
||||
panel.querySelectorAll('[data-mode]').forEach(function(button) {
|
||||
button.setAttribute('aria-pressed', button.getAttribute('data-mode') == mode ? 'true' : 'false');
|
||||
});
|
||||
}
|
||||
|
||||
themes.forEach(function(item) {
|
||||
var button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.title = item[0];
|
||||
button.setAttribute('data-theme', item[0]);
|
||||
button.style.setProperty('--debug-color', item[1]);
|
||||
button.addEventListener('click', function() {
|
||||
root.setAttribute('data-theme', item[0]);
|
||||
localStorage.setItem(themeKey, item[0]);
|
||||
setPressed();
|
||||
});
|
||||
panel.appendChild(button);
|
||||
});
|
||||
|
||||
['auto', 'light', 'dark'].forEach(function(mode) {
|
||||
var button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.title = mode;
|
||||
button.setAttribute('aria-label', mode);
|
||||
button.setAttribute('data-mode', mode);
|
||||
button.addEventListener('click', function() {
|
||||
if (mode == 'auto')
|
||||
localStorage.removeItem(modeKey);
|
||||
else
|
||||
localStorage.setItem(modeKey, mode);
|
||||
|
||||
if (window.material3ApplyColorMode)
|
||||
window.material3ApplyColorMode(window.matchMedia('(prefers-color-scheme: dark)'));
|
||||
|
||||
setPressed();
|
||||
});
|
||||
panel.appendChild(button);
|
||||
});
|
||||
|
||||
switcher.append(toggle, panel);
|
||||
document.body.appendChild(switcher);
|
||||
setPressed();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="lang_{{ dispatcher.lang }} {{ entityencode(striptags(node?.title ?? ''), true) }}" data-page="{{ entityencode(join('-', ctx.request_path), true) }}">
|
||||
{% if (!blank_page): %}
|
||||
<header>
|
||||
<div class="menu-btn">
|
||||
<span aria-label="{{ _('Toggle navigation menu') }}"></span>
|
||||
</div>
|
||||
|
||||
<button class="menu-btn" type="button" aria-label="{{ _('Toggle navigation menu') }}" aria-expanded="false">
|
||||
<span></span>
|
||||
</button>
|
||||
<a class="brand" href="/">{{ striptags(boardinfo.hostname ?? '?') }}</a>
|
||||
|
||||
<div class="header-controls">
|
||||
<a href="#" class="header-icon theme-toggle" id="theme-toggle" title="{{ _('Toggle dark mode') }}">
|
||||
<svg class="icon moon-icon" width="20" height="25" viewBox="0 0 24 24">
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1-8.313-12.454z"/>
|
||||
</svg>
|
||||
<svg class="icon sun-icon" width="20" height="25" viewBox="0 0 24 24">
|
||||
<path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<div id="indicators" class="pull-right"></div>
|
||||
</div>
|
||||
<div id="indicators" class="pull-right"></div>
|
||||
</header>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const toggle = document.getElementById('theme-toggle');
|
||||
const html = document.documentElement;
|
||||
const transitionDuration = 300; // ms
|
||||
|
||||
// 初始化主题(自动检测+记忆手动设置)
|
||||
function initTheme() {
|
||||
const manualMode = localStorage.getItem('luci-theme-manual');
|
||||
const autoMode = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'true' : 'false';
|
||||
const initMode = manualMode || autoMode;
|
||||
|
||||
// 添加过渡类
|
||||
html.classList.add('theme-transition');
|
||||
html.setAttribute('data-darkmode', initMode);
|
||||
updateToggleState(initMode);
|
||||
|
||||
// 移除过渡类
|
||||
setTimeout(() => {
|
||||
html.classList.remove('theme-transition');
|
||||
}, transitionDuration);
|
||||
}
|
||||
|
||||
// 更新开关状态
|
||||
function updateToggleState(isDark) {
|
||||
if (toggle) {
|
||||
toggle.checked = isDark === 'true';
|
||||
// 添加切换动画
|
||||
toggle.classList.add('theme-switching');
|
||||
setTimeout(() => {
|
||||
toggle.classList.remove('theme-switching');
|
||||
}, transitionDuration);
|
||||
}
|
||||
}
|
||||
|
||||
// 切换主题(单次点击)
|
||||
function toggleTheme() {
|
||||
const current = html.getAttribute('data-darkmode');
|
||||
const newMode = current === 'true' ? 'false' : 'true';
|
||||
|
||||
// 添加过渡类
|
||||
html.classList.add('theme-transition');
|
||||
|
||||
// 更新状态
|
||||
html.setAttribute('data-darkmode', newMode);
|
||||
localStorage.setItem('luci-theme-manual', newMode);
|
||||
updateToggleState(newMode);
|
||||
|
||||
// 移除过渡类
|
||||
setTimeout(() => {
|
||||
html.classList.remove('theme-transition');
|
||||
}, transitionDuration);
|
||||
|
||||
// 同步到服务端
|
||||
fetch('<%=url("admin/system/set-darkmode")%>', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
mode: newMode,
|
||||
source: 'manual'
|
||||
})
|
||||
}).catch(error => {
|
||||
console.error('Failed to sync theme preference:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// 监听系统主题变化
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
|
||||
if (!localStorage.getItem('luci-theme-manual')) {
|
||||
const newMode = e.matches ? 'true' : 'false';
|
||||
html.classList.add('theme-transition');
|
||||
html.setAttribute('data-darkmode', newMode);
|
||||
updateToggleState(newMode);
|
||||
setTimeout(() => {
|
||||
html.classList.remove('theme-transition');
|
||||
}, transitionDuration);
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化
|
||||
initTheme();
|
||||
|
||||
// 点击事件
|
||||
if (toggle) {
|
||||
toggle.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<aside class="sidebar">
|
||||
<aside class="sidebar" aria-label="{{ _('Navigation') }}">
|
||||
<ul class="nav" id="topmenu" style="display:none"></ul>
|
||||
</aside>
|
||||
<div class="sidebar-overlay"></div>
|
||||
|
||||
<div id="maincontent" class="container">
|
||||
{% if (getuid() == 0 && getspnam('root')?.pwdp === ''): %}
|
||||
|
||||
@ -6,6 +6,14 @@
|
||||
{% include('header', { blank_page: true }) %}
|
||||
|
||||
<section hidden>
|
||||
<div class="material3-login-header">
|
||||
<img src="{{ media }}/logo.svg" alt="">
|
||||
<div>
|
||||
<h2>{{ _('Authorization Required') }}</h2>
|
||||
<p>{{ _('Sign in to manage this device.') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="post" class="cbi-map">
|
||||
<div class="cbi-section">
|
||||
<div class="cbi-section-node">
|
||||
@ -21,13 +29,49 @@
|
||||
<input name="luci_password" id="luci_password" type="password" autocomplete="current-password">
|
||||
</div>
|
||||
</div>
|
||||
{% if (auth_fields): %}
|
||||
{% for (let field in auth_fields): %}
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title" for="{{ field.name }}">{{ _(field.label ?? field.name) }}</label>
|
||||
<div class="cbi-value-field">
|
||||
<input
|
||||
name="{{ field.name }}"
|
||||
id="{{ field.name }}"
|
||||
type="{{ field.type ?? 'text' }}"
|
||||
{% if (field.placeholder): %}placeholder="{{ field.placeholder }}"{% endif %}
|
||||
{% if (field.inputmode): %}inputmode="{{ field.inputmode }}"{% endif %}
|
||||
{% if (field.pattern): %}pattern="{{ field.pattern }}"{% endif %}
|
||||
{% if (field.maxlength): %}maxlength="{{ field.maxlength }}"{% endif %}
|
||||
{% if (field.autocomplete): %}autocomplete="{{ field.autocomplete }}"{% endif %}
|
||||
{% if (field.required): %}required{% endif %}
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if (auth_html): %}
|
||||
<div class="cbi-value">
|
||||
{{ auth_html }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if (auth_assets): %}
|
||||
{% for (let asset in auth_assets): %}
|
||||
{% if (asset.type == 'script'): %}
|
||||
<script src="{{ asset.src }}"></script>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
{% if (fuser): %}
|
||||
{% if (auth_message): %}
|
||||
<div class="alert-message{% if (auth_plugin): %} warning{% endif %}">
|
||||
{{ auth_message }}
|
||||
</div>
|
||||
{% elif (fuser): %}
|
||||
<div class="alert-message error">
|
||||
{{ _('Invalid username and/or password! Please try again.') }}
|
||||
</div>
|
||||
|
||||