feat(abonnements): paliers LLM Essentielle/Premium, admin modeles par forfait, statistiques revenus, emails marketing
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m51s

- Gamme officielle : Essentielle (Pro) = deepseek-v4-flash, glm-5.3-flash,
  minimax-m3 ; Premium (Business) = claude-sonnet-5, deepseek-v4-pro, glm-5.3
- Routage reel : le modele employe suit le palier IA du forfait (reglages
  admin > defaut du plan), garde anti-croisement de palier
- Nouvelle page admin « Modeles & abonnements » (matrice forfaits/paliers,
  modele par defaut, catalogue OpenRouter)
- Statistiques enrichies : revenus (30 j + total), MRR estime, credits,
  liste d'attente, paliers utilises
- Nouvelle page admin « Marketing » : audiences avec compteurs, apercu,
  envoi test obligatoire, historique, desabonnement public + en-tetes
  List-Unsubscribe ; .gitignore pour les donnees d'execution
- Interface (accueil + tarifs) alignee sur la gamme, 13 langues completes
- Tests : routage par palier (fonction + tache), marketing, revenus en base
This commit is contained in:
2026-09-05 12:51:49 +02:00
parent 4e6850d6b1
commit 6c26712687
76 changed files with 5289 additions and 271 deletions

View File

@@ -0,0 +1,159 @@
"use client";
import { useEffect, useState } from "react";
import { Euro, TrendingUp, Users, Cpu, Loader2 } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { useTranslationStore } from "@/lib/store";
import { API_BASE } from "@/lib/config";
import { useI18n } from "@/lib/i18n";
import type { AdminStatsResponse } from "./types";
const getToken = () => useTranslationStore.getState().settings.adminToken ?? "";
function formatMoney(value: number, currency: string): string {
const currencyLabel = currency === "EUR" ? "€" : currency === "USD" ? "$" : currency;
return `${value.toLocaleString("fr-FR", { maximumFractionDigits: 2 })} ${currencyLabel}`;
}
/**
* Cartes business (revenus, MRR estimé, crédits, liste d'attente, paliers IA)
* alimentées par GET /api/v1/admin/stats (champs revenue, mrr_estimated,
* waitlist_count, ai_tier_usage).
*/
export function RevenueOverview() {
const { t } = useI18n();
const [stats, setStats] = useState<AdminStatsResponse | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
let cancelled = false;
const load = async () => {
try {
const response = await fetch(`${API_BASE}/api/v1/admin/stats`, {
headers: { Authorization: `Bearer ${getToken()}` },
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const json = await response.json();
if (!cancelled) {
setStats(json.data ?? json);
setError(null);
}
} catch (e) {
if (!cancelled) setError(e instanceof Error ? e.message : "Erreur");
} finally {
if (!cancelled) setIsLoading(false);
}
};
load();
const interval = setInterval(load, 30000);
return () => {
cancelled = true;
clearInterval(interval);
};
}, []);
if (isLoading && !stats) {
return (
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5">
{Array.from({ length: 5 }).map((_, i) => (
<Card key={i}>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<div className="h-4 w-24 animate-pulse rounded bg-muted" />
</CardHeader>
<CardContent>
<div className="h-8 w-20 animate-pulse rounded bg-muted" />
</CardContent>
</Card>
))}
</div>
);
}
if (error || !stats) {
return (
<Card>
<CardContent className="flex items-center gap-2 py-4 text-sm text-red-500">
<Cpu className="size-4" /> {t("admin.stats.unavailable", { error: error ?? "" })}
</CardContent>
</Card>
);
}
const currency = stats.revenue?.currency ?? "EUR";
const tierTotal =
(stats.ai_tier_usage?.essential ?? 0) +
(stats.ai_tier_usage?.premium ?? 0) +
(stats.ai_tier_usage?.classic ?? 0) +
(stats.ai_tier_usage?.other ?? 0);
const cards = [
{
title: t("admin.stats.revenue30"),
icon: <Euro className="h-4 w-4 text-muted-foreground" />,
value: formatMoney(stats.revenue?.collected_30d ?? 0, currency),
sub: t("admin.stats.payments30", { count: stats.revenue?.payments_30d ?? 0 }),
},
{
title: t("admin.stats.revenueTotal"),
icon: <TrendingUp className="h-4 w-4 text-muted-foreground" />,
value: formatMoney(stats.revenue?.collected_total ?? 0, currency),
sub: t("admin.stats.includingCredits", {
amount: formatMoney(stats.revenue?.credits_purchased ?? 0, currency),
}),
},
{
title: t("admin.stats.mrr"),
icon: <TrendingUp className="h-4 w-4 text-muted-foreground" />,
value: formatMoney(stats.mrr_estimated?.total ?? 0, currency),
sub:
Object.entries(stats.mrr_estimated?.by_plan ?? {})
.map(([plan, mrr]) => `${plan} : ${formatMoney(mrr, currency)}`)
.join(" · ") || "—",
},
{
title: t("admin.stats.waitlist"),
icon: <Users className="h-4 w-4 text-muted-foreground" />,
value: String(stats.waitlist_count ?? 0),
sub: t("admin.stats.waitlistSub"),
},
{
title: t("admin.stats.aiTiers"),
icon: <Cpu className="h-4 w-4 text-muted-foreground" />,
value: `${stats.ai_tier_usage?.essential ?? 0} / ${stats.ai_tier_usage?.premium ?? 0}`,
sub: t("admin.stats.tiersSub", {
classic: stats.ai_tier_usage?.classic ?? 0,
other: stats.ai_tier_usage?.other ?? 0,
}),
},
];
return (
<div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5">
{cards.map((c) => (
<Card key={c.title}>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">{c.title}</CardTitle>
{c.icon}
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{c.value}</div>
<p className="truncate text-xs text-muted-foreground" title={c.sub}>
{c.sub}
</p>
</CardContent>
</Card>
))}
</div>
{tierTotal === 0 && (
<p className="mt-2 text-xs text-muted-foreground">{t("admin.stats.noTranslationsYet")}</p>
)}
{isLoading && (
<p className="mt-2 flex items-center gap-1.5 text-xs text-muted-foreground">
<Loader2 className="size-3 animate-spin" /> {t("admin.stats.refreshing")}
</p>
)}
</div>
);
}

View File

@@ -1,4 +1,4 @@
import { CreditCard, LayoutDashboard, Settings, FileText, Users, type LucideIcon } from 'lucide-react';
import { CreditCard, LayoutDashboard, Settings, FileText, Users, Cpu, Megaphone, BarChart3, type LucideIcon } from 'lucide-react';
export interface AdminNavItem {
labelKey: string;
@@ -8,9 +8,12 @@ export interface AdminNavItem {
export const adminNavItems: AdminNavItem[] = [
{ labelKey: 'admin.nav.dashboard', href: '/admin', icon: LayoutDashboard },
{ labelKey: 'admin.nav.stats', href: '/admin/stats', icon: BarChart3 },
{ labelKey: 'admin.nav.users', href: '/admin/users', icon: Users },
{ labelKey: 'admin.nav.pricing', href: '/admin/pricing', icon: CreditCard },
{ labelKey: 'admin.nav.models', href: '/admin/models', icon: Cpu },
{ labelKey: 'admin.nav.providers', href: '/admin/settings', icon: Settings },
{ labelKey: 'admin.nav.marketing', href: '/admin/marketing', icon: Megaphone },
{ labelKey: 'admin.nav.system', href: '/admin/system', icon: Settings },
{ labelKey: 'admin.nav.logs', href: '/admin/logs', icon: FileText },
];

View File

@@ -0,0 +1,426 @@
"use client";
import { useState, useEffect, useMemo } from "react";
import {
Megaphone,
Loader2,
Send,
FlaskConical,
History,
AlertCircle,
CheckCircle2,
Eye,
} from "lucide-react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useNotification } from "@/components/ui/notification";
import { useTranslationStore } from "@/lib/store";
import { API_BASE } from "@/lib/config";
import { useI18n } from "@/lib/i18n";
import type {
MarketingAudiencesResponse,
MarketingEmailHistoryEntry,
MarketingEmailSendResponse,
} from "../types";
const getToken = () => useTranslationStore.getState().settings.adminToken ?? "";
/** Clés i18n par identifiant d'audience (l'identifiant part en base/historique). */
const AUDIENCE_LABEL_KEYS: Record<string, string> = {
waitlist: "admin.marketing.audienceWaitlist",
inactive_30: "admin.marketing.audienceInactive",
"plan:pro": "admin.marketing.audiencePlanPro",
"plan:starter": "admin.marketing.audiencePlanStarter",
"plan:business": "admin.marketing.audiencePlanBusiness",
"plan:enterprise": "admin.marketing.audiencePlanEnterprise",
"plan:free": "admin.marketing.audiencePlanFree",
all_users: "admin.marketing.audienceAllUsers",
};
export default function AdminMarketingPage() {
const { t } = useI18n();
const { success, error } = useNotification();
const [audiences, setAudiences] = useState<Record<string, number>>({});
const [unsubscribedCount, setUnsubscribedCount] = useState(0);
const [audience, setAudience] = useState("waitlist");
const [subject, setSubject] = useState("");
const [html, setHtml] = useState("");
const [testEmail, setTestEmail] = useState("");
const [showPreview, setShowPreview] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [isSendingTest, setIsSendingTest] = useState(false);
const [isSending, setIsSending] = useState(false);
const [history, setHistory] = useState<MarketingEmailHistoryEntry[]>([]);
/** Empreinte SHA-256 du contenu courant (même calcul que le backend). */
const [contentHash, setContentHash] = useState<string | null>(null);
/** false si le navigateur n'expose pas crypto.subtle (indicateur absent,
* l'envoi reste possible : le serveur valide l'envoi test). */
const [hashSupported, setHashSupported] = useState(true);
useEffect(() => {
if (!crypto?.subtle) {
setHashSupported(false);
setContentHash(null);
return;
}
let cancelled = false;
const data = new TextEncoder().encode(`${subject.trim()}\n${html.trim()}`);
crypto.subtle
.digest("SHA-256", data)
.then((buf) => {
if (cancelled) return;
const hex = Array.from(new Uint8Array(buf))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
setContentHash(hex);
})
.catch(() => setContentHash(null));
return () => {
cancelled = true;
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [subject, html]);
const loadAudiences = async () => {
const response = await fetch(`${API_BASE}/api/v1/admin/marketing/audiences`, {
headers: { Authorization: `Bearer ${getToken()}` },
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const json: MarketingAudiencesResponse = await response.json();
setAudiences(json.data.audiences);
setUnsubscribedCount(json.data.unsubscribed_count);
};
const loadHistory = async () => {
const response = await fetch(`${API_BASE}/api/v1/admin/marketing/email/history`, {
headers: { Authorization: `Bearer ${getToken()}` },
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const json = await response.json();
setHistory(json.data ?? []);
};
useEffect(() => {
setIsLoading(true);
Promise.all([loadAudiences(), loadHistory()])
.catch((e) =>
error({ title: t("admin.marketing.loadErrorTitle"), description: String(e.message ?? e) })
)
.finally(() => setIsLoading(false));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const audienceLabel = (key: string): string => {
const labelKey = AUDIENCE_LABEL_KEYS[key];
return labelKey ? t(labelKey) : key;
};
const recipientCount = audiences[audience] ?? 0;
/** Simple indicateur (non bloquant) : un test réussi de ce contenu exact
* apparaît dans l'historique chargé. La décision d'autoriser l'envoi réel
* appartient au serveur (l'historique affiché est tronqué à 100 entrées). */
const testSeenInHistory =
!!contentHash &&
history.some(
(h) => h.test_mode && h.sent_count > 0 && h.content_hash === contentHash
);
const sendTest = async () => {
if (!subject.trim() || !html.trim()) {
error({ title: t("admin.marketing.incompleteTitle"), description: t("admin.marketing.incompleteDesc") });
return;
}
setIsSendingTest(true);
try {
const response = await fetch(`${API_BASE}/api/v1/admin/marketing/email/send`, {
method: "POST",
headers: {
Authorization: `Bearer ${getToken()}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
audience,
subject: subject.trim(),
html: html.trim(),
test_mode: true,
test_email: testEmail.trim() || null,
}),
});
const json = await response.json().catch(() => ({}));
if (response.ok) {
const d: MarketingEmailSendResponse["data"] = json.data;
success({
title: t("admin.marketing.testDoneTitle"),
description: t("admin.marketing.testDoneDesc", { email: d.recipient ?? "" }),
});
await loadHistory();
} else {
error({
title: t("admin.marketing.testFailedTitle"),
description: json.message || `HTTP ${response.status}`,
});
await loadHistory();
}
} catch {
error({ title: t("admin.marketing.loadErrorTitle"), description: t("admin.marketing.networkDesc") });
} finally {
setIsSendingTest(false);
}
};
const sendReal = async () => {
if (!subject.trim() || !html.trim()) {
error({ title: t("admin.marketing.incompleteTitle"), description: t("admin.marketing.incompleteDesc") });
return;
}
if (
!window.confirm(
t("admin.marketing.confirmSend", { count: recipientCount, audience: audienceLabel(audience) })
)
) {
return;
}
setIsSending(true);
try {
const response = await fetch(`${API_BASE}/api/v1/admin/marketing/email/send`, {
method: "POST",
headers: {
Authorization: `Bearer ${getToken()}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
audience,
subject: subject.trim(),
html: html.trim(),
test_mode: false,
}),
});
const json = await response.json().catch(() => ({}));
if (response.ok) {
const d: MarketingEmailSendResponse["data"] = json.data;
success({
title: t("admin.marketing.sendingTitle"),
description: t("admin.marketing.sendingDesc", { count: d.queued ?? 0 }),
});
setTimeout(() => {
loadHistory().catch(() => {});
}, 3000);
} else {
error({
title: t("admin.marketing.sendRefusedTitle"),
description: json.message || `HTTP ${response.status}`,
});
}
} catch {
error({ title: t("admin.marketing.loadErrorTitle"), description: t("admin.marketing.networkDesc") });
} finally {
setIsSending(false);
}
};
const previewDoc = useMemo(
() =>
html.trim() ||
`<html><body style='font-family:sans-serif;color:#94a3b8;padding:32px;text-align:center;'>${t(
"admin.marketing.previewEmpty"
)}</body></html>`,
[html, t]
);
return (
<div className="space-y-6">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-purple-600/20 rounded-lg flex items-center justify-center">
<Megaphone className="w-5 h-5 text-purple-400" />
</div>
<div>
<h1 className="text-xl font-semibold text-foreground">{t("admin.marketing.title")}</h1>
<p className="text-sm text-muted-foreground">{t("admin.marketing.subtitle")}</p>
</div>
</div>
{isLoading ? (
<div className="flex items-center justify-center py-12">
<Loader2 className="size-8 animate-spin text-muted-foreground" />
</div>
) : (
<div className="grid gap-6 lg:grid-cols-3">
{/* ── Composition ── */}
<Card className="lg:col-span-2 overflow-visible">
<CardHeader>
<CardTitle className="text-base">{t("admin.marketing.newCampaign")}</CardTitle>
<CardDescription>
{t("admin.marketing.unsubscribedNote", { count: unsubscribedCount })}
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid gap-4 sm:grid-cols-2">
<div className="space-y-2">
<Label>{t("admin.marketing.audience")}</Label>
<Select value={audience} onValueChange={setAudience}>
<SelectTrigger>
<SelectValue placeholder={t("admin.marketing.audiencePlaceholder")} />
</SelectTrigger>
<SelectContent>
{Object.keys(audiences)
.sort((a, b) => (audiences[b] ?? 0) - (audiences[a] ?? 0))
.map((key) => (
<SelectItem key={key} value={key}>
{audienceLabel(key)} ({audiences[key]})
</SelectItem>
))}
</SelectContent>
</Select>
<p className="text-xs text-muted-foreground">
{t("admin.marketing.recipientsAvailable", { count: recipientCount })}
</p>
</div>
<div className="space-y-2">
<Label htmlFor="marketing-test-email">{t("admin.marketing.testEmail")}</Label>
<Input
id="marketing-test-email"
type="email"
placeholder={t("admin.marketing.testEmailPlaceholder")}
value={testEmail}
onChange={(e) => setTestEmail(e.target.value)}
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="marketing-subject">{t("admin.marketing.subject")}</Label>
<Input
id="marketing-subject"
placeholder={t("admin.marketing.subjectPlaceholder")}
value={subject}
onChange={(e) => setSubject(e.target.value)}
maxLength={200}
/>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<Label htmlFor="marketing-html">{t("admin.marketing.html")}</Label>
<Button
variant="ghost"
size="sm"
className="h-7 gap-1.5 text-xs"
onClick={() => setShowPreview((v) => !v)}
>
<Eye className="size-3" />
{showPreview ? t("admin.marketing.hidePreview") : t("admin.marketing.preview")}
</Button>
</div>
<Textarea
id="marketing-html"
className="min-h-48 font-mono text-xs"
placeholder={t("admin.marketing.htmlPlaceholder")}
value={html}
onChange={(e) => setHtml(e.target.value)}
/>
<p className="text-xs text-muted-foreground">{t("admin.marketing.footerNote")}</p>
{showPreview && (
<iframe
title={t("admin.marketing.previewTitle")}
srcDoc={previewDoc}
className="h-72 w-full rounded-lg border border-border bg-white"
sandbox=""
/>
)}
</div>
<div className="flex flex-wrap items-center gap-3 border-t border-border/60 pt-4">
<Button variant="outline" onClick={sendTest} disabled={isSendingTest} className="gap-2">
{isSendingTest ? (
<Loader2 className="size-4 animate-spin" />
) : (
<FlaskConical className="size-4" />
)}
{t("admin.marketing.sendTest")}
</Button>
<Button
onClick={sendReal}
disabled={isSending || recipientCount === 0}
className="gap-2"
>
{isSending ? (
<Loader2 className="size-4 animate-spin" />
) : (
<Send className="size-4" />
)}
{t("admin.marketing.sendReal", { count: recipientCount })}
</Button>
{!hashSupported && (
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<AlertCircle className="size-3.5" />
{t("admin.marketing.localCheckUnavailable")}
</span>
)}
{hashSupported && testSeenInHistory && (
<span className="flex items-center gap-1.5 text-xs text-green-500">
<CheckCircle2 className="size-3.5" />
{t("admin.marketing.testValidated")}
</span>
)}
{hashSupported && !testSeenInHistory && (
<span className="flex items-center gap-1.5 text-xs text-amber-500">
<AlertCircle className="size-3.5" />
{t("admin.marketing.testRequiredHint")}
</span>
)}
</div>
</CardContent>
</Card>
{/* ── Historique ── */}
<Card>
<CardHeader className="flex flex-row items-center gap-2 pb-3">
<History className="size-4 text-muted-foreground" />
<CardTitle className="text-base">{t("admin.marketing.history")}</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
{history.length === 0 && (
<p className="text-sm text-muted-foreground">{t("admin.marketing.noHistory")}</p>
)}
{history.map((h) => (
<div key={h.id} className="rounded-lg border border-border/60 p-3 text-xs">
<div className="mb-1 flex flex-wrap items-center gap-2">
{h.test_mode ? (
<Badge variant="outline" className="text-[10px]">
{t("admin.marketing.badgeTest")}
</Badge>
) : (
<Badge className="bg-accent/10 text-accent border-accent/30 text-[10px]">
{t("admin.marketing.badgeReal")}
</Badge>
)}
<span className="text-muted-foreground">
{new Date(h.sent_at).toLocaleString("fr-FR")}
</span>
</div>
<p className="mb-1 font-medium text-foreground">{h.subject}</p>
<p className="text-muted-foreground">
{audienceLabel(h.audience)} {" "}
{t("admin.marketing.historySent", {
sent: h.sent_count,
total: h.recipients_total,
})}
{h.failed_count > 0
? t("admin.marketing.historyFailedSuffix", { count: h.failed_count })
: ""}
</p>
</div>
))}
</CardContent>
</Card>
</div>
)}
</div>
);
}

View File

@@ -0,0 +1,375 @@
"use client";
import { useState, useEffect } from "react";
import { Cpu, Save, Loader2, ArrowUp, ArrowDown, X, Plus, RefreshCw } from "lucide-react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { useNotification } from "@/components/ui/notification";
import { ModelCombobox, ModelOption } from "@/components/ui/model-combobox";
import { useTranslationStore } from "@/lib/store";
import { API_BASE } from "@/lib/config";
import { useI18n } from "@/lib/i18n";
import type { AiTierSettings, AiTiersSettings } from "../types";
interface FullSettings {
[key: string]: unknown;
}
const getToken = () => useTranslationStore.getState().settings.adminToken ?? "";
/** Éditeur d'un palier : liste ordonnée (ordre = priorité de secours) + radio « par défaut ». */
function TierEditor({
tier,
onChange,
catalog,
onLoadCatalog,
catalogLoading,
}: {
tier: AiTierSettings;
onChange: (next: AiTierSettings) => void;
catalog: ModelOption[];
onLoadCatalog: () => void;
catalogLoading: boolean;
}) {
const { t } = useI18n();
const [adding, setAdding] = useState(false);
const move = (index: number, dir: -1 | 1) => {
const models = [...tier.models];
const target = index + dir;
if (target < 0 || target >= models.length) return;
[models[index], models[target]] = [models[target], models[index]];
onChange({ ...tier, models });
};
const remove = (index: number) => {
const models = tier.models.filter((_, i) => i !== index);
onChange({ ...tier, models });
};
const add = (id: string) => {
const idClean = id.trim();
if (!idClean || tier.models.includes(idClean)) {
setAdding(false);
return;
}
onChange({ ...tier, models: [...tier.models, idClean] });
setAdding(false);
};
const defaultModel = tier.default_model || tier.models[0] || "";
return (
<div className="space-y-2">
{tier.models.map((model, i) => {
const isDefault = model === defaultModel;
return (
<div
key={model}
className={
"flex items-center gap-2 rounded-lg border px-3 py-2 " +
(isDefault ? "border-accent/50 bg-accent/5" : "border-border/60 bg-card")
}
>
<button
type="button"
role="radio"
aria-checked={isDefault}
aria-label={t("admin.models.setDefault", { model })}
onClick={() => onChange({ ...tier, default_model: model })}
className={
"flex size-4 shrink-0 items-center justify-center rounded-full border " +
(isDefault ? "border-accent" : "border-muted-foreground/40")
}
>
{isDefault && <span className="size-2 rounded-full bg-accent" />}
</button>
<span className="flex-1 cursor-pointer font-mono text-xs" onClick={() => onChange({ ...tier, default_model: model })}>
{model}
{isDefault ? (
<Badge variant="secondary" className="ms-2 font-sans text-[10px]">
{t("admin.models.defaultBadge")}
</Badge>
) : i === 0 ? (
<span className="ms-2 font-sans text-[10px] font-bold uppercase tracking-wider text-muted-foreground">
{t("admin.models.fallbackFirst")}
</span>
) : null}
</span>
<Button
variant="ghost"
size="sm"
className="h-6 w-6 p-0"
onClick={() => move(i, -1)}
disabled={i === 0}
aria-label={t("admin.models.moveUp")}
>
<ArrowUp className="size-3" />
</Button>
<Button
variant="ghost"
size="sm"
className="h-6 w-6 p-0"
onClick={() => move(i, 1)}
disabled={i === tier.models.length - 1}
aria-label={t("admin.models.moveDown")}
>
<ArrowDown className="size-3" />
</Button>
<Button
variant="ghost"
size="sm"
className="h-6 w-6 p-0 text-red-500"
onClick={() => remove(i)}
aria-label={t("admin.models.remove")}
>
<X className="size-3" />
</Button>
</div>
);
})}
{tier.models.length === 0 && (
<p className="text-xs text-muted-foreground">{t("admin.models.emptyTier")}</p>
)}
{adding ? (
<div className="space-y-2 rounded-lg border border-dashed border-border p-3">
<ModelCombobox
value=""
onChange={add}
models={catalog}
isLoading={catalogLoading}
onFetchModels={onLoadCatalog}
providerLabel="OpenRouter"
placeholder="provider/nom-du-modèle"
/>
<Button variant="ghost" size="sm" onClick={() => setAdding(false)}>
{t("admin.models.cancel")}
</Button>
</div>
) : (
<div className="flex items-center gap-2 pt-1">
<Button variant="outline" size="sm" onClick={() => setAdding(true)} className="gap-1.5">
<Plus className="size-3" /> {t("admin.models.addModel")}
</Button>
<Button
variant="ghost"
size="sm"
onClick={onLoadCatalog}
disabled={catalogLoading}
className="h-7 gap-1.5 px-2 text-xs text-muted-foreground"
>
{catalogLoading ? (
<Loader2 className="size-3 animate-spin" />
) : (
<RefreshCw className="size-3" />
)}
{t("admin.models.catalog")}
</Button>
</div>
)}
</div>
);
}
export default function AdminModelsPage() {
const { t } = useI18n();
const { success, error } = useNotification();
const [aiTiers, setAiTiers] = useState<AiTiersSettings | null>(null);
const [fullSettings, setFullSettings] = useState<FullSettings>({});
const [isLoading, setIsLoading] = useState(true);
const [isSaving, setIsSaving] = useState(false);
const [catalog, setCatalog] = useState<ModelOption[]>([]);
const [catalogLoading, setCatalogLoading] = useState(false);
useEffect(() => {
loadSettings();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const loadSettings = async () => {
setIsLoading(true);
try {
const response = await fetch(`${API_BASE}/api/v1/admin/settings`, {
headers: { Authorization: `Bearer ${getToken()}` },
});
if (response.ok) {
const envelope = await response.json();
const payload = envelope.data ?? envelope;
setFullSettings(payload);
if (payload.ai_tiers) {
setAiTiers(payload.ai_tiers);
}
} else {
error({
title: t("admin.models.loadErrorTitle"),
description: t("admin.models.loadErrorDesc", { status: response.status }),
});
}
} catch {
error({ title: t("admin.models.networkTitle"), description: t("admin.models.networkDesc") });
} finally {
setIsLoading(false);
}
};
const loadCatalog = async () => {
setCatalogLoading(true);
try {
const response = await fetch(`${API_BASE}/api/v1/admin/providers/openrouter/models`, {
headers: { Authorization: `Bearer ${getToken()}` },
});
if (response.ok) {
const data = await response.json();
setCatalog(data.data || []);
} else {
error({
title: t("admin.models.catalogErrorTitle"),
description: t("admin.models.loadErrorDesc", { status: response.status }),
});
}
} catch {
error({
title: t("admin.models.catalogErrorTitle"),
description: t("admin.models.catalogErrorDesc"),
});
} finally {
setCatalogLoading(false);
}
};
const save = async () => {
if (!aiTiers) return;
setIsSaving(true);
try {
const body = { ...fullSettings, ai_tiers: aiTiers };
const response = await fetch(`${API_BASE}/api/v1/admin/settings`, {
method: "PUT",
headers: {
Authorization: `Bearer ${getToken()}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (response.ok) {
const envelope = await response.json();
const payload = envelope.data ?? envelope;
if (payload?.ai_tiers) setAiTiers(payload.ai_tiers);
success({
title: t("admin.models.savedTitle"),
description: t("admin.models.savedDesc"),
});
} else {
const detail = await response.json().catch(() => ({}));
error({
title: t("admin.models.saveErrorTitle"),
description: detail.detail || detail.message || t("admin.models.loadErrorDesc", { status: response.status }),
});
}
} catch {
error({ title: t("admin.models.networkTitle"), description: t("admin.models.saveNetworkDesc") });
} finally {
setIsSaving(false);
}
};
if (isLoading) {
return (
<div className="flex items-center justify-center py-12">
<Loader2 className="size-8 animate-spin text-muted-foreground" />
</div>
);
}
if (!aiTiers) {
return (
<Card>
<CardContent className="py-8 text-center text-sm text-muted-foreground">
{t("admin.models.missingConfig")}
</CardContent>
</Card>
);
}
return (
<div className="space-y-6">
<div className="flex items-start justify-between gap-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-blue-600/20 rounded-lg flex items-center justify-center">
<Cpu className="w-5 h-5 text-blue-400" />
</div>
<div>
<h1 className="text-xl font-semibold text-foreground">{t("admin.models.title")}</h1>
<p className="text-sm text-muted-foreground">{t("admin.models.subtitle")}</p>
</div>
</div>
<Button onClick={save} disabled={isSaving}>
{isSaving ? (
<>
<Loader2 className="me-2 size-4 animate-spin" /> {t("admin.models.saving")}
</>
) : (
<>
<Save className="me-2 size-4" /> {t("admin.models.save")}
</>
)}
</Button>
</div>
<Card className="overflow-visible">
<CardHeader>
<CardTitle className="text-base">{t("admin.models.matrixTitle")}</CardTitle>
<CardDescription>{t("admin.models.matrixDesc")}</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{/* Forfait Pro — palier Essentielle */}
<div className="rounded-xl border border-border/60 p-4">
<div className="mb-3 flex flex-wrap items-center gap-2">
<Badge className="bg-accent/10 text-accent border-accent/30">{t("admin.models.proBadge")}</Badge>
<Badge variant="secondary">{t("admin.models.essentialBadge")}</Badge>
<span className="text-xs text-muted-foreground">{t("admin.models.essentialCost")}</span>
</div>
<TierEditor
tier={aiTiers.essential}
onChange={(next) => setAiTiers({ ...aiTiers, essential: next })}
catalog={catalog}
onLoadCatalog={loadCatalog}
catalogLoading={catalogLoading}
/>
<p className="mt-3 text-xs text-muted-foreground">{t("admin.models.sharedTierNote")}</p>
</div>
{/* Forfait Business — palier Premium */}
<div className="rounded-xl border border-accent/30 p-4">
<div className="mb-3 flex flex-wrap items-center gap-2">
<Badge className="bg-blue-500/10 text-blue-600 border-blue-500/30 dark:text-blue-300">
{t("admin.models.businessBadge")}
</Badge>
<Badge variant="secondary">{t("admin.models.premiumBadge")}</Badge>
<span className="text-xs text-muted-foreground">{t("admin.models.premiumCost")}</span>
</div>
<TierEditor
tier={aiTiers.premium}
onChange={(next) => setAiTiers({ ...aiTiers, premium: next })}
catalog={catalog}
onLoadCatalog={loadCatalog}
catalogLoading={catalogLoading}
/>
<p className="mt-3 text-xs text-muted-foreground">{t("admin.models.premiumReservedNote")}</p>
</div>
{/* Forfait Enterprise — lecture seule */}
<div className="rounded-xl border border-border/40 p-4">
<div className="mb-1 flex flex-wrap items-center gap-2">
<Badge variant="outline">{t("admin.models.enterpriseBadge")}</Badge>
<Badge variant="secondary">{t("admin.models.customBadge")}</Badge>
</div>
<p className="text-xs text-muted-foreground">{t("admin.models.customNote")}</p>
</div>
</CardContent>
</Card>
</div>
);
}

View File

@@ -13,6 +13,7 @@ import { useNotification } from "@/components/ui/notification";
import { ModelCombobox, ModelOption } from "@/components/ui/model-combobox";
import { useTranslationStore } from "@/lib/store";
import { API_BASE } from "@/lib/config";
import type { AiTiersSettings } from "../types";
interface ProviderConfig {
enabled: boolean;
@@ -43,6 +44,8 @@ interface SettingsConfig {
zai: ProviderConfig;
mistral: ProviderConfig;
smtp: SmtpConfig;
/** Paliers IA « Modèles & abonnements » — renvoyé tel quel à la sauvegarde. */
ai_tiers?: AiTiersSettings;
fallback_chain: string;
fallback_chain_classic: string;
fallback_chain_llm: string;
@@ -70,8 +73,8 @@ const defaultConfig: SettingsConfig = {
google_cloud: { enabled: false, api_key: "", timeout: 30, max_retries: 3 },
openai: { enabled: false, api_key: "", timeout: 60, max_retries: 3 },
ollama: { enabled: false, base_url: "http://localhost:11434", model: "llama3" },
openrouter: { enabled: false, api_key: "", model: "deepseek/deepseek-chat" },
openrouter_premium: { enabled: false, api_key: "", model: "openai/gpt-4o-mini" },
openrouter: { enabled: false, api_key: "", model: "deepseek/deepseek-v4-flash" },
openrouter_premium: { enabled: false, api_key: "", model: "anthropic/claude-sonnet-5" },
zai: { enabled: false, api_key: "", base_url: "https://api.x.ai/v1", model: "grok-2-1212" },
mistral: { enabled: false, api_key: "", model: "mistral-ocr-latest", timeout: 180 },
smtp: { enabled: false, host: "", port: 587, username: "", password: "", from_email: "", use_tls: true },
@@ -101,7 +104,6 @@ export default function AdminSettingsPage() {
const [ollamaModels, setOllamaModels] = useState<OllamaModel[]>([]);
const [isLoadingModels, setIsLoadingModels] = useState(false);
const [openaiModels, setOpenaiModels] = useState<ModelOption[]>([]);
const [openrouterModels, setOpenrouterModels] = useState<ModelOption[]>([]);
const [zaiModels, setZaiModels] = useState<ModelOption[]>([]);
const [loadingModelsProvider, setLoadingModelsProvider] = useState<string | null>(null);
const [isSendingTestEmail, setIsSendingTestEmail] = useState(false);
@@ -144,6 +146,9 @@ export default function AdminSettingsPage() {
const saveConfig = async () => {
setIsSaving(true);
try {
// `config` inclut `ai_tiers` tel que chargé (voir loadConfig) : la
// sauvegarde des fournisseurs ne doit jamais réinitialiser les paliers
// personnalisés de la page « Modèles & abonnements ».
const response = await fetch(`${API_BASE}/api/v1/admin/settings`, {
method: "PUT",
headers: {
@@ -238,7 +243,6 @@ export default function AdminSettingsPage() {
const data = await response.json();
const models: ModelOption[] = data.data || [];
if (provider === "openai") setOpenaiModels(models);
else if (provider === "openrouter") setOpenrouterModels(models);
else if (provider === "zai") setZaiModels(models);
info({ title: `${models.length} modèles ${provider} trouvés` });
} else {
@@ -476,7 +480,7 @@ export default function AdminSettingsPage() {
<ProviderCard
title="Traduction IA Essentielle"
description="Affichée aux utilisateurs comme 'Traduction IA Essentielle'. Modèles économiques recommandés : deepseek/deepseek-chat, google/gemini-2.0-flash, meta-llama/llama-3.3-70b-instruct. Clé API : openrouter.ai"
description="Palier Essentielle (forfait Pro). Le modèle réellement routé se règle dans « Modèles & abonnements ». Gamme : deepseek/deepseek-v4-flash, z-ai/glm-5.3-flash, minimax/minimax-m3. Clé API : openrouter.ai"
enabled={config.openrouter.enabled}
onToggle={(enabled) => updateProvider("openrouter", { enabled })}
onTest={() => testProvider("openrouter")}
@@ -496,24 +500,24 @@ export default function AdminSettingsPage() {
/>
</div>
<div className="space-y-2">
<Label htmlFor="openrouter-model">Modèle Essentiel</Label>
<ModelCombobox
<Label htmlFor="openrouter-model">Modèle Essentiel (lecture seule)</Label>
<Input
id="openrouter-model"
value={config.openrouter.model || ""}
onChange={(v) => updateProvider("openrouter", { model: v })}
models={openrouterModels}
isLoading={loadingModelsProvider === "openrouter"}
onFetchModels={() => fetchModels("openrouter")}
providerLabel="OpenRouter"
placeholder="deepseek/deepseek-chat"
disabled
readOnly
placeholder="deepseek/deepseek-v4-flash"
/>
<p className="text-xs text-muted-foreground">Recommandé : <code>deepseek/deepseek-chat</code> (~0.04/doc)</p>
<p className="text-xs text-amber-500">
Piloté par la page <strong>Modèles &amp; abonnements</strong> (matrice par forfait).
</p>
</div>
</div>
</ProviderCard>
<ProviderCard
title="Traduction IA Premium"
description="Affichée aux utilisateurs comme 'Traduction IA Premium'. Modèles haute qualité : openai/gpt-4o, anthropic/claude-sonnet-4.6, google/gemini-3.5-pro. Partage la même clé OpenRouter."
description="Palier Premium (forfait Business). Le modèle réellement routé se règle dans « Modèles & abonnements ». Gamme : anthropic/claude-sonnet-5, deepseek/deepseek-v4-pro, z-ai/glm-5.3. Partage la même clé OpenRouter."
enabled={config.openrouter_premium.enabled}
onToggle={(enabled) => updateProvider("openrouter_premium", { enabled })}
onTest={() => testProvider("openrouter_premium")}
@@ -521,21 +525,19 @@ export default function AdminSettingsPage() {
testMessage={testMessages.openrouter_premium}
envKeySet={envInfo.openrouter_premium}
>
<div className="space-y-2">
<Label htmlFor="openrouter-premium-model">Modèle Premium</Label>
<ModelCombobox
value={config.openrouter_premium.model || ""}
onChange={(v) => updateProvider("openrouter_premium", { model: v })}
models={openrouterModels}
isLoading={loadingModelsProvider === "openrouter"}
onFetchModels={() => fetchModels("openrouter")}
providerLabel="OpenRouter"
placeholder="anthropic/claude-sonnet-4.6"
/>
<p className="text-xs text-muted-foreground">
Recommandé : <code>anthropic/claude-sonnet-4.6</code> (~0.20/doc) ou <code>openai/gpt-4o</code> (~0.30/doc)
</p>
</div>
<div className="space-y-2">
<Label htmlFor="openrouter-premium-model">Modèle Premium (lecture seule)</Label>
<Input
id="openrouter-premium-model"
value={config.openrouter_premium.model || ""}
disabled
readOnly
placeholder="anthropic/claude-sonnet-5"
/>
<p className="text-xs text-amber-500">
Piloté par la page <strong>Modèles &amp; abonnements</strong> (matrice par forfait).
</p>
</div>
</ProviderCard>
<ProviderCard

View File

@@ -4,6 +4,7 @@ import { useState } from "react";
import { BarChart3, RefreshCw, Loader2, AlertCircle, Info } from "lucide-react";
import { Button } from "@/components/ui/button";
import { StatsOverview } from "../StatsOverview";
import { RevenueOverview } from "../RevenueOverview";
import { TopUsersTable } from "../TopUsersTable";
import { ProviderBreakdownChart } from "../ProviderBreakdownChart";
import { FormatBreakdownChart } from "../FormatBreakdownChart";
@@ -33,10 +34,10 @@ export default function StatsPage() {
</div>
<div>
<h1 className="text-xl font-semibold text-foreground">
Statistiques de Traduction
Statistiques
</h1>
<p className="text-sm text-muted-foreground">
Analyse des traductions et patterns d&apos;utilisation
Revenus, MRR, traductions et patterns d&apos;utilisation
</p>
</div>
</div>
@@ -74,6 +75,8 @@ export default function StatsPage() {
</div>
)}
<RevenueOverview />
<StatsOverview data={data} isLoading={isLoading} />
<div className="grid gap-6 md:grid-cols-2">

View File

@@ -78,3 +78,90 @@ export interface TranslationStatsResponse {
generated_at: string;
};
}
/* ── Modèles & abonnements (paliers IA) ─────────────────────── */
export interface AiTierSettings {
/** Modèles actifs — l'ordre est la priorité de secours. */
models: string[];
/** Modèle par défaut ; vide = premier de la liste = défaut du plan. */
default_model: string;
}
export interface AiTiersSettings {
essential: AiTierSettings;
premium: AiTierSettings;
}
/* ── Statistiques enrichies (revenus, MRR, liste d'attente) ── */
export interface AdminStatsResponse {
users: {
total: number;
active_this_month: number;
by_plan: Record<string, number>;
};
translations: {
docs_this_month: number;
pages_this_month: number;
};
revenue: {
collected_total: number;
collected_30d: number;
credits_purchased: number;
payments_30d: number;
currency: string;
};
mrr_estimated: {
total: number;
by_plan: Record<string, number>;
};
ai_tier_usage: {
essential: number;
premium: number;
classic: number;
other: number;
};
waitlist_count: number;
cache: Record<string, unknown>;
config: Record<string, unknown>;
}
/* ── Marketing (relances email) ─────────────────────────────── */
export interface MarketingAudiences {
audiences: Record<string, number>;
unsubscribed_count: number;
}
export interface MarketingAudiencesResponse {
data: MarketingAudiences;
meta: Record<string, unknown>;
}
export interface MarketingEmailHistoryEntry {
id: string;
sent_at: string;
completed_at?: string;
audience: string;
subject: string;
test_mode: boolean;
test_recipient?: string;
recipients_total: number;
sent_count: number;
failed_count: number;
failed: { email: string; error: string }[];
content_hash?: string;
}
export interface MarketingEmailSendResponse {
data: {
test_mode: boolean;
sent?: number;
failed?: number;
recipient?: string;
queued?: number;
audience?: string;
};
meta: Record<string, unknown>;
}

View File

@@ -922,7 +922,7 @@ export default function PricingPage() {
</div>
<div className="flex flex-wrap gap-2 text-xs">
<span className="px-2 py-1 bg-muted rounded">{t('pricing.aiModels.essential.context')}</span>
<span className="px-2 py-1 bg-muted rounded">$0.25/$0.38 per 1M</span>
<span className="px-2 py-1 bg-muted rounded">{t('pricing.aiModels.essential.price')}</span>
<span className="px-2 py-1 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 rounded">{t('pricing.aiModels.essential.value')}</span>
</div>
</div>
@@ -933,11 +933,11 @@ export default function PricingPage() {
<Badge className="ml-auto text-xs bg-accent/10 text-accent border-accent/30">{t('pricing.aiModels.premium.plan')}</Badge>
</div>
<div className="text-sm text-muted-foreground mb-3">
{t('pricing.aiModels.premium.descPrefix')} <strong className="text-foreground">Claude Sonnet 4.6</strong> {t('pricing.aiModels.premium.descSuffix')}
{t('pricing.aiModels.premium.descPrefix')} <strong className="text-foreground">{t('pricing.aiModels.premium.modelName')}</strong> {t('pricing.aiModels.premium.descSuffix')}
</div>
<div className="flex flex-wrap gap-2 text-xs">
<span className="px-2 py-1 bg-muted rounded">{t('pricing.aiModels.premium.context')}</span>
<span className="px-2 py-1 bg-muted rounded">$3.00/$15.00 per 1M</span>
<span className="px-2 py-1 bg-muted rounded">{t('pricing.aiModels.premium.alternatives')}</span>
<span className="px-2 py-1 bg-accent/10 text-accent rounded">{t('pricing.aiModels.premium.precision')}</span>
</div>
</div>

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "المزوّدون",
"admin.nav.system": "النظام",
"admin.nav.logs": "السجلات",
"admin.nav.stats": "الإحصائيات",
"admin.users.title": "إدارة المستخدمين",
"admin.users.subtitle": "عرض حسابات المستخدمين وإدارتها",
"admin.users.planUpdated": "تم تحديث الخطة",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "في انتظار البيانات...",
"admin.system.purging": "جارٍ الحذف...",
"admin.system.clean": "تنظيف",
"admin.system.purge": "حذف"
"admin.system.purge": "حذف",
"admin.nav.models": "النماذج والاشتراكات",
"admin.nav.marketing": "التسويق",
"admin.marketing.audience": "الجمهور",
"admin.marketing.audienceAllUsers": "جميع الحسابات",
"admin.marketing.audienceInactive": "حسابات غير نشطة منذ 30 يومًا",
"admin.marketing.audiencePlaceholder": "اختر جمهورًا",
"admin.marketing.audiencePlanBusiness": "خطة Business",
"admin.marketing.audiencePlanEnterprise": "خطة Enterprise",
"admin.marketing.audiencePlanFree": "الخطة المجانية",
"admin.marketing.audiencePlanPro": "خطة Pro",
"admin.marketing.audiencePlanStarter": "خطة Starter",
"admin.marketing.audienceWaitlist": "قائمة الانتظار",
"admin.marketing.badgeReal": "فعلي",
"admin.marketing.badgeTest": "اختباري",
"admin.marketing.confirmSend": "إرسال هذه الرسالة إلى {count} مستلم («{audience}»)؟",
"admin.marketing.footerNote": "يُضاف تلقائيًا تذييل يحتوي على رابط إلغاء الاشتراك عند الإرسال.",
"admin.marketing.hidePreview": "إخفاء المعاينة",
"admin.marketing.history": "سجل الإرسالات",
"admin.marketing.historyFailedSuffix": "، {count} فاشلة",
"admin.marketing.historySent": "{sent}/{total} مُرسلة",
"admin.marketing.html": "محتوى HTML",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "أدخل الموضوع وHTML.",
"admin.marketing.incompleteTitle": "محتوى غير مكتمل",
"admin.marketing.loadErrorTitle": "خطأ في التحميل",
"admin.marketing.localCheckUnavailable": "التحقق المحلي غير متاح في هذا المتصفح: سيتحقق الخادم من الإرسال الاختباري المسبق.",
"admin.marketing.networkDesc": "لا يمكن الوصول إلى الخادم الخلفي.",
"admin.marketing.newCampaign": "حملة جديدة",
"admin.marketing.noHistory": "لا توجد إرسالات مسجلة.",
"admin.marketing.preview": "معاينة",
"admin.marketing.previewEmpty": "معاينة: الصق HTML بجانب هذه اللوحة.",
"admin.marketing.previewTitle": "معاينة البريد",
"admin.marketing.recipientsAvailable": "{count} مستلم متاح بعد استثناء الملغين لاشتراكهم.",
"admin.marketing.sendReal": "الإرسال إلى {count} مستلم",
"admin.marketing.sendRefusedTitle": "تم رفض الإرسال",
"admin.marketing.sendTest": "إرسال اختباري",
"admin.marketing.sendingDesc": "{count} رسالة في قائمة الإرسال (فاصل 0,2 ثانية). الملغون لاشتراكهم مستثنون.",
"admin.marketing.sendingTitle": "الإرسال جارٍ",
"admin.marketing.subject": "الموضوع",
"admin.marketing.subjectPlaceholder": "مثال: ترجمتك بانتظارك — خصم 20٪ لمدة 7 أيام",
"admin.marketing.subtitle": "إرسال رسائل إلى جمهور محدد، مع إرسال اختباري إلزامي ورابط إلغاء اشتراك تلقائي وسجل كامل.",
"admin.marketing.testDoneDesc": "وصل البريد إلى {email}",
"admin.marketing.testDoneTitle": "تم الإرسال الاختباري",
"admin.marketing.testEmail": "بريد اختباري (اختياري)",
"admin.marketing.testEmailPlaceholder": "وإلا: عنوان المرسل SMTP",
"admin.marketing.testFailedTitle": "فشل الإرسال الاختباري",
"admin.marketing.testRequiredHint": "يتطلب الإرسال الفعلي إرسالًا اختباريًا مسبقًا لنفس هذا المحتوى (يتحقق منه الخادم).",
"admin.marketing.testValidated": "تم التحقق من الإرسال الاختباري لهذا المحتوى.",
"admin.marketing.title": "التسويق — حملات البريد الإلكتروني",
"admin.marketing.unsubscribedNote": "سيتم استثناء {count} من الملغين لاشتراكهم من كل إرسال.",
"admin.models.addModel": "إضافة نموذج",
"admin.models.businessBadge": "خطة Business",
"admin.models.cancel": "إلغاء",
"admin.models.catalog": "كتالوج OpenRouter",
"admin.models.catalogErrorDesc": "تعذر تحميل كتالوج OpenRouter.",
"admin.models.catalogErrorTitle": "الكتالوج غير متاح",
"admin.models.customBadge": "مستوى مخصص",
"admin.models.customNote": "نماذج حسب الطلب، تُحدد حالة بحالة مع العميل.",
"admin.models.defaultBadge": "افتراضي",
"admin.models.emptyTier": "لا نماذج: ستُستخدم المجموعة الرسمية للخطة.",
"admin.models.enterpriseBadge": "خطة Enterprise",
"admin.models.essentialBadge": "مستوى الذكاء الاصطناعي الأساسي",
"admin.models.essentialCost": "— يُحتسب بمعامل تكلفة 1",
"admin.models.fallbackFirst": "(احتياط رقم 1)",
"admin.models.loadErrorDesc": "HTTP {status} — تحقق من رمز المسؤول.",
"admin.models.loadErrorTitle": "خطأ في التحميل",
"admin.models.matrixDesc": "النماذج النشطة لكل مستوى — ترتيب القائمة هو أولوية الاحتياط. يختار زر الراديو النموذج الافتراضي، ويُطبق فورًا دون إعادة نشر.",
"admin.models.matrixTitle": "مصفوفة النماذج حسب الخطة",
"admin.models.missingConfig": "لم يتم العثور على إعدادات مستويات الذكاء الاصطناعي. أعد تحميل الصفحة.",
"admin.models.moveDown": "تحريك لأسفل",
"admin.models.moveUp": "تحريك لأعلى",
"admin.models.networkDesc": "لا يمكن الوصول إلى الخادم الخلفي.",
"admin.models.networkTitle": "خطأ في الشبكة",
"admin.models.premiumBadge": "مستوى الذكاء الاصطناعي المتميز",
"admin.models.premiumCost": "— يُحتسب بمعامل تكلفة 5",
"admin.models.premiumReservedNote": "محصور في خطتي Business وEnterprise (محرك «openrouter_premium»).",
"admin.models.proBadge": "خطة Pro",
"admin.models.remove": "إزالة",
"admin.models.save": "حفظ",
"admin.models.saveErrorTitle": "خطأ في الحفظ",
"admin.models.saveNetworkDesc": "تعذر حفظ الإعدادات.",
"admin.models.savedDesc": "يُستخدم النموذج الافتراضي الجديد بدءًا من الترجمة التالية، دون إعادة نشر.",
"admin.models.savedTitle": "تم حفظ النماذج",
"admin.models.saving": "جارٍ الحفظ...",
"admin.models.setDefault": "تعيين {model} كنموذج افتراضي",
"admin.models.sharedTierNote": "مستوى مشترك: تستخدم خطة Business المستوى الأساسي أيضًا لمحركها «openrouter» — القائمة أعلاه تنطبق على الخطتين.",
"admin.models.subtitle": "مصفوفة الخطط → مستويات الذكاء الاصطناعي. النموذج المستخدم فعليًا في كل ترجمة هو نموذج مستوى الخطة: خطة Pro لا يمكنها أبدًا تشغيل نموذج Premium.",
"admin.models.title": "النماذج والاشتراكات",
"admin.stats.aiTiers": "مستويات الذكاء الاصطناعي (30 يومًا)",
"admin.stats.includingCredits": "منها {amount} من الرصيد الإضافي",
"admin.stats.mrr": "الإيراد الشهري المتكرر المقدر",
"admin.stats.noTranslationsYet": "لا توجد ترجمات مسجلة خلال آخر 30 يومًا: ستكتمل توزيعات المستويات مع الترجمات القادمة.",
"admin.stats.payments30": "{count} دفعة خلال 30 يومًا",
"admin.stats.refreshing": "جارٍ التحديث...",
"admin.stats.revenue30": "الإيرادات (30 يومًا)",
"admin.stats.revenueTotal": "إجمالي الإيرادات المحصلة",
"admin.stats.tiersSub": "أساسي / متميز · كلاسيكي {classic} · آخر {other}",
"admin.stats.unavailable": "إحصائيات الأعمال غير متاحة ({error}).",
"admin.stats.waitlist": "قائمة الانتظار",
"admin.stats.waitlistSub": "مُدرجون في قائمة الانتظار"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "للمحترفين المتميزين",
"landing.pricing.pro.f1": "200 مستند / شهر",
"landing.pricing.pro.f2": "حتى 200 صفحة لكل مستند",
"landing.pricing.pro.f3": "ترجمة بالذكاء الاصطناعي",
"landing.pricing.pro.f3": "ذكاء اصطناعي أساسي: DeepSeek V4 Flash، GLM-5.3 Flash، MiniMax M3",
"landing.pricing.pro.f4": "Google مشمولان",
"landing.pricing.pro.f5": "قواميس وأوامر مخصصة",
"landing.pricing.pro.f6": "دعم ذو أولوية",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "للفرق ذات الاحتياجات الكبيرة",
"landing.pricing.business.f1": "1,000 مستند / شهر",
"landing.pricing.business.f2": "حتى 500 صفحة لكل مستند",
"landing.pricing.business.f3": "ذكاء اصطناعي متميز (Claude)",
"landing.pricing.business.f3": "ذكاء اصطناعي متميز (Claude 5)",
"landing.pricing.business.f4": "جميع المزودين + واجهة برمجة التطبيقات",
"landing.pricing.business.f5": "خطاطف الويب والأتمتة",
"landing.pricing.business.f6": "5 مقاعد للفريق",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "ملفات DOCX, XLSX, PPTX أو PDF مدعومة",
"landing.translate.aiAnalysis": "تحليل AI نشط",
"landing.translate.processing": "جاري المعالجة",
"landing.translate.preservingLayout": "جاري الحفاظ على التنسيق"
"landing.translate.preservingLayout": "جاري الحفاظ على التنسيق",
"landing.beforeAfter.seal": "نفس التخطيط، كلمة بكلمة",
"landing.beforeAfter.proof1": "مخططات SmartArt يُعاد بناؤها، وليس تسطيحها",
"landing.beforeAfter.proof2": "سلاسل الرسوم البيانية ومحاورها مترجمة",
"landing.beforeAfter.proof3": "جداول المحتويات يُعاد إنشاؤها باللغة الهدف",
"landing.beforeAfter.targetTitle": "المواصفات الفنية — معالجة الهواء",
"landing.beforeAfter.targetPara1": "يجب تشغيل نظام التهوية قبل نهاية الربع الثاني.",
"landing.beforeAfter.targetPara2Before": "",
"landing.beforeAfter.targetTerm": "وحدة معالجة الهواء",
"landing.beforeAfter.targetPara2After": "يجب أن تتوافق مع فئة الترشيح F7 وفقًا للجدول.",
"landing.beforeAfter.targetItem1": "الحمل الحراري: 42 كيلوواط عند التدفق الاسمي",
"landing.beforeAfter.targetItem2": "مستوى الصوت أقل من 45 dB(A) على مسافة 3 أمتار",
"landing.formats.pill": "التوافق",
"landing.hero.visualCaption": "نفس التخطيط، لغة جديدة — لا شيء آخر يتغير",
"landing.pricing.free.name": "مجاني",
"landing.pricing.free.desc": "مثالي لاكتشاف التطبيق",
"landing.pricing.free.cta": "اختر هذه الخطة",
"landing.pricing.enterprise.name": "المؤسسات",
"landing.pricing.enterprise.desc": "حلول مخصصة للمؤسسات الكبيرة",
"landing.pricing.enterprise.cta": "اتصل بنا",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "سجل 90 يومًا",
"pricing.plans.business.feat1": "1 000 مستند / شهر",
"pricing.plans.business.feat2": "حتى 500 صفحة لكل مستند",
"pricing.plans.business.feat3": "AI أساسية + متميزة (Claude Haiku)",
"pricing.plans.business.feat3": "الذكاء الاصطناعي الأساسي + المتميز (Claude 5)",
"pricing.plans.business.feat4": "جميع مزوّدي الترجمة",
"pricing.plans.business.feat5": "ملفات حتى 50 ميغابايت",
"pricing.plans.business.feat6": "وصول API (10 000 استدعاء/شهر)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "سجل سنة واحدة",
"pricing.plans.business.feat10": "تحليلات متقدمة",
"pricing.plans.enterprise.feat1": "مستندات بلا حدود",
"pricing.plans.enterprise.feat2": "جميع نماذج AI (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "جميع نماذج AI (Claude 5، DeepSeek V4 Pro، GLM-5.3…)",
"pricing.plans.enterprise.feat3": "نشر محلي أو سحابة مخصصة",
"pricing.plans.enterprise.feat4": "SLA 99.9% مضمون",
"pricing.plans.enterprise.feat5": "دعم مخصص على مدار الساعة",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "ذكاء اصطناعي متعدد المسارات فائق السرعة",
"pricing.trust.availability.title": "متاح على مدار الساعة",
"pricing.trust.availability.sub": "ضمان وقت تشغيل 99.9%",
"pricing.aiModels.title": "نماذج الذكاء الاصطناعي — مارس 2026",
"pricing.aiModels.title": "نماذج الذكاء الاصطناعي — سبتمبر 2026",
"pricing.aiModels.essential.title": "ترجمة AI أساسية",
"pricing.aiModels.essential.plan": "خطة Pro",
"pricing.aiModels.essential.descPrefix": "مبني على",
"pricing.aiModels.essential.descSuffix": "— أنموذج الذكاء الاصطناعي الأكثر فعالية من حيث التكلفة لعام 2026. جودة مماثلة للنماذج المتقدمة بتكلفة أقل بكثير.",
"pricing.aiModels.essential.modelName": "نموذج الذكاء الاصطناعي الأساسي",
"pricing.aiModels.essential.context": "163K رمز سياقي",
"pricing.aiModels.essential.value": "قيمة ممتازة مقابل المال",
"pricing.aiModels.essential.descSuffix": "— نماذج الذكاء الاصطناعي الأفضل قيمة مقابل المال لعام 2026.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash وGLM-5.3 Flash وMiniMax M3",
"pricing.aiModels.essential.context": "سياق يصل إلى 1.3 مليون رمز (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "أفضل قيمة مقابل السعر",
"pricing.aiModels.premium.title": "ترجمة AI متميزة",
"pricing.aiModels.premium.plan": "خطة Business",
"pricing.aiModels.premium.descPrefix": "مبني على",
"pricing.aiModels.premium.descSuffix": "من Anthropic — دقة عالية في المستندات القانونية والطبية والتقنية المعقدة.",
"pricing.aiModels.premium.context": "200K رمز سياقي",
"pricing.aiModels.premium.context": "مليون رمز سياقي",
"pricing.aiModels.premium.precision": "أعلى دقة",
"pricing.faq.title": "الأسئلة الشائعة",
"pricing.faq.q1": "هل يمكنني تغيير خطتي في أي وقت؟",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "ما هي «ترجمة AI الأساسية»؟",
"pricing.faq.a2": "إنه محرك الذكاء الاصطناعي الخاص بنا. يفهم سياق مستنداتك، ويحافظ على التخطيط، ويتعامل مع المصطلحات التقنية بشكل أفضل بكثير من الترجمة الكلاسيكية.",
"pricing.faq.q3": "ما الفرق بين AI الأساسية وAI المتميزة؟",
"pricing.faq.a3": "الذكاء الاصطناعي الأساسي يستخدم نموذجًا محسّنًا (قيمة ممتازة مقابل المال). الذكاء الاصطناعي المتميز يستخدم Claude 3.5 Haiku من Anthropic، أكثر دقة في المستندات القانونية والطبية والتقنية المعقدة.",
"pricing.faq.a3": "الذكاء الاصطناعي الأساسي يعمل بنماذج DeepSeek V4 Flash وGLM-5.3 Flash وMiniMax M3 (قيمة ممتازة مقابل المال). الذكاء الاصطناعي المتميز يستخدم Claude 5 من Anthropic، أكثر دقة في المستندات القانونية والطبية والتقنية المعقدة.",
"pricing.faq.q4": "هل تُحفظ مستنداتي بعد الترجمة؟",
"pricing.faq.a4": "الملفات المترجمة متاحة حسب خطتك (30 يومًا لـ Starter، 90 يومًا لـ Pro، سنة واحدة لـ Business). وهي مشفرة أثناء التخزين والنقل.",
"pricing.faq.q5": "ماذا يحدث إذا تجاوزت حصتي الشهرية؟",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "خطأ أثناء إنشاء الدفع.",
"pricing.dashboard": "لوحة التحكم",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "ابتداءً من 0.09 دولار لكل مليون رمز",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "بدائل: DeepSeek V4 Pro وGLM-5.3",
"pricing.confirm.title": "أكّد اشتراكك",
"pricing.confirm.subtitle": "سيتم تحويلك إلى مزود الدفع الآمن لدينا.",
"pricing.confirm.cancel": "إلغاء",
"pricing.confirm.cta": "المتابعة إلى الدفع",
"pricing.confirm.year": "سنة",
"pricing.confirm.month": "شهر",
"pricing.confirm.monthlyEquivalent": "فوترة سنوية — أي {price} € / شهر.",
"pricing.confirm.secureNote": "يمكنك الإلغاء في أي وقت من ملفك الشخصي. تتم معالجة الدفع عبر Stripe؛ ولا تمر بيانات بطاقتك أبدًا عبر خوادمنا.",
"pricing.enterprise.subject": "عرض المؤسسات",
"pricing.enterpriseBand.cta": "اتصل بنا",
"pricing.enterpriseBand.text": "حجم كبير، محركات مخصصة، خيارات تثبيت داخلي — لنتحدث.",
"pricing.error.server": "خطأ في الخادم {status}",
"pricing.freeBand.cta": "ابدأ مجانًا",
"pricing.freeBand.text": "تريد التجربة فقط؟ ابدأ مجانًا — 5 مستندات شهريًا، بدون بطاقة.",
"pricing.header.titleBase": "خطة لكل",
"pricing.header.titleAccent": "احتياج",
"pricing.toast.close": "إغلاق",
"pricing.aiModels.premium.price": "2 $ / 10 $ لكل مليون رمز"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "وصول موحد إلى أفضل النماذج مفتوحة المصدر المحسّنة للترجمة.",
"providerTheme.openrouter_premium.badge": "فائق",
"providerTheme.openrouter_premium.subBadge": "السياق الأقصى",
"providerTheme.openrouter_premium.desc": "مدعوم من أحدث النماذج (GPT-4o، Claude Sonnet 4.6) للمستندات الطويلة.",
"providerTheme.openrouter_premium.desc": "مدعوم من أحدث النماذج (GPT-4o، Claude 5) للمستندات الطويلة.",
"providerTheme.zai.badge": "متخصص",
"providerTheme.zai.subBadge": "المال والقانون",
"providerTheme.zai.desc": "نموذج مضبوط بدقة للمصطلحات التجارية المتطلبة (قانونية، مالية).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "Anbieter",
"admin.nav.system": "System",
"admin.nav.logs": "Protokolle",
"admin.nav.stats": "Statistiken",
"admin.users.title": "Benutzerverwaltung",
"admin.users.subtitle": "Benutzerkonten anzeigen und verwalten",
"admin.users.planUpdated": "Plan aktualisiert",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "Warte auf Daten...",
"admin.system.purging": "Bereinigung läuft...",
"admin.system.clean": "Bereinigen",
"admin.system.purge": "Bereinigen"
"admin.system.purge": "Bereinigen",
"admin.nav.models": "Modelle & Abonnements",
"admin.nav.marketing": "Marketing",
"admin.marketing.audience": "Zielgruppe",
"admin.marketing.audienceAllUsers": "Alle Konten",
"admin.marketing.audienceInactive": "Seit 30 Tagen inaktive Konten",
"admin.marketing.audiencePlaceholder": "Zielgruppe wählen",
"admin.marketing.audiencePlanBusiness": "Business-Tarif",
"admin.marketing.audiencePlanEnterprise": "Enterprise-Tarif",
"admin.marketing.audiencePlanFree": "Kostenlos-Tarif",
"admin.marketing.audiencePlanPro": "Pro-Tarif",
"admin.marketing.audiencePlanStarter": "Starter-Tarif",
"admin.marketing.audienceWaitlist": "Warteliste",
"admin.marketing.badgeReal": "echt",
"admin.marketing.badgeTest": "Test",
"admin.marketing.confirmSend": "Diese E-Mail an {count} Empfänger senden („{audience}“)?",
"admin.marketing.footerNote": "Eine Fußzeile mit dem Abmeldelink wird beim Senden automatisch ergänzt.",
"admin.marketing.hidePreview": "Vorschau ausblenden",
"admin.marketing.history": "Sendungsverlauf",
"admin.marketing.historyFailedSuffix": ", {count} Fehler",
"admin.marketing.historySent": "{sent}/{total} gesendet",
"admin.marketing.html": "HTML-Inhalt",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "Bitte Betreff und HTML ausfüllen.",
"admin.marketing.incompleteTitle": "Unvollständiger Inhalt",
"admin.marketing.loadErrorTitle": "Ladefehler",
"admin.marketing.localCheckUnavailable": "Lokale Prüfung in diesem Browser nicht möglich: Der Server kontrolliert die vorherige Testsendung.",
"admin.marketing.networkDesc": "Backend nicht erreichbar.",
"admin.marketing.newCampaign": "Neue Kampagne",
"admin.marketing.noHistory": "Keine Sendung erfasst.",
"admin.marketing.preview": "Vorschau",
"admin.marketing.previewEmpty": "Vorschau: HTML daneben einfügen.",
"admin.marketing.previewTitle": "E-Mail-Vorschau",
"admin.marketing.recipientsAvailable": "{count} Empfänger nach Ausschluss der Abmeldungen verfügbar.",
"admin.marketing.sendReal": "An {count} Empfänger senden",
"admin.marketing.sendRefusedTitle": "Sendung abgelehnt",
"admin.marketing.sendTest": "Testsendung",
"admin.marketing.sendingDesc": "{count} E-Mail(s) in der Warteschlange (0,2 s Abstand). Abmeldungen werden ausgeschlossen.",
"admin.marketing.sendingTitle": "Sendung läuft",
"admin.marketing.subject": "Betreff",
"admin.marketing.subjectPlaceholder": "z. B.: Ihre Übersetzung wartet — 20 % für 7 Tage",
"admin.marketing.subtitle": "E-Mails an eine Zielgruppe senden, mit Pflicht-Testsendung, automatischem Abmeldelink und vollständigem Verlauf.",
"admin.marketing.testDoneDesc": "E-Mail erhalten an {email}",
"admin.marketing.testDoneTitle": "Testsendung erfolgt",
"admin.marketing.testEmail": "Test-E-Mail (optional)",
"admin.marketing.testEmailPlaceholder": "Sonst: SMTP-Absenderadresse",
"admin.marketing.testFailedTitle": "Testsendung fehlgeschlagen",
"admin.marketing.testRequiredHint": "Eine echte Sendung erfordert eine vorherige Testsendung exakt dieses Inhalts (vom Server geprüft).",
"admin.marketing.testValidated": "Testsendung für diesen Inhalt bestätigt.",
"admin.marketing.title": "Marketing — E-Mail-Kampagnen",
"admin.marketing.unsubscribedNote": "{count} abgemeldete Kontakte werden von jeder Sendung ausgeschlossen.",
"admin.models.addModel": "Modell hinzufügen",
"admin.models.businessBadge": "Business-Tarif",
"admin.models.cancel": "Abbrechen",
"admin.models.catalog": "OpenRouter-Katalog",
"admin.models.catalogErrorDesc": "OpenRouter-Katalog konnte nicht geladen werden.",
"admin.models.catalogErrorTitle": "Katalog nicht verfügbar",
"admin.models.customBadge": "Individuelle Stufe",
"admin.models.customNote": "Sondermodelle, im Einzelfall mit dem Kunden vereinbart.",
"admin.models.defaultBadge": "Standard",
"admin.models.emptyTier": "Kein Modell: Die offizielle Modellrange des Tarifs wird verwendet.",
"admin.models.enterpriseBadge": "Enterprise-Tarif",
"admin.models.essentialBadge": "KI-Stufe Basis",
"admin.models.essentialCost": "— Abrechnungsfaktor 1",
"admin.models.fallbackFirst": "(Fallback Nr. 1)",
"admin.models.loadErrorDesc": "HTTP {status} — prüfen Sie Ihr Admin-Token.",
"admin.models.loadErrorTitle": "Ladefehler",
"admin.models.matrixDesc": "Aktive Modelle pro Stufe — die Reihenfolge der Liste ist die Fallback-Priorität. Der Radioknopf wählt das Standardmodell, sofort und ohne neues Deployment wirksam.",
"admin.models.matrixTitle": "Modellmatrix pro Tarif",
"admin.models.missingConfig": "KI-Stufen-Konfiguration nicht gefunden. Bitte Seite neu laden.",
"admin.models.moveDown": "Nach unten",
"admin.models.moveUp": "Nach oben",
"admin.models.networkDesc": "Backend nicht erreichbar.",
"admin.models.networkTitle": "Netzwerkfehler",
"admin.models.premiumBadge": "KI-Stufe Premium",
"admin.models.premiumCost": "— Abrechnungsfaktor 5",
"admin.models.premiumReservedNote": "Den Tarifen Business und Enterprise vorbehalten (Engine „openrouter_premium“).",
"admin.models.proBadge": "Pro-Tarif",
"admin.models.remove": "Entfernen",
"admin.models.save": "Speichern",
"admin.models.saveErrorTitle": "Speicherfehler",
"admin.models.saveNetworkDesc": "Konfiguration konnte nicht gespeichert werden.",
"admin.models.savedDesc": "Das neue Standardmodell wird ab der nächsten Übersetzung verwendet — ohne neues Deployment.",
"admin.models.savedTitle": "Modelle gespeichert",
"admin.models.saving": "Speichern...",
"admin.models.setDefault": "{model} als Standardmodell festlegen",
"admin.models.sharedTierNote": "Gemeinsame Stufe: Der Business-Tarif nutzt die Basis-Stufe ebenfalls für seine Engine „openrouter“ — die obige Liste gilt für beide Tarife.",
"admin.models.subtitle": "Matrix Tarife → KI-Stufen. Das tatsächlich pro Übersetzung verwendete Modell ist das der KI-Stufe des Tarifs: Ein Pro-Tarif kann nie ein Premium-Modell auslösen.",
"admin.models.title": "Modelle & Abonnements",
"admin.stats.aiTiers": "KI-Stufen (30 T)",
"admin.stats.includingCredits": "davon {amount} Credits",
"admin.stats.mrr": "Geschätzter MRR",
"admin.stats.noTranslationsYet": "Keine Übersetzungen der letzten 30 Tage in der Datenbank: Die Stufenverteilung füllt sich mit den nächsten Übersetzungen.",
"admin.stats.payments30": "{count} Zahlung(en) in 30 Tagen",
"admin.stats.refreshing": "Aktualisierung...",
"admin.stats.revenue30": "Umsatz (30 Tage)",
"admin.stats.revenueTotal": "Eingenommener Umsatz (gesamt)",
"admin.stats.tiersSub": "Basis / Premium · klassisch {classic} · sonstige {other}",
"admin.stats.unavailable": "Geschäftszahlen nicht verfügbar ({error}).",
"admin.stats.waitlist": "Warteliste",
"admin.stats.waitlistSub": "Einträge auf der Warteliste"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "Für anspruchsvolle Profis",
"landing.pricing.pro.f1": "200 Dokumente / Monat",
"landing.pricing.pro.f2": "Bis zu 200 Seiten pro Dokument",
"landing.pricing.pro.f3": "KI-gestützte Übersetzung",
"landing.pricing.pro.f3": "Basis-KI: DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google inklusive",
"landing.pricing.pro.f5": "Individuelle Glossare & Prompts",
"landing.pricing.pro.f6": "Prioritäts-Support",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "Für Teams mit hohem Bedarf",
"landing.pricing.business.f1": "1 000 Dokumente / Monat",
"landing.pricing.business.f2": "Bis zu 500 Seiten pro Dokument",
"landing.pricing.business.f3": "Premium-KI (Claude)",
"landing.pricing.business.f3": "Premium-KI (Claude 5)",
"landing.pricing.business.f4": "Alle Anbieter + API-Zugang",
"landing.pricing.business.f5": "Webhooks & Automatisierung",
"landing.pricing.business.f6": "5 Teamplätze",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "DOCX, XLSX, PPTX oder PDF Dateien unterstützt",
"landing.translate.aiAnalysis": "KI-Analyse aktiv",
"landing.translate.processing": "Verarbeitung läuft",
"landing.translate.preservingLayout": "Ihr Layout wird beibehalten"
"landing.translate.preservingLayout": "Ihr Layout wird beibehalten",
"landing.beforeAfter.seal": "Gleiches Layout, Wort für Wort",
"landing.beforeAfter.proof1": "SmartArt-Diagramme werden neu aufgebaut, nicht abgeflacht",
"landing.beforeAfter.proof2": "Diagrammreihen und Achsen übersetzt",
"landing.beforeAfter.proof3": "Verzeichnisse in der Zielsprache neu erstellt",
"landing.beforeAfter.targetTitle": "Technisches Datenblatt — Luftaufbereitung",
"landing.beforeAfter.targetPara1": "Die Lüftungsanlage muss vor Ende des zweiten Quartals in Betrieb genommen werden.",
"landing.beforeAfter.targetPara2Before": "Die",
"landing.beforeAfter.targetTerm": "Lüftungseinheit",
"landing.beforeAfter.targetPara2After": "muss gemäß Planung der Filterklasse F7 entsprechen.",
"landing.beforeAfter.targetItem1": "Wärmebelastung: 42 kW bei Nenndurchfluss",
"landing.beforeAfter.targetItem2": "Schallpegel unter 45 dB(A) bei 3 m",
"landing.formats.pill": "KOMPATIBILITÄT",
"landing.hero.visualCaption": "Gleiches Layout, neue Sprache — nichts anderes verändert sich",
"landing.pricing.free.name": "Kostenlos",
"landing.pricing.free.desc": "Ideal zum Entdecken der App",
"landing.pricing.free.cta": "Diesen Plan wählen",
"landing.pricing.enterprise.name": "Enterprise",
"landing.pricing.enterprise.desc": "Maßgeschneiderte Lösungen für große Organisationen",
"landing.pricing.enterprise.cta": "Kontakt aufnehmen",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "90 Tage Verlauf",
"pricing.plans.business.feat1": "1.000 Dokumente / Monat",
"pricing.plans.business.feat2": "Bis zu 500 Seiten pro Dokument",
"pricing.plans.business.feat3": "Basis- + Premium-KI (Claude Haiku)",
"pricing.plans.business.feat3": "Basis-KI + Premium-KI (Claude 5)",
"pricing.plans.business.feat4": "Alle Übersetzungsanbieter",
"pricing.plans.business.feat5": "Dateien bis zu 50 MB",
"pricing.plans.business.feat6": "API-Zugang (10.000 Aufrufe/Monat)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "1 Jahr Verlauf",
"pricing.plans.business.feat10": "Erweiterte Analysen",
"pricing.plans.enterprise.feat1": "Unbegrenzte Dokumente",
"pricing.plans.enterprise.feat2": "Alle KI-Modelle (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "Alle KI-Modelle (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "On-Premise oder dedizierte Cloud",
"pricing.plans.enterprise.feat4": "99,9 % SLA garantiert",
"pricing.plans.enterprise.feat5": "24/7 dedizierter Support",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "Ultraschnelle Multi-Thread-KI",
"pricing.trust.availability.title": "24/7 verfügbar",
"pricing.trust.availability.sub": "99,9 % garantierte Verfügbarkeit",
"pricing.aiModels.title": "Unsere KI-Modelle — März 2026",
"pricing.aiModels.title": "Unsere KI-Modelle — September 2026",
"pricing.aiModels.essential.title": "KI-Basisübersetzung",
"pricing.aiModels.essential.plan": "Pro-Plan",
"pricing.aiModels.essential.descPrefix": "Basierend auf",
"pricing.aiModels.essential.descSuffix": "— dem kosteneffizientesten KI-Modell 2026. Qualität vergleichbar mit Frontier-Modellen zu einem Bruchteil der Kosten.",
"pricing.aiModels.essential.modelName": "unser Essentielles KI-Modell",
"pricing.aiModels.essential.context": "163K Token Kontext",
"pricing.aiModels.essential.value": "Hervorragendes Preis-Leistungs-Verhältnis",
"pricing.aiModels.essential.descSuffix": "— die KI-Modelle mit dem besten Preis-Leistungs-Verhältnis 2026.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash und MiniMax M3",
"pricing.aiModels.essential.context": "Bis zu 1,3 M Kontext (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "Das beste Preis-Leistungs-Verhältnis",
"pricing.aiModels.premium.title": "KI-Premiumübersetzung",
"pricing.aiModels.premium.plan": "Business-Plan",
"pricing.aiModels.premium.descPrefix": "Basierend auf",
"pricing.aiModels.premium.descSuffix": "von Anthropic — präzise bei juristischen, medizinischen und komplexen technischen Dokumenten.",
"pricing.aiModels.premium.context": "200K Token Kontext",
"pricing.aiModels.premium.context": "1M Kontext",
"pricing.aiModels.premium.precision": "Höchste Genauigkeit",
"pricing.faq.title": "Häufig gestellte Fragen",
"pricing.faq.q1": "Kann ich jederzeit den Plan wechseln?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "Was ist die «KI-Basisübersetzung»?",
"pricing.faq.a2": "Unser KI-Motor versteht den Kontext Ihrer Dokumente, erhält das Layout und verarbeitet Fachbegriffe deutlich besser als klassische Übersetzungen.",
"pricing.faq.q3": "Was ist der Unterschied zwischen Basis- und Premium-KI?",
"pricing.faq.a3": "Die Basis-KI nutzt ein optimiertes Modell (hervorragendes Preis-Leistungs-Verhältnis). Die Premium-KI verwendet Claude 3.5 Haiku von Anthropic und ist genauer bei juristischen, medizinischen und komplexen technischen Dokumenten.",
"pricing.faq.a3": "Die Basis-KI nutzt DeepSeek V4 Flash, GLM-5.3 Flash und MiniMax M3 (hervorragendes Preis-Leistungs-Verhältnis). Die Premium-KI verwendet Claude 5 von Anthropic und ist genauer bei juristischen, medizinischen und komplexen technischen Dokumenten.",
"pricing.faq.q4": "Werden meine Dokumente nach der Übersetzung gespeichert?",
"pricing.faq.a4": "Übersetzte Dateien sind je nach Plan verfügbar (30 Tage Starter, 90 Tage Pro, 1 Jahr Business). Sie sind im Ruhezustand und bei der Übertragung verschlüsselt.",
"pricing.faq.q5": "Was passiert, wenn ich mein monatliches Kontingent überschreite?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "Fehler beim Erstellen der Zahlung.",
"pricing.dashboard": "Dashboard",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "Ab 0,09 $ pro Million Token",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "Alternativen: DeepSeek V4 Pro und GLM-5.3",
"pricing.confirm.title": "Bestätigen Sie Ihr Abonnement",
"pricing.confirm.subtitle": "Sie werden zu unserem sicheren Zahlungsanbieter weitergeleitet.",
"pricing.confirm.cancel": "Abbrechen",
"pricing.confirm.cta": "Weiter zur Zahlung",
"pricing.confirm.year": "Jahr",
"pricing.confirm.month": "Monat",
"pricing.confirm.monthlyEquivalent": "Jährliche Abrechnung — entspricht {price} € / Monat.",
"pricing.confirm.secureNote": "Jederzeit über Ihr Profil kündbar. Die Zahlung wird von Stripe abgewickelt; Ihre Kartendaten erreichen nie unsere Server.",
"pricing.enterprise.subject": "Enterprise-Angebot",
"pricing.enterpriseBand.cta": "Kontakt aufnehmen",
"pricing.enterpriseBand.text": "Volumen, dedizierte Engines, On-Premise-Optionen — sprechen wir darüber.",
"pricing.error.server": "Serverfehler {status}",
"pricing.freeBand.cta": "Kostenlos starten",
"pricing.freeBand.text": "Nur ausprobieren? Kostenlos starten — 5 Dokumente pro Monat, ohne Karte.",
"pricing.header.titleBase": "Ein Plan für",
"pricing.header.titleAccent": "jeden Bedarf",
"pricing.toast.close": "Schließen",
"pricing.aiModels.premium.price": "2 $ / 10 $ pro 1M Token"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "Einheitlicher Zugriff auf die besten Open-Source-Modelle, optimiert für Übersetzung.",
"providerTheme.openrouter_premium.badge": "Ultra",
"providerTheme.openrouter_premium.subBadge": "Maximaler Kontext",
"providerTheme.openrouter_premium.desc": "Unterstützt durch modernste Modelle (GPT-4o, Claude Sonnet 4.6) für lange Dokumente.",
"providerTheme.openrouter_premium.desc": "Unterstützt durch modernste Modelle (GPT-4o, Claude 5) für lange Dokumente.",
"providerTheme.zai.badge": "Spezialisiert",
"providerTheme.zai.subBadge": "Finanzen & Recht",
"providerTheme.zai.desc": "Modell feinabgestimmt auf anspruchsvolle Geschäftsterminologien (Recht, Finanzen).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "Providers",
"admin.nav.system": "System",
"admin.nav.logs": "Logs",
"admin.nav.stats": "Statistics",
"admin.users.title": "User Management",
"admin.users.subtitle": "View and manage user accounts",
"admin.users.planUpdated": "Plan updated",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "Waiting for data...",
"admin.system.purging": "Purging...",
"admin.system.clean": "Clean",
"admin.system.purge": "Purge"
"admin.system.purge": "Purge",
"admin.nav.models": "Models & subscriptions",
"admin.nav.marketing": "Marketing",
"admin.marketing.audience": "Audience",
"admin.marketing.audienceAllUsers": "All accounts",
"admin.marketing.audienceInactive": "Accounts inactive for 30 days",
"admin.marketing.audiencePlaceholder": "Choose an audience",
"admin.marketing.audiencePlanBusiness": "Business plan",
"admin.marketing.audiencePlanEnterprise": "Enterprise plan",
"admin.marketing.audiencePlanFree": "Free plan",
"admin.marketing.audiencePlanPro": "Pro plan",
"admin.marketing.audiencePlanStarter": "Starter plan",
"admin.marketing.audienceWaitlist": "Waitlist",
"admin.marketing.badgeReal": "real",
"admin.marketing.badgeTest": "test",
"admin.marketing.confirmSend": "Send this email to {count} recipient(s) (“{audience}”)?",
"admin.marketing.footerNote": "A footer with the unsubscribe link is automatically added when sending.",
"admin.marketing.hidePreview": "Hide preview",
"admin.marketing.history": "Send history",
"admin.marketing.historyFailedSuffix": ", {count} failed",
"admin.marketing.historySent": "{sent}/{total} sent",
"admin.marketing.html": "HTML content",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "Please fill in the subject and the HTML.",
"admin.marketing.incompleteTitle": "Incomplete content",
"admin.marketing.loadErrorTitle": "Loading error",
"admin.marketing.localCheckUnavailable": "Local check unavailable in this browser: the server will verify the prior test send.",
"admin.marketing.networkDesc": "Cannot reach the backend.",
"admin.marketing.newCampaign": "New campaign",
"admin.marketing.noHistory": "No send recorded.",
"admin.marketing.preview": "Preview",
"admin.marketing.previewEmpty": "Preview: paste your HTML next to this panel.",
"admin.marketing.previewTitle": "Email preview",
"admin.marketing.recipientsAvailable": "{count} recipient(s) available after excluding unsubscribed contacts.",
"admin.marketing.sendReal": "Send to {count} recipient(s)",
"admin.marketing.sendRefusedTitle": "Send refused",
"admin.marketing.sendTest": "Send test",
"admin.marketing.sendingDesc": "{count} email(s) queued for sending (0.2 s interval). Unsubscribed contacts are excluded.",
"admin.marketing.sendingTitle": "Send in progress",
"admin.marketing.subject": "Subject",
"admin.marketing.subjectPlaceholder": "E.g.: Your translation is waiting — 20% off for 7 days",
"admin.marketing.subtitle": "Send emails to an audience, with a mandatory test send, automatic unsubscribe link and full history.",
"admin.marketing.testDoneDesc": "Email received at {email}",
"admin.marketing.testDoneTitle": "Test send done",
"admin.marketing.testEmail": "Test email (optional)",
"admin.marketing.testEmailPlaceholder": "Otherwise: SMTP sender address",
"admin.marketing.testFailedTitle": "Test send failed",
"admin.marketing.testRequiredHint": "A real send requires a prior test send of this exact content (verified by the server).",
"admin.marketing.testValidated": "Test send validated for this content.",
"admin.marketing.title": "Marketing — email campaigns",
"admin.marketing.unsubscribedNote": "{count} unsubscribed contact(s) will be excluded from any send.",
"admin.models.addModel": "Add a model",
"admin.models.businessBadge": "Business plan",
"admin.models.cancel": "Cancel",
"admin.models.catalog": "OpenRouter catalog",
"admin.models.catalogErrorDesc": "Failed to load the OpenRouter catalog.",
"admin.models.catalogErrorTitle": "Catalog unavailable",
"admin.models.customBadge": "Custom tier",
"admin.models.customNote": "Bespoke models, agreed case by case with the customer.",
"admin.models.defaultBadge": "default",
"admin.models.emptyTier": "No model: the plan's official range will be used.",
"admin.models.enterpriseBadge": "Enterprise plan",
"admin.models.essentialBadge": "Essential AI tier",
"admin.models.essentialCost": "— billed at cost factor 1",
"admin.models.fallbackFirst": "(fallback #1)",
"admin.models.loadErrorDesc": "HTTP {status} — check your admin token.",
"admin.models.loadErrorTitle": "Loading error",
"admin.models.matrixDesc": "Active models per tier — the list order is the fallback priority. The radio button picks the default model, applied immediately without redeployment.",
"admin.models.matrixTitle": "Model matrix by plan",
"admin.models.missingConfig": "AI tier configuration not found. Reload the page.",
"admin.models.moveDown": "Move down",
"admin.models.moveUp": "Move up",
"admin.models.networkDesc": "Cannot reach the backend.",
"admin.models.networkTitle": "Network error",
"admin.models.premiumBadge": "Premium AI tier",
"admin.models.premiumCost": "— billed at cost factor 5",
"admin.models.premiumReservedNote": "Reserved for Business and Enterprise plans (“openrouter_premium” engine).",
"admin.models.proBadge": "Pro plan",
"admin.models.remove": "Remove",
"admin.models.save": "Save",
"admin.models.saveErrorTitle": "Save error",
"admin.models.saveNetworkDesc": "Could not save the configuration.",
"admin.models.savedDesc": "The new default model applies from the next translation, without redeployment.",
"admin.models.savedTitle": "Models saved",
"admin.models.saving": "Saving...",
"admin.models.setDefault": "Set {model} as default model",
"admin.models.sharedTierNote": "Shared tier: the Business plan also uses the Essential tier for its “openrouter” engine — the list above applies to both plans.",
"admin.models.subtitle": "Plans → AI tiers matrix. The model actually used per translation is the plan's tier model: a Pro plan can never trigger a Premium model.",
"admin.models.title": "Models & subscriptions",
"admin.stats.aiTiers": "AI tiers (30 d)",
"admin.stats.includingCredits": "including {amount} in credits",
"admin.stats.mrr": "Estimated MRR",
"admin.stats.noTranslationsYet": "No translation stored in the last 30 days: the AI tier breakdown will fill in with upcoming translations.",
"admin.stats.payments30": "{count} payment(s) in 30 days",
"admin.stats.refreshing": "Refreshing...",
"admin.stats.revenue30": "Revenue (30 days)",
"admin.stats.revenueTotal": "Total collected revenue",
"admin.stats.tiersSub": "Essential / Premium · classic {classic} · other {other}",
"admin.stats.unavailable": "Business statistics unavailable ({error}).",
"admin.stats.waitlist": "Waitlist",
"admin.stats.waitlistSub": "people waiting"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "For demanding professionals",
"landing.pricing.pro.f1": "200 documents / month",
"landing.pricing.pro.f2": "Up to 200 pages per doc",
"landing.pricing.pro.f3": "AI-powered translation",
"landing.pricing.pro.f3": "Essential AI: DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google included",
"landing.pricing.pro.f5": "Custom glossaries & prompts",
"landing.pricing.pro.f6": "Priority support",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "For teams with high-volume needs",
"landing.pricing.business.f1": "1,000 documents / month",
"landing.pricing.business.f2": "Up to 500 pages per doc",
"landing.pricing.business.f3": "Premium AI (Claude)",
"landing.pricing.business.f3": "Premium AI (Claude 5)",
"landing.pricing.business.f4": "All providers + API access",
"landing.pricing.business.f5": "Webhooks & automation",
"landing.pricing.business.f6": "5 team seats",

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "90-day history",
"pricing.plans.business.feat1": "1,000 documents / month",
"pricing.plans.business.feat2": "Up to 500 pages per document",
"pricing.plans.business.feat3": "Essential + Premium AI (Claude Haiku)",
"pricing.plans.business.feat3": "Essential AI + Premium AI (Claude 5)",
"pricing.plans.business.feat4": "All translation providers",
"pricing.plans.business.feat5": "Files up to 50 MB",
"pricing.plans.business.feat6": "API access (10,000 calls/month)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "1-year history",
"pricing.plans.business.feat10": "Advanced analytics",
"pricing.plans.enterprise.feat1": "Unlimited documents",
"pricing.plans.enterprise.feat2": "All AI models (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "All AI models (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "On-premise or dedicated cloud deployment",
"pricing.plans.enterprise.feat4": "99.9% SLA guaranteed",
"pricing.plans.enterprise.feat5": "24/7 dedicated support",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "Ultra-fast multi-threaded AI",
"pricing.trust.availability.title": "Available 24/7",
"pricing.trust.availability.sub": "99.9% guaranteed uptime",
"pricing.aiModels.title": "Our AI Models — March 2026",
"pricing.aiModels.title": "Our AI Models — September 2026",
"pricing.aiModels.essential.title": "Essential AI Translation",
"pricing.aiModels.essential.plan": "Pro Plan",
"pricing.aiModels.essential.descPrefix": "Based on",
"pricing.aiModels.essential.descSuffix": "— the most cost-effective AI model of 2026. Quality comparable to frontier models at a fraction of the cost.",
"pricing.aiModels.essential.modelName": "our Essential AI model",
"pricing.aiModels.essential.context": "163K tokens of context",
"pricing.aiModels.essential.value": "Excellent value for money",
"pricing.aiModels.essential.descSuffix": "— the most cost-effective AI models of 2026.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash and MiniMax M3",
"pricing.aiModels.essential.context": "Up to 1.3M context (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "The best value for money",
"pricing.aiModels.premium.title": "Premium AI Translation",
"pricing.aiModels.premium.plan": "Business Plan",
"pricing.aiModels.premium.descPrefix": "Based on",
"pricing.aiModels.premium.descSuffix": "by Anthropic — accurate on legal, medical and complex technical documents.",
"pricing.aiModels.premium.context": "200K tokens of context",
"pricing.aiModels.premium.context": "1M context",
"pricing.aiModels.premium.precision": "Best accuracy",
"pricing.faq.title": "Frequently asked questions",
"pricing.faq.q1": "Can I change plans at any time?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "What is \\\"Essential AI Translation\\\"?",
"pricing.faq.a2": "It's our AI engine. It understands your documents' context, preserves layout and handles technical terms much better than classic translation.",
"pricing.faq.q3": "What's the difference between Essential and Premium AI?",
"pricing.faq.a3": "Essential AI uses an optimized model (excellent value for money). Premium AI uses Anthropic's Claude Sonnet 4.6, more accurate on legal, medical and complex technical documents.",
"pricing.faq.a3": "Essential AI runs on DeepSeek V4 Flash, GLM-5.3 Flash and MiniMax M3 (excellent value for money). Premium AI uses Anthropic's Claude 5, more accurate on legal, medical and complex technical documents.",
"pricing.faq.q4": "Are my documents kept after translation?",
"pricing.faq.a4": "Translated files are available according to your plan (30 days Starter, 90 days Pro, 1 year Business). They are encrypted at rest and in transit.",
"pricing.faq.q5": "What happens if I exceed my monthly quota?",
@@ -163,5 +163,9 @@
"pricing.freeBand.text": "Just want to try? Start free — 5 documents per month, no card required.",
"pricing.freeBand.cta": "Start free",
"pricing.enterpriseBand.text": "Volume, dedicated engines, on-premise options — let's talk.",
"pricing.enterpriseBand.cta": "Contact us"
"pricing.enterpriseBand.cta": "Contact us",
"pricing.aiModels.essential.price": "From $0.09 per million tokens",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "Alternatives: DeepSeek V4 Pro and GLM-5.3",
"pricing.aiModels.premium.price": "$2 / $10 per 1M tokens"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "Unified access to the best open-source models optimized for translation.",
"providerTheme.openrouter_premium.badge": "Ultra",
"providerTheme.openrouter_premium.subBadge": "Maximum context",
"providerTheme.openrouter_premium.desc": "Assisted by state-of-the-art models (GPT-4o, Claude Sonnet 4.6) for long documents.",
"providerTheme.openrouter_premium.desc": "Assisted by state-of-the-art models (GPT-4o, Claude 5) for long documents.",
"providerTheme.zai.badge": "Specialized",
"providerTheme.zai.subBadge": "Finance & Law",
"providerTheme.zai.desc": "Model fine-tuned for demanding business terminologies (legal, finance).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "Proveedores",
"admin.nav.system": "Sistema",
"admin.nav.logs": "Registros",
"admin.nav.stats": "Estadísticas",
"admin.users.title": "Gestión de Usuarios",
"admin.users.subtitle": "Ver y gestionar cuentas de usuario",
"admin.users.planUpdated": "Plan actualizado",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "Esperando datos...",
"admin.system.purging": "Purgando...",
"admin.system.clean": "Limpiar",
"admin.system.purge": "Purgar"
"admin.system.purge": "Purgar",
"admin.nav.models": "Modelos y suscripciones",
"admin.nav.marketing": "Marketing",
"admin.marketing.audience": "Audiencia",
"admin.marketing.audienceAllUsers": "Todas las cuentas",
"admin.marketing.audienceInactive": "Cuentas inactivas desde hace 30 días",
"admin.marketing.audiencePlaceholder": "Elegir una audiencia",
"admin.marketing.audiencePlanBusiness": "Plan Business",
"admin.marketing.audiencePlanEnterprise": "Plan Enterprise",
"admin.marketing.audiencePlanFree": "Plan Gratuito",
"admin.marketing.audiencePlanPro": "Plan Pro",
"admin.marketing.audiencePlanStarter": "Plan Starter",
"admin.marketing.audienceWaitlist": "Lista de espera",
"admin.marketing.badgeReal": "real",
"admin.marketing.badgeTest": "prueba",
"admin.marketing.confirmSend": "¿Enviar este correo a {count} destinatario(s) («{audience}»)?",
"admin.marketing.footerNote": "Un pie de página con el enlace de baja se añade automáticamente al enviar.",
"admin.marketing.hidePreview": "Ocultar vista previa",
"admin.marketing.history": "Historial de envíos",
"admin.marketing.historyFailedSuffix": ", {count} fallos",
"admin.marketing.historySent": "{sent}/{total} enviados",
"admin.marketing.html": "Contenido HTML",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "Rellena el asunto y el HTML.",
"admin.marketing.incompleteTitle": "Contenido incompleto",
"admin.marketing.loadErrorTitle": "Error de carga",
"admin.marketing.localCheckUnavailable": "Verificación local no disponible en este navegador: el servidor controlará el envío de prueba previo.",
"admin.marketing.networkDesc": "No se puede contactar con el backend.",
"admin.marketing.newCampaign": "Nuevo envío",
"admin.marketing.noHistory": "Ningún envío registrado.",
"admin.marketing.preview": "Vista previa",
"admin.marketing.previewEmpty": "Vista previa: pega tu HTML al lado.",
"admin.marketing.previewTitle": "Vista previa del correo",
"admin.marketing.recipientsAvailable": "{count} destinatario(s) disponibles tras excluir las bajas.",
"admin.marketing.sendReal": "Enviar a {count} destinatario(s)",
"admin.marketing.sendRefusedTitle": "Envío rechazado",
"admin.marketing.sendTest": "Envío de prueba",
"admin.marketing.sendingDesc": "{count} correo(s) en cola de envío (intervalo de 0,2 s). Las bajas quedan excluidas.",
"admin.marketing.sendingTitle": "Envío en curso",
"admin.marketing.subject": "Asunto",
"admin.marketing.subjectPlaceholder": "Ej.: Tu traducción te espera — 20 % durante 7 días",
"admin.marketing.subtitle": "Envío de correos a una audiencia, con envío de prueba obligatorio, enlace de baja automático e historial completo.",
"admin.marketing.testDoneDesc": "Correo recibido en {email}",
"admin.marketing.testDoneTitle": "Envío de prueba realizado",
"admin.marketing.testEmail": "Correo de prueba (opcional)",
"admin.marketing.testEmailPlaceholder": "Si no: dirección remitente SMTP",
"admin.marketing.testFailedTitle": "Fallo del envío de prueba",
"admin.marketing.testRequiredHint": "El envío real exige un envío de prueba previo de este contenido exacto (verificado por el servidor).",
"admin.marketing.testValidated": "Envío de prueba validado para este contenido.",
"admin.marketing.title": "Marketing — envíos de correo",
"admin.marketing.unsubscribedNote": "{count} contacto(s) de baja serán excluidos de todo envío.",
"admin.models.addModel": "Añadir un modelo",
"admin.models.businessBadge": "Plan Business",
"admin.models.cancel": "Cancelar",
"admin.models.catalog": "Catálogo de OpenRouter",
"admin.models.catalogErrorDesc": "No se pudo cargar el catálogo de OpenRouter.",
"admin.models.catalogErrorTitle": "Catálogo no disponible",
"admin.models.customBadge": "Nivel personalizado",
"admin.models.customNote": "Modelos a medida, definidos caso por caso con el cliente.",
"admin.models.defaultBadge": "por defecto",
"admin.models.emptyTier": "Sin modelos: se usará la gama oficial del plan.",
"admin.models.enterpriseBadge": "Plan Enterprise",
"admin.models.essentialBadge": "Nivel de IA Esencial",
"admin.models.essentialCost": "— facturado con factor de coste 1",
"admin.models.fallbackFirst": "(respaldo n.º 1)",
"admin.models.loadErrorDesc": "HTTP {status} — comprueba tu token de administrador.",
"admin.models.loadErrorTitle": "Error de carga",
"admin.models.matrixDesc": "Modelos activos por nivel — el orden de la lista es la prioridad de respaldo. El botón de opción elige el modelo por defecto, aplicado al instante sin redespliegue.",
"admin.models.matrixTitle": "Matriz de modelos por plan",
"admin.models.missingConfig": "Configuración de niveles de IA no encontrada. Recarga la página.",
"admin.models.moveDown": "Bajar",
"admin.models.moveUp": "Subir",
"admin.models.networkDesc": "No se puede contactar con el backend.",
"admin.models.networkTitle": "Error de red",
"admin.models.premiumBadge": "Nivel de IA Premium",
"admin.models.premiumCost": "— facturado con factor de coste 5",
"admin.models.premiumReservedNote": "Reservado a los planes Business y Enterprise (motor «openrouter_premium»).",
"admin.models.proBadge": "Plan Pro",
"admin.models.remove": "Quitar",
"admin.models.save": "Guardar",
"admin.models.saveErrorTitle": "Error al guardar",
"admin.models.saveNetworkDesc": "No se pudo guardar la configuración.",
"admin.models.savedDesc": "El nuevo modelo por defecto se usa desde la siguiente traducción, sin redespliegue.",
"admin.models.savedTitle": "Modelos guardados",
"admin.models.saving": "Guardando...",
"admin.models.setDefault": "Definir {model} como modelo por defecto",
"admin.models.sharedTierNote": "Nivel compartido: el plan Business también usa el nivel Esencial con su motor «openrouter» — la lista de arriba se aplica a ambos planes.",
"admin.models.subtitle": "Matriz planes → niveles de IA. El modelo realmente usado en cada traducción es el del nivel del plan: un plan Pro nunca puede disparar un modelo Premium.",
"admin.models.title": "Modelos y suscripciones",
"admin.stats.aiTiers": "Niveles de IA (30 d)",
"admin.stats.includingCredits": "incluidos {amount} en créditos",
"admin.stats.mrr": "MRR estimado",
"admin.stats.noTranslationsYet": "Sin traducciones registradas en los últimos 30 días: el reparto por niveles se completará con las próximas traducciones.",
"admin.stats.payments30": "{count} pago(s) en 30 días",
"admin.stats.refreshing": "Actualizando...",
"admin.stats.revenue30": "Ingresos (30 días)",
"admin.stats.revenueTotal": "Ingresos cobrados (total)",
"admin.stats.tiersSub": "Esencial / Premium · clásico {classic} · otro {other}",
"admin.stats.unavailable": "Estadísticas de negocio no disponibles ({error}).",
"admin.stats.waitlist": "Lista de espera",
"admin.stats.waitlistSub": "inscritos en espera"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "Para profesionales exigentes",
"landing.pricing.pro.f1": "200 documentos / mes",
"landing.pricing.pro.f2": "Hasta 200 páginas por doc",
"landing.pricing.pro.f3": "Traducción con IA",
"landing.pricing.pro.f3": "IA Esencial: DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google incluidos",
"landing.pricing.pro.f5": "Glosarios y prompts personalizados",
"landing.pricing.pro.f6": "Soporte prioritario",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "Para equipos con grandes necesidades",
"landing.pricing.business.f1": "1 000 documentos / mes",
"landing.pricing.business.f2": "Hasta 500 páginas por doc",
"landing.pricing.business.f3": "IA Premium (Claude)",
"landing.pricing.business.f3": "IA Premium (Claude 5)",
"landing.pricing.business.f4": "Todos los proveedores + API",
"landing.pricing.business.f5": "Webhooks y automatización",
"landing.pricing.business.f6": "5 puestos de equipo",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "Archivos DOCX, XLSX, PPTX o PDF compatibles",
"landing.translate.aiAnalysis": "Análisis IA Activo",
"landing.translate.processing": "Procesando",
"landing.translate.preservingLayout": "Tu diseño se está preservando"
"landing.translate.preservingLayout": "Tu diseño se está preservando",
"landing.beforeAfter.seal": "El mismo diseño, palabra por palabra",
"landing.beforeAfter.proof1": "Los diagramas SmartArt se reconstruyen, no se aplanan",
"landing.beforeAfter.proof2": "Series y ejes de los gráficos traducidos",
"landing.beforeAfter.proof3": "Índices regenerados en el idioma de destino",
"landing.beforeAfter.targetTitle": "Pliego técnico — Tratamiento de aire",
"landing.beforeAfter.targetPara1": "La instalación de ventilación debe ponerse en servicio antes de finales del segundo trimestre.",
"landing.beforeAfter.targetPara2Before": "La",
"landing.beforeAfter.targetTerm": "unidad de tratamiento de aire",
"landing.beforeAfter.targetPara2After": "debe cumplir la clase de filtro F7 según el calendario.",
"landing.beforeAfter.targetItem1": "Carga térmica: 42 kW a caudal nominal",
"landing.beforeAfter.targetItem2": "Nivel sonoro inferior a 45 dB(A) a 3 m",
"landing.formats.pill": "COMPATIBILIDAD",
"landing.hero.visualCaption": "El mismo diseño, otro idioma — nada más cambia",
"landing.pricing.free.name": "Gratis",
"landing.pricing.free.desc": "Ideal para descubrir la aplicación",
"landing.pricing.free.cta": "Elegir este plan",
"landing.pricing.enterprise.name": "Empresas",
"landing.pricing.enterprise.desc": "Soluciones a medida para grandes organizaciones",
"landing.pricing.enterprise.cta": "Contáctenos",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "Historial de 90 días",
"pricing.plans.business.feat1": "1 000 documentos / mes",
"pricing.plans.business.feat2": "Hasta 500 páginas por documento",
"pricing.plans.business.feat3": "IA Esencial + Premium (Claude Haiku)",
"pricing.plans.business.feat3": "IA Esencial + IA Premium (Claude 5)",
"pricing.plans.business.feat4": "Todos los proveedores de traducción",
"pricing.plans.business.feat5": "Archivos de hasta 50 MB",
"pricing.plans.business.feat6": "Acceso API (10 000 llamadas/mes)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "Historial de 1 año",
"pricing.plans.business.feat10": "Analíticas avanzadas",
"pricing.plans.enterprise.feat1": "Documentos ilimitados",
"pricing.plans.enterprise.feat2": "Todos los modelos de IA (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "Todos los modelos de IA (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "Implementación local o en nube dedicada",
"pricing.plans.enterprise.feat4": "SLA 99,9 % garantizado",
"pricing.plans.enterprise.feat5": "Soporte dedicado 24/7",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "IA multiproceso ultrarrápida",
"pricing.trust.availability.title": "Disponible 24/7",
"pricing.trust.availability.sub": "Disponibilidad garantizada del 99,9 %",
"pricing.aiModels.title": "Nuestros modelos de IA — Marzo 2026",
"pricing.aiModels.title": "Nuestros modelos de IA — Septiembre 2026",
"pricing.aiModels.essential.title": "Traducción IA Esencial",
"pricing.aiModels.essential.plan": "Plan Pro",
"pricing.aiModels.essential.descPrefix": "Basado en",
"pricing.aiModels.essential.descSuffix": "— el modelo de IA más rentable de 2026. Calidad comparable a los modelos frontier a una fracción del coste.",
"pricing.aiModels.essential.modelName": "nuestro modelo IA Esencial",
"pricing.aiModels.essential.context": "163K tokens de contexto",
"pricing.aiModels.essential.value": "Excelente relación calidad-precio",
"pricing.aiModels.essential.descSuffix": "— los modelos de IA con la mejor relación calidad-precio de 2026.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash y MiniMax M3",
"pricing.aiModels.essential.context": "Hasta 1,3 M de contexto (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "La mejor relación calidad-precio",
"pricing.aiModels.premium.title": "Traducción IA Premium",
"pricing.aiModels.premium.plan": "Plan Business",
"pricing.aiModels.premium.descPrefix": "Basado en",
"pricing.aiModels.premium.descSuffix": "de Anthropic — preciso en documentos jurídicos, médicos y técnicos complejos.",
"pricing.aiModels.premium.context": "200K tokens de contexto",
"pricing.aiModels.premium.context": "1M de contexto",
"pricing.aiModels.premium.precision": "Máxima precisión",
"pricing.faq.title": "Preguntas frecuentes",
"pricing.faq.q1": "¿Puedo cambiar de plan en cualquier momento?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "¿Qué es la «Traducción IA Esencial»?",
"pricing.faq.a2": "Es nuestro motor de IA. Comprende el contexto de tus documentos, conserva el diseño y maneja términos técnicos mucho mejor que una traducción clásica.",
"pricing.faq.q3": "¿Cuál es la diferencia entre IA Esencial e IA Premium?",
"pricing.faq.a3": "La IA Esencial usa un modelo optimizado (excelente relación calidad-precio). La IA Premium usa Claude 3.5 Haiku de Anthropic, más precisa en documentos jurídicos, médicos y técnicos complejos.",
"pricing.faq.a3": "La IA Esencial se apoya en DeepSeek V4 Flash, GLM-5.3 Flash y MiniMax M3 (excelente relación calidad-precio). La IA Premium usa Claude 5 de Anthropic, más precisa en documentos jurídicos, médicos y técnicos complejos.",
"pricing.faq.q4": "¿Se conservan mis documentos después de la traducción?",
"pricing.faq.a4": "Los archivos traducidos están disponibles según tu plan (30 días Starter, 90 días Pro, 1 año Business). Están cifrados en reposo y en tránsito.",
"pricing.faq.q5": "¿Qué ocurre si supero mi cuota mensual?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "Error al crear el pago.",
"pricing.dashboard": "Panel",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "Desde 0,09 $ por millón de tokens",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "Alternativas: DeepSeek V4 Pro y GLM-5.3",
"pricing.confirm.title": "Confirma tu suscripción",
"pricing.confirm.subtitle": "Serás redirigido a nuestro proveedor de pago seguro.",
"pricing.confirm.cancel": "Cancelar",
"pricing.confirm.cta": "Continuar al pago",
"pricing.confirm.year": "año",
"pricing.confirm.month": "mes",
"pricing.confirm.monthlyEquivalent": "Facturación anual — equivalente a {price} € / mes.",
"pricing.confirm.secureNote": "Cancelable en cualquier momento desde tu perfil. El pago lo procesa Stripe; los datos de tu tarjeta nunca pasan por nuestros servidores.",
"pricing.enterprise.subject": "Consulta Enterprise",
"pricing.enterpriseBand.cta": "Contáctenos",
"pricing.enterpriseBand.text": "Volumen, motores dedicados, opciones on-premise — hablemos.",
"pricing.error.server": "Error del servidor {status}",
"pricing.freeBand.cta": "Empieza gratis",
"pricing.freeBand.text": "¿Solo quieres probar? Empieza gratis — 5 documentos al mes, sin tarjeta.",
"pricing.header.titleBase": "Un plan para",
"pricing.header.titleAccent": "cada necesidad",
"pricing.toast.close": "Cerrar",
"pricing.aiModels.premium.price": "2 $ / 10 $ por 1M de tokens"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "Acceso unificado a los mejores modelos de código abierto optimizados para traducción.",
"providerTheme.openrouter_premium.badge": "Ultra",
"providerTheme.openrouter_premium.subBadge": "Contexto máximo",
"providerTheme.openrouter_premium.desc": "Asistido por modelos de última generación (GPT-4o, Claude Sonnet 4.6) para documentos largos.",
"providerTheme.openrouter_premium.desc": "Asistido por modelos de última generación (GPT-4o, Claude 5) para documentos largos.",
"providerTheme.zai.badge": "Especializada",
"providerTheme.zai.subBadge": "Finanzas y Derecho",
"providerTheme.zai.desc": "Modelo ajustado para terminologías empresariales exigentes (legal, finanzas).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "ارائه‌دهندگان",
"admin.nav.system": "سیستم",
"admin.nav.logs": "گزارش‌ها",
"admin.nav.stats": "آمار",
"admin.users.title": "مدیریت کاربران",
"admin.users.subtitle": "مشاهده و مدیریت حساب‌های کاربری",
"admin.users.planUpdated": "طرح به‌روز شد",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "در انتظار داده...",
"admin.system.purging": "در حال پاکسازی...",
"admin.system.clean": "پاکسازی",
"admin.system.purge": "حذف کامل"
"admin.system.purge": "حذف کامل",
"admin.nav.models": "مدل‌ها و اشتراک‌ها",
"admin.nav.marketing": "بازاریابی",
"admin.marketing.audience": "مخاطب",
"admin.marketing.audienceAllUsers": "همه حساب‌ها",
"admin.marketing.audienceInactive": "حساب‌های غیرفعال از ۳۰ روز پیش",
"admin.marketing.audiencePlaceholder": "انتخاب مخاطب",
"admin.marketing.audiencePlanBusiness": "اشتراک Business",
"admin.marketing.audiencePlanEnterprise": "اشتراک Enterprise",
"admin.marketing.audiencePlanFree": "اشتراک رایگان",
"admin.marketing.audiencePlanPro": "اشتراک Pro",
"admin.marketing.audiencePlanStarter": "اشتراک Starter",
"admin.marketing.audienceWaitlist": "فهرست انتظار",
"admin.marketing.badgeReal": "واقعی",
"admin.marketing.badgeTest": "آزمایشی",
"admin.marketing.confirmSend": "این ایمیل به {count} گیرنده ارسال شود («{audience}»)؟",
"admin.marketing.footerNote": "یک پانوشت با پیوند لغو اشتراک به‌طور خودکار به ارسال افزوده می‌شود.",
"admin.marketing.hidePreview": "پنهان کردن پیش‌نمایش",
"admin.marketing.history": "تاریخچه ارسال‌ها",
"admin.marketing.historyFailedSuffix": "، {count} ناموفق",
"admin.marketing.historySent": "{sent}/{total} ارسال‌شده",
"admin.marketing.html": "محتوای HTML",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "موضوع و HTML را پر کنید.",
"admin.marketing.incompleteTitle": "محتوای ناقص",
"admin.marketing.loadErrorTitle": "خطا در بارگذاری",
"admin.marketing.localCheckUnavailable": "بررسی محلی در این مرورگر در دسترس نیست: سرور ارسال آزمایشی قبلی را کنترل خواهد کرد.",
"admin.marketing.networkDesc": "دسترسی به بک‌اند ممکن نیست.",
"admin.marketing.newCampaign": "کمپین جدید",
"admin.marketing.noHistory": "هیچ ارسالی ثبت نشده است.",
"admin.marketing.preview": "پیش‌نمایش",
"admin.marketing.previewEmpty": "پیش‌نمایش: HTML خود را در کنار این بوم بچسبانید.",
"admin.marketing.previewTitle": "پیش‌نمایش ایمیل",
"admin.marketing.recipientsAvailable": "{count} گیرنده پس از کنارگذاشتن لغواشتراک‌ها در دسترس است.",
"admin.marketing.sendReal": "ارسال به {count} گیرنده",
"admin.marketing.sendRefusedTitle": "ارسال رد شد",
"admin.marketing.sendTest": "ارسال آزمایشی",
"admin.marketing.sendingDesc": "{count} ایمیل در صف ارسال (فاصله ۰٫۲ ثانیه). لغواشتراک‌ها مستثنی هستند.",
"admin.marketing.sendingTitle": "ارسال در جریان است",
"admin.marketing.subject": "موضوع",
"admin.marketing.subjectPlaceholder": "مثال: ترجمه شما منتظر است — ۲۰٪ به مدت ۷ روز",
"admin.marketing.subtitle": "ارسال ایمیل به یک مخاطب، با ارسال آزمایشی الزامی، پیوند لغو اشتراک خودکار و تاریخچه کامل.",
"admin.marketing.testDoneDesc": "ایمیل به {email} رسید",
"admin.marketing.testDoneTitle": "ارسال آزمایشی انجام شد",
"admin.marketing.testEmail": "ایمیل آزمایشی (اختیاری)",
"admin.marketing.testEmailPlaceholder": "در غیر این صورت: آدرس فرستنده SMTP",
"admin.marketing.testFailedTitle": "ارسال آزمایشی ناموفق بود",
"admin.marketing.testRequiredHint": "ارسال واقعی نیازمند ارسال آزمایشی قبلی همین محتوا است (تأییدشده توسط سرور).",
"admin.marketing.testValidated": "ارسال آزمایشی این محتوا تأیید شده است.",
"admin.marketing.title": "بازاریابی — کمپین‌های ایمیلی",
"admin.marketing.unsubscribedNote": "{count} لغواشتراک از هر ارسالی مستثنی خواهند شد.",
"admin.models.addModel": "افزودن مدل",
"admin.models.businessBadge": "اشتراک Business",
"admin.models.cancel": "لغو",
"admin.models.catalog": "کاتالوگ OpenRouter",
"admin.models.catalogErrorDesc": "بارگذاری کاتالوگ OpenRouter ممکن نشد.",
"admin.models.catalogErrorTitle": "کاتالوگ در دسترس نیست",
"admin.models.customBadge": "سطح سفارشی",
"admin.models.customNote": "مدل‌های سفارشی، مورد به مورد با مشتری توافق می‌شود.",
"admin.models.defaultBadge": "پیش‌فرض",
"admin.models.emptyTier": "بدون مدل: مجموعه رسمی اشتراک استفاده خواهد شد.",
"admin.models.enterpriseBadge": "اشتراک Enterprise",
"admin.models.essentialBadge": "سطح هوش مصنوعی پایه",
"admin.models.essentialCost": "— محاسبه با ضریب هزینه ۱",
"admin.models.fallbackFirst": "(پشتیبان شماره ۱)",
"admin.models.loadErrorDesc": "HTTP {status} — توکن مدیر را بررسی کنید.",
"admin.models.loadErrorTitle": "خطا در بارگذاری",
"admin.models.matrixDesc": "مدل‌های فعال هر سطح — ترتیب فهرست، اولویت پشتیبان است. دکمه رادیویی مدل پیش‌فرض را انتخاب می‌کند که بلافاصله و بدون استقرار مجدد اعمال می‌شود.",
"admin.models.matrixTitle": "ماتریس مدل‌ها به تفکیک اشتراک",
"admin.models.missingConfig": "پیکربندی سطوح هوش مصنوعی یافت نشد. صفحه را دوباره بارگذاری کنید.",
"admin.models.moveDown": "انتقال به پایین",
"admin.models.moveUp": "انتقال به بالا",
"admin.models.networkDesc": "دسترسی به بک‌اند ممکن نیست.",
"admin.models.networkTitle": "خطای شبکه",
"admin.models.premiumBadge": "سطح هوش مصنوعی پیشرفته",
"admin.models.premiumCost": "— محاسبه با ضریب هزینه ۵",
"admin.models.premiumReservedNote": "مخصوص اشتراک‌های Business و Enterprise (موتور «openrouter_premium»).",
"admin.models.proBadge": "اشتراک Pro",
"admin.models.remove": "حذف",
"admin.models.save": "ذخیره",
"admin.models.saveErrorTitle": "خطا در ذخیره",
"admin.models.saveNetworkDesc": "ذخیره پیکربندی ممکن نشد.",
"admin.models.savedDesc": "مدل پیش‌فرض جدید از ترجمه بعدی استفاده می‌شود، بدون استقرار مجدد.",
"admin.models.savedTitle": "مدل‌ها ذخیره شدند",
"admin.models.saving": "در حال ذخیره...",
"admin.models.setDefault": "تنظیم {model} به‌عنوان مدل پیش‌فرض",
"admin.models.sharedTierNote": "سطح مشترک: اشتراک Business نیز برای موتور «openrouter» از سطح پایه استفاده می‌کند — فهرست بالا برای هر دو اشتراک اعمال می‌شود.",
"admin.models.subtitle": "ماتریس plans → سطوح هوش مصنوعی. مدل واقعی استفاده‌شده در هر ترجمه، مدل سطحِ همان اشتراک است: اشتراک Pro هرگز نمی‌تواند مدل Premium را فعال کند.",
"admin.models.title": "مدل‌ها و اشتراک‌ها",
"admin.stats.aiTiers": "سطوح هوش مصنوعی (۳۰ روز)",
"admin.stats.includingCredits": "شامل {amount} اعتبار",
"admin.stats.mrr": "درآمد ماهانه تکرارشونده تخمینی",
"admin.stats.noTranslationsYet": "هیچ ترجمه‌ای در ۳۰ روز گذشته ثبت نشده است: تفکیک سطوح با ترجمه‌های بعدی کامل می‌شود.",
"admin.stats.payments30": "{count} پرداخت در ۳۰ روز",
"admin.stats.refreshing": "در حال به‌روزرسانی...",
"admin.stats.revenue30": "درآمد (۳۰ روز)",
"admin.stats.revenueTotal": "کل درآمد دریافت‌شده",
"admin.stats.tiersSub": "پایه / پیشرفته · کلاسیک {classic} · سایر {other}",
"admin.stats.unavailable": "آمار کسب‌وکار در دسترس نیست ({error}).",
"admin.stats.waitlist": "فهرست انتظار",
"admin.stats.waitlistSub": "نفر در انتظار"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "برای متخصصان حرفه‌ای",
"landing.pricing.pro.f1": "۲۰۰ سند / ماه",
"landing.pricing.pro.f2": "تا ۲۰۰ صفحه برای هر سند",
"landing.pricing.pro.f3": "ترجمه مبتنی بر هوش مصنوعی",
"landing.pricing.pro.f3": "هوش مصنوعی پایه: DeepSeek V4 Flash، GLM-5.3 Flash، MiniMax M3",
"landing.pricing.pro.f4": "Google شامل است",
"landing.pricing.pro.f5": "واژه‌نامه و پرامپت سفارشی",
"landing.pricing.pro.f6": "پشتیبانی اولویت‌دار",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "برای تیم‌ها با نیاز بالا",
"landing.pricing.business.f1": "۱,۰۰۰ سند / ماه",
"landing.pricing.business.f2": "تا ۵۰۰ صفحه برای هر سند",
"landing.pricing.business.f3": "هوش مصنوعی پیشرفته (Claude)",
"landing.pricing.business.f3": "هوش مصنوعی پیشرفته (Claude 5)",
"landing.pricing.business.f4": "همه ارائه‌دهندگان + API",
"landing.pricing.business.f5": "وب‌هوک و خودکارسازی",
"landing.pricing.business.f6": "۵ صندلی تیمی",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "فایل‌های DOCX, XLSX, PPTX یا PDF پشتیبانی می‌شوند",
"landing.translate.aiAnalysis": "تحلیل AI فعال",
"landing.translate.processing": "در حال پردازش",
"landing.translate.preservingLayout": "طرح‌بندی شما حفظ می‌شود"
"landing.translate.preservingLayout": "طرح‌بندی شما حفظ می‌شود",
"landing.beforeAfter.seal": "همان چیدمان، کلمه به کلمه",
"landing.beforeAfter.proof1": "نمودارهای SmartArt بازسازی می‌شوند، نه تخت‌شده",
"landing.beforeAfter.proof2": "سری‌ها و محورهای نمودار ترجمه می‌شوند",
"landing.beforeAfter.proof3": "فهرست مطالب به زبان مقصد بازسازی می‌شود",
"landing.beforeAfter.targetTitle": "مشخصات فنی — تهویه هوا",
"landing.beforeAfter.targetPara1": "سیستم تهویه باید پیش از پایان سه‌ماهه دوم راه‌اندازی شود.",
"landing.beforeAfter.targetPara2Before": "",
"landing.beforeAfter.targetTerm": "هواساز مرکزی",
"landing.beforeAfter.targetPara2After": "باید مطابق برنامه‌ریزی کلاس فیلتر F7 را رعایت کند.",
"landing.beforeAfter.targetItem1": "بار حرارتی: ۴۲ کیلووات در جریان اسمی",
"landing.beforeAfter.targetItem2": "سطح صدا کمتر از ۴۵ دسی‌بل (A) در فاصله ۳ متری",
"landing.formats.pill": "سازگاری",
"landing.hero.visualCaption": "همان چیدمان، زبان جدید — هیچ چیز دیگری تغییر نمی‌کند",
"landing.pricing.free.name": "رایگان",
"landing.pricing.free.desc": "برای آشنایی با اپلیکیشن ایده‌آل است",
"landing.pricing.free.cta": "انتخاب این برنامه",
"landing.pricing.enterprise.name": "سازمانی",
"landing.pricing.enterprise.desc": "راهکارهای سفارشی برای سازمان‌های بزرگ",
"landing.pricing.enterprise.cta": "تماس با ما",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "تاریخچه ۹۰ روزه",
"pricing.plans.business.feat1": "۱,۰۰۰ سند / ماه",
"pricing.plans.business.feat2": "تا ۵۰۰ صفحه برای هر سند",
"pricing.plans.business.feat3": "هوش مصنوعی پایه + پیشرفته (Claude Haiku)",
"pricing.plans.business.feat3": "هوش مصنوعی پایه + پیشرفته (Claude 5)",
"pricing.plans.business.feat4": "تمام ارائه‌دهنده‌های ترجمه",
"pricing.plans.business.feat5": "فایل‌ها تا ۵۰ مگابایت",
"pricing.plans.business.feat6": "دسترسی API (۱۰,۰۰۰ فراخوان/ماه)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "تاریخچه ۱ ساله",
"pricing.plans.business.feat10": "تحلیل پیشرفته",
"pricing.plans.enterprise.feat1": "اسناد نامحدود",
"pricing.plans.enterprise.feat2": "تمام مدل‌های هوش مصنوعی (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "تمام مدل‌های هوش مصنوعی (Claude 5، DeepSeek V4 Pro، GLM-5.3…)",
"pricing.plans.enterprise.feat3": "استقرار محلی یا ابری اختصاصی",
"pricing.plans.enterprise.feat4": "SLA 99.9% تضمین‌شده",
"pricing.plans.enterprise.feat5": "پشتیبانی اختصاصی ۲۴/۷",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "هوش مصنوعی چندنخی فوق‌سریع",
"pricing.trust.availability.title": "۲۴/۷ در دسترس",
"pricing.trust.availability.sub": "۹۹.۹٪ زمان فعالیت تضمین‌شده",
"pricing.aiModels.title": "مدل‌های هوش مصنوعی ما — مارس ۲۰۲۶",
"pricing.aiModels.title": "مدل‌های هوش مصنوعی ما — سپتامبر ۲۰۲۶",
"pricing.aiModels.essential.title": "ترجمه هوش مصنوعی پایه",
"pricing.aiModels.essential.plan": "طرح حرفه‌ای",
"pricing.aiModels.essential.descPrefix": "مبتنی بر",
"pricing.aiModels.essential.descSuffix": "— مقرون‌به‌صرفه‌ترین مدل هوش مصنوعی سال ۲۰۲۶. کیفیت قابل مقایسه با مدل‌های پیشرو با کسر هزینه.",
"pricing.aiModels.essential.modelName": "مدل هوش مصنوعی Essential",
"pricing.aiModels.essential.context": "۱۶۳هزار توکن زمینه",
"pricing.aiModels.essential.value": "ارزش عالی نسبت به قیمت",
"pricing.aiModels.essential.descSuffix": "— مقرون‌به‌صرفه‌ترین مدل‌های هوش مصنوعی سال ۲۰۲۶.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash، GLM-5.3 Flash و MiniMax M3",
"pricing.aiModels.essential.context": "زمینه تا ۱٫۳ میلیون توکن (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "بهترین نسبت کیفیت به قیمت",
"pricing.aiModels.premium.title": "ترجمه هوش مصنوعی پیشرفته",
"pricing.aiModels.premium.plan": "طرح سازمانی",
"pricing.aiModels.premium.descPrefix": "مبتنی بر",
"pricing.aiModels.premium.descSuffix": "توسط Anthropic — دقیق در اسناد حقوقی، پزشکی و فنی پیچیده.",
"pricing.aiModels.premium.context": "۲۰۰هزار توکن زمینه",
"pricing.aiModels.premium.context": "یک میلیون توکن زمینه",
"pricing.aiModels.premium.precision": "بالاترین دقت",
"pricing.faq.title": "سوالات متداول",
"pricing.faq.q1": "آیا می‌توانم طرح را هر زمان بخواهم تغییر دهم؟",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "\\\"ترجمه هوش مصنوعی پایه\\\" چیست؟",
"pricing.faq.a2": "این موتور هوش مصنوعی ماست. زمینه اسناد شما را درک می‌کند، طرح‌بندی را حفظ می‌کند و اصطلاحات فنی را بسیار بهتر از ترجمه کلاسیک مدیریت می‌کند.",
"pricing.faq.q3": "تفاوت هوش مصنوعی پایه و پیشرفته چیست؟",
"pricing.faq.a3": "هوش مصنوعی Essential از یک مدل بهینه‌شده استفاده می‌کند (ارزش عالی برای پول). هوش مصنوعی Premium از Claude 3.5 Haiku انترپیک استفاده می‌کند که در اسناد حقوقی، پزشکی و فنی پیچیده دقیق‌تر است.",
"pricing.faq.a3": "هوش مصنوعی Essential از مدل‌های DeepSeek V4 Flash، GLM-5.3 Flash و MiniMax M3 استفاده می‌کند (ارزش عالی برای پول). هوش مصنوعی Premium از Claude 5 انترپیک استفاده می‌کند که در اسناد حقوقی، پزشکی و فنی پیچیده دقیق‌تر است.",
"pricing.faq.q4": "آیا اسناد من پس از ترجمه نگهداری می‌شوند؟",
"pricing.faq.a4": "فایل‌های ترجمه‌شده طبق طرح شما در دسترس هستند (۳۰ روز مبتدی، ۹۰ روز حرفه‌ای، ۱ سال سازمانی). آنها در حالت استراحت و هنگام انتقال رمزنگاری می‌شوند.",
"pricing.faq.q5": "اگر از سهمیه ماهانه خود فراتر رویم چه می‌شود؟",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "خطا در ایجاد پرداخت.",
"pricing.dashboard": "داشبورد",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "از ۰٫۰۹ دلار به ازای هر میلیون توکن",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "جایگزین‌ها: DeepSeek V4 Pro و GLM-5.3",
"pricing.confirm.title": "اشتراک خود را تأیید کنید",
"pricing.confirm.subtitle": "به درگاه پرداخت امن ما هدایت می‌شوید.",
"pricing.confirm.cancel": "لغو",
"pricing.confirm.cta": "ادامه به پرداخت",
"pricing.confirm.year": "سال",
"pricing.confirm.month": "ماه",
"pricing.confirm.monthlyEquivalent": "صورتحساب سالانه — یعنی {price} یورو در ماه.",
"pricing.confirm.secureNote": "هر زمان از پروفایل خود قابل لغو است. پرداخت توسط Stripe انجام می‌شود؛ اطلاعات کارت شما هرگز به سرورهای ما نمی‌رسد.",
"pricing.enterprise.subject": "پیشنهاد سازمانی",
"pricing.enterpriseBand.cta": "تماس با ما",
"pricing.enterpriseBand.text": "حجم بالا، موتورهای اختصاصی، گزینه‌های درون‌سازمانی — صحبت کنیم.",
"pricing.error.server": "خطای سرور {status}",
"pricing.freeBand.cta": "رایگان شروع کنید",
"pricing.freeBand.text": "فقط می‌خواهید امتحان کنید؟ رایگان شروع کنید — ماهی ۵ سند، بدون کارت.",
"pricing.header.titleBase": "برنامه‌ای برای",
"pricing.header.titleAccent": "هر نیاز",
"pricing.toast.close": "بستن",
"pricing.aiModels.premium.price": "۲ دلار / ۱۰ دلار به ازای هر میلیون توکن"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "دسترسی یکپارچه به بهترین مدل‌های متن‌باز بهینه‌سازی‌شده برای ترجمه.",
"providerTheme.openrouter_premium.badge": "فوق‌العاده",
"providerTheme.openrouter_premium.subBadge": "حداکثر زمینه",
"providerTheme.openrouter_premium.desc": "با کمک مدل‌های پیشرفته (GPT-4o، Claude Sonnet 4.6) برای اسناد طولانی.",
"providerTheme.openrouter_premium.desc": "با کمک مدل‌های پیشرفته (GPT-4o، Claude 5) برای اسناد طولانی.",
"providerTheme.zai.badge": "تخصصی",
"providerTheme.zai.subBadge": "مالی و حقوقی",
"providerTheme.zai.desc": "مدل تنظیم‌شده برای اصطلاحات تجاری سخت‌گیرانه (حقوقی، مالی).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "Fournisseurs",
"admin.nav.system": "Système",
"admin.nav.logs": "Logs",
"admin.nav.stats": "Statistiques",
"admin.users.title": "Gestion des Utilisateurs",
"admin.users.subtitle": "Visualiser et gérer les comptes utilisateurs",
"admin.users.planUpdated": "Plan mis à jour",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "En attente de données...",
"admin.system.purging": "Purge...",
"admin.system.clean": "Nettoyer",
"admin.system.purge": "Purger"
"admin.system.purge": "Purger",
"admin.nav.models": "Modèles & abonnements",
"admin.nav.marketing": "Marketing",
"admin.marketing.audience": "Audience",
"admin.marketing.audienceAllUsers": "Tous les comptes",
"admin.marketing.audienceInactive": "Comptes inactifs depuis 30 jours",
"admin.marketing.audiencePlaceholder": "Choisir une audience",
"admin.marketing.audiencePlanBusiness": "Forfait Business",
"admin.marketing.audiencePlanEnterprise": "Forfait Enterprise",
"admin.marketing.audiencePlanFree": "Forfait Gratuit",
"admin.marketing.audiencePlanPro": "Forfait Pro",
"admin.marketing.audiencePlanStarter": "Forfait Starter",
"admin.marketing.audienceWaitlist": "Liste d'attente",
"admin.marketing.badgeReal": "réel",
"admin.marketing.badgeTest": "test",
"admin.marketing.confirmSend": "Envoyer cet email à {count} destinataire(s) (« {audience} ») ?",
"admin.marketing.footerNote": "Un pied de page avec le lien de désabonnement est ajouté automatiquement à l'envoi.",
"admin.marketing.hidePreview": "Masquer l'aperçu",
"admin.marketing.history": "Historique des envois",
"admin.marketing.historyFailedSuffix": ", {count} échec(s)",
"admin.marketing.historySent": "{sent}/{total} envoyé(s)",
"admin.marketing.html": "Contenu HTML",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "Renseignez le sujet et le HTML.",
"admin.marketing.incompleteTitle": "Contenu incomplet",
"admin.marketing.loadErrorTitle": "Erreur de chargement",
"admin.marketing.localCheckUnavailable": "Vérification locale indisponible sur ce navigateur : le serveur contrôlera l'envoi test préalable.",
"admin.marketing.networkDesc": "Impossible de contacter le backend.",
"admin.marketing.newCampaign": "Nouvelle relance",
"admin.marketing.noHistory": "Aucun envoi enregistré.",
"admin.marketing.preview": "Aperçu",
"admin.marketing.previewEmpty": "Aperçu : collez votre HTML ci-contre.",
"admin.marketing.previewTitle": "Aperçu de l'email",
"admin.marketing.recipientsAvailable": "{count} destinataire(s) disponibles après exclusion des désabonnés.",
"admin.marketing.sendReal": "Envoyer à {count} destinataire(s)",
"admin.marketing.sendRefusedTitle": "Envoi refusé",
"admin.marketing.sendTest": "Envoi test",
"admin.marketing.sendingDesc": "{count} email(s) en file d'envoi (0,2 s d'intervalle). Les désabonnés sont exclus.",
"admin.marketing.sendingTitle": "Envoi en cours",
"admin.marketing.subject": "Sujet",
"admin.marketing.subjectPlaceholder": "Ex. : Votre traduction vous attend — 20 % pendant 7 jours",
"admin.marketing.subtitle": "Envoi d'emails à une audience, avec envoi test obligatoire, lien de désabonnement automatique et historique complet.",
"admin.marketing.testDoneDesc": "Email reçu sur {email}",
"admin.marketing.testDoneTitle": "Envoi test effectué",
"admin.marketing.testEmail": "Email de test (optionnel)",
"admin.marketing.testEmailPlaceholder": "Sinon : adresse d'expédition SMTP",
"admin.marketing.testFailedTitle": "Échec de l'envoi test",
"admin.marketing.testRequiredHint": "L'envoi réel exige un envoi test préalable de ce contenu exact (vérifié par le serveur).",
"admin.marketing.testValidated": "Envoi test validé pour ce contenu.",
"admin.marketing.title": "Marketing — relances par email",
"admin.marketing.unsubscribedNote": "{count} désabonné(s) seront exclus de tout envoi.",
"admin.models.addModel": "Ajouter un modèle",
"admin.models.businessBadge": "Forfait Business",
"admin.models.cancel": "Annuler",
"admin.models.catalog": "Catalogue OpenRouter",
"admin.models.catalogErrorDesc": "Impossible de charger le catalogue OpenRouter.",
"admin.models.catalogErrorTitle": "Catalogue indisponible",
"admin.models.customBadge": "Palier personnalisé",
"admin.models.customNote": "Modèles sur mesure, définis au cas par cas avec le client.",
"admin.models.defaultBadge": "par défaut",
"admin.models.emptyTier": "Aucun modèle : la gamme officielle du plan sera utilisée.",
"admin.models.enterpriseBadge": "Forfait Enterprise",
"admin.models.essentialBadge": "Palier IA Essentielle",
"admin.models.essentialCost": "— facturation coût 1",
"admin.models.fallbackFirst": "(secours n°1)",
"admin.models.loadErrorDesc": "HTTP {status} — vérifiez votre token admin.",
"admin.models.loadErrorTitle": "Erreur de chargement",
"admin.models.matrixDesc": "Modèles actifs par palier — l'ordre de la liste est la priorité de secours. Le bouton radio choisit le modèle par défaut, utilisé immédiatement sans redéploiement.",
"admin.models.matrixTitle": "Matrice des modèles par forfait",
"admin.models.missingConfig": "Configuration des paliers IA introuvable. Rechargez la page.",
"admin.models.moveDown": "Descendre",
"admin.models.moveUp": "Monter",
"admin.models.networkDesc": "Impossible de contacter le backend.",
"admin.models.networkTitle": "Erreur réseau",
"admin.models.premiumBadge": "Palier IA Premium",
"admin.models.premiumCost": "— facturation coût 5",
"admin.models.premiumReservedNote": "Réservé aux forfaits Business et Enterprise (moteur « openrouter_premium »).",
"admin.models.proBadge": "Forfait Pro",
"admin.models.remove": "Retirer",
"admin.models.save": "Enregistrer",
"admin.models.saveErrorTitle": "Erreur de sauvegarde",
"admin.models.saveNetworkDesc": "Impossible d'enregistrer la configuration.",
"admin.models.savedDesc": "Le nouveau modèle par défaut est utilisé dès la prochaine traduction, sans redéploiement.",
"admin.models.savedTitle": "Modèles enregistrés",
"admin.models.saving": "Enregistrement...",
"admin.models.setDefault": "Définir {model} comme modèle par défaut",
"admin.models.sharedTierNote": "Palier commun : le forfait Business utilise aussi la Essentielle pour son moteur « openrouter » — la liste ci-dessus s'applique aux deux forfaits.",
"admin.models.subtitle": "Matrice forfaits → paliers IA. Le modèle réellement utilisé par traduction est celui du palier du plan : un forfait Pro ne peut jamais déclencher un modèle Premium.",
"admin.models.title": "Modèles & abonnements",
"admin.stats.aiTiers": "Paliers IA (30 j)",
"admin.stats.includingCredits": "dont {amount} de crédits",
"admin.stats.mrr": "MRR estimé",
"admin.stats.noTranslationsYet": "Aucune traduction en base sur les 30 derniers jours : la répartition des paliers se remplira dès les prochaines traductions.",
"admin.stats.payments30": "{count} paiement(s) sur 30 jours",
"admin.stats.refreshing": "Actualisation...",
"admin.stats.revenue30": "Revenus (30 jours)",
"admin.stats.revenueTotal": "Revenus encaissés (total)",
"admin.stats.tiersSub": "Essentielle / Premium · classique {classic} · autre {other}",
"admin.stats.unavailable": "Statistiques business indisponibles ({error}).",
"admin.stats.waitlist": "Liste d'attente",
"admin.stats.waitlistSub": "inscrits en attente"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "Pour les professionnels exigeants",
"landing.pricing.pro.f1": "200 documents / mois",
"landing.pricing.pro.f2": "Jusqu'à 200 pages par doc",
"landing.pricing.pro.f3": "Traduction par IA",
"landing.pricing.pro.f3": "IA Essentielle : DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google inclus",
"landing.pricing.pro.f5": "Glossaires et prompts",
"landing.pricing.pro.f6": "Support prioritaire",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "Pour les équipes avec des besoins élevés",
"landing.pricing.business.f1": "1 000 documents / mois",
"landing.pricing.business.f2": "Jusqu'à 500 pages par doc",
"landing.pricing.business.f3": "IA Premium (Claude)",
"landing.pricing.business.f3": "IA Premium (Claude 5)",
"landing.pricing.business.f4": "Tous les fournisseurs + API",
"landing.pricing.business.f5": "Webhooks et automatisation",
"landing.pricing.business.f6": "5 postes d'équipe",

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "Historique 90 jours",
"pricing.plans.business.feat1": "1 000 documents / mois",
"pricing.plans.business.feat2": "Jusqu'à 500 pages par document",
"pricing.plans.business.feat3": "IA Essentielle + Premium (Claude Haiku)",
"pricing.plans.business.feat3": "IA Essentielle + IA Premium (Claude 5)",
"pricing.plans.business.feat4": "Tous les fournisseurs de traduction",
"pricing.plans.business.feat5": "Fichiers jusqu'à 50 Mo",
"pricing.plans.business.feat6": "Accès API (10 000 appels/mois)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "Historique 1 an",
"pricing.plans.business.feat10": "Analytiques avancées",
"pricing.plans.enterprise.feat1": "Documents illimités",
"pricing.plans.enterprise.feat2": "Tous les modèles IA (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "Tous les modèles IA (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "Déploiement on-premise ou cloud dédié",
"pricing.plans.enterprise.feat4": "SLA 99,9 % garanti",
"pricing.plans.enterprise.feat5": "Support 24/7 dédié",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "IA multi-thread ultra-rapide",
"pricing.trust.availability.title": "Disponible 24/7",
"pricing.trust.availability.sub": "Uptime garanti 99,9 %",
"pricing.aiModels.title": "Nos modèles IA — Mars 2026",
"pricing.aiModels.title": "Nos modèles IA — Septembre 2026",
"pricing.aiModels.essential.title": "Traduction IA Essentielle",
"pricing.aiModels.essential.plan": "Forfait Pro",
"pricing.aiModels.essential.descPrefix": "Basée sur",
"pricing.aiModels.essential.descSuffix": "— le modèle IA le plus rentable de 2026. Qualité comparable aux modèles frontier à une fraction du coût.",
"pricing.aiModels.essential.modelName": "notre modèle IA Essentiel",
"pricing.aiModels.essential.context": "163K tokens de contexte",
"pricing.aiModels.essential.value": "Excellent rapport qualité/prix",
"pricing.aiModels.essential.descSuffix": "— les modèles IA au meilleur rapport qualité/prix de 2026.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash et MiniMax M3",
"pricing.aiModels.essential.context": "Jusqu'à 1,3 M de contexte (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "Le meilleur rapport qualité/prix",
"pricing.aiModels.premium.title": "Traduction IA Premium",
"pricing.aiModels.premium.plan": "Forfait Business",
"pricing.aiModels.premium.descPrefix": "Basée sur",
"pricing.aiModels.premium.descSuffix": "d'Anthropic — précis sur les documents juridiques, médicaux et techniques complexes.",
"pricing.aiModels.premium.context": "200K tokens de contexte",
"pricing.aiModels.premium.context": "1M de contexte",
"pricing.aiModels.premium.precision": "Meilleure précision",
"pricing.faq.title": "Questions fréquentes",
"pricing.faq.q1": "Puis-je changer de forfait à tout moment ?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "Qu'est-ce que la « Traduction IA Essentielle » ?",
"pricing.faq.a2": "C'est notre moteur IA. Il comprend le contexte de vos documents, préserve la mise en page et gère les termes techniques bien mieux qu'une traduction classique.",
"pricing.faq.q3": "Quelle est la différence entre IA Essentielle et IA Premium ?",
"pricing.faq.a3": "L'IA Essentielle utilise un modèle optimisé (excellent rapport qualité/prix). L'IA Premium utilise Claude Sonnet 4.6 d'Anthropic, plus précis sur les documents juridiques, médicaux et techniques complexes.",
"pricing.faq.a3": "L'IA Essentielle s'appuie sur DeepSeek V4 Flash, GLM-5.3 Flash et MiniMax M3 (excellent rapport qualité/prix). L'IA Premium utilise Claude 5 d'Anthropic, plus précis sur les documents juridiques, médicaux et techniques complexes.",
"pricing.faq.q4": "Mes documents sont-ils conservés après traduction ?",
"pricing.faq.a4": "Les fichiers traduits sont disponibles selon votre forfait (30 jours Starter, 90 jours Pro, 1 an Business). Ils sont chiffrés au repos et en transit.",
"pricing.faq.q5": "Que se passe-t-il si je dépasse mon quota mensuel ?",
@@ -163,5 +163,9 @@
"pricing.freeBand.text": "Juste envie d'essayer ? Commencez gratuitement — 5 documents par mois, sans carte.",
"pricing.freeBand.cta": "Commencer gratuitement",
"pricing.enterpriseBand.text": "Volume, moteurs dédiés, hébergement spécifique — parlons-en.",
"pricing.enterpriseBand.cta": "Nous contacter"
"pricing.enterpriseBand.cta": "Nous contacter",
"pricing.aiModels.essential.price": "À partir de 0,09 $ par million de jetons",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "Alternatives : DeepSeek V4 Pro et GLM-5.3",
"pricing.aiModels.premium.price": "2 $ / 10 $ par 1M de jetons"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "Accès unifié aux meilleurs modèles open-source optimisés pour la traduction.",
"providerTheme.openrouter_premium.badge": "Ultra",
"providerTheme.openrouter_premium.subBadge": "Maximum Context",
"providerTheme.openrouter_premium.desc": "Traduction assistée par les modèles de pointe (GPT-4o, Claude Sonnet 4.6) pour documents longs.",
"providerTheme.openrouter_premium.desc": "Traduction assistée par les modèles de pointe (GPT-4o, Claude 5) pour documents longs.",
"providerTheme.zai.badge": "Spécialisée",
"providerTheme.zai.subBadge": "Finance & Droit",
"providerTheme.zai.desc": "Modèle affiné pour les terminologies métiers exigeantes (juridique, finance).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "Fornitori",
"admin.nav.system": "Sistema",
"admin.nav.logs": "Log",
"admin.nav.stats": "Statistiche",
"admin.users.title": "Gestione Utenti",
"admin.users.subtitle": "Visualizza e gestisci gli account utente",
"admin.users.planUpdated": "Piano aggiornato",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "In attesa di dati...",
"admin.system.purging": "Pulizia in corso...",
"admin.system.clean": "Pulisci",
"admin.system.purge": "Pulisci"
"admin.system.purge": "Pulisci",
"admin.nav.models": "Modelli e abbonamenti",
"admin.nav.marketing": "Marketing",
"admin.marketing.audience": "Pubblico",
"admin.marketing.audienceAllUsers": "Tutti gli account",
"admin.marketing.audienceInactive": "Account inattivi da 30 giorni",
"admin.marketing.audiencePlaceholder": "Scegli un pubblico",
"admin.marketing.audiencePlanBusiness": "Piano Business",
"admin.marketing.audiencePlanEnterprise": "Piano Enterprise",
"admin.marketing.audiencePlanFree": "Piano Gratuito",
"admin.marketing.audiencePlanPro": "Piano Pro",
"admin.marketing.audiencePlanStarter": "Piano Starter",
"admin.marketing.audienceWaitlist": "Lista d'attesa",
"admin.marketing.badgeReal": "reale",
"admin.marketing.badgeTest": "prova",
"admin.marketing.confirmSend": "Inviare questa email a {count} destinatario/i («{audience}»)?",
"admin.marketing.footerNote": "Un piè di pagina con il link di disiscrizione è aggiunto automaticamente all'invio.",
"admin.marketing.hidePreview": "Nascondi anteprima",
"admin.marketing.history": "Cronologia degli invii",
"admin.marketing.historyFailedSuffix": ", {count} falliti",
"admin.marketing.historySent": "{sent}/{total} inviati",
"admin.marketing.html": "Contenuto HTML",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "Compila l'oggetto e l'HTML.",
"admin.marketing.incompleteTitle": "Contenuto incompleto",
"admin.marketing.loadErrorTitle": "Errore di caricamento",
"admin.marketing.localCheckUnavailable": "Verifica locale non disponibile in questo browser: il server controllerà l'invio di prova previo.",
"admin.marketing.networkDesc": "Impossibile contattare il backend.",
"admin.marketing.newCampaign": "Nuovo invio",
"admin.marketing.noHistory": "Nessun invio registrato.",
"admin.marketing.preview": "Anteprima",
"admin.marketing.previewEmpty": "Anteprima: incolla qui il tuo HTML.",
"admin.marketing.previewTitle": "Anteprima dell'email",
"admin.marketing.recipientsAvailable": "{count} destinatario/i disponibili dopo l'esclusione dei disiscritti.",
"admin.marketing.sendReal": "Invia a {count} destinatario/i",
"admin.marketing.sendRefusedTitle": "Invio rifiutato",
"admin.marketing.sendTest": "Invio di prova",
"admin.marketing.sendingDesc": "{count} email in coda di invio (intervallo 0,2 s). I disiscritti sono esclusi.",
"admin.marketing.sendingTitle": "Invio in corso",
"admin.marketing.subject": "Oggetto",
"admin.marketing.subjectPlaceholder": "Es.: La tua traduzione ti aspetta — 20% per 7 giorni",
"admin.marketing.subtitle": "Invio di email a un pubblico, con invio di prova obbligatorio, link di disiscrizione automatico e cronologia completa.",
"admin.marketing.testDoneDesc": "Email ricevuta su {email}",
"admin.marketing.testDoneTitle": "Invio di prova effettuato",
"admin.marketing.testEmail": "Email di prova (opzionale)",
"admin.marketing.testEmailPlaceholder": "Altrimenti: indirizzo mittente SMTP",
"admin.marketing.testFailedTitle": "Fallimento dell'invio di prova",
"admin.marketing.testRequiredHint": "L'invio reale richiede un invio di prova previo di questo identico contenuto (verificato dal server).",
"admin.marketing.testValidated": "Invio di prova convalidato per questo contenuto.",
"admin.marketing.title": "Marketing — invii email",
"admin.marketing.unsubscribedNote": "{count} contatti disiscritti saranno esclusi da ogni invio.",
"admin.models.addModel": "Aggiungi un modello",
"admin.models.businessBadge": "Piano Business",
"admin.models.cancel": "Annulla",
"admin.models.catalog": "Catalogo OpenRouter",
"admin.models.catalogErrorDesc": "Impossibile caricare il catalogo OpenRouter.",
"admin.models.catalogErrorTitle": "Catalogo non disponibile",
"admin.models.customBadge": "Livello personalizzato",
"admin.models.customNote": "Modelli su misura, definiti caso per caso con il cliente.",
"admin.models.defaultBadge": "predefinito",
"admin.models.emptyTier": "Nessun modello: verrà usata la gamma ufficiale del piano.",
"admin.models.enterpriseBadge": "Piano Enterprise",
"admin.models.essentialBadge": "Livello IA Essenziale",
"admin.models.essentialCost": "— fatturato con fattore di costo 1",
"admin.models.fallbackFirst": "(fallback n. 1)",
"admin.models.loadErrorDesc": "HTTP {status} — verifica il token amministratore.",
"admin.models.loadErrorTitle": "Errore di caricamento",
"admin.models.matrixDesc": "Modelli attivi per livello — l'ordine della lista è la priorità di fallback. Il pulsante di opzione sceglie il modello predefinito, attivo subito senza ridistribuzione.",
"admin.models.matrixTitle": "Matrice dei modelli per piano",
"admin.models.missingConfig": "Configurazione dei livelli IA non trovata. Ricarica la pagina.",
"admin.models.moveDown": "Sposta giù",
"admin.models.moveUp": "Sposta su",
"admin.models.networkDesc": "Impossibile contattare il backend.",
"admin.models.networkTitle": "Errore di rete",
"admin.models.premiumBadge": "Livello IA Premium",
"admin.models.premiumCost": "— fatturato con fattore di costo 5",
"admin.models.premiumReservedNote": "Riservato ai piani Business ed Enterprise (motore «openrouter_premium»).",
"admin.models.proBadge": "Piano Pro",
"admin.models.remove": "Rimuovi",
"admin.models.save": "Salva",
"admin.models.saveErrorTitle": "Errore di salvataggio",
"admin.models.saveNetworkDesc": "Impossibile salvare la configurazione.",
"admin.models.savedDesc": "Il nuovo modello predefinito è usato dalla prossima traduzione, senza ridistribuzione.",
"admin.models.savedTitle": "Modelli salvati",
"admin.models.saving": "Salvataggio...",
"admin.models.setDefault": "Imposta {model} come modello predefinito",
"admin.models.sharedTierNote": "Livello condiviso: il piano Business usa il livello Essenziale anche per il motore «openrouter» — l'elenco sopra vale per entrambi i piani.",
"admin.models.subtitle": "Matrice piani → livelli IA. Il modello realmente usato per ogni traduzione è quello del livello del piano: un piano Pro non può mai attivare un modello Premium.",
"admin.models.title": "Modelli e abbonamenti",
"admin.stats.aiTiers": "Livelli IA (30 g)",
"admin.stats.includingCredits": "di cui {amount} di crediti",
"admin.stats.mrr": "MRR stimato",
"admin.stats.noTranslationsYet": "Nessuna traduzione registrata negli ultimi 30 giorni: la ripartizione per livelli si completerà con le prossime traduzioni.",
"admin.stats.payments30": "{count} pagamento/i in 30 giorni",
"admin.stats.refreshing": "Aggiornamento...",
"admin.stats.revenue30": "Ricavi (30 giorni)",
"admin.stats.revenueTotal": "Ricavi incassati (totale)",
"admin.stats.tiersSub": "Essenziale / Premium · classico {classic} · altro {other}",
"admin.stats.unavailable": "Statistiche business non disponibili ({error}).",
"admin.stats.waitlist": "Lista d'attesa",
"admin.stats.waitlistSub": "iscritti in attesa"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "Per professionisti esigenti",
"landing.pricing.pro.f1": "200 documenti / mese",
"landing.pricing.pro.f2": "Fino a 200 pagine per documento",
"landing.pricing.pro.f3": "Traduzione con IA",
"landing.pricing.pro.f3": "IA Essenziale: DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google inclusi",
"landing.pricing.pro.f5": "Glossari e prompt personalizzati",
"landing.pricing.pro.f6": "Supporto prioritario",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "Per team con esigenze elevate",
"landing.pricing.business.f1": "1 000 documenti / mese",
"landing.pricing.business.f2": "Fino a 500 pagine per documento",
"landing.pricing.business.f3": "IA Premium (Claude)",
"landing.pricing.business.f3": "IA Premium (Claude 5)",
"landing.pricing.business.f4": "Tutti i provider + accesso API",
"landing.pricing.business.f5": "Webhook e automazione",
"landing.pricing.business.f6": "5 postazioni team",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "File DOCX, XLSX, PPTX o PDF supportati",
"landing.translate.aiAnalysis": "Analisi IA Attiva",
"landing.translate.processing": "Elaborazione in corso",
"landing.translate.preservingLayout": "Il tuo layout viene preservato"
"landing.translate.preservingLayout": "Il tuo layout viene preservato",
"landing.beforeAfter.seal": "Stesso layout, parola per parola",
"landing.beforeAfter.proof1": "I diagrammi SmartArt vengono ricostruiti, non appiattiti",
"landing.beforeAfter.proof2": "Serie e assi dei grafici tradotti",
"landing.beforeAfter.proof3": "Indici rigenerati nella lingua di destinazione",
"landing.beforeAfter.targetTitle": "Specifiche tecniche — Trattamento aria",
"landing.beforeAfter.targetPara1": "L'impianto di ventilazione deve essere messo in servizio entro la fine del secondo trimestre.",
"landing.beforeAfter.targetPara2Before": "",
"landing.beforeAfter.targetTerm": "L'unità di trattamento aria",
"landing.beforeAfter.targetPara2After": "deve rispettare la classe di filtraggio F7 come da programma.",
"landing.beforeAfter.targetItem1": "Carico termico: 42 kW alla portata nominale",
"landing.beforeAfter.targetItem2": "Livello sonoro inferiore a 45 dB(A) a 3 m",
"landing.formats.pill": "COMPATIBILITÀ",
"landing.hero.visualCaption": "Stesso layout, nuova lingua — il resto non si tocca",
"landing.pricing.free.name": "Gratuito",
"landing.pricing.free.desc": "Ideale per scoprire l'app",
"landing.pricing.free.cta": "Scegli questo piano",
"landing.pricing.enterprise.name": "Enterprise",
"landing.pricing.enterprise.desc": "Soluzioni su misura per grandi organizzazioni",
"landing.pricing.enterprise.cta": "Contattaci",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "Cronologia di 90 giorni",
"pricing.plans.business.feat1": "1 000 documenti / mese",
"pricing.plans.business.feat2": "Fino a 500 pagine per documento",
"pricing.plans.business.feat3": "IA Essenziale + Premium (Claude Haiku)",
"pricing.plans.business.feat3": "IA Essenziale + IA Premium (Claude 5)",
"pricing.plans.business.feat4": "Tutti i provider di traduzione",
"pricing.plans.business.feat5": "File fino a 50 MB",
"pricing.plans.business.feat6": "Accesso API (10 000 chiamate/mese)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "Cronologia di 1 anno",
"pricing.plans.business.feat10": "Analisi avanzate",
"pricing.plans.enterprise.feat1": "Documenti illimitati",
"pricing.plans.enterprise.feat2": "Tutti i modelli IA (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "Tutti i modelli IA (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "Distribuzione on-premise o cloud dedicato",
"pricing.plans.enterprise.feat4": "SLA 99,9 % garantito",
"pricing.plans.enterprise.feat5": "Supporto dedicato 24/7",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "IA multi-thread ultraveloce",
"pricing.trust.availability.title": "Disponibile 24/7",
"pricing.trust.availability.sub": "99,9 % di uptime garantito",
"pricing.aiModels.title": "I nostri modelli IA — Marzo 2026",
"pricing.aiModels.title": "I nostri modelli IA — Settembre 2026",
"pricing.aiModels.essential.title": "Traduzione IA Essenziale",
"pricing.aiModels.essential.plan": "Piano Pro",
"pricing.aiModels.essential.descPrefix": "Basato su",
"pricing.aiModels.essential.descSuffix": "— il modello IA più conveniente del 2026. Qualità paragonabile ai modelli frontier a una frazione del costo.",
"pricing.aiModels.essential.modelName": "il nostro modello IA Essenziale",
"pricing.aiModels.essential.context": "163K token di contesto",
"pricing.aiModels.essential.value": "Eccellente rapporto qualità-prezzo",
"pricing.aiModels.essential.descSuffix": "— i modelli IA con il miglior rapporto qualità-prezzo del 2026.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash e MiniMax M3",
"pricing.aiModels.essential.context": "Fino a 1,3 M di contesto (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "Il miglior rapporto qualità-prezzo",
"pricing.aiModels.premium.title": "Traduzione IA Premium",
"pricing.aiModels.premium.plan": "Piano Business",
"pricing.aiModels.premium.descPrefix": "Basato su",
"pricing.aiModels.premium.descSuffix": "di Anthropic — preciso su documenti legali, medici e tecnici complessi.",
"pricing.aiModels.premium.context": "200K token di contesto",
"pricing.aiModels.premium.context": "1M di contesto",
"pricing.aiModels.premium.precision": "Massima precisione",
"pricing.faq.title": "Domande frequenti",
"pricing.faq.q1": "Posso cambiare piano in qualsiasi momento?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "Cos'è la «Traduzione IA Essenziale»?",
"pricing.faq.a2": "È il nostro motore IA. Comprende il contesto dei vostri documenti, preserva il layout e gestisce i termini tecnici molto meglio della traduzione classica.",
"pricing.faq.q3": "Qual è la differenza tra IA Essenziale e IA Premium?",
"pricing.faq.a3": "La IA Essenziale usa un modello ottimizzato (eccellente rapporto qualità/prezzo). La IA Premium usa Claude 3.5 Haiku di Anthropic, più precisa su documenti legali, medici e tecnici complessi.",
"pricing.faq.a3": "La IA Essenziale si basa su DeepSeek V4 Flash, GLM-5.3 Flash e MiniMax M3 (eccellente rapporto qualità/prezzo). La IA Premium usa Claude 5 di Anthropic, più precisa su documenti legali, medici e tecnici complessi.",
"pricing.faq.q4": "I miei documenti vengono conservati dopo la traduzione?",
"pricing.faq.a4": "I file tradotti sono disponibili secondo il tuo piano (30 giorni Starter, 90 giorni Pro, 1 anno Business). Sono crittografati a riposo e in transito.",
"pricing.faq.q5": "Cosa succede se supero la quota mensile?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "Errore durante la creazione del pagamento.",
"pricing.dashboard": "Dashboard",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "Da 0,09 $ per milione di token",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "Alternative: DeepSeek V4 Pro e GLM-5.3",
"pricing.confirm.title": "Conferma il tuo abbonamento",
"pricing.confirm.subtitle": "Verrai reindirizzato al nostro fornitore di pagamento sicuro.",
"pricing.confirm.cancel": "Annulla",
"pricing.confirm.cta": "Vai al pagamento",
"pricing.confirm.year": "anno",
"pricing.confirm.month": "mese",
"pricing.confirm.monthlyEquivalent": "Fatturazione annuale — ovvero {price} € / mese.",
"pricing.confirm.secureNote": "Disdicibile in qualsiasi momento dal tuo profilo. Il pagamento è elaborato da Stripe; i dati della tua carta non passano mai dai nostri server.",
"pricing.enterprise.subject": "Richiesta Enterprise",
"pricing.enterpriseBand.cta": "Contattaci",
"pricing.enterpriseBand.text": "Volume, motori dedicati, opzioni on-premise — parliamone.",
"pricing.error.server": "Errore del server {status}",
"pricing.freeBand.cta": "Inizia gratis",
"pricing.freeBand.text": "Vuoi solo provare? Inizia gratis — 5 documenti al mese, senza carta.",
"pricing.header.titleBase": "Un piano per",
"pricing.header.titleAccent": "ogni esigenza",
"pricing.toast.close": "Chiudi",
"pricing.aiModels.premium.price": "2 $ / 10 $ per 1M di token"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "Accesso unificato ai migliori modelli open-source ottimizzati per la traduzione.",
"providerTheme.openrouter_premium.badge": "Ultra",
"providerTheme.openrouter_premium.subBadge": "Contesto massimo",
"providerTheme.openrouter_premium.desc": "Assistito da modelli all'avanguardia (GPT-4o, Claude Sonnet 4.6) per documenti lunghi.",
"providerTheme.openrouter_premium.desc": "Assistito da modelli all'avanguardia (GPT-4o, Claude 5) per documenti lunghi.",
"providerTheme.zai.badge": "Specializzata",
"providerTheme.zai.subBadge": "Finanza e Diritto",
"providerTheme.zai.desc": "Modello ottimizzato per terminologie aziendali impegnative (legale, finanza).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "プロバイダー",
"admin.nav.system": "システム",
"admin.nav.logs": "ログ",
"admin.nav.stats": "統計",
"admin.users.title": "ユーザー管理",
"admin.users.subtitle": "ユーザーアカウントの表示と管理",
"admin.users.planUpdated": "プランが更新されました",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "データを待機中...",
"admin.system.purging": "パージ中...",
"admin.system.clean": "クリーン",
"admin.system.purge": "パージ"
"admin.system.purge": "パージ",
"admin.nav.models": "モデル & サブスクリプション",
"admin.nav.marketing": "マーケティング",
"admin.marketing.audience": "対象者",
"admin.marketing.audienceAllUsers": "全アカウント",
"admin.marketing.audienceInactive": "30日間非アクティブなアカウント",
"admin.marketing.audiencePlaceholder": "対象者を選択",
"admin.marketing.audiencePlanBusiness": "Businessプラン",
"admin.marketing.audiencePlanEnterprise": "Enterpriseプラン",
"admin.marketing.audiencePlanFree": "無料プラン",
"admin.marketing.audiencePlanPro": "Proプラン",
"admin.marketing.audiencePlanStarter": "Starterプラン",
"admin.marketing.audienceWaitlist": "ウェイトリスト",
"admin.marketing.badgeReal": "本番",
"admin.marketing.badgeTest": "テスト",
"admin.marketing.confirmSend": "このメールを {count} 名(「{audience}」)に送信しますか?",
"admin.marketing.footerNote": "送信時、配信停止リンク付きフッターが自動で追加されます。",
"admin.marketing.hidePreview": "プレビューを隠す",
"admin.marketing.history": "送信履歴",
"admin.marketing.historyFailedSuffix": "、{count} 件失敗",
"admin.marketing.historySent": "{sent}/{total} 送信済み",
"admin.marketing.html": "HTMLコンテンツ",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "件名とHTMLを入力してください。",
"admin.marketing.incompleteTitle": "内容が不完全です",
"admin.marketing.loadErrorTitle": "読み込みエラー",
"admin.marketing.localCheckUnavailable": "このブラウザではローカル確認ができないため、サーバーが事前テスト送信を検証します。",
"admin.marketing.networkDesc": "バックエンドに接続できません。",
"admin.marketing.newCampaign": "新しいキャンペーン",
"admin.marketing.noHistory": "送信履歴はありません。",
"admin.marketing.preview": "プレビュー",
"admin.marketing.previewEmpty": "プレビュー左側にHTMLを貼り付けてください。",
"admin.marketing.previewTitle": "メールプレビュー",
"admin.marketing.recipientsAvailable": "配信停止を除いた {count} 名に送信できます。",
"admin.marketing.sendReal": "{count} 名に送信",
"admin.marketing.sendRefusedTitle": "送信が拒否されました",
"admin.marketing.sendTest": "テスト送信",
"admin.marketing.sendingDesc": "{count} 件が送信キューに入りました0.2秒間隔)。配信停止中の宛先は除外されます。",
"admin.marketing.sendingTitle": "送信中",
"admin.marketing.subject": "件名",
"admin.marketing.subjectPlaceholder": "例:翻訳ができあがっています — 7日間20%オフ",
"admin.marketing.subtitle": "対象者へのメール送信。テスト送信が必須で、配信停止リンク自動付加、完全な履歴付き。",
"admin.marketing.testDoneDesc": "{email} でメールを受信",
"admin.marketing.testDoneTitle": "テスト送信が完了しました",
"admin.marketing.testEmail": "テストメール(任意)",
"admin.marketing.testEmailPlaceholder": "未指定の場合SMTP送信者アドレス",
"admin.marketing.testFailedTitle": "テスト送信に失敗しました",
"admin.marketing.testRequiredHint": "本送信には、同一内容の事前テスト送信が必要です(サーバーが検証します)。",
"admin.marketing.testValidated": "この内容のテスト送信は検証済みです。",
"admin.marketing.title": "マーケティング — メールキャンペーン",
"admin.marketing.unsubscribedNote": "配信停止中の {count} 件はすべての送信から除外されます。",
"admin.models.addModel": "モデルを追加",
"admin.models.businessBadge": "Businessプラン",
"admin.models.cancel": "キャンセル",
"admin.models.catalog": "OpenRouterカタログ",
"admin.models.catalogErrorDesc": "OpenRouterカタログを読み込めませんでした。",
"admin.models.catalogErrorTitle": "カタログを利用できません",
"admin.models.customBadge": "カスタムティア",
"admin.models.customNote": "カスタムモデルはお客様ごとに個別に決定します。",
"admin.models.defaultBadge": "既定",
"admin.models.emptyTier": "モデルなし:プランの公式ラインナップが使用されます。",
"admin.models.enterpriseBadge": "Enterpriseプラン",
"admin.models.essentialBadge": "エッセンシャルAIティア",
"admin.models.essentialCost": "— コスト係数 1 で課金",
"admin.models.fallbackFirst": "フォールバック第1位",
"admin.models.loadErrorDesc": "HTTP {status} — 管理者トークンを確認してください。",
"admin.models.loadErrorTitle": "読み込みエラー",
"admin.models.matrixDesc": "ティアごとの有効モデル — リストの順序がフォールバック優先度です。ラジオボタンで既定モデルを選ぶと、再デプロイなしですぐに反映されます。",
"admin.models.matrixTitle": "プラン別モデルマトリクス",
"admin.models.missingConfig": "AIティアの設定が見つかりません。ページを再読み込みしてください。",
"admin.models.moveDown": "下へ移動",
"admin.models.moveUp": "上へ移動",
"admin.models.networkDesc": "バックエンドに接続できません。",
"admin.models.networkTitle": "ネットワークエラー",
"admin.models.premiumBadge": "プレミアムAIティア",
"admin.models.premiumCost": "— コスト係数 5 で課金",
"admin.models.premiumReservedNote": "Business・Enterpriseプラン専用「openrouter_premium」エンジン。",
"admin.models.proBadge": "Proプラン",
"admin.models.remove": "削除",
"admin.models.save": "保存",
"admin.models.saveErrorTitle": "保存エラー",
"admin.models.saveNetworkDesc": "設定を保存できませんでした。",
"admin.models.savedDesc": "新しい既定モデルは次の翻訳から使用されます(再デプロイ不要)。",
"admin.models.savedTitle": "モデルを保存しました",
"admin.models.saving": "保存中...",
"admin.models.setDefault": "{model} を既定モデルに設定",
"admin.models.sharedTierNote": "共通ティアBusinessプランも「openrouter」エンジンにはエッセンシャルティアを使います — 上のリストは両プランに適用されます。",
"admin.models.subtitle": "プラン → AIティアのマトリクス。翻訳ごとに実際に使われるモデルはプランのティアのモデルですProプランがプレミアムモデルを呼び出すことは決してありません。",
"admin.models.title": "モデル & サブスクリプション",
"admin.stats.aiTiers": "AIティア30日",
"admin.stats.includingCredits": "うちクレジット {amount}",
"admin.stats.mrr": "推定MRR",
"admin.stats.noTranslationsYet": "過去30日間の翻訳記録がありません今後の翻訳でティア別内訳が埋まります。",
"admin.stats.payments30": "30日間の支払い {count} 件",
"admin.stats.refreshing": "更新中...",
"admin.stats.revenue30": "売上30日",
"admin.stats.revenueTotal": "累計売上",
"admin.stats.tiersSub": "エッセンシャル / プレミアム · クラシック {classic} · その他 {other}",
"admin.stats.unavailable": "ビジネス統計を利用できません({error})。",
"admin.stats.waitlist": "ウェイトリスト",
"admin.stats.waitlistSub": "待機中の登録者"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "プロフェッショナル向け",
"landing.pricing.pro.f1": "月200ドキュメント",
"landing.pricing.pro.f2": "1ドキュメント最大200ページ",
"landing.pricing.pro.f3": "AI翻訳",
"landing.pricing.pro.f3": "エッセンシャルAIDeepSeek V4 Flash、GLM-5.3 Flash、MiniMax M3",
"landing.pricing.pro.f4": "Google込み",
"landing.pricing.pro.f5": "カスタム用語集とプロンプト",
"landing.pricing.pro.f6": "優先サポート",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "大量処理が必要なチーム向け",
"landing.pricing.business.f1": "月1,000ドキュメント",
"landing.pricing.business.f2": "1ドキュメント最大500ページ",
"landing.pricing.business.f3": "プレミアムAIClaude",
"landing.pricing.business.f3": "プレミアムAIClaude 5",
"landing.pricing.business.f4": "全プロバイダー + API",
"landing.pricing.business.f5": "Webhookと自動化",
"landing.pricing.business.f6": "チームシート5席",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "DOCX, XLSX, PPTX, PDFファイル対応",
"landing.translate.aiAnalysis": "AI分析アクティブ",
"landing.translate.processing": "処理中",
"landing.translate.preservingLayout": "レイアウトを保持しています"
"landing.translate.preservingLayout": "レイアウトを保持しています",
"landing.beforeAfter.seal": "同じレイアウト、一語一句そのまま",
"landing.beforeAfter.proof1": "SmartArt図面は平面化されず、再構築されます",
"landing.beforeAfter.proof2": "グラフの系列と軸も翻訳",
"landing.beforeAfter.proof3": "目次は翻訳先言語で再生成",
"landing.beforeAfter.targetTitle": "技術仕様 — 空調処理",
"landing.beforeAfter.targetPara1": "換気設備は第2四半期末までに稼働させなければなりません。",
"landing.beforeAfter.targetPara2Before": "",
"landing.beforeAfter.targetTerm": "空調機",
"landing.beforeAfter.targetPara2After": "は計画どおりフィルタクラス F7 を満たす必要があります。",
"landing.beforeAfter.targetItem1": "熱負荷定格流量で42 kW",
"landing.beforeAfter.targetItem2": "騒音レベル3 mで45 dB(A)未満",
"landing.formats.pill": "対応フォーマット",
"landing.hero.visualCaption": "同じレイアウト、新しい言語 — 他は一切変わりません",
"landing.pricing.free.name": "無料",
"landing.pricing.free.desc": "アプリのお試しに最適",
"landing.pricing.free.cta": "このプランを選択",
"landing.pricing.enterprise.name": "エンタープライズ",
"landing.pricing.enterprise.desc": "大規模組織向けのカスタムソリューション",
"landing.pricing.enterprise.cta": "お問い合わせ",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "90日間の履歴",
"pricing.plans.business.feat1": "月1,000ドキュメント",
"pricing.plans.business.feat2": "1ドキュメントあたり最大500ページ",
"pricing.plans.business.feat3": "エッセンシャル + プレミアムAIClaude Haiku",
"pricing.plans.business.feat3": "エッセンシャル + プレミアムAIClaude 5",
"pricing.plans.business.feat4": "全翻訳プロバイダー",
"pricing.plans.business.feat5": "最大50 MBのファイル",
"pricing.plans.business.feat6": "APIアクセス月10,000コール",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "1年間の履歴",
"pricing.plans.business.feat10": "高度な分析",
"pricing.plans.enterprise.feat1": "無制限ドキュメント",
"pricing.plans.enterprise.feat2": "全AIモデルGPT-5、Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "全AIモデルClaude 5、DeepSeek V4 Pro、GLM-5.3…)",
"pricing.plans.enterprise.feat3": "オンプレミスまたは専用クラウド展開",
"pricing.plans.enterprise.feat4": "99.9% SLA保証",
"pricing.plans.enterprise.feat5": "24/7専任サポート",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "超高速マルチスレッドAI",
"pricing.trust.availability.title": "24/7利用可能",
"pricing.trust.availability.sub": "99.9%稼働率保証",
"pricing.aiModels.title": "AIモデル一覧 — 2026年3月",
"pricing.aiModels.title": "AIモデル一覧 — 2026年9月",
"pricing.aiModels.essential.title": "エッセンシャルAI翻訳",
"pricing.aiModels.essential.plan": "Proプラン",
"pricing.aiModels.essential.descPrefix": "ベース:",
"pricing.aiModels.essential.descSuffix": "— 2026年で最も費用対効果の高いAIモデル。フロンティアモデルと同等の品質をわずかなコストで実現。",
"pricing.aiModels.essential.modelName": "Essential AIモデル",
"pricing.aiModels.essential.context": "163Kトークンのコンテキスト",
"pricing.aiModels.essential.value": "優れた費用対効果",
"pricing.aiModels.essential.descSuffix": "— 2026年で最も費用対効果の高いAIモデル。",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash、GLM-5.3 Flash、MiniMax M3",
"pricing.aiModels.essential.context": "最大130万トークンのコンテキストGLM-5.3 Flash",
"pricing.aiModels.essential.value": "最高のコストパフォーマンス",
"pricing.aiModels.premium.title": "プレミアムAI翻訳",
"pricing.aiModels.premium.plan": "Businessプラン",
"pricing.aiModels.premium.descPrefix": "ベース:",
"pricing.aiModels.premium.descSuffix": "Anthropic社製— 法務、医療、複雑な技術文書に高精度。",
"pricing.aiModels.premium.context": "200Kトークンのコンテキスト",
"pricing.aiModels.premium.context": "100トークンのコンテキスト",
"pricing.aiModels.premium.precision": "最高精度",
"pricing.faq.title": "よくある質問",
"pricing.faq.q1": "いつでもプランを変更できますか?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "「エッセンシャルAI翻訳」とは何ですか",
"pricing.faq.a2": "独自のAIエンジンです。ドキュメントの文脈を理解し、レイアウトを保持し、技術用語を従来の翻訳よりはるかに適切に処理します。",
"pricing.faq.q3": "エッセンシャルAIとプレミアムAIの違いは何ですか",
"pricing.faq.a3": "Essential AIは最適化されたモデルを使用していますコストパフォーマンスに優れています。Premium AIはAnthropicのClaude 3.5 Haikuを使用し、法的、医学的、複雑な技術文書により正確です。",
"pricing.faq.a3": "Essential AIはDeepSeek V4 Flash、GLM-5.3 Flash、MiniMax M3を使用していますコストパフォーマンスに優れています。Premium AIはAnthropicのClaude 5を使用し、法的、医学的、複雑な技術文書により正確です。",
"pricing.faq.q4": "翻訳後もドキュメントは保存されますか?",
"pricing.faq.a4": "翻訳済みファイルはプランに応じて利用可能ですStarter 30日、Pro 90日、Business 1年。保存時および通信時は暗号化されています。",
"pricing.faq.q5": "月間枠を超えた場合はどうなりますか?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "支払いの作成中にエラーが発生しました。",
"pricing.dashboard": "ダッシュボード",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "100万トークンあたり$0.09から",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "代替モデルDeepSeek V4 Pro、GLM-5.3",
"pricing.confirm.title": "サブスクリプションの確認",
"pricing.confirm.subtitle": "安全な決済プロバイダーへ移動します。",
"pricing.confirm.cancel": "キャンセル",
"pricing.confirm.cta": "支払いへ進む",
"pricing.confirm.year": "年",
"pricing.confirm.month": "月",
"pricing.confirm.monthlyEquivalent": "年間請求 — 月あたり {price} ユーロ相当。",
"pricing.confirm.secureNote": "プロフィールからいつでも解約できます。決済はStripeが処理し、カード情報が当社のサーバーに送信されることはありません。",
"pricing.enterprise.subject": "エンタープライズプランについてのお問い合わせ",
"pricing.enterpriseBand.cta": "お問い合わせ",
"pricing.enterpriseBand.text": "大量処理、専用エンジン、オンプレミス対応 — ご相談ください。",
"pricing.error.server": "サーバーエラー {status}",
"pricing.freeBand.cta": "無料で始める",
"pricing.freeBand.text": "まず試してみたい方へ — 毎月5件まで無料、カード不要。",
"pricing.header.titleBase": "あらゆるニーズに",
"pricing.header.titleAccent": "ぴったりのプラン",
"pricing.toast.close": "閉じる",
"pricing.aiModels.premium.price": "100万トークンあたり $2 / $10"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "翻訳に最適化された最高のオープンソースモデルへの統一アクセス。",
"providerTheme.openrouter_premium.badge": "ウルトラ",
"providerTheme.openrouter_premium.subBadge": "最大コンテキスト",
"providerTheme.openrouter_premium.desc": "GPT-4o、Claude Sonnet 4.6 などの最先端モデルによる長文支援。",
"providerTheme.openrouter_premium.desc": "GPT-4o、Claude 5 などの最先端モデルによる長文支援。",
"providerTheme.zai.badge": "特化型",
"providerTheme.zai.subBadge": "金融と法律",
"providerTheme.zai.desc": "要求の厳しいビジネス用語 (法務、金融) 向けに微調整されたモデル。",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "제공업체",
"admin.nav.system": "시스템",
"admin.nav.logs": "로그",
"admin.nav.stats": "통계",
"admin.users.title": "사용자 관리",
"admin.users.subtitle": "사용자 계정 보기 및 관리",
"admin.users.planUpdated": "플랜이 업데이트되었습니다",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "데이터 대기 중...",
"admin.system.purging": "삭제 중...",
"admin.system.clean": "정리",
"admin.system.purge": "삭제"
"admin.system.purge": "삭제",
"admin.nav.models": "모델 & 구독",
"admin.nav.marketing": "마케팅",
"admin.marketing.audience": "대상",
"admin.marketing.audienceAllUsers": "전체 계정",
"admin.marketing.audienceInactive": "30일간 비활성 계정",
"admin.marketing.audiencePlaceholder": "대상 선택",
"admin.marketing.audiencePlanBusiness": "Business 플랜",
"admin.marketing.audiencePlanEnterprise": "Enterprise 플랜",
"admin.marketing.audiencePlanFree": "무료 플랜",
"admin.marketing.audiencePlanPro": "Pro 플랜",
"admin.marketing.audiencePlanStarter": "Starter 플랜",
"admin.marketing.audienceWaitlist": "대기 명단",
"admin.marketing.badgeReal": "실제",
"admin.marketing.badgeTest": "테스트",
"admin.marketing.confirmSend": "이 메일을 {count}명(«{audience}»)에게 보내시겠습니까?",
"admin.marketing.footerNote": "발송 시 수신거부 링크가 있는 바닥글이 자동으로 추가됩니다.",
"admin.marketing.hidePreview": "미리보기 숨기기",
"admin.marketing.history": "발송 이력",
"admin.marketing.historyFailedSuffix": ", {count}건 실패",
"admin.marketing.historySent": "{sent}/{total} 발송",
"admin.marketing.html": "HTML 내용",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "제목과 HTML을 입력하세요.",
"admin.marketing.incompleteTitle": "내용 불완전",
"admin.marketing.loadErrorTitle": "불러오기 오류",
"admin.marketing.localCheckUnavailable": "이 브라우저에서는 로컬 확인이 불가하여 서버가 사전 테스트 발송을 검증합니다.",
"admin.marketing.networkDesc": "백엔드에 연결할 수 없습니다.",
"admin.marketing.newCampaign": "새 캠페인",
"admin.marketing.noHistory": "발송 기록이 없습니다.",
"admin.marketing.preview": "미리보기",
"admin.marketing.previewEmpty": "미리보기: 왼쪽에 HTML을 붙여넣으세요.",
"admin.marketing.previewTitle": "이메일 미리보기",
"admin.marketing.recipientsAvailable": "수신거부 제외 후 {count}명에게 발송할 수 있습니다.",
"admin.marketing.sendReal": "{count}명에게 보내기",
"admin.marketing.sendRefusedTitle": "발송이 거부되었습니다",
"admin.marketing.sendTest": "테스트 발송",
"admin.marketing.sendingDesc": "{count}건이 발송 대기열에 있습니다(0.2초 간격). 수신거부는 제외됩니다.",
"admin.marketing.sendingTitle": "발송 진행 중",
"admin.marketing.subject": "제목",
"admin.marketing.subjectPlaceholder": "예: 번역이 기다리고 있습니다 — 7일간 20% 할인",
"admin.marketing.subtitle": "대상에게 이메일을 보냅니다. 필수 테스트 발송, 자동 수신거부 링크, 전체 이력이 포함됩니다.",
"admin.marketing.testDoneDesc": "{email}에서 메일 수신",
"admin.marketing.testDoneTitle": "테스트 발송 완료",
"admin.marketing.testEmail": "테스트 이메일 (선택)",
"admin.marketing.testEmailPlaceholder": "미입력 시: SMTP 발신 주소",
"admin.marketing.testFailedTitle": "테스트 발송 실패",
"admin.marketing.testRequiredHint": "실제 발송에는 동일 내용의 사전 테스트 발송이 필요합니다(서버가 검증).",
"admin.marketing.testValidated": "이 내용의 테스트 발송이 검증되었습니다.",
"admin.marketing.title": "마케팅 — 이메일 캠페인",
"admin.marketing.unsubscribedNote": "수신거부 {count}건은 모든 발송에서 제외됩니다.",
"admin.models.addModel": "모델 추가",
"admin.models.businessBadge": "Business 플랜",
"admin.models.cancel": "취소",
"admin.models.catalog": "OpenRouter 카탈로그",
"admin.models.catalogErrorDesc": "OpenRouter 카탈로그를 불러오지 못했습니다.",
"admin.models.catalogErrorTitle": "카탈로그 사용 불가",
"admin.models.customBadge": "맞춤 등급",
"admin.models.customNote": "맞춤 모델은 고객과 사례별로 정의합니다.",
"admin.models.defaultBadge": "기본",
"admin.models.emptyTier": "모델 없음: 플랜의 공식 라인업이 사용됩니다.",
"admin.models.enterpriseBadge": "Enterprise 플랜",
"admin.models.essentialBadge": "에센셜 AI 등급",
"admin.models.essentialCost": "— 비용 계수 1로 청구",
"admin.models.fallbackFirst": "(폴백 1순위)",
"admin.models.loadErrorDesc": "HTTP {status} — 관리자 토큰을 확인하세요.",
"admin.models.loadErrorTitle": "불러오기 오류",
"admin.models.matrixDesc": "등급별 활성 모델 — 목록 순서가 폴백 우선순위입니다. 라디오 버튼으로 기본 모델을 선택하면 재배포 없이 즉시 적용됩니다.",
"admin.models.matrixTitle": "플랜별 모델 매트릭스",
"admin.models.missingConfig": "AI 등급 구성을 찾을 수 없습니다. 페이지를 새로 고침하세요.",
"admin.models.moveDown": "아래로 이동",
"admin.models.moveUp": "위로 이동",
"admin.models.networkDesc": "백엔드에 연결할 수 없습니다.",
"admin.models.networkTitle": "네트워크 오류",
"admin.models.premiumBadge": "프리미엄 AI 등급",
"admin.models.premiumCost": "— 비용 계수 5로 청구",
"admin.models.premiumReservedNote": "Business·Enterprise 플랜 전용 («openrouter_premium» 엔진).",
"admin.models.proBadge": "Pro 플랜",
"admin.models.remove": "제거",
"admin.models.save": "저장",
"admin.models.saveErrorTitle": "저장 오류",
"admin.models.saveNetworkDesc": "구성을 저장할 수 없습니다.",
"admin.models.savedDesc": "새 기본 모델은 다음 번역부터 재배포 없이 적용됩니다.",
"admin.models.savedTitle": "모델 저장됨",
"admin.models.saving": "저장 중...",
"admin.models.setDefault": "{model}을(를) 기본 모델로 설정",
"admin.models.sharedTierNote": "공유 등급: Business 플랜도 «openrouter» 엔진에는 에센셜 등급을 사용합니다 — 위 목록은 두 플랜 모두에 적용됩니다.",
"admin.models.subtitle": "플랜 → AI 등급 매트릭스. 번역 시 실제 사용되는 모델은 플랜 등급의 모델입니다: Pro 플랜은 프리미엄 모델을 절대 호출할 수 없습니다.",
"admin.models.title": "모델 & 구독",
"admin.stats.aiTiers": "AI 등급 (30일)",
"admin.stats.includingCredits": "크레딧 {amount} 포함",
"admin.stats.mrr": "추정 MRR",
"admin.stats.noTranslationsYet": "최근 30일간 번역 기록이 없습니다: 앞으로의 번역으로 등급별 분포가 채워집니다.",
"admin.stats.payments30": "30일간 결제 {count}건",
"admin.stats.refreshing": "새로 고치는 중...",
"admin.stats.revenue30": "매출 (30일)",
"admin.stats.revenueTotal": "총 수령 매출",
"admin.stats.tiersSub": "에센셜 / 프리미엄 · 클래식 {classic} · 기타 {other}",
"admin.stats.unavailable": "비즈니스 통계를 사용할 수 없습니다 ({error}).",
"admin.stats.waitlist": "대기 명단",
"admin.stats.waitlistSub": "대기 중인 등록자"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "전문가용",
"landing.pricing.pro.f1": "월 200개 문서",
"landing.pricing.pro.f2": "문서당 최대 200페이지",
"landing.pricing.pro.f3": "AI 번역",
"landing.pricing.pro.f3": "에센셜 AI: DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google 포함",
"landing.pricing.pro.f5": "맞춤 용어집 및 프롬프트",
"landing.pricing.pro.f6": "우선 지원",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "대용량이 필요한 팀용",
"landing.pricing.business.f1": "월 1,000개 문서",
"landing.pricing.business.f2": "문서당 최대 500페이지",
"landing.pricing.business.f3": "프리미엄 AI (Claude)",
"landing.pricing.business.f3": "프리미엄 AI (Claude 5)",
"landing.pricing.business.f4": "모든 제공자 + API",
"landing.pricing.business.f5": "웹훅 및 자동화",
"landing.pricing.business.f6": "팀 시트 5석",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "DOCX, XLSX, PPTX 또는 PDF 파일 지원",
"landing.translate.aiAnalysis": "AI 분석 활성",
"landing.translate.processing": "처리 중",
"landing.translate.preservingLayout": "레이아웃이 보존되고 있습니다"
"landing.translate.preservingLayout": "레이아웃이 보존되고 있습니다",
"landing.beforeAfter.seal": "동일한 레이아웃, 단어 하나까지 그대로",
"landing.beforeAfter.proof1": "SmartArt 다이어그램은 병합되지 않고 재구성됩니다",
"landing.beforeAfter.proof2": "차트 계열과 축 번역",
"landing.beforeAfter.proof3": "목차는 대상 언어로 재생성",
"landing.beforeAfter.targetTitle": "기술 사양 — 공기 처리",
"landing.beforeAfter.targetPara1": "환기 설비는 2분기 종료 전에 가동되어야 합니다.",
"landing.beforeAfter.targetPara2Before": "",
"landing.beforeAfter.targetTerm": "공기조화기",
"landing.beforeAfter.targetPara2After": "는 일정에 따라 F7 필터 등급을 준수해야 합니다.",
"landing.beforeAfter.targetItem1": "열부하: 정격 유량에서 42kW",
"landing.beforeAfter.targetItem2": "소음 수준: 3m에서 45dB(A) 미만",
"landing.formats.pill": "호환성",
"landing.hero.visualCaption": "동일한 레이아웃, 새로운 언어 — 그 외에는 아무것도 바뀌지 않습니다",
"landing.pricing.free.name": "무료",
"landing.pricing.free.desc": "앱을 경험하기에 적합",
"landing.pricing.free.cta": "이 플랜 선택",
"landing.pricing.enterprise.name": "엔터프라이즈",
"landing.pricing.enterprise.desc": "대규모 조직을 위한 맞춤 솔루션",
"landing.pricing.enterprise.cta": "문의하기",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "90일 기록",
"pricing.plans.business.feat1": "월 1,000개 문서",
"pricing.plans.business.feat2": "문서당 최대 500페이지",
"pricing.plans.business.feat3": "에센셜 + 프리미엄 AI (Claude Haiku)",
"pricing.plans.business.feat3": "에센셜 + 프리미엄 AI (Claude 5)",
"pricing.plans.business.feat4": "모든 번역 제공업체",
"pricing.plans.business.feat5": "최대 50 MB 파일",
"pricing.plans.business.feat6": "API 액세스 (월 10,000회 호출)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "1년 기록",
"pricing.plans.business.feat10": "고급 분석",
"pricing.plans.enterprise.feat1": "무제한 문서",
"pricing.plans.enterprise.feat2": "모든 AI 모델 (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "모든 AI 모델 (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "온프레미스 또는 전용 클라우드 배포",
"pricing.plans.enterprise.feat4": "99.9% SLA 보장",
"pricing.plans.enterprise.feat5": "24/7 전담 지원",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "초고속 멀티스레드 AI",
"pricing.trust.availability.title": "24/7 이용 가능",
"pricing.trust.availability.sub": "99.9% 가동 보장",
"pricing.aiModels.title": "AI 모델 — 2026년 3월",
"pricing.aiModels.title": "AI 모델 — 2026년 9월",
"pricing.aiModels.essential.title": "에센셜 AI 번역",
"pricing.aiModels.essential.plan": "Pro 플랜",
"pricing.aiModels.essential.descPrefix": "기반:",
"pricing.aiModels.essential.descSuffix": "— 2026년 가장 비용 효율적인 AI 모델. 프론티어 모델과 동등한 품질을 극소수의 비용으로 제공.",
"pricing.aiModels.essential.modelName": "Essential AI 모델",
"pricing.aiModels.essential.context": "163K 토큰 컨텍스트",
"pricing.aiModels.essential.value": "우수한 가성비",
"pricing.aiModels.essential.descSuffix": "— 2026년 가장 비용 효율적인 AI 모델.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"pricing.aiModels.essential.context": "최대 130만 토큰 컨텍스트 (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "최고의 가성비",
"pricing.aiModels.premium.title": "프리미엄 AI 번역",
"pricing.aiModels.premium.plan": "Business 플랜",
"pricing.aiModels.premium.descPrefix": "기반:",
"pricing.aiModels.premium.descSuffix": "Anthropic사 제품 — 법률, 의료 및 복잡한 기술 문서에서 높은 정확도.",
"pricing.aiModels.premium.context": "200K 토큰 컨텍스트",
"pricing.aiModels.premium.context": "100 토큰 컨텍스트",
"pricing.aiModels.premium.precision": "최고 정확도",
"pricing.faq.title": "자주 묻는 질문",
"pricing.faq.q1": "언제든지 플랜을 변경할 수 있나요?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "「에센셜 AI 번역」이란 무엇인가요?",
"pricing.faq.a2": "당사의 AI 엔진입니다. 문서의 맥락을 이해하고, 레이아웃을 보존하며, 기술 용어를 기존 번역보다 훨씬 잘 처리합니다.",
"pricing.faq.q3": "에센셜 AI와 프리미엄 AI의 차이점은 무엇인가요?",
"pricing.faq.a3": "Essential AI는 최적화된 모델을 사용합니다 (우수한 가성비). Premium AI는 Anthropic의 Claude 3.5 Haiku를 사용하여 법률, 의료 및 복잡한 기술 문서에서 더 정확합니다.",
"pricing.faq.a3": "Essential AI는 DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3를 사용합니다 (우수한 가성비). Premium AI는 Anthropic의 Claude 5를 사용하여 법률, 의료 및 복잡한 기술 문서에서 더 정확합니다.",
"pricing.faq.q4": "번역 후 문서가 보관되나요?",
"pricing.faq.a4": "번역된 파일은 플랜에 따라 이용 가능합니다 (Starter 30일, Pro 90일, Business 1년). 저장 시 및 전송 중 암호화됩니다.",
"pricing.faq.q5": "월간 할당량을 초과하면 어떻게 되나요?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "결제 생성 중 오류가 발생했습니다.",
"pricing.dashboard": "대시보드",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "백만 토큰당 $0.09부터",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "대체 모델: DeepSeek V4 Pro, GLM-5.3",
"pricing.confirm.title": "구독 확인",
"pricing.confirm.subtitle": "안전한 결제 대행사로 이동합니다.",
"pricing.confirm.cancel": "취소",
"pricing.confirm.cta": "결제로 계속",
"pricing.confirm.year": "년",
"pricing.confirm.month": "개월",
"pricing.confirm.monthlyEquivalent": "연간 결제 — 월 {price}유로 상당.",
"pricing.confirm.secureNote": "프로필에서 언제든지 해지할 수 있습니다. 결제는 Stripe에서 처리되며 카드 정보는 당사 서버에 저장되지 않습니다.",
"pricing.enterprise.subject": "엔터프라이즈 문의",
"pricing.enterpriseBand.cta": "문의하기",
"pricing.enterpriseBand.text": "대용량, 전용 엔진, 온프레미스 옵션 — 상담해 보세요.",
"pricing.error.server": "서버 오류 {status}",
"pricing.freeBand.cta": "무료로 시작",
"pricing.freeBand.text": "일단 써보고 싶으신가요? 무료로 시작 — 월 5개 문서, 카드 불필요.",
"pricing.header.titleBase": "모든 필요를 위한",
"pricing.header.titleAccent": "하나의 플랜",
"pricing.toast.close": "닫기",
"pricing.aiModels.premium.price": "백만 토큰당 $2 / $10"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "번역에 최적화된 최고의 오픈소스 모델에 대한 통합 액세스.",
"providerTheme.openrouter_premium.badge": "울트라",
"providerTheme.openrouter_premium.subBadge": "최대 컨텍스트",
"providerTheme.openrouter_premium.desc": "최신 모델(GPT-4o, Claude Sonnet 4.6)의 지원을 받는 긴 문서 번역.",
"providerTheme.openrouter_premium.desc": "최신 모델(GPT-4o, Claude 5)의 지원을 받는 긴 문서 번역.",
"providerTheme.zai.badge": "전문",
"providerTheme.zai.subBadge": "금융 및 법률",
"providerTheme.zai.desc": "까다로운 비즈니스 용어(법률, 금융)에 맞게 미세 조정된 모델.",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "Providers",
"admin.nav.system": "Systeem",
"admin.nav.logs": "Logboeken",
"admin.nav.stats": "Statistieken",
"admin.users.title": "Gebruikersbeheer",
"admin.users.subtitle": "Gebruikersaccounts bekijken en beheren",
"admin.users.planUpdated": "Abonnement bijgewerkt",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "Wachten op gegevens...",
"admin.system.purging": "Wissen...",
"admin.system.clean": "Opschonen",
"admin.system.purge": "Wissen"
"admin.system.purge": "Wissen",
"admin.nav.models": "Modellen & abonnementen",
"admin.nav.marketing": "Marketing",
"admin.marketing.audience": "Doelgroep",
"admin.marketing.audienceAllUsers": "Alle accounts",
"admin.marketing.audienceInactive": "Accounts 30 dagen inactief",
"admin.marketing.audiencePlaceholder": "Kies een doelgroep",
"admin.marketing.audiencePlanBusiness": "Business-abonnement",
"admin.marketing.audiencePlanEnterprise": "Enterprise-abonnement",
"admin.marketing.audiencePlanFree": "Gratis-abonnement",
"admin.marketing.audiencePlanPro": "Pro-abonnement",
"admin.marketing.audiencePlanStarter": "Starter-abonnement",
"admin.marketing.audienceWaitlist": "Wachtlijst",
"admin.marketing.badgeReal": "echt",
"admin.marketing.badgeTest": "test",
"admin.marketing.confirmSend": "Deze e-mail versturen naar {count} ontvanger(s) („{audience}”)?",
"admin.marketing.footerNote": "Een voettekst met de uitschrijflink wordt automatisch toegevoegd bij verzending.",
"admin.marketing.hidePreview": "Voorbeeld verbergen",
"admin.marketing.history": "Verzendgeschiedenis",
"admin.marketing.historyFailedSuffix": ", {count} mislukt",
"admin.marketing.historySent": "{sent}/{total} verzonden",
"admin.marketing.html": "HTML-inhoud",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "Vul het onderwerp en de HTML in.",
"admin.marketing.incompleteTitle": "Onvolledige inhoud",
"admin.marketing.loadErrorTitle": "Laadfout",
"admin.marketing.localCheckUnavailable": "Lokale controle niet beschikbaar in deze browser: de server controleert de voorafgaande testzending.",
"admin.marketing.networkDesc": "Kan de backend niet bereiken.",
"admin.marketing.newCampaign": "Nieuwe campagne",
"admin.marketing.noHistory": "Geen zending geregistreerd.",
"admin.marketing.preview": "Voorbeeld",
"admin.marketing.previewEmpty": "Voorbeeld: plak je HTML hiernaast.",
"admin.marketing.previewTitle": "E-mailvoorbeeld",
"admin.marketing.recipientsAvailable": "{count} ontvanger(s) beschikbaar na uitsluiting van uitschrijvingen.",
"admin.marketing.sendReal": "Versturen naar {count} ontvanger(s)",
"admin.marketing.sendRefusedTitle": "Verzending geweigerd",
"admin.marketing.sendTest": "Testzending",
"admin.marketing.sendingDesc": "{count} e-mail(s) in de verzendwachtrij (interval 0,2 s). Uitschrijvingen worden uitgesloten.",
"admin.marketing.sendingTitle": "Verzending bezig",
"admin.marketing.subject": "Onderwerp",
"admin.marketing.subjectPlaceholder": "Bijv.: Uw vertaling wacht — 20% gedurende 7 dagen",
"admin.marketing.subtitle": "E-mails sturen naar een doelgroep, met verplichte testzending, automatische uitschrijflink en volledige geschiedenis.",
"admin.marketing.testDoneDesc": "E-mail ontvangen op {email}",
"admin.marketing.testDoneTitle": "Testzending uitgevoerd",
"admin.marketing.testEmail": "Test-e-mail (optioneel)",
"admin.marketing.testEmailPlaceholder": "Anders: SMTP-afzenderadres",
"admin.marketing.testFailedTitle": "Testzending mislukt",
"admin.marketing.testRequiredHint": "Een echte zending vereist een voorafgaande testzending van exact deze inhoud (door de server gecontroleerd).",
"admin.marketing.testValidated": "Testzending gevalideerd voor deze inhoud.",
"admin.marketing.title": "Marketing — e-mailcampagnes",
"admin.marketing.unsubscribedNote": "{count} uitgeschreven contact(en) worden van elke zending uitgesloten.",
"admin.models.addModel": "Model toevoegen",
"admin.models.businessBadge": "Business-abonnement",
"admin.models.cancel": "Annuleren",
"admin.models.catalog": "OpenRouter-catalogus",
"admin.models.catalogErrorDesc": "OpenRouter-catalogus kon niet worden geladen.",
"admin.models.catalogErrorTitle": "Catalogus niet beschikbaar",
"admin.models.customBadge": "Aangepast niveau",
"admin.models.customNote": "Maatwerkmodellen, per geval met de klant afgesproken.",
"admin.models.defaultBadge": "standaard",
"admin.models.emptyTier": "Geen model: de officiële modellenreeks van het abonnement wordt gebruikt.",
"admin.models.enterpriseBadge": "Enterprise-abonnement",
"admin.models.essentialBadge": "Basis-AI-niveau",
"admin.models.essentialCost": "— gefactoreerd met kostenfactor 1",
"admin.models.fallbackFirst": "(fallback nr. 1)",
"admin.models.loadErrorDesc": "HTTP {status} — controleer je admin-token.",
"admin.models.loadErrorTitle": "Laadfout",
"admin.models.matrixDesc": "Actieve modellen per niveau — de volgorde van de lijst is de fallback-prioriteit. De keuzerondje kiest het standaardmodel, direct actief zonder heruitrol.",
"admin.models.matrixTitle": "Modelmatrix per abonnement",
"admin.models.missingConfig": "AI-niveauconfiguratie niet gevonden. Herlaad de pagina.",
"admin.models.moveDown": "Omlaag",
"admin.models.moveUp": "Omhoog",
"admin.models.networkDesc": "Kan de backend niet bereiken.",
"admin.models.networkTitle": "Netwerkfout",
"admin.models.premiumBadge": "Premium-AI-niveau",
"admin.models.premiumCost": "— gefactoreerd met kostenfactor 5",
"admin.models.premiumReservedNote": "Voorbehouden aan Business- en Enterprise-abonnementen (engine «openrouter_premium»).",
"admin.models.proBadge": "Pro-abonnement",
"admin.models.remove": "Verwijderen",
"admin.models.save": "Opslaan",
"admin.models.saveErrorTitle": "Opslagfout",
"admin.models.saveNetworkDesc": "Configuratie kon niet worden opgeslagen.",
"admin.models.savedDesc": "Het nieuwe standaardmodel wordt vanaf de volgende vertaling gebruikt, zonder heruitrol.",
"admin.models.savedTitle": "Modellen opgeslagen",
"admin.models.saving": "Opslaan...",
"admin.models.setDefault": "{model} als standaardmodel instellen",
"admin.models.sharedTierNote": "Gedeeld niveau: het Business-abonnement gebruikt het Basis-niveau ook voor zijn «openrouter»-engine — de bovenstaande lijst geldt voor beide abonnementen.",
"admin.models.subtitle": "Matrix abonnementen → AI-niveaus. Het model dat per vertaling echt wordt gebruikt is dat van het niveau van het abonnement: een Pro-abonnement kan nooit een Premium-model aanroepen.",
"admin.models.title": "Modellen & abonnementen",
"admin.stats.aiTiers": "AI-niveaus (30 d)",
"admin.stats.includingCredits": "waarvan {amount} aan credits",
"admin.stats.mrr": "Geschatte MRR",
"admin.stats.noTranslationsYet": "Geen vertalingen van de laatste 30 dagen in de database: de niveauverdeling vult zich aan met de komende vertalingen.",
"admin.stats.payments30": "{count} betaling(en) in 30 dagen",
"admin.stats.refreshing": "Vernieuwen...",
"admin.stats.revenue30": "Omzet (30 dagen)",
"admin.stats.revenueTotal": "Totaal ontvangen omzet",
"admin.stats.tiersSub": "Basis / Premium · klassiek {classic} · overig {other}",
"admin.stats.unavailable": "Bedrijfsstatistieken niet beschikbaar ({error}).",
"admin.stats.waitlist": "Wachtlijst",
"admin.stats.waitlistSub": "inschrijvingen op de wachtlijst"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "Voor veeleisende professionals",
"landing.pricing.pro.f1": "200 documenten / maand",
"landing.pricing.pro.f2": "Tot 200 pagina's per doc",
"landing.pricing.pro.f3": "IA-aangedreven vertaling",
"landing.pricing.pro.f3": "Basis-AI: DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google inbegrepen",
"landing.pricing.pro.f5": "Eigen glossaria en prompts",
"landing.pricing.pro.f6": "Prioriteitsondersteuning",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "Voor teams met grote behoeften",
"landing.pricing.business.f1": "1 000 documenten / maand",
"landing.pricing.business.f2": "Tot 500 pagina's per doc",
"landing.pricing.business.f3": "Premium AI (Claude)",
"landing.pricing.business.f3": "Premium-AI (Claude 5)",
"landing.pricing.business.f4": "Alle providers + API-toegang",
"landing.pricing.business.f5": "Webhooks en automatisering",
"landing.pricing.business.f6": "5 teamplekken",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "DOCX, XLSX, PPTX of PDF bestanden ondersteund",
"landing.translate.aiAnalysis": "Actieve AI-analyse",
"landing.translate.processing": "Verwerking bezig",
"landing.translate.preservingLayout": "Uw opmaak wordt behouden"
"landing.translate.preservingLayout": "Uw opmaak wordt behouden",
"landing.beforeAfter.seal": "Zelfde lay-out, woord voor woord",
"landing.beforeAfter.proof1": "SmartArt-diagrammen worden herbouwd, niet afgevlakt",
"landing.beforeAfter.proof2": "Diagramreeksen en assen vertaald",
"landing.beforeAfter.proof3": "Inhoudsopgaven opnieuw gegenereerd in de doeltaal",
"landing.beforeAfter.targetTitle": "Technische specificatie — Luchtbehandeling",
"landing.beforeAfter.targetPara1": "Het ventilatiesysteem moet vóór het einde van het tweede kwartaal in bedrijf worden gesteld.",
"landing.beforeAfter.targetPara2Before": "De",
"landing.beforeAfter.targetTerm": "luchtbehandelingsgroep",
"landing.beforeAfter.targetPara2After": "moet volgens planning voldoen aan filterklasse F7.",
"landing.beforeAfter.targetItem1": "Thermische belasting: 42 kW bij nominale doorstroom",
"landing.beforeAfter.targetItem2": "Geluidsniveau onder 45 dB(A) op 3 m",
"landing.formats.pill": "COMPATIBILITEIT",
"landing.hero.visualCaption": "Zelfde lay-out, nieuwe taal — verder verandert niets",
"landing.pricing.free.name": "Gratis",
"landing.pricing.free.desc": "Ideaal om de app te ontdekken",
"landing.pricing.free.cta": "Dit plan kiezen",
"landing.pricing.enterprise.name": "Enterprise",
"landing.pricing.enterprise.desc": "Op maat gemaakte oplossingen voor grote organisaties",
"landing.pricing.enterprise.cta": "Neem contact op",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "90 dagen geschiedenis",
"pricing.plans.business.feat1": "1 000 documenten / maand",
"pricing.plans.business.feat2": "Tot 500 pagina's per document",
"pricing.plans.business.feat3": "Basis- + Premium-AI (Claude Haiku)",
"pricing.plans.business.feat3": "Basis-AI + Premium-AI (Claude 5)",
"pricing.plans.business.feat4": "Alle vertaalproviders",
"pricing.plans.business.feat5": "Bestanden tot 50 MB",
"pricing.plans.business.feat6": "API-toegang (10 000 aanroepen/maand)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "1 jaar geschiedenis",
"pricing.plans.business.feat10": "Geavanceerde analyses",
"pricing.plans.enterprise.feat1": "Onbeperkte documenten",
"pricing.plans.enterprise.feat2": "Alle AI-modellen (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "Alle AI-modellen (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "On-premise of dedicated cloud",
"pricing.plans.enterprise.feat4": "99,9 % SLA gegarandeerd",
"pricing.plans.enterprise.feat5": "24/7 dedicated support",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "Ultrasnelle multi-threaded AI",
"pricing.trust.availability.title": "24/7 beschikbaar",
"pricing.trust.availability.sub": "99,9 % gegarandeerde beschikbaarheid",
"pricing.aiModels.title": "Onze AI-modellen — maart 2026",
"pricing.aiModels.title": "Onze AI-modellen — september 2026",
"pricing.aiModels.essential.title": "AI-basisvertaling",
"pricing.aiModels.essential.plan": "Pro-abonnement",
"pricing.aiModels.essential.descPrefix": "Gebaseerd op",
"pricing.aiModels.essential.descSuffix": "— het meest kostenefficiënte AI-model van 2026. Kwaliteit vergelijkbaar met frontier-modellen voor een fractie van de kosten.",
"pricing.aiModels.essential.modelName": "ons Essential AI-model",
"pricing.aiModels.essential.context": "163K tokens context",
"pricing.aiModels.essential.value": "Uitstekende prijs-kwaliteitverhouding",
"pricing.aiModels.essential.descSuffix": "— de AI-modellen met de beste prijs-kwaliteitverhouding van 2026.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash en MiniMax M3",
"pricing.aiModels.essential.context": "Tot 1,3 mln context (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "De beste prijs-kwaliteitverhouding",
"pricing.aiModels.premium.title": "AI-premiumvertaling",
"pricing.aiModels.premium.plan": "Business-abonnement",
"pricing.aiModels.premium.descPrefix": "Gebaseerd op",
"pricing.aiModels.premium.descSuffix": "van Anthropic — nauwkeurig bij juridische, medische en complexe technische documenten.",
"pricing.aiModels.premium.context": "200K tokens context",
"pricing.aiModels.premium.context": "1 mln context",
"pricing.aiModels.premium.precision": "Beste nauwkeurigheid",
"pricing.faq.title": "Veelgestelde vragen",
"pricing.faq.q1": "Kan ik op elk moment van abonnement wisselen?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "Wat is «AI-basisvertaling»?",
"pricing.faq.a2": "Het is onze IA-engine. Hij begrijpt de context van uw documenten, behoudt de lay-out en behandelt technische termen veel beter dan klassieke vertaling.",
"pricing.faq.q3": "Wat is het verschil tussen Basis- en Premium-AI?",
"pricing.faq.a3": "Essential IA gebruikt een geoptimaliseerd model (uitstekende prijs-kwaliteitverhouding). Premium IA gebruikt Claude 3.5 Haiku van Anthropic, nauwkeuriger bij juridische, medische en complexe technische documenten.",
"pricing.faq.a3": "Basis-AI draait op DeepSeek V4 Flash, GLM-5.3 Flash en MiniMax M3 (uitstekende prijs-kwaliteitverhouding). Premium-AI gebruikt Claude 5 van Anthropic, nauwkeuriger bij juridische, medische en complexe technische documenten.",
"pricing.faq.q4": "Worden mijn documenten bewaard na vertaling?",
"pricing.faq.a4": "Vertaalde bestanden zijn beschikbaar volgens uw abonnement (30 dagen Starter, 90 dagen Pro, 1 jaar Business). Ze zijn versleuteld at-rest en in transit.",
"pricing.faq.q5": "Wat gebeurt er als ik mijn maandelijkse quotum overschrijd?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "Fout bij aanmaken van de betaling.",
"pricing.dashboard": "Dashboard",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "Vanaf $0,09 per miljoen tokens",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "Alternatieven: DeepSeek V4 Pro en GLM-5.3",
"pricing.confirm.title": "Bevestig uw abonnement",
"pricing.confirm.subtitle": "U wordt doorgestuurd naar onze veilige betaalprovider.",
"pricing.confirm.cancel": "Annuleren",
"pricing.confirm.cta": "Verder naar betaling",
"pricing.confirm.year": "jaar",
"pricing.confirm.month": "maand",
"pricing.confirm.monthlyEquivalent": "Jaarlijkse facturering — dus {price} € / maand.",
"pricing.confirm.secureNote": "Op elk moment opzegbaar via uw profiel. Betaling wordt verwerkt door Stripe; uw kaartgegevens raken onze servers nooit.",
"pricing.enterprise.subject": "Enterprise-aanvraag",
"pricing.enterpriseBand.cta": "Neem contact op",
"pricing.enterpriseBand.text": "Volume, speciale engines, on-premise opties — laten we praten.",
"pricing.error.server": "Serverfout {status}",
"pricing.freeBand.cta": "Gratis starten",
"pricing.freeBand.text": "Eerst uitproberen? Start gratis — 5 documenten per maand, geen kaart nodig.",
"pricing.header.titleBase": "Een plan voor",
"pricing.header.titleAccent": "elke behoefte",
"pricing.toast.close": "Sluiten",
"pricing.aiModels.premium.price": "$2 / $10 per 1M tokens"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "Uniforme toegang tot de beste open-source modellen, geoptimaliseerd voor vertaling.",
"providerTheme.openrouter_premium.badge": "Ultra",
"providerTheme.openrouter_premium.subBadge": "Maximale context",
"providerTheme.openrouter_premium.desc": "Ondersteund door state-of-the-art modellen (GPT-4o, Claude Sonnet 4.6) voor lange documenten.",
"providerTheme.openrouter_premium.desc": "Ondersteund door state-of-the-art modellen (GPT-4o, Claude 5) voor lange documenten.",
"providerTheme.zai.badge": "Gespecialiseerd",
"providerTheme.zai.subBadge": "Financiën & Recht",
"providerTheme.zai.desc": "Model afgestemd op veeleisende bedrijfsterminologieën (juridisch, financieel).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "Provedores",
"admin.nav.system": "Sistema",
"admin.nav.logs": "Registros",
"admin.nav.stats": "Estatísticas",
"admin.users.title": "Gestão de Usuários",
"admin.users.subtitle": "Visualizar e gerenciar contas de usuários",
"admin.users.planUpdated": "Plano atualizado",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "Aguardando dados...",
"admin.system.purging": "Limpando...",
"admin.system.clean": "Limpar",
"admin.system.purge": "Limpar"
"admin.system.purge": "Limpar",
"admin.nav.models": "Modelos e assinaturas",
"admin.nav.marketing": "Marketing",
"admin.marketing.audience": "Público",
"admin.marketing.audienceAllUsers": "Todas as contas",
"admin.marketing.audienceInactive": "Contas inativas há 30 dias",
"admin.marketing.audiencePlaceholder": "Escolher um público",
"admin.marketing.audiencePlanBusiness": "Plano Business",
"admin.marketing.audiencePlanEnterprise": "Plano Enterprise",
"admin.marketing.audiencePlanFree": "Plano Gratuito",
"admin.marketing.audiencePlanPro": "Plano Pro",
"admin.marketing.audiencePlanStarter": "Plano Starter",
"admin.marketing.audienceWaitlist": "Lista de espera",
"admin.marketing.badgeReal": "real",
"admin.marketing.badgeTest": "teste",
"admin.marketing.confirmSend": "Enviar este email para {count} destinatário(s) («{audience}»)?",
"admin.marketing.footerNote": "Um rodapé com o link de descadastro é adicionado automaticamente ao envio.",
"admin.marketing.hidePreview": "Ocultar pré-visualização",
"admin.marketing.history": "Histórico de envios",
"admin.marketing.historyFailedSuffix": ", {count} falhas",
"admin.marketing.historySent": "{sent}/{total} enviados",
"admin.marketing.html": "Conteúdo HTML",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "Preencha o assunto e o HTML.",
"admin.marketing.incompleteTitle": "Conteúdo incompleto",
"admin.marketing.loadErrorTitle": "Erro ao carregar",
"admin.marketing.localCheckUnavailable": "Verificação local indisponível neste navegador: o servidor verificará o envio de teste prévio.",
"admin.marketing.networkDesc": "Não foi possível contatar o backend.",
"admin.marketing.newCampaign": "Novo envio",
"admin.marketing.noHistory": "Nenhum envio registrado.",
"admin.marketing.preview": "Pré-visualização",
"admin.marketing.previewEmpty": "Pré-visualização: cole seu HTML ao lado.",
"admin.marketing.previewTitle": "Pré-visualização do email",
"admin.marketing.recipientsAvailable": "{count} destinatário(s) disponíveis após excluir os descadastrados.",
"admin.marketing.sendReal": "Enviar para {count} destinatário(s)",
"admin.marketing.sendRefusedTitle": "Envio recusado",
"admin.marketing.sendTest": "Envio de teste",
"admin.marketing.sendingDesc": "{count} email(s) na fila de envio (intervalo de 0,2 s). Os descadastrados ficam excluídos.",
"admin.marketing.sendingTitle": "Envio em andamento",
"admin.marketing.subject": "Assunto",
"admin.marketing.subjectPlaceholder": "Ex.: Sua tradução o espera — 20% por 7 dias",
"admin.marketing.subtitle": "Envio de emails para um público, com envio de teste obrigatório, link de descadastro automático e histórico completo.",
"admin.marketing.testDoneDesc": "Email recebido em {email}",
"admin.marketing.testDoneTitle": "Envio de teste realizado",
"admin.marketing.testEmail": "Email de teste (opcional)",
"admin.marketing.testEmailPlaceholder": "Caso contrário: endereço de remetente SMTP",
"admin.marketing.testFailedTitle": "Falha no envio de teste",
"admin.marketing.testRequiredHint": "O envio real exige um envio de teste prévio deste conteúdo exato (verificado pelo servidor).",
"admin.marketing.testValidated": "Envio de teste validado para este conteúdo.",
"admin.marketing.title": "Marketing — envios por email",
"admin.marketing.unsubscribedNote": "{count} contato(s) descadastrado(s) serão excluídos de todo envio.",
"admin.models.addModel": "Adicionar um modelo",
"admin.models.businessBadge": "Plano Business",
"admin.models.cancel": "Cancelar",
"admin.models.catalog": "Catálogo do OpenRouter",
"admin.models.catalogErrorDesc": "Não foi possível carregar o catálogo do OpenRouter.",
"admin.models.catalogErrorTitle": "Catálogo indisponível",
"admin.models.customBadge": "Nível personalizado",
"admin.models.customNote": "Modelos sob medida, definidos caso a caso com o cliente.",
"admin.models.defaultBadge": "padrão",
"admin.models.emptyTier": "Nenhum modelo: a gama oficial do plano será usada.",
"admin.models.enterpriseBadge": "Plano Enterprise",
"admin.models.essentialBadge": "Nível de IA Essencial",
"admin.models.essentialCost": "— faturado com fator de custo 1",
"admin.models.fallbackFirst": "(reserva n.º 1)",
"admin.models.loadErrorDesc": "HTTP {status} — verifique seu token de administrador.",
"admin.models.loadErrorTitle": "Erro ao carregar",
"admin.models.matrixDesc": "Modelos ativos por nível — a ordem da lista é a prioridade de reserva. O botão de opção escolhe o modelo padrão, aplicado imediatamente sem nova implantação.",
"admin.models.matrixTitle": "Matriz de modelos por plano",
"admin.models.missingConfig": "Configuração dos níveis de IA não encontrada. Recarregue a página.",
"admin.models.moveDown": "Mover para baixo",
"admin.models.moveUp": "Mover para cima",
"admin.models.networkDesc": "Não foi possível contatar o backend.",
"admin.models.networkTitle": "Erro de rede",
"admin.models.premiumBadge": "Nível de IA Premium",
"admin.models.premiumCost": "— faturado com fator de custo 5",
"admin.models.premiumReservedNote": "Reservado aos planos Business e Enterprise (motor «openrouter_premium»).",
"admin.models.proBadge": "Plano Pro",
"admin.models.remove": "Remover",
"admin.models.save": "Salvar",
"admin.models.saveErrorTitle": "Erro ao salvar",
"admin.models.saveNetworkDesc": "Não foi possível salvar a configuração.",
"admin.models.savedDesc": "O novo modelo padrão é usado já na próxima tradução, sem nova implantação.",
"admin.models.savedTitle": "Modelos salvos",
"admin.models.saving": "Salvando...",
"admin.models.setDefault": "Definir {model} como modelo padrão",
"admin.models.sharedTierNote": "Nível compartilhado: o plano Business também usa o Essencial para o motor «openrouter» — a lista acima vale para os dois planos.",
"admin.models.subtitle": "Matriz planos → níveis de IA. O modelo realmente usado em cada tradução é o do nível do plano: um plano Pro nunca pode disparar um modelo Premium.",
"admin.models.title": "Modelos e assinaturas",
"admin.stats.aiTiers": "Níveis de IA (30 d)",
"admin.stats.includingCredits": "incluindo {amount} em créditos",
"admin.stats.mrr": "MRR estimado",
"admin.stats.noTranslationsYet": "Nenhuma tradução registrada nos últimos 30 dias: a distribuição por níveis se preencherá com as próximas traduções.",
"admin.stats.payments30": "{count} pagamento(s) em 30 dias",
"admin.stats.refreshing": "Atualizando...",
"admin.stats.revenue30": "Receitas (30 dias)",
"admin.stats.revenueTotal": "Receitas recebidas (total)",
"admin.stats.tiersSub": "Essencial / Premium · clássico {classic} · outro {other}",
"admin.stats.unavailable": "Estatísticas de negócio indisponíveis ({error}).",
"admin.stats.waitlist": "Lista de espera",
"admin.stats.waitlistSub": "inscritos na espera"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "Para profissionais exigentes",
"landing.pricing.pro.f1": "200 documentos / mês",
"landing.pricing.pro.f2": "Até 200 páginas por doc",
"landing.pricing.pro.f3": "Tradução com IA",
"landing.pricing.pro.f3": "IA Essencial: DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google incluídos",
"landing.pricing.pro.f5": "Glossários e prompts personalizados",
"landing.pricing.pro.f6": "Suporte prioritário",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "Para equipes com alto volume",
"landing.pricing.business.f1": "1 000 documentos / mês",
"landing.pricing.business.f2": "Até 500 páginas por doc",
"landing.pricing.business.f3": "IA Premium (Claude)",
"landing.pricing.business.f3": "IA Premium (Claude 5)",
"landing.pricing.business.f4": "Todos os provedores + API",
"landing.pricing.business.f5": "Webhooks e automação",
"landing.pricing.business.f6": "5 assentos de equipe",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "Ficheiros DOCX, XLSX, PPTX ou PDF suportados",
"landing.translate.aiAnalysis": "Análise IA Ativa",
"landing.translate.processing": "Em processamento",
"landing.translate.preservingLayout": "O seu layout está a ser preservado"
"landing.translate.preservingLayout": "O seu layout está a ser preservado",
"landing.beforeAfter.seal": "O mesmo layout, palavra por palavra",
"landing.beforeAfter.proof1": "Diagramas SmartArt reconstruídos, não achatados",
"landing.beforeAfter.proof2": "Séries e eixos dos gráficos traduzidos",
"landing.beforeAfter.proof3": "Sumários regenerados no idioma de destino",
"landing.beforeAfter.targetTitle": "Especificação técnica — Tratamento de ar",
"landing.beforeAfter.targetPara1": "A instalação de ventilação deve ser colocada em serviço antes do fim do segundo trimestre.",
"landing.beforeAfter.targetPara2Before": "A",
"landing.beforeAfter.targetTerm": "unidade de tratamento de ar",
"landing.beforeAfter.targetPara2After": "deve atender à classe de filtro F7 conforme o cronograma.",
"landing.beforeAfter.targetItem1": "Carga térmica: 42 kW em vazão nominal",
"landing.beforeAfter.targetItem2": "Nível sonoro abaixo de 45 dB(A) a 3 m",
"landing.formats.pill": "COMPATIBILIDADE",
"landing.hero.visualCaption": "O mesmo layout, novo idioma — nada mais muda",
"landing.pricing.free.name": "Grátis",
"landing.pricing.free.desc": "Ideal para descobrir a aplicação",
"landing.pricing.free.cta": "Escolher este plano",
"landing.pricing.enterprise.name": "Empresas",
"landing.pricing.enterprise.desc": "Soluções à medida para grandes organizações",
"landing.pricing.enterprise.cta": "Fale conosco",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "Histórico de 90 dias",
"pricing.plans.business.feat1": "1 000 documentos / mês",
"pricing.plans.business.feat2": "Até 500 páginas por documento",
"pricing.plans.business.feat3": "IA Essencial + Premium (Claude Haiku)",
"pricing.plans.business.feat3": "IA Essencial + IA Premium (Claude 5)",
"pricing.plans.business.feat4": "Todos os provedores de tradução",
"pricing.plans.business.feat5": "Arquivos de até 50 MB",
"pricing.plans.business.feat6": "Acesso à API (10 000 chamadas/mês)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "Histórico de 1 ano",
"pricing.plans.business.feat10": "Análises avançadas",
"pricing.plans.enterprise.feat1": "Documentos ilimitados",
"pricing.plans.enterprise.feat2": "Todos os modelos de IA (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "Todos os modelos de IA (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "Implantação local ou em nuvem dedicada",
"pricing.plans.enterprise.feat4": "SLA 99,9 % garantido",
"pricing.plans.enterprise.feat5": "Suporte dedicado 24/7",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "IA multi-thread ultrarrápida",
"pricing.trust.availability.title": "Disponível 24/7",
"pricing.trust.availability.sub": "99,9 % de uptime garantido",
"pricing.aiModels.title": "Nossos modelos de IA — Março 2026",
"pricing.aiModels.title": "Nossos modelos de IA — Setembro de 2026",
"pricing.aiModels.essential.title": "Tradução IA Essencial",
"pricing.aiModels.essential.plan": "Plano Pro",
"pricing.aiModels.essential.descPrefix": "Baseado em",
"pricing.aiModels.essential.descSuffix": "— o modelo de IA mais econômico de 2026. Qualidade comparável a modelos frontier a uma fração do custo.",
"pricing.aiModels.essential.modelName": "nosso modelo IA Essencial",
"pricing.aiModels.essential.context": "163K tokens de contexto",
"pricing.aiModels.essential.value": "Excelente custo-benefício",
"pricing.aiModels.essential.descSuffix": "— os modelos de IA com o melhor custo-benefício de 2026.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash e MiniMax M3",
"pricing.aiModels.essential.context": "Até 1,3 M de contexto (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "O melhor custo-benefício",
"pricing.aiModels.premium.title": "Tradução IA Premium",
"pricing.aiModels.premium.plan": "Plano Business",
"pricing.aiModels.premium.descPrefix": "Baseado em",
"pricing.aiModels.premium.descSuffix": "da Anthropic — preciso em documentos jurídicos, médicos e técnicos complexos.",
"pricing.aiModels.premium.context": "200K tokens de contexto",
"pricing.aiModels.premium.context": "1M de contexto",
"pricing.aiModels.premium.precision": "Maior precisão",
"pricing.faq.title": "Perguntas frequentes",
"pricing.faq.q1": "Posso trocar de plano a qualquer momento?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "O que é a «Tradução IA Essencial»?",
"pricing.faq.a2": "É nosso motor de IA. Ele compreende o contexto dos seus documentos, preserva a formatação e lida com termos técnicos muito melhor do que a tradução clássica.",
"pricing.faq.q3": "Qual a diferença entre IA Essencial e IA Premium?",
"pricing.faq.a3": "A IA Essencial usa um modelo otimizado (excelente custo-benefício). A IA Premium usa Claude 3.5 Haiku da Anthropic, mais precisa em documentos jurídicos, médicos e técnicos complexos.",
"pricing.faq.a3": "A IA Essencial usa DeepSeek V4 Flash, GLM-5.3 Flash e MiniMax M3 (excelente custo-benefício). A IA Premium usa Claude 5 da Anthropic, mais precisa em documentos jurídicos, médicos e técnicos complexos.",
"pricing.faq.q4": "Meus documentos são mantidos após a tradução?",
"pricing.faq.a4": "Os arquivos traduzidos ficam disponíveis de acordo com seu plano (30 dias Starter, 90 dias Pro, 1 ano Business). São criptografados em repouso e em trânsito.",
"pricing.faq.q5": "O que acontece se eu exceder minha cota mensal?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "Erro ao criar o pagamento.",
"pricing.dashboard": "Painel",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "A partir de 0,09 US$ por milhão de tokens",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "Alternativas: DeepSeek V4 Pro e GLM-5.3",
"pricing.confirm.title": "Confirme a sua assinatura",
"pricing.confirm.subtitle": "Você será redirecionado ao nosso provedor de pagamento seguro.",
"pricing.confirm.cancel": "Cancelar",
"pricing.confirm.cta": "Continuar para o pagamento",
"pricing.confirm.year": "ano",
"pricing.confirm.month": "mês",
"pricing.confirm.monthlyEquivalent": "Faturação anual — ou seja, {price} € / mês.",
"pricing.confirm.secureNote": "Cancelável a qualquer momento no seu perfil. O pagamento é processado pelo Stripe; os dados do seu cartão nunca passam pelos nossos servidores.",
"pricing.enterprise.subject": "Pedido Enterprise",
"pricing.enterpriseBand.cta": "Fale conosco",
"pricing.enterpriseBand.text": "Volume, motores dedicados, opções on-premise — vamos conversar.",
"pricing.error.server": "Erro do servidor {status}",
"pricing.freeBand.cta": "Comece grátis",
"pricing.freeBand.text": "Só quer experimentar? Comece grátis — 5 documentos por mês, sem cartão.",
"pricing.header.titleBase": "Um plano para",
"pricing.header.titleAccent": "cada necessidade",
"pricing.toast.close": "Fechar",
"pricing.aiModels.premium.price": "2 US$ / 10 US$ por 1M de tokens"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "Acesso unificado aos melhores modelos open-source otimizados para tradução.",
"providerTheme.openrouter_premium.badge": "Ultra",
"providerTheme.openrouter_premium.subBadge": "Contexto máximo",
"providerTheme.openrouter_premium.desc": "Assistido pelos modelos mais avançados (GPT-4o, Claude Sonnet 4.6) para documentos longos.",
"providerTheme.openrouter_premium.desc": "Assistido pelos modelos mais avançados (GPT-4o, Claude 5) para documentos longos.",
"providerTheme.zai.badge": "Especializada",
"providerTheme.zai.subBadge": "Finanças e Direito",
"providerTheme.zai.desc": "Modelo afinado para terminologias empresariais exigentes (jurídico, financeiro).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "Провайдеры",
"admin.nav.system": "Система",
"admin.nav.logs": "Журналы",
"admin.nav.stats": "Статистика",
"admin.users.title": "Управление пользователями",
"admin.users.subtitle": "Просмотр и управление учётными записями",
"admin.users.planUpdated": "План обновлён",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "Ожидание данных...",
"admin.system.purging": "Очистка...",
"admin.system.clean": "Очистить",
"admin.system.purge": "Очистить"
"admin.system.purge": "Очистить",
"admin.nav.models": "Модели и подписки",
"admin.nav.marketing": "Маркетинг",
"admin.marketing.audience": "Аудитория",
"admin.marketing.audienceAllUsers": "Все аккаунты",
"admin.marketing.audienceInactive": "Аккаунты без активности 30 дней",
"admin.marketing.audiencePlaceholder": "Выберите аудиторию",
"admin.marketing.audiencePlanBusiness": "Тариф Business",
"admin.marketing.audiencePlanEnterprise": "Тариф Enterprise",
"admin.marketing.audiencePlanFree": "Бесплатный тариф",
"admin.marketing.audiencePlanPro": "Тариф Pro",
"admin.marketing.audiencePlanStarter": "Тариф Starter",
"admin.marketing.audienceWaitlist": "Лист ожидания",
"admin.marketing.badgeReal": "реальная",
"admin.marketing.badgeTest": "тест",
"admin.marketing.confirmSend": "Отправить это письмо {count} получателю(ям) («{audience}»)?",
"admin.marketing.footerNote": "При отправке автоматически добавляется подвал со ссылкой отписки.",
"admin.marketing.hidePreview": "Скрыть предпросмотр",
"admin.marketing.history": "История рассылок",
"admin.marketing.historyFailedSuffix": ", {count} сбоев",
"admin.marketing.historySent": "{sent}/{total} отправлено",
"admin.marketing.html": "HTML-содержимое",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "Заполните тему и HTML.",
"admin.marketing.incompleteTitle": "Содержимое неполное",
"admin.marketing.loadErrorTitle": "Ошибка загрузки",
"admin.marketing.localCheckUnavailable": "Локальная проверка в этом браузере недоступна: сервер проверит предварительную тестовую отправку.",
"admin.marketing.networkDesc": "Не удаётся связаться с сервером.",
"admin.marketing.newCampaign": "Новая рассылка",
"admin.marketing.noHistory": "Рассылок не зарегистрировано.",
"admin.marketing.preview": "Предпросмотр",
"admin.marketing.previewEmpty": "Предпросмотр: вставьте HTML рядом с этой панелью.",
"admin.marketing.previewTitle": "Предпросмотр письма",
"admin.marketing.recipientsAvailable": "{count} получателей доступно после исключения отписавшихся.",
"admin.marketing.sendReal": "Отправить {count} получателю(ям)",
"admin.marketing.sendRefusedTitle": "Рассылка отклонена",
"admin.marketing.sendTest": "Тестовая отправка",
"admin.marketing.sendingDesc": "{count} письмо(ем) в очереди отправки (интервал 0,2 с). Отписавшиеся исключаются.",
"admin.marketing.sendingTitle": "Идёт рассылка",
"admin.marketing.subject": "Тема",
"admin.marketing.subjectPlaceholder": "Напр.: Ваш перевод готов — скидка 20% на 7 дней",
"admin.marketing.subtitle": "Рассылка писем по аудитории с обязательной тестовой отправкой, автоматической ссылкой отписки и полной историей.",
"admin.marketing.testDoneDesc": "Письмо получено на {email}",
"admin.marketing.testDoneTitle": "Тестовая отправка выполнена",
"admin.marketing.testEmail": "Тестовый email (необязательно)",
"admin.marketing.testEmailPlaceholder": "Иначе: SMTP-адрес отправителя",
"admin.marketing.testFailedTitle": "Тестовая отправка не удалась",
"admin.marketing.testRequiredHint": "Реальной рассылке предшествует тестовая отправка точно такого же содержимого (проверяется сервером).",
"admin.marketing.testValidated": "Тестовая отправка этого содержимого подтверждена.",
"admin.marketing.title": "Маркетинг — email-рассылки",
"admin.marketing.unsubscribedNote": "{count} отписавшихся будут исключены из любой рассылки.",
"admin.models.addModel": "Добавить модель",
"admin.models.businessBadge": "Тариф Business",
"admin.models.cancel": "Отмена",
"admin.models.catalog": "Каталог OpenRouter",
"admin.models.catalogErrorDesc": "Не удалось загрузить каталог OpenRouter.",
"admin.models.catalogErrorTitle": "Каталог недоступен",
"admin.models.customBadge": "Индивидуальный уровень",
"admin.models.customNote": "Специальные модели, согласовываются с клиентом индивидуально.",
"admin.models.defaultBadge": "по умолчанию",
"admin.models.emptyTier": "Нет моделей: будет использован официальный набор тарифа.",
"admin.models.enterpriseBadge": "Тариф Enterprise",
"admin.models.essentialBadge": "Уровень ИИ «Базовый»",
"admin.models.essentialCost": "— с коэффициентом стоимости 1",
"admin.models.fallbackFirst": "(запасная № 1)",
"admin.models.loadErrorDesc": "HTTP {status} — проверьте токен администратора.",
"admin.models.loadErrorTitle": "Ошибка загрузки",
"admin.models.matrixDesc": "Активные модели по уровням — порядок в списке задаёт приоритет запасного варианта. Радиокнопка выбирает модель по умолчанию, применяемую сразу, без повторного развёртывания.",
"admin.models.matrixTitle": "Матрица моделей по тарифам",
"admin.models.missingConfig": "Конфигурация уровней ИИ не найдена. Перезагрузите страницу.",
"admin.models.moveDown": "Вниз",
"admin.models.moveUp": "Вверх",
"admin.models.networkDesc": "Не удаётся связаться с сервером.",
"admin.models.networkTitle": "Сетевая ошибка",
"admin.models.premiumBadge": "Уровень ИИ «Премиум»",
"admin.models.premiumCost": "— с коэффициентом стоимости 5",
"admin.models.premiumReservedNote": "Только для тарифов Business и Enterprise (движок «openrouter_premium»).",
"admin.models.proBadge": "Тариф Pro",
"admin.models.remove": "Убрать",
"admin.models.save": "Сохранить",
"admin.models.saveErrorTitle": "Ошибка сохранения",
"admin.models.saveNetworkDesc": "Не удалось сохранить конфигурацию.",
"admin.models.savedDesc": "Новая модель по умолчанию применяется уже со следующего перевода, без повторного развёртывания.",
"admin.models.savedTitle": "Модели сохранены",
"admin.models.saving": "Сохранение...",
"admin.models.setDefault": "Назначить {model} моделью по умолчанию",
"admin.models.sharedTierNote": "Общий уровень: тариф Business также использует «Базовый» для движка «openrouter» — приведённый выше список относится к обоим тарифам.",
"admin.models.subtitle": "Матрица тарифы → уровни ИИ. Модель, реально используемая при переводе, — это модель уровня тарифа: тариф Pro никогда не задействует модель Premium.",
"admin.models.title": "Модели и подписки",
"admin.stats.aiTiers": "Уровни ИИ (30 дн.)",
"admin.stats.includingCredits": "в том числе {amount} кредитами",
"admin.stats.mrr": "Оценочный MRR",
"admin.stats.noTranslationsYet": "За последние 30 дней переводов в базе нет: распределение по уровням заполнится следующими переводами.",
"admin.stats.payments30": "{count} платёж(ей) за 30 дней",
"admin.stats.refreshing": "Обновление...",
"admin.stats.revenue30": "Выручка (30 дней)",
"admin.stats.revenueTotal": "Всего получено выручки",
"admin.stats.tiersSub": "Базовый / Премиум · классика {classic} · прочее {other}",
"admin.stats.unavailable": "Бизнес-статистика недоступна ({error}).",
"admin.stats.waitlist": "Лист ожидания",
"admin.stats.waitlistSub": "записей в листе ожидания"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "Для требовательных профессионалов",
"landing.pricing.pro.f1": "200 документов / мес.",
"landing.pricing.pro.f2": "До 200 страниц на документ",
"landing.pricing.pro.f3": "Перевод на базе ИИ",
"landing.pricing.pro.f3": "Базовый ИИ: DeepSeek V4 Flash, GLM-5.3 Flash, MiniMax M3",
"landing.pricing.pro.f4": "Google включены",
"landing.pricing.pro.f5": "Пользовательские глоссарии и промпты",
"landing.pricing.pro.f6": "Приоритетная поддержка",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "Для команд с большими объёмами",
"landing.pricing.business.f1": "1 000 документов / мес.",
"landing.pricing.business.f2": "До 500 страниц на документ",
"landing.pricing.business.f3": "Премиум ИИ (Claude)",
"landing.pricing.business.f3": "Премиум ИИ (Claude 5)",
"landing.pricing.business.f4": "Все провайдеры + API",
"landing.pricing.business.f5": "Вебхуки и автоматизация",
"landing.pricing.business.f6": "5 рабочих мест",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "Поддерживаются файлы DOCX, XLSX, PPTX или PDF",
"landing.translate.aiAnalysis": "Активный ИИ-анализ",
"landing.translate.processing": "Обработка",
"landing.translate.preservingLayout": "Ваше форматирование сохраняется"
"landing.translate.preservingLayout": "Ваше форматирование сохраняется",
"landing.beforeAfter.seal": "Тот же макет, слово в слово",
"landing.beforeAfter.proof1": "Диаграммы SmartArt воссоздаются, а не сплющиваются",
"landing.beforeAfter.proof2": "Ряды и оси диаграмм переведены",
"landing.beforeAfter.proof3": "Оглавления заново формируются на целевом языке",
"landing.beforeAfter.targetTitle": "Техническая спецификация — Обработка воздуха",
"landing.beforeAfter.targetPara1": "Система вентиляции должна быть введена в эксплуатацию до конца второго квартала.",
"landing.beforeAfter.targetPara2Before": "",
"landing.beforeAfter.targetTerm": "Приточно-вытяжная установка",
"landing.beforeAfter.targetPara2After": "должна соответствовать классу фильтрации F7 согласно графику.",
"landing.beforeAfter.targetItem1": "Тепловая нагрузка: 42 кВт при номинальном расходе",
"landing.beforeAfter.targetItem2": "Уровень шума ниже 45 dB(A) на расстоянии 3 м",
"landing.formats.pill": "СОВМЕСТИМОСТЬ",
"landing.hero.visualCaption": "Тот же макет, новый язык — больше ничего не меняется",
"landing.pricing.free.name": "Бесплатно",
"landing.pricing.free.desc": "Идеально, чтобы попробовать приложение",
"landing.pricing.free.cta": "Выбрать этот план",
"landing.pricing.enterprise.name": "Enterprise",
"landing.pricing.enterprise.desc": "Индивидуальные решения для крупных организаций",
"landing.pricing.enterprise.cta": "Связаться с нами",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "История за 90 дней",
"pricing.plans.business.feat1": "1 000 документов / месяц",
"pricing.plans.business.feat2": "До 500 страниц на документ",
"pricing.plans.business.feat3": "Базовый + Премиум ИИ (Claude Haiku)",
"pricing.plans.business.feat3": "Базовый + Премиум ИИ (Claude 5)",
"pricing.plans.business.feat4": "Все провайдеры перевода",
"pricing.plans.business.feat5": "Файлы до 50 МБ",
"pricing.plans.business.feat6": "Доступ к API (10 000 вызовов/мес.)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "История за 1 год",
"pricing.plans.business.feat10": "Расширенная аналитика",
"pricing.plans.enterprise.feat1": "Безлимитные документы",
"pricing.plans.enterprise.feat2": "Все ИИ-модели (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "Все ИИ-модели (Claude 5, DeepSeek V4 Pro, GLM-5.3…)",
"pricing.plans.enterprise.feat3": "Локальное развёртывание или выделенное облако",
"pricing.plans.enterprise.feat4": "SLA 99,9 % гарантировано",
"pricing.plans.enterprise.feat5": "Выделенная поддержка 24/7",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "Сверхбыстрая многопоточная ИИ",
"pricing.trust.availability.title": "Доступно 24/7",
"pricing.trust.availability.sub": "99,9 % гарантированный аптайм",
"pricing.aiModels.title": "Наши ИИ-модели — март 2026",
"pricing.aiModels.title": "Наши ИИ-модели — сентябрь 2026",
"pricing.aiModels.essential.title": "Базовый ИИ-перевод",
"pricing.aiModels.essential.plan": "Тариф Pro",
"pricing.aiModels.essential.descPrefix": "На базе",
"pricing.aiModels.essential.descSuffix": "— самой экономичной ИИ-модели 2026 года. Качество на уровне frontier-моделей при стоимости в десятки раз ниже.",
"pricing.aiModels.essential.modelName": "наша базовая ИИ-модель",
"pricing.aiModels.essential.context": "163K токенов контекста",
"pricing.aiModels.essential.value": "Отличное соотношение цены и качества",
"pricing.aiModels.essential.descSuffix": "— самые экономичные ИИ-модели 2026 года.",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash, GLM-5.3 Flash и MiniMax M3",
"pricing.aiModels.essential.context": "Контекст до 1,3 млн токенов (GLM-5.3 Flash)",
"pricing.aiModels.essential.value": "Лучшее соотношение цены и качества",
"pricing.aiModels.premium.title": "Премиум ИИ-перевод",
"pricing.aiModels.premium.plan": "Тариф Business",
"pricing.aiModels.premium.descPrefix": "На базе",
"pricing.aiModels.premium.descSuffix": "от Anthropic — высокая точность на юридических, медицинских и сложных технических документах.",
"pricing.aiModels.premium.context": "200K токенов контекста",
"pricing.aiModels.premium.context": "1 млн токенов контекста",
"pricing.aiModels.premium.precision": "Наивысшая точность",
"pricing.faq.title": "Часто задаваемые вопросы",
"pricing.faq.q1": "Могу ли я сменить тариф в любое время?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "Что такое «Базовый ИИ-перевод»?",
"pricing.faq.a2": "Это наш ИИ-движок. Он понимает контекст ваших документов, сохраняет вёрстку и обрабатывает технические термины намного лучше классического перевода.",
"pricing.faq.q3": "В чём разница между базовым и премиум ИИ-переводом?",
"pricing.faq.a3": "Базовый ИИ использует оптимизированную модель (отличное соотношение цены и качества). Премиум ИИ использует Claude 3.5 Haiku от Anthropic, более точный на юридических, медицинских и сложных технических документах.",
"pricing.faq.a3": "Базовый ИИ работает на моделях DeepSeek V4 Flash, GLM-5.3 Flash и MiniMax M3 (отличное соотношение цены и качества). Премиум ИИ использует Claude 5 от Anthropic, более точный на юридических, медицинских и сложных технических документах.",
"pricing.faq.q4": "Сохраняются ли мои документы после перевода?",
"pricing.faq.a4": "Переведённые файлы доступны в зависимости от тарифа (30 дней Starter, 90 дней Pro, 1 год Business). Они зашифрованы при хранении и передаче.",
"pricing.faq.q5": "Что произойдёт при превышении месячной квоты?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "Ошибка при создании платежа.",
"pricing.dashboard": "Панель",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "От $0,09 за 1 млн токенов",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "Альтернативы: DeepSeek V4 Pro и GLM-5.3",
"pricing.confirm.title": "Подтвердите подписку",
"pricing.confirm.subtitle": "Вы будете перенаправлены к нашему безопасному платёжному провайдеру.",
"pricing.confirm.cancel": "Отмена",
"pricing.confirm.cta": "Перейти к оплате",
"pricing.confirm.year": "год",
"pricing.confirm.month": "месяц",
"pricing.confirm.monthlyEquivalent": "Годовая оплата — то есть {price} € / месяц.",
"pricing.confirm.secureNote": "Отмена в любой момент из профиля. Платёж обрабатывает Stripe; данные вашей карты никогда не попадают на наши серверы.",
"pricing.enterprise.subject": "Запрос по тарифу Enterprise",
"pricing.enterpriseBand.cta": "Связаться с нами",
"pricing.enterpriseBand.text": "Объёмы, выделенные движки, локальное размещение — давайте обсудим.",
"pricing.error.server": "Ошибка сервера {status}",
"pricing.freeBand.cta": "Начать бесплатно",
"pricing.freeBand.text": "Хотите просто попробовать? Начните бесплатно — 5 документов в месяц, без карты.",
"pricing.header.titleBase": "Тариф для",
"pricing.header.titleAccent": "каждой задачи",
"pricing.toast.close": "Закрыть",
"pricing.aiModels.premium.price": "$2 / $10 за 1 млн токенов"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "Единый доступ к лучшим open-source моделям, оптимизированным для перевода.",
"providerTheme.openrouter_premium.badge": "Ультра",
"providerTheme.openrouter_premium.subBadge": "Максимальный контекст",
"providerTheme.openrouter_premium.desc": "С помощью современных моделей (GPT-4o, Claude Sonnet 4.6) для длинных документов.",
"providerTheme.openrouter_premium.desc": "С помощью современных моделей (GPT-4o, Claude 5) для длинных документов.",
"providerTheme.zai.badge": "Специализированный",
"providerTheme.zai.subBadge": "Финансы и право",
"providerTheme.zai.desc": "Модель точно настроена для требовательных бизнес-терминологий (юриспруденция, финансы).",

View File

@@ -20,6 +20,7 @@
"admin.nav.providers": "服务商",
"admin.nav.system": "系统",
"admin.nav.logs": "日志",
"admin.nav.stats": "统计",
"admin.users.title": "用户管理",
"admin.users.subtitle": "查看和管理用户账户",
"admin.users.planUpdated": "套餐已更新",
@@ -44,5 +45,105 @@
"admin.system.waitingData": "等待数据...",
"admin.system.purging": "清理中...",
"admin.system.clean": "清理",
"admin.system.purge": "清除"
"admin.system.purge": "清除",
"admin.nav.models": "模型与订阅",
"admin.nav.marketing": "市场营销",
"admin.marketing.audience": "目标人群",
"admin.marketing.audienceAllUsers": "全部账户",
"admin.marketing.audienceInactive": "30 天未活动的账户",
"admin.marketing.audiencePlaceholder": "选择目标人群",
"admin.marketing.audiencePlanBusiness": "Business 套餐",
"admin.marketing.audiencePlanEnterprise": "Enterprise 套餐",
"admin.marketing.audiencePlanFree": "免费套餐",
"admin.marketing.audiencePlanPro": "Pro 套餐",
"admin.marketing.audiencePlanStarter": "Starter 套餐",
"admin.marketing.audienceWaitlist": "等候名单",
"admin.marketing.badgeReal": "正式",
"admin.marketing.badgeTest": "测试",
"admin.marketing.confirmSend": "将此邮件发送给 {count} 位收件人(「{audience}」)?",
"admin.marketing.footerNote": "发送时会自动添加包含退订链接的页脚。",
"admin.marketing.hidePreview": "隐藏预览",
"admin.marketing.history": "发送历史",
"admin.marketing.historyFailedSuffix": "{count} 封失败",
"admin.marketing.historySent": "已发送 {sent}/{total}",
"admin.marketing.html": "HTML 内容",
"admin.marketing.htmlPlaceholder": "<html><body>…</body></html>",
"admin.marketing.incompleteDesc": "请填写主题和 HTML。",
"admin.marketing.incompleteTitle": "内容不完整",
"admin.marketing.loadErrorTitle": "加载错误",
"admin.marketing.localCheckUnavailable": "此浏览器不支持本地校验:服务器将检查事先的测试发送。",
"admin.marketing.networkDesc": "无法连接后端。",
"admin.marketing.newCampaign": "新营销活动",
"admin.marketing.noHistory": "暂无发送记录。",
"admin.marketing.preview": "预览",
"admin.marketing.previewEmpty": "预览:请在旁边粘贴您的 HTML。",
"admin.marketing.previewTitle": "邮件预览",
"admin.marketing.recipientsAvailable": "排除退订用户后,共有 {count} 位收件人。",
"admin.marketing.sendReal": "发送给 {count} 位收件人",
"admin.marketing.sendRefusedTitle": "发送被拒绝",
"admin.marketing.sendTest": "测试发送",
"admin.marketing.sendingDesc": "{count} 封邮件进入发送队列(间隔 0.2 秒)。退订用户已被排除。",
"admin.marketing.sendingTitle": "发送进行中",
"admin.marketing.subject": "主题",
"admin.marketing.subjectPlaceholder": "例如:您的翻译已完成 — 7 天内 8 折",
"admin.marketing.subtitle": "向目标人群发送邮件,必须先测试发送,自动附加退订链接,并保留完整历史。",
"admin.marketing.testDoneDesc": "邮件已送达 {email}",
"admin.marketing.testDoneTitle": "测试发送完成",
"admin.marketing.testEmail": "测试邮箱(可选)",
"admin.marketing.testEmailPlaceholder": "否则使用 SMTP 发件地址",
"admin.marketing.testFailedTitle": "测试发送失败",
"admin.marketing.testRequiredHint": "正式发送要求先对完全相同的内容进行测试发送(由服务器校验)。",
"admin.marketing.testValidated": "此内容的测试发送已通过。",
"admin.marketing.title": "营销 — 邮件营销",
"admin.marketing.unsubscribedNote": "{count} 位退订用户将被排除在所有发送之外。",
"admin.models.addModel": "添加模型",
"admin.models.businessBadge": "Business 套餐",
"admin.models.cancel": "取消",
"admin.models.catalog": "OpenRouter 目录",
"admin.models.catalogErrorDesc": "无法加载 OpenRouter 目录。",
"admin.models.catalogErrorTitle": "目录不可用",
"admin.models.customBadge": "定制层级",
"admin.models.customNote": "定制模型,与客户逐案商定。",
"admin.models.defaultBadge": "默认",
"admin.models.emptyTier": "暂无模型:将使用套餐的官方模型阵容。",
"admin.models.enterpriseBadge": "Enterprise 套餐",
"admin.models.essentialBadge": "基础 AI 层级",
"admin.models.essentialCost": "— 按成本系数 1 计费",
"admin.models.fallbackFirst": "(首选备用)",
"admin.models.loadErrorDesc": "HTTP {status} — 请检查管理员令牌。",
"admin.models.loadErrorTitle": "加载错误",
"admin.models.matrixDesc": "每个层级的有效模型 — 列表顺序即备用优先级。单选按钮选择默认模型,立即生效,无需重新部署。",
"admin.models.matrixTitle": "按套餐划分的模型矩阵",
"admin.models.missingConfig": "未找到 AI 层级配置。请刷新页面。",
"admin.models.moveDown": "下移",
"admin.models.moveUp": "上移",
"admin.models.networkDesc": "无法连接后端。",
"admin.models.networkTitle": "网络错误",
"admin.models.premiumBadge": "高级 AI 层级",
"admin.models.premiumCost": "— 按成本系数 5 计费",
"admin.models.premiumReservedNote": "仅限 Business 和 Enterprise 套餐「openrouter_premium」引擎。",
"admin.models.proBadge": "Pro 套餐",
"admin.models.remove": "移除",
"admin.models.save": "保存",
"admin.models.saveErrorTitle": "保存错误",
"admin.models.saveNetworkDesc": "无法保存配置。",
"admin.models.savedDesc": "新的默认模型从下一次翻译起生效,无需重新部署。",
"admin.models.savedTitle": "模型已保存",
"admin.models.saving": "保存中...",
"admin.models.setDefault": "将 {model} 设为默认模型",
"admin.models.sharedTierNote": "共享层级Business 套餐的「openrouter」引擎同样使用基础层级 — 上面的列表对两个套餐都适用。",
"admin.models.subtitle": "套餐 → AI 层级矩阵。每次翻译实际使用的模型是套餐所属层级的模型Pro 套餐绝不会触发 Premium 模型。",
"admin.models.title": "模型与订阅",
"admin.stats.aiTiers": "AI 层级30 天)",
"admin.stats.includingCredits": "其中 {amount} 为积分",
"admin.stats.mrr": "预估 MRR",
"admin.stats.noTranslationsYet": "最近 30 天数据库中没有翻译记录:层级分布将随后续翻译逐步填充。",
"admin.stats.payments30": "30 天内 {count} 笔付款",
"admin.stats.refreshing": "刷新中...",
"admin.stats.revenue30": "收入30 天)",
"admin.stats.revenueTotal": "累计已收收入",
"admin.stats.tiersSub": "基础 / 高级 · 经典 {classic} · 其他 {other}",
"admin.stats.unavailable": "业务统计不可用({error})。",
"admin.stats.waitlist": "等候名单",
"admin.stats.waitlistSub": "位用户等候中"
}

View File

@@ -100,7 +100,7 @@
"landing.pricing.pro.desc": "适合专业用户",
"landing.pricing.pro.f1": "每月200份文档",
"landing.pricing.pro.f2": "每份文档最多200页",
"landing.pricing.pro.f3": "AI翻译",
"landing.pricing.pro.f3": "基础 AIDeepSeek V4 Flash、GLM-5.3 Flash、MiniMax M3",
"landing.pricing.pro.f4": "包含Google",
"landing.pricing.pro.f5": "自定义术语表和提示词",
"landing.pricing.pro.f6": "优先支持",
@@ -109,7 +109,7 @@
"landing.pricing.business.desc": "适合大批量需求的团队",
"landing.pricing.business.f1": "每月1,000份文档",
"landing.pricing.business.f2": "每份文档最多500页",
"landing.pricing.business.f3": "高级AIClaude",
"landing.pricing.business.f3": "高级AIClaude 5",
"landing.pricing.business.f4": "所有供应商 + API",
"landing.pricing.business.f5": "Webhook和自动化",
"landing.pricing.business.f6": "5个团队席位",
@@ -142,5 +142,31 @@
"landing.translate.supportedFormats": "支持 DOCX, XLSX, PPTX 或 PDF 文件",
"landing.translate.aiAnalysis": "AI 分析中",
"landing.translate.processing": "正在处理",
"landing.translate.preservingLayout": "正在保留您的排版"
"landing.translate.preservingLayout": "正在保留您的排版",
"landing.beforeAfter.seal": "相同的排版,逐字对应",
"landing.beforeAfter.proof1": "SmartArt 图形会重新构建,而不是被压平",
"landing.beforeAfter.proof2": "图表系列与坐标轴一并翻译",
"landing.beforeAfter.proof3": "目录按目标语言重新生成",
"landing.beforeAfter.targetTitle": "技术规格 — 空气处理",
"landing.beforeAfter.targetPara1": "通风系统必须在第二季度结束前调试运行。",
"landing.beforeAfter.targetPara2Before": "",
"landing.beforeAfter.targetTerm": "空气处理机组",
"landing.beforeAfter.targetPara2After": "必须按照计划达到 F7 过滤等级。",
"landing.beforeAfter.targetItem1": "热负荷:额定流量下 42 kW",
"landing.beforeAfter.targetItem2": "3 米处噪音低于 45 dB(A)",
"landing.formats.pill": "兼容性",
"landing.hero.visualCaption": "相同的排版,新的语言 — 其余一切保持不变",
"landing.pricing.free.name": "免费",
"landing.pricing.free.desc": "适合初次体验应用",
"landing.pricing.free.cta": "选择此套餐",
"landing.pricing.enterprise.name": "企业版",
"landing.pricing.enterprise.desc": "面向大型组织的定制解决方案",
"landing.pricing.enterprise.cta": "联系我们",
"landing.beforeAfter.sourceTitle": "Cahier des charges — Traitement d'air",
"landing.beforeAfter.sourcePara1": "L'installation de ventilation doit être mise en service avant la fin du deuxième trimestre.",
"landing.beforeAfter.sourcePara2Before": "Le",
"landing.beforeAfter.sourceTerm": "groupe de traitement d'air",
"landing.beforeAfter.sourcePara2After": "doit respecter la classe de filtration F7 conformément au planning.",
"landing.beforeAfter.sourceItem1": "Charge thermique : 42 kW au débit nominal",
"landing.beforeAfter.sourceItem2": "Niveau sonore inférieur à 45 dB(A) à 3 m"
}

View File

@@ -41,7 +41,7 @@
"pricing.plans.pro.feat8": "90 天历史记录",
"pricing.plans.business.feat1": "每月 1,000 份文档",
"pricing.plans.business.feat2": "每份文档最多 500 页",
"pricing.plans.business.feat3": "基础 + 高级 AIClaude Haiku",
"pricing.plans.business.feat3": "基础 + 高级 AIClaude 5",
"pricing.plans.business.feat4": "所有翻译服务商",
"pricing.plans.business.feat5": "文件最大 50 MB",
"pricing.plans.business.feat6": "API 访问(每月 10,000 次调用)",
@@ -50,7 +50,7 @@
"pricing.plans.business.feat9": "1 年历史记录",
"pricing.plans.business.feat10": "高级分析",
"pricing.plans.enterprise.feat1": "无限文档",
"pricing.plans.enterprise.feat2": "所有 AI 模型(GPT-5、Claude Opus 4.6…)",
"pricing.plans.enterprise.feat2": "所有 AI 模型Claude 5、DeepSeek V4 Pro、GLM-5.3…)",
"pricing.plans.enterprise.feat3": "本地部署或专属云",
"pricing.plans.enterprise.feat4": "99.9% SLA 保障",
"pricing.plans.enterprise.feat5": "24/7 专属支持",
@@ -108,19 +108,19 @@
"pricing.trust.parallel.sub": "超快多线程 AI",
"pricing.trust.availability.title": "7×24 小时可用",
"pricing.trust.availability.sub": "99.9% 可用性保障",
"pricing.aiModels.title": "我们的 AI 模型 — 2026年3月",
"pricing.aiModels.title": "我们的 AI 模型 — 2026年9月",
"pricing.aiModels.essential.title": "基础 AI 翻译",
"pricing.aiModels.essential.plan": "专业版方案",
"pricing.aiModels.essential.descPrefix": "基于",
"pricing.aiModels.essential.descSuffix": "— 2026 年最具性价比的 AI 模型。质量媲美前沿模型,成本仅为其一小部分。",
"pricing.aiModels.essential.modelName": "Essential AI模型",
"pricing.aiModels.essential.context": "163K 上下文 Token",
"pricing.aiModels.essential.value": "性价比极佳",
"pricing.aiModels.essential.descSuffix": "— 2026 年最具性价比的 AI 模型。",
"pricing.aiModels.essential.modelName": "DeepSeek V4 Flash、GLM-5.3 Flash 和 MiniMax M3",
"pricing.aiModels.essential.context": "上下文最多 130 万 TokenGLM-5.3 Flash",
"pricing.aiModels.essential.value": "极致性价比",
"pricing.aiModels.premium.title": "高级 AI 翻译",
"pricing.aiModels.premium.plan": "企业版方案",
"pricing.aiModels.premium.descPrefix": "基于",
"pricing.aiModels.premium.descSuffix": "Anthropic 出品 — 在法律、医疗和复杂技术文档方面表现精准。",
"pricing.aiModels.premium.context": "200K 上下文 Token",
"pricing.aiModels.premium.context": "100 上下文 Token",
"pricing.aiModels.premium.precision": "最高精度",
"pricing.faq.title": "常见问题",
"pricing.faq.q1": "我可以随时更换方案吗?",
@@ -128,7 +128,7 @@
"pricing.faq.q2": "什么是「基础 AI 翻译」?",
"pricing.faq.a2": "这是我们的AI引擎。它能理解文档上下文保留排版并比传统翻译更好地处理技术术语。",
"pricing.faq.q3": "基础 AI 和高级 AI 有什么区别?",
"pricing.faq.a3": "Essential AI使用优化模型性价比极佳。Premium AI使用Anthropic的Claude 3.5 Haiku,在法律、医学和复杂技术文档上更准确。",
"pricing.faq.a3": "Essential AI使用DeepSeek V4 Flash、GLM-5.3 Flash和MiniMax M3性价比极佳。Premium AI使用Anthropic的Claude 5,在法律、医学和复杂技术文档上更准确。",
"pricing.faq.q4": "翻译后文档会被保留吗?",
"pricing.faq.a4": "翻译文件根据您的方案保留(入门版 30 天、专业版 90 天、企业版 1 年)。存储和传输过程中均已加密。",
"pricing.faq.q5": "超过月度配额会怎样?",
@@ -146,5 +146,26 @@
"pricing.toast.paymentError": "创建支付时出错。",
"pricing.dashboard": "仪表板",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
"pricing.errSymbol": "✕",
"pricing.aiModels.essential.price": "每百万 Token 低至 $0.09",
"pricing.aiModels.premium.modelName": "Claude 5",
"pricing.aiModels.premium.alternatives": "备选模型DeepSeek V4 Pro 和 GLM-5.3",
"pricing.confirm.title": "确认您的订阅",
"pricing.confirm.subtitle": "您将被重定向到我们的安全支付服务商。",
"pricing.confirm.cancel": "取消",
"pricing.confirm.cta": "继续付款",
"pricing.confirm.year": "年",
"pricing.confirm.month": "个月",
"pricing.confirm.monthlyEquivalent": "按年计费 — 相当于每月 {price} 欧元。",
"pricing.confirm.secureNote": "可随时在个人资料中取消。付款由 Stripe 处理;您的银行卡信息绝不会经过我们的服务器。",
"pricing.enterprise.subject": "企业版方案咨询",
"pricing.enterpriseBand.cta": "联系我们",
"pricing.enterpriseBand.text": "大批量、专属引擎、本地部署选项 — 欢迎洽谈。",
"pricing.error.server": "服务器错误 {status}",
"pricing.freeBand.cta": "免费开始",
"pricing.freeBand.text": "只想先试试?免费开始 — 每月 5 份文档,无需银行卡。",
"pricing.header.titleBase": "总有一款套餐适合",
"pricing.header.titleAccent": "您的需求",
"pricing.toast.close": "关闭",
"pricing.aiModels.premium.price": "每百万 Token $2 / $10"
}

View File

@@ -13,7 +13,7 @@
"providerTheme.openrouter.desc": "统一访问为翻译优化的最佳开源模型。",
"providerTheme.openrouter_premium.badge": "超级",
"providerTheme.openrouter_premium.subBadge": "最大上下文",
"providerTheme.openrouter_premium.desc": "由尖端模型(GPT-4o、Claude Sonnet 4.6)辅助,适用于长文档。",
"providerTheme.openrouter_premium.desc": "由尖端模型(GPT-4o、Claude 5)辅助,适用于长文档。",
"providerTheme.zai.badge": "专业",
"providerTheme.zai.subBadge": "金融与法律",
"providerTheme.zai.desc": "针对苛刻的业务术语(法律、金融)进行了微调的模型。",

View File

@@ -8,9 +8,12 @@ export const openaiModels = [
];
export const openrouterModels = [
{ id: "google/gemini-3.5-flash", name: "Gemini 3.5 Flash" },
{ id: "deepseek/deepseek-chat", name: "DeepSeek Chat" },
{ id: "anthropic/claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
{ id: "deepseek/deepseek-v4-flash", name: "DeepSeek V4 Flash" },
{ id: "z-ai/glm-5.3-flash", name: "GLM-5.3 Flash" },
{ id: "minimax/minimax-m3", name: "MiniMax M3" },
{ id: "anthropic/claude-sonnet-5", name: "Claude 5" },
{ id: "deepseek/deepseek-v4-pro", name: "DeepSeek V4 Pro" },
{ id: "z-ai/glm-5.3", name: "GLM-5.3" },
];
interface TranslationSettings {
@@ -101,7 +104,7 @@ const defaultSettings: TranslationSettings = {
openaiApiKey: "",
openaiModel: "gpt-4o-mini",
openrouterApiKey: "",
openrouterModel: "deepseek/deepseek-chat-v3-0324",
openrouterModel: "deepseek/deepseek-v4-flash",
libreTranslateUrl: "",
systemPrompt: "",
glossary: "",