Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ export function getInitialLocale(): AppLocale {
return detectBrowserLocale() ?? 'en';
}

// Russian and Ukrainian use three cardinal forms for the filter count summary.
function russianUkrainianPlural(choice: number, choicesLength: number): number {
const number = Math.abs(choice);
if (choicesLength === 2) return number === 1 ? 0 : 1;
if (number % 10 === 1 && number % 100 !== 11) return 0;
if (number % 10 >= 2 && number % 10 <= 4 && (number % 100 < 10 || number % 100 >= 20)) {
return 1;
}
return 2;
}

const MOMENT_LOCALE: Record<AppLocale, string> = {
en: 'en',
uk: 'uk',
Expand All @@ -74,6 +85,10 @@ export const i18n = new VueI18n({
locale: initialLocale,
fallbackLocale: 'en',
messages: { en, uk, de, ru, 'zh-CN': zhCN, sv },
pluralizationRules: {
ru: russianUkrainianPlural,
uk: russianUkrainianPlural,
},
silentTranslationWarn: process.env.NODE_ENV === 'production',
});

Expand Down
29 changes: 29 additions & 0 deletions src/i18n/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,35 @@ export default {
noEvents: 'Keine Ereignisse entsprechen den Kriterien. Zeitleiste nicht aktualisiert.',
scrollHint: 'Scrollen zum Zoomen, Wischen zum Schwenken, Pfeiltasten zur Navigation',
loading: 'Laden…',
filters: {
label: 'Filter:',
reset: 'Zurücksetzen',
duration: 'Dauer:',
hosts: 'Hosts:',
clients: 'Clients:',
categories: 'Kategorien:',
all: 'Alle',
min: 'Min.',
max: 'Max.',
minimumDuration: 'Mindestdauer',
maximumDuration: 'Höchstdauer',
minimumDurationUnit: 'Einheit der Mindestdauer',
maximumDurationUnit: 'Einheit der Höchstdauer',
seconds: 'Sekunden',
minutes: 'Minuten',
hours: 'Stunden',
durationNonNegativeError: 'Dauerwerte dürfen nicht negativ sein.',
durationError: 'Die Mindestdauer darf die Höchstdauer nicht überschreiten.',
hostCount: '{count} Host | {count} Hosts',
clientCount: '{count} Client | {count} Clients',
categoryCount: '{count} Kategorie | {count} Kategorien',
afkSummary: 'AFK gefiltert',
mergeSummary: 'nach App zusammengeführt',
none: 'keine',
durationRange: '{min} bis {max}',
durationAtLeast: 'Mindestens {value}',
durationAtMost: 'Höchstens {value}',
},
},
stopwatch: {
title: 'Stoppuhr',
Expand Down
29 changes: 29 additions & 0 deletions src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,35 @@ export default {
noEvents: 'No events match selected criteria. Timeline is not updated.',
scrollHint: 'Scroll to zoom, swipe/horizontal-scroll to pan, arrow keys to navigate',
loading: 'Loading...',
filters: {
label: 'Filters:',
reset: 'Reset',
duration: 'Duration:',
hosts: 'Hosts:',
clients: 'Clients:',
categories: 'Categories:',
all: 'All',
min: 'Min',
max: 'Max',
minimumDuration: 'Minimum duration',
maximumDuration: 'Maximum duration',
minimumDurationUnit: 'Minimum duration unit',
maximumDurationUnit: 'Maximum duration unit',
seconds: 'seconds',
minutes: 'minutes',
hours: 'hours',
durationNonNegativeError: 'Duration values cannot be negative.',
durationError: 'Minimum duration cannot exceed maximum duration.',
hostCount: '{count} host | {count} hosts',
clientCount: '{count} client | {count} clients',
categoryCount: '{count} category | {count} categories',
afkSummary: 'AFK filtered',
mergeSummary: 'merged by app',
none: 'none',
durationRange: '{min} – {max}',
durationAtLeast: 'At least {value}',
durationAtMost: 'At most {value}',
},
},
stopwatch: {
title: 'Stopwatch',
Expand Down
29 changes: 29 additions & 0 deletions src/i18n/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,35 @@ export default {
scrollHint:
'Колёсико — масштаб, свайп/горизонтальная прокрутка — панорама, стрелки — навигация',
loading: 'Загрузка…',
filters: {
label: 'Фильтры:',
reset: 'Сбросить',
duration: 'Длительность:',
hosts: 'Хосты:',
clients: 'Клиенты:',
categories: 'Категории:',
all: 'Все',
min: 'Мин.',
max: 'Макс.',
minimumDuration: 'Минимальная длительность',
maximumDuration: 'Максимальная длительность',
minimumDurationUnit: 'Единица минимальной длительности',
maximumDurationUnit: 'Единица максимальной длительности',
seconds: 'секунды',
minutes: 'минуты',
hours: 'часы',
durationNonNegativeError: 'Значения длительности не могут быть отрицательными.',
durationError: 'Минимальная длительность не может превышать максимальную.',
hostCount: '{count} хост | {count} хоста | {count} хостов',
clientCount: '{count} клиент | {count} клиента | {count} клиентов',
categoryCount: '{count} категория | {count} категории | {count} категорий',
afkSummary: 'AFK отфильтровано',
mergeSummary: 'объединено по приложению',
none: 'нет',
durationRange: 'от {min} до {max}',
durationAtLeast: 'Не менее {value}',
durationAtMost: 'Не более {value}',
},
},
stopwatch: {
title: 'Секундомер',
Expand Down
29 changes: 29 additions & 0 deletions src/i18n/locales/sv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,35 @@ export default {
scrollHint:
'Rulla för att zooma, svep/rulla horisontellt för att panorera, använd piltangenterna för att navigera',
loading: 'Läser in...',
filters: {
label: 'Filter:',
reset: 'Återställ',
duration: 'Varaktighet:',
hosts: 'Värdar:',
clients: 'Klienter:',
categories: 'Kategorier:',
all: 'Alla',
min: 'Min',
max: 'Max',
minimumDuration: 'Minsta varaktighet',
maximumDuration: 'Högsta varaktighet',
minimumDurationUnit: 'Enhet för minsta varaktighet',
maximumDurationUnit: 'Enhet för högsta varaktighet',
seconds: 'sekunder',
minutes: 'minuter',
hours: 'timmar',
durationNonNegativeError: 'Varaktighetsvärden får inte vara negativa.',
durationError: 'Minsta varaktighet kan inte vara längre än den högsta.',
hostCount: '{count} värd | {count} värdar',
clientCount: '{count} klient | {count} klienter',
categoryCount: '{count} kategori | {count} kategorier',
afkSummary: 'AFK filtrerat',
mergeSummary: 'sammanslagna efter program',
none: 'inga',
durationRange: '{min} till {max}',
durationAtLeast: 'Minst {value}',
durationAtMost: 'Högst {value}',
},
},
stopwatch: {
title: 'Stoppur',
Expand Down
29 changes: 29 additions & 0 deletions src/i18n/locales/uk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,35 @@ export default {
scrollHint:
'Коліщатко — масштаб, свайп/горизонтальна прокрутка — панорама, стрілки — навігація',
loading: 'Завантаження…',
filters: {
label: 'Фільтри:',
reset: 'Скинути',
duration: 'Тривалість:',
hosts: 'Хости:',
clients: 'Клієнти:',
categories: 'Категорії:',
all: 'Усі',
min: 'Мін.',
max: 'Макс.',
minimumDuration: 'Мінімальна тривалість',
maximumDuration: 'Максимальна тривалість',
minimumDurationUnit: 'Одиниця мінімальної тривалості',
maximumDurationUnit: 'Одиниця максимальної тривалості',
seconds: 'секунди',
minutes: 'хвилини',
hours: 'години',
durationNonNegativeError: 'Значення тривалості не можуть бути від’ємними.',
durationError: 'Мінімальна тривалість не може перевищувати максимальну.',
hostCount: '{count} хост | {count} хости | {count} хостів',
clientCount: '{count} клієнт | {count} клієнти | {count} клієнтів',
categoryCount: '{count} категорія | {count} категорії | {count} категорій',
afkSummary: 'AFK відфільтровано',
mergeSummary: 'об’єднано за застосунком',
none: 'немає',
durationRange: 'від {min} до {max}',
durationAtLeast: 'Не менше {value}',
durationAtMost: 'Не більше {value}',
},
},
stopwatch: {
title: 'Секундомір',
Expand Down
29 changes: 29 additions & 0 deletions src/i18n/locales/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,35 @@ export default {
noEvents: '没有符合筛选条件的事件。未更新时间线。',
scrollHint: '滚动缩放,滑动/水平滚动平移,方向键导航',
loading: '加载中...',
filters: {
label: '筛选器:',
reset: '重置',
duration: '时长:',
hosts: '主机:',
clients: '客户端:',
categories: '分类:',
all: '全部',
min: '最小值',
max: '最大值',
minimumDuration: '最小时长',
maximumDuration: '最大时长',
minimumDurationUnit: '最小时长单位',
maximumDurationUnit: '最大时长单位',
seconds: '秒',
minutes: '分钟',
hours: '小时',
durationNonNegativeError: '时长不能为负数。',
durationError: '最小时长不能大于最大时长。',
hostCount: '{count} 个主机',
clientCount: '{count} 个客户端',
categoryCount: '{count} 个分类',
afkSummary: '已过滤 AFK',
mergeSummary: '已按应用合并',
none: '无',
durationRange: '{min} 至 {max}',
durationAtLeast: '至少 {value}',
durationAtMost: '至多 {value}',
},
},
stopwatch: {
title: '秒表',
Expand Down
Loading