update 2026-08-13 00:52:18

This commit is contained in:
action
2026-08-13 00:52:18 +08:00
parent 8de61e28f3
commit 78221232e9
20 changed files with 700 additions and 19 deletions
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 389 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 640 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 659 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

+1 -1
View File
@@ -10,7 +10,7 @@ LUCI_DEPENDS:=+luci-base +luci-lib-jsonc +curl +bandix
PKG_MAINTAINER:=timsaya
PKG_VERSION:=0.12.8
PKG_VERSION:=0.12.9
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk
Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

@@ -9,6 +9,11 @@
var BANDIX_COLOR_UPLOAD = '#f97316'; // 橙色 - 上传/上行
var BANDIX_COLOR_DOWNLOAD = '#06b6d4'; // 青色 - 下载/下行
// 远程广告配置
var BANDIX_AD_CONFIG_URL = 'https://raw.githubusercontent.com/timsaya/bandix-ads/main/ads.json';
var BANDIX_AD_DEFAULT_REFRESH_INTERVAL = 3600;
var BANDIX_AD_RETRY_INTERVAL = 900;
// 悬浮框背景色定义
var BANDIX_TOOLTIP_BG_OPENWRT2020_LIGHT = '#ffffff'; // OpenWrt 2020 浅色主题悬浮框背景
var BANDIX_TOOLTIP_BG_OPENWRT2020_DARK = '#2a2a2a'; // OpenWrt 2020 深色主题悬浮框背景
@@ -556,6 +561,117 @@ return view.extend({
background-color: rgba(239, 68, 68, 0.2);
transform: translateY(-1px);
}
.bandix-ad-row {
display: grid;
grid-template-columns: repeat(var(--bandix-ad-count, 6), minmax(112px, 1fr));
gap: 8px;
margin: 12px 0;
overflow-x: auto;
scrollbar-width: thin;
}
.bandix-ad-slot {
flex: 1 1 0;
min-width: 112px;
padding: 0;
aspect-ratio: 3 / 1;
border: 1px solid rgba(107, 114, 128, 0.35);
border-radius: 6px;
background: linear-gradient(135deg, rgba(225, 37, 27, 0.08), rgba(107, 114, 128, 0.04));
display: flex;
align-items: center;
color: inherit;
box-sizing: border-box;
overflow: hidden;
position: relative;
text-decoration: none;
transition: border-color 0.2s ease, transform 0.2s ease;
}
.bandix-ad-slot:not(.bandix-ad-disabled):hover,
.bandix-ad-slot:not(.bandix-ad-disabled):focus-visible {
border-color: rgba(225, 37, 27, 0.75);
box-shadow: 0 4px 12px rgba(225, 37, 27, 0.12);
transform: translateY(-2px);
}
.bandix-ad-disabled {
cursor: default;
}
.bandix-ad-label {
align-self: flex-start;
padding: 1px 5px;
border: none;
border-radius: 3px;
background: rgba(225, 37, 27, 0.88);
color: #ffffff;
font-size: 0.5625rem;
font-weight: 700;
letter-spacing: 0.08em;
line-height: 1.4;
}
.bandix-ad-copy {
align-self: stretch;
flex: 1 1 auto;
min-width: 0;
padding: 6px 4px 6px 8px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 3px;
box-sizing: border-box;
}
.bandix-ad-title {
width: 100%;
font-size: 0.6875rem;
font-weight: 600;
line-height: 1.25;
text-align: left;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.bandix-ad-media {
align-self: stretch;
flex: 0 0 33.333333%;
min-width: 0;
aspect-ratio: 1 / 1;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.92);
}
.bandix-ad-image {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
.bandix-ad-placeholder {
flex: 0 0 33.333333%;
aspect-ratio: 1 / 1;
align-self: stretch;
display: flex;
align-items: center;
justify-content: center;
padding: 3px;
background: rgba(255, 255, 255, 0.92);
color: #e1251b;
font-size: 0.625rem;
font-weight: 700;
line-height: 1.2;
text-align: center;
box-sizing: border-box;
}
/* 移动端隐藏版本信息和更新徽章 */
@@ -563,6 +679,26 @@ return view.extend({
.bandix-version-wrapper {
display: none;
}
.bandix-ad-row {
display: flex;
gap: 6px;
padding-bottom: 4px;
}
.bandix-ad-slot {
flex: 0 0 180px;
min-width: 180px;
height: 60px;
}
.bandix-ad-copy {
padding-left: 7px;
}
.bandix-ad-title {
font-size: 0.625rem;
}
}
.device-mode-group {
@@ -2820,6 +2956,25 @@ return view.extend({
])
]),
// 广告数据从公开仓库动态加载
E('div', {
'class': 'bandix-ad-row',
'id': 'bandix-ad-row',
'aria-label': _('Advertising spaces')
}, [1, 2, 3, 4, 5, 6].map(function (index) {
return E('div', {
'class': 'bandix-ad-slot bandix-ad-disabled',
'data-ad-slot': String(index),
'aria-disabled': 'true'
}, [
E('div', { 'class': 'bandix-ad-copy' }, [
E('span', { 'class': 'bandix-ad-label' }, _('AD')),
E('span', { 'class': 'bandix-ad-title' }, _('Advertising space') + ' ' + index)
]),
E('span', { 'class': 'bandix-ad-placeholder' }, _('Advertising space'))
]);
})),
// 警告提示(包含在线设备数)
E('div', {
'class': 'bandix-alert' + (getThemeType() === 'wide' ? ' wide-theme' : '')
@@ -2975,7 +3130,8 @@ return view.extend({
])
]),
E('div', { 'class': 'usage-ranking-query-presets' }, [
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'today' }, _('Today')),
E('button', { 'class': 'cbi-button cbi-button-positive', 'data-preset': 'today' }, _('Today')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'yesterday' }, _('Yesterday')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'thisweek' }, _('This Week')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'lastweek' }, _('Last Week')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'thismonth' }, _('This Month')),
@@ -2983,7 +3139,7 @@ return view.extend({
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '7days' }, _('Last 7 Days')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '30days' }, _('Last 30 Days')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '90days' }, _('Last 90 Days')),
E('button', { 'class': 'cbi-button cbi-button-positive', 'data-preset': '1year' }, _('Last Year'))
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '1year' }, _('Last Year'))
]),
E('div', { 'class': 'usage-ranking-timeline', 'id': 'usage-ranking-timeline' }, [
E('div', { 'class': 'usage-ranking-timeline-range', 'id': 'usage-ranking-timeline-range' })
@@ -3047,7 +3203,8 @@ return view.extend({
])
]),
E('div', { 'class': 'usage-ranking-query-presets' }, [
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'today' }, _('Today')),
E('button', { 'class': 'cbi-button cbi-button-positive', 'data-preset': 'today' }, _('Today')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'yesterday' }, _('Yesterday')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'thisweek' }, _('This Week')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'lastweek' }, _('Last Week')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'thismonth' }, _('This Month')),
@@ -3055,7 +3212,7 @@ return view.extend({
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '7days' }, _('Last 7 Days')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '30days' }, _('Last 30 Days')),
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '90days' }, _('Last 90 Days')),
E('button', { 'class': 'cbi-button cbi-button-positive', 'data-preset': '1year' }, _('Last Year'))
E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '1year' }, _('Last Year'))
]),
E('div', { 'class': 'usage-ranking-timeline', 'id': 'traffic-increments-timeline' }, [
E('div', { 'class': 'usage-ranking-timeline-range', 'id': 'traffic-increments-timeline-range' })
@@ -7504,7 +7661,6 @@ return view.extend({
updateDeviceData();
refreshWhitelistStatus();
fetchAllScheduleRules();
updateTrafficStatistics();
// 初始化时间范围查询功能
setTimeout(function () {
@@ -7631,6 +7787,12 @@ return view.extend({
startDate = new Date(today);
endDate = new Date(today);
break;
case 'yesterday':
var yesterdayDate = new Date(today);
yesterdayDate.setDate(yesterdayDate.getDate() - 1);
startDate = new Date(yesterdayDate);
endDate = new Date(yesterdayDate);
break;
case 'thisweek':
// 本周:周一到今天
var dayOfWeek = today.getDay(); // 0=周日, 1=周一, ..., 6=周六
@@ -7724,18 +7886,16 @@ return view.extend({
// 重置按钮
if (resetBtn) {
resetBtn.addEventListener('click', function () {
var oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());
setDateRange(oneYearAgo, today, '1year');
setDateRange(today, today, 'today');
queryData();
});
}
// 初始化:默认选择最近一年
var oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());
setDateRange(oneYearAgo, today, '1year');
// 初始化:默认选择今天
setDateRange(today, today, 'today');
// 设置初始时间范围并自动加载数据(结束时间为当天的 23:59:59)
var startMs = oneYearAgo.getTime();
var startMs = todayMs;
var endToday = new Date(today);
endToday.setHours(23, 59, 59, 999);
var endMs = endToday.getTime();
@@ -7896,6 +8056,12 @@ return view.extend({
startDate = new Date(today);
endDate = new Date(today);
break;
case 'yesterday':
var yesterdayDate = new Date(today);
yesterdayDate.setDate(yesterdayDate.getDate() - 1);
startDate = new Date(yesterdayDate);
endDate = new Date(yesterdayDate);
break;
case 'thisweek':
var dayOfWeek = today.getDay();
var mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
@@ -7952,15 +8118,13 @@ return view.extend({
// 重置按钮
if (resetBtn) {
resetBtn.addEventListener('click', function () {
var oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());
setDateRange(oneYearAgo, today, '1year');
setDateRange(today, today, 'today');
queryData();
});
}
// 初始化:默认选择最近一年
var oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());
setDateRange(oneYearAgo, today, '1year');
// 初始化:默认选择今天
setDateRange(today, today, 'today');
startDateInput.addEventListener('change', function () {
updateTimeline(this.value, endDateInput.value);
@@ -7971,7 +8135,7 @@ return view.extend({
});
// 设置初始时间范围并自动加载数据(不显示 loading)
var startMs = oneYearAgo.getTime();
var startMs = todayMs;
var endToday = new Date(today);
endToday.setHours(23, 59, 59, 999);
var endMs = endToday.getTime();
@@ -7983,6 +8147,205 @@ return view.extend({
updateTrafficIncrements(startMs, endMs, null, null);
}, 700);
// 异步加载远程广告(不阻塞主流程)
(function () {
var refreshTimer = null;
function resolveHttpsUrl(value, baseUrl) {
if (typeof value !== 'string' || !value) return null;
try {
var resolved = new URL(value, baseUrl);
return resolved.protocol === 'https:' ? resolved.href : null;
} catch (e) {
return null;
}
}
function scheduleRefresh(seconds) {
var interval = Number(seconds);
if (!Number.isFinite(interval)) interval = BANDIX_AD_DEFAULT_REFRESH_INTERVAL;
interval = Math.max(300, Math.min(86400, interval));
if (refreshTimer !== null) window.clearTimeout(refreshTimer);
refreshTimer = window.setTimeout(loadAdvertisements, interval * 1000);
}
function normalizeAdvertisementLocale(value) {
if (typeof value !== 'string') return '';
var locale = value.trim().replace(/_/g, '-').toLowerCase();
if (!locale || locale === 'auto' || locale === 'und') return '';
if (locale === 'zh' || locale === 'zh-cn' || locale === 'zh-sg' || locale === 'zh-hans') {
return 'zh-hans';
}
if (locale === 'zh-tw' || locale === 'zh-hk' || locale === 'zh-mo' || locale === 'zh-hant') {
return 'zh-hant';
}
return locale;
}
function getAdvertisementLocale() {
var candidates = [];
if (L.env) candidates.push(L.env.lang || L.env.language || '');
var htmlLanguage = document.documentElement.getAttribute('lang');
if (htmlLanguage) candidates.push(htmlLanguage);
if (window.navigator) candidates.push(window.navigator.language || '');
for (var i = 0; i < candidates.length; i++) {
var locale = normalizeAdvertisementLocale(candidates[i]);
if (locale) return locale;
}
return '';
}
function selectLocalizedAdvertisements(config) {
// 兼容旧版单语言配置,方便两个仓库分开部署
if (config.version === 1 && Array.isArray(config.ads)) {
return { locale: 'legacy', ads: config.ads };
}
if (config.version !== 2 || !config.locales || typeof config.locales !== 'object') {
throw new Error('Invalid advertising configuration');
}
var currentLocale = getAdvertisementLocale();
var defaultLocale = normalizeAdvertisementLocale(config.default_locale);
var localeCandidates = [];
if (currentLocale) {
localeCandidates.push(currentLocale);
var separatorIndex = currentLocale.indexOf('-');
if (separatorIndex > 0) localeCandidates.push(currentLocale.substring(0, separatorIndex));
}
if (defaultLocale) localeCandidates.push(defaultLocale);
for (var i = 0; i < localeCandidates.length; i++) {
var candidate = localeCandidates[i];
if (Object.prototype.hasOwnProperty.call(config.locales, candidate) &&
Array.isArray(config.locales[candidate])) {
return { locale: candidate, ads: config.locales[candidate] };
}
}
throw new Error('No advertising locale is available');
}
function renderAdvertisements(config) {
var adRow = document.getElementById('bandix-ad-row');
if (!adRow || !config) {
throw new Error('Invalid advertising configuration');
}
var selection = selectLocalizedAdvertisements(config);
adRow.setAttribute('data-ad-locale', selection.locale);
var ads = selection.ads.slice(0, 6).map(function (ad, index) {
if (!ad || typeof ad !== 'object') ad = {};
var href = resolveHttpsUrl(ad.href, BANDIX_AD_CONFIG_URL);
var image = resolveHttpsUrl(ad.image, BANDIX_AD_CONFIG_URL);
var title = typeof ad.title === 'string' ? ad.title.trim() : _('Advertising space') + ' ' + (index + 1);
if (!title) title = _('Advertising space') + ' ' + (index + 1);
var alt = typeof ad.alt === 'string' ? ad.alt.trim() : title;
return {
enabled: ad.enabled === true && href !== null,
href: href,
image: image,
title: title,
alt: alt || title
};
});
while (ads.length < 6) {
ads.push({
enabled: false,
href: null,
image: null,
title: _('Advertising space') + ' ' + (ads.length + 1),
alt: _('Advertising space')
});
}
while (adRow.firstChild) adRow.removeChild(adRow.firstChild);
ads.forEach(function (ad, index) {
var tagName = ad.enabled ? 'a' : 'div';
var attributes = {
'class': 'bandix-ad-slot' + (ad.enabled ? '' : ' bandix-ad-disabled'),
'data-ad-slot': String(index + 1),
'title': ad.title
};
if (ad.enabled) {
attributes.href = ad.href;
attributes.target = '_blank';
attributes.rel = 'noopener noreferrer sponsored';
} else {
attributes['aria-disabled'] = 'true';
}
var content = [E('div', { 'class': 'bandix-ad-copy' }, [
E('span', { 'class': 'bandix-ad-label' }, _('AD')),
E('span', { 'class': 'bandix-ad-title' }, ad.title)
])];
if (ad.enabled && ad.image) {
content.push(E('div', { 'class': 'bandix-ad-media' }, [
E('img', {
'class': 'bandix-ad-image',
'src': ad.image,
'alt': ad.alt,
'loading': 'lazy',
'referrerpolicy': 'no-referrer'
})
]));
} else {
content.push(E('span', { 'class': 'bandix-ad-placeholder' }, _('Advertising space')));
}
adRow.appendChild(E(tagName, attributes, content));
});
adRow.style.setProperty('--bandix-ad-count', '6');
}
function loadAdvertisements() {
var adRow = document.getElementById('bandix-ad-row');
if (!adRow) return;
if (typeof window.fetch !== 'function') {
console.debug('Failed to load advertisements: Fetch API is unavailable');
scheduleRefresh(BANDIX_AD_RETRY_INTERVAL);
return;
}
var separator = BANDIX_AD_CONFIG_URL.indexOf('?') === -1 ? '?' : '&';
var configUrl = BANDIX_AD_CONFIG_URL + separator + '_=' + Date.now();
window.fetch(configUrl, {
method: 'GET',
mode: 'cors',
credentials: 'omit',
cache: 'no-store'
}).then(function (response) {
if (!response.ok) throw new Error('HTTP ' + response.status);
return response.json();
}).then(function (config) {
renderAdvertisements(config);
scheduleRefresh(config.refresh_interval);
}).catch(function (err) {
console.debug('Failed to load advertisements:', err);
scheduleRefresh(BANDIX_AD_RETRY_INTERVAL);
});
}
window.setTimeout(loadAdvertisements, 200);
})();
// 异步加载版本信息(不阻塞主流程)
(function () {
// 延迟执行,确保页面先完成初始化
@@ -673,6 +673,46 @@ return view.extend({
return false;
};
// 支持作者(基本设置的最后一项)
var alipayImage = L.resource('bandix/donate/alipay.jpg');
var wechatImage = L.resource('bandix/donate/wechat-pay.png');
function donationCard(title, imageUrl, altText, dotClass) {
return E('div', { 'class': 'bandix-donation-card' }, [
E('h4', { 'class': 'bandix-donation-card-title' }, [
E('span', { 'class': 'bandix-donation-dot ' + dotClass }),
title
]),
E('a', {
'class': 'bandix-donation-image-link',
'href': imageUrl,
'target': '_blank',
'rel': 'noopener noreferrer',
'title': altText
}, [
E('img', {
'class': 'bandix-donation-image',
'src': imageUrl,
'alt': altText,
'loading': 'lazy'
})
])
]);
}
o = s.option(form.DummyValue, '_donation_qr_codes', _('Support the Author'));
o.renderWidget = function () {
return E('div', { 'class': 'bandix-donation-content' }, [
E('p', { 'class': 'bandix-donation-description' },
_('If Bandix is useful to you, you can support its continued development.')),
E('div', { 'class': 'bandix-donation-grid' }, [
donationCard(_('Alipay'), alipayImage, _('Scan with Alipay to support'), 'bandix-donation-dot-alipay'),
donationCard(_('WeChat Pay'), wechatImage, _('Scan with WeChat Pay to support'), 'bandix-donation-dot-wechat')
]),
E('p', { 'class': 'bandix-donation-note' }, _('Donations are voluntary. Thank you for supporting Bandix.'))
]);
};
// 2. 流量监控设置部分 (traffic)
s = m.section(form.NamedSection, 'traffic', 'traffic', _('Traffic Monitor Settings'));
s.description = _('Configure traffic monitoring related parameters');
@@ -826,6 +866,98 @@ return view.extend({
// 将 view 实例关联到 form map,以便在 cfgvalue 中访问
m.view = this;
return m.render();
return m.render().then(function (mapEl) {
var oldStyle = document.getElementById('bandix-donation-styles');
if (oldStyle && oldStyle.parentNode) oldStyle.parentNode.removeChild(oldStyle);
document.head.appendChild(E('style', { 'id': 'bandix-donation-styles' }, `
.bandix-donation-content {
text-align: center;
}
.bandix-donation-description {
margin: 0 auto 18px;
max-width: 620px;
opacity: 0.72;
line-height: 1.6;
}
.bandix-donation-grid {
display: grid;
grid-template-columns: repeat(2, minmax(220px, 280px));
justify-content: center;
gap: 20px;
}
.bandix-donation-card {
padding: 12px;
border: 1px solid rgba(107, 114, 128, 0.3);
border-radius: 10px;
background: rgba(107, 114, 128, 0.04);
box-sizing: border-box;
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.bandix-donation-card:hover {
border-color: rgba(59, 130, 246, 0.55);
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.1);
transform: translateY(-2px);
}
.bandix-donation-card-title {
display: flex;
align-items: center;
justify-content: center;
gap: 7px;
margin: 0 0 10px;
font-size: 1rem;
font-weight: 600;
}
.bandix-donation-dot {
width: 9px;
height: 9px;
border-radius: 50%;
flex-shrink: 0;
}
.bandix-donation-dot-alipay {
background: #1677ff;
}
.bandix-donation-dot-wechat {
background: #07c160;
}
.bandix-donation-image-link {
display: block;
border-radius: 7px;
overflow: hidden;
background: #ffffff;
line-height: 0;
}
.bandix-donation-image {
display: block;
width: 100%;
height: auto;
}
.bandix-donation-note {
margin: 14px 0 0;
font-size: 0.75rem;
opacity: 0.58;
}
@media (max-width: 600px) {
.bandix-donation-grid {
grid-template-columns: minmax(200px, 280px);
gap: 14px;
}
}
`));
return mapEl;
});
}
});
+24
View File
@@ -1112,6 +1112,30 @@ msgstr "Restablecer"
msgid "Today"
msgstr "Hoy"
msgid "Yesterday"
msgstr "Ayer"
msgid "Support the Author"
msgstr "Apoyar al autor"
msgid "If Bandix is useful to you, you can support its continued development."
msgstr "Si Bandix te resulta útil, puedes apoyar su desarrollo continuo."
msgid "Alipay"
msgstr "Alipay"
msgid "Scan with Alipay to support"
msgstr "Escanea con Alipay para apoyar"
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgid "Scan with WeChat Pay to support"
msgstr "Escanea con WeChat Pay para apoyar"
msgid "Donations are voluntary. Thank you for supporting Bandix."
msgstr "Las donaciones son voluntarias. Gracias por apoyar a Bandix."
msgid "This Week"
msgstr "Esta Semana"
+24
View File
@@ -1112,6 +1112,30 @@ msgstr "Réinitialiser"
msgid "Today"
msgstr "Aujourd'hui"
msgid "Yesterday"
msgstr "Hier"
msgid "Support the Author"
msgstr "Soutenir lauteur"
msgid "If Bandix is useful to you, you can support its continued development."
msgstr "Si Bandix vous est utile, vous pouvez soutenir la poursuite de son développement."
msgid "Alipay"
msgstr "Alipay"
msgid "Scan with Alipay to support"
msgstr "Scannez avec Alipay pour nous soutenir"
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgid "Scan with WeChat Pay to support"
msgstr "Scannez avec WeChat Pay pour nous soutenir"
msgid "Donations are voluntary. Thank you for supporting Bandix."
msgstr "Les dons sont facultatifs. Merci de soutenir Bandix."
msgid "This Week"
msgstr "Cette Semaine"
+24
View File
@@ -1112,6 +1112,30 @@ msgstr "リセット"
msgid "Today"
msgstr "今日"
msgid "Yesterday"
msgstr "昨日"
msgid "Support the Author"
msgstr "作者を支援"
msgid "If Bandix is useful to you, you can support its continued development."
msgstr "Bandix が役に立った場合は、継続的な開発をご支援いただけます。"
msgid "Alipay"
msgstr "Alipay"
msgid "Scan with Alipay to support"
msgstr "Alipay でスキャンして支援"
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgid "Scan with WeChat Pay to support"
msgstr "WeChat Pay でスキャンして支援"
msgid "Donations are voluntary. Thank you for supporting Bandix."
msgstr "寄付は任意です。Bandix をご支援いただきありがとうございます。"
msgid "This Week"
msgstr "今週"
+24
View File
@@ -1112,6 +1112,30 @@ msgstr "Resetuj"
msgid "Today"
msgstr "Dzisiaj"
msgid "Yesterday"
msgstr "Wczoraj"
msgid "Support the Author"
msgstr "Wesprzyj autora"
msgid "If Bandix is useful to you, you can support its continued development."
msgstr "Jeśli Bandix jest dla Ciebie przydatny, możesz wesprzeć jego dalszy rozwój."
msgid "Alipay"
msgstr "Alipay"
msgid "Scan with Alipay to support"
msgstr "Zeskanuj w Alipay, aby wesprzeć"
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgid "Scan with WeChat Pay to support"
msgstr "Zeskanuj w WeChat Pay, aby wesprzeć"
msgid "Donations are voluntary. Thank you for supporting Bandix."
msgstr "Darowizny są dobrowolne. Dziękujemy za wsparcie Bandix."
msgid "This Week"
msgstr "Ten Tydzień"
+24
View File
@@ -1112,6 +1112,30 @@ msgstr "Сбросить"
msgid "Today"
msgstr "Сегодня"
msgid "Yesterday"
msgstr "Вчера"
msgid "Support the Author"
msgstr "Поддержать автора"
msgid "If Bandix is useful to you, you can support its continued development."
msgstr "Если Bandix полезен вам, вы можете поддержать его дальнейшую разработку."
msgid "Alipay"
msgstr "Alipay"
msgid "Scan with Alipay to support"
msgstr "Отсканируйте в Alipay, чтобы поддержать"
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgid "Scan with WeChat Pay to support"
msgstr "Отсканируйте в WeChat Pay, чтобы поддержать"
msgid "Donations are voluntary. Thank you for supporting Bandix."
msgstr "Пожертвования добровольны. Спасибо за поддержку Bandix."
msgid "This Week"
msgstr "На этой неделе"
+33
View File
@@ -1094,6 +1094,15 @@ msgstr "有更新"
msgid "Update available, click to go to settings"
msgstr "有更新,点击前往设置"
msgid "Advertising spaces"
msgstr "广告位"
msgid "Advertising space"
msgstr "广告位"
msgid "AD"
msgstr "广告"
msgid "Traffic Statistics"
msgstr "流量统计"
@@ -1115,6 +1124,30 @@ msgstr "重置"
msgid "Today"
msgstr "今天"
msgid "Yesterday"
msgstr "昨天"
msgid "Support the Author"
msgstr "支持作者"
msgid "If Bandix is useful to you, you can support its continued development."
msgstr "如果 Bandix 对您有帮助,您可以支持项目的持续开发。"
msgid "Alipay"
msgstr "支付宝"
msgid "Scan with Alipay to support"
msgstr "使用支付宝扫码支持"
msgid "WeChat Pay"
msgstr "微信支付"
msgid "Scan with WeChat Pay to support"
msgstr "使用微信支付扫码支持"
msgid "Donations are voluntary. Thank you for supporting Bandix."
msgstr "赞助完全自愿。感谢您对 Bandix 的支持。"
msgid "This Week"
msgstr "本周"
+33
View File
@@ -1112,6 +1112,30 @@ msgstr "重置"
msgid "Today"
msgstr "今天"
msgid "Yesterday"
msgstr "昨天"
msgid "Support the Author"
msgstr "支持作者"
msgid "If Bandix is useful to you, you can support its continued development."
msgstr "如果 Bandix 對您有幫助,您可以支持專案的持續開發。"
msgid "Alipay"
msgstr "支付寶"
msgid "Scan with Alipay to support"
msgstr "使用支付寶掃碼支持"
msgid "WeChat Pay"
msgstr "微信支付"
msgid "Scan with WeChat Pay to support"
msgstr "使用微信支付掃碼支持"
msgid "Donations are voluntary. Thank you for supporting Bandix."
msgstr "贊助完全自願。感謝您對 Bandix 的支持。"
msgid "This Week"
msgstr "本週"
@@ -1255,3 +1279,12 @@ msgstr "TCX 出站錨點程式 ID"
msgid "Used when tc_order is before/after. Must be a valid egress program id on the same interface."
msgstr "當 tc_order 為 before/after 時使用。必須是同一介面上的有效出站程式 ID。"
msgid "Advertising spaces"
msgstr "廣告位"
msgid "Advertising space"
msgstr "廣告位"
msgid "AD"
msgstr "廣告"