Преглед изворни кода

fix(default): improve billing settings forms

CaIon пре 3 дана
родитељ
комит
dede1e2968

+ 3 - 3
web/default/src/features/profile/components/profile-settings-card.tsx

@@ -51,10 +51,10 @@ export function ProfileSettingsCard({
       icon={<Settings className='h-4 w-4' />}
     >
       <Tabs value={activeTab} onValueChange={setActiveTab}>
-        <TabsList className='grid h-auto w-full grid-cols-2 gap-1 rounded-xl p-1'>
+        <TabsList className='grid h-10 w-full grid-cols-2 items-stretch gap-1 rounded-xl p-1'>
           <TabsTrigger
             value='bindings'
-            className='h-auto gap-2 rounded-lg px-3 py-2'
+            className='h-full gap-2 rounded-lg px-3 py-0 leading-none'
           >
             <Link2 className='h-4 w-4' />
             <span className='hidden sm:inline'>{t('Account Bindings')}</span>
@@ -62,7 +62,7 @@ export function ProfileSettingsCard({
           </TabsTrigger>
           <TabsTrigger
             value='settings'
-            className='h-auto gap-2 rounded-lg px-3 py-2'
+            className='h-full gap-2 rounded-lg px-3 py-0 leading-none'
           >
             <Settings className='h-4 w-4' />
             <span className='hidden sm:inline'>

+ 7 - 3
web/default/src/features/system-settings/billing/section-registry.tsx

@@ -45,9 +45,13 @@ const BILLING_SECTIONS = [
           QuotaForInviter: settings.QuotaForInviter,
           QuotaForInvitee: settings.QuotaForInvitee,
           TopUpLink: settings.TopUpLink,
-          'general_setting.docs_link': settings['general_setting.docs_link'],
-          'quota_setting.enable_free_model_pre_consume':
-            settings['quota_setting.enable_free_model_pre_consume'],
+          general_setting: {
+            docs_link: settings['general_setting.docs_link'],
+          },
+          quota_setting: {
+            enable_free_model_pre_consume:
+              settings['quota_setting.enable_free_model_pre_consume'],
+          },
         }}
       />
     ),

+ 23 - 11
web/default/src/features/system-settings/general/quota-settings-section.tsx

@@ -1,4 +1,5 @@
 import * as z from 'zod'
+import type { ChangeEvent } from 'react'
 import type { Resolver } from 'react-hook-form'
 import { zodResolver } from '@hookform/resolvers/zod'
 import { useTranslation } from 'react-i18next'
@@ -25,9 +26,13 @@ const quotaSchema = z.object({
   PreConsumedQuota: z.coerce.number().min(0),
   QuotaForInviter: z.coerce.number().min(0),
   QuotaForInvitee: z.coerce.number().min(0),
-  TopUpLink: z.string().url().optional().or(z.literal('')),
-  'general_setting.docs_link': z.string().url().optional().or(z.literal('')),
-  'quota_setting.enable_free_model_pre_consume': z.boolean(),
+  TopUpLink: z.string(),
+  general_setting: z.object({
+    docs_link: z.string(),
+  }),
+  quota_setting: z.object({
+    enable_free_model_pre_consume: z.boolean(),
+  }),
 })
 
 type QuotaFormValues = z.infer<typeof quotaSchema>
@@ -41,6 +46,13 @@ export function QuotaSettingsSection({
 }: QuotaSettingsSectionProps) {
   const { t } = useTranslation()
   const updateOption = useUpdateOption()
+  const handleNumberChange =
+    (onChange: (value: number | string) => void) =>
+    (event: ChangeEvent<HTMLInputElement>) => {
+      onChange(
+        event.target.value === '' ? '' : event.currentTarget.valueAsNumber
+      )
+    }
 
   const { form, handleSubmit, isDirty, isSubmitting } =
     useSettingsForm<QuotaFormValues>({
@@ -79,8 +91,8 @@ export function QuotaSettingsSection({
                 <FormControl>
                   <Input
                     type='number'
-                    value={field.value as number}
-                    onChange={(e) => field.onChange(e.target.valueAsNumber)}
+                    value={field.value ?? ''}
+                    onChange={handleNumberChange(field.onChange)}
                     name={field.name}
                     onBlur={field.onBlur}
                     ref={field.ref}
@@ -103,8 +115,8 @@ export function QuotaSettingsSection({
                 <FormControl>
                   <Input
                     type='number'
-                    value={field.value as number}
-                    onChange={(e) => field.onChange(e.target.valueAsNumber)}
+                    value={field.value ?? ''}
+                    onChange={handleNumberChange(field.onChange)}
                     name={field.name}
                     onBlur={field.onBlur}
                     ref={field.ref}
@@ -127,8 +139,8 @@ export function QuotaSettingsSection({
                 <FormControl>
                   <Input
                     type='number'
-                    value={field.value as number}
-                    onChange={(e) => field.onChange(e.target.valueAsNumber)}
+                    value={field.value ?? ''}
+                    onChange={handleNumberChange(field.onChange)}
                     name={field.name}
                     onBlur={field.onBlur}
                     ref={field.ref}
@@ -151,8 +163,8 @@ export function QuotaSettingsSection({
                 <FormControl>
                   <Input
                     type='number'
-                    value={field.value as number}
-                    onChange={(e) => field.onChange(e.target.valueAsNumber)}
+                    value={field.value ?? ''}
+                    onChange={handleNumberChange(field.onChange)}
                     name={field.name}
                     onBlur={field.onBlur}
                     ref={field.ref}

+ 188 - 2
web/default/src/features/system-settings/models/group-ratio-form.tsx

@@ -1,8 +1,14 @@
 import { memo, useCallback, useState } from 'react'
 import { type UseFormReturn } from 'react-hook-form'
-import { Code2, Eye } from 'lucide-react'
+import { Code2, Eye, HelpCircle } from 'lucide-react'
 import { useTranslation } from 'react-i18next'
 import { Button } from '@/components/ui/button'
+import {
+  Accordion,
+  AccordionContent,
+  AccordionItem,
+  AccordionTrigger,
+} from '@/components/ui/accordion'
 import {
   Form,
   FormControl,
@@ -14,6 +20,13 @@ import {
 } from '@/components/ui/form'
 import { Switch } from '@/components/ui/switch'
 import { Textarea } from '@/components/ui/textarea'
+import {
+  Sheet,
+  SheetContent,
+  SheetDescription,
+  SheetHeader,
+  SheetTitle,
+} from '@/components/ui/sheet'
 import { GroupRatioVisualEditor } from './group-ratio-visual-editor'
 import { GroupSpecialUsableRulesEditor } from './group-special-usable-editor'
 
@@ -40,6 +53,7 @@ export const GroupRatioForm = memo(function GroupRatioForm({
 }: GroupRatioFormProps) {
   const { t } = useTranslation()
   const [editMode, setEditMode] = useState<'visual' | 'json'>('visual')
+  const [guideOpen, setGuideOpen] = useState(false)
 
   const handleFieldChange = useCallback(
     (field: keyof GroupFormValues, value: string) => {
@@ -57,7 +71,15 @@ export const GroupRatioForm = memo(function GroupRatioForm({
 
   return (
     <div className='space-y-6'>
-      <div className='flex justify-end'>
+      <div className='flex flex-wrap justify-end gap-2'>
+        <Button
+          variant='outline'
+          size='sm'
+          onClick={() => setGuideOpen(true)}
+        >
+          <HelpCircle className='mr-2 h-4 w-4' />
+          {t('Usage guide')}
+        </Button>
         <Button variant='outline' size='sm' onClick={toggleEditMode}>
           {editMode === 'visual' ? (
             <>
@@ -73,6 +95,8 @@ export const GroupRatioForm = memo(function GroupRatioForm({
         </Button>
       </div>
 
+      <GroupPricingGuide open={guideOpen} onOpenChange={setGuideOpen} />
+
       <Form {...form}>
         {editMode === 'visual' ? (
           <div className='space-y-6'>
@@ -276,3 +300,165 @@ export const GroupRatioForm = memo(function GroupRatioForm({
     </div>
   )
 })
+
+type GroupPricingGuideProps = {
+  open: boolean
+  onOpenChange: (open: boolean) => void
+}
+
+function GuideCodeBlock({ children }: { children: string }) {
+  return (
+    <pre className='bg-muted/60 overflow-x-auto rounded-lg border px-3 py-2 text-xs leading-6 whitespace-pre-wrap'>
+      {children}
+    </pre>
+  )
+}
+
+function GroupPricingGuide({ open, onOpenChange }: GroupPricingGuideProps) {
+  const { t } = useTranslation()
+
+  return (
+    <Sheet open={open} onOpenChange={onOpenChange}>
+      <SheetContent side='right' className='w-full gap-0 p-0 sm:max-w-2xl'>
+        <SheetHeader className='border-b p-4'>
+          <SheetTitle>{t('Group pricing usage guide')}</SheetTitle>
+          <SheetDescription>
+            {t(
+              'Understand how user groups, token groups, ratios, and special rules work together.'
+            )}
+          </SheetDescription>
+        </SheetHeader>
+
+        <div className='space-y-5 overflow-y-auto p-4'>
+          <section className='space-y-2'>
+            <h3 className='text-sm font-semibold'>{t('Core concepts')}</h3>
+            <div className='text-muted-foreground space-y-2 text-sm leading-6'>
+              <p>
+                <span className='text-foreground font-medium'>
+                  {t('User group')}
+                </span>
+                {': '}
+                {t(
+                  'Assigned by administrators and used to represent a user level, such as default or vip.'
+                )}
+              </p>
+              <p>
+                <span className='text-foreground font-medium'>
+                  {t('Token group')}
+                </span>
+                {': '}
+                {t(
+                  'Selected when creating a token and used as the default billing group for API calls.'
+                )}
+              </p>
+              <p>
+                <span className='text-foreground font-medium'>
+                  {t('Ratio')}
+                </span>
+                {': '}
+                {t(
+                  'A billing multiplier. Lower ratios mean lower API call costs.'
+                )}
+              </p>
+              <p>
+                <span className='text-foreground font-medium'>
+                  {t('User selectable')}
+                </span>
+                {': '}
+                {t(
+                  'When enabled, users can pick this group when creating tokens.'
+                )}
+              </p>
+            </div>
+          </section>
+
+          <Accordion className='rounded-lg border px-3'>
+            <AccordionItem value='groups'>
+              <AccordionTrigger>{t('Pricing group example')}</AccordionTrigger>
+              <AccordionContent className='space-y-3'>
+                <p className='text-muted-foreground text-sm leading-6'>
+                  {t(
+                    'Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.'
+                  )}
+                </p>
+                <GuideCodeBlock>
+                  {`${t('Group name')}   ${t('Ratio')}   ${t('User selectable')}   ${t('Description')}
+standard     1.0     ${t('Yes')}               ${t('Standard price')}
+premium      0.5     ${t('Yes')}               ${t('Premium plan, half price')}
+vip          0.5     ${t('No')}                ${t('Assigned by administrator only')}`}
+                </GuideCodeBlock>
+                <p className='text-muted-foreground text-sm leading-6'>
+                  {t(
+                    'Users only see groups marked as user selectable. Non-selectable groups can still be assigned by administrators.'
+                  )}
+                </p>
+              </AccordionContent>
+            </AccordionItem>
+
+            <AccordionItem value='auto'>
+              <AccordionTrigger>{t('Auto group behavior')}</AccordionTrigger>
+              <AccordionContent className='space-y-3'>
+                <p className='text-muted-foreground text-sm leading-6'>
+                  {t(
+                    'When a token uses the auto group, the system tries groups from top to bottom until it finds an available group.'
+                  )}
+                </p>
+                <GuideCodeBlock>{`["default", "vip"]`}</GuideCodeBlock>
+                <p className='text-muted-foreground text-sm leading-6'>
+                  {t(
+                    'If default auto group is enabled, newly created tokens start with auto instead of an empty group.'
+                  )}
+                </p>
+              </AccordionContent>
+            </AccordionItem>
+
+            <AccordionItem value='special-ratio'>
+              <AccordionTrigger>{t('Special ratio rules')}</AccordionTrigger>
+              <AccordionContent className='space-y-3'>
+                <p className='text-muted-foreground text-sm leading-6'>
+                  {t(
+                    'Special ratios override the token group ratio for specific user group and token group combinations.'
+                  )}
+                </p>
+                <GuideCodeBlock>{`{
+  "vip": {
+    "standard": 0.8,
+    "premium": 0.3
+  }
+}`}</GuideCodeBlock>
+                <p className='text-muted-foreground text-sm leading-6'>
+                  {t(
+                    'Only configured combinations are overridden. All other calls keep the token group base ratio.'
+                  )}
+                </p>
+              </AccordionContent>
+            </AccordionItem>
+
+            <AccordionItem value='usable'>
+              <AccordionTrigger>{t('Special usable group rules')}</AccordionTrigger>
+              <AccordionContent className='space-y-3'>
+                <p className='text-muted-foreground text-sm leading-6'>
+                  {t(
+                    'Special usable group rules can add, remove, or append selectable token groups for a specific user group.'
+                  )}
+                </p>
+                <GuideCodeBlock>{`{
+  "vip": {
+    "+:premium": "${t('Premium plan, half price')}",
+    "-:default": "remove",
+    "special": "${t('Special group')}"
+  }
+}`}</GuideCodeBlock>
+                <p className='text-muted-foreground text-sm leading-6'>
+                  {t(
+                    'Use +: to add a group, -: to remove a default selectable group, or no prefix to append a group.'
+                  )}
+                </p>
+              </AccordionContent>
+            </AccordionItem>
+          </Accordion>
+        </div>
+      </SheetContent>
+    </Sheet>
+  )
+}

+ 353 - 313
web/default/src/features/system-settings/models/group-ratio-visual-editor.tsx

@@ -1,4 +1,4 @@
-import { useState, useMemo, memo } from 'react'
+import { useState, useMemo, useEffect, useCallback, memo } from 'react'
 import { Pencil, Plus, Trash2, GripVertical, ChevronDown } from 'lucide-react'
 import { useTranslation } from 'react-i18next'
 import { Button } from '@/components/ui/button'
@@ -14,6 +14,7 @@ import {
   CollapsibleContent,
   CollapsibleTrigger,
 } from '@/components/ui/collapsible'
+import { Checkbox } from '@/components/ui/checkbox'
 import {
   Dialog,
   DialogContent,
@@ -48,8 +49,11 @@ type SimpleGroup = {
   value: string
 }
 
-type UsableGroup = {
+type GroupPricingRow = {
+  _id: string
   name: string
+  ratio: number
+  selectable: boolean
   description: string
 }
 
@@ -58,6 +62,90 @@ type GroupOverride = {
   ratio: number
 }
 
+const sectionCardClassName =
+  'relative shadow-sm ring-0 before:pointer-events-none before:absolute before:inset-0 before:rounded-xl before:border before:border-border/90'
+const sectionHeaderClassName = 'border-b bg-muted/20'
+
+let groupPricingIdCounter = 0
+function createGroupPricingId() {
+  groupPricingIdCounter += 1
+  return `gpr_${groupPricingIdCounter}`
+}
+
+function normalizeRatio(value: unknown): number {
+  const parsed = Number(value)
+  return Number.isFinite(parsed) ? parsed : 1
+}
+
+function buildGroupPricingRows(
+  groupRatio: string,
+  userUsableGroups: string
+): GroupPricingRow[] {
+  const ratioMap = safeJsonParse<Record<string, number>>(groupRatio, {
+    fallback: {},
+    context: 'group ratios',
+  })
+  const usableMap = safeJsonParse<Record<string, string>>(userUsableGroups, {
+    fallback: {},
+    context: 'user usable groups',
+  })
+  const names = new Set([...Object.keys(ratioMap), ...Object.keys(usableMap)])
+
+  return Array.from(names).map((name) => ({
+    _id: createGroupPricingId(),
+    name,
+    ratio: normalizeRatio(ratioMap[name]),
+    selectable: Object.prototype.hasOwnProperty.call(usableMap, name),
+    description: String(usableMap[name] ?? ''),
+  }))
+}
+
+function serializeGroupPricingRows(rows: GroupPricingRow[]) {
+  const groupRatio: Record<string, number> = {}
+  const userUsableGroups: Record<string, string> = {}
+
+  for (const row of rows) {
+    const name = row.name.trim()
+    if (!name) continue
+    groupRatio[name] = normalizeRatio(row.ratio)
+    if (row.selectable) {
+      userUsableGroups[name] = row.description
+    }
+  }
+
+  return {
+    GroupRatio: JSON.stringify(groupRatio, null, 2),
+    UserUsableGroups: JSON.stringify(userUsableGroups, null, 2),
+  }
+}
+
+function groupPricingSignature(rows: GroupPricingRow[]): string {
+  const serialized = serializeGroupPricingRows(rows)
+  return JSON.stringify({
+    groupRatio: safeJsonParse(serialized.GroupRatio, {
+      fallback: {},
+      silent: true,
+    }),
+    userUsableGroups: safeJsonParse(serialized.UserUsableGroups, {
+      fallback: {},
+      silent: true,
+    }),
+  })
+}
+
+function sourceGroupPricingSignature(
+  groupRatio: string,
+  userUsableGroups: string
+): string {
+  return JSON.stringify({
+    groupRatio: safeJsonParse(groupRatio, { fallback: {}, silent: true }),
+    userUsableGroups: safeJsonParse(userUsableGroups, {
+      fallback: {},
+      silent: true,
+    }),
+  })
+}
+
 export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
   groupRatio,
   topupGroupRatio,
@@ -73,9 +161,6 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
   >(null)
   const [simpleEditData, setSimpleEditData] = useState<SimpleGroup | null>(null)
 
-  const [usableDialogOpen, setUsableDialogOpen] = useState(false)
-  const [usableEditData, setUsableEditData] = useState<UsableGroup | null>(null)
-
   const [autoGroupDialogOpen, setAutoGroupDialogOpen] = useState(false)
   const [autoGroupInput, setAutoGroupInput] = useState('')
 
@@ -89,18 +174,6 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
   const [userGroupDialogOpen, setUserGroupDialogOpen] = useState(false)
   const [userGroupInput, setUserGroupInput] = useState('')
 
-  // Parse group ratios
-  const groupRatioList = useMemo(() => {
-    const map = safeJsonParse<Record<string, number>>(groupRatio, {
-      fallback: {},
-      context: 'group ratios',
-    })
-    return Object.entries(map).map(([name, value]) => ({
-      name,
-      value: String(value),
-    }))
-  }, [groupRatio])
-
   // Parse topup group ratios
   const topupRatioList = useMemo(() => {
     const map = safeJsonParse<Record<string, number>>(topupGroupRatio, {
@@ -113,18 +186,6 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
     }))
   }, [topupGroupRatio])
 
-  // Parse usable groups
-  const usableGroupsList = useMemo(() => {
-    const map = safeJsonParse<Record<string, string>>(userUsableGroups, {
-      fallback: {},
-      context: 'user usable groups',
-    })
-    return Object.entries(map).map(([name, description]) => ({
-      name,
-      description: String(description),
-    }))
-  }, [userUsableGroups])
-
   // Parse auto groups
   const autoGroupsList = useMemo(() => {
     return safeJsonParse<string[]>(autoGroups, {
@@ -204,42 +265,6 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
     onChange(field, JSON.stringify(map, null, 2))
   }
 
-  // Usable groups handlers
-  const handleUsableAdd = () => {
-    setUsableEditData(null)
-    setUsableDialogOpen(true)
-  }
-
-  const handleUsableEdit = (group: UsableGroup) => {
-    setUsableEditData(group)
-    setUsableDialogOpen(true)
-  }
-
-  const handleUsableSave = (name: string, description: string) => {
-    const map = safeJsonParse<Record<string, string>>(userUsableGroups, {
-      fallback: {},
-      silent: true,
-    })
-
-    if (usableEditData && usableEditData.name !== name) {
-      delete map[usableEditData.name]
-    }
-
-    map[name] = description
-
-    onChange('UserUsableGroups', JSON.stringify(map, null, 2))
-    setUsableDialogOpen(false)
-  }
-
-  const handleUsableDelete = (name: string) => {
-    const map = safeJsonParse<Record<string, string>>(userUsableGroups, {
-      fallback: {},
-      silent: true,
-    })
-    delete map[name]
-    onChange('UserUsableGroups', JSON.stringify(map, null, 2))
-  }
-
   // Auto groups handlers
   const handleAutoGroupAdd = () => {
     setAutoGroupInput('')
@@ -366,75 +391,16 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
   }
 
   return (
-    <div className='space-y-6'>
-      {/* Group Ratios */}
-      <Card>
-        <CardHeader>
-          <CardTitle>{t('Group ratios')}</CardTitle>
-          <CardDescription>
-            {t('Base multipliers applied when users select specific groups.')}
-          </CardDescription>
-        </CardHeader>
-        <CardContent>
-          <div className='space-y-4'>
-            <Button onClick={() => handleSimpleAdd('groupRatio')} size='sm'>
-              <Plus className='mr-2 h-4 w-4' />
-              {t('Add group')}
-            </Button>
-            {groupRatioList.length > 0 && (
-              <div className='rounded-md border'>
-                <Table>
-                  <TableHeader>
-                    <TableRow>
-                      <TableHead>{t('Group name')}</TableHead>
-                      <TableHead>{t('Ratio')}</TableHead>
-                      <TableHead className='text-right'>
-                        {t('Actions')}
-                      </TableHead>
-                    </TableRow>
-                  </TableHeader>
-                  <TableBody>
-                    {groupRatioList.map((group) => (
-                      <TableRow key={group.name}>
-                        <TableCell className='font-medium'>
-                          {group.name}
-                        </TableCell>
-                        <TableCell>{group.value}</TableCell>
-                        <TableCell className='text-right'>
-                          <div className='flex justify-end gap-2'>
-                            <Button
-                              variant='ghost'
-                              size='sm'
-                              onClick={() =>
-                                handleSimpleEdit('groupRatio', group)
-                              }
-                            >
-                              <Pencil className='h-4 w-4' />
-                            </Button>
-                            <Button
-                              variant='ghost'
-                              size='sm'
-                              onClick={() =>
-                                handleSimpleDelete('groupRatio', group.name)
-                              }
-                            >
-                              <Trash2 className='h-4 w-4' />
-                            </Button>
-                          </div>
-                        </TableCell>
-                      </TableRow>
-                    ))}
-                  </TableBody>
-                </Table>
-              </div>
-            )}
-          </div>
-        </CardContent>
-      </Card>
+    <div className='space-y-4'>
+      <GroupPricingTable
+        groupRatio={groupRatio}
+        userUsableGroups={userUsableGroups}
+        onChange={onChange}
+      />
 
       {/* Topup Group Ratios */}
-      <Card>
-        <CardHeader>
+      <Card className={sectionCardClassName}>
+        <CardHeader className={sectionHeaderClassName}>
           <CardTitle>{t('Top-up group ratios')}</CardTitle>
           <CardDescription>
             {t('Multipliers for recharge pricing based on user groups.')}
@@ -504,8 +470,8 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
       </Card>
 
       {/* Inter-group ratio overrides */}
-      <Card>
-        <CardHeader>
+      <Card className={sectionCardClassName}>
+        <CardHeader className={sectionHeaderClassName}>
           <CardTitle>{t('Inter-group ratio overrides')}</CardTitle>
           <CardDescription>
             {t(
@@ -625,70 +591,9 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
         </CardContent>
       </Card>
 
-      {/* Usable Groups */}
-      <Card>
-        <CardHeader>
-          <CardTitle>{t('Selectable groups')}</CardTitle>
-          <CardDescription>
-            {t('Groups that users can select when creating API keys.')}
-          </CardDescription>
-        </CardHeader>
-        <CardContent>
-          <div className='space-y-4'>
-            <Button onClick={handleUsableAdd} size='sm'>
-              <Plus className='mr-2 h-4 w-4' />
-              {t('Add group')}
-            </Button>
-            {usableGroupsList.length > 0 && (
-              <div className='rounded-md border'>
-                <Table>
-                  <TableHeader>
-                    <TableRow>
-                      <TableHead>{t('Group name')}</TableHead>
-                      <TableHead>{t('Description')}</TableHead>
-                      <TableHead className='text-right'>
-                        {t('Actions')}
-                      </TableHead>
-                    </TableRow>
-                  </TableHeader>
-                  <TableBody>
-                    {usableGroupsList.map((group) => (
-                      <TableRow key={group.name}>
-                        <TableCell className='font-medium'>
-                          {group.name}
-                        </TableCell>
-                        <TableCell>{group.description}</TableCell>
-                        <TableCell className='text-right'>
-                          <div className='flex justify-end gap-2'>
-                            <Button
-                              variant='ghost'
-                              size='sm'
-                              onClick={() => handleUsableEdit(group)}
-                            >
-                              <Pencil className='h-4 w-4' />
-                            </Button>
-                            <Button
-                              variant='ghost'
-                              size='sm'
-                              onClick={() => handleUsableDelete(group.name)}
-                            >
-                              <Trash2 className='h-4 w-4' />
-                            </Button>
-                          </div>
-                        </TableCell>
-                      </TableRow>
-                    ))}
-                  </TableBody>
-                </Table>
-              </div>
-            )}
-          </div>
-        </CardContent>
-      </Card>
-
       {/* Auto Groups */}
-      <Card>
-        <CardHeader>
+      <Card className={sectionCardClassName}>
+        <CardHeader className={sectionHeaderClassName}>
           <CardTitle>{t('Auto assignment order')}</CardTitle>
           <CardDescription>
             {t(
@@ -753,14 +658,6 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
         type={simpleDialogType}
       />
 
-      {/* Usable Group Dialog */}
-      <UsableGroupDialog
-        open={usableDialogOpen}
-        onOpenChange={setUsableDialogOpen}
-        onSave={handleUsableSave}
-        editData={usableEditData}
-      />
-
       {/* Auto Group Dialog */}
       <Dialog open={autoGroupDialogOpen} onOpenChange={setAutoGroupDialogOpen}>
         <DialogContent>
@@ -835,6 +732,233 @@ export const GroupRatioVisualEditor = memo(function GroupRatioVisualEditor({
   )
 })
 
+type GroupPricingTableProps = {
+  groupRatio: string
+  userUsableGroups: string
+  onChange: (field: string, value: string) => void
+}
+
+function GroupPricingTable({
+  groupRatio,
+  userUsableGroups,
+  onChange,
+}: GroupPricingTableProps) {
+  const { t } = useTranslation()
+  const [rows, setRows] = useState<GroupPricingRow[]>(() =>
+    buildGroupPricingRows(groupRatio, userUsableGroups)
+  )
+
+  useEffect(() => {
+    const incomingSignature = sourceGroupPricingSignature(
+      groupRatio,
+      userUsableGroups
+    )
+    setRows((currentRows) => {
+      if (groupPricingSignature(currentRows) === incomingSignature) {
+        return currentRows
+      }
+      return buildGroupPricingRows(groupRatio, userUsableGroups)
+    })
+  }, [groupRatio, userUsableGroups])
+
+  const emitRows = useCallback(
+    (nextRows: GroupPricingRow[]) => {
+      setRows(nextRows)
+      const serialized = serializeGroupPricingRows(nextRows)
+      onChange('GroupRatio', serialized.GroupRatio)
+      onChange('UserUsableGroups', serialized.UserUsableGroups)
+    },
+    [onChange]
+  )
+
+  const updateRow = useCallback(
+    (
+      id: string,
+      field: Exclude<keyof GroupPricingRow, '_id'>,
+      value: string | number | boolean
+    ) => {
+      emitRows(
+        rows.map((row) => (row._id === id ? { ...row, [field]: value } : row))
+      )
+    },
+    [emitRows, rows]
+  )
+
+  const addRow = useCallback(() => {
+    const existingNames = new Set(rows.map((row) => row.name))
+    let index = 1
+    let name = `group_${index}`
+    while (existingNames.has(name)) {
+      index += 1
+      name = `group_${index}`
+    }
+    emitRows([
+      ...rows,
+      {
+        _id: createGroupPricingId(),
+        name,
+        ratio: 1,
+        selectable: true,
+        description: '',
+      },
+    ])
+  }, [emitRows, rows])
+
+  const removeRow = useCallback(
+    (id: string) => {
+      emitRows(rows.filter((row) => row._id !== id))
+    },
+    [emitRows, rows]
+  )
+
+  const duplicateNames = useMemo(() => {
+    const counts = new Map<string, number>()
+    for (const row of rows) {
+      const name = row.name.trim()
+      if (!name) continue
+      counts.set(name, (counts.get(name) ?? 0) + 1)
+    }
+    return Array.from(counts.entries())
+      .filter(([, count]) => count > 1)
+      .map(([name]) => name)
+  }, [rows])
+
+  return (
+    <Card className={sectionCardClassName}>
+      <CardHeader className={sectionHeaderClassName}>
+        <div className='flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between'>
+          <div>
+            <CardTitle>{t('Pricing groups')}</CardTitle>
+            <CardDescription>
+              {t('Edit billing ratios and user-selectable groups in one table.')}
+            </CardDescription>
+          </div>
+          <Button onClick={addRow} size='sm' className='sm:self-start'>
+            <Plus className='mr-2 h-4 w-4' />
+            {t('Add group')}
+          </Button>
+        </div>
+      </CardHeader>
+      <CardContent>
+        <div className='space-y-3'>
+          <div className='overflow-hidden rounded-md border'>
+            <Table>
+              <TableHeader>
+                <TableRow>
+                  <TableHead className='min-w-40'>{t('Group name')}</TableHead>
+                  <TableHead className='w-28'>{t('Ratio')}</TableHead>
+                  <TableHead className='w-28 text-center'>
+                    {t('User selectable')}
+                  </TableHead>
+                  <TableHead className='min-w-56'>{t('Description')}</TableHead>
+                  <TableHead className='w-16 text-right'>
+                    {t('Actions')}
+                  </TableHead>
+                </TableRow>
+              </TableHeader>
+              <TableBody>
+                {rows.length === 0 ? (
+                  <TableRow>
+                    <TableCell
+                      colSpan={5}
+                      className='text-muted-foreground h-20 text-center text-sm'
+                    >
+                      {t('No groups yet. Add a group to get started.')}
+                    </TableCell>
+                  </TableRow>
+                ) : (
+                  rows.map((row) => (
+                    <TableRow key={row._id}>
+                      <TableCell>
+                        <Input
+                          value={row.name}
+                          onChange={(event) =>
+                            updateRow(row._id, 'name', event.target.value)
+                          }
+                          aria-invalid={duplicateNames.includes(
+                            row.name.trim()
+                          )}
+                        />
+                      </TableCell>
+                      <TableCell>
+                        <Input
+                          type='number'
+                          min={0}
+                          step={0.1}
+                          value={String(row.ratio)}
+                          onChange={(event) =>
+                            updateRow(
+                              row._id,
+                              'ratio',
+                              normalizeRatio(event.target.value)
+                            )
+                          }
+                        />
+                      </TableCell>
+                      <TableCell>
+                        <div className='flex justify-center'>
+                          <Checkbox
+                            checked={row.selectable}
+                            onCheckedChange={(checked) =>
+                              updateRow(
+                                row._id,
+                                'selectable',
+                                checked === true
+                              )
+                            }
+                            aria-label={t('User selectable')}
+                          />
+                        </div>
+                      </TableCell>
+                      <TableCell>
+                        {row.selectable ? (
+                          <Input
+                            value={row.description}
+                            placeholder={t('Group description')}
+                            onChange={(event) =>
+                              updateRow(
+                                row._id,
+                                'description',
+                                event.target.value
+                              )
+                            }
+                          />
+                        ) : (
+                          <span className='text-muted-foreground px-3 text-sm'>
+                            -
+                          </span>
+                        )}
+                      </TableCell>
+                      <TableCell className='text-right'>
+                        <Button
+                          variant='ghost'
+                          size='sm'
+                          onClick={() => removeRow(row._id)}
+                          aria-label={t('Delete')}
+                        >
+                          <Trash2 className='h-4 w-4' />
+                        </Button>
+                      </TableCell>
+                    </TableRow>
+                  ))
+                )}
+              </TableBody>
+            </Table>
+          </div>
+
+          {duplicateNames.length > 0 && (
+            <p className='text-destructive text-sm'>
+              {t('Duplicate group names: {{names}}', {
+                names: duplicateNames.join(', '),
+              })}
+            </p>
+          )}
+        </div>
+      </CardContent>
+    </Card>
+  )
+}
+
 // Simple Group Dialog Component
 type SimpleGroupDialogProps = {
   open: boolean
@@ -857,6 +981,17 @@ function SimpleGroupDialog({
 
   const title = type === 'groupRatio' ? t('group ratio') : t('top-up ratio')
 
+  useEffect(() => {
+    if (!open) {
+      setName('')
+      setValue('')
+      return
+    }
+
+    setName(editData?.name ?? '')
+    setValue(editData?.value ?? '')
+  }, [editData, open])
+
   const handleSave = () => {
     if (!name.trim() || !value.trim()) return
     onSave(name.trim(), value.trim())
@@ -865,19 +1000,7 @@ function SimpleGroupDialog({
   }
 
   return (
-    <Dialog
-      open={open}
-      onOpenChange={(open) => {
-        onOpenChange(open)
-        if (open && editData) {
-          setName(editData.name)
-          setValue(editData.value)
-        } else {
-          setName('')
-          setValue('')
-        }
-      }}
-    >
+    <Dialog open={open} onOpenChange={onOpenChange}>
       <DialogContent>
         <DialogHeader>
           <DialogTitle>
@@ -926,88 +1049,6 @@ function SimpleGroupDialog({
   )
 }
 
-// Usable Group Dialog Component
-type UsableGroupDialogProps = {
-  open: boolean
-  onOpenChange: (open: boolean) => void
-  onSave: (name: string, description: string) => void
-  editData: UsableGroup | null
-}
-
-function UsableGroupDialog({
-  open,
-  onOpenChange,
-  onSave,
-  editData,
-}: UsableGroupDialogProps) {
-  const { t } = useTranslation()
-  const [name, setName] = useState('')
-  const [description, setDescription] = useState('')
-
-  const handleSave = () => {
-    if (!name.trim() || !description.trim()) return
-    onSave(name.trim(), description.trim())
-    setName('')
-    setDescription('')
-  }
-
-  return (
-    <Dialog
-      open={open}
-      onOpenChange={(open) => {
-        onOpenChange(open)
-        if (open && editData) {
-          setName(editData.name)
-          setDescription(editData.description)
-        } else {
-          setName('')
-          setDescription('')
-        }
-      }}
-    >
-      <DialogContent>
-        <DialogHeader>
-          <DialogTitle>
-            {editData ? t('Edit selectable group') : t('Add selectable group')}
-          </DialogTitle>
-          <DialogDescription>
-            {t(
-              'Configure a group that users can select when creating API keys.'
-            )}
-          </DialogDescription>
-        </DialogHeader>
-        <div className='space-y-4 py-4'>
-          <div className='space-y-2'>
-            <Label>{t('Group name')}</Label>
-            <Input
-              value={name}
-              onChange={(e) => setName(e.target.value)}
-              placeholder={t('vip')}
-              disabled={!!editData}
-            />
-          </div>
-          <div className='space-y-2'>
-            <Label>{t('Description')}</Label>
-            <Input
-              value={description}
-              onChange={(e) => setDescription(e.target.value)}
-              placeholder={t('VIP users with premium access')}
-            />
-          </div>
-        </div>
-        <DialogFooter>
-          <Button variant='outline' onClick={() => onOpenChange(false)}>
-            {t('Cancel')}
-          </Button>
-          <Button onClick={handleSave}>
-            {editData ? t('Update') : t('Add')}
-          </Button>
-        </DialogFooter>
-      </DialogContent>
-    </Dialog>
-  )
-}
-
 // Group Override Dialog Component
 type GroupOverrideDialogProps = {
   open: boolean
@@ -1028,6 +1069,17 @@ function GroupOverrideDialog({
   const [targetGroup, setTargetGroup] = useState('')
   const [ratio, setRatio] = useState('')
 
+  useEffect(() => {
+    if (!open) {
+      setTargetGroup('')
+      setRatio('')
+      return
+    }
+
+    setTargetGroup(editData?.targetGroup ?? '')
+    setRatio(editData ? String(editData.ratio) : '')
+  }, [editData, open])
+
   const handleSave = () => {
     if (!targetGroup.trim() || !ratio.trim()) return
     const parsedRatio = parseFloat(ratio)
@@ -1039,19 +1091,7 @@ function GroupOverrideDialog({
   }
 
   return (
-    <Dialog
-      open={open}
-      onOpenChange={(open) => {
-        onOpenChange(open)
-        if (open && editData) {
-          setTargetGroup(editData.targetGroup)
-          setRatio(String(editData.ratio))
-        } else {
-          setTargetGroup('')
-          setRatio('')
-        }
-      }}
-    >
+    <Dialog open={open} onOpenChange={onOpenChange}>
       <DialogContent>
         <DialogHeader>
           <DialogTitle>

+ 5 - 2
web/default/src/features/system-settings/models/group-special-usable-editor.tsx

@@ -27,6 +27,9 @@ import { StatusBadge } from '@/components/status-badge'
 const OP_ADD = 'add' as const
 const OP_REMOVE = 'remove' as const
 const OP_APPEND = 'append' as const
+const sectionCardClassName =
+  'relative shadow-sm ring-0 before:pointer-events-none before:absolute before:inset-0 before:rounded-xl before:border before:border-border/90'
+const sectionHeaderClassName = 'border-b bg-muted/20'
 
 type OpType = typeof OP_ADD | typeof OP_REMOVE | typeof OP_APPEND
 
@@ -344,8 +347,8 @@ export function GroupSpecialUsableRulesEditor(
   }, [rules])
 
   return (
-    <Card>
-      <CardHeader>
+    <Card className={sectionCardClassName}>
+      <CardHeader className={sectionHeaderClassName}>
         <CardTitle>{t('Special usable group rules')}</CardTitle>
         <CardDescription>
           {t(

+ 4 - 4
web/default/src/features/system-settings/models/model-ratio-form.tsx

@@ -132,7 +132,7 @@ export const ModelRatioForm = memo(function ModelRatioForm({
 
             <div className='flex flex-wrap gap-4'>
               <Button onClick={form.handleSubmit(onSave)} disabled={isSaving}>
-                {isSaving ? t('Saving...') : t('Save model ratios')}
+                {isSaving ? t('Saving...') : t('Save model prices')}
               </Button>
               <Button
                 type='button'
@@ -140,7 +140,7 @@ export const ModelRatioForm = memo(function ModelRatioForm({
                 onClick={onReset}
                 disabled={isResetting}
               >
-                {t('Reset ratios')}
+                {t('Reset prices')}
               </Button>
             </div>
           </div>
@@ -323,7 +323,7 @@ export const ModelRatioForm = memo(function ModelRatioForm({
 
             <div className='flex flex-wrap gap-4'>
               <Button type='submit' disabled={isSaving}>
-                {isSaving ? t('Saving...') : t('Save model ratios')}
+                {isSaving ? t('Saving...') : t('Save model prices')}
               </Button>
               <Button
                 type='button'
@@ -331,7 +331,7 @@ export const ModelRatioForm = memo(function ModelRatioForm({
                 onClick={onReset}
                 disabled={isResetting}
               >
-                {t('Reset ratios')}
+                {t('Reset prices')}
               </Button>
             </div>
           </form>

+ 20 - 16
web/default/src/features/system-settings/models/ratio-settings-card.tsx

@@ -207,7 +207,7 @@ export function RatioSettingsCard({
     mutationFn: resetModelRatios,
     onSuccess: (data) => {
       if (data.success) {
-        toast.success(t('Model ratios reset successfully'))
+        toast.success(t('Model prices reset successfully'))
         queryClient.invalidateQueries({ queryKey: ['system-options'] })
         setConfirmOpen(false)
       } else {
@@ -422,7 +422,7 @@ export function RatioSettingsCard({
   }, [resetMutate])
 
   const tabLabels: Record<RatioTabId, string> = {
-    models: 'Model ratios',
+    models: 'Model prices',
     groups: 'Group ratios',
     'tool-prices': 'Tool prices',
     'upstream-sync': 'Upstream price sync',
@@ -480,26 +480,30 @@ export function RatioSettingsCard({
 
   return (
     <SettingsSection title={t(titleKey)} description={t(descriptionKey)}>
-      <Tabs defaultValue={defaultTab} className='space-y-6'>
-        <TabsList className={`grid w-full ${tabsGridClass}`}>
+      {visibleTabs.length === 1 ? (
+        renderTabContent(defaultTab)
+      ) : (
+        <Tabs defaultValue={defaultTab} className='space-y-6'>
+          <TabsList className={`grid w-full ${tabsGridClass}`}>
+            {visibleTabs.map((tab) => (
+              <TabsTrigger key={tab} value={tab}>
+                {t(tabLabels[tab])}
+              </TabsTrigger>
+            ))}
+          </TabsList>
+
           {visibleTabs.map((tab) => (
-            <TabsTrigger key={tab} value={tab}>
-              {t(tabLabels[tab])}
-            </TabsTrigger>
+            <TabsContent key={tab} value={tab}>
+              {renderTabContent(tab)}
+            </TabsContent>
           ))}
-        </TabsList>
-
-        {visibleTabs.map((tab) => (
-          <TabsContent key={tab} value={tab}>
-            {renderTabContent(tab)}
-          </TabsContent>
-        ))}
-      </Tabs>
+        </Tabs>
+      )}
 
       <ConfirmDialog
         open={confirmOpen}
         onOpenChange={setConfirmOpen}
-        title={t('Reset all model ratios?')}
+        title={t('Reset all model prices?')}
         desc={t(
           'This will clear custom pricing ratios and revert to upstream defaults.'
         )}

+ 1 - 1
web/default/src/i18n/locales/_reports/ja.untranslated.json

@@ -16,6 +16,7 @@
   "DeepSeek": "DeepSeek",
   "Discord": "Discord",
   "DoubaoVideo": "DoubaoVideo",
+  "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
   "edit_this": "edit_this",
   "FastGPT": "FastGPT",
   "footer.columns.related.links.midjourney": "Midjourney-Proxy",
@@ -78,7 +79,6 @@
   "SunoAPI": "SunoAPI",
   "Telegram": "Telegram",
   "Token prices": "Token prices",
-  "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
   "TTFT P50": "TTFT P50",
   "TTFT P95": "TTFT P95",
   "TTFT P99": "TTFT P99",

+ 13 - 13
web/default/src/i18n/locales/_reports/ru.untranslated.json

@@ -8,19 +8,25 @@
   "AccessKey / SecretAccessKey": "AccessKey / SecretAccessKey",
   "AI Proxy": "AI Proxy",
   "AIGC2D": "AIGC2D",
+  "All conditions must match before this tier is used.": "All conditions must match before this tier is used.",
   "Anthropic": "Anthropic",
   "API2GPT": "API2GPT",
   "AZURE_OPENAI_ENDPOINT *": "AZURE_OPENAI_ENDPOINT *",
   "Baidu V2": "Baidu V2",
+  "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
+  "Cache pricing": "Cache pricing",
   "checkout.session.completed": "checkout.session.completed",
   "checkout.session.expired": "checkout.session.expired",
   "Cloudflare": "Cloudflare",
   "Cohere": "Cohere",
+  "Core pricing": "Core pricing",
   "DeepSeek": "DeepSeek",
   "Discord": "Discord",
   "DoubaoVideo": "DoubaoVideo",
+  "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
   "example.com&#10;blocked-site.com": "example.com&#10;blocked-site.com",
   "example.com&#10;company.com": "example.com&#10;company.com",
+  "Fallback tier": "Fallback tier",
   "FastGPT": "FastGPT",
   "footer.columns.related.links.midjourney": "Midjourney-Proxy",
   "footer.columns.related.links.neko": "neko-api-key-tool",
@@ -53,6 +59,7 @@
   "JustSong": "JustSong",
   "LingYiWanWu": "LingYiWanWu",
   "LinuxDO": "LinuxDO",
+  "Media pricing": "Media pricing",
   "Midjourney": "Midjourney",
   "MidjourneyPlus": "MidjourneyPlus",
   "MiniMax": "MiniMax",
@@ -61,6 +68,7 @@
   "Moonshot": "Moonshot",
   "name@example.com": "name@example.com",
   "NewAPI": "NewAPI",
+  "No separate media pricing configured.": "No separate media pricing configured.",
   "noreply@example.com": "noreply@example.com",
   "OAuth Client Secret": "OAuth Client Secret",
   "OhMyGPT": "OhMyGPT",
@@ -73,6 +81,8 @@
   "price_xxx": "price_xxx",
   "QuantumNous": "QuantumNous",
   "Replicate": "Replicate",
+  "Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
+  "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
   "SiliconFlow": "SiliconFlow",
   "smtp.example.com": "smtp.example.com",
   "socks5://user:pass@host:port": "socks5://user:pass@host:port",
@@ -81,8 +91,9 @@
   "SunoAPI": "SunoAPI",
   "Telegram": "Telegram",
   "Tencent": "Tencent",
+  "This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
+  "Tier conditions": "Tier conditions",
   "Token prices": "Token prices",
-  "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
   "TTFT P50": "TTFT P50",
   "TTFT P95": "TTFT P95",
   "TTFT P99": "TTFT P99",
@@ -92,16 +103,5 @@
   "whsec_xxx": "whsec_xxx",
   "Xinference": "Xinference",
   "Xunfei": "Xunfei",
-  "Zhipu V4": "Zhipu V4",
-  "Cache pricing": "Cache pricing",
-  "Core pricing": "Core pricing",
-  "All conditions must match before this tier is used.": "All conditions must match before this tier is used.",
-  "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
-  "Fallback tier": "Fallback tier",
-  "Media pricing": "Media pricing",
-  "No separate media pricing configured.": "No separate media pricing configured.",
-  "Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
-  "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
-  "This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
-  "Tier conditions": "Tier conditions"
+  "Zhipu V4": "Zhipu V4"
 }

+ 1 - 1
web/default/src/i18n/locales/_reports/vi.untranslated.json

@@ -1,5 +1,5 @@
 {
-  "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
   "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
+  "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
   "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes."
 }

+ 112 - 77
web/default/src/i18n/locales/en.json

@@ -38,6 +38,7 @@
     "{{count}} models": "{{count}} models",
     "{{count}} months ago": "{{count}} months ago",
     "{{count}} override": "{{count}} override",
+    "{{count}} selected targets available for bulk copy.": "{{count}} selected targets available for bulk copy.",
     "{{count}} tiers": "{{count}} tiers",
     "{{count}} vendors": "{{count}} vendors",
     "{{count}} weeks ago": "{{count}} weeks ago",
@@ -96,6 +97,7 @@
     "7 Days": "7 Days",
     "7 days ago": "7 days ago",
     "80,443,8080": "80,443,8080",
+    "A billing multiplier. Lower ratios mean lower API call costs.": "A billing multiplier. Lower ratios mean lower API call costs.",
     "About": "About",
     "Accept Unpriced Models": "Accept Unpriced Models",
     "Accepts a JSON array of model identifiers that support the Imagine API.": "Accepts a JSON array of model identifiers that support the Imagine API.",
@@ -158,6 +160,7 @@
     "Add Mode": "Add Mode",
     "Add model": "Add model",
     "Add Model": "Add Model",
+    "Add model pricing": "Add model pricing",
     "Add Models": "Add Models",
     "Add new amount": "Add new amount",
     "Add new redemption code(s) by providing necessary info.": "Add new redemption code(s) by providing necessary info.",
@@ -236,6 +239,7 @@
     "Ali": "Ali",
     "All": "All",
     "All categories": "All categories",
+    "All conditions must match before this tier is used.": "All conditions must match before this tier is used.",
     "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "All edits are overwrite operations. Leave fields empty to keep current values unchanged.",
     "All files exceed the maximum size.": "All files exceed the maximum size.",
     "All Groups": "All Groups",
@@ -354,6 +358,7 @@
     "Append value to array / string / object end": "Append value to array / string / object end",
     "appended": "appended",
     "Application": "Application",
+    "Applied {{name}} pricing to {{count}} models": "Applied {{name}} pricing to {{count}} models",
     "Applies to custom completion endpoints. JSON map of model → ratio.": "Applies to custom completion endpoints. JSON map of model → ratio.",
     "Apply All Upstream Updates": "Apply All Upstream Updates",
     "Apply Filters": "Apply Filters",
@@ -383,6 +388,8 @@
     "Array of chat client presets. Each item is an object with one key-value pair: client name and its URL.": "Array of chat client presets. Each item is an object with one key-value pair: client name and its URL.",
     "Asc": "Asc",
     "Ask anything": "Ask anything",
+    "Assigned by administrator only": "Assigned by administrator only",
+    "Assigned by administrators and used to represent a user level, such as default or vip.": "Assigned by administrators and used to represent a user level, such as default or vip.",
     "Async task refund": "Async task refund",
     "At least one model regex pattern is required": "At least one model regex pattern is required",
     "At least one valid key source is required": "At least one valid key source is required",
@@ -393,10 +400,13 @@
     "Audio In": "Audio In",
     "Audio input": "Audio input",
     "Audio Input": "Audio Input",
+    "Audio input price": "Audio input price",
     "Audio Input Price": "Audio Input Price",
     "Audio Out": "Audio Out",
     "Audio output": "Audio output",
     "Audio Output": "Audio Output",
+    "Audio output price": "Audio output price",
+    "Audio output price requires an audio input price.": "Audio output price requires an audio input price.",
     "Audio playback failed": "Audio playback failed",
     "Audio Preview": "Audio Preview",
     "Audio ratio": "Audio ratio",
@@ -413,6 +423,7 @@
     "Auto Ban": "Auto Ban",
     "Auto detect (default)": "Auto detect (default)",
     "Auto Disabled": "Auto Disabled",
+    "Auto group behavior": "Auto group behavior",
     "Auto Group Chain": "Auto Group Chain",
     "Auto refresh": "Auto refresh",
     "Auto Sync Upstream Models": "Auto Sync Upstream Models",
@@ -469,6 +480,8 @@
     "Bark Push URL": "Bark Push URL",
     "Base address provided by your Epay service": "Base address provided by your Epay service",
     "Base amount. Actual deduction = base amount × system group rate.": "Base amount. Actual deduction = base amount × system group rate.",
+    "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
+    "Base input price only": "Base input price only",
     "Base Limits": "Base Limits",
     "Base multipliers applied when users select specific groups.": "Base multipliers applied when users select specific groups.",
     "Base Price": "Base Price",
@@ -493,6 +506,8 @@
     "Batch upstream model updates applied: {{channels}} channels, {{added}} added, {{removed}} removed, {{fails}} failed": "Batch upstream model updates applied: {{channels}} channels, {{added}} added, {{removed}} removed, {{fails}} failed",
     "Best for single-tenant deployments. Pricing and billing options stay hidden.": "Best for single-tenant deployments. Pricing and billing options stay hidden.",
     "Best TTFT": "Best TTFT",
+    "Billable input tokens": "Billable input tokens",
+    "Billable output tokens": "Billable output tokens",
     "Billing": "Billing",
     "Billing & Payment": "Billing & Payment",
     "Billing currency": "Billing currency",
@@ -545,6 +560,8 @@
     "By category": "By category",
     "By model author": "By model author",
     "Cache": "Cache",
+    "Cache create (1h) price": "Cache create (1h) price",
+    "Cache create price": "Cache create price",
     "Cache Creation": "Cache Creation",
     "Cache Creation (1h)": "Cache Creation (1h)",
     "Cache Creation (5m)": "Cache Creation (5m)",
@@ -553,13 +570,16 @@
     "Cache Directory Info": "Cache Directory Info",
     "Cache Entries": "Cache Entries",
     "Cache mode": "Cache mode",
+    "Cache pricing": "Cache pricing",
     "Cache ratio": "Cache ratio",
     "Cache Read": "Cache Read",
+    "Cache read price": "Cache read price",
     "Cache repeated prompt prefixes for cheaper, faster reuse": "Cache repeated prompt prefixes for cheaper, faster reuse",
     "Cache write": "Cache write",
     "Cache Write": "Cache Write",
     "Cache Write (1h)": "Cache Write (1h)",
     "Cache Write (5m)": "Cache Write (5m)",
+    "Cache write price": "Cache write price",
     "Cached": "Cached",
     "Cached input": "Cached input",
     "Calculated price: ${{price}} per 1M tokens": "Calculated price: ${{price}} per 1M tokens",
@@ -592,6 +612,7 @@
     "Change language": "Change language",
     "Change Password": "Change Password",
     "Change To": "Change To",
+    "Changes are written to the settings draft on save.": "Changes are written to the settings draft on save.",
     "Changing...": "Changing...",
     "Channel": "Channel",
     "Channel Affinity": "Channel Affinity",
@@ -663,6 +684,7 @@
     "Classic (Legacy Frontend)": "Classic (Legacy Frontend)",
     "Claude": "Claude",
     "Claude CLI Header Passthrough": "Claude CLI Header Passthrough",
+    "Clean": "Clean",
     "Clean history logs": "Clean history logs",
     "Clean logs": "Clean logs",
     "Clean up inactive cache": "Clean up inactive cache",
@@ -755,6 +777,7 @@
     "Complete these steps to finish the initial installation.": "Complete these steps to finish the initial installation.",
     "Completed": "Completed",
     "Completion": "Completion",
+    "Completion price": "Completion price",
     "Completion price ($/1M tokens)": "Completion price ($/1M tokens)",
     "Completion ratio": "Completion ratio",
     "Concatenate channel system prompt with user&apos;s prompt": "Concatenate channel system prompt with user&apos;s prompt",
@@ -894,6 +917,7 @@
     "Copied: {{model}}": "Copied: {{model}}",
     "Copied!": "Copied!",
     "Copy": "Copy",
+    "Copy {{name}} pricing": "Copy {{name}} pricing",
     "Copy a request header": "Copy a request header",
     "Copy All": "Copy All",
     "Copy all backup codes": "Copy all backup codes",
@@ -924,8 +948,10 @@
     "Copy token": "Copy token",
     "Copy URL": "Copy URL",
     "Copywriting, ad creative, SEO": "Copywriting, ad creative, SEO",
+    "Core concepts": "Core concepts",
     "Core Configuration": "Core Configuration",
     "Core Features": "Core Features",
+    "Core pricing": "Core pricing",
     "Cost": "Cost",
     "Cost in USD per request, regardless of tokens used.": "Cost in USD per request, regardless of tokens used.",
     "Cost Tracking": "Cost Tracking",
@@ -1148,6 +1174,7 @@
     "disabled": "disabled",
     "Disabled": "Disabled",
     "Disabled all channels with tag: {{tag}}": "Disabled all channels with tag: {{tag}}",
+    "Disabled lanes are omitted on save.": "Disabled lanes are omitted on save.",
     "Disabled Reason": "Disabled Reason",
     "Disabled Time": "Disabled Time",
     "Disabling...": "Disabling...",
@@ -1206,6 +1233,7 @@
     "Drawing Logs": "Drawing Logs",
     "Drawing task records": "Drawing task records",
     "Duplicate": "Duplicate",
+    "Duplicate group names: {{names}}": "Duplicate group names: {{names}}",
     "Duration": "Duration",
     "Duration (hours)": "Duration (hours)",
     "Duration Settings": "Duration Settings",
@@ -1257,12 +1285,15 @@
     "Each item must have exactly one key-value pair.": "Each item must have exactly one key-value pair.",
     "Each line represents one keyword. Leave blank to disable the list but keep the switch states.": "Each line represents one keyword. Leave blank to disable the list but keep the switch states.",
     "Each tier supports 0~2 conditions (over len, p, c); the last tier is the catch-all without conditions. Use len (full input length, including cache hits) for tier conditions to avoid mis-routing when cache hits reduce p.": "Each tier supports 0~2 conditions (over len, p, c); the last tier is the catch-all without conditions. Use len (full input length, including cache hits) for tier conditions to avoid mis-routing when cache hits reduce p.",
+    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.",
+    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Earn rewards when your referrals add funds. Transfer accumulated rewards to your balance anytime.": "Earn rewards when your referrals add funds. Transfer accumulated rewards to your balance anytime.",
     "Edit": "Edit",
     "Edit {{title}}": "Edit {{title}}",
     "Edit all channels with tag:": "Edit all channels with tag:",
     "Edit Announcement": "Edit Announcement",
     "Edit API Shortcut": "Edit API Shortcut",
+    "Edit billing ratios and user-selectable groups in one table.": "Edit billing ratios and user-selectable groups in one table.",
     "Edit Channel": "Edit Channel",
     "Edit chat preset": "Edit chat preset",
     "Edit discount tier": "Edit discount tier",
@@ -1272,6 +1303,7 @@
     "Edit JSON text directly. Format will be validated on save.": "Edit JSON text directly. Format will be validated on save.",
     "Edit model": "Edit model",
     "Edit Model": "Edit Model",
+    "Edit model pricing": "Edit model pricing",
     "Edit OAuth Provider": "Edit OAuth Provider",
     "Edit payment method": "Edit payment method",
     "Edit Prefill Group": "Edit Prefill Group",
@@ -1297,6 +1329,7 @@
     "Email Verification": "Email Verification",
     "Email, summarisation, knowledge work": "Email, summarisation, knowledge work",
     "Embeddings": "Embeddings",
+    "Empty": "Empty",
     "Empty value will be saved as {}.": "Empty value will be saved as {}.",
     "Enable": "Enable",
     "Enable 2FA": "Enable 2FA",
@@ -1475,9 +1508,12 @@
     "Expose grouped Uptime Kuma status pages directly on the dashboard": "Expose grouped Uptime Kuma status pages directly on the dashboard",
     "Expose ratio API": "Expose ratio API",
     "Exposes the pricing/models catalog in the top navigation.": "Exposes the pricing/models catalog in the top navigation.",
+    "Expression": "Expression",
+    "Expression based": "Expression based",
     "Expression billing": "Expression billing",
     "Expression editor": "Expression editor",
     "Expression error": "Expression error",
+    "Expression pricing": "Expression pricing",
     "Extend": "Extend",
     "Extend deployment": "Extend deployment",
     "Extend failed": "Extend failed",
@@ -1489,6 +1525,7 @@
     "External Speed Test": "External Speed Test",
     "Extra": "Extra",
     "Extra Notes (Optional)": "Extra Notes (Optional)",
+    "extras": "extras",
     "Fail Reason": "Fail Reason",
     "Fail Reason Details": "Fail Reason Details",
     "Failed": "Failed",
@@ -1610,6 +1647,7 @@
     "Failed to update user": "Failed to update user",
     "Failure keywords": "Failure keywords",
     "Fair": "Fair",
+    "Fallback tier": "Fallback tier",
     "FAQ": "FAQ",
     "FAQ added. Click \"Save Settings\" to apply.": "FAQ added. Click \"Save Settings\" to apply.",
     "FAQ deleted. Click \"Save Settings\" to apply.": "FAQ deleted. Click \"Save Settings\" to apply.",
@@ -1679,6 +1717,7 @@
     "Fixed abilities: {{success}} succeeded, {{fails}} failed": "Fixed abilities: {{success}} succeeded, {{fails}} failed",
     "Fixed price": "Fixed price",
     "Fixed price (USD)": "Fixed price (USD)",
+    "Fixed request price": "Fixed request price",
     "Floating": "Floating",
     "FluentRead extension not detected. Please ensure it is installed and active.": "FluentRead extension not detected. Please ensure it is installed and active.",
     "Flush interval (minutes)": "Flush interval (minutes)",
@@ -1732,6 +1771,7 @@
     "Full API Key": "Full API Key",
     "Full Base URL (supports": "Full Base URL (supports",
     "Full Code": "Full Code",
+    "Full input length": "Full input length",
     "Full layout": "Full layout",
     "Full width": "Full width",
     "Function calling": "Function calling",
@@ -1785,10 +1825,10 @@
     "gpt-4": "gpt-4",
     "gpt-4, claude-3-opus, etc.": "gpt-4, claude-3-opus, etc.",
     "GPU count": "GPU count",
-    "Greater Than": "Greater Than",
-    "Greater Than or Equal": "Greater Than or Equal",
     "Greater than": "Greater than",
+    "Greater Than": "Greater Than",
     "Greater than or equal": "Greater than or equal",
+    "Greater Than or Equal": "Greater Than or Equal",
     "Grok": "Grok",
     "Grok Settings": "Grok Settings",
     "Group": "Group",
@@ -1797,6 +1837,7 @@
     "Group channels by tag for batch operations": "Group channels by tag for batch operations",
     "Group config overrides global limits, shares the same period": "Group config overrides global limits, shares the same period",
     "Group deleted. Click \"Save Settings\" to apply.": "Group deleted. Click \"Save Settings\" to apply.",
+    "Group description": "Group description",
     "Group details": "Group details",
     "Group identifier": "Group identifier",
     "Group is required": "Group is required",
@@ -1805,6 +1846,7 @@
     "Group name cannot be changed when editing.": "Group name cannot be changed when editing.",
     "Group prices cannot be expanded because this expression is not a standard tiered pricing expression.": "Group prices cannot be expanded because this expression is not a standard tiered pricing expression.",
     "Group Pricing": "Group Pricing",
+    "Group pricing usage guide": "Group pricing usage guide",
     "group ratio": "group ratio",
     "Group Ratio": "Group Ratio",
     "Group ratios": "Group ratios",
@@ -1906,14 +1948,17 @@
     "If an upstream error contains any of these keywords (case insensitive), the channel will be disabled automatically.": "If an upstream error contains any of these keywords (case insensitive), the channel will be disabled automatically.",
     "If authorization succeeds, the generated JSON will be inserted into the key field. You still need to save the channel to persist it.": "If authorization succeeds, the generated JSON will be inserted into the key field. You still need to save the channel to persist it.",
     "If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing": "If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing",
-    "If this keeps happening, please report it on GitHub Issues.": "If this keeps happening, please report it on GitHub Issues.",
+    "If default auto group is enabled, newly created tokens start with auto instead of an empty group.": "If default auto group is enabled, newly created tokens start with auto instead of an empty group.",
     "If the affinity channel fails and retry succeeds on another channel, update affinity to the successful channel.": "If the affinity channel fails and retry succeeds on another channel, update affinity to the successful channel.",
+    "If this keeps happening, please report it on GitHub Issues.": "If this keeps happening, please report it on GitHub Issues.",
     "Ignored upstream models": "Ignored upstream models",
     "Image": "Image",
     "Image Generation": "Image Generation",
     "Image In": "Image In",
     "Image input": "Image input",
+    "Image input price": "Image input price",
     "Image Out": "Image Out",
+    "Image output price": "Image output price",
     "Image Preview": "Image Preview",
     "Image ratio": "Image ratio",
     "Image to Video": "Image to Video",
@@ -1927,6 +1972,7 @@
     "Include Group": "Include Group",
     "Include Model": "Include Model",
     "Include Rule Name": "Include Rule Name",
+    "Includes request rules": "Includes request rules",
     "Including failed requests, 0 = unlimited": "Including failed requests, 0 = unlimited",
     "Index": "Index",
     "Initial quota given to new users": "Initial quota given to new users",
@@ -1938,6 +1984,7 @@
     "Input": "Input",
     "Input mode": "Input mode",
     "Input price": "Input price",
+    "Input price is required before saving dependent prices.": "Input price is required before saving dependent prices.",
     "Input tokens": "Input tokens",
     "Input Tokens": "Input Tokens",
     "Inset": "Inset",
@@ -2068,10 +2115,10 @@
     "Legacy Format Template": "Legacy Format Template",
     "Legal": "Legal",
     "Less": "Less",
-    "Less Than": "Less Than",
-    "Less Than or Equal": "Less Than or Equal",
     "Less than": "Less than",
+    "Less Than": "Less Than",
     "Less than or equal": "Less than or equal",
+    "Less Than or Equal": "Less Than or Equal",
     "License": "License",
     "Light": "Light",
     "Lightning Fast": "Lightning Fast",
@@ -2188,6 +2235,7 @@
     "Maximum tokens per response": "Maximum tokens per response",
     "maxRequests ≥ 0, maxSuccess ≥ 1, both ≤ 2,147,483,647": "maxRequests ≥ 0, maxSuccess ≥ 1, both ≤ 2,147,483,647",
     "May be used for training by upstream provider": "May be used for training by upstream provider",
+    "Media pricing": "Media pricing",
     "Median time-to-first-token (TTFT) sampled hourly per group": "Median time-to-first-token (TTFT) sampled hourly per group",
     "Medical Q&A, mental health support": "Medical Q&A, mental health support",
     "Memory Hits": "Memory Hits",
@@ -2255,6 +2303,8 @@
     "Model performance metrics": "Model performance metrics",
     "Model Price": "Model Price",
     "Model Price Not Configured": "Model Price Not Configured",
+    "Model prices": "Model prices",
+    "Model prices reset successfully": "Model prices reset successfully",
     "Model Pricing": "Model Pricing",
     "Model pull failed: {{msg}}": "Model pull failed: {{msg}}",
     "Model ratio": "Model ratio",
@@ -2365,6 +2415,7 @@
     "New API Project Repository:": "New API Project Repository:",
     "New Format Template": "New Format Template",
     "New Group": "New Group",
+    "New model": "New model",
     "New Models ({{count}})": "New Models ({{count}})",
     "New name will be:": "New name will be:",
     "New password": "New password",
@@ -2393,6 +2444,7 @@
     "No available models": "No available models",
     "No available Web chat links": "No available Web chat links",
     "No backup": "No backup",
+    "No base input price": "No base input price",
     "No billing records found": "No billing records found",
     "No capabilities reported for this model.": "No capabilities reported for this model.",
     "No Change": "No Change",
@@ -2428,6 +2480,7 @@
     "No group found.": "No group found.",
     "No group-based rate limits configured. Click \"Add group\" to get started.": "No group-based rate limits configured. Click \"Add group\" to get started.",
     "No groups match your search": "No groups match your search",
+    "No groups yet. Add a group to get started.": "No groups yet. Add a group to get started.",
     "No header overrides configured.": "No header overrides configured.",
     "No history data available": "No history data available",
     "No incidents in the last 24 hours": "No incidents in the last 24 hours",
@@ -2449,6 +2502,7 @@
     "No models available": "No models available",
     "No models available in this category": "No models available in this category",
     "No models available. Create your first model to get started.": "No models available. Create your first model to get started.",
+    "No models configured. Use Add model to get started.": "No models configured. Use Add model to get started.",
     "No models fetched from upstream": "No models fetched from upstream",
     "No models fetched yet.": "No models fetched yet.",
     "No models found": "No models found",
@@ -2493,6 +2547,7 @@
     "No Retry": "No Retry",
     "No rules yet": "No rules yet",
     "No rules yet. Add a group below to get started.": "No rules yet. Add a group below to get started.",
+    "No separate media pricing configured.": "No separate media pricing configured.",
     "No status code mappings configured.": "No status code mappings configured.",
     "No subscription plans yet": "No subscription plans yet",
     "No subscription records": "No subscription records",
@@ -2579,6 +2634,7 @@
     "Online topup is not enabled. Please use redemption code or contact administrator.": "Online topup is not enabled. Please use redemption code or contact administrator.",
     "Only allow specific email domains": "Only allow specific email domains",
     "Only available for admins. When enabled, you will receive a summary notification via your selected method when the scheduled model check detects upstream model changes or check failures.": "Only available for admins. When enabled, you will receive a summary notification via your selected method when the scheduled model check detects upstream model changes or check failures.",
+    "Only configured combinations are overridden. All other calls keep the token group base ratio.": "Only configured combinations are overridden. All other calls keep the token group base ratio.",
     "Only selected fields will be overwritten. You can re-run the sync wizard if new conflicts appear.": "Only selected fields will be overwritten. You can re-run the sync wizard if new conflicts appear.",
     "Only successful requests": "Only successful requests",
     "Only successful requests count toward this limit.": "Only successful requests count toward this limit.",
@@ -2586,6 +2642,7 @@
     "Oops! Page Not Found!": "Oops! Page Not Found!",
     "Oops! Something went wrong": "Oops! Something went wrong",
     "Open": "Open",
+    "Open a source model first": "Open a source model first",
     "Open authorization page": "Open authorization page",
     "Open CC Switch": "Open CC Switch",
     "Open in chat": "Open in chat",
@@ -2641,9 +2698,11 @@
     "Output aspect ratio": "Output aspect ratio",
     "Output image size": "Output image size",
     "Output price": "Output price",
+    "Output token price for generated tokens.": "Output token price for generated tokens.",
     "Output tokens": "Output tokens",
     "Output Tokens": "Output Tokens",
     "overall": "overall",
+    "Overnight range": "Overnight range",
     "override": "override",
     "Override": "Override",
     "Override Anthropic headers, defaults, and thinking adapter behavior": "Override Anthropic headers, defaults, and thinking adapter behavior",
@@ -2656,7 +2715,6 @@
     "Override Rules": "Override Rules",
     "Override the endpoint used for testing. Leave empty to auto detect.": "Override the endpoint used for testing. Leave empty to auto detect.",
     "overrides for matching model prefix.": "overrides for matching model prefix.",
-    "Overnight range": "Overnight range",
     "Overview": "Overview",
     "Overwritten": "Overwritten",
     "Page": "Page",
@@ -2751,6 +2809,7 @@
     "Per-call": "Per-call",
     "Per-feature metered windows split by model or capability.": "Per-feature metered windows split by model or capability.",
     "Per-group performance": "Per-group performance",
+    "Per-request": "Per-request",
     "Per-request (fixed price)": "Per-request (fixed price)",
     "Per-token": "Per-token",
     "Per-token (ratio based)": "Per-token (ratio based)",
@@ -2854,6 +2913,7 @@
     "Prefix used when displaying prices": "Prefix used when displaying prices",
     "Prefix/Suffix Text": "Prefix/Suffix Text",
     "Premium chat models": "Premium chat models",
+    "Premium plan, half price": "Premium plan, half price",
     "Preparing chat keys…": "Preparing chat keys…",
     "Preparing your chat link, please try again in a moment.": "Preparing your chat link, please try again in a moment.",
     "Preparing your chat link…": "Preparing your chat link…",
@@ -2890,6 +2950,7 @@
     "Price estimation description": "After completing the hardware type, deployment location, replica count, etc., the price will be automatically calculated.",
     "Price ID": "Price ID",
     "Price mode (USD per 1M tokens)": "Price mode (USD per 1M tokens)",
+    "Price summary": "Price summary",
     "price_xxx": "price_xxx",
     "Price:": "Price:",
     "Price: High to Low": "Price: High to Low",
@@ -2901,6 +2962,8 @@
     "Pricing & Display": "Pricing & Display",
     "Pricing by Group": "Pricing by Group",
     "Pricing Configuration": "Pricing Configuration",
+    "Pricing group example": "Pricing group example",
+    "Pricing groups": "Pricing groups",
     "Pricing mode": "Pricing mode",
     "Pricing Ratios": "Pricing Ratios",
     "Pricing Type": "Pricing Type",
@@ -2943,8 +3006,6 @@
     "Provide Markdown, HTML, or an external URL for the user agreement": "Provide Markdown, HTML, or an external URL for the user agreement",
     "Provide per-category safety overrides as JSON. Use `default` for fallback values.": "Provide per-category safety overrides as JSON. Use `default` for fallback values.",
     "Provide per-model header overrides as JSON. Useful for enabling beta features such as expanded context windows.": "Provide per-model header overrides as JSON. Useful for enabling beta features such as expanded context windows.",
-    "Public model catalog and pricing page.": "Public model catalog and pricing page.",
-    "Public rankings page based on live usage data.": "Public rankings page based on live usage data.",
     "Provider": "Provider",
     "Provider & data privacy": "Provider & data privacy",
     "Provider created successfully": "Provider created successfully",
@@ -2957,6 +3018,8 @@
     "Prune Object Items": "Prune Object Items",
     "Prune object items by conditions": "Prune object items by conditions",
     "Prune Rule (string or JSON object)": "Prune Rule (string or JSON object)",
+    "Public model catalog and pricing page.": "Public model catalog and pricing page.",
+    "Public rankings page based on live usage data.": "Public rankings page based on live usage data.",
     "Publish Date": "Publish Date",
     "Published": "Published",
     "Published:": "Published:",
@@ -3171,6 +3234,7 @@
     "Resend ({{seconds}}s)": "Resend ({{seconds}}s)",
     "Reset": "Reset",
     "Reset 2FA": "Reset 2FA",
+    "Reset all model prices?": "Reset all model prices?",
     "Reset all model ratios?": "Reset all model ratios?",
     "Reset all settings to default values": "Reset all settings to default values",
     "Reset at:": "Reset at:",
@@ -3181,6 +3245,7 @@
     "Reset Passkey": "Reset Passkey",
     "Reset password": "Reset password",
     "Reset Period": "Reset Period",
+    "Reset prices": "Reset prices",
     "Reset ratios": "Reset ratios",
     "Reset Stats": "Reset Stats",
     "Reset to default": "Reset to default",
@@ -3272,12 +3337,14 @@
     "Save group ratios": "Save group ratios",
     "Save io.net settings": "Save io.net settings",
     "Save log settings": "Save log settings",
+    "Save model prices": "Save model prices",
     "Save model ratios": "Save model ratios",
     "Save Models": "Save Models",
     "Save monitoring rules": "Save monitoring rules",
     "Save navigation": "Save navigation",
     "Save notice": "Save notice",
     "Save Preferences": "Save Preferences",
+    "Save preview": "Save preview",
     "Save rate limits": "Save rate limits",
     "Save sensitive words": "Save sensitive words",
     "Save Settings": "Save Settings",
@@ -3340,6 +3407,7 @@
     "Select a color": "Select a color",
     "Select a group": "Select a group",
     "Select a group type": "Select a group type",
+    "Select a model to edit pricing": "Select a model to edit pricing",
     "Select a preset...": "Select a preset...",
     "Select a role": "Select a role",
     "Select a rule to edit.": "Select a rule to edit.",
@@ -3353,6 +3421,7 @@
     "Select an operation mode and enter the amount": "Select an operation mode and enter the amount",
     "Select announcement type": "Select announcement type",
     "Select at least one field to overwrite.": "Select at least one field to overwrite.",
+    "Select at least one target model": "Select at least one target model",
     "Select border radius": "Select border radius",
     "Select channel type": "Select channel type",
     "Select color preset": "Select color preset",
@@ -3406,6 +3475,7 @@
     "selected": "selected",
     "selected channel(s). Leave empty to remove tag.": "selected channel(s). Leave empty to remove tag.",
     "Selected conflicts were overwritten successfully.": "Selected conflicts were overwritten successfully.",
+    "Selected when creating a token and used as the default billing group for API calls.": "Selected when creating a token and used as the default billing group for API calls.",
     "Self-Use Mode": "Self-Use Mode",
     "Send": "Send",
     "Send code": "Send code",
@@ -3413,6 +3483,7 @@
     "Sending...": "Sending...",
     "Sensitive Words": "Sensitive Words",
     "Sent the API key to FluentRead.": "Sent the API key to FluentRead.",
+    "Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
     "Serve multiple users or teams with billing and quota control.": "Serve multiple users or teams with billing and quota control.",
     "Server Address": "Server Address",
     "Server IP": "Server IP",
@@ -3436,6 +3507,7 @@
     "Set quota amount and limits": "Set quota amount and limits",
     "Set Request Header": "Set Request Header",
     "Set runtime request header: override entire value, or manipulate comma-separated tokens": "Set runtime request header: override entire value, or manipulate comma-separated tokens",
+    "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
     "Set Tag": "Set Tag",
     "Set tag for selected channels": "Set tag for selected channels",
     "Set the language used across the interface": "Set the language used across the interface",
@@ -3513,10 +3585,14 @@
     "Space-separated OAuth scopes": "Space-separated OAuth scopes",
     "Spark model version, e.g., v2.1 (version number in API URL)": "Spark model version, e.g., v2.1 (version number in API URL)",
     "Special billing expression": "Special billing expression",
+    "Special group": "Special group",
+    "Special ratios override the token group ratio for specific user group and token group combinations.": "Special ratios override the token group ratio for specific user group and token group combinations.",
     "Special usable group rules": "Special usable group rules",
+    "Special usable group rules can add, remove, or append selectable token groups for a specific user group.": "Special usable group rules can add, remove, or append selectable token groups for a specific user group.",
     "SQLite stores all data in a single file. Make sure that file is persisted when running in containers.": "SQLite stores all data in a single file. Make sure that file is persisted when running in containers.",
     "SSRF Protection": "SSRF Protection",
     "Standard": "Standard",
+    "Standard price": "Standard price",
     "Start": "Start",
     "Start a conversation to see messages here": "Start a conversation to see messages here",
     "Start for free with generous limits. No credit card required.": "Start for free with generous limits. No credit card required.",
@@ -3731,12 +3807,15 @@
     "This may cause cache failures.": "This may cause cache failures.",
     "This may take a few moments while we validate the request and update your session.": "This may take a few moments while we validate the request and update your session.",
     "This model has both fixed price and ratio billing conflicts": "This model has both fixed price and ratio billing conflicts",
+    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.",
+    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.",
     "This model is not available in any group, or no group pricing information is configured.": "This model is not available in any group, or no group pricing information is configured.",
     "This month": "This month",
     "This page has not been created yet.": "This page has not been created yet.",
     "This project must be used in compliance with the": "This project must be used in compliance with the",
     "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.",
     "This site currently has {{count}} models enabled": "This site currently has {{count}} models enabled",
+    "This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
     "this token group": "this token group",
     "this user group": "this user group",
     "This user has no bindings": "This user has no bindings",
@@ -3758,19 +3837,20 @@
     "Throughput by group": "Throughput by group",
     "Throughput trend": "Throughput trend",
     "Tier": "Tier",
+    "Tier conditions": "Tier conditions",
     "Tier name": "Tier name",
     "Tiered": "Tiered",
-    "Token prices": "Token prices",
-    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Tiered (billing expression)": "Tiered (billing expression)",
     "Tiered price table": "Tiered price table",
+    "Tiered pricing": "Tiered pricing",
+    "tiers": "tiers",
     "Time": "Time",
     "Time Granularity": "Time Granularity",
     "Time remaining": "Time remaining",
     "Time window for rate limiting": "Time window for rate limiting",
     "Time-based": "Time-based",
-    "Time:": "Time:",
     "Time-sliced cache (Claude)": "Time-sliced cache (Claude)",
+    "Time:": "Time:",
     "Timeline": "Timeline",
     "times": "times",
     "Timing": "Timing",
@@ -3794,11 +3874,18 @@
     "Token Endpoint": "Token Endpoint",
     "Token Endpoint (Optional)": "Token Endpoint (Optional)",
     "Token estimator": "Token estimator",
+    "Token group": "Token group",
     "Token management": "Token management",
     "Token Management": "Token Management",
     "Token Mgmt": "Token Mgmt",
     "Token Name": "Token Name",
     "Token obtained from your Gotify application": "Token obtained from your Gotify application",
+    "Token price for audio input.": "Token price for audio input.",
+    "Token price for audio output.": "Token price for audio output.",
+    "Token price for cache reads.": "Token price for cache reads.",
+    "Token price for creating cache entries.": "Token price for creating cache entries.",
+    "Token price for image input.": "Token price for image input.",
+    "Token prices": "Token prices",
     "Token regenerated and copied to clipboard": "Token regenerated and copied to clipboard",
     "Token share by model author across the last 24 hours": "Token share by model author across the last 24 hours",
     "Token share by model author across the past few weeks": "Token share by model author across the past few weeks",
@@ -3922,6 +4009,7 @@
     "Unbind failed": "Unbind failed",
     "Unbound {{provider}}": "Unbound {{provider}}",
     "Underground": "Underground",
+    "Understand how user groups, token groups, ratios, and special rules work together.": "Understand how user groups, token groups, ratios, and special rules work together.",
     "Understand image inputs alongside text": "Understand image inputs alongside text",
     "Unexpected release payload": "Unexpected release payload",
     "Unified API Gateway for": "Unified API Gateway for",
@@ -3935,6 +4023,7 @@
     "Unlimited": "Unlimited",
     "Unlimited Quota": "Unlimited Quota",
     "Unsaved changes": "Unsaved changes",
+    "Unset price": "Unset price",
     "Until": "Until",
     "Untitled": "Untitled",
     "Untrusted upstream data:": "Untrusted upstream data:",
@@ -3999,12 +4088,16 @@
     "URL is required": "URL is required",
     "URL to your logo image (optional)": "URL to your logo image (optional)",
     "Usage": "Usage",
+    "Usage guide": "Usage guide",
     "Usage logs": "Usage logs",
     "Usage Logs": "Usage Logs",
     "Usage mode": "Usage mode",
     "Usage-based": "Usage-based",
     "USD": "USD",
     "USD Exchange Rate": "USD Exchange Rate",
+    "USD price per 1M input tokens.": "USD price per 1M input tokens.",
+    "USD price per 1M tokens.": "USD price per 1M tokens.",
+    "Use +: to add a group, -: to remove a default selectable group, or no prefix to append a group.": "Use +: to add a group, -: to remove a default selectable group, or no prefix to append a group.",
     "Use a compatible browser or device with biometric authentication or a security key to register a Passkey.": "Use a compatible browser or device with biometric authentication or a security key to register a Passkey.",
     "Use authenticator code": "Use authenticator code",
     "Use backup code": "Use backup code",
@@ -4014,6 +4107,8 @@
     "Use Passkey to sign in without entering your password.": "Use Passkey to sign in without entering your password.",
     "Use secure connection when sending emails": "Use secure connection when sending emails",
     "Use sidebar shortcut": "Use sidebar shortcut",
+    "Use the full-width table to scan prices, then select a row to edit it here.": "Use the full-width table to scan prices, then select a row to edit it here.",
+    "Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.": "Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.",
     "Use this token for API authentication": "Use this token for API authentication",
     "Use your Passkey": "Use your Passkey",
     "used": "used",
@@ -4034,6 +4129,7 @@
     "User created successfully": "User created successfully",
     "User dashboard and quota controls.": "User dashboard and quota controls.",
     "User Exclusive Ratio": "User Exclusive Ratio",
+    "User group": "User group",
     "User Group": "User Group",
     "User group name": "User group name",
     "User Group: {{ratio}}x": "User Group: {{ratio}}x",
@@ -4047,6 +4143,7 @@
     "User Information": "User Information",
     "User Menu": "User Menu",
     "User personal functions": "User personal functions",
+    "User selectable": "User selectable",
     "User Subscription Management": "User Subscription Management",
     "User updated successfully": "User updated successfully",
     "User Verification": "User Verification",
@@ -4058,6 +4155,7 @@
     "Users": "Users",
     "Users call the model on the left. The platform forwards the request to the upstream model on the right.": "Users call the model on the left. The platform forwards the request to the upstream model on the right.",
     "Users must wait for a successful drawing before upscales or variations.": "Users must wait for a successful drawing before upscales or variations.",
+    "Users only see groups marked as user selectable. Non-selectable groups can still be assigned by administrators.": "Users only see groups marked as user selectable. Non-selectable groups can still be assigned by administrators.",
     "uses": "uses",
     "Validity": "Validity",
     "Validity Period": "Validity Period",
@@ -4188,6 +4286,7 @@
     "Well-Known URL": "Well-Known URL",
     "Well-Known URL must start with http:// or https://": "Well-Known URL must start with http:// or https://",
     "What would you like to know?": "What would you like to know?",
+    "When a token uses the auto group, the system tries groups from top to bottom until it finds an available group.": "When a token uses the auto group, the system tries groups from top to bottom until it finds an available group.",
     "When conditions match, the final price is multiplied by X. Multiple matches multiply together; values < 1 act as discounts.": "When conditions match, the final price is multiplied by X. Multiple matches multiply together; values < 1 act as discounts.",
     "When enabled, if channels in the current group fail, it will try channels in the next group in order.": "When enabled, if channels in the current group fail, it will try channels in the next group in order.",
     "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. SSD recommended.": "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. SSD recommended.",
@@ -4195,6 +4294,7 @@
     "When enabled, newly created tokens start in the first auto group.": "When enabled, newly created tokens start in the first auto group.",
     "When enabled, prompts are scanned before reaching upstream models.": "When enabled, prompts are scanned before reaching upstream models.",
     "When enabled, the store field will be blocked": "When enabled, the store field will be blocked",
+    "When enabled, users can pick this group when creating tokens.": "When enabled, users can pick this group when creating tokens.",
     "When enabled, violation requests will incur additional charges.": "When enabled, violation requests will incur additional charges.",
     "When enabled, zero-cost models also pre-consume quota before final settlement.": "When enabled, zero-cost models also pre-consume quota before final settlement.",
     "When no conditions are set, the operation always executes.": "When no conditions are set, the operation always executes.",
@@ -4249,71 +4349,6 @@
     "Zero retention": "Zero retention",
     "Zhipu": "Zhipu",
     "Zhipu V4": "Zhipu V4",
-    "Zoom": "Zoom",
-    "Add model pricing": "Add model pricing",
-    "Applied {{name}} pricing to {{count}} models": "Applied {{name}} pricing to {{count}} models",
-    "Audio input price": "Audio input price",
-    "Audio output price": "Audio output price",
-    "Audio output price requires an audio input price.": "Audio output price requires an audio input price.",
-    "Billable input tokens": "Billable input tokens",
-    "Billable output tokens": "Billable output tokens",
-    "Cache create (1h) price": "Cache create (1h) price",
-    "Cache create price": "Cache create price",
-    "Cache read price": "Cache read price",
-    "Cache pricing": "Cache pricing",
-    "Cache write price": "Cache write price",
-    "Changes are written to the settings draft on save.": "Changes are written to the settings draft on save.",
-    "Clean": "Clean",
-    "Completion price": "Completion price",
-    "Core pricing": "Core pricing",
-    "Copy {{name}} pricing": "Copy {{name}} pricing",
-    "Disabled lanes are omitted on save.": "Disabled lanes are omitted on save.",
-    "Edit model pricing": "Edit model pricing",
-    "Empty": "Empty",
-    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.",
-    "All conditions must match before this tier is used.": "All conditions must match before this tier is used.",
-    "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
-    "Expression": "Expression",
-    "Fallback tier": "Fallback tier",
-    "Full input length": "Full input length",
-    "Input price is required before saving dependent prices.": "Input price is required before saving dependent prices.",
-    "Image input price": "Image input price",
-    "Image output price": "Image output price",
-    "Media pricing": "Media pricing",
-    "New model": "New model",
-    "No separate media pricing configured.": "No separate media pricing configured.",
-    "Open a source model first": "Open a source model first",
-    "Output token price for generated tokens.": "Output token price for generated tokens.",
-    "Per-request": "Per-request",
-    "Save preview": "Save preview",
-    "Select at least one target model": "Select at least one target model",
-    "Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
-    "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
-    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.",
-    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.",
-    "This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
-    "Tier conditions": "Tier conditions",
-    "Token price for audio input.": "Token price for audio input.",
-    "Token price for audio output.": "Token price for audio output.",
-    "Token price for cache reads.": "Token price for cache reads.",
-    "Token price for creating cache entries.": "Token price for creating cache entries.",
-    "Token price for image input.": "Token price for image input.",
-    "USD price per 1M input tokens.": "USD price per 1M input tokens.",
-    "USD price per 1M tokens.": "USD price per 1M tokens.",
-    "{{count}} selected targets available for bulk copy.": "{{count}} selected targets available for bulk copy.",
-    "Base input price only": "Base input price only",
-    "Expression based": "Expression based",
-    "Expression pricing": "Expression pricing",
-    "Fixed request price": "Fixed request price",
-    "Includes request rules": "Includes request rules",
-    "No base input price": "No base input price",
-    "No models configured. Use Add model to get started.": "No models configured. Use Add model to get started.",
-    "Price summary": "Price summary",
-    "Select a model to edit pricing": "Select a model to edit pricing",
-    "Tiered pricing": "Tiered pricing",
-    "Unset price": "Unset price",
-    "Use the full-width table to scan prices, then select a row to edit it here.": "Use the full-width table to scan prices, then select a row to edit it here.",
-    "extras": "extras",
-    "tiers": "tiers"
+    "Zoom": "Zoom"
   }
 }

+ 112 - 77
web/default/src/i18n/locales/fr.json

@@ -38,6 +38,7 @@
     "{{count}} models": "{{count}} modèles",
     "{{count}} months ago": "il y a {{count}} mois",
     "{{count}} override": "{{count}} remplacement",
+    "{{count}} selected targets available for bulk copy.": "{{count}} cibles sélectionnées disponibles pour la copie en lot.",
     "{{count}} tiers": "{{count}} paliers",
     "{{count}} vendors": "{{count}} fournisseurs",
     "{{count}} weeks ago": "il y a {{count}} semaines",
@@ -96,6 +97,7 @@
     "7 Days": "7 jours",
     "7 days ago": "Il y a 7 jours",
     "80,443,8080": "80,443,8080",
+    "A billing multiplier. Lower ratios mean lower API call costs.": "Un multiplicateur de facturation. Plus le ratio est faible, plus le coût des appels API est bas.",
     "About": "À propos",
     "Accept Unpriced Models": "Accepter les modèles non tarifés",
     "Accepts a JSON array of model identifiers that support the Imagine API.": "Accepte un tableau JSON d'identifiants de modèles qui prennent en charge l'API Imagine.",
@@ -158,6 +160,7 @@
     "Add Mode": "Ajouter un mode",
     "Add model": "Ajouter un modèle",
     "Add Model": "Ajouter un modèle",
+    "Add model pricing": "Ajouter une tarification de modèle",
     "Add Models": "Ajouter des modèles",
     "Add new amount": "Ajouter un nouveau montant",
     "Add new redemption code(s) by providing necessary info.": "Ajouter de nouveaux codes de réduction en fournissant les informations nécessaires.",
@@ -236,6 +239,7 @@
     "Ali": "Ali",
     "All": "Tout",
     "All categories": "Toutes catégories",
+    "All conditions must match before this tier is used.": "Toutes les conditions doivent correspondre pour utiliser ce palier.",
     "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "Toutes les modifications sont des opérations d'écrasement. Laissez les champs vides pour conserver les valeurs actuelles inchangées.",
     "All files exceed the maximum size.": "Tous les fichiers dépassent la taille maximale.",
     "All Groups": "Tous les groupes",
@@ -354,6 +358,7 @@
     "Append value to array / string / object end": "Ajouter la valeur à la fin du tableau / chaîne / objet",
     "appended": "ajouté",
     "Application": "Application",
+    "Applied {{name}} pricing to {{count}} models": "Tarification de {{name}} appliquée à {{count}} modèles",
     "Applies to custom completion endpoints. JSON map of model → ratio.": "S'applique aux points de terminaison de complétion personnalisés. Mappage JSON de modèle → ratio.",
     "Apply All Upstream Updates": "Appliquer toutes les mises à jour upstream",
     "Apply Filters": "Appliquer les filtres",
@@ -383,6 +388,8 @@
     "Array of chat client presets. Each item is an object with one key-value pair: client name and its URL.": "Tableau de préréglages de clients de chat. Chaque élément est un objet avec une paire clé-valeur : nom du client et son URL.",
     "Asc": "Asc",
     "Ask anything": "Demandez n'importe quoi",
+    "Assigned by administrator only": "Attribué uniquement par l'administrateur",
+    "Assigned by administrators and used to represent a user level, such as default or vip.": "Attribué par les administrateurs pour représenter un niveau utilisateur, comme default ou vip.",
     "Async task refund": "Remboursement de tâche asynchrone",
     "At least one model regex pattern is required": "Au moins un modèle de regex est requis",
     "At least one valid key source is required": "Au moins une source de clé valide est requise",
@@ -393,10 +400,13 @@
     "Audio In": "Entrée audio",
     "Audio input": "Entrée audio",
     "Audio Input": "Entrée audio",
+    "Audio input price": "Prix d’entrée audio",
     "Audio Input Price": "Prix entrée audio",
     "Audio Out": "Sortie audio",
     "Audio output": "Sortie audio",
     "Audio Output": "Sortie audio",
+    "Audio output price": "Prix de sortie audio",
+    "Audio output price requires an audio input price.": "Le prix de sortie audio nécessite un prix d’entrée audio.",
     "Audio playback failed": "Échec de la lecture audio",
     "Audio Preview": "Aperçu audio",
     "Audio ratio": "Ratio audio",
@@ -413,6 +423,7 @@
     "Auto Ban": "Bannissement automatique",
     "Auto detect (default)": "Détection automatique (par défaut)",
     "Auto Disabled": "Désactivé automatiquement",
+    "Auto group behavior": "Comportement du groupe auto",
     "Auto Group Chain": "Chaîne de groupes automatique",
     "Auto refresh": "Actualisation automatique",
     "Auto Sync Upstream Models": "Synchronisation automatique des modèles en amont",
@@ -469,6 +480,8 @@
     "Bark Push URL": "URL de notification Bark",
     "Base address provided by your Epay service": "Adresse de base fournie par votre service Epay",
     "Base amount. Actual deduction = base amount × system group rate.": "Montant de base. Déduction réelle = montant de base × taux du groupe système.",
+    "Base input and output token prices for this tier.": "Prix de base des tokens d’entrée et de sortie pour ce palier.",
+    "Base input price only": "Prix d’entrée de base uniquement",
     "Base Limits": "Limites de base",
     "Base multipliers applied when users select specific groups.": "Multiplicateurs de base appliqués lorsque les utilisateurs sélectionnent des groupes spécifiques.",
     "Base Price": "Prix de base",
@@ -493,6 +506,8 @@
     "Batch upstream model updates applied: {{channels}} channels, {{added}} added, {{removed}} removed, {{fails}} failed": "Mises à jour par lot des modèles en amont appliquées : {{channels}} canaux, {{added}} ajoutés, {{removed}} supprimés, {{fails}} échoués",
     "Best for single-tenant deployments. Pricing and billing options stay hidden.": "Idéal pour les déploiements mono-utilisateur. Les options de tarification et de facturation restent masquées.",
     "Best TTFT": "Meilleur TTFT",
+    "Billable input tokens": "Tokens d’entrée facturables",
+    "Billable output tokens": "Tokens de sortie facturables",
     "Billing": "Facturation",
     "Billing & Payment": "Facturation et paiement",
     "Billing currency": "Devise de facturation",
@@ -545,6 +560,8 @@
     "By category": "Par catégorie",
     "By model author": "Par auteur du modèle",
     "Cache": "Cache",
+    "Cache create (1h) price": "Prix de création du cache (1 h)",
+    "Cache create price": "Prix de création du cache",
     "Cache Creation": "Création cache",
     "Cache Creation (1h)": "Création cache (1h)",
     "Cache Creation (5m)": "Création cache (5m)",
@@ -553,13 +570,16 @@
     "Cache Directory Info": "Infos du répertoire de cache",
     "Cache Entries": "Entrées de cache",
     "Cache mode": "Mode de cache",
+    "Cache pricing": "Tarification du cache",
     "Cache ratio": "Ratio de cache",
     "Cache Read": "Lecture du cache",
+    "Cache read price": "Prix de lecture du cache",
     "Cache repeated prompt prefixes for cheaper, faster reuse": "Mettre en cache les préfixes répétés pour une réutilisation plus rapide et moins coûteuse",
     "Cache write": "Écriture du cache",
     "Cache Write": "Écriture du cache",
     "Cache Write (1h)": "Écriture cache (1h)",
     "Cache Write (5m)": "Écriture cache (5m)",
+    "Cache write price": "Prix d’écriture du cache",
     "Cached": "Cache",
     "Cached input": "Entrée mise en cache",
     "Calculated price: ${{price}} per 1M tokens": "Prix calculé : ${{price}} par 1M tokens",
@@ -592,6 +612,7 @@
     "Change language": "Changer de langue",
     "Change Password": "Changer le mot de passe",
     "Change To": "Changer en",
+    "Changes are written to the settings draft on save.": "Les modifications sont écrites dans le brouillon des paramètres lors de l’enregistrement.",
     "Changing...": "Modification en cours...",
     "Channel": "Canal",
     "Channel Affinity": "Affinité de canal",
@@ -663,6 +684,7 @@
     "Classic (Legacy Frontend)": "Classique (Ancien frontend)",
     "Claude": "Claude",
     "Claude CLI Header Passthrough": "Passthrough en-tête Claude CLI",
+    "Clean": "Sans conflit",
     "Clean history logs": "Nettoyer les journaux d'historique",
     "Clean logs": "Nettoyer les logs",
     "Clean up inactive cache": "Nettoyer le cache inactif",
@@ -755,6 +777,7 @@
     "Complete these steps to finish the initial installation.": "Suivez ces étapes pour terminer l'installation initiale.",
     "Completed": "Terminé",
     "Completion": "Achèvement",
+    "Completion price": "Prix de complétion",
     "Completion price ($/1M tokens)": "Prix de la complétion (USD/1M jetons)",
     "Completion ratio": "Ratio de complétion",
     "Concatenate channel system prompt with user&apos;s prompt": "Concaténer l'invite système du canal avec l'invite de l'utilisateur",
@@ -894,6 +917,7 @@
     "Copied: {{model}}": "Copié : {{model}}",
     "Copied!": "Copié !",
     "Copy": "Copier",
+    "Copy {{name}} pricing": "Copier la tarification de {{name}}",
     "Copy a request header": "Copier un en-tête de requête",
     "Copy All": "Tout copier",
     "Copy all backup codes": "Copier tous les codes de sauvegarde",
@@ -924,8 +948,10 @@
     "Copy token": "Copier le Jeton",
     "Copy URL": "Copier l'URL",
     "Copywriting, ad creative, SEO": "Rédaction publicitaire, créatif, SEO",
+    "Core concepts": "Concepts clés",
     "Core Configuration": "Configuration principale",
     "Core Features": "Fonctionnalités principales",
+    "Core pricing": "Tarification principale",
     "Cost": "Coût",
     "Cost in USD per request, regardless of tokens used.": "Coût en USD par requête, quel que soit le nombre de jetons utilisés.",
     "Cost Tracking": "Suivi des coûts",
@@ -1148,6 +1174,7 @@
     "disabled": "désactivé",
     "Disabled": "Désactivé",
     "Disabled all channels with tag: {{tag}}": "Tous les canaux avec le tag {{tag}} ont été désactivés",
+    "Disabled lanes are omitted on save.": "Les voies désactivées sont omises à l’enregistrement.",
     "Disabled Reason": "Raison de la désactivation",
     "Disabled Time": "Heure de désactivation",
     "Disabling...": "Désactivation en cours...",
@@ -1206,6 +1233,7 @@
     "Drawing Logs": "Journaux de dessin",
     "Drawing task records": "Historique des tâches de dessin",
     "Duplicate": "Dupliquer",
+    "Duplicate group names: {{names}}": "Noms de groupe en double : {{names}}",
     "Duration": "Durée",
     "Duration (hours)": "Durée (heures)",
     "Duration Settings": "Paramètres de durée",
@@ -1257,12 +1285,15 @@
     "Each item must have exactly one key-value pair.": "Chaque élément doit avoir exactement une paire clé-valeur.",
     "Each line represents one keyword. Leave blank to disable the list but keep the switch states.": "Chaque ligne représente un mot-clé. Laissez vide pour désactiver la liste mais conserver les états des interrupteurs.",
     "Each tier supports 0~2 conditions (over len, p, c); the last tier is the catch-all without conditions. Use len (full input length, including cache hits) for tier conditions to avoid mis-routing when cache hits reduce p.": "Chaque palier accepte 0 à 2 conditions (sur len, p, c) ; le dernier palier est le filet de sécurité sans condition. Utilisez len (longueur d'entrée complète, y compris les cache hits) pour les conditions de palier afin d'éviter les routages erronés lorsque les cache hits réduisent p.",
+    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "Chaque palier accepte jusqu’à 2 conditions ; le dernier palier sert de repli sans condition. Utilisez la longueur complète de l’entrée pour éviter un mauvais aiguillage lorsque les lectures de cache réduisent les tokens d’entrée facturables.",
+    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Earn rewards when your referrals add funds. Transfer accumulated rewards to your balance anytime.": "Gagnez des récompenses lorsque vos filleuls ajoutent des fonds. Transférez les récompenses accumulées à votre solde à tout moment.",
     "Edit": "Modifier",
     "Edit {{title}}": "Modifier {{title}}",
     "Edit all channels with tag:": "Modifier tous les canaux avec l'étiquette :",
     "Edit Announcement": "Modifier l'annonce",
     "Edit API Shortcut": "Modifier le raccourci API",
+    "Edit billing ratios and user-selectable groups in one table.": "Modifiez les ratios de facturation et les groupes sélectionnables par les utilisateurs dans un seul tableau.",
     "Edit Channel": "Modifier le canal",
     "Edit chat preset": "Modifier le préréglage de chat",
     "Edit discount tier": "Modifier le palier de remise",
@@ -1272,6 +1303,7 @@
     "Edit JSON text directly. Format will be validated on save.": "Modifier le texte JSON directement. Le format sera validé à l'enregistrement.",
     "Edit model": "Modifier le modèle",
     "Edit Model": "Modifier le modèle",
+    "Edit model pricing": "Modifier la tarification du modèle",
     "Edit OAuth Provider": "Modifier le fournisseur OAuth",
     "Edit payment method": "Modifier le mode de paiement",
     "Edit Prefill Group": "Modifier le groupe de préremplissage",
@@ -1297,6 +1329,7 @@
     "Email Verification": "Vérification d'e-mail",
     "Email, summarisation, knowledge work": "Email, résumé, travail intellectuel",
     "Embeddings": "Embeddings",
+    "Empty": "Vide",
     "Empty value will be saved as {}.": "Une valeur vide sera enregistrée comme {}.",
     "Enable": "Activer",
     "Enable 2FA": "Activer 2FA",
@@ -1475,9 +1508,12 @@
     "Expose grouped Uptime Kuma status pages directly on the dashboard": "Exposer les pages d'état groupées d'Uptime Kuma directement sur le tableau de bord",
     "Expose ratio API": "Exposer l'API de ratio",
     "Exposes the pricing/models catalog in the top navigation.": "Expose le catalogue des prix/modèles dans la navigation supérieure.",
+    "Expression": "Expression",
+    "Expression based": "Basé sur une expression",
     "Expression billing": "Facturation par expression",
     "Expression editor": "Éditeur d’expression",
     "Expression error": "Erreur d’expression",
+    "Expression pricing": "Tarification par expression",
     "Extend": "Prolonger",
     "Extend deployment": "Prolonger le déploiement",
     "Extend failed": "Échec de la prolongation",
@@ -1489,6 +1525,7 @@
     "External Speed Test": "Test de vitesse externe",
     "Extra": "Supplémentaire",
     "Extra Notes (Optional)": "Notes supplémentaires (facultatif)",
+    "extras": "suppléments",
     "Fail Reason": "Raison de l'échec",
     "Fail Reason Details": "Détails de la raison de l'échec",
     "Failed": "Échec",
@@ -1610,6 +1647,7 @@
     "Failed to update user": "Échec de la mise à jour de l'utilisateur",
     "Failure keywords": "Mots-clés d'échec",
     "Fair": "Correct",
+    "Fallback tier": "Palier de repli",
     "FAQ": "FAQ",
     "FAQ added. Click \"Save Settings\" to apply.": "FAQ ajouté. Cliquez sur \"Enregistrer les paramètres\" pour appliquer.",
     "FAQ deleted. Click \"Save Settings\" to apply.": "FAQ supprimé. Cliquez sur \"Enregistrer les paramètres\" pour appliquer.",
@@ -1679,6 +1717,7 @@
     "Fixed abilities: {{success}} succeeded, {{fails}} failed": "Correction des capacités : {{success}} réussie(s), {{fails}} échouée(s)",
     "Fixed price": "Prix fixe",
     "Fixed price (USD)": "Prix fixe (USD)",
+    "Fixed request price": "Prix fixe par requête",
     "Floating": "Flottant",
     "FluentRead extension not detected. Please ensure it is installed and active.": "Extension FluentRead non détectée. Veuillez vous assurer qu'elle est installée et activée.",
     "Flush interval (minutes)": "Intervalle d’écriture (minutes)",
@@ -1732,6 +1771,7 @@
     "Full API Key": "Clé API complète",
     "Full Base URL (supports": "URL de base complète (prend en charge",
     "Full Code": "Code complet",
+    "Full input length": "Longueur complète de l’entrée",
     "Full layout": "Disposition complète",
     "Full width": "Pleine largeur",
     "Function calling": "Appel de fonction",
@@ -1785,10 +1825,10 @@
     "gpt-4": "gpt-4",
     "gpt-4, claude-3-opus, etc.": "gpt-4, claude-3-opus, etc.",
     "GPU count": "Nombre de GPU",
-    "Greater Than": "Supérieur à",
-    "Greater Than or Equal": "Supérieur ou égal",
     "Greater than": "Supérieur à",
+    "Greater Than": "Supérieur à",
     "Greater than or equal": "Supérieur ou égal",
+    "Greater Than or Equal": "Supérieur ou égal",
     "Grok": "Grok",
     "Grok Settings": "Paramètres Grok",
     "Group": "Groupe",
@@ -1797,6 +1837,7 @@
     "Group channels by tag for batch operations": "Regrouper les canaux par étiquette pour les opérations par lots",
     "Group config overrides global limits, shares the same period": "La configuration du groupe annule les limites globales et partage la même période",
     "Group deleted. Click \"Save Settings\" to apply.": "Groupe supprimé. Cliquez sur \"Enregistrer les paramètres\" pour appliquer.",
+    "Group description": "Description du groupe",
     "Group details": "Détails du groupe",
     "Group identifier": "Identifiant du groupe",
     "Group is required": "Le groupe est requis",
@@ -1805,6 +1846,7 @@
     "Group name cannot be changed when editing.": "Le nom du groupe ne peut pas être modifié lors de la modification.",
     "Group prices cannot be expanded because this expression is not a standard tiered pricing expression.": "Les prix par groupe ne peuvent pas être détaillés car cette expression n'est pas une expression tarifaire par paliers standard.",
     "Group Pricing": "Tarification des groupes",
+    "Group pricing usage guide": "Guide d'utilisation des groupes tarifaires",
     "group ratio": "ratio de groupe",
     "Group Ratio": "Ratio de groupe",
     "Group ratios": "Ratios de groupe",
@@ -1906,14 +1948,17 @@
     "If an upstream error contains any of these keywords (case insensitive), the channel will be disabled automatically.": "Si une erreur en amont contient l'un de ces mots-clés (insensible à la casse), le canal sera désactivé automatiquement.",
     "If authorization succeeds, the generated JSON will be inserted into the key field. You still need to save the channel to persist it.": "Si l'autorisation réussit, le JSON généré sera inséré dans le champ clé. Vous devez encore enregistrer le canal pour le conserver.",
     "If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing": "Si vous vous connectez à des projets de relais One API ou New API en amont, utilisez le type OpenAI à la place sauf si vous savez ce que vous faites",
-    "If this keeps happening, please report it on GitHub Issues.": "Si cela continue, veuillez le signaler sur GitHub Issues.",
+    "If default auto group is enabled, newly created tokens start with auto instead of an empty group.": "Si le groupe auto par défaut est activé, les nouveaux jetons commencent avec auto au lieu d’un groupe vide.",
     "If the affinity channel fails and retry succeeds on another channel, update affinity to the successful channel.": "Si le canal affinitaire échoue et qu'une nouvelle tentative réussit sur un autre canal, mettre à jour l'affinité vers le canal ayant réussi.",
+    "If this keeps happening, please report it on GitHub Issues.": "Si cela continue, veuillez le signaler sur GitHub Issues.",
     "Ignored upstream models": "Modèles amont ignorés",
     "Image": "Image",
     "Image Generation": "Génération d'images",
     "Image In": "Entrée d’image",
     "Image input": "Entrée image",
+    "Image input price": "Prix d’entrée image",
     "Image Out": "Sortie d’image",
+    "Image output price": "Prix de sortie image",
     "Image Preview": "Aperçu de l'image",
     "Image ratio": "Ratio d'image",
     "Image to Video": "Image vers vidéo",
@@ -1927,6 +1972,7 @@
     "Include Group": "Inclure le groupe",
     "Include Model": "Inclure le modèle",
     "Include Rule Name": "Inclure le nom de la règle",
+    "Includes request rules": "Inclut des règles de requête",
     "Including failed requests, 0 = unlimited": "Y compris les requêtes échouées, 0 = illimité",
     "Index": "Index",
     "Initial quota given to new users": "Quota initial donné aux nouveaux utilisateurs",
@@ -1938,6 +1984,7 @@
     "Input": "Entrée",
     "Input mode": "Mode d'entrée",
     "Input price": "Prix d’entrée",
+    "Input price is required before saving dependent prices.": "Le prix d’entrée est requis avant d’enregistrer les prix dépendants.",
     "Input tokens": "Jetons d’entrée",
     "Input Tokens": "Tokens d'entrée",
     "Inset": "Encastré",
@@ -2068,10 +2115,10 @@
     "Legacy Format Template": "Modèle ancien format",
     "Legal": "Juridique",
     "Less": "Moins",
-    "Less Than": "Inférieur à",
-    "Less Than or Equal": "Inférieur ou égal",
     "Less than": "Inférieur à",
+    "Less Than": "Inférieur à",
     "Less than or equal": "Inférieur ou égal",
+    "Less Than or Equal": "Inférieur ou égal",
     "License": "Licence",
     "Light": "Clair",
     "Lightning Fast": "Extrêmement rapide",
@@ -2188,6 +2235,7 @@
     "Maximum tokens per response": "Nombre maximal de jetons par réponse",
     "maxRequests ≥ 0, maxSuccess ≥ 1, both ≤ 2,147,483,647": "maxRequests ≥ 0, maxSuccess ≥ 1, les deux ≤ 2 147 483 647",
     "May be used for training by upstream provider": "Peut être utilisé pour l'entraînement par le fournisseur amont",
+    "Media pricing": "Tarification multimodale",
     "Median time-to-first-token (TTFT) sampled hourly per group": "Latence médiane jusqu'au premier jeton (TTFT) échantillonnée par heure et par groupe",
     "Medical Q&A, mental health support": "Q&R médicales, soutien en santé mentale",
     "Memory Hits": "Hits mémoire",
@@ -2255,6 +2303,8 @@
     "Model performance metrics": "Indicateurs de performance des modèles",
     "Model Price": "Prix du modèle",
     "Model Price Not Configured": "Prix du modèle non configuré",
+    "Model prices": "Prix des modèles",
+    "Model prices reset successfully": "Prix des modèles réinitialisés avec succès",
     "Model Pricing": "Tarification des modèles",
     "Model pull failed: {{msg}}": "Échec du téléchargement du modèle : {{msg}}",
     "Model ratio": "Ratio modèle",
@@ -2365,6 +2415,7 @@
     "New API Project Repository:": "Dépôt du projet New API :",
     "New Format Template": "Modèle nouveau format",
     "New Group": "Nouveau groupe",
+    "New model": "Nouveau modèle",
     "New Models ({{count}})": "Nouveaux modèles ({{count}})",
     "New name will be:": "Le nouveau nom sera :",
     "New password": "Nouveau mot de passe",
@@ -2393,6 +2444,7 @@
     "No available models": "Aucun modèle disponible",
     "No available Web chat links": "Aucun lien de chat Web disponible",
     "No backup": "Pas de sauvegarde",
+    "No base input price": "Aucun prix d’entrée de base",
     "No billing records found": "Aucun enregistrement de facturation trouvé",
     "No capabilities reported for this model.": "Aucune capacité n'a été signalée pour ce modèle.",
     "No Change": "Aucun changement",
@@ -2428,6 +2480,7 @@
     "No group found.": "Aucun groupe trouvé.",
     "No group-based rate limits configured. Click \"Add group\" to get started.": "Aucune limite de taux basée sur les groupes configurée. Cliquez sur \"Ajouter un groupe\" pour commencer.",
     "No groups match your search": "Aucun groupe ne correspond à votre recherche",
+    "No groups yet. Add a group to get started.": "Aucun groupe pour le moment. Ajoutez un groupe pour commencer.",
     "No header overrides configured.": "Aucune surcharge d'en-têtes configurée.",
     "No history data available": "Aucune donnée historique disponible",
     "No incidents in the last 24 hours": "Aucun incident au cours des dernières 24 heures",
@@ -2449,6 +2502,7 @@
     "No models available": "Aucun modèle disponible",
     "No models available in this category": "Aucun modèle disponible dans cette catégorie",
     "No models available. Create your first model to get started.": "Aucun modèle disponible. Créez votre premier modèle pour commencer.",
+    "No models configured. Use Add model to get started.": "Aucun modèle configuré. Utilisez Ajouter un modèle pour commencer.",
     "No models fetched from upstream": "Aucun modèle récupéré depuis l'amont",
     "No models fetched yet.": "Aucun modèle récupéré pour l'instant.",
     "No models found": "Aucun modèle trouvé",
@@ -2493,6 +2547,7 @@
     "No Retry": "Pas de réessai",
     "No rules yet": "Aucune règle",
     "No rules yet. Add a group below to get started.": "Aucune règle pour le moment. Ajoutez un groupe ci-dessous pour commencer.",
+    "No separate media pricing configured.": "Aucune tarification multimodale séparée n’est configurée.",
     "No status code mappings configured.": "Aucun mappage de codes de statut configuré.",
     "No subscription plans yet": "Aucun plan d'abonnement pour le moment",
     "No subscription records": "Aucun enregistrement d'abonnement",
@@ -2579,6 +2634,7 @@
     "Online topup is not enabled. Please use redemption code or contact administrator.": "La recharge en ligne n'est pas activée. Veuillez utiliser un code d'échange ou contacter l'administrateur.",
     "Only allow specific email domains": "Autoriser uniquement des domaines d'e-mail spécifiques",
     "Only available for admins. When enabled, you will receive a summary notification via your selected method when the scheduled model check detects upstream model changes or check failures.": "Uniquement disponible pour les administrateurs. Lorsque cette option est activée, vous recevrez une notification récapitulative via votre méthode sélectionnée lorsque la vérification planifiée des modèles détecte des changements de modèles en amont ou des échecs de vérification.",
+    "Only configured combinations are overridden. All other calls keep the token group base ratio.": "Seules les combinaisons configurées sont remplacées. Les autres appels conservent le ratio de base du groupe du jeton.",
     "Only selected fields will be overwritten. You can re-run the sync wizard if new conflicts appear.": "Seuls les champs sélectionnés seront écrasés. Vous pouvez relancer l'assistant de synchronisation si de nouveaux conflits apparaissent.",
     "Only successful requests": "Uniquement les requêtes réussies",
     "Only successful requests count toward this limit.": "Seules les requêtes réussies comptent pour cette limite.",
@@ -2586,6 +2642,7 @@
     "Oops! Page Not Found!": "Oups ! Page introuvable !",
     "Oops! Something went wrong": "Oups ! Quelque chose s'est mal passé",
     "Open": "Ouvrir",
+    "Open a source model first": "Ouvrez d’abord un modèle source",
     "Open authorization page": "Ouvrir la page d'autorisation",
     "Open CC Switch": "Ouvrir le commutateur CC",
     "Open in chat": "Ouvrir dans le chat",
@@ -2641,9 +2698,11 @@
     "Output aspect ratio": "Format d'image de sortie",
     "Output image size": "Taille de l'image de sortie",
     "Output price": "Prix de sortie",
+    "Output token price for generated tokens.": "Prix des tokens de sortie générés.",
     "Output tokens": "Jetons de sortie",
     "Output Tokens": "Tokens de sortie",
     "overall": "global",
+    "Overnight range": "Plage nocturne",
     "override": "remplacer",
     "Override": "Remplacer",
     "Override Anthropic headers, defaults, and thinking adapter behavior": "Remplacer les en-têtes, les valeurs par défaut et le comportement de l'adaptateur de réflexion d'Anthropic",
@@ -2656,7 +2715,6 @@
     "Override Rules": "Règles de remplacement",
     "Override the endpoint used for testing. Leave empty to auto detect.": "Remplacer le point de terminaison utilisé pour les tests. Laisser vide pour la détection automatique.",
     "overrides for matching model prefix.": "remplace le tarif si le modèle a ce préfixe.",
-    "Overnight range": "Plage nocturne",
     "Overview": "Vue d'ensemble",
     "Overwritten": "Écrasé",
     "Page": "Page",
@@ -2751,6 +2809,7 @@
     "Per-call": "Par appel",
     "Per-feature metered windows split by model or capability.": "Fenêtres mesurées par fonction, réparties par modèle ou capacité.",
     "Per-group performance": "Performance par groupe",
+    "Per-request": "Par requête",
     "Per-request (fixed price)": "Par requête (prix fixe)",
     "Per-token": "Par jeton",
     "Per-token (ratio based)": "Par jeton (basé sur un ratio)",
@@ -2854,6 +2913,7 @@
     "Prefix used when displaying prices": "Préfixe utilisé lors de l'affichage des prix",
     "Prefix/Suffix Text": "Texte préfixe/suffixe",
     "Premium chat models": "Modèles de chat Premium",
+    "Premium plan, half price": "Offre premium, moitié prix",
     "Preparing chat keys…": "Préparation des clés de chat…",
     "Preparing your chat link, please try again in a moment.": "Préparation de votre lien de discussion, veuillez réessayer dans un instant.",
     "Preparing your chat link…": "Préparation de votre lien de chat…",
@@ -2890,6 +2950,7 @@
     "Price estimation description": "Après avoir configuré le type de matériel, l'emplacement de déploiement, le nombre de réplicas, etc., le prix sera calculé automatiquement.",
     "Price ID": "ID du prix",
     "Price mode (USD per 1M tokens)": "Mode de tarification (USD par 1M de jetons)",
+    "Price summary": "Résumé des prix",
     "price_xxx": "price_xxx",
     "Price:": "Prix :",
     "Price: High to Low": "Prix : Du plus élevé au plus bas",
@@ -2901,6 +2962,8 @@
     "Pricing & Display": "Tarification et Affichage",
     "Pricing by Group": "Tarification par groupe",
     "Pricing Configuration": "Configuration de la tarification",
+    "Pricing group example": "Exemple de groupe tarifaire",
+    "Pricing groups": "Groupes tarifaires",
     "Pricing mode": "Mode de tarification",
     "Pricing Ratios": "Ratios de tarification",
     "Pricing Type": "Type de tarification",
@@ -2943,8 +3006,6 @@
     "Provide Markdown, HTML, or an external URL for the user agreement": "Fournir du Markdown, du HTML ou une URL externe pour l'accord utilisateur",
     "Provide per-category safety overrides as JSON. Use `default` for fallback values.": "Fournir des remplacements de sécurité par catégorie au format JSON. Utilisez `default` pour les valeurs de secours.",
     "Provide per-model header overrides as JSON. Useful for enabling beta features such as expanded context windows.": "Fournir des remplacements d'en-tête par modèle au format JSON. Utile pour activer des fonctionnalités bêta telles que les fenêtres de contexte étendues.",
-    "Public model catalog and pricing page.": "Page publique du catalogue des modèles et des tarifs.",
-    "Public rankings page based on live usage data.": "Page publique des classements basée sur les données d'utilisation réelles.",
     "Provider": "Fournisseur",
     "Provider & data privacy": "Fournisseur & confidentialité",
     "Provider created successfully": "Fournisseur créé avec succès",
@@ -2957,6 +3018,8 @@
     "Prune Object Items": "Nettoyer les éléments objet",
     "Prune object items by conditions": "Nettoyer les éléments d'objets par conditions",
     "Prune Rule (string or JSON object)": "Règle de nettoyage (chaîne ou objet JSON)",
+    "Public model catalog and pricing page.": "Page publique du catalogue des modèles et des tarifs.",
+    "Public rankings page based on live usage data.": "Page publique des classements basée sur les données d'utilisation réelles.",
     "Publish Date": "Date de publication",
     "Published": "Publié",
     "Published:": "Publié :",
@@ -3171,6 +3234,7 @@
     "Resend ({{seconds}}s)": "Renvoyer ({{seconds}}s)",
     "Reset": "Réinitialiser",
     "Reset 2FA": "Réinitialiser la 2FA",
+    "Reset all model prices?": "Réinitialiser tous les prix des modèles ?",
     "Reset all model ratios?": "Réinitialiser tous les ratios de modèle ?",
     "Reset all settings to default values": "Réinitialiser tous les paramètres aux valeurs par défaut",
     "Reset at:": "Réinitialisation à :",
@@ -3181,6 +3245,7 @@
     "Reset Passkey": "Réinitialiser le Passkey",
     "Reset password": "Réinitialiser le mot de passe",
     "Reset Period": "Période de réinitialisation",
+    "Reset prices": "Réinitialiser les prix",
     "Reset ratios": "Réinitialiser les ratios",
     "Reset Stats": "Réinitialiser les statistiques",
     "Reset to default": "Réinitialiser par défaut",
@@ -3272,12 +3337,14 @@
     "Save group ratios": "Enregistrer les ratios de groupes",
     "Save io.net settings": "Enregistrer les paramètres io.net",
     "Save log settings": "Enregistrer les paramètres de journal",
+    "Save model prices": "Enregistrer les prix des modèles",
     "Save model ratios": "Enregistrer les ratios de modèles",
     "Save Models": "Enregistrer les modèles",
     "Save monitoring rules": "Enregistrer les règles de surveillance",
     "Save navigation": "Enregistrer la navigation",
     "Save notice": "Enregistrer l'avis",
     "Save Preferences": "Enregistrer les préférences",
+    "Save preview": "Aperçu de l’enregistrement",
     "Save rate limits": "Enregistrer les limites de débit",
     "Save sensitive words": "Enregistrer les mots sensibles",
     "Save Settings": "Enregistrer les paramètres",
@@ -3340,6 +3407,7 @@
     "Select a color": "Sélectionner une couleur",
     "Select a group": "Sélectionner un groupe",
     "Select a group type": "Sélectionner un type de groupe",
+    "Select a model to edit pricing": "Sélectionnez un modèle pour modifier sa tarification",
     "Select a preset...": "Sélectionner un préréglage...",
     "Select a role": "Sélectionner un rôle",
     "Select a rule to edit.": "Sélectionnez une règle à modifier.",
@@ -3353,6 +3421,7 @@
     "Select an operation mode and enter the amount": "Sélectionnez un mode d'opération et entrez le montant",
     "Select announcement type": "Sélectionner le type d'annonce",
     "Select at least one field to overwrite.": "Sélectionnez au moins un champ à écraser.",
+    "Select at least one target model": "Sélectionnez au moins un modèle cible",
     "Select border radius": "Sélectionner le rayon de bordure",
     "Select channel type": "Sélectionner le type de canal",
     "Select color preset": "Sélectionner un préréglage de couleur",
@@ -3406,6 +3475,7 @@
     "selected": "sélectionné",
     "selected channel(s). Leave empty to remove tag.": "canal(aux) sélectionné(s). Laisser vide pour supprimer l'étiquette.",
     "Selected conflicts were overwritten successfully.": "Les conflits sélectionnés ont été écrasés avec succès.",
+    "Selected when creating a token and used as the default billing group for API calls.": "Sélectionné lors de la création d’un jeton et utilisé comme groupe de facturation par défaut pour les appels API.",
     "Self-Use Mode": "Mode d'utilisation personnelle",
     "Send": "Envoyer",
     "Send code": "Envoyer le code",
@@ -3413,6 +3483,7 @@
     "Sending...": "Envoi en cours...",
     "Sensitive Words": "Mots sensibles",
     "Sent the API key to FluentRead.": "Clé API envoyée à FluentRead.",
+    "Separate image/audio prices are enabled.": "Les prix séparés image/audio sont activés.",
     "Serve multiple users or teams with billing and quota control.": "Servir plusieurs utilisateurs ou équipes avec gestion de la facturation et des quotas.",
     "Server Address": "Adresse du serveur",
     "Server IP": "IP du serveur",
@@ -3436,6 +3507,7 @@
     "Set quota amount and limits": "Définir le quota et les limites",
     "Set Request Header": "Définir un en-tête de requête",
     "Set runtime request header: override entire value, or manipulate comma-separated tokens": "Définir l'en-tête de requête : remplacer la valeur ou manipuler les tokens séparés par des virgules",
+    "Set separate prices for cache reads and writes.": "Définissez des prix séparés pour les lectures et écritures du cache.",
     "Set Tag": "Définir un tag",
     "Set tag for selected channels": "Définir un tag pour les canaux sélectionnés",
     "Set the language used across the interface": "Définir la langue utilisée dans l'interface",
@@ -3513,10 +3585,14 @@
     "Space-separated OAuth scopes": "Scopes OAuth séparés par des espaces",
     "Spark model version, e.g., v2.1 (version number in API URL)": "Version du modèle Spark, par exemple v2.1 (numéro de version dans l'URL de l'API)",
     "Special billing expression": "Expression de facturation spéciale",
+    "Special group": "Groupe spécial",
+    "Special ratios override the token group ratio for specific user group and token group combinations.": "Les ratios spéciaux remplacent le ratio du groupe de jeton pour des combinaisons précises de groupe utilisateur et de groupe de jeton.",
     "Special usable group rules": "Règles spéciales de groupes utilisables",
+    "Special usable group rules can add, remove, or append selectable token groups for a specific user group.": "Les règles de groupes utilisables spéciaux peuvent ajouter, supprimer ou annexer des groupes de jetons sélectionnables pour un groupe utilisateur précis.",
     "SQLite stores all data in a single file. Make sure that file is persisted when running in containers.": "SQLite stocke toutes les données dans un seul fichier. Assurez-vous que ce fichier est persisté lors de l'exécution dans des conteneurs.",
     "SSRF Protection": "Protection SSRF",
     "Standard": "Standard",
+    "Standard price": "Prix standard",
     "Start": "Début",
     "Start a conversation to see messages here": "Démarrez une conversation pour voir les messages ici",
     "Start for free with generous limits. No credit card required.": "Commencez gratuitement avec des limites généreuses. Aucune carte de crédit requise.",
@@ -3731,12 +3807,15 @@
     "This may cause cache failures.": "Cela peut provoquer des échecs de cache.",
     "This may take a few moments while we validate the request and update your session.": "Cela peut prendre quelques instants pendant que nous validons la requête et mettons à jour votre session.",
     "This model has both fixed price and ratio billing conflicts": "Ce modèle présente des conflits de facturation à la fois en prix fixe et au ratio",
+    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "Ce modèle possède à la fois un prix fixe et des paramètres de ratio. L’enregistrement du mode actuel réécrira les champs en conflit.",
+    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "Ce modèle possède à la fois un prix fixe et des prix par token. L’enregistrement du mode actuel réécrira les champs en conflit.",
     "This model is not available in any group, or no group pricing information is configured.": "Ce modèle n'est disponible dans aucun groupe, ou aucune information de tarification de groupe n'est configurée.",
     "This month": "Ce mois-ci",
     "This page has not been created yet.": "Cette page n'a pas encore été créée.",
     "This project must be used in compliance with the": "Ce projet doit être utilisé conformément aux",
     "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "Cet enregistrement provient d’une instance avant la mise à niveau et n’inclut pas d’audits. Mettez à jour l’instance pour enregistrer l’IP du serveur, l’IP de callback, le moyen de paiement et la version du système.",
     "This site currently has {{count}} models enabled": "Ce site compte actuellement {{count}} modèles activés",
+    "This tier catches any request that did not match earlier tiers.": "Ce palier récupère toute requête qui n’a pas correspondu aux paliers précédents.",
     "this token group": "ce groupe de jetons",
     "this user group": "ce groupe d'utilisateurs",
     "This user has no bindings": "Cet utilisateur n'a aucune liaison",
@@ -3758,19 +3837,20 @@
     "Throughput by group": "Débit par groupe",
     "Throughput trend": "Tendance du débit",
     "Tier": "Palier",
+    "Tier conditions": "Conditions du palier",
     "Tier name": "Nom du palier",
     "Tiered": "Par paliers",
-    "Token prices": "Token prices",
-    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Tiered (billing expression)": "Par paliers (expression de facturation)",
     "Tiered price table": "Grille de prix par paliers",
+    "Tiered pricing": "Tarification par paliers",
+    "tiers": "paliers",
     "Time": "Heure",
     "Time Granularity": "Granularité temporelle",
     "Time remaining": "Temps restant",
     "Time window for rate limiting": "Fenêtre de temps pour la limitation de débit",
     "Time-based": "Selon l’heure",
-    "Time:": "Heure :",
     "Time-sliced cache (Claude)": "Cache segmenté (Claude)",
+    "Time:": "Heure :",
     "Timeline": "Chronologie",
     "times": "Fois",
     "Timing": "Durée",
@@ -3794,11 +3874,18 @@
     "Token Endpoint": "Point de terminaison de jeton",
     "Token Endpoint (Optional)": "Point de terminaison du jeton (Facultatif)",
     "Token estimator": "Estimation des jetons",
+    "Token group": "Groupe de jetons",
     "Token management": "Gestion des jetons",
     "Token Management": "Gestion des tokens",
     "Token Mgmt": "Gestion des jetons",
     "Token Name": "Nom du jeton",
     "Token obtained from your Gotify application": "Jeton obtenu depuis votre application Gotify",
+    "Token price for audio input.": "Prix par token pour l’entrée audio.",
+    "Token price for audio output.": "Prix par token pour la sortie audio.",
+    "Token price for cache reads.": "Prix par token pour les lectures du cache.",
+    "Token price for creating cache entries.": "Prix par token pour la création d’entrées de cache.",
+    "Token price for image input.": "Prix par token pour l’entrée image.",
+    "Token prices": "Token prices",
     "Token regenerated and copied to clipboard": "Jeton régénéré et copié dans le presse-papiers",
     "Token share by model author across the last 24 hours": "Part des tokens par auteur de modèle sur les dernières 24 heures",
     "Token share by model author across the past few weeks": "Part des tokens par auteur de modèle au cours des dernières semaines",
@@ -3922,6 +4009,7 @@
     "Unbind failed": "Échec de la dissociation",
     "Unbound {{provider}}": "{{provider}} dissocié",
     "Underground": "Underground",
+    "Understand how user groups, token groups, ratios, and special rules work together.": "Comprendre comment les groupes utilisateur, groupes de jetons, ratios et règles spéciales fonctionnent ensemble.",
     "Understand image inputs alongside text": "Comprendre des entrées image en complément du texte",
     "Unexpected release payload": "Format de version inattendu",
     "Unified API Gateway for": "Passerelle API unifiée pour",
@@ -3935,6 +4023,7 @@
     "Unlimited": "Illimité",
     "Unlimited Quota": "Quota illimité",
     "Unsaved changes": "Modifications non enregistrées",
+    "Unset price": "Prix non défini",
     "Until": "Jusqu'au",
     "Untitled": "Sans titre",
     "Untrusted upstream data:": "Données amont non fiables :",
@@ -3999,12 +4088,16 @@
     "URL is required": "L'URL est requise",
     "URL to your logo image (optional)": "URL de votre image de logo (facultatif)",
     "Usage": "Utilisation",
+    "Usage guide": "Guide d'utilisation",
     "Usage logs": "Journaux d'utilisation",
     "Usage Logs": "Journaux d'utilisation",
     "Usage mode": "Mode d'utilisation",
     "Usage-based": "Basé sur l'utilisation",
     "USD": "USD",
     "USD Exchange Rate": "Taux de change USD",
+    "USD price per 1M input tokens.": "Prix en USD par million de tokens d’entrée.",
+    "USD price per 1M tokens.": "Prix en USD par million de tokens.",
+    "Use +: to add a group, -: to remove a default selectable group, or no prefix to append a group.": "Utilisez +: pour ajouter un groupe, -: pour supprimer un groupe sélectionnable par défaut, ou aucun préfixe pour annexer un groupe.",
     "Use a compatible browser or device with biometric authentication or a security key to register a Passkey.": "Utilisez un navigateur ou un appareil compatible avec l'authentification biométrique ou une clé de sécurité pour enregistrer une clé d'accès (Passkey).",
     "Use authenticator code": "Utiliser le code de l'authentificateur",
     "Use backup code": "Utiliser un code de secours",
@@ -4014,6 +4107,8 @@
     "Use Passkey to sign in without entering your password.": "Utilisez une clé d'accès (Passkey) pour vous connecter sans saisir votre mot de passe.",
     "Use secure connection when sending emails": "Utiliser une connexion sécurisée lors de l'envoi d'e-mails",
     "Use sidebar shortcut": "Utiliser le raccourci de la barre latérale",
+    "Use the full-width table to scan prices, then select a row to edit it here.": "Parcourez les prix dans le tableau, puis sélectionnez une ligne pour la modifier ici.",
+    "Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.": "Utilisez le tableau des groupes tarifaires pour gérer le ratio et l’apparition du groupe dans la liste de création de jeton.",
     "Use this token for API authentication": "Utilisez ce jeton pour l'authentification API",
     "Use your Passkey": "Utiliser votre clé d'accès (Passkey)",
     "used": "utilisé",
@@ -4034,6 +4129,7 @@
     "User created successfully": "Utilisateur créé avec succès",
     "User dashboard and quota controls.": "Tableau de bord utilisateur et contrôles de quotas.",
     "User Exclusive Ratio": "Ratio exclusif utilisateur",
+    "User group": "Groupe utilisateur",
     "User Group": "Groupe d'utilisateurs",
     "User group name": "Nom du groupe d'utilisateurs",
     "User Group: {{ratio}}x": "Groupe utilisateur : {{ratio}}x",
@@ -4047,6 +4143,7 @@
     "User Information": "Informations utilisateur",
     "User Menu": "Menu utilisateur",
     "User personal functions": "Fonctions personnelles de l'utilisateur",
+    "User selectable": "Sélectionnable par l'utilisateur",
     "User Subscription Management": "Gestion des abonnements utilisateur",
     "User updated successfully": "Utilisateur mis à jour avec succès",
     "User Verification": "Vérification de l'utilisateur",
@@ -4058,6 +4155,7 @@
     "Users": "Utilisateurs",
     "Users call the model on the left. The platform forwards the request to the upstream model on the right.": "Les utilisateurs appellent le modèle à gauche. La plateforme transmet la requête au modèle amont à droite.",
     "Users must wait for a successful drawing before upscales or variations.": "Les utilisateurs doivent attendre une génération réussie avant les upscales ou variations.",
+    "Users only see groups marked as user selectable. Non-selectable groups can still be assigned by administrators.": "Les utilisateurs ne voient que les groupes marqués comme sélectionnables. Les groupes non sélectionnables peuvent toujours être attribués par les administrateurs.",
     "uses": "utilisations",
     "Validity": "Validité",
     "Validity Period": "Période de validité",
@@ -4188,6 +4286,7 @@
     "Well-Known URL": "URL bien connue",
     "Well-Known URL must start with http:// or https://": "L'URL bien connue doit commencer par http:// ou https://",
     "What would you like to know?": "Que voulez-vous savoir ?",
+    "When a token uses the auto group, the system tries groups from top to bottom until it finds an available group.": "Quand un jeton utilise le groupe auto, le système essaie les groupes de haut en bas jusqu’à trouver un groupe disponible.",
     "When conditions match, the final price is multiplied by X. Multiple matches multiply together; values < 1 act as discounts.": "Si les conditions sont remplies, le prix final est multiplié par X. Plusieurs correspondances se multiplient ; les valeurs < 1 agissent comme des remises.",
     "When enabled, if channels in the current group fail, it will try channels in the next group in order.": "Lorsqu'elle est activée, si les canaux du groupe actuel échouent, le système essaiera les canaux du groupe suivant dans l'ordre.",
     "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. SSD recommended.": "Lorsqu'activé, les corps de requête volumineux sont temporairement stockés sur disque, réduisant considérablement l'utilisation mémoire. SSD recommandé.",
@@ -4195,6 +4294,7 @@
     "When enabled, newly created tokens start in the first auto group.": "Lorsqu'elle est activée, les jetons nouvellement créés commencent dans le premier groupe automatique.",
     "When enabled, prompts are scanned before reaching upstream models.": "Lorsqu'elle est activée, les invites sont scannées avant d'atteindre les modèles en amont.",
     "When enabled, the store field will be blocked": "Lorsqu'il est activé, le champ de la boutique sera bloqué",
+    "When enabled, users can pick this group when creating tokens.": "Une fois activé, les utilisateurs peuvent choisir ce groupe lors de la création de jetons.",
     "When enabled, violation requests will incur additional charges.": "Lorsqu'activé, les requêtes en violation entraîneront des frais supplémentaires.",
     "When enabled, zero-cost models also pre-consume quota before final settlement.": "Lorsqu'elle est activée, les modèles à coût zéro pré-consomment également du quota avant le règlement final.",
     "When no conditions are set, the operation always executes.": "Sans conditions, l'opération s'exécute toujours.",
@@ -4249,71 +4349,6 @@
     "Zero retention": "Aucune rétention",
     "Zhipu": "Zhipu",
     "Zhipu V4": "Zhipu V4",
-    "Zoom": "Zoom",
-    "Add model pricing": "Ajouter une tarification de modèle",
-    "Applied {{name}} pricing to {{count}} models": "Tarification de {{name}} appliquée à {{count}} modèles",
-    "Audio input price": "Prix d’entrée audio",
-    "Audio output price": "Prix de sortie audio",
-    "Audio output price requires an audio input price.": "Le prix de sortie audio nécessite un prix d’entrée audio.",
-    "Billable input tokens": "Tokens d’entrée facturables",
-    "Billable output tokens": "Tokens de sortie facturables",
-    "Cache create (1h) price": "Prix de création du cache (1 h)",
-    "Cache create price": "Prix de création du cache",
-    "Cache read price": "Prix de lecture du cache",
-    "Cache pricing": "Tarification du cache",
-    "Cache write price": "Prix d’écriture du cache",
-    "Changes are written to the settings draft on save.": "Les modifications sont écrites dans le brouillon des paramètres lors de l’enregistrement.",
-    "Clean": "Sans conflit",
-    "Completion price": "Prix de complétion",
-    "Core pricing": "Tarification principale",
-    "Copy {{name}} pricing": "Copier la tarification de {{name}}",
-    "Disabled lanes are omitted on save.": "Les voies désactivées sont omises à l’enregistrement.",
-    "Edit model pricing": "Modifier la tarification du modèle",
-    "Empty": "Vide",
-    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "Chaque palier accepte jusqu’à 2 conditions ; le dernier palier sert de repli sans condition. Utilisez la longueur complète de l’entrée pour éviter un mauvais aiguillage lorsque les lectures de cache réduisent les tokens d’entrée facturables.",
-    "All conditions must match before this tier is used.": "Toutes les conditions doivent correspondre pour utiliser ce palier.",
-    "Base input and output token prices for this tier.": "Prix de base des tokens d’entrée et de sortie pour ce palier.",
-    "Expression": "Expression",
-    "Fallback tier": "Palier de repli",
-    "Full input length": "Longueur complète de l’entrée",
-    "Input price is required before saving dependent prices.": "Le prix d’entrée est requis avant d’enregistrer les prix dépendants.",
-    "Image input price": "Prix d’entrée image",
-    "Image output price": "Prix de sortie image",
-    "Media pricing": "Tarification multimodale",
-    "New model": "Nouveau modèle",
-    "No separate media pricing configured.": "Aucune tarification multimodale séparée n’est configurée.",
-    "Open a source model first": "Ouvrez d’abord un modèle source",
-    "Output token price for generated tokens.": "Prix des tokens de sortie générés.",
-    "Per-request": "Par requête",
-    "Save preview": "Aperçu de l’enregistrement",
-    "Select at least one target model": "Sélectionnez au moins un modèle cible",
-    "Separate image/audio prices are enabled.": "Les prix séparés image/audio sont activés.",
-    "Set separate prices for cache reads and writes.": "Définissez des prix séparés pour les lectures et écritures du cache.",
-    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "Ce modèle possède à la fois un prix fixe et des paramètres de ratio. L’enregistrement du mode actuel réécrira les champs en conflit.",
-    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "Ce modèle possède à la fois un prix fixe et des prix par token. L’enregistrement du mode actuel réécrira les champs en conflit.",
-    "This tier catches any request that did not match earlier tiers.": "Ce palier récupère toute requête qui n’a pas correspondu aux paliers précédents.",
-    "Tier conditions": "Conditions du palier",
-    "Token price for audio input.": "Prix par token pour l’entrée audio.",
-    "Token price for audio output.": "Prix par token pour la sortie audio.",
-    "Token price for cache reads.": "Prix par token pour les lectures du cache.",
-    "Token price for creating cache entries.": "Prix par token pour la création d’entrées de cache.",
-    "Token price for image input.": "Prix par token pour l’entrée image.",
-    "USD price per 1M input tokens.": "Prix en USD par million de tokens d’entrée.",
-    "USD price per 1M tokens.": "Prix en USD par million de tokens.",
-    "{{count}} selected targets available for bulk copy.": "{{count}} cibles sélectionnées disponibles pour la copie en lot.",
-    "Base input price only": "Prix d’entrée de base uniquement",
-    "Expression based": "Basé sur une expression",
-    "Expression pricing": "Tarification par expression",
-    "Fixed request price": "Prix fixe par requête",
-    "Includes request rules": "Inclut des règles de requête",
-    "No base input price": "Aucun prix d’entrée de base",
-    "No models configured. Use Add model to get started.": "Aucun modèle configuré. Utilisez Ajouter un modèle pour commencer.",
-    "Price summary": "Résumé des prix",
-    "Select a model to edit pricing": "Sélectionnez un modèle pour modifier sa tarification",
-    "Tiered pricing": "Tarification par paliers",
-    "Unset price": "Prix non défini",
-    "Use the full-width table to scan prices, then select a row to edit it here.": "Parcourez les prix dans le tableau, puis sélectionnez une ligne pour la modifier ici.",
-    "extras": "suppléments",
-    "tiers": "paliers"
+    "Zoom": "Zoom"
   }
 }

+ 112 - 77
web/default/src/i18n/locales/ja.json

@@ -38,6 +38,7 @@
     "{{count}} models": "{{count}} モデル",
     "{{count}} months ago": "{{count}} ヶ月前",
     "{{count}} override": "{{count}} 個のオーバーライド",
+    "{{count}} selected targets available for bulk copy.": "一括コピーに使用できる対象が {{count}} 個選択されています。",
     "{{count}} tiers": "{{count}} 段階",
     "{{count}} vendors": "{{count}} ベンダー",
     "{{count}} weeks ago": "{{count}} 週間前",
@@ -96,6 +97,7 @@
     "7 Days": "7日",
     "7 days ago": "7日前",
     "80,443,8080": "80,443,8080",
+    "A billing multiplier. Lower ratios mean lower API call costs.": "課金倍率です。倍率が低いほど API 呼び出しコストは低くなります。",
     "About": "このサービスについて",
     "Accept Unpriced Models": "価格設定されていないモデルを許可",
     "Accepts a JSON array of model identifiers that support the Imagine API.": "Imagine APIをサポートするモデル識別子のJSON配列を受け入れます。",
@@ -158,6 +160,7 @@
     "Add Mode": "モードを追加",
     "Add model": "モデル追加",
     "Add Model": "モデルを追加",
+    "Add model pricing": "モデル料金を追加",
     "Add Models": "モデルを追加",
     "Add new amount": "新しい金額を追加",
     "Add new redemption code(s) by providing necessary info.": "必要な情報を提供して新しい引き換えコードを追加します。",
@@ -236,6 +239,7 @@
     "Ali": "Ali",
     "All": "すべて",
     "All categories": "すべてのカテゴリ",
+    "All conditions must match before this tier is used.": "この階層を使用するには、すべての条件に一致する必要があります。",
     "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "すべての編集は上書き操作です。現在の値を変更しないままにするには、フィールドを空のままにしてください。",
     "All files exceed the maximum size.": "すべてのファイルが最大サイズを超えています。",
     "All Groups": "すべてのグループ",
@@ -354,6 +358,7 @@
     "Append value to array / string / object end": "配列/文字列/オブジェクトの末尾に値を追加",
     "appended": "追加済み",
     "Application": "アプリケーション",
+    "Applied {{name}} pricing to {{count}} models": "{{name}} の料金を {{count}} 個のモデルに適用しました",
     "Applies to custom completion endpoints. JSON map of model → ratio.": "カスタム補完エンドポイントに適用されます。モデル → 比率のJSONマップ。",
     "Apply All Upstream Updates": "すべてのアップストリーム更新を適用",
     "Apply Filters": "フィルターを適用",
@@ -383,6 +388,8 @@
     "Array of chat client presets. Each item is an object with one key-value pair: client name and its URL.": "チャットクライアントプリセットの配列。各項目は、クライアント名とそのURLという1つのキーと値のペアを持つオブジェクトです。",
     "Asc": "昇順",
     "Ask anything": "何でも質問する",
+    "Assigned by administrator only": "管理者のみ割り当て",
+    "Assigned by administrators and used to represent a user level, such as default or vip.": "管理者が割り当て、default や vip などのユーザーレベルを表します。",
     "Async task refund": "非同期タスク返金",
     "At least one model regex pattern is required": "少なくとも1つのモデル正規表現パターンが必要です",
     "At least one valid key source is required": "少なくとも1つの有効なキーソースが必要です",
@@ -393,10 +400,13 @@
     "Audio In": "音声入力",
     "Audio input": "音声入力",
     "Audio Input": "音声入力",
+    "Audio input price": "音声入力価格",
     "Audio Input Price": "音声入力価格",
     "Audio Out": "音声出力",
     "Audio output": "音声出力",
     "Audio Output": "音声出力",
+    "Audio output price": "音声出力価格",
+    "Audio output price requires an audio input price.": "音声出力価格には音声入力価格が必要です。",
     "Audio playback failed": "音声の再生に失敗しました",
     "Audio Preview": "音声プレビュー",
     "Audio ratio": "音声倍率",
@@ -413,6 +423,7 @@
     "Auto Ban": "自動BAN",
     "Auto detect (default)": "自動検出 (デフォルト)",
     "Auto Disabled": "自動無効化",
+    "Auto group behavior": "auto グループの動作",
     "Auto Group Chain": "自動グループチェーン",
     "Auto refresh": "自動更新",
     "Auto Sync Upstream Models": "アップストリームモデルの自動同期",
@@ -469,6 +480,8 @@
     "Bark Push URL": "BarkプッシュURL",
     "Base address provided by your Epay service": "Epayサービスによって提供されるベースアドレス",
     "Base amount. Actual deduction = base amount × system group rate.": "基本金額。実際の控除 = 基本金額 × システムグループ倍率。",
+    "Base input and output token prices for this tier.": "この階層の基本入力・出力トークン価格。",
+    "Base input price only": "基本入力価格のみ",
     "Base Limits": "基本枠",
     "Base multipliers applied when users select specific groups.": "ユーザーが特定のグループを選択したときに適用される基本乗数。",
     "Base Price": "基本価格",
@@ -493,6 +506,8 @@
     "Batch upstream model updates applied: {{channels}} channels, {{added}} added, {{removed}} removed, {{fails}} failed": "一括上流モデル更新を処理しました:{{channels}} チャネル、{{added}} 個追加、{{removed}} 個削除、{{fails}} 個失敗",
     "Best for single-tenant deployments. Pricing and billing options stay hidden.": "シングルテナント環境に最適です。料金設定や請求オプションは非表示になります。",
     "Best TTFT": "最良 TTFT",
+    "Billable input tokens": "課金対象の入力トークン",
+    "Billable output tokens": "課金対象の出力トークン",
     "Billing": "請求",
     "Billing & Payment": "請求と支払い",
     "Billing currency": "請求通貨",
@@ -545,6 +560,8 @@
     "By category": "カテゴリ別",
     "By model author": "モデル提供者別",
     "Cache": "キャッシュ",
+    "Cache create (1h) price": "キャッシュ作成価格 (1時間)",
+    "Cache create price": "キャッシュ作成価格",
     "Cache Creation": "キャッシュ作成",
     "Cache Creation (1h)": "キャッシュ作成 (1h)",
     "Cache Creation (5m)": "キャッシュ作成 (5m)",
@@ -553,13 +570,16 @@
     "Cache Directory Info": "キャッシュディレクトリ情報",
     "Cache Entries": "キャッシュエントリ",
     "Cache mode": "キャッシュモード",
+    "Cache pricing": "キャッシュ価格",
     "Cache ratio": "キャッシュ倍率",
     "Cache Read": "キャッシュ読み取り",
+    "Cache read price": "キャッシュ読み取り価格",
     "Cache repeated prompt prefixes for cheaper, faster reuse": "繰り返しのプロンプト先頭部分をキャッシュし、低コスト・高速に再利用",
     "Cache write": "キャッシュ書き込み",
     "Cache Write": "キャッシュ書き込み",
     "Cache Write (1h)": "キャッシュ書込 (1h)",
     "Cache Write (5m)": "キャッシュ書込 (5m)",
+    "Cache write price": "キャッシュ書き込み価格",
     "Cached": "キャッシュ",
     "Cached input": "キャッシュ入力",
     "Calculated price: ${{price}} per 1M tokens": "計算価格:${{price}} / 1M トークン",
@@ -592,6 +612,7 @@
     "Change language": "言語を変更",
     "Change Password": "パスワードの変更",
     "Change To": "変更先",
+    "Changes are written to the settings draft on save.": "保存すると変更は設定ドラフトに書き込まれます。",
     "Changing...": "変更中...",
     "Channel": "チャネル",
     "Channel Affinity": "チャネルアフィニティ",
@@ -663,6 +684,7 @@
     "Classic (Legacy Frontend)": "クラシック(旧フロントエンド)",
     "Claude": "Claude",
     "Claude CLI Header Passthrough": "Claude CLI ヘッダーパススルー",
+    "Clean": "問題なし",
     "Clean history logs": "履歴ログをクリーンアップ",
     "Clean logs": "ログをクリア",
     "Clean up inactive cache": "非アクティブキャッシュをクリーンアップ",
@@ -755,6 +777,7 @@
     "Complete these steps to finish the initial installation.": "初期インストールを完了するには、これらの手順を完了してください。",
     "Completed": "完了",
     "Completion": "補完",
+    "Completion price": "補完価格",
     "Completion price ($/1M tokens)": "完了価格 (トークン100万あたり$)",
     "Completion ratio": "補完倍率",
     "Concatenate channel system prompt with user&apos;s prompt": "チャネルのシステムプロンプトをユーザーのプロンプトと連結する",
@@ -894,6 +917,7 @@
     "Copied: {{model}}": "コピーしました: {{model}}",
     "Copied!": "コピーしました!",
     "Copy": "コピー",
+    "Copy {{name}} pricing": "{{name}} の料金をコピー",
     "Copy a request header": "リクエストヘッダーをコピー",
     "Copy All": "すべてコピー",
     "Copy all backup codes": "すべてのバックアップコードをコピー",
@@ -924,8 +948,10 @@
     "Copy token": "トークンをコピー",
     "Copy URL": "URLをコピー",
     "Copywriting, ad creative, SEO": "コピーライティング・広告クリエイティブ・SEO",
+    "Core concepts": "基本概念",
     "Core Configuration": "コア設定",
     "Core Features": "主要機能",
+    "Core pricing": "基本価格",
     "Cost": "コスト",
     "Cost in USD per request, regardless of tokens used.": "使用されたトークンに関係なく、リクエストあたりのUSDでのコスト。",
     "Cost Tracking": "コスト追跡",
@@ -1148,6 +1174,7 @@
     "disabled": "無効",
     "Disabled": "無効",
     "Disabled all channels with tag: {{tag}}": "タグ「{{tag}}」の全チャネルを無効にしました",
+    "Disabled lanes are omitted on save.": "無効な価格レーンは保存時に省略されます。",
     "Disabled Reason": "無効化の理由",
     "Disabled Time": "無効化された時刻",
     "Disabling...": "無効化中...",
@@ -1206,6 +1233,7 @@
     "Drawing Logs": "画像生成履歴",
     "Drawing task records": "描画タスク記録",
     "Duplicate": "複製",
+    "Duplicate group names: {{names}}": "重複するグループ名: {{names}}",
     "Duration": "所要時間",
     "Duration (hours)": "期間(時間)",
     "Duration Settings": "有効期間設定",
@@ -1257,12 +1285,15 @@
     "Each item must have exactly one key-value pair.": "各項目には正確に 1 つのキーと値のペアが必要です。",
     "Each line represents one keyword. Leave blank to disable the list but keep the switch states.": "各行は1つのキーワードを表します。リストを無効にするが、スイッチの状態を維持するには、空白のままにしてください。",
     "Each tier supports 0~2 conditions (over len, p, c); the last tier is the catch-all without conditions. Use len (full input length, including cache hits) for tier conditions to avoid mis-routing when cache hits reduce p.": "各層は 0~2 個の条件(len、p、c に対して)を設定でき、最後の層は条件なしのキャッチオール層です。キャッシュヒットによって p が下がり層が誤判定されるのを防ぐため、層の条件には len(キャッシュヒットを含む完全な入力長)を使用してください。",
+    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "各階層は最大2つの条件をサポートします。最後の階層は条件なしのフォールバックです。キャッシュヒットで課金対象の入力トークンが減っても誤った階層にならないよう、条件には完全な入力長を使用してください。",
+    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Earn rewards when your referrals add funds. Transfer accumulated rewards to your balance anytime.": "紹介者が資金を追加すると報酬を獲得できます。いつでも蓄積された報酬を残高に振り替えることができます。",
     "Edit": "編集",
     "Edit {{title}}": "{{title}}を編集",
     "Edit all channels with tag:": "タグを持つすべてのチャネルを編集:",
     "Edit Announcement": "お知らせを編集",
     "Edit API Shortcut": "API ショートカットを編集",
+    "Edit billing ratios and user-selectable groups in one table.": "課金倍率とユーザーが選択できるグループを1つの表で編集します。",
     "Edit Channel": "チャンネルを編集",
     "Edit chat preset": "チャットプリセットを編集",
     "Edit discount tier": "割引ティアを編集",
@@ -1272,6 +1303,7 @@
     "Edit JSON text directly. Format will be validated on save.": "JSONテキストを直接編集します。保存時にフォーマットが検証されます。",
     "Edit model": "モデルを編集",
     "Edit Model": "モデルを編集",
+    "Edit model pricing": "モデル料金を編集",
     "Edit OAuth Provider": "OAuthプロバイダーを編集",
     "Edit payment method": "決済方法を編集",
     "Edit Prefill Group": "プリフィルグループを編集",
@@ -1297,6 +1329,7 @@
     "Email Verification": "メール認証",
     "Email, summarisation, knowledge work": "メール・要約・ナレッジワーク",
     "Embeddings": "埋め込み",
+    "Empty": "空",
     "Empty value will be saved as {}.": "空の値は {} として保存されます。",
     "Enable": "有効にする",
     "Enable 2FA": "2FA を有効にする",
@@ -1475,9 +1508,12 @@
     "Expose grouped Uptime Kuma status pages directly on the dashboard": "グループ化されたUptime Kumaステータスページをダッシュボードに直接公開する",
     "Expose ratio API": "倍率APIを公開",
     "Exposes the pricing/models catalog in the top navigation.": "価格/モデルカタログをトップナビゲーションに表示します。",
+    "Expression": "式",
+    "Expression based": "式ベース",
     "Expression billing": "式による課金",
     "Expression editor": "式エディター",
     "Expression error": "式のエラー",
+    "Expression pricing": "式による料金",
     "Extend": "延長",
     "Extend deployment": "デプロイメントを延長",
     "Extend failed": "延長に失敗しました",
@@ -1489,6 +1525,7 @@
     "External Speed Test": "外部スピードテスト",
     "Extra": "追加",
     "Extra Notes (Optional)": "追加のメモ (オプション)",
+    "extras": "追加項目",
     "Fail Reason": "失敗理由",
     "Fail Reason Details": "失敗理由の詳細",
     "Failed": "失敗",
@@ -1610,6 +1647,7 @@
     "Failed to update user": "ユーザーの更新に失敗しました",
     "Failure keywords": "失敗キーワード",
     "Fair": "公平",
+    "Fallback tier": "フォールバック階層",
     "FAQ": "FAQ",
     "FAQ added. Click \"Save Settings\" to apply.": "FAQ が追加されました。「設定を保存」をクリックして適用してください。",
     "FAQ deleted. Click \"Save Settings\" to apply.": "FAQ が削除されました。「設定を保存」をクリックして適用してください。",
@@ -1679,6 +1717,7 @@
     "Fixed abilities: {{success}} succeeded, {{fails}} failed": "能力修正:{{success}} 件成功、{{fails}} 件失敗",
     "Fixed price": "固定価格",
     "Fixed price (USD)": "固定価格 (USD)",
+    "Fixed request price": "固定リクエスト価格",
     "Floating": "フローティング",
     "FluentRead extension not detected. Please ensure it is installed and active.": "FluentRead 拡張機能が検出されませんでした。インストールされていて有効になっていることを確認してください。",
     "Flush interval (minutes)": "書き込み間隔(分)",
@@ -1732,6 +1771,7 @@
     "Full API Key": "完全なAPIキー",
     "Full Base URL (supports": "完全なベースURL (サポート",
     "Full Code": "完全なコード",
+    "Full input length": "完全な入力長",
     "Full layout": "フルレイアウト",
     "Full width": "全幅",
     "Function calling": "関数呼び出し",
@@ -1785,10 +1825,10 @@
     "gpt-4": "gpt-4",
     "gpt-4, claude-3-opus, etc.": "gpt-4、claude-3-opus など",
     "GPU count": "GPU 数",
-    "Greater Than": "より大きい",
-    "Greater Than or Equal": "以上",
     "Greater than": "より大きい",
+    "Greater Than": "より大きい",
     "Greater than or equal": "以上",
+    "Greater Than or Equal": "以上",
     "Grok": "Grok",
     "Grok Settings": "Grok 設定",
     "Group": "グループ",
@@ -1797,6 +1837,7 @@
     "Group channels by tag for batch operations": "バッチ操作のためにタグでチャネルをグループ化",
     "Group config overrides global limits, shares the same period": "グループ設定はグローバル制限を上書きし、同じ期間を共有します",
     "Group deleted. Click \"Save Settings\" to apply.": "グループが削除されました。「Save Settings」をクリックして適用してください。",
+    "Group description": "グループの説明",
     "Group details": "グループの詳細",
     "Group identifier": "グループ識別子",
     "Group is required": "グループは必須です",
@@ -1805,6 +1846,7 @@
     "Group name cannot be changed when editing.": "編集時はグループ名を変更できません。",
     "Group prices cannot be expanded because this expression is not a standard tiered pricing expression.": "この式は標準の段階制料金式ではないため、グループ別価格を展開できません。",
     "Group Pricing": "グループ料金",
+    "Group pricing usage guide": "グループ料金の使用ガイド",
     "group ratio": "グループ倍率",
     "Group Ratio": "グループ倍率",
     "Group ratios": "グループ比率",
@@ -1906,14 +1948,17 @@
     "If an upstream error contains any of these keywords (case insensitive), the channel will be disabled automatically.": "アップストリームエラーにこれらのキーワードのいずれかが含まれている場合 (大文字と小文字を区別しない)、チャネルは自動的に無効になります。",
     "If authorization succeeds, the generated JSON will be inserted into the key field. You still need to save the channel to persist it.": "認証が成功すると、生成されたJSONがキー欄に挿入されます。保存するにはチャンネルを保存してください。",
     "If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing": "上流の One API または New API リレープロジェクトに接続する場合、知っている場合を除き OpenAI タイプを使用してください",
-    "If this keeps happening, please report it on GitHub Issues.": "この問題が続く場合は、GitHub Issues で報告してください。",
+    "If default auto group is enabled, newly created tokens start with auto instead of an empty group.": "デフォルト auto グループを有効にすると、新規トークンは空グループではなく auto で開始します。",
     "If the affinity channel fails and retry succeeds on another channel, update affinity to the successful channel.": "アフィニティチャネルが失敗し、別のチャネルでリトライが成功した場合、アフィニティを成功したチャネルに更新します。",
+    "If this keeps happening, please report it on GitHub Issues.": "この問題が続く場合は、GitHub Issues で報告してください。",
     "Ignored upstream models": "無視する上流モデル",
     "Image": "画像",
     "Image Generation": "画像生成",
     "Image In": "画像入力",
     "Image input": "画像入力",
+    "Image input price": "画像入力価格",
     "Image Out": "画像出力",
+    "Image output price": "画像出力価格",
     "Image Preview": "画像プレビュー",
     "Image ratio": "画像倍率",
     "Image to Video": "画像から動画",
@@ -1927,6 +1972,7 @@
     "Include Group": "グループを含む",
     "Include Model": "モデルを含む",
     "Include Rule Name": "ルール名を含む",
+    "Includes request rules": "リクエストルールを含む",
     "Including failed requests, 0 = unlimited": "失敗したリクエストを含む、0 = 無制限",
     "Index": "インデックス",
     "Initial quota given to new users": "新規ユーザーに付与される初期クォータ",
@@ -1938,6 +1984,7 @@
     "Input": "入力",
     "Input mode": "入力モード",
     "Input price": "入力価格",
+    "Input price is required before saving dependent prices.": "依存する価格を保存する前に入力価格が必要です。",
     "Input tokens": "入力トークン",
     "Input Tokens": "入力トークン",
     "Inset": "インセット",
@@ -2068,10 +2115,10 @@
     "Legacy Format Template": "旧フォーマットテンプレート",
     "Legal": "法務",
     "Less": "少ない",
-    "Less Than": "より小さい",
-    "Less Than or Equal": "以下",
     "Less than": "より小さい",
+    "Less Than": "より小さい",
     "Less than or equal": "以下",
+    "Less Than or Equal": "以下",
     "License": "ライセンス",
     "Light": "ライト",
     "Lightning Fast": "超高速",
@@ -2188,6 +2235,7 @@
     "Maximum tokens per response": "1 回の応答あたりの最大トークン数",
     "maxRequests ≥ 0, maxSuccess ≥ 1, both ≤ 2,147,483,647": "maxRequests ≥ 0、maxSuccess ≥ 1、両方とも ≤ 2,147,483,647",
     "May be used for training by upstream provider": "上流プロバイダーが学習に利用する可能性があります",
+    "Media pricing": "メディア価格",
     "Median time-to-first-token (TTFT) sampled hourly per group": "グループ別に毎時サンプリングした最初のトークンまでの中央値レイテンシ (TTFT)",
     "Medical Q&A, mental health support": "医療Q&A・メンタルヘルスサポート",
     "Memory Hits": "メモリヒット",
@@ -2255,6 +2303,8 @@
     "Model performance metrics": "モデル性能メトリクス",
     "Model Price": "モデル価格",
     "Model Price Not Configured": "モデル価格が未設定",
+    "Model prices": "モデル価格",
+    "Model prices reset successfully": "モデル価格が正常にリセットされました",
     "Model Pricing": "モデル料金",
     "Model pull failed: {{msg}}": "モデルのプルに失敗しました: __ PH_0 __",
     "Model ratio": "モデル倍率",
@@ -2365,6 +2415,7 @@
     "New API Project Repository:": "New APIプロジェクトリポジトリ:",
     "New Format Template": "新フォーマットテンプレート",
     "New Group": "新しいグループ",
+    "New model": "新しいモデル",
     "New Models ({{count}})": "新しいモデル ({{count}})",
     "New name will be:": "新しい名前は次のようになります:",
     "New password": "新しいパスワード",
@@ -2393,6 +2444,7 @@
     "No available models": "利用可能なモデルがありません",
     "No available Web chat links": "利用可能なWebチャットリンクがありません",
     "No backup": "バックアップなし",
+    "No base input price": "基本入力価格なし",
     "No billing records found": "請求記録が見つかりません",
     "No capabilities reported for this model.": "このモデルには報告されている機能がありません。",
     "No Change": "変更なし",
@@ -2428,6 +2480,7 @@
     "No group found.": "グループが見つかりません。",
     "No group-based rate limits configured. Click \"Add group\" to get started.": "グループベースのレート制限が設定されていません。\"グループを追加\" をクリックして開始してください。",
     "No groups match your search": "検索に一致するグループがありません",
+    "No groups yet. Add a group to get started.": "グループはまだありません。グループを追加して開始してください。",
     "No header overrides configured.": "ヘッダーのオーバーライドが設定されていません。",
     "No history data available": "履歴データがありません",
     "No incidents in the last 24 hours": "過去 24 時間にインシデントはありません",
@@ -2449,6 +2502,7 @@
     "No models available": "利用可能なモデルがありません",
     "No models available in this category": "このカテゴリにはモデルがありません",
     "No models available. Create your first model to get started.": "利用可能なモデルがありません。最初のモデルを作成して開始してください。",
+    "No models configured. Use Add model to get started.": "モデルが設定されていません。モデルを追加して開始してください。",
     "No models fetched from upstream": "アップストリームからモデルを取得できませんでした",
     "No models fetched yet.": "まだモデルはフェッチされていません。",
     "No models found": "モデルが見つかりません",
@@ -2493,6 +2547,7 @@
     "No Retry": "リトライなし",
     "No rules yet": "ルールがありません",
     "No rules yet. Add a group below to get started.": "まだルールがありません。下にグループを追加して開始してください。",
+    "No separate media pricing configured.": "個別のメディア価格は設定されていません。",
     "No status code mappings configured.": "ステータスコードのマッピングが設定されていません。",
     "No subscription plans yet": "サブスクリプションプランがありません",
     "No subscription records": "サブスクリプション記録がありません",
@@ -2579,6 +2634,7 @@
     "Online topup is not enabled. Please use redemption code or contact administrator.": "オンラインチャージは有効になっていません。引き換えコードを使用するか、管理者に連絡してください。",
     "Only allow specific email domains": "特定のEメール ドメインのみを許可する",
     "Only available for admins. When enabled, you will receive a summary notification via your selected method when the scheduled model check detects upstream model changes or check failures.": "管理者のみ利用可能です。有効にすると、スケジュールされたモデルチェックでアップストリームモデルの変更やチェック失敗が検出された際に、選択した方法で概要通知を受け取ります。",
+    "Only configured combinations are overridden. All other calls keep the token group base ratio.": "設定済みの組み合わせだけが上書きされます。他の呼び出しはトークングループの基本倍率を維持します。",
     "Only selected fields will be overwritten. You can re-run the sync wizard if new conflicts appear.": "選択されたフィールドのみが上書きされます。新しい競合が発生した場合は、同期ウィザードを再実行できます。",
     "Only successful requests": "成功したリクエストのみ",
     "Only successful requests count toward this limit.": "成功したリクエストのみがこの制限にカウントされます。",
@@ -2586,6 +2642,7 @@
     "Oops! Page Not Found!": "おっと!ページが見つかりません!",
     "Oops! Something went wrong": "おっと!何か問題が発生しました",
     "Open": "開く",
+    "Open a source model first": "先にソースモデルを開いてください",
     "Open authorization page": "認証ページを開く",
     "Open CC Switch": "CC Switch を開く",
     "Open in chat": "チャットで開く",
@@ -2641,9 +2698,11 @@
     "Output aspect ratio": "出力アスペクト比",
     "Output image size": "出力画像サイズ",
     "Output price": "出力価格",
+    "Output token price for generated tokens.": "生成された出力トークンの価格。",
     "Output tokens": "出力トークン",
     "Output Tokens": "出力トークン",
     "overall": "全体",
+    "Overnight range": "日跨ぎ範囲",
     "override": "上書き",
     "Override": "上書き",
     "Override Anthropic headers, defaults, and thinking adapter behavior": "Anthropicのヘッダー、デフォルト、および思考アダプターの動作を上書きする",
@@ -2656,7 +2715,6 @@
     "Override Rules": "上書きルール",
     "Override the endpoint used for testing. Leave empty to auto detect.": "テストに使用されるエンドポイントを上書きします。自動検出するには空のままにします。",
     "overrides for matching model prefix.": "は一致するモデル接頭辞に上書きします。",
-    "Overnight range": "日跨ぎ範囲",
     "Overview": "概要",
     "Overwritten": "上書き済み",
     "Page": "ページ",
@@ -2751,6 +2809,7 @@
     "Per-call": "呼び出しごと",
     "Per-feature metered windows split by model or capability.": "機能ごとの従量制ウィンドウ。モデルまたは能力別に分かれます。",
     "Per-group performance": "グループ別パフォーマンス",
+    "Per-request": "リクエスト単位",
     "Per-request (fixed price)": "リクエストごと (固定価格)",
     "Per-token": "トークン単位",
     "Per-token (ratio based)": "トークンごと (比率ベース)",
@@ -2854,6 +2913,7 @@
     "Prefix used when displaying prices": "価格表示に使用されるプレフィックス",
     "Prefix/Suffix Text": "プレフィックス/サフィックステキスト",
     "Premium chat models": "プレミアムチャットモデル",
+    "Premium plan, half price": "プレミアムプラン、半額",
     "Preparing chat keys…": "チャットキーを準備中…",
     "Preparing your chat link, please try again in a moment.": "チャットリンクを準備中です。しばらくお待ちになってから再度お試しください。",
     "Preparing your chat link…": "チャットリンクを準備中…",
@@ -2890,6 +2950,7 @@
     "Price estimation description": "ハードウェアタイプ、デプロイ場所、レプリカ数などを設定すると、料金が自動的に計算されます。",
     "Price ID": "価格 ID",
     "Price mode (USD per 1M tokens)": "価格モード (100万トークンあたりのUSD)",
+    "Price summary": "価格概要",
     "price_xxx": "price_xxx",
     "Price:": "価格:",
     "Price: High to Low": "価格:高い順",
@@ -2901,6 +2962,8 @@
     "Pricing & Display": "価格設定と表示",
     "Pricing by Group": "グループ別価格設定",
     "Pricing Configuration": "価格設定",
+    "Pricing group example": "料金グループの例",
+    "Pricing groups": "料金グループ",
     "Pricing mode": "価格モード",
     "Pricing Ratios": "価格比率",
     "Pricing Type": "価格タイプ",
@@ -2943,8 +3006,6 @@
     "Provide Markdown, HTML, or an external URL for the user agreement": "ユーザー同意書にMarkdown、HTML、または外部URLを提供する",
     "Provide per-category safety overrides as JSON. Use `default` for fallback values.": "カテゴリごとの安全オーバーライドをJSONとして提供します。フォールバック値には`default`を使用してください。",
     "Provide per-model header overrides as JSON. Useful for enabling beta features such as expanded context windows.": "モデルごとのヘッダーオーバーライドをJSONとして提供します。拡張コンテキストウィンドウなどのベータ機能を有効にするのに役立ちます。",
-    "Public model catalog and pricing page.": "モデルカタログと料金の公開ページ。",
-    "Public rankings page based on live usage data.": "実際の利用データに基づく公開ランキングページ。",
     "Provider": "プロバイダ",
     "Provider & data privacy": "プロバイダーとデータ保護",
     "Provider created successfully": "プロバイダーの作成に成功しました",
@@ -2957,6 +3018,8 @@
     "Prune Object Items": "オブジェクト項目を整理",
     "Prune object items by conditions": "条件に基づいてオブジェクト項目を削除",
     "Prune Rule (string or JSON object)": "削除ルール(文字列またはJSONオブジェクト)",
+    "Public model catalog and pricing page.": "モデルカタログと料金の公開ページ。",
+    "Public rankings page based on live usage data.": "実際の利用データに基づく公開ランキングページ。",
     "Publish Date": "公開日",
     "Published": "公開済み",
     "Published:": "公開済み:",
@@ -3171,6 +3234,7 @@
     "Resend ({{seconds}}s)": "再送信 ({{seconds}}秒)",
     "Reset": "リセット",
     "Reset 2FA": "2FAをリセット",
+    "Reset all model prices?": "すべてのモデル価格をリセットしますか?",
     "Reset all model ratios?": "すべてのモデル比率をリセットしますか?",
     "Reset all settings to default values": "すべての設定をデフォルト値にリセット",
     "Reset at:": "リセット日時:",
@@ -3181,6 +3245,7 @@
     "Reset Passkey": "Passkeyリセット",
     "Reset password": "パスワードをリセット",
     "Reset Period": "リセット期間",
+    "Reset prices": "価格をリセット",
     "Reset ratios": "比率をリセット",
     "Reset Stats": "統計をリセット",
     "Reset to default": "デフォルトにリセット",
@@ -3272,12 +3337,14 @@
     "Save group ratios": "グループ比率を保存",
     "Save io.net settings": "io.net設定を保存",
     "Save log settings": "ログ設定を保存",
+    "Save model prices": "モデル価格を保存",
     "Save model ratios": "モデル比率を保存",
     "Save Models": "モデルを保存",
     "Save monitoring rules": "監視ルールを保存",
     "Save navigation": "ナビゲーションを保存",
     "Save notice": "通知を保存",
     "Save Preferences": "設定を保存",
+    "Save preview": "保存プレビュー",
     "Save rate limits": "レート制限を保存",
     "Save sensitive words": "敏感な言葉を保存",
     "Save Settings": "設定を保存",
@@ -3340,6 +3407,7 @@
     "Select a color": "色を選択",
     "Select a group": "グループを選択",
     "Select a group type": "グループタイプを選択",
+    "Select a model to edit pricing": "料金を編集するモデルを選択",
     "Select a preset...": "プリセットを選択...",
     "Select a role": "ロールを選択",
     "Select a rule to edit.": "編集するルールを選択してください。",
@@ -3353,6 +3421,7 @@
     "Select an operation mode and enter the amount": "操作モードを選択し、金額を入力してください",
     "Select announcement type": "アナウンスメントタイプを選択",
     "Select at least one field to overwrite.": "上書きするフィールドを少なくとも 1 つ選択してください。",
+    "Select at least one target model": "少なくとも1つの対象モデルを選択してください",
     "Select border radius": "角丸を選択",
     "Select channel type": "チャネルタイプを選択",
     "Select color preset": "カラープリセットを選択",
@@ -3406,6 +3475,7 @@
     "selected": "選択済み",
     "selected channel(s). Leave empty to remove tag.": "選択されたチャンネル。タグを削除するには空のままにしてください。",
     "Selected conflicts were overwritten successfully.": "選択した競合が正常に上書きされました。",
+    "Selected when creating a token and used as the default billing group for API calls.": "トークン作成時に選択され、API 呼び出しのデフォルト課金グループとして使われます。",
     "Self-Use Mode": "セルフユースモード",
     "Send": "送信",
     "Send code": "コードを送信",
@@ -3413,6 +3483,7 @@
     "Sending...": "送信中...",
     "Sensitive Words": "機密語",
     "Sent the API key to FluentRead.": "API キーを FluentRead に送信しました。",
+    "Separate image/audio prices are enabled.": "画像/音声の個別価格が有効です。",
     "Serve multiple users or teams with billing and quota control.": "課金とクォータ管理で複数のユーザーやチームにサービスを提供します。",
     "Server Address": "サーバーURL",
     "Server IP": "サーバー IP",
@@ -3436,6 +3507,7 @@
     "Set quota amount and limits": "クォータ量と制限を設定",
     "Set Request Header": "リクエストヘッダーを設定",
     "Set runtime request header: override entire value, or manipulate comma-separated tokens": "ランタイムリクエストヘッダーを設定:値全体を上書き、またはカンマ区切りトークンを操作",
+    "Set separate prices for cache reads and writes.": "キャッシュ読み取りと書き込みに個別価格を設定します。",
     "Set Tag": "タグを設定",
     "Set tag for selected channels": "選択したチャネルにタグを設定",
     "Set the language used across the interface": "インターフェースで使用する言語を設定します",
@@ -3513,10 +3585,14 @@
     "Space-separated OAuth scopes": "スペース区切りのOAuthスコープ",
     "Spark model version, e.g., v2.1 (version number in API URL)": "Sparkモデルバージョン(例:v2.1、API URLのバージョン番号)",
     "Special billing expression": "特殊な課金式",
+    "Special group": "特別グループ",
+    "Special ratios override the token group ratio for specific user group and token group combinations.": "特殊倍率は、特定のユーザーグループとトークングループの組み合わせでトークングループ倍率を上書きします。",
     "Special usable group rules": "特別な使用可能グループルール",
+    "Special usable group rules can add, remove, or append selectable token groups for a specific user group.": "特殊利用可能グループルールでは、特定ユーザーグループ向けに選択可能なトークングループを追加、削除、追記できます。",
     "SQLite stores all data in a single file. Make sure that file is persisted when running in containers.": "SQLite はすべてのデータを単一ファイルに保存します。コンテナで実行する場合は、ファイルが永続化されていることを確認してください。",
     "SSRF Protection": "SSRF保護",
     "Standard": "標準",
+    "Standard price": "標準価格",
     "Start": "開始",
     "Start a conversation to see messages here": "会話を開始すると、ここにメッセージが表示されます",
     "Start for free with generous limits. No credit card required.": "豊富な無料枠で始められます。クレジットカードは不要です。",
@@ -3731,12 +3807,15 @@
     "This may cause cache failures.": "これによりキャッシュ障害が発生する可能性があります。",
     "This may take a few moments while we validate the request and update your session.": "リクエストを検証し、セッションを更新するのに数分かかる場合があります。",
     "This model has both fixed price and ratio billing conflicts": "このモデルには固定価格と比率請求の両方の競合があります",
+    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "このモデルには固定価格と比率設定の両方があります。現在のモードで保存すると、競合するフィールドが上書きされます。",
+    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "このモデルには固定価格とトークン価格設定の両方があります。現在のモードで保存すると、競合するフィールドが上書きされます。",
     "This model is not available in any group, or no group pricing information is configured.": "このモデルはどのグループでも利用できないか、グループの料金情報が設定されていません。",
     "This month": "今月",
     "This page has not been created yet.": "このページはまだ作成されていません。",
     "This project must be used in compliance with the": "このプロジェクトは、以下を遵守して使用する必要があります",
     "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "古いバージョンのインスタンスがこの記録を書き込み、監査情報がありません。最新に更新し、サーバーIP・コールバックIP・支払方法・OSバージョンの記録を有効にしてください。",
     "This site currently has {{count}} models enabled": "このサイトでは現在 {{count}} 個のモデルが有効です",
+    "This tier catches any request that did not match earlier tiers.": "この階層は、前の階層に一致しなかったすべてのリクエストを受けます。",
     "this token group": "このトークングループ",
     "this user group": "このユーザーグループ",
     "This user has no bindings": "このユーザーには連携がありません",
@@ -3758,19 +3837,20 @@
     "Throughput by group": "グループ別スループット",
     "Throughput trend": "スループット推移",
     "Tier": "ティア",
+    "Tier conditions": "階層条件",
     "Tier name": "ティア名",
     "Tiered": "段階的",
-    "Token prices": "Token prices",
-    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Tiered (billing expression)": "段階的(課金式)",
     "Tiered price table": "段階別価格表",
+    "Tiered pricing": "階層料金",
+    "tiers": "階層",
     "Time": "時間",
     "Time Granularity": "時間の粒度",
     "Time remaining": "残り時間",
     "Time window for rate limiting": "レート制限の時間枠",
     "Time-based": "時間条件あり",
-    "Time:": "時間:",
     "Time-sliced cache (Claude)": "時間分割キャッシュ(Claude)",
+    "Time:": "時間:",
     "Timeline": "タイムライン",
     "times": "回",
     "Timing": "所要時間",
@@ -3794,11 +3874,18 @@
     "Token Endpoint": "トークンエンドポイント",
     "Token Endpoint (Optional)": "トークンエンドポイント (オプション)",
     "Token estimator": "トークン見積り",
+    "Token group": "トークングループ",
     "Token management": "トークン管理",
     "Token Management": "トークン管理",
     "Token Mgmt": "トークン管理",
     "Token Name": "トークン名",
     "Token obtained from your Gotify application": "Gotifyアプリケーションから取得したトークン",
+    "Token price for audio input.": "音声入力のトークン価格。",
+    "Token price for audio output.": "音声出力のトークン価格。",
+    "Token price for cache reads.": "キャッシュ読み取りのトークン価格。",
+    "Token price for creating cache entries.": "キャッシュ作成のトークン価格。",
+    "Token price for image input.": "画像入力のトークン価格。",
+    "Token prices": "Token prices",
     "Token regenerated and copied to clipboard": "トークンが再生成され、クリップボードにコピーされました",
     "Token share by model author across the last 24 hours": "過去 24 時間におけるモデル提供者別のトークンシェア",
     "Token share by model author across the past few weeks": "過去数週間におけるモデル提供者別のトークンシェア",
@@ -3922,6 +4009,7 @@
     "Unbind failed": "連携解除に失敗しました",
     "Unbound {{provider}}": "{{provider}}の連携を解除しました",
     "Underground": "アンダーグラウンド",
+    "Understand how user groups, token groups, ratios, and special rules work together.": "ユーザーグループ、トークングループ、倍率、特殊ルールがどのように連携するかを理解します。",
     "Understand image inputs alongside text": "テキストとともに画像入力を理解",
     "Unexpected release payload": "予期しないリリースデータ",
     "Unified API Gateway for": "統合APIゲートウェイ -",
@@ -3935,6 +4023,7 @@
     "Unlimited": "無制限",
     "Unlimited Quota": "無制限のクォータ",
     "Unsaved changes": "未保存の変更",
+    "Unset price": "価格未設定",
     "Until": "まで",
     "Untitled": "無題",
     "Untrusted upstream data:": "信頼されていないアップストリームデータ:",
@@ -3999,12 +4088,16 @@
     "URL is required": "URL は必須です",
     "URL to your logo image (optional)": "ロゴ画像のURL (オプション)",
     "Usage": "使用量",
+    "Usage guide": "使用ガイド",
     "Usage logs": "使用ログ",
     "Usage Logs": "利用履歴",
     "Usage mode": "利用モード",
     "Usage-based": "使用量ベース",
     "USD": "USD",
     "USD Exchange Rate": "USD 為替レート",
+    "USD price per 1M input tokens.": "100万入力トークンあたりのUSD価格。",
+    "USD price per 1M tokens.": "100万トークンあたりのUSD価格。",
+    "Use +: to add a group, -: to remove a default selectable group, or no prefix to append a group.": "+: はグループ追加、-: はデフォルト選択可能グループの削除、接頭辞なしはグループ追記に使います。",
     "Use a compatible browser or device with biometric authentication or a security key to register a Passkey.": "生体認証またはセキュリティキーを備えた互換性のあるブラウザまたはデバイスを使用して、パスキーを登録してください。",
     "Use authenticator code": "認証コードを使用",
     "Use backup code": "バックアップコードを使用",
@@ -4014,6 +4107,8 @@
     "Use Passkey to sign in without entering your password.": "パスワードを入力せずにサインインするには、パスキーを使用してください。",
     "Use secure connection when sending emails": "メール送信時に安全な接続を使用する",
     "Use sidebar shortcut": "サイドバーのショートカットを使用",
+    "Use the full-width table to scan prices, then select a row to edit it here.": "表で価格を確認し、行を選択してここで編集します。",
+    "Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.": "料金グループ表で倍率と、トークン作成ドロップダウンに表示するかどうかを管理します。",
     "Use this token for API authentication": "API認証にはこのトークンを使用してください",
     "Use your Passkey": "パスキーを使用",
     "used": "使用済み",
@@ -4034,6 +4129,7 @@
     "User created successfully": "ユーザーの作成に成功しました",
     "User dashboard and quota controls.": "ユーザーダッシュボードとクォータ制御。",
     "User Exclusive Ratio": "専用倍率",
+    "User group": "ユーザーグループ",
     "User Group": "ユーザーグループ",
     "User group name": "ユーザーグループ名",
     "User Group: {{ratio}}x": "ユーザーグループ:{{ratio}}x",
@@ -4047,6 +4143,7 @@
     "User Information": "ユーザー情報",
     "User Menu": "ユーザーメニュー",
     "User personal functions": "ユーザー個人機能",
+    "User selectable": "ユーザー選択可",
     "User Subscription Management": "ユーザーサブスクリプション管理",
     "User updated successfully": "ユーザーの更新に成功しました",
     "User Verification": "ユーザー認証",
@@ -4058,6 +4155,7 @@
     "Users": "ユーザー",
     "Users call the model on the left. The platform forwards the request to the upstream model on the right.": "ユーザーは左側のモデルを呼び出します。プラットフォームはリクエストを右側のアップストリームモデルに転送します。",
     "Users must wait for a successful drawing before upscales or variations.": "アップスケールやバリエーションを行う前に、ユーザーは成功した描画を待つ必要があります。",
+    "Users only see groups marked as user selectable. Non-selectable groups can still be assigned by administrators.": "ユーザーにはユーザー選択可のグループだけが表示されます。選択不可グループも管理者は割り当てできます。",
     "uses": "使用回数",
     "Validity": "有効期間",
     "Validity Period": "有効期間",
@@ -4188,6 +4286,7 @@
     "Well-Known URL": "よく知られたURL",
     "Well-Known URL must start with http:// or https://": "Well-Known URL は http:// または https:// で始まる必要があります",
     "What would you like to know?": "何を知りたいですか?",
+    "When a token uses the auto group, the system tries groups from top to bottom until it finds an available group.": "トークンが auto グループを使用すると、システムは上から順に利用可能なグループを探します。",
     "When conditions match, the final price is multiplied by X. Multiple matches multiply together; values < 1 act as discounts.": "条件に一致したとき、最終価格に X を掛けます。複数一致は掛け合わさり、1 未満は割引として効きます。",
     "When enabled, if channels in the current group fail, it will try channels in the next group in order.": "有効にすると、現在のグループのチャンネルが失敗した場合、次のグループのチャンネルを順番に試します。",
     "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. SSD recommended.": "有効にすると、大きなリクエストボディはメモリではなくディスクに一時保存され、メモリ使用量が大幅に削減されます。SSD環境での使用を推奨します。",
@@ -4195,6 +4294,7 @@
     "When enabled, newly created tokens start in the first auto group.": "有効にすると、新しく作成されたトークンは最初の自動グループで開始されます。",
     "When enabled, prompts are scanned before reaching upstream models.": "有効にすると、プロンプトはアップストリームモデルに到達する前にスキャンされます。",
     "When enabled, the store field will be blocked": "有効にすると、ストアフィールドはブロックされます",
+    "When enabled, users can pick this group when creating tokens.": "有効にすると、ユーザーはトークン作成時にこのグループを選択できます。",
     "When enabled, violation requests will incur additional charges.": "有効にすると、違反リクエストに追加料金が発生します。",
     "When enabled, zero-cost models also pre-consume quota before final settlement.": "有効にすると、ゼロコストモデルも最終決済前にクォータを事前消費します。",
     "When no conditions are set, the operation always executes.": "条件が設定されていない場合、操作は常に実行されます。",
@@ -4249,71 +4349,6 @@
     "Zero retention": "データ保持なし",
     "Zhipu": "Zhipu",
     "Zhipu V4": "Zhipu V 4",
-    "Zoom": "ズーム",
-    "Add model pricing": "モデル料金を追加",
-    "Applied {{name}} pricing to {{count}} models": "{{name}} の料金を {{count}} 個のモデルに適用しました",
-    "Audio input price": "音声入力価格",
-    "Audio output price": "音声出力価格",
-    "Audio output price requires an audio input price.": "音声出力価格には音声入力価格が必要です。",
-    "Billable input tokens": "課金対象の入力トークン",
-    "Billable output tokens": "課金対象の出力トークン",
-    "Cache create (1h) price": "キャッシュ作成価格 (1時間)",
-    "Cache create price": "キャッシュ作成価格",
-    "Cache read price": "キャッシュ読み取り価格",
-    "Cache pricing": "キャッシュ価格",
-    "Cache write price": "キャッシュ書き込み価格",
-    "Changes are written to the settings draft on save.": "保存すると変更は設定ドラフトに書き込まれます。",
-    "Clean": "問題なし",
-    "Completion price": "補完価格",
-    "Core pricing": "基本価格",
-    "Copy {{name}} pricing": "{{name}} の料金をコピー",
-    "Disabled lanes are omitted on save.": "無効な価格レーンは保存時に省略されます。",
-    "Edit model pricing": "モデル料金を編集",
-    "Empty": "空",
-    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "各階層は最大2つの条件をサポートします。最後の階層は条件なしのフォールバックです。キャッシュヒットで課金対象の入力トークンが減っても誤った階層にならないよう、条件には完全な入力長を使用してください。",
-    "All conditions must match before this tier is used.": "この階層を使用するには、すべての条件に一致する必要があります。",
-    "Base input and output token prices for this tier.": "この階層の基本入力・出力トークン価格。",
-    "Expression": "式",
-    "Fallback tier": "フォールバック階層",
-    "Full input length": "完全な入力長",
-    "Input price is required before saving dependent prices.": "依存する価格を保存する前に入力価格が必要です。",
-    "Image input price": "画像入力価格",
-    "Image output price": "画像出力価格",
-    "Media pricing": "メディア価格",
-    "New model": "新しいモデル",
-    "No separate media pricing configured.": "個別のメディア価格は設定されていません。",
-    "Open a source model first": "先にソースモデルを開いてください",
-    "Output token price for generated tokens.": "生成された出力トークンの価格。",
-    "Per-request": "リクエスト単位",
-    "Save preview": "保存プレビュー",
-    "Select at least one target model": "少なくとも1つの対象モデルを選択してください",
-    "Separate image/audio prices are enabled.": "画像/音声の個別価格が有効です。",
-    "Set separate prices for cache reads and writes.": "キャッシュ読み取りと書き込みに個別価格を設定します。",
-    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "このモデルには固定価格と比率設定の両方があります。現在のモードで保存すると、競合するフィールドが上書きされます。",
-    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "このモデルには固定価格とトークン価格設定の両方があります。現在のモードで保存すると、競合するフィールドが上書きされます。",
-    "This tier catches any request that did not match earlier tiers.": "この階層は、前の階層に一致しなかったすべてのリクエストを受けます。",
-    "Tier conditions": "階層条件",
-    "Token price for audio input.": "音声入力のトークン価格。",
-    "Token price for audio output.": "音声出力のトークン価格。",
-    "Token price for cache reads.": "キャッシュ読み取りのトークン価格。",
-    "Token price for creating cache entries.": "キャッシュ作成のトークン価格。",
-    "Token price for image input.": "画像入力のトークン価格。",
-    "USD price per 1M input tokens.": "100万入力トークンあたりのUSD価格。",
-    "USD price per 1M tokens.": "100万トークンあたりのUSD価格。",
-    "{{count}} selected targets available for bulk copy.": "一括コピーに使用できる対象が {{count}} 個選択されています。",
-    "Base input price only": "基本入力価格のみ",
-    "Expression based": "式ベース",
-    "Expression pricing": "式による料金",
-    "Fixed request price": "固定リクエスト価格",
-    "Includes request rules": "リクエストルールを含む",
-    "No base input price": "基本入力価格なし",
-    "No models configured. Use Add model to get started.": "モデルが設定されていません。モデルを追加して開始してください。",
-    "Price summary": "価格概要",
-    "Select a model to edit pricing": "料金を編集するモデルを選択",
-    "Tiered pricing": "階層料金",
-    "Unset price": "価格未設定",
-    "Use the full-width table to scan prices, then select a row to edit it here.": "表で価格を確認し、行を選択してここで編集します。",
-    "extras": "追加項目",
-    "tiers": "階層"
+    "Zoom": "ズーム"
   }
 }

+ 112 - 77
web/default/src/i18n/locales/ru.json

@@ -38,6 +38,7 @@
     "{{count}} models": "моделей: {{count}}",
     "{{count}} months ago": "{{count}} месяцев назад",
     "{{count}} override": "{{count}} переопределений",
+    "{{count}} selected targets available for bulk copy.": "Для массового копирования выбрано целей: {{count}}.",
     "{{count}} tiers": "{{count}} уровней",
     "{{count}} vendors": "поставщиков: {{count}}",
     "{{count}} weeks ago": "{{count}} недель назад",
@@ -96,6 +97,7 @@
     "7 Days": "7 дней",
     "7 days ago": "7 дней назад",
     "80,443,8080": "80,443,8080",
+    "A billing multiplier. Lower ratios mean lower API call costs.": "Множитель тарификации. Чем ниже коэффициент, тем ниже стоимость вызовов API.",
     "About": "О проекте",
     "Accept Unpriced Models": "Принимать модели без цены",
     "Accepts a JSON array of model identifiers that support the Imagine API.": "Принимает JSON-массив идентификаторов моделей, поддерживающих Imagine API.",
@@ -158,6 +160,7 @@
     "Add Mode": "Добавить режим",
     "Add model": "Добавить модель",
     "Add Model": "Добавить модель",
+    "Add model pricing": "Добавить тариф модели",
     "Add Models": "Добавить модели",
     "Add new amount": "Добавить новую сумму",
     "Add new redemption code(s) by providing necessary info.": "Добавьте новый(-ые) код(-ы) активации, предоставив необходимую информацию.",
@@ -236,6 +239,7 @@
     "Ali": "Ali",
     "All": "Все",
     "All categories": "Все категории",
+    "All conditions must match before this tier is used.": "All conditions must match before this tier is used.",
     "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "Все изменения являются операциями перезаписи. Оставьте поля пустыми, чтобы сохранить текущие значения без изменений.",
     "All files exceed the maximum size.": "Все файлы превышают максимальный размер.",
     "All Groups": "Все группы",
@@ -354,6 +358,7 @@
     "Append value to array / string / object end": "Добавить значение в конец массива / строки / объекта",
     "appended": "добавлено",
     "Application": "Приложение",
+    "Applied {{name}} pricing to {{count}} models": "Тариф {{name}} применён к {{count}} моделям",
     "Applies to custom completion endpoints. JSON map of model → ratio.": "Применяется к пользовательским конечным точкам завершения. JSON-карта модель → коэффициент.",
     "Apply All Upstream Updates": "Применить все обновления из upstream",
     "Apply Filters": "Применить фильтры",
@@ -383,6 +388,8 @@
     "Array of chat client presets. Each item is an object with one key-value pair: client name and its URL.": "Массив предустановок чат-клиентов. Каждый элемент представляет собой объект с одной парой ключ-значение: имя клиента и его URL.",
     "Asc": "По возрастанию",
     "Ask anything": "Спросите что угодно",
+    "Assigned by administrator only": "Назначается только администратором",
+    "Assigned by administrators and used to represent a user level, such as default or vip.": "Назначается администраторами и обозначает уровень пользователя, например default или vip.",
     "Async task refund": "Возврат асинхронной задачи",
     "At least one model regex pattern is required": "Требуется хотя бы один шаблон регулярного выражения модели",
     "At least one valid key source is required": "Требуется хотя бы один действительный источник ключа",
@@ -393,10 +400,13 @@
     "Audio In": "Аудиовход",
     "Audio input": "Аудиовход",
     "Audio Input": "Аудио вход",
+    "Audio input price": "Цена аудиовхода",
     "Audio Input Price": "Цена аудиовхода",
     "Audio Out": "Аудиовыход",
     "Audio output": "Аудиовыход",
     "Audio Output": "Аудио выход",
+    "Audio output price": "Цена аудиовыхода",
+    "Audio output price requires an audio input price.": "Для цены аудиовыхода нужна цена аудиовхода.",
     "Audio playback failed": "Ошибка воспроизведения аудио",
     "Audio Preview": "Предпросмотр аудио",
     "Audio ratio": "Коэффициент аудио",
@@ -413,6 +423,7 @@
     "Auto Ban": "Автоматическая блокировка",
     "Auto detect (default)": "Автоматическое определение (по умолчанию)",
     "Auto Disabled": "Автоматически отключено",
+    "Auto group behavior": "Поведение группы auto",
     "Auto Group Chain": "Автоматическая цепочка групп",
     "Auto refresh": "Автообновление",
     "Auto Sync Upstream Models": "Автоматическая синхронизация моделей провайдера",
@@ -469,6 +480,8 @@
     "Bark Push URL": "URL для push-уведомлений Bark",
     "Base address provided by your Epay service": "Базовый адрес, предоставленный вашим сервисом Epay",
     "Base amount. Actual deduction = base amount × system group rate.": "Базовая сумма. Фактический вычет = базовая сумма × коэффициент группы.",
+    "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
+    "Base input price only": "Только базовая цена входа",
     "Base Limits": "Базовые лимиты",
     "Base multipliers applied when users select specific groups.": "Базовые множители, применяемые, когда пользователи выбирают определенные группы.",
     "Base Price": "Базовая цена",
@@ -493,6 +506,8 @@
     "Batch upstream model updates applied: {{channels}} channels, {{added}} added, {{removed}} removed, {{fails}} failed": "Пакетное обновление моделей: {{channels}} каналов, {{added}} добавлено, {{removed}} удалено, {{fails}} ошибок",
     "Best for single-tenant deployments. Pricing and billing options stay hidden.": "Лучший вариант для однопользовательских развёртываний. Опции ценообразования и биллинга будут скрыты.",
     "Best TTFT": "Лучший TTFT",
+    "Billable input tokens": "Оплачиваемые входные токены",
+    "Billable output tokens": "Оплачиваемые выходные токены",
     "Billing": "Биллинг",
     "Billing & Payment": "Биллинг и платежи",
     "Billing currency": "Валюта оплаты",
@@ -545,6 +560,8 @@
     "By category": "По категориям",
     "By model author": "По автору модели",
     "Cache": "Кэш",
+    "Cache create (1h) price": "Цена создания кэша (1 ч)",
+    "Cache create price": "Цена создания кэша",
     "Cache Creation": "Создание кэша",
     "Cache Creation (1h)": "Создание кэша (1h)",
     "Cache Creation (5m)": "Создание кэша (5m)",
@@ -553,13 +570,16 @@
     "Cache Directory Info": "Информация о каталоге кэша",
     "Cache Entries": "Записи кэша",
     "Cache mode": "Режим кэша",
+    "Cache pricing": "Cache pricing",
     "Cache ratio": "Коэффициент кэша",
     "Cache Read": "Чтение кэша",
+    "Cache read price": "Цена чтения кэша",
     "Cache repeated prompt prefixes for cheaper, faster reuse": "Кэшировать повторяющиеся префиксы промптов для дешёвого и быстрого повторного использования",
     "Cache write": "Запись кэша",
     "Cache Write": "Запись в кэш",
     "Cache Write (1h)": "Запись кэша (1h)",
     "Cache Write (5m)": "Запись кэша (5m)",
+    "Cache write price": "Цена записи кэша",
     "Cached": "Кэш",
     "Cached input": "Кэшированный ввод",
     "Calculated price: ${{price}} per 1M tokens": "Расчётная цена: ${{price}} за 1М токенов",
@@ -592,6 +612,7 @@
     "Change language": "Изменить язык",
     "Change Password": "Изменить пароль",
     "Change To": "Изменить на",
+    "Changes are written to the settings draft on save.": "Изменения будут записаны в черновик настроек при сохранении.",
     "Changing...": "Изменение...",
     "Channel": "Канал",
     "Channel Affinity": "Привязка к каналу",
@@ -663,6 +684,7 @@
     "Classic (Legacy Frontend)": "Классический (Старый интерфейс)",
     "Claude": "Клод",
     "Claude CLI Header Passthrough": "Проброс заголовков Claude CLI",
+    "Clean": "Без конфликта",
     "Clean history logs": "Очистить журналы истории",
     "Clean logs": "Очистить логи",
     "Clean up inactive cache": "Очистить неактивный кэш",
@@ -755,6 +777,7 @@
     "Complete these steps to finish the initial installation.": "Выполните эти шаги, чтобы завершить начальную установку.",
     "Completed": "Завершено",
     "Completion": "Вывод",
+    "Completion price": "Цена завершения",
     "Completion price ($/1M tokens)": "Цена завершения ($/1 млн токенов)",
     "Completion ratio": "Коэффициент завершения",
     "Concatenate channel system prompt with user&apos;s prompt": "Объединить системный промпт канала с промптом пользователя",
@@ -894,6 +917,7 @@
     "Copied: {{model}}": "Скопировано: {{model}}",
     "Copied!": "Скопировано!",
     "Copy": "Копировать",
+    "Copy {{name}} pricing": "Копировать тариф {{name}}",
     "Copy a request header": "Копировать заголовок запроса",
     "Copy All": "Скопировать все",
     "Copy all backup codes": "Скопировать все резервные коды",
@@ -924,8 +948,10 @@
     "Copy token": "Копировать токен",
     "Copy URL": "Скопировать URL",
     "Copywriting, ad creative, SEO": "Копирайтинг, рекламные креативы, SEO",
+    "Core concepts": "Основные понятия",
     "Core Configuration": "Основная конфигурация",
     "Core Features": "Основные функции",
+    "Core pricing": "Core pricing",
     "Cost": "Стоимость",
     "Cost in USD per request, regardless of tokens used.": "Стоимость в долларах США за запрос, независимо от использованных токенов.",
     "Cost Tracking": "Отслеживание затрат",
@@ -1148,6 +1174,7 @@
     "disabled": "отключено",
     "Disabled": "Отключено",
     "Disabled all channels with tag: {{tag}}": "Все каналы с тегом {{tag}} отключены",
+    "Disabled lanes are omitted on save.": "Отключённые каналы цен не сохраняются.",
     "Disabled Reason": "Причина отключения",
     "Disabled Time": "Время отключения",
     "Disabling...": "Отключение...",
@@ -1206,6 +1233,7 @@
     "Drawing Logs": "Журнал рисования",
     "Drawing task records": "Записи задач рисования",
     "Duplicate": "Дублировать",
+    "Duplicate group names: {{names}}": "Повторяющиеся имена групп: {{names}}",
     "Duration": "Длительность",
     "Duration (hours)": "Длительность (часы)",
     "Duration Settings": "Настройки срока действия",
@@ -1257,12 +1285,15 @@
     "Each item must have exactly one key-value pair.": "Каждый элемент должен иметь ровно одну пару ключ-значение.",
     "Each line represents one keyword. Leave blank to disable the list but keep the switch states.": "Каждая строка представляет одно ключевое слово. Оставьте пустым, чтобы отключить список, но сохранить состояния переключателей.",
     "Each tier supports 0~2 conditions (over len, p, c); the last tier is the catch-all without conditions. Use len (full input length, including cache hits) for tier conditions to avoid mis-routing when cache hits reduce p.": "Каждый уровень поддерживает 0–2 условия (по len, p, c); последний уровень — резервный, без условий. Используйте len (полная длина ввода, включая попадания в кэш) для условий уровня, чтобы избежать ошибочной маршрутизации, когда попадания в кэш уменьшают p.",
+    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "Каждый уровень поддерживает до 2 условий; последний уровень является резервным и не содержит условий. Используйте полную длину входа для условий уровня, чтобы кэш-попадания не снижали оплачиваемые входные токены и не приводили к неверному маршруту.",
+    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Earn rewards when your referrals add funds. Transfer accumulated rewards to your balance anytime.": "Получайте вознаграждения, когда ваши рефералы пополняют счет. Переводите накопленные вознаграждения на свой баланс в любое время.",
     "Edit": "Редактировать",
     "Edit {{title}}": "Редактировать {{title}}",
     "Edit all channels with tag:": "Редактировать все каналы с тегом:",
     "Edit Announcement": "Редактировать объявление",
     "Edit API Shortcut": "Редактировать ярлык API",
+    "Edit billing ratios and user-selectable groups in one table.": "Редактируйте коэффициенты тарификации и доступные пользователю группы в одной таблице.",
     "Edit Channel": "Редактировать канал",
     "Edit chat preset": "Редактировать пресет чата",
     "Edit discount tier": "Редактировать уровень скидки",
@@ -1272,6 +1303,7 @@
     "Edit JSON text directly. Format will be validated on save.": "Редактируйте JSON-текст напрямую. Формат будет проверен при сохранении.",
     "Edit model": "Редактировать модель",
     "Edit Model": "Редактировать модель",
+    "Edit model pricing": "Изменить тариф модели",
     "Edit OAuth Provider": "Редактировать поставщика OAuth",
     "Edit payment method": "Редактировать способ оплаты",
     "Edit Prefill Group": "Редактировать группу предзаполнения",
@@ -1297,6 +1329,7 @@
     "Email Verification": "Верификация Email",
     "Email, summarisation, knowledge work": "Электронная почта, резюме, knowledge work",
     "Embeddings": "Встраивания",
+    "Empty": "Пусто",
     "Empty value will be saved as {}.": "Пустое значение будет сохранено как {}.",
     "Enable": "Включить",
     "Enable 2FA": "Включить 2FA",
@@ -1475,9 +1508,12 @@
     "Expose grouped Uptime Kuma status pages directly on the dashboard": "Отображать сгруппированные страницы статуса Uptime Kuma непосредственно на панели управления",
     "Expose ratio API": "Интерфейс экспонирования коэффициента",
     "Exposes the pricing/models catalog in the top navigation.": "Отображает каталог цен/моделей в верхней навигации.",
+    "Expression": "Выражение",
+    "Expression based": "На основе выражения",
     "Expression billing": "Тарификация по выражению",
     "Expression editor": "Редактор выражения",
     "Expression error": "Ошибка выражения",
+    "Expression pricing": "Тарификация выражением",
     "Extend": "Продлить",
     "Extend deployment": "Продлить развертывание",
     "Extend failed": "Не удалось продлить",
@@ -1489,6 +1525,7 @@
     "External Speed Test": "Внешний тест скорости",
     "Extra": "Дополнительно",
     "Extra Notes (Optional)": "Дополнительные примечания (необязательно)",
+    "extras": "доп. пункты",
     "Fail Reason": "Причина сбоя",
     "Fail Reason Details": "Детали причины сбоя",
     "Failed": "Неудача",
@@ -1610,6 +1647,7 @@
     "Failed to update user": "Не удалось обновить пользователя",
     "Failure keywords": "Ключевые слова сбоя",
     "Fair": "Удовлетворительно",
+    "Fallback tier": "Fallback tier",
     "FAQ": "Часто задаваемые вопросы",
     "FAQ added. Click \"Save Settings\" to apply.": "FAQ добавлен. Нажмите \"Сохранить настройки\" чтобы применить.",
     "FAQ deleted. Click \"Save Settings\" to apply.": "FAQ удалён. Нажмите \"Сохранить настройки\" чтобы применить.",
@@ -1679,6 +1717,7 @@
     "Fixed abilities: {{success}} succeeded, {{fails}} failed": "Исправление способностей: {{success}} успешно, {{fails}} неудачно",
     "Fixed price": "Фиксированная цена",
     "Fixed price (USD)": "Фиксированная цена (USD)",
+    "Fixed request price": "Фиксированная цена запроса",
     "Floating": "Плавающая",
     "FluentRead extension not detected. Please ensure it is installed and active.": "Расширение FluentRead не обнаружено. Убедитесь, что оно установлено и активно.",
     "Flush interval (minutes)": "Интервал записи (минуты)",
@@ -1732,6 +1771,7 @@
     "Full API Key": "Полный ключ API",
     "Full Base URL (supports": "Полный базовый URL (поддерживает",
     "Full Code": "Полный код",
+    "Full input length": "Полная длина входа",
     "Full layout": "Полная разметка",
     "Full width": "Полная ширина",
     "Function calling": "Вызов функций",
@@ -1785,10 +1825,10 @@
     "gpt-4": "gpt-4",
     "gpt-4, claude-3-opus, etc.": "gpt-4, claude-3-opus и т. д.",
     "GPU count": "Количество GPU",
-    "Greater Than": "Больше",
-    "Greater Than or Equal": "Больше или равно",
     "Greater than": "Больше",
+    "Greater Than": "Больше",
     "Greater than or equal": "Больше или равно",
+    "Greater Than or Equal": "Больше или равно",
     "Grok": "Grok",
     "Grok Settings": "Настройки Grok",
     "Group": "Группа",
@@ -1797,6 +1837,7 @@
     "Group channels by tag for batch operations": "Группировать каналы по тегу для пакетных операций",
     "Group config overrides global limits, shares the same period": "Конфигурация группы переопределяет глобальные лимиты, использует тот же период",
     "Group deleted. Click \"Save Settings\" to apply.": "Группа удалена. Нажмите \"Сохранить настройки\", чтобы применить.",
+    "Group description": "Описание группы",
     "Group details": "Детали группы",
     "Group identifier": "Идентификатор группы",
     "Group is required": "Группа обязательна",
@@ -1805,6 +1846,7 @@
     "Group name cannot be changed when editing.": "Имя группы нельзя изменить при редактировании.",
     "Group prices cannot be expanded because this expression is not a standard tiered pricing expression.": "Цены по группам нельзя развернуть, потому что это не стандартное выражение тарифов по уровням.",
     "Group Pricing": "Тарификация групп",
+    "Group pricing usage guide": "Руководство по групповой тарификации",
     "group ratio": "коэффициент группы",
     "Group Ratio": "Групповой коэффициент",
     "Group ratios": "Соотношения группы",
@@ -1906,14 +1948,17 @@
     "If an upstream error contains any of these keywords (case insensitive), the channel will be disabled automatically.": "Если ошибка вышестоящего уровня содержит любое из этих ключевых слов (без учета регистра), канал будет автоматически отключен.",
     "If authorization succeeds, the generated JSON will be inserted into the key field. You still need to save the channel to persist it.": "При успешной авторизации сгенерированный JSON будет вставлен в поле ключа. Сохраните канал, чтобы применить изменения.",
     "If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing": "При подключении к upstream One API или проектам-ретрансляторам New API используйте тип OpenAI, если только вы точно знаете, что делаете",
-    "If this keeps happening, please report it on GitHub Issues.": "Если проблема повторяется, сообщите о ней в GitHub Issues.",
+    "If default auto group is enabled, newly created tokens start with auto instead of an empty group.": "Если группа auto включена по умолчанию, новые токены создаются с auto вместо пустой группы.",
     "If the affinity channel fails and retry succeeds on another channel, update affinity to the successful channel.": "Если привязанный канал не работает и повторная попытка удалась через другой канал, привязка обновляется на успешный канал.",
+    "If this keeps happening, please report it on GitHub Issues.": "Если проблема повторяется, сообщите о ней в GitHub Issues.",
     "Ignored upstream models": "Игнорируемые upstream-модели",
     "Image": "Изображение",
     "Image Generation": "Генерация изображений",
     "Image In": "Вход изображения",
     "Image input": "Ввод изображения",
+    "Image input price": "Цена входного изображения",
     "Image Out": "Выход изображения",
+    "Image output price": "Цена выходного изображения",
     "Image Preview": "Предпросмотр изображения",
     "Image ratio": "Коэффициент изображения",
     "Image to Video": "Изображение в видео",
@@ -1927,6 +1972,7 @@
     "Include Group": "Включить группу",
     "Include Model": "Включить модель",
     "Include Rule Name": "Включить имя правила",
+    "Includes request rules": "Включает правила запросов",
     "Including failed requests, 0 = unlimited": "Включая неудачные запросы, 0 = без ограничений",
     "Index": "Индекс",
     "Initial quota given to new users": "Начальная квота, предоставляемая новым пользователям",
@@ -1938,6 +1984,7 @@
     "Input": "Ввод",
     "Input mode": "Режим ввода",
     "Input price": "Цена входа",
+    "Input price is required before saving dependent prices.": "Перед сохранением зависимых цен укажите входную цену.",
     "Input tokens": "Входные токены",
     "Input Tokens": "Входные токены",
     "Inset": "Встроенная",
@@ -2068,10 +2115,10 @@
     "Legacy Format Template": "Шаблон старого формата",
     "Legal": "Юриспруденция",
     "Less": "Меньше",
-    "Less Than": "Меньше",
-    "Less Than or Equal": "Меньше или равно",
     "Less than": "Меньше",
+    "Less Than": "Меньше",
     "Less than or equal": "Меньше или равно",
+    "Less Than or Equal": "Меньше или равно",
     "License": "Лицензия",
     "Light": "Светлая",
     "Lightning Fast": "Молниеносно быстро",
@@ -2188,6 +2235,7 @@
     "Maximum tokens per response": "Максимум токенов на ответ",
     "maxRequests ≥ 0, maxSuccess ≥ 1, both ≤ 2,147,483,647": "maxRequests ≥ 0, maxSuccess ≥ 1, оба ≤ 2,147,483,647",
     "May be used for training by upstream provider": "Может использоваться поставщиком для обучения",
+    "Media pricing": "Media pricing",
     "Median time-to-first-token (TTFT) sampled hourly per group": "Медианная задержка первого токена (TTFT), измеряемая ежечасно по группам",
     "Medical Q&A, mental health support": "Медицинские Q&A, поддержка ментального здоровья",
     "Memory Hits": "Попаданий памяти",
@@ -2255,6 +2303,8 @@
     "Model performance metrics": "Метрики производительности моделей",
     "Model Price": "Цена модели",
     "Model Price Not Configured": "Цена модели не настроена",
+    "Model prices": "Цены моделей",
+    "Model prices reset successfully": "Цены моделей успешно сброшены",
     "Model Pricing": "Тарификация моделей",
     "Model pull failed: {{msg}}": "Ошибка тяги модели: {{msg}}",
     "Model ratio": "Коэффициент модели",
@@ -2365,6 +2415,7 @@
     "New API Project Repository:": "Репозиторий проекта New API:",
     "New Format Template": "Шаблон нового формата",
     "New Group": "Новая группа",
+    "New model": "Новая модель",
     "New Models ({{count}})": "Новые модели ({{count}})",
     "New name will be:": "Новое имя будет:",
     "New password": "Новый пароль",
@@ -2393,6 +2444,7 @@
     "No available models": "Нет доступных моделей",
     "No available Web chat links": "Нет доступных веб-ссылок для чата",
     "No backup": "Нет резервной копии",
+    "No base input price": "Нет базовой цены входа",
     "No billing records found": "Записи о выставлении счетов не найдены",
     "No capabilities reported for this model.": "Для этой модели не указаны возможности.",
     "No Change": "Без изменений",
@@ -2428,6 +2480,7 @@
     "No group found.": "Группа не найдена.",
     "No group-based rate limits configured. Click \"Add group\" to get started.": "Групповые лимиты скорости не настроены. Нажмите \"Добавить группу\", чтобы начать.",
     "No groups match your search": "Нет групп, соответствующих вашему поиску",
+    "No groups yet. Add a group to get started.": "Групп пока нет. Добавьте группу, чтобы начать.",
     "No header overrides configured.": "Нет настроенных переопределений заголовков.",
     "No history data available": "Исторические данные недоступны",
     "No incidents in the last 24 hours": "За последние 24 часа инцидентов не было",
@@ -2449,6 +2502,7 @@
     "No models available": "Модели недоступны",
     "No models available in this category": "В этой категории нет моделей",
     "No models available. Create your first model to get started.": "Нет доступных моделей. Создайте свою первую модель, чтобы начать.",
+    "No models configured. Use Add model to get started.": "Модели не настроены. Используйте добавление модели, чтобы начать.",
     "No models fetched from upstream": "Модели не получены от upstream",
     "No models fetched yet.": "Модели еще не получены.",
     "No models found": "Модели не найдены",
@@ -2493,6 +2547,7 @@
     "No Retry": "Без повтора",
     "No rules yet": "Правила отсутствуют",
     "No rules yet. Add a group below to get started.": "Правил пока нет. Добавьте группу ниже, чтобы начать.",
+    "No separate media pricing configured.": "No separate media pricing configured.",
     "No status code mappings configured.": "Сопоставления кодов состояния не настроены.",
     "No subscription plans yet": "Планов подписки пока нет",
     "No subscription records": "Нет записей подписок",
@@ -2579,6 +2634,7 @@
     "Online topup is not enabled. Please use redemption code or contact administrator.": "Онлайн-пополнение не включено. Пожалуйста, используйте код активации или свяжитесь с администратором.",
     "Only allow specific email domains": "Разрешить только определенные домены электронной почты",
     "Only available for admins. When enabled, you will receive a summary notification via your selected method when the scheduled model check detects upstream model changes or check failures.": "Доступно только для администраторов. При включении вы будете получать сводное уведомление выбранным способом, когда запланированная проверка моделей обнаружит изменения в вышестоящих моделях или сбои проверки.",
+    "Only configured combinations are overridden. All other calls keep the token group base ratio.": "Переопределяются только настроенные комбинации. Остальные вызовы используют базовый коэффициент группы токена.",
     "Only selected fields will be overwritten. You can re-run the sync wizard if new conflicts appear.": "Будут перезаписаны только выбранные поля. Вы можете повторно запустить мастер синхронизации, если появятся новые конфликты.",
     "Only successful requests": "Только успешные запросы",
     "Only successful requests count toward this limit.": "Только успешные запросы учитываются в этом лимите.",
@@ -2586,6 +2642,7 @@
     "Oops! Page Not Found!": "Ой! Страница не найдена!",
     "Oops! Something went wrong": "Ой! Что-то пошло не так",
     "Open": "Открыть",
+    "Open a source model first": "Сначала откройте исходную модель",
     "Open authorization page": "Открыть страницу авторизации",
     "Open CC Switch": "Открыть CC Switch",
     "Open in chat": "Открыть в чате",
@@ -2641,9 +2698,11 @@
     "Output aspect ratio": "Соотношение сторон",
     "Output image size": "Размер выходного изображения",
     "Output price": "Цена выхода",
+    "Output token price for generated tokens.": "Цена выходных токенов для сгенерированного текста.",
     "Output tokens": "Выходные токены",
     "Output Tokens": "Выходные токены",
     "overall": "всего",
+    "Overnight range": "Диапазон через полночь",
     "override": "переопределить",
     "Override": "Перезаписать",
     "Override Anthropic headers, defaults, and thinking adapter behavior": "Переопределить заголовки Anthropic, значения по умолчанию и поведение адаптера мышления",
@@ -2656,7 +2715,6 @@
     "Override Rules": "Правила переопределения",
     "Override the endpoint used for testing. Leave empty to auto detect.": "Переопределить конечную точку, используемую для тестирования. Оставьте пустым для автоматического определения.",
     "overrides for matching model prefix.": "переопределяет цену по совпавшему префиксу модели.",
-    "Overnight range": "Диапазон через полночь",
     "Overview": "Обзор",
     "Overwritten": "Перезаписано",
     "Page": "Страница",
@@ -2751,6 +2809,7 @@
     "Per-call": "По вызову",
     "Per-feature metered windows split by model or capability.": "Окна с поминутной тарификацией по фиче, в разбивке по модели или возможностям.",
     "Per-group performance": "Производительность по группам",
+    "Per-request": "За запрос",
     "Per-request (fixed price)": "За запрос (фиксированная цена)",
     "Per-token": "За токен",
     "Per-token (ratio based)": "За токен (на основе соотношения)",
@@ -2854,6 +2913,7 @@
     "Prefix used when displaying prices": "Префикс, используемый при отображении цен",
     "Prefix/Suffix Text": "Текст префикса/суффикса",
     "Premium chat models": "Премиум-модели чата",
+    "Premium plan, half price": "Премиум-план, половина цены",
     "Preparing chat keys…": "Подготовка ключей чата…",
     "Preparing your chat link, please try again in a moment.": "Подготовка вашей ссылки на чат, попробуйте снова через мгновение.",
     "Preparing your chat link…": "Подготовка вашей ссылки для чата…",
@@ -2890,6 +2950,7 @@
     "Price estimation description": "После настройки типа оборудования, места размещения, количества реплик и т.д. стоимость будет рассчитана автоматически.",
     "Price ID": "ID цены",
     "Price mode (USD per 1M tokens)": "Режим ценообразования (USD за 1 млн токенов)",
+    "Price summary": "Сводка цен",
     "price_xxx": "price_xxx",
     "Price:": "Цена:",
     "Price: High to Low": "Цена: от высокой к низкой",
@@ -2901,6 +2962,8 @@
     "Pricing & Display": "Цены и отображение",
     "Pricing by Group": "Ценообразование по группам",
     "Pricing Configuration": "Конфигурация ценообразования",
+    "Pricing group example": "Пример группы тарификации",
+    "Pricing groups": "Группы тарификации",
     "Pricing mode": "Режим ценообразования",
     "Pricing Ratios": "Коэффициенты ценообразования",
     "Pricing Type": "Тип ценообразования",
@@ -2943,8 +3006,6 @@
     "Provide Markdown, HTML, or an external URL for the user agreement": "Укажите Markdown, HTML или внешний URL для пользовательского соглашения",
     "Provide per-category safety overrides as JSON. Use `default` for fallback values.": "Предоставьте переопределения безопасности по категориям в формате JSON. Используйте `default` для резервных значений.",
     "Provide per-model header overrides as JSON. Useful for enabling beta features such as expanded context windows.": "Предоставьте переопределения заголовков для каждой модели в формате JSON. Полезно для включения бета-функций, таких как расширенные окна контекста.",
-    "Public model catalog and pricing page.": "Публичная страница каталога моделей и цен.",
-    "Public rankings page based on live usage data.": "Публичная страница рейтингов на основе реальных данных использования.",
     "Provider": "Провайдер",
     "Provider & data privacy": "Поставщик и конфиденциальность",
     "Provider created successfully": "Поставщик успешно создан",
@@ -2957,6 +3018,8 @@
     "Prune Object Items": "Очистить элементы объекта",
     "Prune object items by conditions": "Удалить элементы объекта по условиям",
     "Prune Rule (string or JSON object)": "Правило очистки (строка или JSON-объект)",
+    "Public model catalog and pricing page.": "Публичная страница каталога моделей и цен.",
+    "Public rankings page based on live usage data.": "Публичная страница рейтингов на основе реальных данных использования.",
     "Publish Date": "Дата публикации",
     "Published": "Опубликовано",
     "Published:": "Опубликовано:",
@@ -3171,6 +3234,7 @@
     "Resend ({{seconds}}s)": "Отправить повторно ({{seconds}}с)",
     "Reset": "Сброс",
     "Reset 2FA": "Сбросить 2FA",
+    "Reset all model prices?": "Сбросить все цены моделей?",
     "Reset all model ratios?": "Сбросить все соотношения моделей?",
     "Reset all settings to default values": "Сбросить все настройки до значений по умолчанию",
     "Reset at:": "Сброс в:",
@@ -3181,6 +3245,7 @@
     "Reset Passkey": "Сброс Passkey",
     "Reset password": "Сбросить пароль",
     "Reset Period": "Период сброса",
+    "Reset prices": "Сбросить цены",
     "Reset ratios": "Сбросить соотношения",
     "Reset Stats": "Сбросить статистику",
     "Reset to default": "Сбросить до значений по умолчанию",
@@ -3272,12 +3337,14 @@
     "Save group ratios": "Сохранить коэффициенты групп",
     "Save io.net settings": "Сохранить настройки io.net",
     "Save log settings": "Сохранить настройки журнала",
+    "Save model prices": "Сохранить цены моделей",
     "Save model ratios": "Сохранить коэффициенты моделей",
     "Save Models": "Сохранить модели",
     "Save monitoring rules": "Сохранить правила мониторинга",
     "Save navigation": "Сохранить навигацию",
     "Save notice": "Сохранить уведомление",
     "Save Preferences": "Сохранить настройки",
+    "Save preview": "Предпросмотр сохранения",
     "Save rate limits": "Сохранить лимиты скорости",
     "Save sensitive words": "Сохранить чувствительные слова",
     "Save Settings": "Сохранить настройки",
@@ -3340,6 +3407,7 @@
     "Select a color": "Выбрать цвет",
     "Select a group": "Выбрать группу",
     "Select a group type": "Выбрать тип группы",
+    "Select a model to edit pricing": "Выберите модель для редактирования тарифа",
     "Select a preset...": "Выберите предустановку...",
     "Select a role": "Выбрать роль",
     "Select a rule to edit.": "Выберите правило для редактирования.",
@@ -3353,6 +3421,7 @@
     "Select an operation mode and enter the amount": "Выберите режим операции и введите сумму",
     "Select announcement type": "Выбрать тип объявления",
     "Select at least one field to overwrite.": "Выберите хотя бы одно поле для перезаписи.",
+    "Select at least one target model": "Выберите хотя бы одну целевую модель",
     "Select border radius": "Выберите радиус скругления",
     "Select channel type": "Выбрать тип канала",
     "Select color preset": "Выберите цветовую предустановку",
@@ -3406,6 +3475,7 @@
     "selected": "выбрано",
     "selected channel(s). Leave empty to remove tag.": "выбранный канал(ы). Оставьте пустым, чтобы удалить тег.",
     "Selected conflicts were overwritten successfully.": "Выбранные конфликты успешно перезаписаны.",
+    "Selected when creating a token and used as the default billing group for API calls.": "Выбирается при создании токена и используется как группа тарификации по умолчанию для вызовов API.",
     "Self-Use Mode": "Режим самоиспользования",
     "Send": "Отправить",
     "Send code": "Отправить код",
@@ -3413,6 +3483,7 @@
     "Sending...": "Отправка...",
     "Sensitive Words": "Чувствительные слова",
     "Sent the API key to FluentRead.": "API-ключ отправлен в FluentRead.",
+    "Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
     "Serve multiple users or teams with billing and quota control.": "Обслуживание нескольких пользователей или команд с управлением биллингом и квотами.",
     "Server Address": "Адрес сервера",
     "Server IP": "IP сервера",
@@ -3436,6 +3507,7 @@
     "Set quota amount and limits": "Настройте квоту и лимиты",
     "Set Request Header": "Установить заголовок запроса",
     "Set runtime request header: override entire value, or manipulate comma-separated tokens": "Установить заголовок запроса: переопределить значение или управлять токенами через запятую",
+    "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
     "Set Tag": "Установить тег",
     "Set tag for selected channels": "Установить тег для выбранных каналов",
     "Set the language used across the interface": "Настроить язык интерфейса",
@@ -3513,10 +3585,14 @@
     "Space-separated OAuth scopes": "Области доступа OAuth, разделенные пробелами",
     "Spark model version, e.g., v2.1 (version number in API URL)": "Версия модели Spark, например, v2.1 (номер версии в URL API)",
     "Special billing expression": "Специальное выражение тарификации",
+    "Special group": "Специальная группа",
+    "Special ratios override the token group ratio for specific user group and token group combinations.": "Специальные коэффициенты переопределяют коэффициент группы токена для конкретных сочетаний группы пользователя и группы токена.",
     "Special usable group rules": "Специальные правила для групп с доступом",
+    "Special usable group rules can add, remove, or append selectable token groups for a specific user group.": "Правила специальных доступных групп могут добавлять, удалять или дополнять выбираемые группы токенов для конкретной группы пользователей.",
     "SQLite stores all data in a single file. Make sure that file is persisted when running in containers.": "SQLite хранит все данные в одном файле. Убедитесь, что файл сохраняется при работе в контейнерах.",
     "SSRF Protection": "Защита от SSRF",
     "Standard": "Стандартный",
+    "Standard price": "Стандартная цена",
     "Start": "Начало",
     "Start a conversation to see messages here": "Начните разговор, чтобы увидеть сообщения здесь",
     "Start for free with generous limits. No credit card required.": "Начните бесплатно с щедрыми лимитами. Кредитная карта не требуется.",
@@ -3731,12 +3807,15 @@
     "This may cause cache failures.": "Это может привести к сбоям кэша.",
     "This may take a few moments while we validate the request and update your session.": "Это может занять несколько мгновений, пока мы проверяем запрос и обновляем вашу сессию.",
     "This model has both fixed price and ratio billing conflicts": "Эта модель имеет конфликты как фиксированной цены, так и пропорциональной тарификации",
+    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "У этой модели одновременно заданы фиксированная цена и коэффициенты. Сохранение текущего режима перезапишет конфликтующие поля.",
+    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "У этой модели одновременно заданы фиксированная цена и цены за токены. Сохранение текущего режима перезапишет конфликтующие поля.",
     "This model is not available in any group, or no group pricing information is configured.": "Эта модель недоступна ни в одной группе, или информация о ценах для групп не настроена.",
     "This month": "В этом месяце",
     "This page has not been created yet.": "Эта страница еще не создана.",
     "This project must be used in compliance with the": "Этот проект должен использоваться в соответствии с",
     "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "Запись создана экземпляром до обновления и не содержит сведений аудита. Обновите экземпляр, чтобы фиксировать IP сервера, IP callback, способ оплаты и версию ОС.",
     "This site currently has {{count}} models enabled": "На этом сайте сейчас включено моделей: {{count}}",
+    "This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
     "this token group": "эта группа токенов",
     "this user group": "эта группа пользователей",
     "This user has no bindings": "У этого пользователя нет привязок",
@@ -3758,19 +3837,20 @@
     "Throughput by group": "Пропускная способность по группам",
     "Throughput trend": "Тренд пропускной способности",
     "Tier": "Уровень",
+    "Tier conditions": "Tier conditions",
     "Tier name": "Название уровня",
     "Tiered": "Ступенчато",
-    "Token prices": "Token prices",
-    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Tiered (billing expression)": "Ступенчато (платёжное выражение)",
     "Tiered price table": "Тариф по уровням",
+    "Tiered pricing": "Многоуровневая тарификация",
+    "tiers": "уровни",
     "Time": "Время",
     "Time Granularity": "Гранулярность времени",
     "Time remaining": "Осталось времени",
     "Time window for rate limiting": "Временное окно для ограничения скорости запросов",
     "Time-based": "Зависит от времени",
-    "Time:": "Время:",
     "Time-sliced cache (Claude)": "Сегментированный кэш (Claude)",
+    "Time:": "Время:",
     "Timeline": "Хронология",
     "times": "раз",
     "Timing": "Время",
@@ -3794,11 +3874,18 @@
     "Token Endpoint": "Конечная точка токена",
     "Token Endpoint (Optional)": "Конечная точка токена (необязательно)",
     "Token estimator": "Оценка токенов",
+    "Token group": "Группа токена",
     "Token management": "Управление токенами",
     "Token Management": "Управление токенами",
     "Token Mgmt": "Управление токенами",
     "Token Name": "Имя токена",
     "Token obtained from your Gotify application": "Токен, полученный из вашего приложения Gotify",
+    "Token price for audio input.": "Цена токенов для аудиовхода.",
+    "Token price for audio output.": "Цена токенов для аудиовыхода.",
+    "Token price for cache reads.": "Цена токенов для чтения кэша.",
+    "Token price for creating cache entries.": "Цена токенов для создания записей кэша.",
+    "Token price for image input.": "Цена токенов для входного изображения.",
+    "Token prices": "Token prices",
     "Token regenerated and copied to clipboard": "Токен перегенерирован и скопирован в буфер обмена",
     "Token share by model author across the last 24 hours": "Доля токенов по автору модели за последние 24 часа",
     "Token share by model author across the past few weeks": "Доля токенов по автору модели за последние недели",
@@ -3922,6 +4009,7 @@
     "Unbind failed": "Не удалось отвязать",
     "Unbound {{provider}}": "{{provider}} отвязан",
     "Underground": "Подземелье",
+    "Understand how user groups, token groups, ratios, and special rules work together.": "Поймите, как вместе работают группы пользователей, группы токенов, коэффициенты и специальные правила.",
     "Understand image inputs alongside text": "Понимать изображения наряду с текстом",
     "Unexpected release payload": "Неожиданный формат данных релиза",
     "Unified API Gateway for": "Единый API-шлюз для",
@@ -3935,6 +4023,7 @@
     "Unlimited": "Без ограничений",
     "Unlimited Quota": "Неограниченная квота",
     "Unsaved changes": "Несохранённые изменения",
+    "Unset price": "Цена не задана",
     "Until": "До",
     "Untitled": "Без названия",
     "Untrusted upstream data:": "Недоверенные вышестоящие данные:",
@@ -3999,12 +4088,16 @@
     "URL is required": "URL обязателен",
     "URL to your logo image (optional)": "URL изображения вашего логотипа (необязательно)",
     "Usage": "Использование",
+    "Usage guide": "Руководство",
     "Usage logs": "Журналы использования",
     "Usage Logs": "Журнал использования",
     "Usage mode": "Режим использования",
     "Usage-based": "На основе использования",
     "USD": "USD",
     "USD Exchange Rate": "Обменный курс USD",
+    "USD price per 1M input tokens.": "Цена в USD за 1 млн входных токенов.",
+    "USD price per 1M tokens.": "Цена в USD за 1 млн токенов.",
+    "Use +: to add a group, -: to remove a default selectable group, or no prefix to append a group.": "Используйте +: для добавления группы, -: для удаления выбираемой по умолчанию группы, без префикса — для добавления в конец.",
     "Use a compatible browser or device with biometric authentication or a security key to register a Passkey.": "Используйте совместимый браузер или устройство с биометрической аутентификацией или ключ безопасности для регистрации ключа доступа.",
     "Use authenticator code": "Использовать код аутентификатора",
     "Use backup code": "Использовать резервный код",
@@ -4014,6 +4107,8 @@
     "Use Passkey to sign in without entering your password.": "Используйте ключ доступа для входа без ввода пароля.",
     "Use secure connection when sending emails": "Использовать безопасное соединение при отправке электронных писем",
     "Use sidebar shortcut": "Использовать ярлык боковой панели",
+    "Use the full-width table to scan prices, then select a row to edit it here.": "Просмотрите цены в таблице, затем выберите строку для редактирования здесь.",
+    "Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.": "Используйте таблицу групп тарификации, чтобы управлять коэффициентом и отображением группы в списке создания токена.",
     "Use this token for API authentication": "Используйте этот токен для аутентификации API",
     "Use your Passkey": "Используйте свой ключ доступа",
     "used": "использовано",
@@ -4034,6 +4129,7 @@
     "User created successfully": "Пользователь успешно создан",
     "User dashboard and quota controls.": "Панель пользователя и управление квотами.",
     "User Exclusive Ratio": "Эксклюзивный коэффициент",
+    "User group": "Группа пользователя",
     "User Group": "Группа пользователей",
     "User group name": "Название группы пользователей",
     "User Group: {{ratio}}x": "Группа пользователя: {{ratio}}x",
@@ -4047,6 +4143,7 @@
     "User Information": "Информация о пользователе",
     "User Menu": "Меню пользователя",
     "User personal functions": "Личные функции пользователя",
+    "User selectable": "Доступно пользователю",
     "User Subscription Management": "Управление подписками пользователя",
     "User updated successfully": "Пользователь успешно обновлен",
     "User Verification": "Проверка пользователя",
@@ -4058,6 +4155,7 @@
     "Users": "Пользователи",
     "Users call the model on the left. The platform forwards the request to the upstream model on the right.": "Пользователи вызывают модель слева. Платформа перенаправляет запрос вышестоящей модели справа.",
     "Users must wait for a successful drawing before upscales or variations.": "Пользователи должны дождаться успешного рисунка перед апскейлом или вариациями.",
+    "Users only see groups marked as user selectable. Non-selectable groups can still be assigned by administrators.": "Пользователи видят только группы, отмеченные как доступные для выбора. Недоступные для выбора группы всё равно могут назначаться администраторами.",
     "uses": "использует",
     "Validity": "Срок действия",
     "Validity Period": "Срок действия",
@@ -4188,6 +4286,7 @@
     "Well-Known URL": "Известный эксперт",
     "Well-Known URL must start with http:// or https://": "Well-Known URL должен начинаться с http:// или https://",
     "What would you like to know?": "Что вы хотели бы узнать?",
+    "When a token uses the auto group, the system tries groups from top to bottom until it finds an available group.": "Когда токен использует группу auto, система перебирает группы сверху вниз, пока не найдёт доступную.",
     "When conditions match, the final price is multiplied by X. Multiple matches multiply together; values < 1 act as discounts.": "При совпадении условий итоговая цена умножается на X. Несколько совпадений умножаются вместе; значения < 1 действуют как скидки.",
     "When enabled, if channels in the current group fail, it will try channels in the next group in order.": "Если включено, при сбое каналов в текущей группе система попробует каналы следующей группы по порядку.",
     "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. SSD recommended.": "При включении большие тела запросов временно сохраняются на диске, что значительно снижает использование памяти. Рекомендуется SSD.",
@@ -4195,6 +4294,7 @@
     "When enabled, newly created tokens start in the first auto group.": "При включении вновь созданные токены начинаются в первой автогруппе.",
     "When enabled, prompts are scanned before reaching upstream models.": "При включении запросы сканируются перед достижением вышестоящих моделей.",
     "When enabled, the store field will be blocked": "Если включено, поле магазина будет заблокировано",
+    "When enabled, users can pick this group when creating tokens.": "Если включено, пользователи могут выбрать эту группу при создании токенов.",
     "When enabled, violation requests will incur additional charges.": "При включении за нарушения будут начисляться дополнительные расходы.",
     "When enabled, zero-cost models also pre-consume quota before final settlement.": "При включении бесплатные модели также предварительно потребляют квоту до окончательного расчета.",
     "When no conditions are set, the operation always executes.": "Без условий операция выполняется всегда.",
@@ -4249,71 +4349,6 @@
     "Zero retention": "Без хранения данных",
     "Zhipu": "Zhipu",
     "Zhipu V4": "Zhipu V4",
-    "Zoom": "Zoom",
-    "Add model pricing": "Добавить тариф модели",
-    "Applied {{name}} pricing to {{count}} models": "Тариф {{name}} применён к {{count}} моделям",
-    "Audio input price": "Цена аудиовхода",
-    "Audio output price": "Цена аудиовыхода",
-    "Audio output price requires an audio input price.": "Для цены аудиовыхода нужна цена аудиовхода.",
-    "Billable input tokens": "Оплачиваемые входные токены",
-    "Billable output tokens": "Оплачиваемые выходные токены",
-    "Cache create (1h) price": "Цена создания кэша (1 ч)",
-    "Cache create price": "Цена создания кэша",
-    "Cache read price": "Цена чтения кэша",
-    "Cache pricing": "Cache pricing",
-    "Cache write price": "Цена записи кэша",
-    "Changes are written to the settings draft on save.": "Изменения будут записаны в черновик настроек при сохранении.",
-    "Clean": "Без конфликта",
-    "Completion price": "Цена завершения",
-    "Core pricing": "Core pricing",
-    "Copy {{name}} pricing": "Копировать тариф {{name}}",
-    "Disabled lanes are omitted on save.": "Отключённые каналы цен не сохраняются.",
-    "Edit model pricing": "Изменить тариф модели",
-    "Empty": "Пусто",
-    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "Каждый уровень поддерживает до 2 условий; последний уровень является резервным и не содержит условий. Используйте полную длину входа для условий уровня, чтобы кэш-попадания не снижали оплачиваемые входные токены и не приводили к неверному маршруту.",
-    "All conditions must match before this tier is used.": "All conditions must match before this tier is used.",
-    "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
-    "Expression": "Выражение",
-    "Fallback tier": "Fallback tier",
-    "Full input length": "Полная длина входа",
-    "Input price is required before saving dependent prices.": "Перед сохранением зависимых цен укажите входную цену.",
-    "Image input price": "Цена входного изображения",
-    "Image output price": "Цена выходного изображения",
-    "Media pricing": "Media pricing",
-    "New model": "Новая модель",
-    "No separate media pricing configured.": "No separate media pricing configured.",
-    "Open a source model first": "Сначала откройте исходную модель",
-    "Output token price for generated tokens.": "Цена выходных токенов для сгенерированного текста.",
-    "Per-request": "За запрос",
-    "Save preview": "Предпросмотр сохранения",
-    "Select at least one target model": "Выберите хотя бы одну целевую модель",
-    "Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
-    "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
-    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "У этой модели одновременно заданы фиксированная цена и коэффициенты. Сохранение текущего режима перезапишет конфликтующие поля.",
-    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "У этой модели одновременно заданы фиксированная цена и цены за токены. Сохранение текущего режима перезапишет конфликтующие поля.",
-    "This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
-    "Tier conditions": "Tier conditions",
-    "Token price for audio input.": "Цена токенов для аудиовхода.",
-    "Token price for audio output.": "Цена токенов для аудиовыхода.",
-    "Token price for cache reads.": "Цена токенов для чтения кэша.",
-    "Token price for creating cache entries.": "Цена токенов для создания записей кэша.",
-    "Token price for image input.": "Цена токенов для входного изображения.",
-    "USD price per 1M input tokens.": "Цена в USD за 1 млн входных токенов.",
-    "USD price per 1M tokens.": "Цена в USD за 1 млн токенов.",
-    "{{count}} selected targets available for bulk copy.": "Для массового копирования выбрано целей: {{count}}.",
-    "Base input price only": "Только базовая цена входа",
-    "Expression based": "На основе выражения",
-    "Expression pricing": "Тарификация выражением",
-    "Fixed request price": "Фиксированная цена запроса",
-    "Includes request rules": "Включает правила запросов",
-    "No base input price": "Нет базовой цены входа",
-    "No models configured. Use Add model to get started.": "Модели не настроены. Используйте добавление модели, чтобы начать.",
-    "Price summary": "Сводка цен",
-    "Select a model to edit pricing": "Выберите модель для редактирования тарифа",
-    "Tiered pricing": "Многоуровневая тарификация",
-    "Unset price": "Цена не задана",
-    "Use the full-width table to scan prices, then select a row to edit it here.": "Просмотрите цены в таблице, затем выберите строку для редактирования здесь.",
-    "extras": "доп. пункты",
-    "tiers": "уровни"
+    "Zoom": "Zoom"
   }
 }

+ 112 - 77
web/default/src/i18n/locales/vi.json

@@ -38,6 +38,7 @@
     "{{count}} models": "{{count}} mô hình",
     "{{count}} months ago": "{{count}} tháng trước",
     "{{count}} override": "{{count}} ghi đè",
+    "{{count}} selected targets available for bulk copy.": "Có {{count}} mục tiêu đã chọn để sao chép hàng loạt.",
     "{{count}} tiers": "{{count}} bậc",
     "{{count}} vendors": "{{count}} nhà cung cấp",
     "{{count}} weeks ago": "{{count}} tuần trước",
@@ -96,6 +97,7 @@
     "7 Days": "7 ngày",
     "7 days ago": "7 ngày trước",
     "80,443,8080": "80,443,8080",
+    "A billing multiplier. Lower ratios mean lower API call costs.": "Hệ số tính phí. Tỷ lệ càng thấp thì chi phí gọi API càng thấp.",
     "About": "Giới thiệu",
     "Accept Unpriced Models": "Chấp nhận các Mô hình chưa định giá",
     "Accepts a JSON array of model identifiers that support the Imagine API.": "Chấp nhận một mảng JSON gồm các mã định danh mô hình hỗ trợ API Imagine.",
@@ -158,6 +160,7 @@
     "Add Mode": "Thêm Chế độ",
     "Add model": "Thêm mô hình",
     "Add Model": "Thêm Mô hình",
+    "Add model pricing": "Thêm giá mô hình",
     "Add Models": "Thêm mô hình",
     "Add new amount": "Thêm số tiền mới",
     "Add new redemption code(s) by providing necessary info.": "Thêm mã đổi thưởng mới bằng cách cung cấp thông tin cần thiết.",
@@ -236,6 +239,7 @@
     "Ali": "Ali",
     "All": "All",
     "All categories": "Tất cả danh mục",
+    "All conditions must match before this tier is used.": "All conditions must match before this tier is used.",
     "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "Tất cả các chỉnh sửa đều là thao tác ghi đè. Để trống các trường để giữ nguyên giá trị hiện tại.",
     "All files exceed the maximum size.": "Tất cả các tệp vượt quá kích thước tối đa.",
     "All Groups": "Tất cả các nhóm",
@@ -354,6 +358,7 @@
     "Append value to array / string / object end": "Thêm giá trị vào cuối mảng / chuỗi / đối tượng",
     "appended": "đã thêm vào cuối, được phụ lục",
     "Application": "Ứng dụng",
+    "Applied {{name}} pricing to {{count}} models": "Đã áp dụng giá của {{name}} cho {{count}} mô hình",
     "Applies to custom completion endpoints. JSON map of model → ratio.": "Áp dụng cho các điểm cuối hoàn thành tùy chỉnh. Bản đồ JSON của mô hình → tỷ lệ.",
     "Apply All Upstream Updates": "Áp dụng Tất cả Cập nhật Upstream",
     "Apply Filters": "Áp dụng bộ lọc",
@@ -383,6 +388,8 @@
     "Array of chat client presets. Each item is an object with one key-value pair: client name and its URL.": "Mảng các thiết lập sẵn của ứng dụng trò chuyện. Mỗi mục là một đối tượng với",
     "Asc": "Asc",
     "Ask anything": "Hỏi gì cũng được",
+    "Assigned by administrator only": "Chỉ quản trị viên gán",
+    "Assigned by administrators and used to represent a user level, such as default or vip.": "Do quản trị viên gán và dùng để biểu thị cấp người dùng, ví dụ default hoặc vip.",
     "Async task refund": "Hoàn tiền tác vụ bất đồng bộ",
     "At least one model regex pattern is required": "Cần ít nhất một mẫu regex mô hình",
     "At least one valid key source is required": "Cần ít nhất một nguồn khóa hợp lệ",
@@ -393,10 +400,13 @@
     "Audio In": "Đầu vào âm thanh",
     "Audio input": "Đầu vào âm thanh",
     "Audio Input": "Đầu vào âm thanh",
+    "Audio input price": "Giá đầu vào âm thanh",
     "Audio Input Price": "Giá đầu vào âm thanh",
     "Audio Out": "Đầu ra âm thanh",
     "Audio output": "Đầu ra âm thanh",
     "Audio Output": "Đầu ra âm thanh",
+    "Audio output price": "Giá đầu ra âm thanh",
+    "Audio output price requires an audio input price.": "Giá đầu ra âm thanh cần có giá đầu vào âm thanh.",
     "Audio playback failed": "Phát âm thanh thất bại",
     "Audio Preview": "Xem trước âm thanh",
     "Audio ratio": "Tỷ lệ âm thanh",
@@ -413,6 +423,7 @@
     "Auto Ban": "Cấm tự động",
     "Auto detect (default)": "Tự động phát hiện (mặc định)",
     "Auto Disabled": "Vô hiệu hóa tự động",
+    "Auto group behavior": "Cách hoạt động của nhóm auto",
     "Auto Group Chain": "Chuỗi nhóm tự động",
     "Auto refresh": "Tự động làm mới",
     "Auto Sync Upstream Models": "Tự động đồng bộ mô hình nguồn",
@@ -469,6 +480,8 @@
     "Bark Push URL": "URL đẩy Bark",
     "Base address provided by your Epay service": "Địa chỉ cơ sở được cung cấp bởi dịch vụ Epay của bạn",
     "Base amount. Actual deduction = base amount × system group rate.": "Số tiền cơ sở. Số tiền trừ thực tế = số tiền cơ sở × tỷ lệ nhóm hệ thống.",
+    "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
+    "Base input price only": "Chỉ có giá đầu vào cơ bản",
     "Base Limits": "Giới hạn cơ bản",
     "Base multipliers applied when users select specific groups.": "Hệ số nhân cơ bản được áp dụng khi người dùng chọn các nhóm cụ thể.",
     "Base Price": "Giá cơ bản",
@@ -493,6 +506,8 @@
     "Batch upstream model updates applied: {{channels}} channels, {{added}} added, {{removed}} removed, {{fails}} failed": "Đã áp dụng cập nhật hàng loạt mô hình upstream: {{channels}} kênh, {{added}} đã thêm, {{removed}} đã xóa, {{fails}} thất bại",
     "Best for single-tenant deployments. Pricing and billing options stay hidden.": "Phù hợp nhất cho triển khai đơn người dùng. Các tùy chọn giá và thanh toán sẽ được ẩn.",
     "Best TTFT": "TTFT tốt nhất",
+    "Billable input tokens": "Token đầu vào tính phí",
+    "Billable output tokens": "Token đầu ra tính phí",
     "Billing": "Thanh toán",
     "Billing & Payment": "Thanh toán & chi phí",
     "Billing currency": "Loại tiền thanh toán",
@@ -545,6 +560,8 @@
     "By category": "Theo danh mục",
     "By model author": "Theo nhà phát triển mô hình",
     "Cache": "Bộ nhớ đệm",
+    "Cache create (1h) price": "Giá tạo cache (1 giờ)",
+    "Cache create price": "Giá tạo cache",
     "Cache Creation": "Tạo cache",
     "Cache Creation (1h)": "Tạo cache (1h)",
     "Cache Creation (5m)": "Tạo cache (5m)",
@@ -553,13 +570,16 @@
     "Cache Directory Info": "Thông tin thư mục bộ nhớ đệm",
     "Cache Entries": "Mục bộ nhớ đệm",
     "Cache mode": "Chế độ bộ đệm",
+    "Cache pricing": "Cache pricing",
     "Cache ratio": "Tỷ lệ bộ nhớ đệm",
     "Cache Read": "Đọc bộ nhớ đệm",
+    "Cache read price": "Giá đọc cache",
     "Cache repeated prompt prefixes for cheaper, faster reuse": "Lưu cache phần đầu lời nhắc lặp lại để tái sử dụng nhanh và rẻ hơn",
     "Cache write": "Ghi cache",
     "Cache Write": "Ghi bộ nhớ đệm",
     "Cache Write (1h)": "Ghi cache (1h)",
     "Cache Write (5m)": "Ghi cache (5m)",
+    "Cache write price": "Giá ghi cache",
     "Cached": "Đã cache",
     "Cached input": "Đầu vào đã cache",
     "Calculated price: ${{price}} per 1M tokens": "Giá tính toán: ${{price}} mỗi 1M token",
@@ -592,6 +612,7 @@
     "Change language": "Đổi ngôn ngữ",
     "Change Password": "Đổi mật khẩu",
     "Change To": "Thay đổi thành",
+    "Changes are written to the settings draft on save.": "Các thay đổi sẽ được ghi vào bản nháp cài đặt khi lưu.",
     "Changing...": "Đang thay đổi...",
     "Channel": "Kênh",
     "Channel Affinity": "Ưu tiên kênh",
@@ -663,6 +684,7 @@
     "Classic (Legacy Frontend)": "Cổ điển (Frontend cũ)",
     "Claude": "Claude",
     "Claude CLI Header Passthrough": "Chuyển tiếp header Claude CLI",
+    "Clean": "Không xung đột",
     "Clean history logs": "Xóa nhật ký lịch sử",
     "Clean logs": "Dọn dẹp nhật ký",
     "Clean up inactive cache": "Dọn dẹp bộ nhớ đệm không hoạt động",
@@ -755,6 +777,7 @@
     "Complete these steps to finish the initial installation.": "Hoàn thành các bước này để hoàn tất quá trình cài đặt ban đầu.",
     "Completed": "Hoàn thành",
     "Completion": "Hoàn thành",
+    "Completion price": "Giá hoàn thành",
     "Completion price ($/1M tokens)": "Giá hoàn thành ($/1M tokens)",
     "Completion ratio": "Tỷ lệ hoàn thành",
     "Concatenate channel system prompt with user&apos;s prompt": "Nối lời nhắc hệ thống kênh với lời nhắc của người dùng",
@@ -894,6 +917,7 @@
     "Copied: {{model}}": "Đã sao chép: {{model}}",
     "Copied!": "Đã sao chép!",
     "Copy": "Sao chép",
+    "Copy {{name}} pricing": "Sao chép giá của {{name}}",
     "Copy a request header": "Sao chép header yêu cầu",
     "Copy All": "Sao chép tất cả",
     "Copy all backup codes": "Sao chép tất cả mã dự phòng",
@@ -924,8 +948,10 @@
     "Copy token": "Sao chép mã thông báo",
     "Copy URL": "Sao chép URL",
     "Copywriting, ad creative, SEO": "Viết copy, sáng tạo quảng cáo, SEO",
+    "Core concepts": "Khái niệm chính",
     "Core Configuration": "Cấu hình chính",
     "Core Features": "Tính năng cốt lõi",
+    "Core pricing": "Core pricing",
     "Cost": "Chi phí",
     "Cost in USD per request, regardless of tokens used.": "Chi phí bằng USD cho mỗi yêu cầu, bất kể số lượng token được sử dụng.",
     "Cost Tracking": "Theo dõi chi phí",
@@ -1148,6 +1174,7 @@
     "disabled": "vô hiệu hóa",
     "Disabled": "Đã tắt",
     "Disabled all channels with tag: {{tag}}": "Đã tắt tất cả kênh với nhãn: {{tag}}",
+    "Disabled lanes are omitted on save.": "Các kênh bị tắt sẽ được bỏ qua khi lưu.",
     "Disabled Reason": "Lý do vô hiệu hóa",
     "Disabled Time": "Thời gian vô hiệu hóa",
     "Disabling...": "Đang vô hiệu hóa...",
@@ -1206,6 +1233,7 @@
     "Drawing Logs": "Nhật ký bản vẽ",
     "Drawing task records": "Lịch sử tác vụ vẽ",
     "Duplicate": "Nhân bản",
+    "Duplicate group names: {{names}}": "Tên nhóm bị trùng: {{names}}",
     "Duration": "Thời lượng",
     "Duration (hours)": "Thời lượng (giờ)",
     "Duration Settings": "Cài đặt thời lượng",
@@ -1257,12 +1285,15 @@
     "Each item must have exactly one key-value pair.": "Mỗi mục phải có chính xác một cặp khóa-giá trị.",
     "Each line represents one keyword. Leave blank to disable the list but keep the switch states.": "Mỗi dòng đại diện cho một từ khóa. Để trống để tắt danh sách nhưng vẫn giữ trạng thái công tắc.",
     "Each tier supports 0~2 conditions (over len, p, c); the last tier is the catch-all without conditions. Use len (full input length, including cache hits) for tier conditions to avoid mis-routing when cache hits reduce p.": "Mỗi bậc hỗ trợ 0~2 điều kiện (đối với len, p, c); bậc cuối là bậc dự phòng không cần điều kiện. Hãy dùng len (độ dài đầu vào đầy đủ, bao gồm cả cache hits) cho điều kiện bậc để tránh định tuyến sai khi cache hits làm giảm p.",
+    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "Mỗi tầng hỗ trợ tối đa 2 điều kiện; tầng cuối cùng là tầng dự phòng không có điều kiện. Hãy dùng độ dài đầu vào đầy đủ cho điều kiện tầng để tránh chọn sai tầng khi cache hit làm giảm token đầu vào tính phí.",
+    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Earn rewards when your referrals add funds. Transfer accumulated rewards to your balance anytime.": "Nhận phần thưởng khi người bạn giới thiệu nạp tiền",
     "Edit": "Chỉnh sửa",
     "Edit {{title}}": "Chỉnh sửa {{title}}",
     "Edit all channels with tag:": "Chỉnh sửa tất cả các kênh với thẻ:",
     "Edit Announcement": "Chỉnh sửa thông báo",
     "Edit API Shortcut": "Chỉnh sửa lối tắt API",
+    "Edit billing ratios and user-selectable groups in one table.": "Chỉnh sửa tỷ lệ tính phí và nhóm người dùng có thể chọn trong một bảng.",
     "Edit Channel": "Chỉnh sửa Kênh",
     "Edit chat preset": "Chỉnh sửa cài đặt trước trò chuyện",
     "Edit discount tier": "Chỉnh sửa bậc giảm giá",
@@ -1272,6 +1303,7 @@
     "Edit JSON text directly. Format will be validated on save.": "Chỉnh sửa văn bản JSON trực tiếp. Định dạng sẽ được kiểm tra khi lưu.",
     "Edit model": "Chỉnh sửa mô hình",
     "Edit Model": "Chỉnh sửa Mô hình",
+    "Edit model pricing": "Chỉnh sửa giá mô hình",
     "Edit OAuth Provider": "Chỉnh Sửa Nhà Cung Cấp OAuth",
     "Edit payment method": "Sửa phương thức thanh toán",
     "Edit Prefill Group": "Chỉnh sửa Nhóm Điền sẵn",
@@ -1297,6 +1329,7 @@
     "Email Verification": "Xác minh Email",
     "Email, summarisation, knowledge work": "Email, tóm tắt, làm việc tri thức",
     "Embeddings": "Embeddings",
+    "Empty": "Trống",
     "Empty value will be saved as {}.": "Giá trị trống sẽ được lưu thành {}.",
     "Enable": "Bật",
     "Enable 2FA": "Bật 2FA",
@@ -1475,9 +1508,12 @@
     "Expose grouped Uptime Kuma status pages directly on the dashboard": "Hiển thị các trang trạng thái Uptime Kuma đã nhóm trực tiếp trên bảng điều khiển",
     "Expose ratio API": "Cung cấp API tỷ lệ",
     "Exposes the pricing/models catalog in the top navigation.": "Hiển thị danh mục giá/mô hình trên thanh điều hướng đầu trang.",
+    "Expression": "Biểu thức",
+    "Expression based": "Dựa trên biểu thức",
     "Expression billing": "Tính phí biểu thức",
     "Expression editor": "Trình sửa biểu thức",
     "Expression error": "Lỗi biểu thức",
+    "Expression pricing": "Định giá bằng biểu thức",
     "Extend": "Gia hạn",
     "Extend deployment": "Gia hạn triển khai",
     "Extend failed": "Gia hạn thất bại",
@@ -1489,6 +1525,7 @@
     "External Speed Test": "Kiểm tra tốc độ bên ngoài",
     "Extra": "Thêm",
     "Extra Notes (Optional)": "Ghi chú bổ sung (Tùy chọn)",
+    "extras": "mục bổ sung",
     "Fail Reason": "Lý do thất bại",
     "Fail Reason Details": "Chi tiết lý do thất bại",
     "Failed": "Thất bại",
@@ -1610,6 +1647,7 @@
     "Failed to update user": "Không thể cập nhật người dùng",
     "Failure keywords": "Từ khóa thất bại",
     "Fair": "Công bằng",
+    "Fallback tier": "Fallback tier",
     "FAQ": "FAQ",
     "FAQ added. Click \"Save Settings\" to apply.": "Đã thêm FAQ. Nhấp \"Lưu cài đặt\" để áp dụng.",
     "FAQ deleted. Click \"Save Settings\" to apply.": "Đã xóa FAQ. Nhấp \"Lưu cài đặt\" để áp dụng.",
@@ -1679,6 +1717,7 @@
     "Fixed abilities: {{success}} succeeded, {{fails}} failed": "Sửa khả năng: {{success}} thành công, {{fails}} thất bại",
     "Fixed price": "Giá cố định",
     "Fixed price (USD)": "Giá cố định (USD)",
+    "Fixed request price": "Giá cố định theo yêu cầu",
     "Floating": "Nổi",
     "FluentRead extension not detected. Please ensure it is installed and active.": "Không phát hiện tiện ích mở rộng FluentRead. Vui lòng đảm bảo nó đã được cài đặt và kích hoạt.",
     "Flush interval (minutes)": "Khoảng ghi xuống DB (phút)",
@@ -1732,6 +1771,7 @@
     "Full API Key": "Khóa API đầy đủ",
     "Full Base URL (supports": "URL cơ sở đầy đủ (hỗ trợ",
     "Full Code": "Mã đầy đủ",
+    "Full input length": "Độ dài đầu vào đầy đủ",
     "Full layout": "Bố cục đầy đủ",
     "Full width": "Toàn chiều rộng",
     "Function calling": "Gọi hàm",
@@ -1785,10 +1825,10 @@
     "gpt-4": "gpt-4",
     "gpt-4, claude-3-opus, etc.": "gpt-4, claude-3-opus, v.v.",
     "GPU count": "Số lượng GPU",
-    "Greater Than": "Lớn hơn",
-    "Greater Than or Equal": "Lớn hơn hoặc bằng",
     "Greater than": "Lớn hơn",
+    "Greater Than": "Lớn hơn",
     "Greater than or equal": "Lớn hơn hoặc bằng",
+    "Greater Than or Equal": "Lớn hơn hoặc bằng",
     "Grok": "Grok",
     "Grok Settings": "Cài đặt Grok",
     "Group": "Nhóm",
@@ -1797,6 +1837,7 @@
     "Group channels by tag for batch operations": "Nhóm kênh theo thẻ để thực hiện các thao tác hàng loạt",
     "Group config overrides global limits, shares the same period": "Cấu hình nhóm ghi đè giới hạn toàn cầu, chia sẻ cùng một chu kỳ",
     "Group deleted. Click \"Save Settings\" to apply.": "Nhóm đã bị xóa. Nhấp vào \"Lưu Cài đặt\" để áp dụng.",
+    "Group description": "Mô tả nhóm",
     "Group details": "Chi tiết nhóm",
     "Group identifier": "Định danh nhóm",
     "Group is required": "Yêu cầu nhóm",
@@ -1805,6 +1846,7 @@
     "Group name cannot be changed when editing.": "Tên nhóm không thể thay đổi khi chỉnh sửa.",
     "Group prices cannot be expanded because this expression is not a standard tiered pricing expression.": "Không thể mở rộng giá theo nhóm vì biểu thức này không phải là biểu thức giá theo bậc tiêu chuẩn.",
     "Group Pricing": "Định giá nhóm",
+    "Group pricing usage guide": "Hướng dẫn sử dụng định giá theo nhóm",
     "group ratio": "tỷ lệ nhóm",
     "Group Ratio": "Tỷ lệ nhóm",
     "Group ratios": "Tỷ lệ nhóm",
@@ -1906,14 +1948,17 @@
     "If an upstream error contains any of these keywords (case insensitive), the channel will be disabled automatically.": "Nếu một lỗi thượng nguồn chứa bất kỳ từ khóa nào trong số này (không phân biệt chữ hoa chữ thường), kênh sẽ tự động bị vô hiệu hóa.",
     "If authorization succeeds, the generated JSON will be inserted into the key field. You still need to save the channel to persist it.": "Nếu ủy quyền thành công, JSON tạo ra sẽ được chèn vào trường khóa. Bạn vẫn cần lưu kênh để áp dụng.",
     "If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing": "Nếu kết nối với dự án relay One API hoặc New API upstream, hãy sử dụng loại OpenAI thay thế trừ khi bạn biết mình đang làm gì",
-    "If this keeps happening, please report it on GitHub Issues.": "Nếu sự cố tiếp tục xảy ra, vui lòng báo cáo trên GitHub Issues.",
+    "If default auto group is enabled, newly created tokens start with auto instead of an empty group.": "Nếu bật nhóm auto mặc định, token mới sẽ bắt đầu với auto thay vì nhóm trống.",
     "If the affinity channel fails and retry succeeds on another channel, update affinity to the successful channel.": "Nếu kênh ưu tiên thất bại và thử lại thành công trên kênh khác, cập nhật ưu tiên sang kênh thành công.",
+    "If this keeps happening, please report it on GitHub Issues.": "Nếu sự cố tiếp tục xảy ra, vui lòng báo cáo trên GitHub Issues.",
     "Ignored upstream models": "Mô hình upstream bị bỏ qua",
     "Image": "Hình ảnh",
     "Image Generation": "Tạo hình ảnh",
     "Image In": "Ảnh vào",
     "Image input": "Đầu vào hình ảnh",
+    "Image input price": "Giá đầu vào hình ảnh",
     "Image Out": "Ảnh ra",
+    "Image output price": "Giá đầu ra hình ảnh",
     "Image Preview": "Xem trước ảnh",
     "Image ratio": "Tỷ lệ hình ảnh",
     "Image to Video": "Ảnh sang video",
@@ -1927,6 +1972,7 @@
     "Include Group": "Bao gồm nhóm",
     "Include Model": "Bao gồm mô hình",
     "Include Rule Name": "Bao gồm tên quy tắc",
+    "Includes request rules": "Bao gồm quy tắc yêu cầu",
     "Including failed requests, 0 = unlimited": "Bao gồm các yêu cầu thất bại, 0 = không giới hạn",
     "Index": "Chỉ mục",
     "Initial quota given to new users": "Hạn mức ban đầu cấp cho người dùng mới",
@@ -1938,6 +1984,7 @@
     "Input": "Đầu vào",
     "Input mode": "Chế độ nhập",
     "Input price": "Giá đầu vào",
+    "Input price is required before saving dependent prices.": "Cần có giá đầu vào trước khi lưu các giá phụ thuộc.",
     "Input tokens": "Token đầu vào",
     "Input Tokens": "Token đầu vào",
     "Inset": "Khung trong",
@@ -2068,10 +2115,10 @@
     "Legacy Format Template": "Mẫu định dạng cũ",
     "Legal": "Pháp lý",
     "Less": "Ít hơn",
-    "Less Than": "Nhỏ hơn",
-    "Less Than or Equal": "Nhỏ hơn hoặc bằng",
     "Less than": "Nhỏ hơn",
+    "Less Than": "Nhỏ hơn",
     "Less than or equal": "Nhỏ hơn hoặc bằng",
+    "Less Than or Equal": "Nhỏ hơn hoặc bằng",
     "License": "Giấy phép",
     "Light": "Ánh sáng",
     "Lightning Fast": "Nhanh như chớp",
@@ -2188,6 +2235,7 @@
     "Maximum tokens per response": "Số token tối đa mỗi phản hồi",
     "maxRequests ≥ 0, maxSuccess ≥ 1, both ≤ 2,147,483,647": "maxRequests ≥ 0, maxSuccess ≥ 1, cả hai đều ≤ 2,147,483,647",
     "May be used for training by upstream provider": "Có thể được nhà cung cấp dùng để huấn luyện",
+    "Media pricing": "Media pricing",
     "Median time-to-first-token (TTFT) sampled hourly per group": "Độ trễ token đầu tiên trung vị (TTFT) lấy mẫu mỗi giờ theo nhóm",
     "Medical Q&A, mental health support": "Hỏi đáp y tế, hỗ trợ sức khỏe tinh thần",
     "Memory Hits": "Lượt truy cập bộ nhớ",
@@ -2255,6 +2303,8 @@
     "Model performance metrics": "Chỉ số hiệu năng mô hình",
     "Model Price": "Giá mô hình",
     "Model Price Not Configured": "Giá mô hình chưa được cấu hình",
+    "Model prices": "Giá mô hình",
+    "Model prices reset successfully": "Đã đặt lại giá mô hình thành công",
     "Model Pricing": "Định giá mô hình",
     "Model pull failed: {{msg}}": "Tải mô hình thất bại: {{msg}}",
     "Model ratio": "Tỷ lệ mô hình",
@@ -2365,6 +2415,7 @@
     "New API Project Repository:": "Kho lưu trữ Dự án API Mới:",
     "New Format Template": "Mẫu định dạng mới",
     "New Group": "Nhóm mới",
+    "New model": "Mô hình mới",
     "New Models ({{count}})": "Mô hình mới ({{count}})",
     "New name will be:": "Tên mới sẽ là:",
     "New password": "Mật khẩu mới",
@@ -2393,6 +2444,7 @@
     "No available models": "Không có mô hình khả dụng",
     "No available Web chat links": "Không có liên kết Web chat khả dụng",
     "No backup": "Chưa sao lưu",
+    "No base input price": "Chưa có giá đầu vào cơ bản",
     "No billing records found": "Không tìm thấy hồ sơ thanh toán",
     "No capabilities reported for this model.": "Chưa có khả năng nào được báo cáo cho mô hình này.",
     "No Change": "Không thay đổi",
@@ -2428,6 +2480,7 @@
     "No group found.": "Không tìm thấy nhóm.",
     "No group-based rate limits configured. Click \"Add group\" to get started.": "Chưa cấu hình giới hạn tốc độ dựa trên nhóm. Nhấp \"Add group\" để bắt đầu.",
     "No groups match your search": "Không có nhóm nào khớp với tìm kiếm của bạn",
+    "No groups yet. Add a group to get started.": "Chưa có nhóm nào. Thêm một nhóm để bắt đầu.",
     "No header overrides configured.": "Không có ghi đè tiêu đề nào được cấu hình.",
     "No history data available": "Không có dữ liệu lịch sử",
     "No incidents in the last 24 hours": "Không có sự cố trong 24 giờ qua",
@@ -2449,6 +2502,7 @@
     "No models available": "Không có mô hình nào khả dụng",
     "No models available in this category": "Không có mô hình nào trong danh mục này",
     "No models available. Create your first model to get started.": "Không có mô hình nào khả dụng. Hãy tạo mô hình đầu tiên của bạn để bắt đầu.",
+    "No models configured. Use Add model to get started.": "Chưa cấu hình mô hình. Dùng Thêm mô hình để bắt đầu.",
     "No models fetched from upstream": "Không lấy được mô hình nào từ upstream",
     "No models fetched yet.": "Chưa có mô hình nào được tìm nạp.",
     "No models found": "Không tìm thấy mô hình nào",
@@ -2493,6 +2547,7 @@
     "No Retry": "Không thử lại",
     "No rules yet": "Chưa có quy tắc",
     "No rules yet. Add a group below to get started.": "Chưa có quy tắc nào. Thêm một nhóm bên dưới để bắt đầu.",
+    "No separate media pricing configured.": "No separate media pricing configured.",
     "No status code mappings configured.": "Chưa cấu hình ánh xạ mã trạng thái.",
     "No subscription plans yet": "Chưa có gói đăng ký nào",
     "No subscription records": "Không có bản ghi đăng ký",
@@ -2579,6 +2634,7 @@
     "Online topup is not enabled. Please use redemption code or contact administrator.": "Tính năng nạp tiền trực tuyến chưa được bật. Vui lòng sử dụng mã quy đổi hoặc liên hệ quản trị viên.",
     "Only allow specific email domains": "Chỉ cho phép các tên miền email cụ thể",
     "Only available for admins. When enabled, you will receive a summary notification via your selected method when the scheduled model check detects upstream model changes or check failures.": "Chỉ khả dụng cho quản trị viên. Khi bật, bạn sẽ nhận được thông báo tổng hợp qua phương thức đã chọn khi kiểm tra mô hình định kỳ phát hiện thay đổi mô hình nguồn hoặc lỗi kiểm tra.",
+    "Only configured combinations are overridden. All other calls keep the token group base ratio.": "Chỉ các tổ hợp đã cấu hình mới bị ghi đè. Các lệnh gọi khác giữ tỷ lệ cơ bản của nhóm token.",
     "Only selected fields will be overwritten. You can re-run the sync wizard if new conflicts appear.": "Chỉ các trường được chọn sẽ bị ghi đè. Bạn có thể chạy lại trình hướng dẫn đồng bộ hóa nếu có xung đột mới xuất hiện.",
     "Only successful requests": "Chỉ các yêu cầu thành công",
     "Only successful requests count toward this limit.": "Chỉ những yêu cầu thành công mới được tính vào giới hạn này.",
@@ -2586,6 +2642,7 @@
     "Oops! Page Not Found!": "Ối! Không tìm thấy trang!",
     "Oops! Something went wrong": "Oops! An error occurred.",
     "Open": "Mở",
+    "Open a source model first": "Mở một mô hình nguồn trước",
     "Open authorization page": "Mở trang ủy quyền",
     "Open CC Switch": "Mở công tắc CC",
     "Open in chat": "Mở trong trò chuyện",
@@ -2641,9 +2698,11 @@
     "Output aspect ratio": "Tỉ lệ khung hình",
     "Output image size": "Kích thước ảnh đầu ra",
     "Output price": "Giá đầu ra",
+    "Output token price for generated tokens.": "Giá token đầu ra cho nội dung được tạo.",
     "Output tokens": "Token đầu ra",
     "Output Tokens": "Token đầu ra",
     "overall": "tổng",
+    "Overnight range": "Khoảng qua nửa đêm",
     "override": "ghi đè",
     "Override": "Ghi đè",
     "Override Anthropic headers, defaults, and thinking adapter behavior": "Ghi đè tiêu đề, cài đặt mặc định và hành vi bộ điều hợp tư duy của Anthropic",
@@ -2656,7 +2715,6 @@
     "Override Rules": "Quy tắc ghi đè",
     "Override the endpoint used for testing. Leave empty to auto detect.": "Ghi đè điểm cuối dùng để kiểm thử. Để trống để tự động phát hiện.",
     "overrides for matching model prefix.": "ghi đè theo tiền tố model tương ứng.",
-    "Overnight range": "Khoảng qua nửa đêm",
     "Overview": "Tổng quan",
     "Overwritten": "Đã ghi đè",
     "Page": "Trang",
@@ -2751,6 +2809,7 @@
     "Per-call": "Mỗi lần gọi",
     "Per-feature metered windows split by model or capability.": "Cửa sổ tính phí theo từng tính năng, tách theo mô hình hoặc năng lực.",
     "Per-group performance": "Hiệu năng theo nhóm",
+    "Per-request": "Theo yêu cầu",
     "Per-request (fixed price)": "Theo yêu cầu (giá cố định)",
     "Per-token": "Theo token",
     "Per-token (ratio based)": "Mỗi token (dựa trên tỷ lệ)",
@@ -2854,6 +2913,7 @@
     "Prefix used when displaying prices": "Tiền tố được sử dụng khi hiển thị giá",
     "Prefix/Suffix Text": "Văn bản tiền tố/hậu tố",
     "Premium chat models": "Mô hình chat cao cấp",
+    "Premium plan, half price": "Gói premium, nửa giá",
     "Preparing chat keys…": "Đang chuẩn bị khóa trò chuyện…",
     "Preparing your chat link, please try again in a moment.": "Đang chuẩn bị liên kết trò chuyện của bạn, vui lòng thử lại trong giây lát.",
     "Preparing your chat link…": "Đang chuẩn bị liên kết trò chuyện của bạn…",
@@ -2890,6 +2950,7 @@
     "Price estimation description": "Sau khi hoàn thành loại phần cứng, vị trí triển khai, số lượng bản sao, v.v., giá sẽ được tính toán tự động.",
     "Price ID": "Mã giá",
     "Price mode (USD per 1M tokens)": "Chế độ giá (USD mỗi 1 triệu token)",
+    "Price summary": "Tóm tắt giá",
     "price_xxx": "price_xxx",
     "Price:": "Giá:",
     "Price: High to Low": "Giá: Từ cao đến thấp",
@@ -2901,6 +2962,8 @@
     "Pricing & Display": "Giá cả & Hiển thị",
     "Pricing by Group": "Giá theo Nhóm",
     "Pricing Configuration": "Price configuration",
+    "Pricing group example": "Ví dụ nhóm định giá",
+    "Pricing groups": "Nhóm định giá",
     "Pricing mode": "Chế độ định giá",
     "Pricing Ratios": "Tỷ lệ định giá",
     "Pricing Type": "Price type",
@@ -2943,8 +3006,6 @@
     "Provide Markdown, HTML, or an external URL for the user agreement": "Cung cấp Markdown, HTML, hoặc một URL bên ngoài cho thỏa thuận người dùng",
     "Provide per-category safety overrides as JSON. Use `default` for fallback values.": "Cung cấp các ghi đè an toàn theo từng danh mục dưới dạng JSON. Sử dụng `default` cho các giá trị dự phòng.",
     "Provide per-model header overrides as JSON. Useful for enabling beta features such as expanded context windows.": "Cung cấp các ghi đè tiêu đề theo từng mô hình dưới dạng JSON. Hữu ích để bật các tính năng beta như cửa sổ ngữ cảnh mở rộng.",
-    "Public model catalog and pricing page.": "Trang công khai cho danh mục mô hình và giá.",
-    "Public rankings page based on live usage data.": "Trang bảng xếp hạng công khai dựa trên dữ liệu sử dụng thực.",
     "Provider": "Nhà cung cấp",
     "Provider & data privacy": "Nhà cung cấp & quyền riêng tư",
     "Provider created successfully": "Đã tạo nhà cung cấp thành công",
@@ -2957,6 +3018,8 @@
     "Prune Object Items": "Dọn mục đối tượng",
     "Prune object items by conditions": "Dọn dẹp các mục đối tượng theo điều kiện",
     "Prune Rule (string or JSON object)": "Quy tắc dọn dẹp (chuỗi hoặc đối tượng JSON)",
+    "Public model catalog and pricing page.": "Trang công khai cho danh mục mô hình và giá.",
+    "Public rankings page based on live usage data.": "Trang bảng xếp hạng công khai dựa trên dữ liệu sử dụng thực.",
     "Publish Date": "Ngày xuất bản",
     "Published": "Đã xuất bản",
     "Published:": "Đã xuất bản:",
@@ -3171,6 +3234,7 @@
     "Resend ({{seconds}}s)": "Gửi lại ({{seconds}}s)",
     "Reset": "Đặt lại",
     "Reset 2FA": "Đặt lại 2FA",
+    "Reset all model prices?": "Đặt lại tất cả giá mô hình?",
     "Reset all model ratios?": "Đặt lại tất cả tỷ lệ mô hình?",
     "Reset all settings to default values": "Đặt lại tất cả cài đặt về giá trị mặc định",
     "Reset at:": "Đặt lại lúc:",
@@ -3181,6 +3245,7 @@
     "Reset Passkey": "Đặt lại Khóa truy cập",
     "Reset password": "Đặt lại mật khẩu",
     "Reset Period": "Chu kỳ đặt lại",
+    "Reset prices": "Đặt lại giá",
     "Reset ratios": "Đặt lại tỷ lệ",
     "Reset Stats": "Đặt lại thống kê",
     "Reset to default": "Đặt lại mặc định",
@@ -3272,12 +3337,14 @@
     "Save group ratios": "Lưu tỷ lệ nhóm",
     "Save io.net settings": "Lưu cài đặt io.net",
     "Save log settings": "Lưu cài đặt nhật ký",
+    "Save model prices": "Lưu giá mô hình",
     "Save model ratios": "Lưu tỷ lệ mô hình",
     "Save Models": "Lưu Mô hình",
     "Save monitoring rules": "Lưu quy tắc giám sát",
     "Save navigation": "Lưu điều hướng",
     "Save notice": "Lưu thông báo",
     "Save Preferences": "Lưu tùy chọn",
+    "Save preview": "Xem trước lưu",
     "Save rate limits": "Lưu giới hạn tốc độ",
     "Save sensitive words": "Lưu từ nhạy cảm",
     "Save Settings": "Lưu Cài đặt",
@@ -3340,6 +3407,7 @@
     "Select a color": "Chọn một màu",
     "Select a group": "Chọn một nhóm",
     "Select a group type": "Chọn loại nhóm",
+    "Select a model to edit pricing": "Chọn mô hình để chỉnh sửa giá",
     "Select a preset...": "Chọn cấu hình sẵn...",
     "Select a role": "Chọn vai trò",
     "Select a rule to edit.": "Chọn một quy tắc để chỉnh sửa.",
@@ -3353,6 +3421,7 @@
     "Select an operation mode and enter the amount": "Chọn chế độ thao tác và nhập số tiền",
     "Select announcement type": "Select notification type",
     "Select at least one field to overwrite.": "Chọn ít nhất một trường để ghi đè.",
+    "Select at least one target model": "Chọn ít nhất một mô hình đích",
     "Select border radius": "Chọn độ bo góc",
     "Select channel type": "Chọn loại kênh",
     "Select color preset": "Chọn cài đặt màu sẵn",
@@ -3406,6 +3475,7 @@
     "selected": "đã chọn",
     "selected channel(s). Leave empty to remove tag.": "Kênh đã chọn. Để trống để xóa thẻ.",
     "Selected conflicts were overwritten successfully.": "Các xung đột được chọn đã được ghi đè thành công.",
+    "Selected when creating a token and used as the default billing group for API calls.": "Được chọn khi tạo token và dùng làm nhóm tính phí mặc định cho các lệnh gọi API.",
     "Self-Use Mode": "Chế độ tự sử dụng",
     "Send": "Gửi",
     "Send code": "Gửi mã",
@@ -3413,6 +3483,7 @@
     "Sending...": "Đang gửi...",
     "Sensitive Words": "Từ ngữ nhạy cảm",
     "Sent the API key to FluentRead.": "Đã gửi khóa API đến FluentRead.",
+    "Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
     "Serve multiple users or teams with billing and quota control.": "Phục vụ nhiều người dùng hoặc nhóm với quản lý thanh toán và hạn mức.",
     "Server Address": "Địa chỉ máy chủ",
     "Server IP": "IP máy chủ",
@@ -3436,6 +3507,7 @@
     "Set quota amount and limits": "Thiết lập hạn mức và giới hạn",
     "Set Request Header": "Đặt header yêu cầu",
     "Set runtime request header: override entire value, or manipulate comma-separated tokens": "Đặt header yêu cầu runtime: ghi đè toàn bộ giá trị hoặc thao tác token phân cách bằng dấu phẩy",
+    "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
     "Set Tag": "Gán Thẻ",
     "Set tag for selected channels": "Đặt thẻ cho các kênh đã chọn",
     "Set the language used across the interface": "Đặt ngôn ngữ sử dụng trong giao diện",
@@ -3513,10 +3585,14 @@
     "Space-separated OAuth scopes": "Phạm vi OAuth phân cách bằng dấu cách",
     "Spark model version, e.g., v2.1 (version number in API URL)": "Phiên bản mô hình Spark, ví dụ: v2.1 (số phiên bản trong URL API)",
     "Special billing expression": "Biểu thức tính phí đặc biệt",
+    "Special group": "Nhóm đặc biệt",
+    "Special ratios override the token group ratio for specific user group and token group combinations.": "Tỷ lệ đặc biệt ghi đè tỷ lệ nhóm token cho các tổ hợp nhóm người dùng và nhóm token cụ thể.",
     "Special usable group rules": "Quy tắc nhóm sử dụng đặc biệt",
+    "Special usable group rules can add, remove, or append selectable token groups for a specific user group.": "Quy tắc nhóm khả dụng đặc biệt có thể thêm, xóa hoặc nối nhóm token có thể chọn cho một nhóm người dùng cụ thể.",
     "SQLite stores all data in a single file. Make sure that file is persisted when running in containers.": "SQLite lưu trữ tất cả dữ liệu trong một tệp duy nhất. Đảm bảo tệp được lưu trữ lâu dài khi chạy trong container.",
     "SSRF Protection": "Bảo vệ SSRF",
     "Standard": "Tiêu chuẩn",
+    "Standard price": "Giá tiêu chuẩn",
     "Start": "Bắt đầu",
     "Start a conversation to see messages here": "Bắt đầu một cuộc trò chuyện để xem tin nhắn tại đây",
     "Start for free with generous limits. No credit card required.": "Bắt đầu miễn phí với giới hạn hào phóng. Không cần thẻ tín dụng.",
@@ -3731,12 +3807,15 @@
     "This may cause cache failures.": "Điều này có thể gây ra lỗi bộ nhớ đệm.",
     "This may take a few moments while we validate the request and update your session.": "Việc này có thể mất vài phút trong khi chúng tôi xác thực yêu cầu và cập nhật phiên của bạn.",
     "This model has both fixed price and ratio billing conflicts": "Mô hình này có cả mâu thuẫn về thanh toán theo giá cố định và theo tỷ lệ.",
+    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "Mô hình này có cả giá cố định và cài đặt tỷ lệ. Lưu chế độ hiện tại sẽ ghi lại các trường xung đột.",
+    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "Mô hình này có cả giá cố định và cài đặt giá theo token. Lưu chế độ hiện tại sẽ ghi lại các trường xung đột.",
     "This model is not available in any group, or no group pricing information is configured.": "Mô hình này không khả dụng trong bất kỳ nhóm nào, hoặc thông tin giá nhóm chưa được cấu hình.",
     "This month": "Tháng này",
     "This page has not been created yet.": "Trang này chưa được tạo.",
     "This project must be used in compliance with the": "Dự án này phải được sử dụng tuân thủ theo",
     "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "Bản ghi này do bản cũ tạo và thiếu thông tin audit. Nâng cấp bản cài để lưu IP máy chủ, IP callback, hình thức thanh toán và phiên bản hệ thống.",
     "This site currently has {{count}} models enabled": "Trang này hiện đã bật {{count}} mô hình",
+    "This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
     "this token group": "nhóm token này",
     "this user group": "nhóm người dùng này",
     "This user has no bindings": "Người dùng này không có liên kết nào",
@@ -3758,19 +3837,20 @@
     "Throughput by group": "Thông lượng theo nhóm",
     "Throughput trend": "Xu hướng thông lượng",
     "Tier": "Bậc",
+    "Tier conditions": "Tier conditions",
     "Tier name": "Tên bậc",
     "Tiered": "Nhiều bậc",
-    "Token prices": "Token prices",
-    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
     "Tiered (billing expression)": "Nhiều bậc (công thức tính phí)",
     "Tiered price table": "Bảng giá theo bậc",
+    "Tiered pricing": "Định giá theo tầng",
+    "tiers": "tầng",
     "Time": "Thời gian",
     "Time Granularity": "Độ chi tiết thời gian",
     "Time remaining": "Thời gian còn lại",
     "Time window for rate limiting": "Cửa sổ thời gian cho giới hạn tốc độ",
     "Time-based": "Theo thời gian",
-    "Time:": "Thời gian:",
     "Time-sliced cache (Claude)": "Bộ đệm phân thời gian (Claude)",
+    "Time:": "Thời gian:",
     "Timeline": "Dòng thời gian",
     "times": "lần",
     "Timing": "Thời gian",
@@ -3794,11 +3874,18 @@
     "Token Endpoint": "Điểm cuối Token",
     "Token Endpoint (Optional)": "Điểm cuối Token (Tùy chọn)",
     "Token estimator": "Ước tính token",
+    "Token group": "Nhóm token",
     "Token management": "Quản lý token",
     "Token Management": "Quản lý token",
     "Token Mgmt": "Quản lý Token",
     "Token Name": "Tên mã thông báo",
     "Token obtained from your Gotify application": "Mã thông báo thu được từ ứng dụng Gotify của bạn",
+    "Token price for audio input.": "Giá token cho đầu vào âm thanh.",
+    "Token price for audio output.": "Giá token cho đầu ra âm thanh.",
+    "Token price for cache reads.": "Giá token cho lượt đọc cache.",
+    "Token price for creating cache entries.": "Giá token cho việc tạo mục cache.",
+    "Token price for image input.": "Giá token cho đầu vào hình ảnh.",
+    "Token prices": "Token prices",
     "Token regenerated and copied to clipboard": "Token đã được tạo lại và sao chép vào bộ nhớ tạm",
     "Token share by model author across the last 24 hours": "Tỷ lệ token theo nhà phát triển trong 24 giờ qua",
     "Token share by model author across the past few weeks": "Tỷ lệ token theo nhà phát triển trong vài tuần qua",
@@ -3922,6 +4009,7 @@
     "Unbind failed": "Hủy liên kết thất bại",
     "Unbound {{provider}}": "Đã hủy liên kết {{provider}}",
     "Underground": "Underground",
+    "Understand how user groups, token groups, ratios, and special rules work together.": "Hiểu cách nhóm người dùng, nhóm token, tỷ lệ và quy tắc đặc biệt hoạt động cùng nhau.",
     "Understand image inputs alongside text": "Hiểu hình ảnh cùng với văn bản",
     "Unexpected release payload": "Dữ liệu phiên bản không mong đợi",
     "Unified API Gateway for": "Cổng API thống nhất cho",
@@ -3935,6 +4023,7 @@
     "Unlimited": "Không giới hạn",
     "Unlimited Quota": "Hạn mức không giới hạn",
     "Unsaved changes": "Thay đổi chưa được lưu",
+    "Unset price": "Chưa đặt giá",
     "Until": "Cho đến",
     "Untitled": "Không có tiêu đề",
     "Untrusted upstream data:": "Dữ liệu nguồn không đáng tin cậy:",
@@ -3999,12 +4088,16 @@
     "URL is required": "URL là bắt buộc",
     "URL to your logo image (optional)": "URL hình ảnh logo của bạn (tùy chọn)",
     "Usage": "Sử dụng",
+    "Usage guide": "Hướng dẫn sử dụng",
     "Usage logs": "Nhật ký sử dụng",
     "Usage Logs": "Nhật ký sử dụng",
     "Usage mode": "Chế độ sử dụng",
     "Usage-based": "Dựa trên sử dụng",
     "USD": "USD",
     "USD Exchange Rate": "Tỷ giá USD",
+    "USD price per 1M input tokens.": "Giá USD cho mỗi 1 triệu token đầu vào.",
+    "USD price per 1M tokens.": "Giá USD cho mỗi 1 triệu token.",
+    "Use +: to add a group, -: to remove a default selectable group, or no prefix to append a group.": "Dùng +: để thêm nhóm, -: để xóa nhóm có thể chọn mặc định, hoặc không có tiền tố để nối nhóm.",
     "Use a compatible browser or device with biometric authentication or a security key to register a Passkey.": "Sử dụng trình duyệt hoặc thiết bị tương thích có xác thực sinh trắc học hoặc khóa bảo mật để đăng ký Khóa truy cập.",
     "Use authenticator code": "Sử dụng mã xác thực",
     "Use backup code": "Sử dụng mã dự phòng",
@@ -4014,6 +4107,8 @@
     "Use Passkey to sign in without entering your password.": "Sử dụng Khóa truy cập để đăng nhập mà không cần nhập mật khẩu của bạn.",
     "Use secure connection when sending emails": "Sử dụng kết nối an toàn khi gửi email",
     "Use sidebar shortcut": "Sử dụng phím tắt thanh bên",
+    "Use the full-width table to scan prices, then select a row to edit it here.": "Duyệt giá trong bảng, rồi chọn một hàng để chỉnh sửa tại đây.",
+    "Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.": "Dùng bảng nhóm định giá để quản lý tỷ lệ và việc nhóm có xuất hiện trong danh sách tạo token hay không.",
     "Use this token for API authentication": "Sử dụng token này để xác thực API",
     "Use your Passkey": "Sử dụng Passkey của bạn",
     "used": "đã sử dụng, cũ",
@@ -4034,6 +4129,7 @@
     "User created successfully": "Tạo người dùng thành công",
     "User dashboard and quota controls.": "Bảng điều khiển người dùng và kiểm soát hạn ngạch.",
     "User Exclusive Ratio": "Tỷ lệ riêng",
+    "User group": "Nhóm người dùng",
     "User Group": "Nhóm người dùng",
     "User group name": "Tên nhóm người dùng",
     "User Group: {{ratio}}x": "Nhóm người dùng: {{ratio}}x",
@@ -4047,6 +4143,7 @@
     "User Information": "Thông tin người dùng",
     "User Menu": "Menu người dùng",
     "User personal functions": "Chức năng cá nhân người dùng",
+    "User selectable": "Người dùng có thể chọn",
     "User Subscription Management": "Quản lý đăng ký người dùng",
     "User updated successfully": "Cập nhật người dùng thành công",
     "User Verification": "Xác minh người dùng",
@@ -4058,6 +4155,7 @@
     "Users": "Người dùng",
     "Users call the model on the left. The platform forwards the request to the upstream model on the right.": "Người dùng gọi mô hình bên trái. Nền tảng chuyển tiếp yêu cầu đến mô hình thượng nguồn bên phải.",
     "Users must wait for a successful drawing before upscales or variations.": "Người dùng phải chờ vẽ thành công trước khi upscale hoặc biến thể.",
+    "Users only see groups marked as user selectable. Non-selectable groups can still be assigned by administrators.": "Người dùng chỉ thấy các nhóm được đánh dấu là có thể chọn. Nhóm không thể chọn vẫn có thể do quản trị viên gán.",
     "uses": "sử dụng",
     "Validity": "Hiệu lực",
     "Validity Period": "Thời hạn hiệu lực",
@@ -4188,6 +4286,7 @@
     "Well-Known URL": "URL đã biết",
     "Well-Known URL must start with http:// or https://": "URL Well-Known phải bắt đầu bằng http:// hoặc https://",
     "What would you like to know?": "Bạn muốn biết gì?",
+    "When a token uses the auto group, the system tries groups from top to bottom until it finds an available group.": "Khi token dùng nhóm auto, hệ thống thử các nhóm từ trên xuống dưới cho đến khi tìm được nhóm khả dụng.",
     "When conditions match, the final price is multiplied by X. Multiple matches multiply together; values < 1 act as discounts.": "Khi thỏa điều kiện, giá cuối nhân với X. Nhiều điều kiện khớp nhân lại với nhau; giá trị < 1 hoạt động như giảm giá.",
     "When enabled, if channels in the current group fail, it will try channels in the next group in order.": "Khi được bật, nếu các kênh trong nhóm hiện tại thất bại, hệ thống sẽ thử các kênh của nhóm tiếp theo theo thứ tự.",
     "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. SSD recommended.": "Khi bật, nội dung yêu cầu lớn sẽ được lưu tạm trên đĩa thay vì bộ nhớ, giảm đáng kể việc sử dụng bộ nhớ. Khuyến nghị dùng SSD.",
@@ -4195,6 +4294,7 @@
     "When enabled, newly created tokens start in the first auto group.": "Khi được bật, các token mới được tạo sẽ bắt đầu trong nhóm tự động đầu tiên.",
     "When enabled, prompts are scanned before reaching upstream models.": "Khi được bật,",
     "When enabled, the store field will be blocked": "Khi được bật, trường store sẽ bị chặn",
+    "When enabled, users can pick this group when creating tokens.": "Khi bật, người dùng có thể chọn nhóm này khi tạo token.",
     "When enabled, violation requests will incur additional charges.": "Khi bật, các yêu cầu vi phạm sẽ phải chịu phí bổ sung.",
     "When enabled, zero-cost models also pre-consume quota before final settlement.": "Khi được bật, các mô hình không tốn phí cũng trừ trước hạn mức trước khi quyết toán cuối cùng.",
     "When no conditions are set, the operation always executes.": "Khi không có điều kiện, thao tác luôn được thực thi.",
@@ -4249,71 +4349,6 @@
     "Zero retention": "Không lưu dữ liệu",
     "Zhipu": "Zhipu",
     "Zhipu V4": "Zhipu V4",
-    "Zoom": "Zoom",
-    "Add model pricing": "Thêm giá mô hình",
-    "Applied {{name}} pricing to {{count}} models": "Đã áp dụng giá của {{name}} cho {{count}} mô hình",
-    "Audio input price": "Giá đầu vào âm thanh",
-    "Audio output price": "Giá đầu ra âm thanh",
-    "Audio output price requires an audio input price.": "Giá đầu ra âm thanh cần có giá đầu vào âm thanh.",
-    "Billable input tokens": "Token đầu vào tính phí",
-    "Billable output tokens": "Token đầu ra tính phí",
-    "Cache create (1h) price": "Giá tạo cache (1 giờ)",
-    "Cache create price": "Giá tạo cache",
-    "Cache read price": "Giá đọc cache",
-    "Cache pricing": "Cache pricing",
-    "Cache write price": "Giá ghi cache",
-    "Changes are written to the settings draft on save.": "Các thay đổi sẽ được ghi vào bản nháp cài đặt khi lưu.",
-    "Clean": "Không xung đột",
-    "Completion price": "Giá hoàn thành",
-    "Core pricing": "Core pricing",
-    "Copy {{name}} pricing": "Sao chép giá của {{name}}",
-    "Disabled lanes are omitted on save.": "Các kênh bị tắt sẽ được bỏ qua khi lưu.",
-    "Edit model pricing": "Chỉnh sửa giá mô hình",
-    "Empty": "Trống",
-    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "Mỗi tầng hỗ trợ tối đa 2 điều kiện; tầng cuối cùng là tầng dự phòng không có điều kiện. Hãy dùng độ dài đầu vào đầy đủ cho điều kiện tầng để tránh chọn sai tầng khi cache hit làm giảm token đầu vào tính phí.",
-    "All conditions must match before this tier is used.": "All conditions must match before this tier is used.",
-    "Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
-    "Expression": "Biểu thức",
-    "Fallback tier": "Fallback tier",
-    "Full input length": "Độ dài đầu vào đầy đủ",
-    "Input price is required before saving dependent prices.": "Cần có giá đầu vào trước khi lưu các giá phụ thuộc.",
-    "Image input price": "Giá đầu vào hình ảnh",
-    "Image output price": "Giá đầu ra hình ảnh",
-    "Media pricing": "Media pricing",
-    "New model": "Mô hình mới",
-    "No separate media pricing configured.": "No separate media pricing configured.",
-    "Open a source model first": "Mở một mô hình nguồn trước",
-    "Output token price for generated tokens.": "Giá token đầu ra cho nội dung được tạo.",
-    "Per-request": "Theo yêu cầu",
-    "Save preview": "Xem trước lưu",
-    "Select at least one target model": "Chọn ít nhất một mô hình đích",
-    "Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
-    "Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
-    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "Mô hình này có cả giá cố định và cài đặt tỷ lệ. Lưu chế độ hiện tại sẽ ghi lại các trường xung đột.",
-    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "Mô hình này có cả giá cố định và cài đặt giá theo token. Lưu chế độ hiện tại sẽ ghi lại các trường xung đột.",
-    "This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
-    "Tier conditions": "Tier conditions",
-    "Token price for audio input.": "Giá token cho đầu vào âm thanh.",
-    "Token price for audio output.": "Giá token cho đầu ra âm thanh.",
-    "Token price for cache reads.": "Giá token cho lượt đọc cache.",
-    "Token price for creating cache entries.": "Giá token cho việc tạo mục cache.",
-    "Token price for image input.": "Giá token cho đầu vào hình ảnh.",
-    "USD price per 1M input tokens.": "Giá USD cho mỗi 1 triệu token đầu vào.",
-    "USD price per 1M tokens.": "Giá USD cho mỗi 1 triệu token.",
-    "{{count}} selected targets available for bulk copy.": "Có {{count}} mục tiêu đã chọn để sao chép hàng loạt.",
-    "Base input price only": "Chỉ có giá đầu vào cơ bản",
-    "Expression based": "Dựa trên biểu thức",
-    "Expression pricing": "Định giá bằng biểu thức",
-    "Fixed request price": "Giá cố định theo yêu cầu",
-    "Includes request rules": "Bao gồm quy tắc yêu cầu",
-    "No base input price": "Chưa có giá đầu vào cơ bản",
-    "No models configured. Use Add model to get started.": "Chưa cấu hình mô hình. Dùng Thêm mô hình để bắt đầu.",
-    "Price summary": "Tóm tắt giá",
-    "Select a model to edit pricing": "Chọn mô hình để chỉnh sửa giá",
-    "Tiered pricing": "Định giá theo tầng",
-    "Unset price": "Chưa đặt giá",
-    "Use the full-width table to scan prices, then select a row to edit it here.": "Duyệt giá trong bảng, rồi chọn một hàng để chỉnh sửa tại đây.",
-    "extras": "mục bổ sung",
-    "tiers": "tầng"
+    "Zoom": "Zoom"
   }
 }

+ 112 - 77
web/default/src/i18n/locales/zh.json

@@ -38,6 +38,7 @@
     "{{count}} models": "{{count}} 个模型",
     "{{count}} months ago": "{{count}} 个月前",
     "{{count}} override": "{{count}} 个覆盖",
+    "{{count}} selected targets available for bulk copy.": "已选择 {{count}} 个目标,可用于批量复制。",
     "{{count}} tiers": "{{count}} 档",
     "{{count}} vendors": "{{count}} 家厂商",
     "{{count}} weeks ago": "{{count}} 周前",
@@ -96,6 +97,7 @@
     "7 Days": "7 天",
     "7 days ago": "7 天前",
     "80,443,8080": "80,443,8080",
+    "A billing multiplier. Lower ratios mean lower API call costs.": "计费乘数,倍率越低,API 调用费用越低。",
     "About": "关于",
     "Accept Unpriced Models": "接受未定价模型",
     "Accepts a JSON array of model identifiers that support the Imagine API.": "接受支持 Imagine API 的模型标识符的 JSON 数组。",
@@ -158,6 +160,7 @@
     "Add Mode": "添加模式",
     "Add model": "添加模型",
     "Add Model": "添加模型",
+    "Add model pricing": "添加模型定价",
     "Add Models": "新增模型",
     "Add new amount": "添加新金额",
     "Add new redemption code(s) by providing necessary info.": "通过提供必要信息添加新的兑换码。",
@@ -236,6 +239,7 @@
     "Ali": "阿里",
     "All": "全部",
     "All categories": "全部分类",
+    "All conditions must match before this tier is used.": "所有条件都满足后才会使用该档位。",
     "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "所有编辑都是覆盖操作。留空字段将保持当前值不变。",
     "All files exceed the maximum size.": "所有文件都超过最大尺寸。",
     "All Groups": "所有分组",
@@ -354,6 +358,7 @@
     "Append value to array / string / object end": "把值追加到数组/字符串/对象末尾",
     "appended": "已追加",
     "Application": "应用",
+    "Applied {{name}} pricing to {{count}} models": "已将 {{name}} 的定价应用到 {{count}} 个模型",
     "Applies to custom completion endpoints. JSON map of model → ratio.": "适用于自定义补全端点。模型 → 比例的 JSON 映射。",
     "Apply All Upstream Updates": "应用所有上游更新",
     "Apply Filters": "应用筛选器",
@@ -383,6 +388,8 @@
     "Array of chat client presets. Each item is an object with one key-value pair: client name and its URL.": "聊天客户端预设数组。每个项目都是一个对象,包含一个键值对:客户端名称及其 URL。",
     "Asc": "升序",
     "Ask anything": "随便问",
+    "Assigned by administrator only": "仅管理员分配",
+    "Assigned by administrators and used to represent a user level, such as default or vip.": "由管理员分配,用于表示用户等级,例如 default 或 vip。",
     "Async task refund": "异步任务退款",
     "At least one model regex pattern is required": "至少需要一个模型正则匹配模式",
     "At least one valid key source is required": "至少需要一个有效的密钥来源",
@@ -393,10 +400,13 @@
     "Audio In": "音频输入",
     "Audio input": "音频输入",
     "Audio Input": "语音输入",
+    "Audio input price": "音频输入价格",
     "Audio Input Price": "音频输入价格",
     "Audio Out": "音频输出",
     "Audio output": "音频输出",
     "Audio Output": "语音输出",
+    "Audio output price": "音频输出价格",
+    "Audio output price requires an audio input price.": "音频输出价格需要先填写音频输入价格。",
     "Audio playback failed": "音频无法播放",
     "Audio Preview": "音乐预览",
     "Audio ratio": "音频倍率",
@@ -413,6 +423,7 @@
     "Auto Ban": "自动封禁",
     "Auto detect (default)": "自动检测(默认)",
     "Auto Disabled": "自动禁用",
+    "Auto group behavior": "自动分组行为",
     "Auto Group Chain": "自动分组链",
     "Auto refresh": "自动刷新",
     "Auto Sync Upstream Models": "自动同步上游模型",
@@ -469,6 +480,8 @@
     "Bark Push URL": "Bark 推送 URL",
     "Base address provided by your Epay service": "您的 Epay 服务提供的基础地址",
     "Base amount. Actual deduction = base amount × system group rate.": "基础金额,实际扣费 = 基础金额 × 系统分组倍率。",
+    "Base input and output token prices for this tier.": "该档位的基础输入与输出 token 价格。",
+    "Base input price only": "仅基础输入价格",
     "Base Limits": "基础额度",
     "Base multipliers applied when users select specific groups.": "当用户选择特定分组时应用的基础乘数。",
     "Base Price": "基础价格",
@@ -493,6 +506,8 @@
     "Batch upstream model updates applied: {{channels}} channels, {{added}} added, {{removed}} removed, {{fails}} failed": "已批量处理上游模型更新:渠道 {{channels}} 个,加入 {{added}} 个,删除 {{removed}} 个,失败 {{fails}} 个",
     "Best for single-tenant deployments. Pricing and billing options stay hidden.": "适合单用户部署。定价和计费选项将被隐藏。",
     "Best TTFT": "最优 TTFT",
+    "Billable input tokens": "计费输入 token",
+    "Billable output tokens": "计费输出 token",
     "Billing": "计费",
     "Billing & Payment": "计费与支付",
     "Billing currency": "计费货币",
@@ -545,6 +560,8 @@
     "By category": "按行业",
     "By model author": "按模型厂商",
     "Cache": "缓存",
+    "Cache create (1h) price": "1 小时缓存写入价格",
+    "Cache create price": "缓存写入价格",
     "Cache Creation": "缓存创建",
     "Cache Creation (1h)": "缓存创建 (1h)",
     "Cache Creation (5m)": "缓存创建 (5m)",
@@ -553,13 +570,16 @@
     "Cache Directory Info": "缓存目录信息",
     "Cache Entries": "缓存条目",
     "Cache mode": "缓存模式",
+    "Cache pricing": "缓存价格",
     "Cache ratio": "缓存倍率",
     "Cache Read": "缓存读取",
+    "Cache read price": "缓存读取价格",
     "Cache repeated prompt prefixes for cheaper, faster reuse": "缓存重复的提示词前缀,复用更快、更省钱",
     "Cache write": "缓存写入",
     "Cache Write": "缓存写入",
     "Cache Write (1h)": "缓存写入 (1h)",
     "Cache Write (5m)": "缓存写入 (5m)",
+    "Cache write price": "缓存写入价格",
     "Cached": "缓存",
     "Cached input": "缓存输入",
     "Calculated price: ${{price}} per 1M tokens": "计算价格:${{price}} / 1M tokens",
@@ -592,6 +612,7 @@
     "Change language": "更改语言",
     "Change Password": "更改密码",
     "Change To": "更改为",
+    "Changes are written to the settings draft on save.": "保存后会写入设置草稿。",
     "Changing...": "修改中...",
     "Channel": "渠道",
     "Channel Affinity": "渠道亲和性",
@@ -663,6 +684,7 @@
     "Classic (Legacy Frontend)": "经典前端",
     "Claude": "Claude",
     "Claude CLI Header Passthrough": "Claude CLI 请求头透传",
+    "Clean": "无冲突",
     "Clean history logs": "清理历史日志",
     "Clean logs": "清理日志",
     "Clean up inactive cache": "清理不活跃缓存",
@@ -755,6 +777,7 @@
     "Complete these steps to finish the initial installation.": "完成这些步骤以完成初始安装。",
     "Completed": "已完成",
     "Completion": "补全",
+    "Completion price": "补全价格",
     "Completion price ($/1M tokens)": "完成价格(美元/百万令牌)",
     "Completion ratio": "补全倍率",
     "Concatenate channel system prompt with user&apos;s prompt": "将渠道系统提示与用户的提示连接起来",
@@ -894,6 +917,7 @@
     "Copied: {{model}}": "已复制: {{model}}",
     "Copied!": "已复制!",
     "Copy": "复制",
+    "Copy {{name}} pricing": "复制 {{name}} 定价",
     "Copy a request header": "复制请求头",
     "Copy All": "全部复制",
     "Copy all backup codes": "复制所有备份代码",
@@ -924,8 +948,10 @@
     "Copy token": "复制令牌",
     "Copy URL": "复制 URL",
     "Copywriting, ad creative, SEO": "文案、广告创意、SEO",
+    "Core concepts": "核心概念",
     "Core Configuration": "核心配置",
     "Core Features": "核心功能",
+    "Core pricing": "核心价格",
     "Cost": "费用",
     "Cost in USD per request, regardless of tokens used.": "每请求的美元费用,不考虑使用的令牌数。",
     "Cost Tracking": "成本跟踪",
@@ -1148,6 +1174,7 @@
     "disabled": "已禁用",
     "Disabled": "已禁用",
     "Disabled all channels with tag: {{tag}}": "已禁用标签「{{tag}}」下的所有渠道",
+    "Disabled lanes are omitted on save.": "关闭的价格通道保存时会被省略。",
     "Disabled Reason": "禁用原因",
     "Disabled Time": "禁用时间",
     "Disabling...": "禁用中...",
@@ -1206,6 +1233,7 @@
     "Drawing Logs": "绘图日志",
     "Drawing task records": "绘图任务记录",
     "Duplicate": "重复",
+    "Duplicate group names: {{names}}": "存在重复的分组名称:{{names}}",
     "Duration": "耗时",
     "Duration (hours)": "时长 (小时)",
     "Duration Settings": "有效期设置",
@@ -1257,12 +1285,15 @@
     "Each item must have exactly one key-value pair.": "每个条目必须恰好包含一个键值对。",
     "Each line represents one keyword. Leave blank to disable the list but keep the switch states.": "每行代表一个关键词。留空以禁用列表,但保留开关状态。",
     "Each tier supports 0~2 conditions (over len, p, c); the last tier is the catch-all without conditions. Use len (full input length, including cache hits) for tier conditions to avoid mis-routing when cache hits reduce p.": "每个档位支持 0~2 个条件(针对 len、p、c),最后一档为兜底档无需条件。建议条件使用 len(完整输入长度,含缓存命中),避免缓存命中降低 p 导致档位误判。",
+    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "每个档位最多支持 2 个条件;最后一个档位是不带条件的兜底档。建议使用完整输入长度作为档位条件,避免缓存命中减少计费输入 token 后误判档位。",
+    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "每个档位最多 2 个条件,最后一个无条件档位为兜底档。",
     "Earn rewards when your referrals add funds. Transfer accumulated rewards to your balance anytime.": "当您的推荐人充值时即可获得奖励。随时将累计奖励转移到您的余额。",
     "Edit": "编辑",
     "Edit {{title}}": "编辑{{title}}",
     "Edit all channels with tag:": "编辑所有带有标签的渠道:",
     "Edit Announcement": "编辑公告",
     "Edit API Shortcut": "编辑 API 快捷方式",
+    "Edit billing ratios and user-selectable groups in one table.": "在一个表格中编辑计费倍率和用户可选分组。",
     "Edit Channel": "编辑渠道",
     "Edit chat preset": "编辑聊天预设",
     "Edit discount tier": "编辑折扣档位",
@@ -1272,6 +1303,7 @@
     "Edit JSON text directly. Format will be validated on save.": "直接编辑 JSON 文本,保存时会校验格式。",
     "Edit model": "编辑模型",
     "Edit Model": "编辑模型",
+    "Edit model pricing": "编辑模型定价",
     "Edit OAuth Provider": "编辑 OAuth 提供商",
     "Edit payment method": "编辑支付方式",
     "Edit Prefill Group": "编辑预填充组",
@@ -1297,6 +1329,7 @@
     "Email Verification": "电子邮件验证",
     "Email, summarisation, knowledge work": "邮件、摘要与知识工作",
     "Embeddings": "嵌入",
+    "Empty": "空",
     "Empty value will be saved as {}.": "空值将保存为 {}。",
     "Enable": "启用",
     "Enable 2FA": "启用 2FA",
@@ -1475,9 +1508,12 @@
     "Expose grouped Uptime Kuma status pages directly on the dashboard": "直接在仪表板上显示分组的 Uptime Kuma 状态页面",
     "Expose ratio API": "暴露倍率接口",
     "Exposes the pricing/models catalog in the top navigation.": "在顶部导航中显示定价/模型目录。",
+    "Expression": "表达式",
+    "Expression based": "基于表达式",
     "Expression billing": "表达式计费",
     "Expression editor": "表达式编辑器",
     "Expression error": "表达式错误",
+    "Expression pricing": "表达式计费",
     "Extend": "延长",
     "Extend deployment": "延长部署",
     "Extend failed": "延长失败",
@@ -1489,6 +1525,7 @@
     "External Speed Test": "外部速度测试",
     "Extra": "额外",
     "Extra Notes (Optional)": "额外备注(可选)",
+    "extras": "额外项",
     "Fail Reason": "失败原因",
     "Fail Reason Details": "失败原因详情",
     "Failed": "失败",
@@ -1610,6 +1647,7 @@
     "Failed to update user": "更新用户失败",
     "Failure keywords": "失败关键词",
     "Fair": "公平",
+    "Fallback tier": "兜底档位",
     "FAQ": "常见问答",
     "FAQ added. Click \"Save Settings\" to apply.": "FAQ 已添加。点击 \"保存设置\" 以应用。",
     "FAQ deleted. Click \"Save Settings\" to apply.": "FAQ 已删除。点击 \"保存设置\" 以应用。",
@@ -1679,6 +1717,7 @@
     "Fixed abilities: {{success}} succeeded, {{fails}} failed": "修复能力:{{success}} 个成功,{{fails}} 个失败",
     "Fixed price": "固定价格",
     "Fixed price (USD)": "固定价格 (USD)",
+    "Fixed request price": "固定按次价格",
     "Floating": "浮动",
     "FluentRead extension not detected. Please ensure it is installed and active.": "未检测到 FluentRead 扩展。请确保已安装并激活。",
     "Flush interval (minutes)": "刷库间隔(分钟)",
@@ -1732,6 +1771,7 @@
     "Full API Key": "完整 API 密钥",
     "Full Base URL (supports": "完整基础 URL (支持",
     "Full Code": "完整代码",
+    "Full input length": "完整输入长度",
     "Full layout": "全屏布局",
     "Full width": "全宽",
     "Function calling": "函数调用",
@@ -1785,10 +1825,10 @@
     "gpt-4": "gpt-4",
     "gpt-4, claude-3-opus, etc.": "gpt-4, claude-3-opus, 等",
     "GPU count": "GPU 数量",
-    "Greater Than": "大于",
-    "Greater Than or Equal": "大于等于",
     "Greater than": "大于",
+    "Greater Than": "大于",
     "Greater than or equal": "大于等于",
+    "Greater Than or Equal": "大于等于",
     "Grok": "Grok",
     "Grok Settings": "Grok 设置",
     "Group": "分组",
@@ -1797,6 +1837,7 @@
     "Group channels by tag for batch operations": "按标签对渠道进行分组以进行批量操作",
     "Group config overrides global limits, shares the same period": "分组配置覆盖全局限制,共享同一周期",
     "Group deleted. Click \"Save Settings\" to apply.": "组已删除。点击 \"保存设置\" 以应用。",
+    "Group description": "分组描述",
     "Group details": "分组详情",
     "Group identifier": "分组标识符",
     "Group is required": "组是必需的",
@@ -1805,6 +1846,7 @@
     "Group name cannot be changed when editing.": "编辑时无法更改组名称。",
     "Group prices cannot be expanded because this expression is not a standard tiered pricing expression.": "该表达式不是标准分档计费表达式,无法展开分组价格。",
     "Group Pricing": "分组定价",
+    "Group pricing usage guide": "分组定价使用教程",
     "group ratio": "分组倍率",
     "Group Ratio": "分组倍率",
     "Group ratios": "分组比例",
@@ -1906,14 +1948,17 @@
     "If an upstream error contains any of these keywords (case insensitive), the channel will be disabled automatically.": "如果上游错误包含以下任何关键字(不区分大小写),渠道将自动禁用。",
     "If authorization succeeds, the generated JSON will be inserted into the key field. You still need to save the channel to persist it.": "授权成功后,生成的 JSON 将插入密钥字段。您仍需保存频道以持久化。",
     "If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing": "如果连接上游 One API 或 New API 中继项目,除非您知道自己在做什么,否则请使用 OpenAI 类型",
-    "If this keeps happening, please report it on GitHub Issues.": "如果问题持续出现,请到 GitHub Issues 反馈。",
+    "If default auto group is enabled, newly created tokens start with auto instead of an empty group.": "如果启用默认 auto 分组,新建令牌会默认使用 auto,而不是空分组。",
     "If the affinity channel fails and retry succeeds on another channel, update affinity to the successful channel.": "如果亲和到的渠道失败,重试到其他渠道成功后,将亲和更新到成功的渠道。",
+    "If this keeps happening, please report it on GitHub Issues.": "如果问题持续出现,请到 GitHub Issues 反馈。",
     "Ignored upstream models": "已忽略上游模型",
     "Image": "图片",
     "Image Generation": "图片生成",
     "Image In": "图像输入",
     "Image input": "图片输入",
+    "Image input price": "图像输入价格",
     "Image Out": "图像输出",
+    "Image output price": "图像输出价格",
     "Image Preview": "图片预览",
     "Image ratio": "图片倍率",
     "Image to Video": "图生视频",
@@ -1927,6 +1972,7 @@
     "Include Group": "包含分组",
     "Include Model": "包含模型",
     "Include Rule Name": "包含规则名",
+    "Includes request rules": "包含请求规则",
     "Including failed requests, 0 = unlimited": "包括失败的请求,0 = 无限制",
     "Index": "索引",
     "Initial quota given to new users": "授予新用户的初始配额",
@@ -1938,6 +1984,7 @@
     "Input": "输入",
     "Input mode": "输入模式",
     "Input price": "输入价格",
+    "Input price is required before saving dependent prices.": "保存依赖价格前必须先填写输入价格。",
     "Input tokens": "输入 token",
     "Input Tokens": "输入 Token",
     "Inset": "内嵌",
@@ -2068,10 +2115,10 @@
     "Legacy Format Template": "旧格式模板",
     "Legal": "法律",
     "Less": "更少",
-    "Less Than": "小于",
-    "Less Than or Equal": "小于等于",
     "Less than": "小于",
+    "Less Than": "小于",
     "Less than or equal": "小于等于",
+    "Less Than or Equal": "小于等于",
     "License": "许可证",
     "Light": "浅色",
     "Lightning Fast": "极速",
@@ -2188,6 +2235,7 @@
     "Maximum tokens per response": "单次响应最大 token 数",
     "maxRequests ≥ 0, maxSuccess ≥ 1, both ≤ 2,147,483,647": "maxRequests ≥ 0, maxSuccess ≥ 1,两者均 ≤ 2,147,483,647",
     "May be used for training by upstream provider": "可能被上游提供商用于训练",
+    "Media pricing": "多模态价格",
     "Median time-to-first-token (TTFT) sampled hourly per group": "按小时采样的各分组首 token 延迟(TTFT)中位数",
     "Medical Q&A, mental health support": "医疗问答与心理健康支持",
     "Memory Hits": "内存命中",
@@ -2255,6 +2303,8 @@
     "Model performance metrics": "模型性能指标",
     "Model Price": "模型价格",
     "Model Price Not Configured": "模型价格未配置",
+    "Model prices": "模型价格",
+    "Model prices reset successfully": "模型价格重置成功",
     "Model Pricing": "模型定价",
     "Model pull failed: {{msg}}": "模型拉取失败:{{msg}}",
     "Model ratio": "模型倍率",
@@ -2365,6 +2415,7 @@
     "New API Project Repository:": "New API 项目仓库:",
     "New Format Template": "新格式模板",
     "New Group": "新建分组",
+    "New model": "新模型",
     "New Models ({{count}})": "新模型 ({{count}})",
     "New name will be:": "新名称将是:",
     "New password": "新密码",
@@ -2393,6 +2444,7 @@
     "No available models": "没有可用模型",
     "No available Web chat links": "没有可用的 Web 聊天链接",
     "No backup": "无备份",
+    "No base input price": "未设置基础输入价格",
     "No billing records found": "未找到账单记录",
     "No capabilities reported for this model.": "该模型暂未报告任何能力。",
     "No Change": "无变化",
@@ -2428,6 +2480,7 @@
     "No group found.": "未找到分组。",
     "No group-based rate limits configured. Click \"Add group\" to get started.": "未配置基于组的速率限制。点击“添加组”开始使用。",
     "No groups match your search": "没有组匹配您的搜索",
+    "No groups yet. Add a group to get started.": "暂无分组,添加一个分组开始配置。",
     "No header overrides configured.": "未配置标头覆盖。",
     "No history data available": "暂无历史数据",
     "No incidents in the last 24 hours": "最近 24 小时无异常",
@@ -2449,6 +2502,7 @@
     "No models available": "没有可用的模型",
     "No models available in this category": "该分类下没有可用模型",
     "No models available. Create your first model to get started.": "没有可用的模型。创建您的第一个模型即可开始使用。",
+    "No models configured. Use Add model to get started.": "暂无模型配置。使用添加模型开始配置。",
     "No models fetched from upstream": "未从上游获取模型",
     "No models fetched yet.": "尚未获取模型。",
     "No models found": "未找到模型",
@@ -2493,6 +2547,7 @@
     "No Retry": "不重试",
     "No rules yet": "暂无规则",
     "No rules yet. Add a group below to get started.": "暂无规则。请在下方添加分组以开始。",
+    "No separate media pricing configured.": "未单独配置多模态价格。",
     "No status code mappings configured.": "未配置状态码映射。",
     "No subscription plans yet": "暂无订阅套餐",
     "No subscription records": "暂无订阅记录",
@@ -2579,6 +2634,7 @@
     "Online topup is not enabled. Please use redemption code or contact administrator.": "尚未启用在线充值。请使用兑换码或联系管理员。",
     "Only allow specific email domains": "仅允许特定的电子邮件域名",
     "Only available for admins. When enabled, you will receive a summary notification via your selected method when the scheduled model check detects upstream model changes or check failures.": "仅管理员可用。启用后,当定时模型检查检测到上游模型变更或检查失败时,您将通过所选方式收到汇总通知。",
+    "Only configured combinations are overridden. All other calls keep the token group base ratio.": "只有已配置的组合会被覆盖,其他调用仍使用令牌分组的基础倍率。",
     "Only selected fields will be overwritten. You can re-run the sync wizard if new conflicts appear.": "仅选定的字段将被覆盖。如果出现新的冲突,您可以重新运行同步向导。",
     "Only successful requests": "仅成功的请求",
     "Only successful requests count toward this limit.": "仅成功的请求计入此限制。",
@@ -2586,6 +2642,7 @@
     "Oops! Page Not Found!": "糟糕!页面未找到!",
     "Oops! Something went wrong": "糟糕!出错了",
     "Open": "打开",
+    "Open a source model first": "请先打开一个源模型",
     "Open authorization page": "打开授权页",
     "Open CC Switch": "打开 CC Switch",
     "Open in chat": "在聊天中打开",
@@ -2641,9 +2698,11 @@
     "Output aspect ratio": "输出宽高比",
     "Output image size": "输出图像尺寸",
     "Output price": "输出价格",
+    "Output token price for generated tokens.": "生成内容的输出 token 价格。",
     "Output tokens": "输出 token",
     "Output Tokens": "输出 Token",
     "overall": "总体",
+    "Overnight range": "跨日范围",
     "override": "覆盖",
     "Override": "覆盖",
     "Override Anthropic headers, defaults, and thinking adapter behavior": "覆盖 Anthropic 标头、默认值和思维适配器行为",
@@ -2656,7 +2715,6 @@
     "Override Rules": "覆盖规则",
     "Override the endpoint used for testing. Leave empty to auto detect.": "覆盖用于测试的端点。留空以自动检测。",
     "overrides for matching model prefix.": "为匹配模型前缀的覆盖价。",
-    "Overnight range": "跨日范围",
     "Overview": "概览",
     "Overwritten": "已覆盖",
     "Page": "页面",
@@ -2751,6 +2809,7 @@
     "Per-call": "每次调用",
     "Per-feature metered windows split by model or capability.": "按模型或能力拆分的附加计费能力窗口。",
     "Per-group performance": "各分组性能",
+    "Per-request": "按次",
     "Per-request (fixed price)": "按请求计费(固定价格)",
     "Per-token": "按 Token",
     "Per-token (ratio based)": "按令牌计费(基于比例)",
@@ -2854,6 +2913,7 @@
     "Prefix used when displaying prices": "显示价格时使用的前缀",
     "Prefix/Suffix Text": "前后缀文本",
     "Premium chat models": "高级聊天模型",
+    "Premium plan, half price": "高级套餐,半价优惠",
     "Preparing chat keys…": "正在准备聊天密钥…",
     "Preparing your chat link, please try again in a moment.": "正在准备您的聊天链接,请稍后再试。",
     "Preparing your chat link…": "正在准备您的聊天链接...",
@@ -2890,6 +2950,7 @@
     "Price estimation description": "完成硬件类型、部署位置、副本数量等设置后,价格将自动计算。",
     "Price ID": "价格 ID",
     "Price mode (USD per 1M tokens)": "价格模式(每 100 万个 token 的美元价格)",
+    "Price summary": "价格摘要",
     "price_xxx": "price_xxx",
     "Price:": "价格:",
     "Price: High to Low": "价格:从高到低",
@@ -2901,6 +2962,8 @@
     "Pricing & Display": "定价与显示",
     "Pricing by Group": "按分组定价",
     "Pricing Configuration": "定价配置",
+    "Pricing group example": "定价分组示例",
+    "Pricing groups": "定价分组",
     "Pricing mode": "定价模式",
     "Pricing Ratios": "定价比例",
     "Pricing Type": "定价类型",
@@ -2943,8 +3006,6 @@
     "Provide Markdown, HTML, or an external URL for the user agreement": "提供 Markdown、HTML 或外部 URL 作为用户协议",
     "Provide per-category safety overrides as JSON. Use `default` for fallback values.": "以 JSON 格式提供按类别划分的安全覆盖。使用 `default` 作为回退值。",
     "Provide per-model header overrides as JSON. Useful for enabling beta features such as expanded context windows.": "以 JSON 格式提供按模型划分的标头覆盖。可用于启用测试功能,例如扩展上下文窗口。",
-    "Public model catalog and pricing page.": "公开模型目录和价格页面。",
-    "Public rankings page based on live usage data.": "基于真实用量数据的公开排行榜页面。",
     "Provider": "提供商",
     "Provider & data privacy": "厂商与数据隐私",
     "Provider created successfully": "提供商创建成功",
@@ -2957,6 +3018,8 @@
     "Prune Object Items": "清理对象项",
     "Prune object items by conditions": "按条件清理对象中的子项",
     "Prune Rule (string or JSON object)": "清理规则(字符串或 JSON 对象)",
+    "Public model catalog and pricing page.": "公开模型目录和价格页面。",
+    "Public rankings page based on live usage data.": "基于真实用量数据的公开排行榜页面。",
     "Publish Date": "发布日期",
     "Published": "已发布",
     "Published:": "已发布:",
@@ -3171,6 +3234,7 @@
     "Resend ({{seconds}}s)": "重新发送 ({{seconds}}s)",
     "Reset": "重置",
     "Reset 2FA": "重置 2FA",
+    "Reset all model prices?": "重置所有模型价格吗?",
     "Reset all model ratios?": "重置所有模型比例吗?",
     "Reset all settings to default values": "将所有设置重置为默认值",
     "Reset at:": "重置于:",
@@ -3181,6 +3245,7 @@
     "Reset Passkey": "重置 Passkey",
     "Reset password": "重置密码",
     "Reset Period": "重置周期",
+    "Reset prices": "重置价格",
     "Reset ratios": "重置比例",
     "Reset Stats": "重置统计",
     "Reset to default": "重置为默认",
@@ -3272,12 +3337,14 @@
     "Save group ratios": "保存分组比率",
     "Save io.net settings": "保存 io.net 设置",
     "Save log settings": "保存日志设置",
+    "Save model prices": "保存模型价格",
     "Save model ratios": "保存模型比率",
     "Save Models": "保存模型",
     "Save monitoring rules": "保存监控规则",
     "Save navigation": "保存导航",
     "Save notice": "保存通知",
     "Save Preferences": "保存偏好设置",
+    "Save preview": "保存预览",
     "Save rate limits": "保存速率限制",
     "Save sensitive words": "保存敏感词",
     "Save Settings": "保存设置",
@@ -3340,6 +3407,7 @@
     "Select a color": "选择颜色",
     "Select a group": "选择一个分组",
     "Select a group type": "选择分组类型",
+    "Select a model to edit pricing": "选择一个模型编辑定价",
     "Select a preset...": "选择一个预设...",
     "Select a role": "选择角色",
     "Select a rule to edit.": "请选择一条规则进行编辑。",
@@ -3353,6 +3421,7 @@
     "Select an operation mode and enter the amount": "选择操作模式并输入金额",
     "Select announcement type": "选择公告类型",
     "Select at least one field to overwrite.": "请选择至少一个要覆盖的字段。",
+    "Select at least one target model": "请至少选择一个目标模型",
     "Select border radius": "选择圆角大小",
     "Select channel type": "选择渠道类型",
     "Select color preset": "选择颜色预设",
@@ -3406,6 +3475,7 @@
     "selected": "已选择",
     "selected channel(s). Leave empty to remove tag.": "选定的渠道。留空以移除标签。",
     "Selected conflicts were overwritten successfully.": "选中的冲突已成功覆盖。",
+    "Selected when creating a token and used as the default billing group for API calls.": "创建令牌时选择,用作 API 调用的默认计费分组。",
     "Self-Use Mode": "自用模式",
     "Send": "发送",
     "Send code": "发送验证码",
@@ -3413,6 +3483,7 @@
     "Sending...": "发送中...",
     "Sensitive Words": "敏感词",
     "Sent the API key to FluentRead.": "API 密钥已发送至 FluentRead。",
+    "Separate image/audio prices are enabled.": "已启用独立图像/音频价格。",
     "Serve multiple users or teams with billing and quota control.": "为多个用户或团队提供计费和配额管理服务。",
     "Server Address": "服务器地址",
     "Server IP": "服务器 IP",
@@ -3436,6 +3507,7 @@
     "Set quota amount and limits": "设置令牌可用额度和数量",
     "Set Request Header": "设置请求头",
     "Set runtime request header: override entire value, or manipulate comma-separated tokens": "设置运行期请求头:可直接覆盖整条值,也可对逗号分隔的 token 做处理",
+    "Set separate prices for cache reads and writes.": "为缓存读取与写入设置独立价格。",
     "Set Tag": "设置标签",
     "Set tag for selected channels": "为选定的渠道设置标签",
     "Set the language used across the interface": "设置界面显示语言",
@@ -3513,10 +3585,14 @@
     "Space-separated OAuth scopes": "以空格分隔的OAuth作用域",
     "Spark model version, e.g., v2.1 (version number in API URL)": "Spark 模型版本,例如 v2.1(API URL 中的版本号)",
     "Special billing expression": "特殊计费表达式",
+    "Special group": "特殊分组",
+    "Special ratios override the token group ratio for specific user group and token group combinations.": "特殊倍率会针对特定用户分组和令牌分组组合覆盖令牌分组倍率。",
     "Special usable group rules": "特殊可用分组规则",
+    "Special usable group rules can add, remove, or append selectable token groups for a specific user group.": "特殊可用分组规则可以为特定用户分组添加、移除或追加可选令牌分组。",
     "SQLite stores all data in a single file. Make sure that file is persisted when running in containers.": "SQLite 将所有数据存储在单个文件中。在容器中运行时请确保该文件已持久化。",
     "SSRF Protection": "SSRF 保护",
     "Standard": "标准",
+    "Standard price": "标准价格",
     "Start": "开始",
     "Start a conversation to see messages here": "开始对话以在此处查看消息",
     "Start for free with generous limits. No credit card required.": "免费开始使用,额度充足,无需绑定信用卡。",
@@ -3731,12 +3807,15 @@
     "This may cause cache failures.": "这可能导致缓存故障。",
     "This may take a few moments while we validate the request and update your session.": "这可能需要一些时间,因为我们正在验证请求并更新您的会话。",
     "This model has both fixed price and ratio billing conflicts": "此模型同时存在固定价格和比例计费冲突",
+    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "该模型同时存在固定价格和比例设置。保存当前模式会重写冲突字段。",
+    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "该模型同时存在固定价格和按 token 价格设置。保存当前模式会重写冲突字段。",
     "This model is not available in any group, or no group pricing information is configured.": "此模型在任何分组中均不可用,或未配置分组定价信息。",
     "This month": "本月获得",
     "This page has not been created yet.": "此页面尚未创建。",
     "This project must be used in compliance with the": "此项目的使用必须遵守",
     "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "该记录由旧版本实例写入,缺少审计信息,建议将实例升级至最新版本以便记录服务器 IP、回调 IP、支付方式与系统版本等审计字段。",
     "This site currently has {{count}} models enabled": "本站当前已启用模型,总计 {{count}} 个",
+    "This tier catches any request that did not match earlier tiers.": "该档位会兜底匹配所有未命中前面档位的请求。",
     "this token group": "此令牌分组",
     "this user group": "此用户分组",
     "This user has no bindings": "该用户无任何绑定",
@@ -3758,19 +3837,20 @@
     "Throughput by group": "各分组吞吐量",
     "Throughput trend": "吞吐量趋势",
     "Tier": "档位",
+    "Tier conditions": "档位条件",
     "Tier name": "档位名称",
     "Tiered": "阶梯",
-    "Token prices": "Token 价格",
-    "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "每个档位最多 2 个条件,最后一个无条件档位为兜底档。",
     "Tiered (billing expression)": "阶梯计费(计费表达式)",
     "Tiered price table": "分档价格表",
+    "Tiered pricing": "阶梯计费",
+    "tiers": "档",
     "Time": "时间",
     "Time Granularity": "时间粒度",
     "Time remaining": "剩余时间",
     "Time window for rate limiting": "速率限制的时间窗口",
     "Time-based": "含时间条件",
-    "Time:": "时间:",
     "Time-sliced cache (Claude)": "分时缓存(Claude)",
+    "Time:": "时间:",
     "Timeline": "时间线",
     "times": "次",
     "Timing": "耗时",
@@ -3794,11 +3874,18 @@
     "Token Endpoint": "令牌端点",
     "Token Endpoint (Optional)": "Token 端点(可选)",
     "Token estimator": "Token 估算器",
+    "Token group": "令牌分组",
     "Token management": "令牌管理",
     "Token Management": "令牌管理",
     "Token Mgmt": "令牌管理",
     "Token Name": "令牌名称",
     "Token obtained from your Gotify application": "从您的 Gotify 应用程序获取的 Token",
+    "Token price for audio input.": "音频输入 token 价格。",
+    "Token price for audio output.": "音频输出 token 价格。",
+    "Token price for cache reads.": "缓存读取 token 价格。",
+    "Token price for creating cache entries.": "创建缓存条目的 token 价格。",
+    "Token price for image input.": "图像输入 token 价格。",
+    "Token prices": "Token 价格",
     "Token regenerated and copied to clipboard": "令牌已重新生成并复制到剪贴板",
     "Token share by model author across the last 24 hours": "过去 24 小时内各厂商的 Token 占比",
     "Token share by model author across the past few weeks": "最近几周内各厂商的 Token 占比",
@@ -3922,6 +4009,7 @@
     "Unbind failed": "解绑失败",
     "Unbound {{provider}}": "已解绑 {{provider}}",
     "Underground": "暗夜",
+    "Understand how user groups, token groups, ratios, and special rules work together.": "了解用户分组、令牌分组、倍率和特殊规则如何共同生效。",
     "Understand image inputs alongside text": "在文本之外理解图像输入",
     "Unexpected release payload": "意外的版本数据格式",
     "Unified API Gateway for": "统一 API 网关,服务于",
@@ -3935,6 +4023,7 @@
     "Unlimited": "无限制",
     "Unlimited Quota": "无限配额",
     "Unsaved changes": "未保存的更改",
+    "Unset price": "未设置价格",
     "Until": "至",
     "Untitled": "未命名",
     "Untrusted upstream data:": "不受信任的上游数据:",
@@ -3999,12 +4088,16 @@
     "URL is required": "URL 为必填项",
     "URL to your logo image (optional)": "您的徽标图片 URL(可选)",
     "Usage": "用量",
+    "Usage guide": "使用教程",
     "Usage logs": "使用日志",
     "Usage Logs": "使用日志",
     "Usage mode": "使用模式",
     "Usage-based": "基于使用量",
     "USD": "USD",
     "USD Exchange Rate": "美元汇率",
+    "USD price per 1M input tokens.": "每 100 万输入 token 的美元价格。",
+    "USD price per 1M tokens.": "每 100 万 token 的美元价格。",
+    "Use +: to add a group, -: to remove a default selectable group, or no prefix to append a group.": "使用 +: 添加分组,使用 -: 移除默认可选分组,不加前缀则追加分组。",
     "Use a compatible browser or device with biometric authentication or a security key to register a Passkey.": "请使用支持生物识别认证或安全密钥的兼容浏览器或设备来注册通行密钥。",
     "Use authenticator code": "使用验证器代码",
     "Use backup code": "使用备用代码",
@@ -4014,6 +4107,8 @@
     "Use Passkey to sign in without entering your password.": "使用通行密钥登录,无需输入密码。",
     "Use secure connection when sending emails": "发送电子邮件时使用安全连接",
     "Use sidebar shortcut": "使用侧边栏快捷方式",
+    "Use the full-width table to scan prices, then select a row to edit it here.": "先在表格中快速浏览价格,然后选择一行在这里编辑。",
+    "Use the pricing group table to manage the ratio and whether the group appears in the token creation dropdown.": "使用定价分组表管理倍率,以及该分组是否出现在创建令牌的下拉框中。",
     "Use this token for API authentication": "使用此令牌进行 API 身份验证",
     "Use your Passkey": "使用您的通行密钥",
     "used": "已使用",
@@ -4034,6 +4129,7 @@
     "User created successfully": "用户创建成功",
     "User dashboard and quota controls.": "用户仪表板和配额控制。",
     "User Exclusive Ratio": "专属倍率",
+    "User group": "用户分组",
     "User Group": "用户分组",
     "User group name": "用户分组名称",
     "User Group: {{ratio}}x": "用户分组:{{ratio}}x",
@@ -4047,6 +4143,7 @@
     "User Information": "用户信息",
     "User Menu": "用户菜单",
     "User personal functions": "用户个人功能",
+    "User selectable": "用户可选",
     "User Subscription Management": "用户订阅管理",
     "User updated successfully": "用户更新成功",
     "User Verification": "用户验证",
@@ -4058,6 +4155,7 @@
     "Users": "用户",
     "Users call the model on the left. The platform forwards the request to the upstream model on the right.": "用户调用左侧的模型。平台将请求转发给右侧的上游模型。",
     "Users must wait for a successful drawing before upscales or variations.": "用户必须等待成功的绘图完成,才能进行放大或变体。",
+    "Users only see groups marked as user selectable. Non-selectable groups can still be assigned by administrators.": "用户只能看到标记为用户可选的分组。不可选分组仍可由管理员分配。",
     "uses": "使用次数",
     "Validity": "有效期",
     "Validity Period": "有效期",
@@ -4188,6 +4286,7 @@
     "Well-Known URL": "Well-Known URL",
     "Well-Known URL must start with http:// or https://": "知名 URL 必须以 http:// 或 https:// 开头",
     "What would you like to know?": "您想了解什么?",
+    "When a token uses the auto group, the system tries groups from top to bottom until it finds an available group.": "当令牌使用 auto 分组时,系统会按从上到下的顺序尝试,直到找到可用分组。",
     "When conditions match, the final price is multiplied by X. Multiple matches multiply together; values < 1 act as discounts.": "条件满足时,最终价格乘以 X;多条命中的倍率会相乘;小于 1 的值为折扣。",
     "When enabled, if channels in the current group fail, it will try channels in the next group in order.": "开启后,当前分组渠道失败时会按顺序尝试下一个分组的渠道。",
     "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. SSD recommended.": "启用磁盘缓存后,大请求体将临时存储到磁盘而非内存,可显著降低内存占用。建议在 SSD 环境下使用。",
@@ -4195,6 +4294,7 @@
     "When enabled, newly created tokens start in the first auto group.": "启用后,新创建的令牌将从第一个自动分组开始。",
     "When enabled, prompts are scanned before reaching upstream models.": "启用后,提示将在到达上游模型之前被扫描。",
     "When enabled, the store field will be blocked": "开启后将阻止 store 字段透传",
+    "When enabled, users can pick this group when creating tokens.": "启用后,用户创建令牌时可以选择该分组。",
     "When enabled, violation requests will incur additional charges.": "开启后,违规请求将额外扣费。",
     "When enabled, zero-cost models also pre-consume quota before final settlement.": "启用后,零成本模型也会在最终结算前预先消耗配额。",
     "When no conditions are set, the operation always executes.": "没有条件时,默认总是执行该操作。",
@@ -4249,71 +4349,6 @@
     "Zero retention": "零数据保留",
     "Zhipu": "智谱",
     "Zhipu V4": "智谱 V4",
-    "Zoom": "缩放",
-    "Add model pricing": "添加模型定价",
-    "Applied {{name}} pricing to {{count}} models": "已将 {{name}} 的定价应用到 {{count}} 个模型",
-    "Audio input price": "音频输入价格",
-    "Audio output price": "音频输出价格",
-    "Audio output price requires an audio input price.": "音频输出价格需要先填写音频输入价格。",
-    "Billable input tokens": "计费输入 token",
-    "Billable output tokens": "计费输出 token",
-    "Cache create (1h) price": "1 小时缓存写入价格",
-    "Cache create price": "缓存写入价格",
-    "Cache read price": "缓存读取价格",
-    "Cache pricing": "缓存价格",
-    "Cache write price": "缓存写入价格",
-    "Changes are written to the settings draft on save.": "保存后会写入设置草稿。",
-    "Clean": "无冲突",
-    "Completion price": "补全价格",
-    "Core pricing": "核心价格",
-    "Copy {{name}} pricing": "复制 {{name}} 定价",
-    "Disabled lanes are omitted on save.": "关闭的价格通道保存时会被省略。",
-    "Edit model pricing": "编辑模型定价",
-    "Empty": "空",
-    "Each tier supports up to 2 conditions; the last tier is the catch-all without conditions. Use full input length for tier conditions to avoid mis-routing when cache hits reduce billable input tokens.": "每个档位最多支持 2 个条件;最后一个档位是不带条件的兜底档。建议使用完整输入长度作为档位条件,避免缓存命中减少计费输入 token 后误判档位。",
-    "All conditions must match before this tier is used.": "所有条件都满足后才会使用该档位。",
-    "Base input and output token prices for this tier.": "该档位的基础输入与输出 token 价格。",
-    "Expression": "表达式",
-    "Fallback tier": "兜底档位",
-    "Full input length": "完整输入长度",
-    "Input price is required before saving dependent prices.": "保存依赖价格前必须先填写输入价格。",
-    "Image input price": "图像输入价格",
-    "Image output price": "图像输出价格",
-    "Media pricing": "多模态价格",
-    "New model": "新模型",
-    "No separate media pricing configured.": "未单独配置多模态价格。",
-    "Open a source model first": "请先打开一个源模型",
-    "Output token price for generated tokens.": "生成内容的输出 token 价格。",
-    "Per-request": "按次",
-    "Save preview": "保存预览",
-    "Select at least one target model": "请至少选择一个目标模型",
-    "Separate image/audio prices are enabled.": "已启用独立图像/音频价格。",
-    "Set separate prices for cache reads and writes.": "为缓存读取与写入设置独立价格。",
-    "This model has both fixed-price and ratio settings. Saving the current mode will rewrite the conflicting fields.": "该模型同时存在固定价格和比例设置。保存当前模式会重写冲突字段。",
-    "This model has both fixed-price and token-price settings. Saving the current mode will rewrite the conflicting fields.": "该模型同时存在固定价格和按 token 价格设置。保存当前模式会重写冲突字段。",
-    "This tier catches any request that did not match earlier tiers.": "该档位会兜底匹配所有未命中前面档位的请求。",
-    "Tier conditions": "档位条件",
-    "Token price for audio input.": "音频输入 token 价格。",
-    "Token price for audio output.": "音频输出 token 价格。",
-    "Token price for cache reads.": "缓存读取 token 价格。",
-    "Token price for creating cache entries.": "创建缓存条目的 token 价格。",
-    "Token price for image input.": "图像输入 token 价格。",
-    "USD price per 1M input tokens.": "每 100 万输入 token 的美元价格。",
-    "USD price per 1M tokens.": "每 100 万 token 的美元价格。",
-    "{{count}} selected targets available for bulk copy.": "已选择 {{count}} 个目标,可用于批量复制。",
-    "Base input price only": "仅基础输入价格",
-    "Expression based": "基于表达式",
-    "Expression pricing": "表达式计费",
-    "Fixed request price": "固定按次价格",
-    "Includes request rules": "包含请求规则",
-    "No base input price": "未设置基础输入价格",
-    "No models configured. Use Add model to get started.": "暂无模型配置。使用添加模型开始配置。",
-    "Price summary": "价格摘要",
-    "Select a model to edit pricing": "选择一个模型编辑定价",
-    "Tiered pricing": "阶梯计费",
-    "Unset price": "未设置价格",
-    "Use the full-width table to scan prices, then select a row to edit it here.": "先在表格中快速浏览价格,然后选择一行在这里编辑。",
-    "extras": "额外项",
-    "tiers": "档"
+    "Zoom": "缩放"
   }
 }