feat(llm-parse): read a photo, as a booking or as a receipt in Costs

Whether the AI Parsing model reads images is an admin setting now, and it
lands with the two features that send a photo, so it has something to
control.

The setting is `vision: 'auto' | 'on' | 'off'` on the addon config. On
Automatic a local Ollama is asked what the model can do (`/api/show`), and a
cloud provider means no; Yes and No are applied as set. The old `multimodal`
flag is not read: the admin screens wrote it false on every save, so a
stored false meant nothing. The per-user toggle keeps its on/off meaning and
is read by the extraction now. The lookup is server-side only: capped read,
validated body, never throws, cached per server and model.
GET /api/llm/capabilities answers it for the signed-in caller, and both
photo pickers below ask it.

The booking import takes JPG, PNG and WEBP when the model reads images.
The photo goes as an image to every provider (image_url, an Anthropic image
block, Ollama's native chat with `images`), capped at 1600px, and skips KDE
Itinerary. A scanned PDF, which used to reach the model as empty text, has
its first two pages drawn by pdf-parse and sent the same way. The rest is
the import as it was: background job, review, the file attached to the
booking, the linked cost. On a real qwen3.5:4b a train ticket came back as
bare clock times until the router gave the model every type's field
meanings, and its price as an object inside a string, which read as 4900;
both are handled.

Costs gets Scan receipt: a dialog laid out like the booking import's takes
one photo, read on the import job queue, then reviewed in the existing
expense editor pre-filled with merchant, total, currency, day and lines,
the photo waiting in Receipts & Invoices to be uploaded on save. No table,
no migration, no category guess, no document-type detection.
This commit is contained in:
RemEx
2026-09-24 17:12:54 +00:00
committed by Maurice
parent 706c6c3959
commit b1c05bca83
183 changed files with 3098 additions and 218 deletions
+9
View File
@@ -1,4 +1,6 @@
import {
asLlmVision,
LLM_VISION_MODES,
adminUserCreateRequestSchema,
adminUserUpdateRequestSchema,
adminPermissionsRequestSchema,
@@ -106,6 +108,13 @@ describe('adminAddonUpdateRequestSchema', () => {
});
});
describe('asLlmVision', () => {
it('keeps the three modes and reads anything else as auto', () => {
for (const mode of LLM_VISION_MODES) expect(asLlmVision(mode)).toBe(mode);
for (const other of [undefined, null, '', 'ON', true, false, 1]) expect(asLlmVision(other)).toBe('auto');
});
});
describe('adminCollabFeaturesRequestSchema', () => {
it('accepts a single computed key', () => {
expect(adminCollabFeaturesRequestSchema.safeParse({ chat: false }).success).toBe(true);
+24
View File
@@ -80,6 +80,30 @@ export const adminAddonUpdateRequestSchema = z.object({
});
export type AdminAddonUpdateRequest = z.infer<typeof adminAddonUpdateRequestSchema>;
/**
* Whether the AI Parsing model is handed a photo, stored as `vision` on that
* addon's config. `auto` asks a local Ollama server what the model can do and
* means no for a cloud provider; `on` and `off` are the admin's word.
*/
export const LLM_VISION_MODES = ['auto', 'on', 'off'] as const;
export type LlmVision = (typeof LLM_VISION_MODES)[number];
/**
* The photos handed to a model that reads images. HEIC is not here: no provider
* TREK talks to reads it, and a browser picking from the camera roll hands over
* a JPEG anyway.
*/
export const LLM_PHOTO_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.webp'] as const;
/** GET /api/llm/capabilities: what the caller's AI model can be handed. */
export const llmCapabilitiesResponseSchema = z.object({ images: z.boolean() });
export type LlmCapabilitiesResponse = z.infer<typeof llmCapabilitiesResponseSchema>;
/** A stored or submitted value as a mode; anything else, a missing value included, is `auto`. */
export function asLlmVision(value: unknown): LlmVision {
return (LLM_VISION_MODES as readonly unknown[]).includes(value) ? (value as LlmVision) : 'auto';
}
// Fully partial — the client PUTs one computed key at a time.
export const adminCollabFeaturesRequestSchema = z.object({
chat: z.boolean().optional(),
+46
View File
@@ -0,0 +1,46 @@
import { z } from 'zod';
/**
* A photographed receipt, as the AI model read it for the Costs tab.
*
* It only pre-fills the expense editor: nothing is saved until the person saves
* the expense there, so every field may be missing and each is checked by eye.
* There is no category: which kind of spending it was is the person's call.
*/
export const receiptLineSchema = z.object({
name: z.string().min(1),
/** What the line cost in total, quantity included, in the receipt's currency. */
price: z.number(),
});
export type ReceiptLine = z.infer<typeof receiptLineSchema>;
export const receiptReadSchema = z.object({
/** The business, which becomes the expense name. */
merchant: z.string().min(1).nullable(),
/** YYYY-MM-DD. */
date: z
.string()
.regex(/^\d{4}-\d{2}-\d{2}$/)
.nullable(),
/** The grand total paid. */
total: z.number().positive().nullable(),
/** ISO 4217. */
currency: z
.string()
.regex(/^[A-Z]{3}$/)
.nullable(),
/** The itemized lines, which seed the Ticket split. */
items: z.array(receiptLineSchema),
});
export type ReceiptRead = z.infer<typeof receiptReadSchema>;
/** What a finished receipt scan job answers: the read, or null with the reason in `warnings`. */
export const receiptScanResultSchema = z.object({
receipt: receiptReadSchema.nullable(),
warnings: z.array(z.string()),
});
export type ReceiptScanResult = z.infer<typeof receiptScanResultSchema>;
/** POST /api/trips/:tripId/budget/receipt-scan: the background job reading the photo. */
export const receiptScanStartResponseSchema = z.object({ jobId: z.string().min(1) });
export type ReceiptScanStartResponse = z.infer<typeof receiptScanStartResponseSchema>;
+5
View File
@@ -626,6 +626,11 @@ const admin: TranslationStrings = {
'قراءة الزيارات والمسارات المسجَّلة من خادم Dawarich يربطه كل قارئ بنفسه',
'admin.addons.catalog.llm_parsing.name': 'التحليل بالذكاء الاصطناعي',
'admin.addons.catalog.llm_parsing.description': 'يقرأ الحجوزات التي يعجز المحلل المدمج عن فهمها، بنموذج ذكاء اصطناعي تختاره',
'admin.addons.llm.vision.auto': 'تلقائي',
'admin.addons.llm.vision.on': 'نعم',
'admin.addons.llm.vision.off': 'لا',
'admin.addons.llm.vision.hintLocal': 'يسأل الخيار «تلقائي» خادم Ollama عمّا إذا كان هذا النموذج يقرأ الصور.',
'admin.addons.llm.vision.hintCloud': 'يعني «تلقائي» «لا» للنموذج السحابي. اختر «نعم» إذا كان هذا النموذج يقرأ الصور.',
'admin.addons.enabled': 'مفعّل',
'admin.addons.disabled': 'معطّل',
'admin.addons.type.trip': 'رحلة',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'الإيصالات',
'costs.receiptsTitle': 'الإيصالات والفواتير',
'costs.attachReceipt': 'إرفاق إيصال / فاتورة',
'costs.scan.button': 'مسح إيصال',
'costs.scan.reading': 'جارٍ قراءة الإيصال…',
'costs.scan.review': 'مراجعة المصروف',
'costs.scan.nothingRead': 'تعذّرت قراءة أي إيصال من هذه الصورة.',
'costs.scan.failed': 'تعذّر بدء قراءة الإيصال.',
'costs.scan.title': 'مسح إيصال',
'costs.scan.accepted': 'صورة لإيصال واحد (JPG أو PNG أو WEBP، حتى 10 ميغابايت). يقرأها نموذج الذكاء الاصطناعي في الخلفية، ثم تراجع المصروف قبل حفظه.',
'costs.scan.dropHere': 'أفلت صورة الإيصال هنا، أو انقر لاختيار صورة أو التقاطها',
'costs.scan.dropActive': 'أفلت الصورة لمسحها',
'costs.scan.start': 'مسح',
'costs.scan.unsupported': 'يمكن مسح الصور فقط: JPG أو PNG أو WEBP.',
'costs.noReceipts': 'لا توجد إيصالات مرفقة',
'costs.deleteReceipt': 'حذف الإيصال',
'costs.viewReceipt': 'عرض الإيصال',
+1
View File
@@ -129,6 +129,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'أسقط الملفات للاستيراد',
'reservations.import.acceptedFormats':
'المقبول: EML، PDF، PKPass، HTML، TXT (بحد أقصى 10 ميغابايت لكل ملف، حتى 5 ملفات)',
'reservations.import.acceptedPhotos': 'يقرأ نموذج الذكاء الاصطناعي الصور (JPG وPNG وWEBP).',
'reservations.import.parsing': 'جارٍ معالجة الملفات…',
'reservations.import.previewHeading': 'تم العثور على {count} حجز/حجوزات',
'reservations.import.previewEmpty': 'تعذّر استخراج أي حجوزات من الملفات المُحمَّلة.',
+2 -2
View File
@@ -383,8 +383,8 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': 'المكان الذي يعمل فيه النموذج — خادم Ollama محلي أو نقطة نهاية متوافقة مع OpenAI.',
'settings.aiParsing.apiKey': 'مفتاح API',
'settings.aiParsing.apiKeyHint': 'يُخزَّن مشفّرًا. اتركه فارغًا للإبقاء على المفتاح الحالي.',
'settings.aiParsing.multimodal': 'إرسال المستندات كصور',
'settings.aiParsing.multimodalHint': 'للنماذج القادرة على الرؤية — يرسل ملف PDF الأصلي بدلًا من النص المستخرج.',
'settings.aiParsing.multimodal': 'النموذج يقرأ الصور',
'settings.aiParsing.multimodalHint': 'فعّله لنموذج يقرأ الصور، ليمكن استيراد صورة أو مسحها.',
'settings.aiParsing.toast.saved': 'تم حفظ إعدادات الذكاء الاصطناعي',
'settings.aiParsing.toast.saveError': 'تعذّر حفظ إعدادات الذكاء الاصطناعي',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -733,6 +733,11 @@ const admin: TranslationStrings = {
'admin.addons.catalog.llm_parsing.name': 'Süni intellektlə təhlil',
'admin.addons.catalog.llm_parsing.description':
'Daxili təhlilçinin oxuya bilmədiyi rezervasiyaları seçdiyiniz süni intellekt modeli ilə oxuyur',
'admin.addons.llm.vision.auto': 'Avtomatik',
'admin.addons.llm.vision.on': 'Bəli',
'admin.addons.llm.vision.off': 'Xeyr',
'admin.addons.llm.vision.hintLocal': 'Avtomatik rejim bu modelin şəkilləri oxuyub-oxumadığını Ollama serverindən soruşur.',
'admin.addons.llm.vision.hintCloud': 'Bulud modeli üçün Avtomatik "xeyr" deməkdir. Bu model şəkilləri oxuyursa, Bəli seç.',
'admin.addons.enabled': 'Aktivdir',
'admin.addons.disabled': 'Deaktivdir',
'admin.addons.type.trip': 'Səyahət',
+11
View File
@@ -186,6 +186,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Qəbzlər',
'costs.receiptsTitle': 'Qəbzlər və fakturalar',
'costs.attachReceipt': 'Qəbz / faktura əlavə et',
'costs.scan.button': 'Qəbzi skan et',
'costs.scan.reading': 'Qəbz oxunur…',
'costs.scan.review': 'Xərci yoxla',
'costs.scan.nothingRead': 'Bu fotodan qəbz oxunmadı.',
'costs.scan.failed': 'Qəbzin oxunmasına başlamaq mümkün olmadı.',
'costs.scan.title': 'Qəbzi skan et',
'costs.scan.accepted': 'Bir qəbzin fotosu (JPG, PNG və ya WEBP, 10 MB-a qədər). Süni intellekt modeli onu arxa planda oxuyur, sonra xərci saxlamazdan əvvəl yoxlayırsan.',
'costs.scan.dropHere': 'Qəbzin fotosunu bura burax və ya seçmək ya çəkmək üçün kliklə',
'costs.scan.dropActive': 'Skan etmək üçün fotonu burax',
'costs.scan.start': 'Skan et',
'costs.scan.unsupported': 'Yalnız foto skan edilə bilər: JPG, PNG və ya WEBP.',
'costs.noReceipts': 'Əlavə edilmiş qəbz yoxdur',
'costs.deleteReceipt': 'Qəbzi sil',
'costs.viewReceipt': 'Qəbzə bax',
+1
View File
@@ -179,6 +179,7 @@ const reservations: TranslationStrings = {
'İdxal etmək üçün faylları buraya buraxın',
'reservations.import.acceptedFormats':
'Qəbul edilən formatlar: EML, PDF, PKPass, HTML, TXT (hər biri maksimum 10 MB, 5 fayladək)',
'reservations.import.acceptedPhotos': 'Fotoları (JPG, PNG, WEBP) süni intellekt modeli oxuyur.',
'reservations.import.parsing': 'Fayllar təhlil edilir…',
'reservations.import.previewHeading':
'{count} rezervasiya tapıldı',
+2 -2
View File
@@ -497,9 +497,9 @@ const settings: TranslationStrings = {
'settings.aiParsing.apiKey': 'API açarı',
'settings.aiParsing.apiKeyHint':
'Şifrələnmiş şəkildə saxlanılır. Cari açarı saxlamaq üçün boş buraxın.',
'settings.aiParsing.multimodal': 'Sənədləri şəkil kimi göndər',
'settings.aiParsing.multimodal': 'Model şəkilləri oxuyur',
'settings.aiParsing.multimodalHint':
'Görmə qabiliyyətli modellər üçün — çıxarılmış mətn əvəzinə orijinal PDF-i göndərir.',
'Şəkilləri oxuyan model üçün aç: onda foto idxal oluna və ya skan edilə bilər.',
'settings.aiParsing.toast.saved': 'AI tənzimləmələri yadda saxlanıldı',
'settings.aiParsing.toast.saveError':
'AI tənzimləmələrini yadda saxlamaq mümkün olmadı',
+5
View File
@@ -618,6 +618,11 @@ const admin: TranslationStrings = {
'Leia visitas e rotas gravadas de uma instância do Dawarich que cada leitor conecta por conta própria',
'admin.addons.catalog.llm_parsing.name': 'Análise por IA',
'admin.addons.catalog.llm_parsing.description': 'Lê reservas que o analisador integrado não entende, usando um modelo de IA à sua escolha',
'admin.addons.llm.vision.auto': 'Automático',
'admin.addons.llm.vision.on': 'Sim',
'admin.addons.llm.vision.off': 'Não',
'admin.addons.llm.vision.hintLocal': 'Automático pergunta ao servidor Ollama se este modelo lê imagens.',
'admin.addons.llm.vision.hintCloud': 'Automático significa não para um modelo na nuvem. Escolha Sim se este modelo lê imagens.',
'admin.addons.enabled': 'Ativado',
'admin.addons.disabled': 'Desativado',
'admin.addons.type.trip': 'Viagem',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Comprovantes',
'costs.receiptsTitle': 'Comprovantes e notas',
'costs.attachReceipt': 'Anexar comprovante / nota',
'costs.scan.button': 'Escanear comprovante',
'costs.scan.reading': 'Lendo o comprovante…',
'costs.scan.review': 'Revisar a despesa',
'costs.scan.nothingRead': 'Não foi possível ler um comprovante nesta foto.',
'costs.scan.failed': 'Não foi possível começar a ler o comprovante.',
'costs.scan.title': 'Escanear comprovante',
'costs.scan.accepted': 'A foto de um único comprovante (JPG, PNG ou WEBP, até 10 MB). O modelo de IA lê em segundo plano e depois você confere a despesa antes de salvar.',
'costs.scan.dropHere': 'Solte aqui a foto do comprovante, ou clique para escolher ou tirar uma',
'costs.scan.dropActive': 'Solte a foto para escaneá-la',
'costs.scan.start': 'Escanear',
'costs.scan.unsupported': 'Só é possível escanear uma foto: JPG, PNG ou WEBP.',
'costs.noReceipts': 'Nenhum comprovante anexado',
'costs.deleteReceipt': 'Remover comprovante',
'costs.viewReceipt': 'Ver comprovante',
+1
View File
@@ -128,6 +128,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Solte os arquivos de confirmação de reserva aqui ou clique para selecionar',
'reservations.import.dropActive': 'Solte os arquivos para importar',
'reservations.import.acceptedFormats': 'Aceitos: EML, PDF, PKPass, HTML, TXT (máx. 10 MB cada, até 5 arquivos)',
'reservations.import.acceptedPhotos': 'As fotos (JPG, PNG, WEBP) são lidas pelo modelo de IA.',
'reservations.import.parsing': 'Analisando arquivos…',
'reservations.import.previewHeading': '{count} reserva(s) encontrada(s)',
'reservations.import.previewEmpty': 'Nenhuma reserva pôde ser extraída dos arquivos enviados.',
+2 -2
View File
@@ -398,9 +398,9 @@ const settings: TranslationStrings = {
'Onde o modelo é executado — um servidor Ollama local ou um endpoint compatível com OpenAI.',
'settings.aiParsing.apiKey': 'Chave de API',
'settings.aiParsing.apiKeyHint': 'Armazenada de forma criptografada. Deixe em branco para manter a chave atual.',
'settings.aiParsing.multimodal': 'Enviar documentos como imagens',
'settings.aiParsing.multimodal': 'O modelo lê imagens',
'settings.aiParsing.multimodalHint':
'Para modelos com capacidade de visão — envia o PDF original em vez do texto extraído.',
'Ative para um modelo que lê imagens, assim uma foto pode ser importada ou escaneada.',
'settings.aiParsing.toast.saved': 'Configurações de IA salvas',
'settings.aiParsing.toast.saveError': 'Não foi possível salvar as configurações de IA',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -233,6 +233,11 @@ const admin: TranslationStrings = {
'Llegeix estades i recorreguts enregistrats d’una instància de Dawarich que cada lector connecta pel seu compte',
'admin.addons.catalog.llm_parsing.name': 'Anàlisi amb IA',
'admin.addons.catalog.llm_parsing.description': 'Llegeix reserves que l’analitzador integrat no entén, amb un model d’IA que triïs',
'admin.addons.llm.vision.auto': 'Automàtic',
'admin.addons.llm.vision.on': 'Sí',
'admin.addons.llm.vision.off': 'No',
'admin.addons.llm.vision.hintLocal': 'Automàtic pregunta al servidor Ollama si aquest model llegeix imatges.',
'admin.addons.llm.vision.hintCloud': 'Automàtic vol dir no per a un model al núvol. Tria Sí si aquest model llegeix imatges.',
'admin.addons.enabled': 'Actiu',
'admin.addons.disabled': 'Desactivat',
'admin.addons.type.trip': 'Viatge',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Rebuts',
'costs.receiptsTitle': 'Rebuts i factures',
'costs.attachReceipt': 'Adjuntar rebut / factura',
'costs.scan.button': 'Escanejar rebut',
'costs.scan.reading': 'Llegint el rebut…',
'costs.scan.review': 'Revisar la despesa',
'costs.scan.nothingRead': "No s'ha pogut llegir cap rebut d'aquesta foto.",
'costs.scan.failed': "No s'ha pogut començar a llegir el rebut.",
'costs.scan.title': 'Escanejar rebut',
'costs.scan.accepted': "Una foto d'un sol rebut (JPG, PNG o WEBP, fins a 10 MB). El model d'IA la llegeix en segon pla i després revises la despesa abans de desar-la.",
'costs.scan.dropHere': 'Deixa aquí la foto del rebut, o fes clic per triar-ne o fer-ne una',
'costs.scan.dropActive': 'Deixa anar la foto per escanejar-la',
'costs.scan.start': 'Escanejar',
'costs.scan.unsupported': 'Només es pot escanejar una foto: JPG, PNG o WEBP.',
'costs.noReceipts': 'Cap rebut adjunt',
'costs.deleteReceipt': 'Eliminar rebut',
'costs.viewReceipt': 'Veure rebut',
+1
View File
@@ -129,6 +129,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Deixa anar els fitxers per importar',
'reservations.import.acceptedFormats':
'Acceptats: EML, PDF, PKPass, HTML, TXT (màx. 10 MB per fitxer, fins a 5 fitxers)',
'reservations.import.acceptedPhotos': "El model d'IA llegeix les fotos (JPG, PNG, WEBP).",
'reservations.import.parsing': 'Analitzant els fitxers…',
'reservations.import.previewHeading': '{count} reserva(es) trobada(es)',
'reservations.import.previewEmpty': "No s'han pogut extreure reserves dels fitxers pujats.",
+2 -2
View File
@@ -379,9 +379,9 @@ const settings: TranslationStrings = {
"On s'executa el model — un servidor local d'Ollama o un punt final compatible amb OpenAI.",
'settings.aiParsing.apiKey': "Clau de l'API",
'settings.aiParsing.apiKeyHint': "S'emmagatzema xifrada. Deixa-ho en blanc per mantenir la clau actual.",
'settings.aiParsing.multimodal': 'Enviar documents com a imatges',
'settings.aiParsing.multimodal': 'El model llegeix imatges',
'settings.aiParsing.multimodalHint':
'Per a models amb capacitats de visió — envia el PDF original en comptes del text extret.',
'Activa-ho per a un model que llegeix imatges, així es pot importar o escanejar una foto.',
'settings.aiParsing.toast.saved': "Ajustos d'IA desats",
'settings.aiParsing.toast.saveError': "No s'han pogut desar els ajustos d'IA",
'settings.tabs.appearance': 'Aparença',
+5
View File
@@ -608,6 +608,11 @@ const admin: TranslationStrings = {
'Načtěte návštěvy a zaznamenané trasy z instance Dawarich, kterou si každý čtenář připojí sám',
'admin.addons.catalog.llm_parsing.name': 'Analýza pomocí AI',
'admin.addons.catalog.llm_parsing.description': 'Přečte rezervace, které vestavěný analyzátor nezvládne, pomocí zvoleného modelu AI',
'admin.addons.llm.vision.auto': 'Automaticky',
'admin.addons.llm.vision.on': 'Ano',
'admin.addons.llm.vision.off': 'Ne',
'admin.addons.llm.vision.hintLocal': 'Automaticky se zeptá serveru Ollama, zda tento model čte obrázky.',
'admin.addons.llm.vision.hintCloud': 'Automaticky znamená u cloudového modelu ne. Zvolte Ano, pokud tento model čte obrázky.',
'admin.addons.catalog.roadtrip.name': 'Cesta autem',
'admin.addons.catalog.roadtrip.description': 'Plánujte jízdy se zastávkami – doby jízdy a časy příjezdu se přepočítají samy',
'admin.addons.enabled': 'Povoleno',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Účtenky',
'costs.receiptsTitle': 'Účtenky a faktury',
'costs.attachReceipt': 'Připojit účtenku / fakturu',
'costs.scan.button': 'Naskenovat účtenku',
'costs.scan.reading': 'Čtení účtenky…',
'costs.scan.review': 'Zkontrolovat výdaj',
'costs.scan.nothingRead': 'Z této fotografie se nepodařilo přečíst žádnou účtenku.',
'costs.scan.failed': 'Čtení účtenky se nepodařilo spustit.',
'costs.scan.title': 'Naskenovat účtenku',
'costs.scan.accepted': 'Fotografie jedné účtenky (JPG, PNG nebo WEBP, do 10 MB). Model AI ji přečte na pozadí a vy pak výdaj před uložením zkontrolujete.',
'costs.scan.dropHere': 'Přetáhněte sem fotografii účtenky, nebo klikněte a vyberte či pořiďte novou',
'costs.scan.dropActive': 'Pusťte fotografii pro naskenování',
'costs.scan.start': 'Skenovat',
'costs.scan.unsupported': 'Skenovat lze jen fotografii: JPG, PNG nebo WEBP.',
'costs.noReceipts': 'Žádné připojené účtenky',
'costs.deleteReceipt': 'Odebrat účtenku',
'costs.viewReceipt': 'Zobrazit účtenku',
+1
View File
@@ -129,6 +129,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Pusťte soubory pro import',
'reservations.import.acceptedFormats':
'Přijímané formáty: EML, PDF, PKPass, HTML, TXT (max. 10 MB každý, až 5 souborů)',
'reservations.import.acceptedPhotos': 'Fotografie (JPG, PNG, WEBP) čte model AI.',
'reservations.import.parsing': 'Zpracování souborů…',
'reservations.import.previewHeading': 'Nalezeno {count} rezervace/í',
'reservations.import.previewEmpty': 'Z nahraných souborů se nepodařilo extrahovat žádné rezervace.',
+2 -2
View File
@@ -390,9 +390,9 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': 'Kde model běží — místní server Ollama nebo koncový bod kompatibilní s OpenAI.',
'settings.aiParsing.apiKey': 'Klíč API',
'settings.aiParsing.apiKeyHint': 'Ukládá se šifrovaně. Ponechte prázdné pro zachování aktuálního klíče.',
'settings.aiParsing.multimodal': 'Odesílat dokumenty jako obrázky',
'settings.aiParsing.multimodal': 'Model čte obrázky',
'settings.aiParsing.multimodalHint':
'Pro modely se schopností zpracovat obraz — odešle původní PDF místo extrahovaného textu.',
'Zapněte pro model, který čte obrázky, aby šlo fotografii importovat nebo naskenovat.',
'settings.aiParsing.toast.saved': 'Nastavení AI uloženo',
'settings.aiParsing.toast.saveError': 'Nastavení AI se nepodařilo uložit',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -624,6 +624,11 @@ const admin: TranslationStrings = {
'Aufenthalte und aufgezeichnete Routen aus einer Dawarich-Instanz lesen, die jeder selbst verbindet',
'admin.addons.catalog.llm_parsing.name': 'KI-Auswertung',
'admin.addons.catalog.llm_parsing.description': 'Liest Buchungen, an denen der eingebaute Parser scheitert, mit einem KI-Modell deiner Wahl',
'admin.addons.llm.vision.auto': 'Automatisch',
'admin.addons.llm.vision.on': 'Ja',
'admin.addons.llm.vision.off': 'Nein',
'admin.addons.llm.vision.hintLocal': 'Automatisch fragt den Ollama-Server, ob dieses Modell Bilder liest.',
'admin.addons.llm.vision.hintCloud': 'Automatisch bedeutet bei einem Cloud-Modell Nein. Wähle Ja, wenn dieses Modell Bilder liest.',
'admin.addons.enabled': 'Aktiviert',
'admin.addons.disabled': 'Deaktiviert',
'admin.addons.type.trip': 'Reise',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Belege',
'costs.receiptsTitle': 'Belege & Rechnungen',
'costs.attachReceipt': 'Beleg / Rechnung anhängen',
'costs.scan.button': 'Beleg scannen',
'costs.scan.reading': 'Beleg wird gelesen…',
'costs.scan.review': 'Ausgabe prüfen',
'costs.scan.nothingRead': 'Aus diesem Foto ließ sich kein Beleg lesen.',
'costs.scan.failed': 'Der Beleg konnte nicht eingelesen werden.',
'costs.scan.title': 'Beleg scannen',
'costs.scan.accepted': 'Ein Foto eines Belegs (JPG, PNG oder WEBP, bis 10 MB). Das KI-Modell liest es im Hintergrund, danach prüfst du die Ausgabe, bevor sie gespeichert wird.',
'costs.scan.dropHere': 'Belegfoto hier ablegen oder klicken, um eins auszuwählen oder aufzunehmen',
'costs.scan.dropActive': 'Foto ablegen, um es zu scannen',
'costs.scan.start': 'Scannen',
'costs.scan.unsupported': 'Nur Fotos lassen sich scannen: JPG, PNG oder WEBP.',
'costs.noReceipts': 'Keine Belege angehängt',
'costs.deleteReceipt': 'Beleg entfernen',
'costs.viewReceipt': 'Beleg ansehen',
+1
View File
@@ -132,6 +132,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Dateien zum Importieren ablegen',
'reservations.import.acceptedFormats':
'Akzeptiert: EML, PDF, PKPass, HTML, TXT (max. 10 MB pro Datei, bis zu 5 Dateien)',
'reservations.import.acceptedPhotos': 'Fotos (JPG, PNG, WEBP) liest das KI-Modell.',
'reservations.import.parsing': 'Dateien werden verarbeitet…',
'reservations.import.previewHeading': '{count} Reservierung(en) gefunden',
'reservations.import.previewEmpty': 'Aus den hochgeladenen Dateien konnten keine Reservierungen extrahiert werden.',
+2 -2
View File
@@ -401,9 +401,9 @@ const settings: TranslationStrings = {
'Wo das Modell läuft — ein lokaler Ollama-Server oder ein OpenAI-kompatibler Endpunkt.',
'settings.aiParsing.apiKey': 'API-Schlüssel',
'settings.aiParsing.apiKeyHint': 'Verschlüsselt gespeichert. Leer lassen, um den aktuellen Schlüssel zu behalten.',
'settings.aiParsing.multimodal': 'Dokumente als Bilder senden',
'settings.aiParsing.multimodal': 'Modell liest Bilder',
'settings.aiParsing.multimodalHint':
'Für Modelle mit Bildverständnis — sendet das Original-PDF statt extrahiertem Text.',
'Für ein Modell, das Bilder liest: Dann lässt sich ein Foto importieren oder scannen.',
'settings.aiParsing.toast.saved': 'KI-Einstellungen gespeichert',
'settings.aiParsing.toast.saveError': 'KI-Einstellungen konnten nicht gespeichert werden',
'settings.tabs.appearance': 'Erscheinungsbild',
+5
View File
@@ -663,6 +663,11 @@ const admin: TranslationStrings = {
'Read visits and recorded routes from a Dawarich instance each reader connects themselves',
'admin.addons.catalog.llm_parsing.name': 'AI Parsing',
'admin.addons.catalog.llm_parsing.description': 'Reads bookings the built-in parser cannot, using an AI model you choose',
'admin.addons.llm.vision.auto': 'Automatic',
'admin.addons.llm.vision.on': 'Yes',
'admin.addons.llm.vision.off': 'No',
'admin.addons.llm.vision.hintLocal': 'Automatic asks the Ollama server whether this model reads images.',
'admin.addons.llm.vision.hintCloud': 'Automatic means no for a cloud model. Choose Yes if this model reads images.',
'admin.addons.enabled': 'Enabled',
'admin.addons.disabled': 'Disabled',
'admin.addons.type.trip': 'Trip',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Receipts',
'costs.receiptsTitle': 'Receipts & Invoices',
'costs.attachReceipt': 'Attach receipt / invoice',
'costs.scan.button': 'Scan receipt',
'costs.scan.reading': 'Reading the receipt…',
'costs.scan.review': 'Review expense',
'costs.scan.nothingRead': 'No receipt could be read from this photo.',
'costs.scan.failed': 'Could not start reading the receipt.',
'costs.scan.title': 'Scan a receipt',
'costs.scan.accepted': 'A photo of one receipt (JPG, PNG or WEBP, up to 10 MB). The AI model reads it in the background, then you check the expense before it is saved.',
'costs.scan.dropHere': 'Drop the receipt photo here, or click to pick or take one',
'costs.scan.dropActive': 'Drop the photo to scan it',
'costs.scan.start': 'Scan',
'costs.scan.unsupported': 'Only a photo can be scanned: JPG, PNG or WEBP.',
'costs.noReceipts': 'No receipts attached',
'costs.deleteReceipt': 'Remove receipt',
'costs.viewReceipt': 'View receipt',
+1
View File
@@ -133,6 +133,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Drop booking confirmation files here, or click to select',
'reservations.import.dropActive': 'Drop files to import',
'reservations.import.acceptedFormats': 'Accepted: EML, PDF, PKPass, HTML, TXT (max 10 MB each, up to 5 files)',
'reservations.import.acceptedPhotos': 'Photos (JPG, PNG, WEBP) are read by the AI model.',
'reservations.import.parsing': 'Parsing files…',
'reservations.import.previewHeading': '{count} reservation(s) found',
'reservations.import.previewEmpty': 'No reservations could be extracted from the uploaded files.',
+2 -2
View File
@@ -400,8 +400,8 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': 'Where the model runs — a local Ollama server or an OpenAI-compatible endpoint.',
'settings.aiParsing.apiKey': 'API key',
'settings.aiParsing.apiKeyHint': 'Stored encrypted. Leave blank to keep the current key.',
'settings.aiParsing.multimodal': 'Send documents as images',
'settings.aiParsing.multimodalHint': 'For vision-capable models — sends the original PDF instead of extracted text.',
'settings.aiParsing.multimodal': 'Model reads images',
'settings.aiParsing.multimodalHint': 'Turn on for a model that reads images, so a photo can be imported or scanned.',
'settings.aiParsing.toast.saved': 'AI settings saved',
'settings.aiParsing.toast.saveError': 'Could not save AI settings',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -609,6 +609,11 @@ const admin: TranslationStrings = {
'Lee estancias y rutas grabadas de una instancia de Dawarich que cada usuario conecta por su cuenta',
'admin.addons.catalog.llm_parsing.name': 'Análisis con IA',
'admin.addons.catalog.llm_parsing.description': 'Lee reservas que el analizador integrado no entiende, con un modelo de IA que tú elijas',
'admin.addons.llm.vision.auto': 'Automático',
'admin.addons.llm.vision.on': 'Sí',
'admin.addons.llm.vision.off': 'No',
'admin.addons.llm.vision.hintLocal': 'Automático pregunta al servidor Ollama si este modelo lee imágenes.',
'admin.addons.llm.vision.hintCloud': 'Automático significa no para un modelo en la nube. Elige Sí si este modelo lee imágenes.',
'admin.addons.enabled': 'Activo',
'admin.addons.disabled': 'Desactivado',
'admin.addons.type.trip': 'Viaje',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Recibos',
'costs.receiptsTitle': 'Recibos y facturas',
'costs.attachReceipt': 'Adjuntar recibo / factura',
'costs.scan.button': 'Escanear recibo',
'costs.scan.reading': 'Leyendo el recibo…',
'costs.scan.review': 'Revisar el gasto',
'costs.scan.nothingRead': 'No se pudo leer ningún recibo en esta foto.',
'costs.scan.failed': 'No se pudo iniciar la lectura del recibo.',
'costs.scan.title': 'Escanear recibo',
'costs.scan.accepted': 'Una foto de un solo recibo (JPG, PNG o WEBP, hasta 10 MB). El modelo de IA la lee en segundo plano y luego revisas el gasto antes de guardarlo.',
'costs.scan.dropHere': 'Suelta aquí la foto del recibo, o haz clic para elegir o hacer una',
'costs.scan.dropActive': 'Suelta la foto para escanearla',
'costs.scan.start': 'Escanear',
'costs.scan.unsupported': 'Solo se puede escanear una foto: JPG, PNG o WEBP.',
'costs.noReceipts': 'No hay recibos adjuntos',
'costs.deleteReceipt': 'Eliminar recibo',
'costs.viewReceipt': 'Ver recibo',
+1
View File
@@ -131,6 +131,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Suelta los archivos para importar',
'reservations.import.acceptedFormats':
'Aceptados: EML, PDF, PKPass, HTML, TXT (máx. 10 MB por archivo, hasta 5 archivos)',
'reservations.import.acceptedPhotos': 'El modelo de IA lee las fotos (JPG, PNG, WEBP).',
'reservations.import.parsing': 'Analizando archivos…',
'reservations.import.previewHeading': '{count} reserva(s) encontrada(s)',
'reservations.import.previewEmpty': 'No se pudieron extraer reservas de los archivos subidos.',
+2 -2
View File
@@ -399,8 +399,8 @@ const settings: TranslationStrings = {
'Donde se ejecuta el modelo: un servidor Ollama local o un endpoint compatible con OpenAI.',
'settings.aiParsing.apiKey': 'Clave de API',
'settings.aiParsing.apiKeyHint': 'Se almacena cifrada. Déjalo en blanco para mantener la clave actual.',
'settings.aiParsing.multimodal': 'Enviar documentos como imágenes',
'settings.aiParsing.multimodalHint': 'Para modelos con visión: envía el PDF original en lugar del texto extraído.',
'settings.aiParsing.multimodal': 'El modelo lee imágenes',
'settings.aiParsing.multimodalHint': 'Actívalo para un modelo que lee imágenes, así se puede importar o escanear una foto.',
'settings.aiParsing.toast.saved': 'Ajustes de IA guardados',
'settings.aiParsing.toast.saveError': 'No se han podido guardar los ajustes de IA',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -681,6 +681,11 @@ const admin: TranslationStrings = {
'admin.addons.catalog.llm_parsing.name': 'Tehisintellektiga parsimine',
'admin.addons.catalog.llm_parsing.description':
'Loeb sinu valitud tehisintellektimudeli abil broneeringuid, mida sisseehitatud parser lugeda ei suuda',
'admin.addons.llm.vision.auto': 'Automaatne',
'admin.addons.llm.vision.on': 'Jah',
'admin.addons.llm.vision.off': 'Ei',
'admin.addons.llm.vision.hintLocal': 'Automaatne küsib Ollama serverilt, kas see mudel loeb pilte.',
'admin.addons.llm.vision.hintCloud': 'Pilvemudeli puhul tähendab Automaatne „ei”. Vali Jah, kui see mudel loeb pilte.',
'admin.addons.enabled': 'Lubatud',
'admin.addons.disabled': 'Keelatud',
'admin.addons.type.trip': 'Reis',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Kviitungid',
'costs.receiptsTitle': 'Kviitungid ja arved',
'costs.attachReceipt': 'Lisa kviitung või arve',
'costs.scan.button': 'Skanni kviitung',
'costs.scan.reading': 'Kviitungit loetakse…',
'costs.scan.review': 'Vaata kulu üle',
'costs.scan.nothingRead': 'Sellelt fotolt ei õnnestunud kviitungit lugeda.',
'costs.scan.failed': 'Kviitungi lugemist ei õnnestunud alustada.',
'costs.scan.title': 'Skanni kviitung',
'costs.scan.accepted': 'Ühe kviitungi foto (JPG, PNG või WEBP, kuni 10 MB). Tehisintellekti mudel loeb selle taustal, seejärel kontrollid kulu enne salvestamist.',
'costs.scan.dropHere': 'Lohista kviitungi foto siia või klõpsa, et valida või pildistada',
'costs.scan.dropActive': 'Lase foto lahti, et see skannida',
'costs.scan.start': 'Skanni',
'costs.scan.unsupported': 'Skannida saab ainult fotot: JPG, PNG või WEBP.',
'costs.noReceipts': 'Kviitungeid pole lisatud',
'costs.deleteReceipt': 'Eemalda kviitung',
'costs.viewReceipt': 'Vaata kviitungit',
+1
View File
@@ -133,6 +133,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Lohista broneeringukinnituse failid siia või klõpsa valimiseks',
'reservations.import.dropActive': 'Impordiks lohista failid siia',
'reservations.import.acceptedFormats': 'Lubatud: EML, PDF, PKPass, HTML, TXT (kuni 10 MB faili kohta, kuni 5 faili)',
'reservations.import.acceptedPhotos': 'Fotosid (JPG, PNG, WEBP) loeb tehisintellekti mudel.',
'reservations.import.parsing': 'Failide töötlemine…',
'reservations.import.previewHeading': 'Leiti {count} broneeringut',
'reservations.import.previewEmpty': 'Üleslaaditud failidest ei õnnestunud broneeringuid eraldada.',
+2 -2
View File
@@ -405,8 +405,8 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': 'Mudeli asukoht — kohalik Ollama server või OpenAI-ühilduv otspunkt.',
'settings.aiParsing.apiKey': 'API-võti',
'settings.aiParsing.apiKeyHint': 'Salvestatakse krüptitult. Praeguse võtme säilitamiseks jäta tühjaks.',
'settings.aiParsing.multimodal': 'Saada dokumendid piltidena',
'settings.aiParsing.multimodalHint': 'Pildituvastusega mudelitele — saadab eraldatud teksti asemel algse PDF-i.',
'settings.aiParsing.multimodal': 'Mudel loeb pilte',
'settings.aiParsing.multimodalHint': 'Lülita sisse pilte lugeva mudeli jaoks, siis saab foto importida või skannida.',
'settings.aiParsing.toast.saved': 'Tehisintellekti seaded salvestatud',
'settings.aiParsing.toast.saveError': 'Tehisintellekti seadete salvestamine ebaõnnestus',
'settings.tabs.appearance': 'Välimus',
+5
View File
@@ -630,6 +630,11 @@ const admin: TranslationStrings = {
'Lisez les séjours et les trajets enregistrés depuis une instance Dawarich que chaque utilisateur connecte lui-même',
'admin.addons.catalog.llm_parsing.name': 'Analyse par IA',
'admin.addons.catalog.llm_parsing.description': 'Lit les réservations que l’analyseur intégré ne comprend pas, via un modèle d’IA de votre choix',
'admin.addons.llm.vision.auto': 'Automatique',
'admin.addons.llm.vision.on': 'Oui',
'admin.addons.llm.vision.off': 'Non',
'admin.addons.llm.vision.hintLocal': 'En automatique, TREK demande au serveur Ollama si ce modèle lit les images.',
'admin.addons.llm.vision.hintCloud': 'En automatique, un modèle cloud est considéré comme ne lisant pas les images. Choisissez Oui si ce modèle les lit.',
'admin.addons.enabled': 'Activé',
'admin.addons.disabled': 'Désactivé',
'admin.addons.type.trip': 'Voyage',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Reçus',
'costs.receiptsTitle': 'Reçus et factures',
'costs.attachReceipt': 'Joindre un reçu / une facture',
'costs.scan.button': 'Scanner un reçu',
'costs.scan.reading': 'Lecture du reçu…',
'costs.scan.review': 'Vérifier la dépense',
'costs.scan.nothingRead': "Aucun reçu n'a pu être lu sur cette photo.",
'costs.scan.failed': 'Impossible de lancer la lecture du reçu.',
'costs.scan.title': 'Scanner un reçu',
'costs.scan.accepted': "Une photo d'un seul reçu (JPG, PNG ou WEBP, 10 Mo max). Le modèle d'IA la lit en arrière-plan, puis vous vérifiez la dépense avant de l'enregistrer.",
'costs.scan.dropHere': 'Déposez la photo du reçu ici, ou cliquez pour en choisir ou en prendre une',
'costs.scan.dropActive': 'Déposez la photo pour la scanner',
'costs.scan.start': 'Scanner',
'costs.scan.unsupported': 'Seule une photo peut être scannée : JPG, PNG ou WEBP.',
'costs.noReceipts': 'Aucun reçu joint',
'costs.deleteReceipt': 'Supprimer le reçu',
'costs.viewReceipt': 'Voir le reçu',
+1
View File
@@ -132,6 +132,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Déposez les fichiers pour importer',
'reservations.import.acceptedFormats':
"Acceptés : EML, PDF, PKPass, HTML, TXT (max. 10 Mo chacun, jusqu'à 5 fichiers)",
'reservations.import.acceptedPhotos': "Les photos (JPG, PNG, WEBP) sont lues par le modèle d'IA.",
'reservations.import.parsing': 'Analyse des fichiers…',
'reservations.import.previewHeading': '{count} réservation(s) trouvée(s)',
'reservations.import.previewEmpty': "Aucune réservation n'a pu être extraite des fichiers envoyés.",
+2 -2
View File
@@ -406,9 +406,9 @@ const settings: TranslationStrings = {
"Emplacement d'exécution du modèle — un serveur Ollama local ou un point de terminaison compatible OpenAI.",
'settings.aiParsing.apiKey': 'Clé API',
'settings.aiParsing.apiKeyHint': 'Stockée de façon chiffrée. Laissez vide pour conserver la clé actuelle.',
'settings.aiParsing.multimodal': "Envoyer les documents sous forme d'images",
'settings.aiParsing.multimodal': 'Le modèle lit les images',
'settings.aiParsing.multimodalHint':
"Pour les modèles capables d'analyser des images — envoie le PDF d'origine au lieu du texte extrait.",
'À activer pour un modèle qui lit les images : une photo peut alors être importée ou scannée.',
'settings.aiParsing.toast.saved': "Paramètres d'IA enregistrés",
'settings.aiParsing.toast.saveError': "Impossible d'enregistrer les paramètres d'IA",
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -685,6 +685,11 @@ const admin: TranslationStrings = {
'Ανάγνωση επισκέψεων και καταγεγραμμένων διαδρομών από μια εγκατάσταση Dawarich που συνδέει ο κάθε χρήστης μόνος του',
'admin.addons.catalog.llm_parsing.name': 'Ανάλυση με τεχνητή νοημοσύνη',
'admin.addons.catalog.llm_parsing.description': 'Διαβάζει κρατήσεις που δεν καταλαβαίνει ο ενσωματωμένος αναλυτής, με μοντέλο ΤΝ της επιλογής σας',
'admin.addons.llm.vision.auto': 'Αυτόματα',
'admin.addons.llm.vision.on': 'Ναι',
'admin.addons.llm.vision.off': 'Όχι',
'admin.addons.llm.vision.hintLocal': 'Η επιλογή Αυτόματα ρωτά τον διακομιστή Ollama αν αυτό το μοντέλο διαβάζει εικόνες.',
'admin.addons.llm.vision.hintCloud': 'Για μοντέλο στο cloud, η επιλογή Αυτόματα σημαίνει όχι. Επιλέξτε Ναι αν αυτό το μοντέλο διαβάζει εικόνες.',
'admin.addons.enabled': 'Ενεργοποιημένο',
'admin.addons.disabled': 'Απενεργοποιημένο',
'admin.addons.type.trip': 'Ταξίδι',
+11
View File
@@ -155,6 +155,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Αποδείξεις',
'costs.receiptsTitle': 'Αποδείξεις & Τιμολόγια',
'costs.attachReceipt': 'Επισύναψη απόδειξης / τιμολογίου',
'costs.scan.button': 'Σάρωση απόδειξης',
'costs.scan.reading': 'Ανάγνωση της απόδειξης…',
'costs.scan.review': 'Έλεγχος εξόδου',
'costs.scan.nothingRead': 'Δεν ήταν δυνατή η ανάγνωση απόδειξης από αυτή τη φωτογραφία.',
'costs.scan.failed': 'Δεν ήταν δυνατή η έναρξη ανάγνωσης της απόδειξης.',
'costs.scan.title': 'Σάρωση απόδειξης',
'costs.scan.accepted': 'Φωτογραφία μίας απόδειξης (JPG, PNG ή WEBP, έως 10 MB). Το μοντέλο ΤΝ τη διαβάζει στο παρασκήνιο και μετά ελέγχετε το έξοδο πριν αποθηκευτεί.',
'costs.scan.dropHere': 'Αφήστε εδώ τη φωτογραφία της απόδειξης ή κάντε κλικ για να επιλέξετε ή να τραβήξετε μία',
'costs.scan.dropActive': 'Αφήστε τη φωτογραφία για σάρωση',
'costs.scan.start': 'Σάρωση',
'costs.scan.unsupported': 'Μόνο φωτογραφία μπορεί να σαρωθεί: JPG, PNG ή WEBP.',
'costs.noReceipts': 'Δεν υπάρχουν συνημμένες αποδείξεις',
'costs.deleteReceipt': 'Αφαίρεση απόδειξης',
'costs.viewReceipt': 'Προβολή απόδειξης',
+1
View File
@@ -131,6 +131,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Αποθέστε αρχεία για εισαγωγή',
'reservations.import.acceptedFormats':
'Αποδεκτά: EML, PDF, PKPass, HTML, TXT (μέγιστο 10 MB το καθένα, έως 5 αρχεία)',
'reservations.import.acceptedPhotos': 'Τις φωτογραφίες (JPG, PNG, WEBP) τις διαβάζει το μοντέλο ΤΝ.',
'reservations.import.parsing': 'Επεξεργασία αρχείων…',
'reservations.import.previewHeading': 'Βρέθηκαν {count} κράτηση/κρατήσεις',
'reservations.import.previewEmpty': 'Δεν ήταν δυνατή η εξαγωγή κρατήσεων από τα μεταφορτωμένα αρχεία.',
+2 -2
View File
@@ -409,9 +409,9 @@ const settings: TranslationStrings = {
'Πού εκτελείται το μοντέλο — ένας τοπικός διακομιστής Ollama ή ένα τελικό σημείο συμβατό με OpenAI.',
'settings.aiParsing.apiKey': 'Κλειδί API',
'settings.aiParsing.apiKeyHint': 'Αποθηκεύεται κρυπτογραφημένο. Αφήστε το κενό για να διατηρήσετε το τρέχον κλειδί.',
'settings.aiParsing.multimodal': 'Αποστολή εγγράφων ως εικόνες',
'settings.aiParsing.multimodal': 'Το μοντέλο διαβάζει εικόνες',
'settings.aiParsing.multimodalHint':
'Για μοντέλα με δυνατότητα όρασης — στέλνει το αρχικό PDF αντί για το εξαγόμενο κείμενο.',
'Ενεργοποιήστε το για μοντέλο που διαβάζει εικόνες, ώστε μια φωτογραφία να μπορεί να εισαχθεί ή να σαρωθεί.',
'settings.aiParsing.toast.saved': 'Οι ρυθμίσεις AI αποθηκεύτηκαν',
'settings.aiParsing.toast.saveError': 'Δεν ήταν δυνατή η αποθήκευση των ρυθμίσεων AI',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -630,6 +630,11 @@ const admin: TranslationStrings = {
'Tartózkodások és rögzített útvonalak olvasása egy Dawarich-példányból, amelyet minden olvasó maga köt be',
'admin.addons.catalog.llm_parsing.name': 'MI-elemzés',
'admin.addons.catalog.llm_parsing.description': 'Beolvassa azokat a foglalásokat, amelyeket a beépített értelmező nem tud, az általad választott MI-modellel',
'admin.addons.llm.vision.auto': 'Automatikus',
'admin.addons.llm.vision.on': 'Igen',
'admin.addons.llm.vision.off': 'Nem',
'admin.addons.llm.vision.hintLocal': 'Az Automatikus megkérdezi az Ollama-szervert, hogy ez a modell olvas-e képeket.',
'admin.addons.llm.vision.hintCloud': 'Felhőalapú modellnél az Automatikus nemet jelent. Válaszd az Igent, ha ez a modell olvas képeket.',
'admin.addons.enabled': 'Engedélyezve',
'admin.addons.disabled': 'Letiltva',
'admin.addons.type.trip': 'Utazás',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Nyugták',
'costs.receiptsTitle': 'Nyugták és számlák',
'costs.attachReceipt': 'Nyugta / számla csatolása',
'costs.scan.button': 'Nyugta beolvasása',
'costs.scan.reading': 'Nyugta olvasása…',
'costs.scan.review': 'Kiadás ellenőrzése',
'costs.scan.nothingRead': 'Erről a fotóról nem sikerült nyugtát olvasni.',
'costs.scan.failed': 'Nem sikerült elindítani a nyugta olvasását.',
'costs.scan.title': 'Nyugta beolvasása',
'costs.scan.accepted': 'Egyetlen nyugta fotója (JPG, PNG vagy WEBP, legfeljebb 10 MB). Az MI-modell a háttérben olvassa be, majd mentés előtt ellenőrzöd a kiadást.',
'costs.scan.dropHere': 'Húzd ide a nyugta fotóját, vagy kattints egy kiválasztásához vagy elkészítéséhez',
'costs.scan.dropActive': 'Engedd el a fotót a beolvasáshoz',
'costs.scan.start': 'Beolvasás',
'costs.scan.unsupported': 'Csak fotó olvasható be: JPG, PNG vagy WEBP.',
'costs.noReceipts': 'Nincsenek csatolt nyugták',
'costs.deleteReceipt': 'Nyugta eltávolítása',
'costs.viewReceipt': 'Nyugta megtekintése',
+1
View File
@@ -130,6 +130,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Dobja ide a fájlokat az importáláshoz',
'reservations.import.acceptedFormats':
'Elfogadott: EML, PDF, PKPass, HTML, TXT (max. 10 MB darabonként, legfeljebb 5 fájl)',
'reservations.import.acceptedPhotos': 'A fotókat (JPG, PNG, WEBP) az MI-modell olvassa be.',
'reservations.import.parsing': 'Fájlok feldolgozása…',
'reservations.import.previewHeading': '{count} foglalás találva',
'reservations.import.previewEmpty': 'A feltöltött fájlokból nem sikerült foglalásokat kinyerni.',
+2 -2
View File
@@ -398,9 +398,9 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': 'Ahol a modell fut — helyi Ollama-kiszolgáló vagy OpenAI-kompatibilis végpont.',
'settings.aiParsing.apiKey': 'API-kulcs',
'settings.aiParsing.apiKeyHint': 'Titkosítva tárolva. Hagyd üresen a jelenlegi kulcs megtartásához.',
'settings.aiParsing.multimodal': 'Dokumentumok küldése képként',
'settings.aiParsing.multimodal': 'A modell olvas képeket',
'settings.aiParsing.multimodalHint':
'Képfelismerésre képes modellekhez — az eredeti PDF-et küldi a kinyert szöveg helyett.',
'Kapcsold be képeket olvasó modellhez, így egy fotó importálható vagy beolvasható.',
'settings.aiParsing.toast.saved': 'AI-beállítások elmentve',
'settings.aiParsing.toast.saveError': 'Az AI-beállítások mentése nem sikerült',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -674,6 +674,11 @@ const admin: TranslationStrings = {
'Baca kunjungan dan rute terekam dari instans Dawarich yang dihubungkan sendiri oleh tiap pembaca',
'admin.addons.catalog.llm_parsing.name': 'Analisis AI',
'admin.addons.catalog.llm_parsing.description': 'Membaca pemesanan yang tidak dipahami pengurai bawaan, dengan model AI pilihanmu',
'admin.addons.llm.vision.auto': 'Otomatis',
'admin.addons.llm.vision.on': 'Ya',
'admin.addons.llm.vision.off': 'Tidak',
'admin.addons.llm.vision.hintLocal': 'Otomatis menanyakan ke server Ollama apakah model ini membaca gambar.',
'admin.addons.llm.vision.hintCloud': 'Otomatis berarti tidak untuk model cloud. Pilih Ya jika model ini membaca gambar.',
'admin.addons.enabled': 'Aktif',
'admin.addons.disabled': 'Nonaktif',
'admin.addons.type.trip': 'Perjalanan',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Kuitansi',
'costs.receiptsTitle': 'Kuitansi & Faktur',
'costs.attachReceipt': 'Lampirkan kuitansi / faktur',
'costs.scan.button': 'Pindai kuitansi',
'costs.scan.reading': 'Membaca kuitansi…',
'costs.scan.review': 'Tinjau pengeluaran',
'costs.scan.nothingRead': 'Tidak ada kuitansi yang dapat dibaca dari foto ini.',
'costs.scan.failed': 'Tidak dapat mulai membaca kuitansi.',
'costs.scan.title': 'Pindai kuitansi',
'costs.scan.accepted': 'Foto satu kuitansi (JPG, PNG, atau WEBP, maks. 10 MB). Model AI membacanya di latar belakang, lalu kamu memeriksa pengeluaran sebelum disimpan.',
'costs.scan.dropHere': 'Letakkan foto kuitansi di sini, atau klik untuk memilih atau mengambil foto',
'costs.scan.dropActive': 'Lepaskan foto untuk memindainya',
'costs.scan.start': 'Pindai',
'costs.scan.unsupported': 'Hanya foto yang dapat dipindai: JPG, PNG, atau WEBP.',
'costs.noReceipts': 'Tidak ada kuitansi terlampir',
'costs.deleteReceipt': 'Hapus kuitansi',
'costs.viewReceipt': 'Lihat kuitansi',
+1
View File
@@ -129,6 +129,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Seret file konfirmasi pemesanan ke sini atau klik untuk memilih',
'reservations.import.dropActive': 'Lepaskan file untuk mengimpor',
'reservations.import.acceptedFormats': 'Diterima: EML, PDF, PKPass, HTML, TXT (maks. 10 MB per file, hingga 5 file)',
'reservations.import.acceptedPhotos': 'Foto (JPG, PNG, WEBP) dibaca oleh model AI.',
'reservations.import.parsing': 'Memproses file…',
'reservations.import.previewHeading': '{count} pemesanan ditemukan',
'reservations.import.previewEmpty': 'Tidak ada pemesanan yang dapat diekstrak dari file yang diunggah.',
+2 -2
View File
@@ -396,9 +396,9 @@ const settings: TranslationStrings = {
'Tempat model berjalan — server Ollama lokal atau endpoint yang kompatibel dengan OpenAI.',
'settings.aiParsing.apiKey': 'Kunci API',
'settings.aiParsing.apiKeyHint': 'Disimpan secara terenkripsi. Biarkan kosong untuk mempertahankan kunci saat ini.',
'settings.aiParsing.multimodal': 'Kirim dokumen sebagai gambar',
'settings.aiParsing.multimodal': 'Model membaca gambar',
'settings.aiParsing.multimodalHint':
'Untuk model yang mendukung visi — mengirim PDF asli alih-alih teks yang diekstrak.',
'Aktifkan untuk model yang membaca gambar, agar foto dapat diimpor atau dipindai.',
'settings.aiParsing.toast.saved': 'Pengaturan AI disimpan',
'settings.aiParsing.toast.saveError': 'Tidak dapat menyimpan pengaturan AI',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -625,6 +625,11 @@ const admin: TranslationStrings = {
'Legge le soste e i percorsi registrati da un’istanza Dawarich che ogni utente collega da sé',
'admin.addons.catalog.llm_parsing.name': 'Analisi con IA',
'admin.addons.catalog.llm_parsing.description': 'Legge le prenotazioni che l’analizzatore integrato non riesce a interpretare, con un modello di IA a tua scelta',
'admin.addons.llm.vision.auto': 'Automatico',
'admin.addons.llm.vision.on': 'Sì',
'admin.addons.llm.vision.off': 'No',
'admin.addons.llm.vision.hintLocal': 'Automatico chiede al server Ollama se questo modello legge le immagini.',
'admin.addons.llm.vision.hintCloud': 'Automatico significa no per un modello cloud. Scegli Sì se questo modello legge le immagini.',
'admin.addons.enabled': 'Abilitato',
'admin.addons.disabled': 'Disabilitato',
'admin.addons.type.trip': 'Viaggio',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Ricevute',
'costs.receiptsTitle': 'Ricevute e fatture',
'costs.attachReceipt': 'Allega ricevuta / fattura',
'costs.scan.button': 'Scansiona ricevuta',
'costs.scan.reading': 'Lettura della ricevuta…',
'costs.scan.review': 'Controlla la spesa',
'costs.scan.nothingRead': 'Non è stato possibile leggere una ricevuta da questa foto.',
'costs.scan.failed': 'Impossibile avviare la lettura della ricevuta.',
'costs.scan.title': 'Scansiona ricevuta',
'costs.scan.accepted': 'La foto di una sola ricevuta (JPG, PNG o WEBP, fino a 10 MB). Il modello di IA la legge in background, poi controlli la spesa prima di salvarla.',
'costs.scan.dropHere': 'Trascina qui la foto della ricevuta, oppure fai clic per sceglierla o scattarla',
'costs.scan.dropActive': 'Rilascia la foto per scansionarla',
'costs.scan.start': 'Scansiona',
'costs.scan.unsupported': 'Si può scansionare solo una foto: JPG, PNG o WEBP.',
'costs.noReceipts': 'Nessuna ricevuta allegata',
'costs.deleteReceipt': 'Rimuovi ricevuta',
'costs.viewReceipt': 'Visualizza ricevuta',
+1
View File
@@ -129,6 +129,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Trascina i file di conferma prenotazione qui o clicca per selezionare',
'reservations.import.dropActive': 'Rilascia i file per importare',
'reservations.import.acceptedFormats': 'Accettati: EML, PDF, PKPass, HTML, TXT (max 10 MB ciascuno, fino a 5 file)',
'reservations.import.acceptedPhotos': 'Le foto (JPG, PNG, WEBP) vengono lette dal modello di IA.',
'reservations.import.parsing': 'Analisi dei file in corso…',
'reservations.import.previewHeading': '{count} prenotazione/i trovata/e',
'reservations.import.previewEmpty': 'Nessuna prenotazione è stata estratta dai file caricati.',
+2 -2
View File
@@ -398,9 +398,9 @@ const settings: TranslationStrings = {
'Dove gira il modello: un server Ollama locale o un endpoint compatibile con OpenAI.',
'settings.aiParsing.apiKey': 'Chiave API',
'settings.aiParsing.apiKeyHint': 'Memorizzata in forma cifrata. Lascia vuoto per mantenere la chiave attuale.',
'settings.aiParsing.multimodal': 'Invia i documenti come immagini',
'settings.aiParsing.multimodal': 'Il modello legge le immagini',
'settings.aiParsing.multimodalHint':
'Per i modelli con capacità visive: invia il PDF originale invece del testo estratto.',
'Attiva per un modello che legge le immagini, così una foto può essere importata o scansionata.',
'settings.aiParsing.toast.saved': 'Impostazioni AI salvate',
'settings.aiParsing.toast.saveError': 'Impossibile salvare le impostazioni AI',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -638,6 +638,11 @@ const admin: TranslationStrings = {
'各自が接続した Dawarich インスタンスから、滞在と記録されたルートを読み取ります',
'admin.addons.catalog.llm_parsing.name': 'AI 解析',
'admin.addons.catalog.llm_parsing.description': '内蔵パーサーが読めない予約を、選んだ AI モデルで読み取ります',
'admin.addons.llm.vision.auto': '自動',
'admin.addons.llm.vision.on': 'はい',
'admin.addons.llm.vision.off': 'いいえ',
'admin.addons.llm.vision.hintLocal': '「自動」では、このモデルが画像を読めるかを Ollama サーバーに問い合わせます。',
'admin.addons.llm.vision.hintCloud': 'クラウドのモデルでは「自動」は「いいえ」になります。このモデルが画像を読める場合は「はい」を選んでください。',
'admin.addons.enabled': '有効',
'admin.addons.disabled': '無効',
'admin.addons.type.trip': '旅行',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'レシート',
'costs.receiptsTitle': 'レシート・請求書',
'costs.attachReceipt': 'レシート・請求書を添付',
'costs.scan.button': 'レシートをスキャン',
'costs.scan.reading': 'レシートを読み取り中…',
'costs.scan.review': '支出を確認',
'costs.scan.nothingRead': 'この写真からレシートを読み取れませんでした。',
'costs.scan.failed': 'レシートの読み取りを開始できませんでした。',
'costs.scan.title': 'レシートをスキャン',
'costs.scan.accepted': 'レシート1枚の写真(JPG、PNG、WEBP、10 MB まで)。AI モデルがバックグラウンドで読み取り、保存前に支出を確認します。',
'costs.scan.dropHere': 'ここにレシートの写真をドロップするか、クリックして選択または撮影',
'costs.scan.dropActive': 'ドロップしてスキャン',
'costs.scan.start': 'スキャン',
'costs.scan.unsupported': 'スキャンできるのは写真(JPG、PNG、WEBP)だけです。',
'costs.noReceipts': '添付されたレシートはありません',
'costs.deleteReceipt': 'レシートを削除',
'costs.viewReceipt': 'レシートを表示',
+1
View File
@@ -128,6 +128,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': '予約確認ファイルをここにドロップするか、クリックして選択',
'reservations.import.dropActive': 'ファイルをドロップしてインポート',
'reservations.import.acceptedFormats': '対応形式:EML、PDF、PKPass、HTML、TXT(各最大 10 MB、最大 5 ファイル)',
'reservations.import.acceptedPhotos': '写真(JPG、PNG、WEBP)は AI モデルが読み取ります。',
'reservations.import.parsing': 'ファイルを解析中…',
'reservations.import.previewHeading': '{count} 件の予約が見つかりました',
'reservations.import.previewEmpty': 'アップロードされたファイルから予約を抽出できませんでした。',
+2 -2
View File
@@ -372,8 +372,8 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': 'モデルの実行場所 — ローカルのOllamaサーバー、またはOpenAI互換のエンドポイント。',
'settings.aiParsing.apiKey': 'APIキー',
'settings.aiParsing.apiKeyHint': '暗号化して保存されます。現在のキーを保持する場合は空欄のままにしてください。',
'settings.aiParsing.multimodal': 'ドキュメントを画像として送信',
'settings.aiParsing.multimodalHint': '画像認識対応モデル向け — 抽出したテキストの代わりに元のPDFを送信します。',
'settings.aiParsing.multimodal': 'モデルが画像を読める',
'settings.aiParsing.multimodalHint': '画像を読めるモデルでオンにすると、写真をインポートやスキャンできます。',
'settings.aiParsing.toast.saved': 'AI設定を保存しました',
'settings.aiParsing.toast.saveError': 'AI設定を保存できませんでした',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -638,6 +638,11 @@ const admin: TranslationStrings = {
'사용자가 각자 연결한 Dawarich 인스턴스에서 방문 기록과 기록된 경로를 읽어옵니다',
'admin.addons.catalog.llm_parsing.name': 'AI 분석',
'admin.addons.catalog.llm_parsing.description': '기본 분석기가 읽지 못하는 예약을 원하는 AI 모델로 읽어냅니다',
'admin.addons.llm.vision.auto': '자동',
'admin.addons.llm.vision.on': '예',
'admin.addons.llm.vision.off': '아니요',
'admin.addons.llm.vision.hintLocal': '자동은 이 모델이 이미지를 읽을 수 있는지 Ollama 서버에 묻습니다.',
'admin.addons.llm.vision.hintCloud': '클라우드 모델에서 자동은 아니요를 뜻합니다. 이 모델이 이미지를 읽을 수 있으면 예를 선택하세요.',
'admin.addons.enabled': '활성화됨',
'admin.addons.disabled': '비활성화됨',
'admin.addons.type.trip': '여행',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': '영수증',
'costs.receiptsTitle': '영수증 및 청구서',
'costs.attachReceipt': '영수증 / 청구서 첨부',
'costs.scan.button': '영수증 스캔',
'costs.scan.reading': '영수증 읽는 중…',
'costs.scan.review': '지출 검토',
'costs.scan.nothingRead': '이 사진에서 영수증을 읽지 못했습니다.',
'costs.scan.failed': '영수증 읽기를 시작하지 못했습니다.',
'costs.scan.title': '영수증 스캔',
'costs.scan.accepted': '영수증 한 장의 사진(JPG, PNG, WEBP, 최대 10MB). AI 모델이 백그라운드에서 읽은 뒤, 저장하기 전에 지출을 확인합니다.',
'costs.scan.dropHere': '영수증 사진을 여기에 놓거나, 클릭해서 선택하거나 촬영하세요',
'costs.scan.dropActive': '놓아서 사진 스캔',
'costs.scan.start': '스캔',
'costs.scan.unsupported': '사진만 스캔할 수 있습니다: JPG, PNG, WEBP.',
'costs.noReceipts': '첨부된 영수증 없음',
'costs.deleteReceipt': '영수증 삭제',
'costs.viewReceipt': '영수증 보기',
+1
View File
@@ -128,6 +128,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': '예약 확인 파일을 여기에 끌어다 놓거나 클릭하여 선택',
'reservations.import.dropActive': '가져올 파일을 여기에 놓으세요',
'reservations.import.acceptedFormats': '허용 형식: EML, PDF, PKPass, HTML, TXT (파일당 최대 10 MB, 최대 5개)',
'reservations.import.acceptedPhotos': '사진(JPG, PNG, WEBP)은 AI 모델이 읽습니다.',
'reservations.import.parsing': '파일 분석 중…',
'reservations.import.previewHeading': '{count}개 예약 발견',
'reservations.import.previewEmpty': '업로드된 파일에서 예약을 추출할 수 없었습니다.',
+2 -2
View File
@@ -387,8 +387,8 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': '모델이 실행되는 위치 — 로컬 Ollama 서버 또는 OpenAI 호환 엔드포인트입니다.',
'settings.aiParsing.apiKey': 'API 키',
'settings.aiParsing.apiKeyHint': '암호화되어 저장됩니다. 현재 키를 유지하려면 비워 두세요.',
'settings.aiParsing.multimodal': '문서를 이미지로 전송',
'settings.aiParsing.multimodalHint': '비전 지원 모델용 — 추출된 텍스트 대신 원본 PDF를 전송합니다.',
'settings.aiParsing.multimodal': '모델이 이미지를 읽음',
'settings.aiParsing.multimodalHint': '이미지를 읽는 모델이면 켜세요. 사진을 가져오거나 스캔할 수 있습니다.',
'settings.aiParsing.toast.saved': 'AI 설정이 저장되었습니다',
'settings.aiParsing.toast.saveError': 'AI 설정을 저장할 수 없습니다',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -622,6 +622,11 @@ const admin: TranslationStrings = {
'Lees bezoeken en opgenomen routes uit een Dawarich-instantie die elke lezer zelf koppelt',
'admin.addons.catalog.llm_parsing.name': 'AI-analyse',
'admin.addons.catalog.llm_parsing.description': 'Leest boekingen die de ingebouwde parser niet begrijpt, met een AI-model naar keuze',
'admin.addons.llm.vision.auto': 'Automatisch',
'admin.addons.llm.vision.on': 'Ja',
'admin.addons.llm.vision.off': 'Nee',
'admin.addons.llm.vision.hintLocal': 'Automatisch vraagt de Ollama-server of dit model afbeeldingen leest.',
'admin.addons.llm.vision.hintCloud': 'Automatisch betekent nee voor een cloudmodel. Kies Ja als dit model afbeeldingen leest.',
'admin.addons.enabled': 'Ingeschakeld',
'admin.addons.disabled': 'Uitgeschakeld',
'admin.addons.type.trip': 'Reis',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Bonnetjes',
'costs.receiptsTitle': 'Bonnetjes & facturen',
'costs.attachReceipt': 'Bon / factuur bijvoegen',
'costs.scan.button': 'Bon scannen',
'costs.scan.reading': 'Bon wordt gelezen…',
'costs.scan.review': 'Uitgave controleren',
'costs.scan.nothingRead': 'Uit deze foto kon geen bon worden gelezen.',
'costs.scan.failed': 'Het lezen van de bon kon niet worden gestart.',
'costs.scan.title': 'Bon scannen',
'costs.scan.accepted': 'Een foto van één bon (JPG, PNG of WEBP, max. 10 MB). Het AI-model leest hem op de achtergrond; daarna controleer je de uitgave voordat die wordt opgeslagen.',
'costs.scan.dropHere': 'Zet de foto van de bon hier neer, of klik om er een te kiezen of te maken',
'costs.scan.dropActive': 'Laat de foto los om te scannen',
'costs.scan.start': 'Scannen',
'costs.scan.unsupported': 'Alleen een foto kan worden gescand: JPG, PNG of WEBP.',
'costs.noReceipts': 'Geen bonnetjes bijgevoegd',
'costs.deleteReceipt': 'Bonnetje verwijderen',
'costs.viewReceipt': 'Bonnetje bekijken',
+1
View File
@@ -130,6 +130,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Laat bestanden los om te importeren',
'reservations.import.acceptedFormats':
'Geaccepteerd: EML, PDF, PKPass, HTML, TXT (max. 10 MB per stuk, tot 5 bestanden)',
'reservations.import.acceptedPhotos': "Foto's (JPG, PNG, WEBP) worden door het AI-model gelezen.",
'reservations.import.parsing': 'Bestanden verwerken…',
'reservations.import.previewHeading': '{count} reservering(en) gevonden',
'reservations.import.previewEmpty': 'Er konden geen reserveringen worden geëxtraheerd uit de geüploade bestanden.',
+2 -2
View File
@@ -398,9 +398,9 @@ const settings: TranslationStrings = {
'Waar het model draait — een lokale Ollama-server of een OpenAI-compatibel endpoint.',
'settings.aiParsing.apiKey': 'API-sleutel',
'settings.aiParsing.apiKeyHint': 'Versleuteld opgeslagen. Laat leeg om de huidige sleutel te behouden.',
'settings.aiParsing.multimodal': 'Documenten als afbeeldingen versturen',
'settings.aiParsing.multimodal': 'Model leest afbeeldingen',
'settings.aiParsing.multimodalHint':
'Voor modellen met beeldherkenning — verstuurt de originele PDF in plaats van geëxtraheerde tekst.',
'Zet aan voor een model dat afbeeldingen leest, zodat een foto kan worden geïmporteerd of gescand.',
'settings.aiParsing.toast.saved': 'AI-instellingen opgeslagen',
'settings.aiParsing.toast.saveError': 'AI-instellingen konden niet worden opgeslagen',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -621,6 +621,11 @@ const admin: TranslationStrings = {
'Odczytuj pobyty i zapisane trasy z instancji Dawarich, którą każdy użytkownik podłącza sam',
'admin.addons.catalog.llm_parsing.name': 'Analiza AI',
'admin.addons.catalog.llm_parsing.description': 'Odczytuje rezerwacje, których nie rozumie wbudowany parser, przy użyciu wybranego modelu AI',
'admin.addons.llm.vision.auto': 'Automatycznie',
'admin.addons.llm.vision.on': 'Tak',
'admin.addons.llm.vision.off': 'Nie',
'admin.addons.llm.vision.hintLocal': 'Automatycznie pyta serwer Ollama, czy ten model czyta obrazy.',
'admin.addons.llm.vision.hintCloud': 'Automatycznie oznacza „nie” dla modelu w chmurze. Wybierz Tak, jeśli ten model czyta obrazy.',
'admin.addons.enabled': 'Włączone',
'admin.addons.disabled': 'Wyłączone',
'admin.addons.type.trip': 'Podróż',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Paragony',
'costs.receiptsTitle': 'Paragony i faktury',
'costs.attachReceipt': 'Załącz paragon / fakturę',
'costs.scan.button': 'Zeskanuj paragon',
'costs.scan.reading': 'Odczytywanie paragonu…',
'costs.scan.review': 'Sprawdź wydatek',
'costs.scan.nothingRead': 'Z tego zdjęcia nie udało się odczytać paragonu.',
'costs.scan.failed': 'Nie udało się rozpocząć odczytu paragonu.',
'costs.scan.title': 'Zeskanuj paragon',
'costs.scan.accepted': 'Zdjęcie jednego paragonu (JPG, PNG lub WEBP, do 10 MB). Model AI odczyta je w tle, a potem sprawdzisz wydatek przed zapisaniem.',
'costs.scan.dropHere': 'Upuść tu zdjęcie paragonu albo kliknij, aby je wybrać lub zrobić',
'costs.scan.dropActive': 'Upuść zdjęcie, aby je zeskanować',
'costs.scan.start': 'Skanuj',
'costs.scan.unsupported': 'Skanować można tylko zdjęcie: JPG, PNG lub WEBP.',
'costs.noReceipts': 'Brak załączonych paragonów',
'costs.deleteReceipt': 'Usuń paragon',
'costs.viewReceipt': 'Zobacz paragon',
+1
View File
@@ -129,6 +129,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Upuść pliki potwierdzeń rezerwacji tutaj lub kliknij, aby wybrać',
'reservations.import.dropActive': 'Upuść pliki, aby zaimportować',
'reservations.import.acceptedFormats': 'Akceptowane: EML, PDF, PKPass, HTML, TXT (maks. 10 MB każdy, do 5 plików)',
'reservations.import.acceptedPhotos': 'Zdjęcia (JPG, PNG, WEBP) odczytuje model AI.',
'reservations.import.parsing': 'Przetwarzanie plików…',
'reservations.import.previewHeading': 'Znaleziono {count} rezerwację/rezerwacje',
'reservations.import.previewEmpty': 'Nie udało się wyodrębnić rezerwacji z przesłanych plików.',
+2 -2
View File
@@ -397,9 +397,9 @@ const settings: TranslationStrings = {
'Miejsce, w którym działa model — lokalny serwer Ollama lub punkt końcowy zgodny z OpenAI.',
'settings.aiParsing.apiKey': 'Klucz API',
'settings.aiParsing.apiKeyHint': 'Przechowywany w postaci zaszyfrowanej. Pozostaw puste, aby zachować bieżący klucz.',
'settings.aiParsing.multimodal': 'Wysyłaj dokumenty jako obrazy',
'settings.aiParsing.multimodal': 'Model czyta obrazy',
'settings.aiParsing.multimodalHint':
'Dla modeli obsługujących obraz — wysyła oryginalny plik PDF zamiast wyodrębnionego tekstu.',
'Włącz dla modelu, który czyta obrazy, aby można było importować lub skanować zdjęcia.',
'settings.aiParsing.toast.saved': 'Zapisano ustawienia AI',
'settings.aiParsing.toast.saveError': 'Nie udało się zapisać ustawień AI',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -626,6 +626,11 @@ const admin: TranslationStrings = {
'Чтение посещений и записанных маршрутов из экземпляра Dawarich, который каждый пользователь подключает сам',
'admin.addons.catalog.llm_parsing.name': 'Разбор с помощью ИИ',
'admin.addons.catalog.llm_parsing.description': 'Читает брони, которые не понимает встроенный анализатор, с помощью выбранной вами модели ИИ',
'admin.addons.llm.vision.auto': 'Автоматически',
'admin.addons.llm.vision.on': 'Да',
'admin.addons.llm.vision.off': 'Нет',
'admin.addons.llm.vision.hintLocal': '«Автоматически» спрашивает сервер Ollama, читает ли эта модель изображения.',
'admin.addons.llm.vision.hintCloud': 'Для облачной модели «Автоматически» означает «нет». Выберите «Да», если эта модель читает изображения.',
'admin.addons.enabled': 'Включено',
'admin.addons.disabled': 'Отключено',
'admin.addons.type.trip': 'Поездка',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Чеки',
'costs.receiptsTitle': 'Чеки и счета',
'costs.attachReceipt': 'Прикрепить чек / счет',
'costs.scan.button': 'Сканировать чек',
'costs.scan.reading': 'Чтение чека…',
'costs.scan.review': 'Проверить расход',
'costs.scan.nothingRead': 'Не удалось прочитать чек с этой фотографии.',
'costs.scan.failed': 'Не удалось начать чтение чека.',
'costs.scan.title': 'Сканировать чек',
'costs.scan.accepted': 'Фото одного чека (JPG, PNG или WEBP, до 10 МБ). Модель ИИ прочитает его в фоне, а затем вы проверите расход перед сохранением.',
'costs.scan.dropHere': 'Перетащите сюда фото чека или нажмите, чтобы выбрать или сделать снимок',
'costs.scan.dropActive': 'Отпустите фото, чтобы отсканировать его',
'costs.scan.start': 'Сканировать',
'costs.scan.unsupported': 'Сканировать можно только фото: JPG, PNG или WEBP.',
'costs.noReceipts': 'Нет прикрепленных чеков',
'costs.deleteReceipt': 'Удалить чек',
'costs.viewReceipt': 'Просмотреть чек',
+1
View File
@@ -128,6 +128,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Перетащите файлы подтверждений бронирования сюда или нажмите для выбора',
'reservations.import.dropActive': 'Отпустите файлы для импорта',
'reservations.import.acceptedFormats': 'Принимаются: EML, PDF, PKPass, HTML, TXT (макс. 10 МБ каждый, до 5 файлов)',
'reservations.import.acceptedPhotos': 'Фотографии (JPG, PNG, WEBP) читает модель ИИ.',
'reservations.import.parsing': 'Обработка файлов…',
'reservations.import.previewHeading': 'Найдено {count} бронирование(й)',
'reservations.import.previewEmpty': 'Из загруженных файлов не удалось извлечь бронирования.',
+2 -2
View File
@@ -398,9 +398,9 @@ const settings: TranslationStrings = {
'Где работает модель — локальный сервер Ollama или конечная точка, совместимая с OpenAI.',
'settings.aiParsing.apiKey': 'Ключ API',
'settings.aiParsing.apiKeyHint': 'Хранится в зашифрованном виде. Оставьте поле пустым, чтобы сохранить текущий ключ.',
'settings.aiParsing.multimodal': 'Отправлять документы как изображения',
'settings.aiParsing.multimodal': 'Модель читает изображения',
'settings.aiParsing.multimodalHint':
'Для моделей с поддержкой изображений — отправляет исходный PDF вместо извлечённого текста.',
'Включите для модели, которая читает изображения, чтобы фотографию можно было импортировать или отсканировать.',
'settings.aiParsing.toast.saved': 'Настройки ИИ сохранены',
'settings.aiParsing.toast.saveError': 'Не удалось сохранить настройки ИИ',
'settings.tabs.appearance': 'Внешний вид',
+5
View File
@@ -676,6 +676,11 @@ const admin: TranslationStrings = {
'admin.addons.catalog.llm_parsing.name': 'Analýza pomocou AI',
'admin.addons.catalog.llm_parsing.description':
'Prečíta rezervácie, ktoré vstavaný analyzátor nezvládne, pomocou zvoleného modelu AI',
'admin.addons.llm.vision.auto': 'Automaticky',
'admin.addons.llm.vision.on': 'Áno',
'admin.addons.llm.vision.off': 'Nie',
'admin.addons.llm.vision.hintLocal': 'Automaticky sa opýta servera Ollama, či tento model číta obrázky.',
'admin.addons.llm.vision.hintCloud': 'Pri cloudovom modeli znamená Automaticky nie. Zvoľte Áno, ak tento model číta obrázky.',
'admin.addons.enabled': 'Povolené',
'admin.addons.disabled': 'Zakázané',
'admin.addons.type.trip': 'Cesta',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Účtenky',
'costs.receiptsTitle': 'Účtenky a faktúry',
'costs.attachReceipt': 'Priložiť účtenku / faktúru',
'costs.scan.button': 'Naskenovať účtenku',
'costs.scan.reading': 'Číta sa účtenka…',
'costs.scan.review': 'Skontrolovať výdavok',
'costs.scan.nothingRead': 'Z tejto fotografie sa nepodarilo prečítať účtenku.',
'costs.scan.failed': 'Čítanie účtenky sa nepodarilo spustiť.',
'costs.scan.title': 'Naskenovať účtenku',
'costs.scan.accepted': 'Fotografia jednej účtenky (JPG, PNG alebo WEBP, do 10 MB). Model AI ju prečíta na pozadí a vy potom výdavok pred uložením skontrolujete.',
'costs.scan.dropHere': 'Presuňte sem fotografiu účtenky alebo kliknite a vyberte či odfoťte novú',
'costs.scan.dropActive': 'Pustite fotografiu na naskenovanie',
'costs.scan.start': 'Skenovať',
'costs.scan.unsupported': 'Skenovať sa dá len fotografia: JPG, PNG alebo WEBP.',
'costs.noReceipts': 'Žiadne priložené účtenky',
'costs.deleteReceipt': 'Odobrať účtenku',
'costs.viewReceipt': 'Zobraziť účtenku',
+1
View File
@@ -134,6 +134,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Presuňte sem súbory s potvrdením rezervácie alebo kliknite pre výber',
'reservations.import.dropActive': 'Pustite súbory pre import',
'reservations.import.acceptedFormats': 'Prijímané: EML, PDF, PKPass, HTML, TXT (max. 10 MB každý, až 5 súborov)',
'reservations.import.acceptedPhotos': 'Fotografie (JPG, PNG, WEBP) číta model AI.',
'reservations.import.parsing': 'Spracúvajú sa súbory…',
'reservations.import.previewHeading': 'Nájdených {count} rezervácií',
'reservations.import.previewEmpty': 'Z nahraných súborov sa nepodarilo extrahovať žiadne rezervácie.',
+2 -2
View File
@@ -404,9 +404,9 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': 'Kde model beží — lokálny server Ollama alebo koncový bod kompatibilný s OpenAI.',
'settings.aiParsing.apiKey': 'API kľúč',
'settings.aiParsing.apiKeyHint': 'Ukladá sa šifrovane. Ponechajte prázdne pre zachovanie aktuálneho kľúča.',
'settings.aiParsing.multimodal': 'Odosielať dokumenty ako obrázky',
'settings.aiParsing.multimodal': 'Model číta obrázky',
'settings.aiParsing.multimodalHint':
'Pre modely so schopnosťou spracovať obraz — odošle pôvodné PDF namiesto extrahovaného textu.',
'Zapnite pre model, ktorý číta obrázky, aby sa fotografia dala importovať alebo naskenovať.',
'settings.aiParsing.toast.saved': 'Nastavenia AI uložené',
'settings.aiParsing.toast.saveError': 'Nastavenia AI sa nepodarilo uložiť',
'settings.tabs.appearance': 'Vzhľad',
+5
View File
@@ -687,6 +687,11 @@ const admin: TranslationStrings = {
'Läs vistelser och inspelade rutter från en Dawarich-instans som varje läsare ansluter själv',
'admin.addons.catalog.llm_parsing.name': 'AI-tolkning',
'admin.addons.catalog.llm_parsing.description': 'Läser bokningar som den inbyggda tolken inte klarar, med en AI-modell du väljer',
'admin.addons.llm.vision.auto': 'Automatiskt',
'admin.addons.llm.vision.on': 'Ja',
'admin.addons.llm.vision.off': 'Nej',
'admin.addons.llm.vision.hintLocal': 'Automatiskt frågar Ollama-servern om modellen läser bilder.',
'admin.addons.llm.vision.hintCloud': 'Automatiskt betyder nej för en molnmodell. Välj Ja om modellen läser bilder.',
'admin.addons.enabled': 'Aktiverad',
'admin.addons.disabled': 'Inaktiverad',
'admin.addons.type.trip': 'Resa',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Kvitton',
'costs.receiptsTitle': 'Kvitton & fakturor',
'costs.attachReceipt': 'Bifoga kvitto / faktura',
'costs.scan.button': 'Skanna kvitto',
'costs.scan.reading': 'Läser kvittot…',
'costs.scan.review': 'Granska utgiften',
'costs.scan.nothingRead': 'Inget kvitto kunde läsas från fotot.',
'costs.scan.failed': 'Det gick inte att börja läsa kvittot.',
'costs.scan.title': 'Skanna kvitto',
'costs.scan.accepted': 'Ett foto av ett kvitto (JPG, PNG eller WEBP, högst 10 MB). AI-modellen läser det i bakgrunden, sedan granskar du utgiften innan den sparas.',
'costs.scan.dropHere': 'Släpp kvittofotot här, eller klicka för att välja eller ta ett',
'costs.scan.dropActive': 'Släpp fotot för att skanna det',
'costs.scan.start': 'Skanna',
'costs.scan.unsupported': 'Bara ett foto kan skannas: JPG, PNG eller WEBP.',
'costs.noReceipts': 'Inga bifogade kvitton',
'costs.deleteReceipt': 'Ta bort kvitto',
'costs.viewReceipt': 'Visa kvitto',
+1
View File
@@ -130,6 +130,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'Dra och släpp filerna som ska importeras',
'reservations.import.acceptedFormats':
'Godkända filformat: EML, PDF, PKPass, HTML, TXT (högst 10 MB per fil, upp till 5 filer)',
'reservations.import.acceptedPhotos': 'Foton (JPG, PNG, WEBP) läses av AI-modellen.',
'reservations.import.parsing': 'Analyserar filer…',
'reservations.import.previewHeading': '{count} reservation(er) hittades',
'reservations.import.previewEmpty': 'Inga bokningar kunde extraheras från de uppladdade filerna.',
+2 -2
View File
@@ -396,9 +396,9 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': 'Var modellen körs — en lokal Ollama-server eller en OpenAI-kompatibel slutpunkt.',
'settings.aiParsing.apiKey': 'API-nyckel',
'settings.aiParsing.apiKeyHint': 'Lagras krypterad. Lämna tomt för att behålla den nuvarande nyckeln.',
'settings.aiParsing.multimodal': 'Skicka dokument som bilder',
'settings.aiParsing.multimodal': 'Modellen läser bilder',
'settings.aiParsing.multimodalHint':
'För modeller med bildstöd — skickar original-PDF:en istället för extraherad text.',
'Slå på för en modell som läser bilder, så att ett foto kan importeras eller skannas.',
'settings.aiParsing.toast.saved': 'AI-inställningar sparade',
'settings.aiParsing.toast.saveError': 'Kunde inte spara AI-inställningarna',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -598,6 +598,11 @@ const admin: TranslationStrings = {
'admin.addons.catalog.airtrail.description': "ซิงค์เที่ยวบินจากอินสแตนซ์ AirTrail ของคุณ",
'admin.addons.catalog.llm_parsing.name': "การแยกวิเคราะห์ AI",
'admin.addons.catalog.llm_parsing.description': "อ่านการจองที่ parser ในตัวไม่สามารถทำได้ โดยใช้โมเดล AI ที่คุณเลือก",
'admin.addons.llm.vision.auto': "อัตโนมัติ",
'admin.addons.llm.vision.on': "ใช่",
'admin.addons.llm.vision.off': "ไม่",
'admin.addons.llm.vision.hintLocal': "โหมดอัตโนมัติจะถามเซิร์ฟเวอร์ Ollama ว่าโมเดลนี้อ่านรูปภาพได้หรือไม่",
'admin.addons.llm.vision.hintCloud': "สำหรับโมเดลบนคลาวด์ โหมดอัตโนมัติหมายถึงไม่ เลือกใช่หากโมเดลนี้อ่านรูปภาพได้",
'admin.addons.enabled': "เปิดใช้งานแล้ว",
'admin.addons.disabled': "ปิดการใช้งาน",
'admin.addons.type.trip': "การเดินทาง",
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': "ใบเสร็จ",
'costs.receiptsTitle': "ใบเสร็จและใบแจ้งหนี้",
'costs.attachReceipt': "แนบใบเสร็จ / ใบแจ้งหนี้",
'costs.scan.button': "สแกนใบเสร็จ",
'costs.scan.reading': "กำลังอ่านใบเสร็จ…",
'costs.scan.review': "ตรวจสอบค่าใช้จ่าย",
'costs.scan.nothingRead': "อ่านใบเสร็จจากรูปนี้ไม่ได้",
'costs.scan.failed': "ไม่สามารถเริ่มอ่านใบเสร็จได้",
'costs.scan.title': "สแกนใบเสร็จ",
'costs.scan.accepted': "รูปถ่ายใบเสร็จหนึ่งใบ (JPG, PNG หรือ WEBP ไม่เกิน 10 MB) โมเดล AI จะอ่านอยู่เบื้องหลัง จากนั้นคุณตรวจสอบค่าใช้จ่ายก่อนบันทึก",
'costs.scan.dropHere': "วางรูปใบเสร็จที่นี่ หรือคลิกเพื่อเลือกหรือถ่ายรูป",
'costs.scan.dropActive': "ปล่อยรูปเพื่อสแกน",
'costs.scan.start': "สแกน",
'costs.scan.unsupported': "สแกนได้เฉพาะรูปถ่าย: JPG, PNG หรือ WEBP",
'costs.noReceipts': "ยังไม่มีใบเสร็จแนบ",
'costs.deleteReceipt': "ลบใบเสร็จ",
'costs.viewReceipt': "ดูใบเสร็จ",
+1
View File
@@ -133,6 +133,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': "วางไฟล์ยืนยันการจองที่นี่ หรือคลิกเพื่อเลือก",
'reservations.import.dropActive': "วางไฟล์ที่จะนำเข้า",
'reservations.import.acceptedFormats': "ยอมรับ: EML, PDF, PKPass, HTML, TXT (สูงสุด 10 MB ต่อไฟล์ สูงสุด 5 ไฟล์)",
'reservations.import.acceptedPhotos': "โมเดล AI จะอ่านรูปถ่าย (JPG, PNG, WEBP)",
'reservations.import.parsing': "กำลังแยกวิเคราะห์ไฟล์...",
'reservations.import.previewHeading': "พบการจอง {count} แล้ว",
'reservations.import.previewEmpty': "ไม่สามารถแยกการจองออกจากไฟล์ที่อัปโหลดได้",
+2 -2
View File
@@ -391,8 +391,8 @@ const settings: TranslationStrings = {
'settings.aiParsing.baseUrlHint': "ตำแหน่งที่โมเดลทำงาน — เซิร์ฟเวอร์ Ollama ในเครื่องหรือจุดสิ้นสุดที่เข้ากันได้กับ OpenAI",
'settings.aiParsing.apiKey': "คีย์เอพีไอ",
'settings.aiParsing.apiKeyHint': "จัดเก็บแบบเข้ารหัส เว้นว่างไว้เพื่อเก็บคีย์ปัจจุบันไว้",
'settings.aiParsing.multimodal': "ส่งเอกสารเป็นรูปภาพ",
'settings.aiParsing.multimodalHint': "สำหรับรุ่นที่มองเห็นได้ — ส่ง PDF ต้นฉบับแทนข้อความที่แยกออกมา",
'settings.aiParsing.multimodal': "โมเดลอ่านรูปภาพได้",
'settings.aiParsing.multimodalHint': "เปิดสำหรับโมเดลที่อ่านรูปภาพได้ เพื่อให้นำเข้าหรือสแกนรูปถ่ายได้",
'settings.aiParsing.toast.saved': "บันทึกการตั้งค่า AI แล้ว",
'settings.aiParsing.toast.saveError': "ไม่สามารถบันทึกการตั้งค่า AI",
'settings.tabs.appearance': "ลักษณะที่ปรากฏ",
+5
View File
@@ -672,6 +672,11 @@ const admin: TranslationStrings = {
'Her kullanıcının kendi bağladığı bir Dawarich sunucusundan ziyaretleri ve kaydedilen rotaları okuyun',
'admin.addons.catalog.llm_parsing.name': 'Yapay zekâ ile ayrıştırma',
'admin.addons.catalog.llm_parsing.description': 'Yerleşik ayrıştırıcının okuyamadığı rezervasyonları, seçtiğiniz yapay zekâ modeliyle okur',
'admin.addons.llm.vision.auto': 'Otomatik',
'admin.addons.llm.vision.on': 'Evet',
'admin.addons.llm.vision.off': 'Hayır',
'admin.addons.llm.vision.hintLocal': 'Otomatik, bu modelin görselleri okuyup okumadığını Ollama sunucusuna sorar.',
'admin.addons.llm.vision.hintCloud': 'Bulut modeli için Otomatik, hayır anlamına gelir. Bu model görselleri okuyorsa Evet’i seç.',
'admin.addons.enabled': 'Etkinleştirilmiş',
'admin.addons.disabled': 'Engelli',
'admin.addons.type.trip': 'Seyahat',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Fişler',
'costs.receiptsTitle': 'Fişler ve Faturalar',
'costs.attachReceipt': 'Fiş / fatura ekle',
'costs.scan.button': 'Fiş tara',
'costs.scan.reading': 'Fiş okunuyor…',
'costs.scan.review': 'Harcamayı gözden geçir',
'costs.scan.nothingRead': 'Bu fotoğraftan fiş okunamadı.',
'costs.scan.failed': 'Fiş okuma başlatılamadı.',
'costs.scan.title': 'Fiş tara',
'costs.scan.accepted': 'Tek bir fişin fotoğrafı (JPG, PNG veya WEBP, en fazla 10 MB). Yapay zekâ modeli onu arka planda okur, sonra harcamayı kaydetmeden önce kontrol edersin.',
'costs.scan.dropHere': 'Fiş fotoğrafını buraya bırak ya da seçmek veya çekmek için tıkla',
'costs.scan.dropActive': 'Taramak için fotoğrafı bırak',
'costs.scan.start': 'Tara',
'costs.scan.unsupported': 'Yalnızca fotoğraf taranabilir: JPG, PNG veya WEBP.',
'costs.noReceipts': 'Ekli fiş yok',
'costs.deleteReceipt': 'Fişi kaldır',
'costs.viewReceipt': 'Fişi görüntüle',
+1
View File
@@ -130,6 +130,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropActive': 'İçe aktarmak için dosyaları bırakın',
'reservations.import.acceptedFormats':
'Kabul edilenler: EML, PDF, PKPass, HTML, TXT (her biri maks. 10 MB, en fazla 5 dosya)',
'reservations.import.acceptedPhotos': 'Fotoğrafları (JPG, PNG, WEBP) yapay zekâ modeli okur.',
'reservations.import.parsing': 'Dosyalar işleniyor…',
'reservations.import.previewHeading': '{count} rezervasyon bulundu',
'reservations.import.previewEmpty': 'Yüklenen dosyalardan hiçbir rezervasyon çıkarılamadı.',
+2 -2
View File
@@ -395,9 +395,9 @@ const settings: TranslationStrings = {
'Modelin çalıştığı yer — yerel bir Ollama sunucusu veya OpenAI uyumlu bir uç nokta.',
'settings.aiParsing.apiKey': 'API anahtarı',
'settings.aiParsing.apiKeyHint': 'Şifrelenmiş olarak saklanır. Mevcut anahtarı korumak için boş bırak.',
'settings.aiParsing.multimodal': 'Belgeleri görsel olarak gönder',
'settings.aiParsing.multimodal': 'Model görselleri okur',
'settings.aiParsing.multimodalHint':
"Görüntü işleyebilen modeller için — çıkarılan metin yerine orijinal PDF'yi gönderir.",
'Görselleri okuyan bir model için aç; böylece bir fotoğraf içe aktarılabilir veya taranabilir.',
'settings.aiParsing.toast.saved': 'Yapay zekâ ayarları kaydedildi',
'settings.aiParsing.toast.saveError': 'Yapay zekâ ayarları kaydedilemedi',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -623,6 +623,11 @@ const admin: TranslationStrings = {
'Читає перебування та записані маршрути із сервера Dawarich, який кожен користувач підключає сам',
'admin.addons.catalog.llm_parsing.name': 'Розбір за допомогою ШІ',
'admin.addons.catalog.llm_parsing.description': 'Читає бронювання, які не розпізнає вбудований аналізатор, за допомогою обраної вами моделі ШІ',
'admin.addons.llm.vision.auto': 'Автоматично',
'admin.addons.llm.vision.on': 'Так',
'admin.addons.llm.vision.off': 'Ні',
'admin.addons.llm.vision.hintLocal': '«Автоматично» запитує сервер Ollama, чи читає ця модель зображення.',
'admin.addons.llm.vision.hintCloud': 'Для хмарної моделі «Автоматично» означає «ні». Виберіть «Так», якщо ця модель читає зображення.',
'admin.addons.enabled': 'Увімкнено',
'admin.addons.disabled': 'Вимкнено',
'admin.addons.type.trip': 'Поїздка',
+11
View File
@@ -154,6 +154,17 @@ const budget: TranslationStrings = {
'costs.receipts': 'Чеки',
'costs.receiptsTitle': 'Чеки та рахунки',
'costs.attachReceipt': 'Додати чек / рахунок',
'costs.scan.button': 'Сканувати чек',
'costs.scan.reading': 'Читання чека…',
'costs.scan.review': 'Перевірити витрату',
'costs.scan.nothingRead': 'Не вдалося прочитати чек із цієї фотографії.',
'costs.scan.failed': 'Не вдалося почати читання чека.',
'costs.scan.title': 'Сканувати чек',
'costs.scan.accepted': 'Фото одного чека (JPG, PNG або WEBP, до 10 МБ). Модель ШІ прочитає його у фоні, а потім ви перевірите витрату перед збереженням.',
'costs.scan.dropHere': 'Перетягніть сюди фото чека або натисніть, щоб вибрати чи зробити знімок',
'costs.scan.dropActive': 'Відпустіть фото, щоб відсканувати його',
'costs.scan.start': 'Сканувати',
'costs.scan.unsupported': 'Сканувати можна лише фото: JPG, PNG або WEBP.',
'costs.noReceipts': 'Немає доданих чеків',
'costs.deleteReceipt': 'Видалити чек',
'costs.viewReceipt': 'Переглянути чек',
+1
View File
@@ -128,6 +128,7 @@ const reservations: TranslationStrings = {
'reservations.import.dropHere': 'Перетягніть файли підтверджень бронювання сюди або натисніть для вибору',
'reservations.import.dropActive': 'Відпустіть файли для імпорту',
'reservations.import.acceptedFormats': 'Підтримуються: EML, PDF, PKPass, HTML, TXT (макс. 10 МБ кожен, до 5 файлів)',
'reservations.import.acceptedPhotos': 'Фотографії (JPG, PNG, WEBP) читає модель ШІ.',
'reservations.import.parsing': 'Обробка файлів…',
'reservations.import.previewHeading': 'Знайдено {count} бронювання(нь)',
'reservations.import.previewEmpty': 'З завантажених файлів не вдалося витягти бронювання.',
+2 -2
View File
@@ -398,9 +398,9 @@ const settings: TranslationStrings = {
'settings.aiParsing.apiKey': 'Ключ API',
'settings.aiParsing.apiKeyHint':
'Зберігається в зашифрованому вигляді. Залиште порожнім, щоб зберегти поточний ключ.',
'settings.aiParsing.multimodal': 'Надсилати документи як зображення',
'settings.aiParsing.multimodal': 'Модель читає зображення',
'settings.aiParsing.multimodalHint':
'Для моделей із підтримкою зображень — надсилає оригінальний PDF замість вилученого тексту.',
'Увімкніть для моделі, яка читає зображення, щоб фотографію можна було імпортувати чи відсканувати.',
'settings.aiParsing.toast.saved': 'Налаштування ШІ збережено',
'settings.aiParsing.toast.saveError': 'Не вдалося зберегти налаштування ШІ',
'settings.tabs.appearance': 'Appearance',
+5
View File
@@ -628,6 +628,11 @@ const admin: TranslationStrings = {
'Đọc các điểm lưu trú và lộ trình đã ghi từ phiên bản Dawarich mà mỗi người tự kết nối',
'admin.addons.catalog.llm_parsing.name': 'Phân tích bằng AI',
'admin.addons.catalog.llm_parsing.description': 'Đọc các đặt chỗ mà bộ phân tích tích hợp không hiểu, bằng mô hình AI bạn chọn',
'admin.addons.llm.vision.auto': 'Tự động',
'admin.addons.llm.vision.on': 'Có',
'admin.addons.llm.vision.off': 'Không',
'admin.addons.llm.vision.hintLocal': 'Tự động sẽ hỏi máy chủ Ollama xem mô hình này có đọc được hình ảnh không.',
'admin.addons.llm.vision.hintCloud': 'Với mô hình đám mây, Tự động nghĩa là không. Chọn Có nếu mô hình này đọc được hình ảnh.',
'admin.addons.enabled': 'Đã bật',
'admin.addons.disabled': 'Tắt',
'admin.addons.type.trip': 'Chuyến đi',

Some files were not shown because too many files have changed in this diff Show More