/** * Key-synced UI locale packs for apps/web/src/lib/i18n/messages/. * English (en.ts) is source of truth. Missing keys fall back at runtime via i18n.t(). * * Run: node apps/web/scripts/gen-locale-packs.mjs */ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { EXTRA as EXTRA_COMMON, SAME_AS_EN } from "./locale-extra.mjs"; import { EXTRA as EXTRA_ES } from "./locale-extra-es.mjs"; import { EXTRA as EXTRA_REST } from "./locale-extra-rest.mjs"; import { EXTRA as EXTRA_ADMIN } from "./locale-extra-admin.mjs"; import { EXTRA as EXTRA_CHROME } from "./locale-extra-chrome.mjs"; import { EXTRA as EXTRA_DEEP_ADMIN } from "./locale-extra-deep-admin.mjs"; import { EXTRA as EXTRA_BROWSER } from "./locale-extra-browser-leftovers.mjs"; import { EXTRA as EXTRA_MARKETING } from "./locale-extra-marketing.mjs"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const messagesDir = path.resolve(__dirname, "../src/lib/i18n/messages"); const enPath = path.join(messagesDir, "en.ts"); function parseMessageDict(source) { const dict = {}; const re = /"([^"\\]+)"\s*:\s*((?:"(?:\\.|[^"\\])*")|(?:`(?:\\.|[^`\\])*`))/gs; let m; while ((m = re.exec(source))) { const key = m[1]; const raw = m[2]; dict[key] = raw.startsWith("`") ? raw.slice(1, -1).replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\n/g, "\n") : JSON.parse(raw); } return dict; } function emitPack(exportName, comment, dict, keyOrder) { const lines = [ `import type { MessageDict } from "./types";`, ``, `/** ${comment} */`, `export const ${exportName}: MessageDict = {` ]; for (const key of keyOrder) { lines.push(`\t${JSON.stringify(key)}: ${JSON.stringify(dict[key])},`); } lines.push(`};`, ``); return lines.join("\n"); } /** Per-locale translations keyed by message id (same keys as en.ts). */ const PACKS = { es: { "app.name": "Descrybe", "app.home": "Inicio de Descrybe", "common.cancel": "Cancelar", "common.save": "Guardar cambios", "common.saveShort": "Guardar", "common.continue": "Continuar", "common.open": "Abrir", "common.markDone": "Marcar como hecho", "common.viewAll": "Ver todo", "common.close": "Cerrar", "a11y.skipToContent": "Saltar al contenido", "theme.switchToDark": "Cambiar a tema oscuro", "theme.switchToLight": "Cambiar a tema claro", "header.signOut": "Cerrar sesión", "header.signingOut": "Cerrando sesión…", "status.emDash": "—", "status.pending": "Pendiente", "nav.section.overview": "Resumen", "nav.section.catalog": "Catálogo", "nav.section.feeds": "Feeds", "nav.section.stores": "Tiendas", "nav.section.processing": "Procesamiento", "nav.section.marketing": "Marketing", "nav.section.integrations": "Integraciones", "nav.section.account": "Cuenta", "nav.section.platform": "Plataforma", "nav.dashboard": "Panel", "nav.products": "Productos", "nav.categories": "Categorías", "nav.attributes": "Atributos", "nav.fields": "Campos", "nav.feeds": "Feeds", "nav.exports": "Exportaciones", "nav.stores": "Tiendas", "nav.jobs": "Trabajos", "nav.campaigns": "Campañas", "nav.calendar": "Calendario", "nav.seo": "SEO", "nav.brand": "Marca", "nav.reviews": "Reseñas", "nav.ai": "IA", "nav.email": "Correo", "nav.billing": "Facturación", "nav.settings": "Configuración", "nav.support": "Soporte", "nav.admin": "Admin", "nav.main": "Navegación principal", "nav.sidebar": "Barra lateral de la app", "nav.close": "Cerrar navegación", "nav.closeMenu": "Cerrar menú", "nav.open": "Abrir navegación", "nav.commandPalette": "Abrir paleta de comandos", "locale.switcher": "Idioma de la interfaz", "locale.menu": "Elegir idioma de la interfaz", "locale.label": "Idioma del panel", "locale.help": "Cambia las etiquetas de la navegación y la configuración. El idioma del contenido generado se define por separado en Empresa.", "settings.contentLanguage": "Idioma del contenido", "settings.contentLanguageHelp": "Idioma usado para títulos de producto, descripciones y otro contenido generado", "settings.tab.profile": "Perfil", "settings.tab.company": "Empresa", "settings.tab.alerts": "Alertas", "settings.tab.apiKeys": "Claves API", "settings.tab.team": "Equipo", "settings.title": "Configuración", "settings.description": "Cuenta, empresa, claves API y equipo.", "dashboard.demoSandbox": "Zona de pruebas demo", "dashboard.demoEmptyTitle": "La zona de pruebas demo está vacía", "dashboard.overviewTitle": "Resumen", "dashboard.quickLinks": "Enlaces rápidos", "dashboard.whatsNew": "Novedades", "dashboard.startTutorial": "Iniciar tutorial", "dashboard.connectFeed": "Conectar un feed", "dashboard.workflowTitle": "Flujo del catálogo", "dashboard.recentActivity": "Actividad reciente", "dashboard.loadFailed": "No se pudo cargar el panel", "dashboard.workspaceFallback": "Este espacio de trabajo", "dashboard.jobFallback": "Trabajo {id}", "dashboard.workflow.feeds.connect": "Conectar importación", "dashboard.workflow.products.build": "Crear catálogo", "dashboard.workflow.products.count": "{count} en el catálogo", "dashboard.workflow.process": "Procesar", "dashboard.workflow.processActive": "{count} activos", "dashboard.workflow.processWaiting": "{count} en espera", "dashboard.workflow.processDone": "{count} listos", "dashboard.workflow.processRun": "Ejecutar trabajos de IA", "dashboard.workflow.export": "Exportar", "dashboard.workflow.exportReady": "Plantillas y descarga", "dashboard.workflow.exportMap": "Mapear y exportar", "activation.title": "Primeros pasos", "activation.description": "Ruta de valor inicial desde tu espacio de trabajo: activar campos → conectar un origen → mapear → sincronizar muestra → procesar → exportar. El recorrido de demostración explica estas pantallas sin cambiar el progreso de la lista.", "activation.dismiss": "Descartar lista", "activation.progress": "{done} de {total} completados", "activation.stepsLabel": "Pasos de activación", "activation.pausedTitle": "Primeros pasos en pausa", "activation.pausedBody": "Reanuda la lista cuando quieras — desde activar campos hasta exportar.", "activation.resume": "Reanudar lista", "stats.products": "Productos", "stats.categories": "Categorías", "stats.attributes": "Atributos", "stats.feeds": "Feeds", "stats.credits": "Créditos", "stats.openCatalog": "Abrir catálogo", "stats.productsHint": "{processed} procesados · {unprocessed} sin procesar", "stats.catalogTree": "Árbol del catálogo", "stats.attributeLibrary": "Biblioteca de atributos", "stats.importSources": "Orígenes de importación", "stats.payAsYouGo": "Pago por uso", "stats.walletBilling": "Monedero · Facturación", "stats.enterpriseBilling": "Enterprise · Facturación", "stats.usedBilling": "{used} usados · Facturación", "processing.jobStatus.processing": "Procesando", "processing.jobStatus.completed": "Completado", "processing.jobStatus.failed": "Fallido", "processing.jobStatus.cancelled": "Cancelado", "processing.jobStatus.pending": "Pendiente", "processing.jobStatus.queued": "En cola", "processing.jobStatus.skipped": "Omitido", "processing.jobStatus.unknown": "Desconocido", "processing.step.normalize": "Normalizar", "processing.step.parse_specs": "Analizar especificaciones", "processing.step.fill_fields": "Completar campos", "processing.step.eprel": "EPREL", "processing.step.ai_enhance": "Mejora con IA", "errors.requestFailed": "La solicitud falló", "errors.maintenance": "El sistema está en mantenimiento. Inténtalo más tarde.", "errors.readOnly": "El sistema está en modo de solo lectura. Los cambios están temporalmente deshabilitados.", "errors.companyAdminDenied": "Solo los administradores de la empresa pueden {action}. Pide ayuda a un administrador.", "errors.companyAdminDenied.actionDefault": "hacer esto", "errors.couldNotUpdateLanguage": "No se pudo actualizar el idioma", "toast.support.replyTitle": "Respuesta de soporte", "toast.support.replyBody": "El equipo respondió a tu ticket de soporte.", "toast.support.replyRe": "Re: {subject}", "toast.support.statusTitle": "Estado del ticket actualizado", "toast.support.statusBody": "El estado de tu ticket de soporte cambió.", "toast.support.updateTitle": "Actualización de soporte", "flash.contentLanguageUpdated": "Idioma del contenido actualizado." }, fr: { "app.name": "Descrybe", "app.home": "Accueil Descrybe", "common.cancel": "Annuler", "common.save": "Enregistrer les modifications", "common.saveShort": "Enregistrer", "common.continue": "Continuer", "common.open": "Ouvrir", "common.markDone": "Marquer comme terminé", "common.viewAll": "Tout voir", "common.close": "Fermer", "a11y.skipToContent": "Aller au contenu", "theme.switchToDark": "Passer au thème sombre", "theme.switchToLight": "Passer au thème clair", "header.signOut": "Se déconnecter", "header.signingOut": "Déconnexion…", "status.emDash": "—", "status.pending": "En attente", "nav.section.overview": "Aperçu", "nav.section.catalog": "Catalogue", "nav.section.feeds": "Flux", "nav.section.stores": "Boutiques", "nav.section.processing": "Traitement", "nav.section.marketing": "Marketing", "nav.section.integrations": "Intégrations", "nav.section.account": "Compte", "nav.section.platform": "Plateforme", "nav.dashboard": "Tableau de bord", "nav.products": "Produits", "nav.categories": "Catégories", "nav.attributes": "Attributs", "nav.fields": "Champs", "nav.feeds": "Flux", "nav.exports": "Exportations", "nav.stores": "Boutiques", "nav.jobs": "Tâches", "nav.campaigns": "Campagnes", "nav.calendar": "Calendrier", "nav.seo": "SEO", "nav.brand": "Marque", "nav.reviews": "Avis", "nav.ai": "IA", "nav.email": "E-mail", "nav.billing": "Facturation", "nav.settings": "Paramètres", "nav.support": "Assistance", "nav.admin": "Admin", "nav.main": "Navigation principale", "nav.sidebar": "Barre latérale de l'application", "nav.close": "Fermer la navigation", "nav.closeMenu": "Fermer le menu", "nav.open": "Ouvrir la navigation", "nav.commandPalette": "Ouvrir la palette de commandes", "locale.switcher": "Langue de l'interface", "locale.menu": "Choisir la langue de l'interface", "locale.label": "Langue du tableau de bord", "locale.help": "Modifie les libellés de la navigation et des paramètres. La langue du contenu généré se règle séparément sous Entreprise.", "settings.contentLanguage": "Langue du contenu", "settings.contentLanguageHelp": "Langue utilisée pour les titres de produits, descriptions et autres contenus générés", "settings.tab.profile": "Profil", "settings.tab.company": "Entreprise", "settings.tab.alerts": "Alertes", "settings.tab.apiKeys": "Clés API", "settings.tab.team": "Équipe", "settings.title": "Paramètres", "settings.description": "Compte, entreprise, clés API et équipe.", "dashboard.demoSandbox": "Bac à sable démo", "dashboard.demoEmptyTitle": "Le bac à sable démo est vide", "dashboard.overviewTitle": "Aperçu", "dashboard.quickLinks": "Liens rapides", "dashboard.whatsNew": "Nouveautés", "dashboard.startTutorial": "Lancer le tutoriel", "dashboard.connectFeed": "Connecter un flux", "dashboard.workflowTitle": "Flux catalogue", "dashboard.recentActivity": "Activité récente", "dashboard.loadFailed": "Échec du chargement du tableau de bord", "dashboard.workspaceFallback": "Cet espace de travail", "dashboard.jobFallback": "Tâche {id}", "dashboard.workflow.feeds.connect": "Connecter l'import", "dashboard.workflow.products.build": "Construire le catalogue", "dashboard.workflow.products.count": "{count} dans le catalogue", "dashboard.workflow.process": "Traiter", "dashboard.workflow.processActive": "{count} actifs", "dashboard.workflow.processWaiting": "{count} en attente", "dashboard.workflow.processDone": "{count} terminés", "dashboard.workflow.processRun": "Lancer les tâches IA", "dashboard.workflow.export": "Exporter", "dashboard.workflow.exportReady": "Modèles et téléchargement", "dashboard.workflow.exportMap": "Mapper puis exporter", "activation.title": "Premiers pas", "activation.description": "Parcours de valeur initial depuis votre espace de travail : activer les champs → connecter une source → mapper → synchroniser un échantillon → traiter → exporter. Le parcours démo explique ces écrans sans modifier la progression de la checklist.", "activation.dismiss": "Masquer la checklist", "activation.progress": "{done} sur {total} terminés", "activation.stepsLabel": "Étapes d'activation", "activation.pausedTitle": "Premiers pas en pause", "activation.pausedBody": "Reprenez la checklist à tout moment — de l'activation des champs jusqu'à l'export.", "activation.resume": "Reprendre la checklist", "stats.products": "Produits", "stats.categories": "Catégories", "stats.attributes": "Attributs", "stats.feeds": "Flux", "stats.credits": "Crédits", "stats.openCatalog": "Ouvrir le catalogue", "stats.productsHint": "{processed} traités · {unprocessed} non traités", "stats.catalogTree": "Arborescence du catalogue", "stats.attributeLibrary": "Bibliothèque d'attributs", "stats.importSources": "Sources d'import", "stats.payAsYouGo": "Paiement à l'usage", "stats.walletBilling": "Portefeuille · Facturation", "stats.enterpriseBilling": "Enterprise · Facturation", "stats.usedBilling": "{used} utilisés · Facturation", "processing.jobStatus.processing": "En cours", "processing.jobStatus.completed": "Terminé", "processing.jobStatus.failed": "Échoué", "processing.jobStatus.cancelled": "Annulé", "processing.jobStatus.pending": "En attente", "processing.jobStatus.queued": "En file", "processing.jobStatus.skipped": "Ignoré", "processing.jobStatus.unknown": "Inconnu", "processing.step.normalize": "Normaliser", "processing.step.parse_specs": "Analyser les specs", "processing.step.fill_fields": "Remplir les champs", "processing.step.eprel": "EPREL", "processing.step.ai_enhance": "Amélioration IA", "errors.requestFailed": "Échec de la requête", "errors.maintenance": "Le système est en maintenance. Réessayez plus tard.", "errors.readOnly": "Le système est en mode lecture seule. Les modifications sont temporairement désactivées.", "errors.companyAdminDenied": "Seuls les administrateurs de l'entreprise peuvent {action}. Demandez de l'aide à un administrateur.", "errors.companyAdminDenied.actionDefault": "faire ceci", "errors.couldNotUpdateLanguage": "Impossible de mettre à jour la langue", "toast.support.replyTitle": "Réponse du support", "toast.support.replyBody": "L'équipe a répondu à votre ticket de support.", "toast.support.replyRe": "Re: {subject}", "toast.support.statusTitle": "Statut du ticket mis à jour", "toast.support.statusBody": "Le statut de votre ticket de support a changé.", "toast.support.updateTitle": "Mise à jour du support", "flash.contentLanguageUpdated": "Langue du contenu mise à jour." }, de: { "app.name": "Descrybe", "app.home": "Descrybe-Startseite", "common.cancel": "Abbrechen", "common.save": "Änderungen speichern", "common.saveShort": "Speichern", "common.continue": "Weiter", "common.open": "Öffnen", "common.markDone": "Als erledigt markieren", "common.viewAll": "Alle anzeigen", "common.close": "Schließen", "a11y.skipToContent": "Zum Inhalt springen", "theme.switchToDark": "Zum dunklen Design wechseln", "theme.switchToLight": "Zum hellen Design wechseln", "header.signOut": "Abmelden", "header.signingOut": "Abmelden…", "status.emDash": "—", "status.pending": "Ausstehend", "nav.section.overview": "Übersicht", "nav.section.catalog": "Katalog", "nav.section.feeds": "Feeds", "nav.section.stores": "Shops", "nav.section.processing": "Verarbeitung", "nav.section.marketing": "Marketing", "nav.section.integrations": "Integrationen", "nav.section.account": "Konto", "nav.section.platform": "Plattform", "nav.dashboard": "Übersicht", "nav.products": "Produkte", "nav.categories": "Kategorien", "nav.attributes": "Attribute", "nav.fields": "Felder", "nav.feeds": "Feeds", "nav.exports": "Exporte", "nav.stores": "Shops", "nav.jobs": "Aufträge", "nav.campaigns": "Kampagnen", "nav.calendar": "Kalender", "nav.seo": "SEO", "nav.brand": "Marke", "nav.reviews": "Bewertungen", "nav.ai": "KI", "nav.email": "E-Mail", "nav.billing": "Abrechnung", "nav.settings": "Einstellungen", "nav.support": "Hilfe", "nav.admin": "Admin", "nav.main": "Hauptnavigation", "nav.sidebar": "App-Seitenleiste", "nav.close": "Navigation schließen", "nav.closeMenu": "Menü schließen", "nav.open": "Navigation öffnen", "nav.commandPalette": "Befehlspalette öffnen", "locale.switcher": "Oberflächensprache", "locale.menu": "Oberflächensprache wählen", "locale.label": "Dashboard-Sprache", "locale.help": "Ändert Beschriftungen in Navigation und Einstellungen. Die Sprache für generierte Inhalte wird separat unter Unternehmen festgelegt.", "settings.contentLanguage": "Inhaltssprache", "settings.contentLanguageHelp": "Sprache für Produkttitel, Beschreibungen und andere generierte Inhalte", "settings.tab.profile": "Profil", "settings.tab.company": "Unternehmen", "settings.tab.alerts": "Benachrichtigungen", "settings.tab.apiKeys": "API-Schlüssel", "settings.tab.team": "Team", "settings.title": "Einstellungen", "settings.description": "Konto, Unternehmen, API-Schlüssel und Team.", "dashboard.demoSandbox": "Demo-Sandbox", "dashboard.demoEmptyTitle": "Demo-Sandbox ist leer", "dashboard.overviewTitle": "Übersicht", "dashboard.quickLinks": "Schnelllinks", "dashboard.whatsNew": "Neuigkeiten", "dashboard.startTutorial": "Tutorial starten", "dashboard.connectFeed": "Feed verbinden", "dashboard.workflowTitle": "Katalog-Workflow", "dashboard.recentActivity": "Letzte Aktivität", "dashboard.loadFailed": "Dashboard konnte nicht geladen werden", "dashboard.workspaceFallback": "Dieser Arbeitsbereich", "dashboard.jobFallback": "Auftrag {id}", "dashboard.workflow.feeds.connect": "Import verbinden", "dashboard.workflow.products.build": "Katalog aufbauen", "dashboard.workflow.products.count": "{count} im Katalog", "dashboard.workflow.process": "Verarbeiten", "dashboard.workflow.processActive": "{count} aktiv", "dashboard.workflow.processWaiting": "{count} wartend", "dashboard.workflow.processDone": "{count} erledigt", "dashboard.workflow.processRun": "KI-Jobs ausführen", "dashboard.workflow.export": "Exportieren", "dashboard.workflow.exportReady": "Vorlagen & Download", "dashboard.workflow.exportMap": "Zuordnen dann exportieren", "activation.title": "Erste Schritte", "activation.description": "Erster Wertpfad aus Ihrem Arbeitsbereich: Felder aktivieren → Quelle verbinden → zuordnen → Stichprobe synchronisieren → verarbeiten → exportieren. Die Demo-Tour erklärt diese Bildschirme, ohne den Checklistenfortschritt zu ändern.", "activation.dismiss": "Checkliste ausblenden", "activation.progress": "{done} von {total} erledigt", "activation.stepsLabel": "Aktivierungsschritte", "activation.pausedTitle": "Erste Schritte pausiert", "activation.pausedBody": "Setzen Sie die Checkliste jederzeit fort — von Feldern aktivieren bis Export.", "activation.resume": "Checkliste fortsetzen", "stats.products": "Produkte", "stats.categories": "Kategorien", "stats.attributes": "Attribute", "stats.feeds": "Feeds", "stats.credits": "Guthaben", "stats.openCatalog": "Katalog öffnen", "stats.productsHint": "{processed} verarbeitet · {unprocessed} unverarbeitet", "stats.catalogTree": "Katalogbaum", "stats.attributeLibrary": "Attributbibliothek", "stats.importSources": "Importquellen", "stats.payAsYouGo": "Nutzung nach Verbrauch", "stats.walletBilling": "Wallet · Abrechnung", "stats.enterpriseBilling": "Enterprise · Abrechnung", "stats.usedBilling": "{used} verbraucht · Abrechnung", "processing.jobStatus.processing": "Verarbeitung", "processing.jobStatus.completed": "Abgeschlossen", "processing.jobStatus.failed": "Fehlgeschlagen", "processing.jobStatus.cancelled": "Abgebrochen", "processing.jobStatus.pending": "Ausstehend", "processing.jobStatus.queued": "In Warteschlange", "processing.jobStatus.skipped": "Übersprungen", "processing.jobStatus.unknown": "Unbekannt", "processing.step.normalize": "Normalisieren", "processing.step.parse_specs": "Specs parsen", "processing.step.fill_fields": "Felder füllen", "processing.step.eprel": "EPREL", "processing.step.ai_enhance": "KI-Verbesserung", "errors.requestFailed": "Anfrage fehlgeschlagen", "errors.maintenance": "Das System ist in Wartung. Versuchen Sie es später erneut.", "errors.readOnly": "Das System ist im Nur-Lesen-Modus. Änderungen sind vorübergehend deaktiviert.", "errors.companyAdminDenied": "Nur Unternehmens-Admins können {action}. Bitten Sie einen Admin um Hilfe.", "errors.companyAdminDenied.actionDefault": "dies tun", "errors.couldNotUpdateLanguage": "Sprache konnte nicht aktualisiert werden", "toast.support.replyTitle": "Support-Antwort", "toast.support.replyBody": "Das Team hat auf Ihr Support-Ticket geantwortet.", "toast.support.replyRe": "Re: {subject}", "toast.support.statusTitle": "Ticketstatus aktualisiert", "toast.support.statusBody": "Der Status Ihres Support-Tickets hat sich geändert.", "toast.support.updateTitle": "Support-Update", "flash.contentLanguageUpdated": "Inhaltssprache aktualisiert." }, it: { "app.name": "Descrybe", "app.home": "Home Descrybe", "common.cancel": "Annulla", "common.save": "Salva modifiche", "common.saveShort": "Salva", "common.continue": "Continua", "common.open": "Apri", "common.markDone": "Segna come fatto", "common.viewAll": "Vedi tutto", "common.close": "Chiudi", "a11y.skipToContent": "Vai al contenuto", "theme.switchToDark": "Passa al tema scuro", "theme.switchToLight": "Passa al tema chiaro", "header.signOut": "Esci", "header.signingOut": "Disconnessione…", "status.emDash": "—", "status.pending": "In sospeso", "nav.section.overview": "Panoramica", "nav.section.catalog": "Catalogo", "nav.section.feeds": "Feed", "nav.section.stores": "Negozi", "nav.section.processing": "Elaborazione", "nav.section.marketing": "Marketing", "nav.section.integrations": "Integrazioni", "nav.section.account": "Account", "nav.section.platform": "Piattaforma", "nav.dashboard": "Cruscotto", "nav.products": "Prodotti", "nav.categories": "Categorie", "nav.attributes": "Attributi", "nav.fields": "Campi", "nav.feeds": "Feed", "nav.exports": "Esportazioni", "nav.stores": "Negozi", "nav.jobs": "Processi", "nav.campaigns": "Campagne", "nav.calendar": "Calendario", "nav.seo": "SEO", "nav.brand": "Marchio", "nav.reviews": "Recensioni", "nav.ai": "IA", "nav.email": "Email", "nav.billing": "Fatturazione", "nav.settings": "Impostazioni", "nav.support": "Supporto", "nav.admin": "Admin", "nav.main": "Navigazione principale", "nav.sidebar": "Barra laterale app", "nav.close": "Chiudi navigazione", "nav.closeMenu": "Chiudi menu", "nav.open": "Apri navigazione", "nav.commandPalette": "Apri palette comandi", "locale.switcher": "Lingua dell'interfaccia", "locale.menu": "Scegli la lingua dell'interfaccia", "locale.label": "Lingua della dashboard", "locale.help": "Modifica le etichette di navigazione e impostazioni. La lingua dei contenuti generati si imposta separatamente in Azienda.", "settings.contentLanguage": "Lingua dei contenuti", "settings.contentLanguageHelp": "Lingua usata per titoli prodotto, descrizioni e altri contenuti generati", "settings.tab.profile": "Profilo", "settings.tab.company": "Azienda", "settings.tab.alerts": "Avvisi", "settings.tab.apiKeys": "Chiavi API", "settings.tab.team": "Team", "settings.title": "Impostazioni", "settings.description": "Account, azienda, chiavi API e team.", "dashboard.demoSandbox": "Sandbox demo", "dashboard.demoEmptyTitle": "La sandbox demo è vuota", "dashboard.overviewTitle": "Panoramica", "dashboard.quickLinks": "Collegamenti rapidi", "dashboard.whatsNew": "Novità", "dashboard.startTutorial": "Avvia tutorial", "dashboard.connectFeed": "Collega un feed", "dashboard.workflowTitle": "Flusso catalogo", "dashboard.recentActivity": "Attività recente", "dashboard.loadFailed": "Impossibile caricare la dashboard", "dashboard.workspaceFallback": "Questo spazio di lavoro", "dashboard.jobFallback": "Processo {id}", "dashboard.workflow.feeds.connect": "Collega importazione", "dashboard.workflow.products.build": "Crea catalogo", "dashboard.workflow.products.count": "{count} nel catalogo", "dashboard.workflow.process": "Elabora", "dashboard.workflow.processActive": "{count} attivi", "dashboard.workflow.processWaiting": "{count} in attesa", "dashboard.workflow.processDone": "{count} completati", "dashboard.workflow.processRun": "Esegui job IA", "dashboard.workflow.export": "Esporta", "dashboard.workflow.exportReady": "Modelli e download", "dashboard.workflow.exportMap": "Mappa poi esporta", "activation.title": "Per iniziare", "activation.description": "Percorso di valore iniziale dal tuo spazio di lavoro: abilita campi → collega un'origine → mappa → sincronizza campione → elabora → esporta. Il tour demo spiega queste schermate senza modificare l'avanzamento della checklist.", "activation.dismiss": "Nascondi checklist", "activation.progress": "{done} di {total} completati", "activation.stepsLabel": "Passaggi di attivazione", "activation.pausedTitle": "Per iniziare in pausa", "activation.pausedBody": "Riprendi la checklist in qualsiasi momento — dall'abilitazione dei campi all'esportazione.", "activation.resume": "Riprendi checklist", "stats.products": "Prodotti", "stats.categories": "Categorie", "stats.attributes": "Attributi", "stats.feeds": "Feed", "stats.credits": "Crediti", "stats.openCatalog": "Apri catalogo", "stats.productsHint": "{processed} elaborati · {unprocessed} non elaborati", "stats.catalogTree": "Albero catalogo", "stats.attributeLibrary": "Libreria attributi", "stats.importSources": "Origini di importazione", "stats.payAsYouGo": "Pagamento a consumo", "stats.walletBilling": "Wallet · Fatturazione", "stats.enterpriseBilling": "Enterprise · Fatturazione", "stats.usedBilling": "{used} usati · Fatturazione", "processing.jobStatus.processing": "Elaborazione", "processing.jobStatus.completed": "Completato", "processing.jobStatus.failed": "Non riuscito", "processing.jobStatus.cancelled": "Annullato", "processing.jobStatus.pending": "In sospeso", "processing.jobStatus.queued": "In coda", "processing.jobStatus.skipped": "Saltato", "processing.jobStatus.unknown": "Sconosciuto", "processing.step.normalize": "Normalizza", "processing.step.parse_specs": "Analizza specifiche", "processing.step.fill_fields": "Compila campi", "processing.step.eprel": "EPREL", "processing.step.ai_enhance": "Miglioramento IA", "errors.requestFailed": "Richiesta non riuscita", "errors.maintenance": "Il sistema è in manutenzione. Riprova più tardi.", "errors.readOnly": "Il sistema è in modalità sola lettura. Le modifiche sono temporaneamente disabilitate.", "errors.companyAdminDenied": "Solo gli amministratori dell'azienda possono {action}. Chiedi aiuto a un amministratore.", "errors.companyAdminDenied.actionDefault": "fare questo", "errors.couldNotUpdateLanguage": "Impossibile aggiornare la lingua", "toast.support.replyTitle": "Risposta del supporto", "toast.support.replyBody": "Lo staff ha risposto al tuo ticket di supporto.", "toast.support.replyRe": "Re: {subject}", "toast.support.statusTitle": "Stato ticket aggiornato", "toast.support.statusBody": "Lo stato del tuo ticket di supporto è cambiato.", "toast.support.updateTitle": "Aggiornamento supporto", "flash.contentLanguageUpdated": "Lingua dei contenuti aggiornata." }, pt: { "app.name": "Descrybe", "app.home": "Início Descrybe", "common.cancel": "Cancelar", "common.save": "Guardar alterações", "common.saveShort": "Guardar", "common.continue": "Continuar", "common.open": "Abrir", "common.markDone": "Marcar como concluído", "common.viewAll": "Ver tudo", "common.close": "Fechar", "a11y.skipToContent": "Saltar para o conteúdo", "theme.switchToDark": "Mudar para tema escuro", "theme.switchToLight": "Mudar para tema claro", "header.signOut": "Terminar sessão", "header.signingOut": "A terminar sessão…", "status.emDash": "—", "status.pending": "Pendente", "nav.section.overview": "Visão geral", "nav.section.catalog": "Catálogo", "nav.section.feeds": "Feeds", "nav.section.stores": "Lojas", "nav.section.processing": "Processamento", "nav.section.marketing": "Marketing", "nav.section.integrations": "Integrações", "nav.section.account": "Conta", "nav.section.platform": "Plataforma", "nav.dashboard": "Painel", "nav.products": "Produtos", "nav.categories": "Categorias", "nav.attributes": "Atributos", "nav.fields": "Campos", "nav.feeds": "Feeds", "nav.exports": "Exportações", "nav.stores": "Lojas", "nav.jobs": "Tarefas", "nav.campaigns": "Campanhas", "nav.calendar": "Calendário", "nav.seo": "SEO", "nav.brand": "Marca", "nav.reviews": "Avaliações", "nav.ai": "IA", "nav.email": "E-mail", "nav.billing": "Faturação", "nav.settings": "Definições", "nav.support": "Suporte", "nav.admin": "Admin", "nav.main": "Navegação principal", "nav.sidebar": "Barra lateral da app", "nav.close": "Fechar navegação", "nav.closeMenu": "Fechar menu", "nav.open": "Abrir navegação", "nav.commandPalette": "Abrir paleta de comandos", "locale.switcher": "Idioma da interface", "locale.menu": "Escolher idioma da interface", "locale.label": "Idioma do painel", "locale.help": "Altera as etiquetas da navegação e das definições. O idioma do conteúdo gerado é definido separadamente em Empresa.", "settings.contentLanguage": "Idioma do conteúdo", "settings.contentLanguageHelp": "Idioma usado para títulos de produto, descrições e outro conteúdo gerado", "settings.tab.profile": "Perfil", "settings.tab.company": "Empresa", "settings.tab.alerts": "Alertas", "settings.tab.apiKeys": "Chaves API", "settings.tab.team": "Equipa", "settings.title": "Definições", "settings.description": "Conta, empresa, chaves API e equipa.", "dashboard.demoSandbox": "Sandbox de demonstração", "dashboard.demoEmptyTitle": "A sandbox de demonstração está vazia", "dashboard.overviewTitle": "Visão geral", "dashboard.quickLinks": "Ligações rápidas", "dashboard.whatsNew": "Novidades", "dashboard.startTutorial": "Iniciar tutorial", "dashboard.connectFeed": "Ligar um feed", "dashboard.workflowTitle": "Fluxo do catálogo", "dashboard.recentActivity": "Atividade recente", "dashboard.loadFailed": "Falha ao carregar o painel", "dashboard.workspaceFallback": "Este espaço de trabalho", "dashboard.jobFallback": "Tarefa {id}", "dashboard.workflow.feeds.connect": "Ligar importação", "dashboard.workflow.products.build": "Criar catálogo", "dashboard.workflow.products.count": "{count} no catálogo", "dashboard.workflow.process": "Processar", "dashboard.workflow.processActive": "{count} ativos", "dashboard.workflow.processWaiting": "{count} em espera", "dashboard.workflow.processDone": "{count} concluídos", "dashboard.workflow.processRun": "Executar tarefas de IA", "dashboard.workflow.export": "Exportar", "dashboard.workflow.exportReady": "Modelos e transferência", "dashboard.workflow.exportMap": "Mapear e exportar", "activation.title": "Começar", "activation.description": "Caminho de valor inicial a partir do seu espaço de trabalho: ativar campos → ligar uma origem → mapear → sincronizar amostra → processar → exportar. O tour de demonstração explica estes ecrãs sem alterar o progresso da lista.", "activation.dismiss": "Dispensar lista", "activation.progress": "{done} de {total} concluídos", "activation.stepsLabel": "Passos de ativação", "activation.pausedTitle": "Começar em pausa", "activation.pausedBody": "Retome a lista quando quiser — desde ativar campos até exportar.", "activation.resume": "Retomar lista", "stats.products": "Produtos", "stats.categories": "Categorias", "stats.attributes": "Atributos", "stats.feeds": "Feeds", "stats.credits": "Créditos", "stats.openCatalog": "Abrir catálogo", "stats.productsHint": "{processed} processados · {unprocessed} não processados", "stats.catalogTree": "Árvore do catálogo", "stats.attributeLibrary": "Biblioteca de atributos", "stats.importSources": "Origens de importação", "stats.payAsYouGo": "Pagamento conforme o uso", "stats.walletBilling": "Carteira · Faturação", "stats.enterpriseBilling": "Enterprise · Faturação", "stats.usedBilling": "{used} usados · Faturação", "processing.jobStatus.processing": "A processar", "processing.jobStatus.completed": "Concluído", "processing.jobStatus.failed": "Falhou", "processing.jobStatus.cancelled": "Cancelado", "processing.jobStatus.pending": "Pendente", "processing.jobStatus.queued": "Em fila", "processing.jobStatus.skipped": "Ignorado", "processing.jobStatus.unknown": "Desconhecido", "processing.step.normalize": "Normalizar", "processing.step.parse_specs": "Analisar especificações", "processing.step.fill_fields": "Preencher campos", "processing.step.eprel": "EPREL", "processing.step.ai_enhance": "Melhoria com IA", "errors.requestFailed": "Pedido falhou", "errors.maintenance": "O sistema está em manutenção. Tente novamente mais tarde.", "errors.readOnly": "O sistema está em modo só de leitura. As alterações estão temporariamente desativadas.", "errors.companyAdminDenied": "Apenas administradores da empresa podem {action}. Peça ajuda a um administrador.", "errors.companyAdminDenied.actionDefault": "fazer isto", "errors.couldNotUpdateLanguage": "Não foi possível atualizar o idioma", "toast.support.replyTitle": "Resposta de suporte", "toast.support.replyBody": "A equipa respondeu ao seu ticket de suporte.", "toast.support.replyRe": "Re: {subject}", "toast.support.statusTitle": "Estado do ticket atualizado", "toast.support.statusBody": "O estado do seu ticket de suporte alterou-se.", "toast.support.updateTitle": "Atualização de suporte", "flash.contentLanguageUpdated": "Idioma do conteúdo atualizado." }, nl: { "app.name": "Descrybe", "app.home": "Descrybe-startpagina", "common.cancel": "Annuleren", "common.save": "Wijzigingen opslaan", "common.saveShort": "Opslaan", "common.continue": "Doorgaan", "common.open": "Openen", "common.markDone": "Markeren als gedaan", "common.viewAll": "Alles bekijken", "common.close": "Sluiten", "a11y.skipToContent": "Ga naar inhoud", "theme.switchToDark": "Overschakelen naar donker thema", "theme.switchToLight": "Overschakelen naar licht thema", "header.signOut": "Uitloggen", "header.signingOut": "Bezig met uitloggen…", "status.emDash": "—", "status.pending": "In behandeling", "nav.section.overview": "Overzicht", "nav.section.catalog": "Catalogus", "nav.section.feeds": "Feeds", "nav.section.stores": "Winkels", "nav.section.processing": "Verwerking", "nav.section.marketing": "Marketing", "nav.section.integrations": "Integraties", "nav.section.account": "Account", "nav.section.platform": "Platform", "nav.dashboard": "Overzicht", "nav.products": "Producten", "nav.categories": "Categorieën", "nav.attributes": "Kenmerken", "nav.fields": "Velden", "nav.feeds": "Feeds", "nav.exports": "Exporten", "nav.stores": "Winkels", "nav.jobs": "Taken", "nav.campaigns": "Campagnes", "nav.calendar": "Kalender", "nav.seo": "SEO", "nav.brand": "Merk", "nav.reviews": "Beoordelingen", "nav.ai": "AI", "nav.email": "E-mail", "nav.billing": "Facturering", "nav.settings": "Instellingen", "nav.support": "Ondersteuning", "nav.admin": "Admin", "nav.main": "Hoofdnavigatie", "nav.sidebar": "App-zijbalk", "nav.close": "Navigatie sluiten", "nav.closeMenu": "Menu sluiten", "nav.open": "Navigatie openen", "nav.commandPalette": "Opdrachtpalet openen", "locale.switcher": "Interfacetaal", "locale.menu": "Kies interfacetaal", "locale.label": "Dashboardtaal", "locale.help": "Wijzigt labels in navigatie en instellingen. De taal voor gegenereerde content stelt u apart in onder Bedrijf.", "settings.contentLanguage": "Contenttaal", "settings.contentLanguageHelp": "Taal voor producttitels, beschrijvingen en andere gegenereerde content", "settings.tab.profile": "Profiel", "settings.tab.company": "Bedrijf", "settings.tab.alerts": "Meldingen", "settings.tab.apiKeys": "API-sleutels", "settings.tab.team": "Team", "settings.title": "Instellingen", "settings.description": "Account, bedrijf, API-sleutels en team.", "dashboard.demoSandbox": "Demo-sandbox", "dashboard.demoEmptyTitle": "Demo-sandbox is leeg", "dashboard.overviewTitle": "Overzicht", "dashboard.quickLinks": "Snelkoppelingen", "dashboard.whatsNew": "Wat is nieuw", "dashboard.startTutorial": "Tutorial starten", "dashboard.connectFeed": "Feed koppelen", "dashboard.workflowTitle": "Catalogusworkflow", "dashboard.recentActivity": "Recente activiteit", "dashboard.loadFailed": "Dashboard laden mislukt", "dashboard.workspaceFallback": "Deze werkruimte", "dashboard.jobFallback": "Taak {id}", "dashboard.workflow.feeds.connect": "Import koppelen", "dashboard.workflow.products.build": "Catalogus opbouwen", "dashboard.workflow.products.count": "{count} in catalogus", "dashboard.workflow.process": "Verwerken", "dashboard.workflow.processActive": "{count} actief", "dashboard.workflow.processWaiting": "{count} wachtend", "dashboard.workflow.processDone": "{count} klaar", "dashboard.workflow.processRun": "AI-jobs uitvoeren", "dashboard.workflow.export": "Exporteren", "dashboard.workflow.exportReady": "Sjablonen & download", "dashboard.workflow.exportMap": "Mappen en exporteren", "activation.title": "Aan de slag", "activation.description": "Eerste waardepad vanuit uw werkruimte: velden inschakelen → bron koppelen → mappen → steekproef synchroniseren → verwerken → exporteren. De demotour legt deze schermen uit zonder de checklistvoortgang te wijzigen.", "activation.dismiss": "Checklist verbergen", "activation.progress": "{done} van {total} voltooid", "activation.stepsLabel": "Activeringsstappen", "activation.pausedTitle": "Aan de slag is gepauzeerd", "activation.pausedBody": "Hervat de checklist wanneer u wilt — van velden inschakelen tot exporteren.", "activation.resume": "Checklist hervatten", "stats.products": "Producten", "stats.categories": "Categorieën", "stats.attributes": "Kenmerken", "stats.feeds": "Feeds", "stats.credits": "Tegoed", "stats.openCatalog": "Catalogus openen", "stats.productsHint": "{processed} verwerkt · {unprocessed} onverwerkt", "stats.catalogTree": "Catalogusboom", "stats.attributeLibrary": "Kenmerkenbibliotheek", "stats.importSources": "Importbronnen", "stats.payAsYouGo": "Betalen naar gebruik", "stats.walletBilling": "Wallet · Facturering", "stats.enterpriseBilling": "Enterprise · Facturering", "stats.usedBilling": "{used} gebruikt · Facturering", "processing.jobStatus.processing": "Bezig", "processing.jobStatus.completed": "Voltooid", "processing.jobStatus.failed": "Mislukt", "processing.jobStatus.cancelled": "Geannuleerd", "processing.jobStatus.pending": "In behandeling", "processing.jobStatus.queued": "In wachtrij", "processing.jobStatus.skipped": "Overgeslagen", "processing.jobStatus.unknown": "Onbekend", "processing.step.normalize": "Normaliseren", "processing.step.parse_specs": "Specs parseren", "processing.step.fill_fields": "Velden vullen", "processing.step.eprel": "EPREL", "processing.step.ai_enhance": "AI-verbetering", "errors.requestFailed": "Verzoek mislukt", "errors.maintenance": "Het systeem is in onderhoud. Probeer het later opnieuw.", "errors.readOnly": "Het systeem staat in alleen-lezenmodus. Wijzigingen zijn tijdelijk uitgeschakeld.", "errors.companyAdminDenied": "Alleen bedrijfsbeheerders kunnen {action}. Vraag een beheerder om hulp.", "errors.companyAdminDenied.actionDefault": "dit doen", "errors.couldNotUpdateLanguage": "Taal kon niet worden bijgewerkt", "toast.support.replyTitle": "Supportantwoord", "toast.support.replyBody": "Medewerkers hebben gereageerd op uw supportticket.", "toast.support.replyRe": "Re: {subject}", "toast.support.statusTitle": "Ticketstatus bijgewerkt", "toast.support.statusBody": "De status van uw supportticket is gewijzigd.", "toast.support.updateTitle": "Supportupdate", "flash.contentLanguageUpdated": "Contenttaal bijgewerkt." }, pl: { "app.name": "Descrybe", "app.home": "Strona główna Descrybe", "common.cancel": "Anuluj", "common.save": "Zapisz zmiany", "common.saveShort": "Zapisz", "common.continue": "Kontynuuj", "common.open": "Otwórz", "common.markDone": "Oznacz jako ukończone", "common.viewAll": "Zobacz wszystko", "common.close": "Zamknij", "a11y.skipToContent": "Przejdź do treści", "theme.switchToDark": "Przełącz na ciemny motyw", "theme.switchToLight": "Przełącz na jasny motyw", "header.signOut": "Wyloguj się", "header.signingOut": "Wylogowywanie…", "status.emDash": "—", "status.pending": "Oczekujące", "nav.section.overview": "Przegląd", "nav.section.catalog": "Katalog", "nav.section.feeds": "Feedy", "nav.section.stores": "Sklepy", "nav.section.processing": "Przetwarzanie", "nav.section.marketing": "Marketing", "nav.section.integrations": "Integracje", "nav.section.account": "Konto", "nav.section.platform": "Platforma", "nav.dashboard": "Panel", "nav.products": "Produkty", "nav.categories": "Kategorie", "nav.attributes": "Atrybuty", "nav.fields": "Pola", "nav.feeds": "Feedy", "nav.exports": "Eksporty", "nav.stores": "Sklepy", "nav.jobs": "Zadania", "nav.campaigns": "Kampanie", "nav.calendar": "Kalendarz", "nav.seo": "SEO", "nav.brand": "Marka", "nav.reviews": "Opinie", "nav.ai": "AI", "nav.email": "E-mail", "nav.billing": "Rozliczenia", "nav.settings": "Ustawienia", "nav.support": "Wsparcie", "nav.admin": "Admin", "nav.main": "Główna nawigacja", "nav.sidebar": "Pasek boczny aplikacji", "nav.close": "Zamknij nawigację", "nav.closeMenu": "Zamknij menu", "nav.open": "Otwórz nawigację", "nav.commandPalette": "Otwórz paletę poleceń", "locale.switcher": "Język interfejsu", "locale.menu": "Wybierz język interfejsu", "locale.label": "Język panelu", "locale.help": "Zmienia etykiety w nawigacji i ustawieniach. Język generowanych treści ustawia się osobno w Firmie.", "settings.contentLanguage": "Język treści", "settings.contentLanguageHelp": "Język używany do tytułów produktów, opisów i innych generowanych treści", "settings.tab.profile": "Profil", "settings.tab.company": "Firma", "settings.tab.alerts": "Alerty", "settings.tab.apiKeys": "Klucze API", "settings.tab.team": "Zespół", "settings.title": "Ustawienia", "settings.description": "Konto, firma, klucze API i zespół.", "dashboard.demoSandbox": "Piaskownica demo", "dashboard.demoEmptyTitle": "Piaskownica demo jest pusta", "dashboard.overviewTitle": "Przegląd", "dashboard.quickLinks": "Szybkie linki", "dashboard.whatsNew": "Co nowego", "dashboard.startTutorial": "Uruchom samouczek", "dashboard.connectFeed": "Podłącz feed", "dashboard.workflowTitle": "Przepływ katalogu", "dashboard.recentActivity": "Ostatnia aktywność", "dashboard.loadFailed": "Nie udało się wczytać panelu", "dashboard.workspaceFallback": "Ta przestrzeń robocza", "dashboard.jobFallback": "Zadanie {id}", "dashboard.workflow.feeds.connect": "Podłącz import", "dashboard.workflow.products.build": "Zbuduj katalog", "dashboard.workflow.products.count": "{count} w katalogu", "dashboard.workflow.process": "Przetwarzaj", "dashboard.workflow.processActive": "{count} aktywnych", "dashboard.workflow.processWaiting": "{count} oczekujących", "dashboard.workflow.processDone": "{count} ukończonych", "dashboard.workflow.processRun": "Uruchom zadania AI", "dashboard.workflow.export": "Eksportuj", "dashboard.workflow.exportReady": "Szablony i pobieranie", "dashboard.workflow.exportMap": "Mapuj, potem eksportuj", "activation.title": "Pierwsze kroki", "activation.description": "Pierwsza ścieżka wartości z przestrzeni roboczej: włącz pola → podłącz źródło → mapuj → synchronizuj próbkę → przetwarzaj → eksportuj. Tour demonstracyjny wyjaśnia te ekrany bez zmiany postępu listy.", "activation.dismiss": "Ukryj listę", "activation.progress": "{done} z {total} ukończonych", "activation.stepsLabel": "Kroki aktywacji", "activation.pausedTitle": "Pierwsze kroki wstrzymane", "activation.pausedBody": "Wznów listę w dowolnym momencie — od włączenia pól do eksportu.", "activation.resume": "Wznów listę", "stats.products": "Produkty", "stats.categories": "Kategorie", "stats.attributes": "Atrybuty", "stats.feeds": "Feedy", "stats.credits": "Kredyty", "stats.openCatalog": "Otwórz katalog", "stats.productsHint": "{processed} przetworzonych · {unprocessed} nieprzetworzonych", "stats.catalogTree": "Drzewo katalogu", "stats.attributeLibrary": "Biblioteka atrybutów", "stats.importSources": "Źródła importu", "stats.payAsYouGo": "Płatność według użycia", "stats.walletBilling": "Portfel · Rozliczenia", "stats.enterpriseBilling": "Enterprise · Rozliczenia", "stats.usedBilling": "{used} użytych · Rozliczenia", "processing.jobStatus.processing": "Przetwarzanie", "processing.jobStatus.completed": "Ukończono", "processing.jobStatus.failed": "Niepowodzenie", "processing.jobStatus.cancelled": "Anulowano", "processing.jobStatus.pending": "Oczekujące", "processing.jobStatus.queued": "W kolejce", "processing.jobStatus.skipped": "Pominięto", "processing.jobStatus.unknown": "Nieznany", "processing.step.normalize": "Normalizuj", "processing.step.parse_specs": "Parsuj specyfikacje", "processing.step.fill_fields": "Wypełnij pola", "processing.step.eprel": "EPREL", "processing.step.ai_enhance": "Ulepszenie AI", "errors.requestFailed": "Żądanie nie powiodło się", "errors.maintenance": "System jest w konserwacji. Spróbuj ponownie później.", "errors.readOnly": "System jest w trybie tylko do odczytu. Zmiany są tymczasowo wyłączone.", "errors.companyAdminDenied": "Tylko administratorzy firmy mogą {action}. Poproś administratora o pomoc.", "errors.companyAdminDenied.actionDefault": "to zrobić", "errors.couldNotUpdateLanguage": "Nie można zaktualizować języka", "toast.support.replyTitle": "Odpowiedź wsparcia", "toast.support.replyBody": "Zespół odpowiedział na Twoje zgłoszenie wsparcia.", "toast.support.replyRe": "Re: {subject}", "toast.support.statusTitle": "Zaktualizowano status zgłoszenia", "toast.support.statusBody": "Status Twojego zgłoszenia wsparcia się zmienił.", "toast.support.updateTitle": "Aktualizacja wsparcia", "flash.contentLanguageUpdated": "Zaktualizowano język treści." }, ja: { "app.name": "Descrybe", "app.home": "Descrybeホーム", "common.cancel": "キャンセル", "common.save": "変更を保存", "common.saveShort": "保存", "common.continue": "続行", "common.open": "開く", "common.markDone": "完了にする", "common.viewAll": "すべて表示", "common.close": "閉じる", "a11y.skipToContent": "コンテンツへスキップ", "theme.switchToDark": "ダークテーマに切り替え", "theme.switchToLight": "ライトテーマに切り替え", "header.signOut": "ログアウト", "header.signingOut": "ログアウト中…", "status.emDash": "—", "status.pending": "保留中", "nav.section.overview": "概要", "nav.section.catalog": "カタログ", "nav.section.feeds": "フィード", "nav.section.stores": "ストア", "nav.section.processing": "処理", "nav.section.marketing": "マーケティング", "nav.section.integrations": "連携", "nav.section.account": "アカウント", "nav.section.platform": "プラットフォーム", "nav.dashboard": "ダッシュボード", "nav.products": "商品", "nav.categories": "カテゴリ", "nav.attributes": "属性", "nav.fields": "フィールド", "nav.feeds": "フィード", "nav.exports": "エクスポート", "nav.stores": "ストア", "nav.jobs": "ジョブ", "nav.campaigns": "キャンペーン", "nav.calendar": "カレンダー", "nav.seo": "SEO", "nav.brand": "ブランド", "nav.reviews": "レビュー", "nav.ai": "AI", "nav.email": "メール", "nav.billing": "請求", "nav.settings": "設定", "nav.support": "サポート", "nav.admin": "管理", "nav.main": "メインナビゲーション", "nav.sidebar": "アプリのサイドバー", "nav.close": "ナビゲーションを閉じる", "nav.closeMenu": "メニューを閉じる", "nav.open": "ナビゲーションを開く", "nav.commandPalette": "コマンドパレットを開く", "locale.switcher": "インターフェース言語", "locale.menu": "インターフェース言語を選択", "locale.label": "ダッシュボードの言語", "locale.help": "ナビゲーションと設定のラベルを変更します。生成コンテンツの言語は会社設定で別途指定します。", "settings.contentLanguage": "コンテンツ言語", "settings.contentLanguageHelp": "商品タイトル、説明、その他の生成コンテンツに使用する言語", "settings.tab.profile": "プロフィール", "settings.tab.company": "会社", "settings.tab.alerts": "アラート", "settings.tab.apiKeys": "APIキー", "settings.tab.team": "チーム", "settings.title": "設定", "settings.description": "アカウント、会社、APIキー、チーム。", "dashboard.demoSandbox": "デモサンドボックス", "dashboard.demoEmptyTitle": "デモサンドボックスは空です", "dashboard.overviewTitle": "概要", "dashboard.quickLinks": "クイックリンク", "dashboard.whatsNew": "新着情報", "dashboard.startTutorial": "チュートリアルを開始", "dashboard.connectFeed": "フィードを接続", "dashboard.workflowTitle": "カタログワークフロー", "dashboard.recentActivity": "最近のアクティビティ", "dashboard.loadFailed": "ダッシュボードの読み込みに失敗しました", "dashboard.workspaceFallback": "このワークスペース", "dashboard.jobFallback": "ジョブ {id}", "dashboard.workflow.feeds.connect": "インポートを接続", "dashboard.workflow.products.build": "カタログを構築", "dashboard.workflow.products.count": "カタログ内 {count} 件", "dashboard.workflow.process": "処理", "dashboard.workflow.processActive": "アクティブ {count}", "dashboard.workflow.processWaiting": "待機 {count}", "dashboard.workflow.processDone": "完了 {count}", "dashboard.workflow.processRun": "AIジョブを実行", "dashboard.workflow.export": "エクスポート", "dashboard.workflow.exportReady": "テンプレートとダウンロード", "dashboard.workflow.exportMap": "マップしてエクスポート", "activation.title": "はじめに", "activation.description": "ワークスペースからの最初の価値パス:フィールドを有効化 → ソースを接続 → マップ → サンプル同期 → 処理 → エクスポート。デモツアーはチェックリストの進捗を変えずにこれらの画面を説明します。", "activation.dismiss": "チェックリストを閉じる", "activation.progress": "{total} 件中 {done} 件完了", "activation.stepsLabel": "アクティベーション手順", "activation.pausedTitle": "はじめが一時停止中です", "activation.pausedBody": "いつでもチェックリストを再開できます — フィールド有効化からエクスポートまで。", "activation.resume": "チェックリストを再開", "stats.products": "商品", "stats.categories": "カテゴリ", "stats.attributes": "属性", "stats.feeds": "フィード", "stats.credits": "クレジット", "stats.openCatalog": "カタログを開く", "stats.productsHint": "処理済み {processed} · 未処理 {unprocessed}", "stats.catalogTree": "カタログツリー", "stats.attributeLibrary": "属性ライブラリ", "stats.importSources": "インポート元", "stats.payAsYouGo": "従量課金", "stats.walletBilling": "ウォレット · 請求", "stats.enterpriseBilling": "Enterprise · 請求", "stats.usedBilling": "使用 {used} · 請求", "processing.jobStatus.processing": "処理中", "processing.jobStatus.completed": "完了", "processing.jobStatus.failed": "失敗", "processing.jobStatus.cancelled": "キャンセル済み", "processing.jobStatus.pending": "保留中", "processing.jobStatus.queued": "キュー待ち", "processing.jobStatus.skipped": "スキップ", "processing.jobStatus.unknown": "不明", "processing.step.normalize": "正規化", "processing.step.parse_specs": "仕様を解析", "processing.step.fill_fields": "フィールドを埋める", "processing.step.eprel": "EPREL", "processing.step.ai_enhance": "AI強化", "errors.requestFailed": "リクエストに失敗しました", "errors.maintenance": "システムはメンテナンス中です。後でもう一度お試しください。", "errors.readOnly": "システムは読み取り専用モードです。変更は一時的に無効です。", "errors.companyAdminDenied": "{action}できるのは会社の管理者のみです。管理者に問い合わせてください。", "errors.companyAdminDenied.actionDefault": "これを実行", "errors.couldNotUpdateLanguage": "言語を更新できませんでした", "toast.support.replyTitle": "サポート返信", "toast.support.replyBody": "スタッフがサポートチケットに返信しました。", "toast.support.replyRe": "Re: {subject}", "toast.support.statusTitle": "チケットステータスが更新されました", "toast.support.statusBody": "サポートチケットのステータスが変更されました。", "toast.support.updateTitle": "サポート更新", "flash.contentLanguageUpdated": "コンテンツ言語を更新しました。" } }; const LOCALES = [ { code: "es", comment: "Spanish (es) UI pack — keys must stay in sync with en.ts." }, { code: "fr", comment: "French (fr) UI pack — keys must stay in sync with en.ts." }, { code: "de", comment: "German (de) UI pack — keys must stay in sync with en.ts." }, { code: "it", comment: "Italian (it) UI pack — keys must stay in sync with en.ts." }, { code: "pt", comment: "Portuguese (pt) UI pack — keys must stay in sync with en.ts." }, { code: "nl", comment: "Dutch (nl) UI pack — keys must stay in sync with en.ts." }, { code: "pl", comment: "Polish (pl) UI pack — keys must stay in sync with en.ts." }, { code: "ja", comment: "Japanese (ja) UI pack — keys must stay in sync with en.ts." } ]; const en = parseMessageDict(fs.readFileSync(enPath, "utf8")); const keyOrder = Object.keys(en); console.log(`en keys: ${keyOrder.length}`); const phraseMapPath = path.join(__dirname, "phrase-map.json"); const phraseMap = fs.existsSync(phraseMapPath) ? JSON.parse(fs.readFileSync(phraseMapPath, "utf8")) : {}; function mergedPack(code) { return { ...(PACKS[code] ?? {}), ...(EXTRA_COMMON[code] ?? {}), ...(EXTRA_ES[code] ?? {}), ...(EXTRA_REST[code] ?? {}), ...(EXTRA_ADMIN[code] ?? {}), ...(EXTRA_CHROME[code] ?? {}), ...(EXTRA_DEEP_ADMIN[code] ?? {}), ...(EXTRA_BROWSER[code] ?? {}), ...(EXTRA_MARKETING[code] ?? {}) }; } let failed = false; const summary = []; for (const loc of LOCALES) { const pack = mergedPack(loc.code); const existingPath = path.join(messagesDir, `${loc.code}.ts`); const existing = fs.existsSync(existingPath) ? parseMessageDict(fs.readFileSync(existingPath, "utf8")) : {}; const dict = {}; const missing = []; const fallbackEn = []; const extra = Object.keys(pack).filter((k) => !(k in en)); for (const key of keyOrder) { const existingVal = existing[key]; // Preserve real translations already on disk (do not wipe back to en). if ( typeof existingVal === "string" && existingVal !== "" && existingVal !== en[key] ) { dict[key] = existingVal; continue; } const translated = pack[key]; const phrase = phraseMap[en[key]]?.[loc.code]; const packUseful = translated != null && translated !== "" && (translated !== en[key] || SAME_AS_EN.has(key)); if (packUseful) { dict[key] = translated; } else if (typeof phrase === "string" && phrase.trim()) { // Prefer phrase-map over unfinished English copies in PACKS/EXTRA. dict[key] = phrase; } else if (SAME_AS_EN.has(key)) { dict[key] = en[key]; } else if (translated != null && translated !== "") { dict[key] = translated; if (translated === en[key]) { missing.push(key); fallbackEn.push(key); } } else { // Keep key present for sync; runtime also falls back to en if removed. dict[key] = en[key]; missing.push(key); fallbackEn.push(key); } } const translatedCount = keyOrder.length - fallbackEn.length; summary.push({ code: loc.code, keys: keyOrder.length, translated: translatedCount, fallbackEn: fallbackEn.length, extra: extra.length }); if (extra.length) { failed = true; console.error(`${loc.code}: extra keys not in en: ${extra.slice(0, 10).join(", ")}`); } if (fallbackEn.length) { console.warn( `${loc.code}: ${fallbackEn.length} keys still English (runtime en fallback also covers omissions)` ); } fs.writeFileSync( path.join(messagesDir, `${loc.code}.ts`), emitPack(loc.code, loc.comment, dict, keyOrder), "utf8" ); console.log( `wrote ${loc.code}.ts (keys=${keyOrder.length} translated=${translatedCount} enFallback=${fallbackEn.length})` ); } fs.writeFileSync( path.join(__dirname, "_locale-pack-summary.json"), JSON.stringify({ enKeys: keyOrder.length, locales: summary }, null, 2), "utf8" ); if (failed) { process.exitCode = 1; } else { console.log("Locale packs key-synced to en (see _locale-pack-summary.json)."); }