Procházet zdrojové kódy

添加类型筛选以及调整部分页面

liqingshan před 1 měsícem
rodič
revize
6b31fa8ee1

+ 2 - 1
code/package.json

@@ -41,5 +41,6 @@
     "typescript": "^5.3.0",
     "vite": "^5.1.0",
     "vue-tsc": "^2.0.0"
-  }
+  },
+  "packageManager": "pnpm@11.5.2+sha512.71c631e382066efc25625d5cf029075de07b61b37f6e27350fbd84b1bda5864c8c1967adc280776b45c30a715c0359a3be08fef42d5bb09e2b99029979692916"
 }

+ 4 - 0
code/pnpm-workspace.yaml

@@ -0,0 +1,4 @@
+allowBuilds:
+  '@reown/appkit': set this to true or false
+  esbuild: set this to true or false
+  vue-demi: set this to true or false

+ 209 - 64
code/src/components/market/MarketTable.vue

@@ -1,56 +1,81 @@
 <script setup lang="ts">
-import { ref, computed } from 'vue'
-import { useI18n } from 'vue-i18n'
-import { storeToRefs } from 'pinia'
-import { useMarketStore } from '@/stores/market'
-import MarketRow from './MarketRow.vue'
-import type { MarketType, MarketItem } from '@/types'
-
-const { t } = useI18n()
-const store = useMarketStore()
-const { filteredList, activeTab, searchQuery, loading } = storeToRefs(store)
-const { setTab, setSearch } = store
+import { ref, computed } from "vue";
+import { useI18n } from "vue-i18n";
+import { storeToRefs } from "pinia";
+import { useMarketStore } from "@/stores/market";
+import MarketRow from "./MarketRow.vue";
+import type { MarketType, MarketItem } from "@/types";
+
+const { t } = useI18n();
+const store = useMarketStore();
+const { filteredList, activeTab, searchQuery, loading } = storeToRefs(store);
+const { setTab, setSearch } = store;
 
 const tabs = computed<{ label: string; value: MarketType }[]>(() => [
-  { label: t('nav.futures'), value: 'futures' },
-  { label: t('nav.spot'), value: 'spot' },
-])
+  { label: t("nav.futures"), value: "futures" },
+  { label: t("nav.spot"), value: "spot" },
+]);
+
+// 搜索标签:股票类型' 1.加密货币,2.大宗商品 3.贵金属 4.外汇
+const serchTagItems = ref([
+  { key: "futuresPage.pairSearchTag.oneType", value: 1 },
+  { key: "futuresPage.pairSearchTag.twoType", value: 2 },
+  { key: "futuresPage.pairSearchTag.threeType", value: 3 },
+  { key: "futuresPage.pairSearchTag.fourType", value: 4 },
+]);
+const currentSearchTag = ref(1);
 
-type SortKey = keyof Pick<MarketItem, 'symbol' | 'price' | 'change24h' | 'high24h' | 'low24h' | 'volume24h'>
-type SortDir = 'asc' | 'desc'
+type SortKey = keyof Pick<
+  MarketItem,
+  | "symbol"
+  | "price"
+  | "change24h"
+  | "high24h"
+  | "low24h"
+  | "volume24h"
+  | "stockType"
+>;
+type SortDir = "asc" | "desc";
 
-const sortKey = ref<SortKey | null>(null)
-const sortDir = ref<SortDir>('desc')
+const sortKey = ref<SortKey | null>(null);
+const sortDir = ref<SortDir>("desc");
 
 const columns = computed<{ key: SortKey; label: string }[]>(() => [
-  { key: 'symbol', label: t('market.name') },
-  { key: 'price', label: t('market.price') },
-  { key: 'change24h', label: t('market.change24hShort') },
-  { key: 'high24h', label: t('market.high24h') },
-  { key: 'low24h', label: t('market.low24h') },
-  { key: 'volume24h', label: t('market.volume24hLabel') },
-])
+  { key: "symbol", label: t("market.name") },
+  { key: "price", label: t("market.price") },
+  { key: "change24h", label: t("market.change24hShort") },
+  { key: "high24h", label: t("market.high24h") },
+  { key: "low24h", label: t("market.low24h") },
+  { key: "volume24h", label: t("market.volume24hLabel") },
+]);
 
 function toggleSort(key: SortKey) {
   if (sortKey.value === key) {
-    sortDir.value = sortDir.value === 'asc' ? 'desc' : 'asc'
+    sortDir.value = sortDir.value === "asc" ? "desc" : "asc";
   } else {
-    sortKey.value = key
-    sortDir.value = 'desc'
+    sortKey.value = key;
+    sortDir.value = "desc";
   }
 }
 
 const sortedList = computed(() => {
-  if (!sortKey.value) return filteredList.value
-  const key = sortKey.value
-  const dir = sortDir.value === 'asc' ? 1 : -1
-  return [...filteredList.value].sort((a, b) => {
-    const va = a[key]
-    const vb = b[key]
-    if (typeof va === 'string') return dir * (va as string).localeCompare(vb as string)
-    return dir * ((va as number) - (vb as number))
-  })
-})
+  let filteredData = [...filteredList.value];
+  if (activeTab.value === "futures") {
+    filteredData = filteredData.filter((item) => {
+      return item.stockType == currentSearchTag.value;
+    });
+  }
+  if (!sortKey.value) return filteredData;
+  const key = sortKey.value;
+  const dir = sortDir.value === "asc" ? 1 : -1;
+  return filteredData.sort((a, b) => {
+    const va = a[key];
+    const vb = b[key];
+    if (typeof va === "string")
+      return dir * (va as string).localeCompare(vb as string);
+    return dir * ((va as number) - (vb as number));
+  });
+});
 </script>
 
 <template>
@@ -76,11 +101,31 @@ const sortedList = computed(() => {
           :placeholder="t('market.searchPair')"
           @input="setSearch(($event.target as HTMLInputElement).value)"
         />
-        <svg class="search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
-          <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
+        <svg
+          class="search-icon"
+          width="16"
+          height="16"
+          viewBox="0 0 24 24"
+          fill="none"
+          stroke="currentColor"
+          stroke-width="1.5"
+        >
+          <circle cx="11" cy="11" r="8" />
+          <line x1="21" y1="21" x2="16.65" y2="16.65" />
         </svg>
       </div>
     </div>
+    <div class="pair-type-search" v-if="activeTab === 'futures'">
+      <div
+        v-for="item in serchTagItems"
+        :key="item.key"
+        class="type-item"
+        :class="{ 'is-active': item.value == currentSearchTag }"
+        @click.stop="currentSearchTag = item.value"
+      >
+        {{ t(item.key) }}
+      </div>
+    </div>
 
     <!-- 表格 -->
     <div class="table-container">
@@ -91,13 +136,24 @@ const sortedList = computed(() => {
               v-for="col in columns"
               :key="col.key"
               class="th"
-              :class="{ 'th-right': col.key !== 'symbol', 'th-active': sortKey === col.key }"
+              :class="{
+                'th-right': col.key !== 'symbol',
+                'th-active': sortKey === col.key,
+              }"
               @click="toggleSort(col.key)"
             >
               {{ col.label }}
               <span class="sort-icon">
-				<span class="sort-up" :class="{ active: sortKey === col.key && sortDir === 'desc' }">↑</span>
-                <span class="sort-down" :class="{ active: sortKey === col.key && sortDir === 'asc' }">↓</span>
+                <span
+                  class="sort-up"
+                  :class="{ active: sortKey === col.key && sortDir === 'desc' }"
+                  >↑</span
+                >
+                <span
+                  class="sort-down"
+                  :class="{ active: sortKey === col.key && sortDir === 'asc' }"
+                  >↓</span
+                >
               </span>
             </th>
           </tr>
@@ -109,10 +165,14 @@ const sortedList = computed(() => {
             </tr>
           </template>
           <template v-else-if="sortedList.length">
-            <MarketRow v-for="item in sortedList" :key="`${item.symbol}-${item.type}`" :item="item" />
+            <MarketRow
+              v-for="item in sortedList"
+              :key="`${item.symbol}-${item.type}`"
+              :item="item"
+            />
           </template>
           <tr v-else>
-            <td colspan="6" class="empty">{{ t('common.noData') }}</td>
+            <td colspan="6" class="empty">{{ t("common.noData") }}</td>
           </tr>
         </tbody>
       </table>
@@ -129,22 +189,31 @@ const sortedList = computed(() => {
   margin-bottom: var(--space-4);
 }
 
-.tabs { display: flex; gap: 0; }
+.tabs {
+  display: flex;
+  gap: 0;
+}
 .tab {
   padding: var(--space-2) var(--space-4);
   font-size: var(--text-body);
   color: var(--color-text-secondary);
   border-bottom: 2px solid transparent;
-  transition: color var(--transition), border-color var(--transition);
+  transition:
+    color var(--transition),
+    border-color var(--transition);
+}
+.tab:hover {
+  color: var(--color-text-primary);
 }
-.tab:hover { color: var(--color-text-primary); }
 .tab.is-active {
   color: var(--color-text-primary);
   font-weight: var(--fw-semibold);
   border-bottom-color: var(--color-primary);
 }
 
-.search-box { position: relative; }
+.search-box {
+  position: relative;
+}
 .search-input {
   height: 36px;
   padding: 0 var(--space-3) 0 var(--space-8);
@@ -156,8 +225,12 @@ const sortedList = computed(() => {
   width: 160px;
   transition: border-color var(--transition);
 }
-.search-input::placeholder { color: var(--color-text-muted); }
-.search-input:focus { border-color: var(--color-border-focus); }
+.search-input::placeholder {
+  color: var(--color-text-muted);
+}
+.search-input:focus {
+  border-color: var(--color-border-focus);
+}
 .search-icon {
   position: absolute;
   left: 10px;
@@ -167,9 +240,56 @@ const sortedList = computed(() => {
   pointer-events: none;
 }
 
+/** 对比类型搜索 */
+.pair-type-search {
+  display: flex;
+  gap: var(--space-5);
+  padding-left: var(--space-2);
+  position: relative;
+}
+.type-item {
+  width: fit-content;
+  font-size: 15px;
+  font-weight: var(--fw-bold);
+  color: var(--color-text-primary);
+  cursor: pointer;
+  transition: color var(--transition);
+  position: relative;
+  padding-bottom: 4px;
+}
+.type-item:hover {
+  color: var(--color-primary);
+}
+.type-item.is-active {
+  color: var(--color-primary);
+}
+.type-item.is-active::after {
+  content: '';
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 2px;
+  background: var(--color-primary);
+  animation: underlineSlide 0.2s ease forwards;
+}
+@keyframes underlineSlide {
+  from {
+    transform: scaleX(0);
+  }
+  to {
+    transform: scaleX(1);
+  }
+}
+
 /* Table */
-.table-container { overflow-x: auto; }
-.table { width: 100%; border-collapse: collapse; }
+.table-container {
+  overflow-x: auto;
+}
+.table {
+  width: 100%;
+  border-collapse: collapse;
+}
 
 .th {
   padding: var(--space-3) var(--space-4);
@@ -183,9 +303,15 @@ const sortedList = computed(() => {
   user-select: none;
   transition: color var(--transition);
 }
-.th:hover { color: var(--color-text-primary); }
-.th.th-active { color: var(--color-primary); }
-.th-right { text-align: right; }
+.th:hover {
+  color: var(--color-text-primary);
+}
+.th.th-active {
+  color: var(--color-primary);
+}
+.th-right {
+  text-align: right;
+}
 
 .sort-icon {
   margin-left: 4px;
@@ -197,26 +323,41 @@ const sortedList = computed(() => {
   gap: 1px;
   vertical-align: middle;
 }
-.th:hover .sort-icon { opacity: 0.8; }
+.th:hover .sort-icon {
+  opacity: 0.8;
+}
 /* .sort-up, .sort-down { opacity: 1 !important; color: var(--color-primary); } */
-.sort-up, .sort-down {
+.sort-up,
+.sort-down {
   opacity: 0.2;
 }
-.sort-up.active, .sort-down.active {
+.sort-up.active,
+.sort-down.active {
   opacity: 1 !important;
   color: var(--color-primary);
 }
 
 /* Loading skeleton */
-.skeleton-row td { padding: var(--space-3) var(--space-4); }
+.skeleton-row td {
+  padding: var(--space-3) var(--space-4);
+}
 .skeleton {
   height: 20px;
-  background: linear-gradient(90deg, var(--color-bg-card) 25%, rgba(255,255,255,0.06) 50%, var(--color-bg-card) 75%);
+  background: linear-gradient(
+    90deg,
+    var(--color-bg-card) 25%,
+    rgba(255, 255, 255, 0.06) 50%,
+    var(--color-bg-card) 75%
+  );
   background-size: 200% 100%;
   border-radius: var(--radius-sm);
   animation: shimmer 1.2s infinite;
 }
-@keyframes shimmer { to { background-position: -200% 0; } }
+@keyframes shimmer {
+  to {
+    background-position: -200% 0;
+  }
+}
 
 .empty {
   padding: var(--space-12);
@@ -232,7 +373,11 @@ const sortedList = computed(() => {
     align-items: stretch;
     gap: var(--space-3);
   }
-  .search-input { width: 100%; }
-  .search-box { width: 100%; }
+  .search-input {
+    width: 100%;
+  }
+  .search-box {
+    width: 100%;
+  }
 }
 </style>

+ 2 - 2
code/src/composables/useMarketWs.ts

@@ -29,7 +29,7 @@ export interface WsKlineBar {
 
 export interface WsTickerData {
   close: string; open: string; high: string; low: string
-  volume: string; turnover: string
+  volume: string; turnover: string; stockType: number
 }
 
 export interface WsMarkData {
@@ -178,7 +178,7 @@ export function useMarketWs(callbacks: MarketWsCallbacks) {
     } else if (ch.includes('.ticket')) {
       callbacks.onTicker?.({
         close: tick.c, open: tick.o, high: tick.h,
-        low: tick.l, volume: tick.v, turnover: tick.q,
+        low: tick.l, volume: tick.v, turnover: tick.q,stockType: 0
       })
     } else if (ch.includes('.mark')) {
       callbacks.onMark?.({

+ 2 - 2
code/src/composables/useSpotMarketWs.ts

@@ -40,7 +40,7 @@ export interface WsKlineBar {
 
 export interface WsTickerData {
   close: string; open: string; high: string; low: string
-  volume: string; turnover: string
+  volume: string; turnover: string; stockType: number
 }
 
 export interface WsTradeItem {
@@ -204,7 +204,7 @@ export function useSpotMarketWs(callbacks: MarketWsCallbacks) {
       const turn  = num(tick.amount ?? tick.quoteVolume ?? tick.q ?? tick.turnover)
       callbacks.onTicker?.({
         close: String(close), open: String(open), high: String(high), low: String(low),
-        volume: String(vol), turnover: String(turn),
+        volume: String(vol), turnover: String(turn),stockType: 0
       })
       return
     }

+ 1 - 1
code/src/locales/de.ts

@@ -15,7 +15,7 @@ export default {
 		download: 'Herunterladen',
 	},
 	lang: {
-		title: '语言',
+		title: 'Sprache',
 		zhCN: '简体中文',
 		zhTW: '繁體中文',
 		en: 'English',

+ 1 - 1
code/src/locales/en.ts

@@ -15,7 +15,7 @@ export default {
 		download: 'Download',
 	},
 	lang: {
-		title: '语言',
+		title: 'Language',
 		zhCN: '简体中文',
 		zhTW: '繁體中文',
 		en: 'English',

+ 1019 - 981
code/src/locales/es.ts

@@ -1,1064 +1,1102 @@
-import { futuresPageByLocale } from './futuresPage.i18n'
-import { financePageByLocale } from './financePage.i18n'
+import { futuresPageByLocale } from "./futuresPage.i18n";
+import { financePageByLocale } from "./financePage.i18n";
 
 export default {
   nav: {
-    home: 'Inicio',
-    market: 'Mercado',
-    spot: 'Spot',
-    futures: 'Futuros',
-    copyTrade: 'Copy Trading',
-    finance: 'Inversiones',
-    idoPresale: 'Preventa IDO',
-    claimAirdrop: 'Reclamar Airdrop',
-    announcements: 'Anuncios',
-    download: 'Descargar',
+    home: "Inicio",
+    market: "Mercado",
+    spot: "Spot",
+    futures: "Futuros",
+    copyTrade: "Copy Trading",
+    finance: "Inversiones",
+    idoPresale: "Preventa IDO",
+    claimAirdrop: "Reclamar Airdrop",
+    announcements: "Anuncios",
+    download: "Descargar",
   },
   lang: {
-    title: 'Idioma',
-    zhCN: '简体中文',
-    zhTW: '繁體中文',
-    en: 'English',
-    ko: '한국어',
-    ja: '日本語',
-    hi: 'हिन्दी',
-    id: 'Bahasa Indonesia',
-    es: 'Español',
-    ru: 'Русский',
-    pt: 'Português',
-    de: 'Deutsch',
-    fr: 'Français',
-    tr: 'Türkçe',
-    vi: 'Tiếng Việt'
+    title: "Idioma",
+    zhCN: "简体中文",
+    zhTW: "繁體中文",
+    en: "English",
+    ko: "한국어",
+    ja: "日本語",
+    hi: "हिन्दी",
+    id: "Bahasa Indonesia",
+    es: "Español",
+    ru: "Русский",
+    pt: "Português",
+    de: "Deutsch",
+    fr: "Français",
+    tr: "Türkçe",
+    vi: "Tiếng Việt",
   },
   header: {
-    login: 'Iniciar Sesión',
-    register: 'Registrarse',
-    account: 'Mi Cuenta',
-    assets: 'Mis Activos',
-    security: 'Seguridad',
-    broker: 'Broker',
-    logout: 'Cerrar Sesión',
-    logoutShort: 'Salir',
-    downloadTitle: 'Descargar',
-    brokerApplyTitle: 'Solicitar ser Broker',
-    brokerApplyDesc: 'Aún no eres broker. El sistema enviará tu solicitud con los datos de tu cuenta, podrás usar las funciones tras aprobación.',
-    cancel: 'Cancelar',
-    applyNow: 'Solicitar Ahora',
-    viewApplyList: 'Ver Estado Solicitud',
-    submitting: 'Enviando…',
-    menu: 'Menú',
+    login: "Iniciar Sesión",
+    register: "Registrarse",
+    account: "Mi Cuenta",
+    assets: "Mis Activos",
+    security: "Seguridad",
+    broker: "Broker",
+    logout: "Cerrar Sesión",
+    logoutShort: "Salir",
+    downloadTitle: "Descargar",
+    brokerApplyTitle: "Solicitar ser Broker",
+    brokerApplyDesc:
+      "Aún no eres broker. El sistema enviará tu solicitud con los datos de tu cuenta, podrás usar las funciones tras aprobación.",
+    cancel: "Cancelar",
+    applyNow: "Solicitar Ahora",
+    viewApplyList: "Ver Estado Solicitud",
+    submitting: "Enviando…",
+    menu: "Menú",
   },
   common: {
-    loading: 'Cargando...',
-    retry: 'Reintentar',
-    cancel: 'Cancelar',
-    confirm: 'Confirmar',
-    submit: 'Enviar',
-    save: 'Guardar',
-    send: 'Enviar',
-    back: 'Volver',
-    next: 'Siguiente',
-    done: 'Listo',
-    noData: 'Sin Datos',
-    noRecord: 'Sin Registros',
-    search: 'Buscar',
-    all: 'Todo',
-    max: 'Máx',
-    copied: 'Copiado',
-    networkError: 'Error de red, reintenta',
-    loadFailed: 'Fallo al cargar',
-    operationFailed: 'Operación fallida, reintenta',
-    saveSuccess: 'Guardado correctamente',
-    more: 'Más',
-    perpetual: 'Perpetuo',
-    set: 'Configurado',
-    notSet: 'Sin configurar',
-    change: 'Modificar',
-    bind: 'Vincular',
-    unbind: 'Desvincular',
-    on: 'Activado',
-    off: 'Desactivado',
-    status: 'Estado',
-    time: 'Fecha',
-    amount: 'Cantidad',
-    type: 'Tipo',
-    coin: 'Moneda',
-    from: 'Desde',
-    to: 'Hasta',
-    close: 'Cerrar',
-    contactService: 'Contactar Soporte',
+    loading: "Cargando...",
+    retry: "Reintentar",
+    cancel: "Cancelar",
+    confirm: "Confirmar",
+    submit: "Enviar",
+    save: "Guardar",
+    send: "Enviar",
+    back: "Volver",
+    next: "Siguiente",
+    done: "Listo",
+    noData: "Sin Datos",
+    noRecord: "Sin Registros",
+    search: "Buscar",
+    all: "Todo",
+    max: "Máx",
+    copied: "Copiado",
+    networkError: "Error de red, reintenta",
+    loadFailed: "Fallo al cargar",
+    operationFailed: "Operación fallida, reintenta",
+    saveSuccess: "Guardado correctamente",
+    more: "Más",
+    perpetual: "Perpetuo",
+    set: "Configurado",
+    notSet: "Sin configurar",
+    change: "Modificar",
+    bind: "Vincular",
+    unbind: "Desvincular",
+    on: "Activado",
+    off: "Desactivado",
+    status: "Estado",
+    time: "Fecha",
+    amount: "Cantidad",
+    type: "Tipo",
+    coin: "Moneda",
+    from: "Desde",
+    to: "Hasta",
+    close: "Cerrar",
+    contactService: "Contactar Soporte",
   },
   home: {
-    heroTitle: 'Seguro · Eficiente · Plataforma Global\nde Activos Digitales',
-    heroDesc: 'iBit brinda servicios de trading estables, transparentes y profesionales para usuarios globales con arquitectura tecnológica líder y estrictos controles de riesgo.',
-    register: 'Registrarse',
-    viewMarket: 'Ver Mercados',
-    downloadApp: 'Descargar App',
-    coreAdvantages: 'Ventajas Principales',
-    assetSafetyTitle: 'Seguridad de Activos',
-    assetSafetyDesc: 'Carteras frías/calientes separadas, firma múltiple y control de permisos con monitoreo 24h para proteger tus fondos.',
-    highPerfTitle: 'Alto Rendimiento',
-    highPerfDesc: 'Motor de emparejamiento propio con procesamiento en milésimas de segundo para operaciones fluidas y estables.',
-    globalComplianceTitle: 'Cumplimiento Global',
-    globalComplianceDesc: 'Cumplimos normativas internacionales para ofrecer un entorno de trading confiable en todo el mundo.',
-    transparentFeeTitle: 'Comisiones Transparentes',
-    transparentFeeDesc: 'Estructura de tarifas clara sin costos ocultos para optimizar tus gastos en trading.',
-    aboutUs: 'Sobre Nosotros',
-    aboutDesc: 'iBit es una plataforma global de intercambio de activos digitales enfocada en seguridad, estabilidad y eficiencia mediante innovación y regulación.',
-    foundedYear: 'Fundada en 2023',
-    headquarters: 'Sede y registro en Dubái, contamos con licencias en EE.UU., Canadá, Australia y Dubái.',
-    ourVision: 'Nuestra Visión',
-    visionSubtitle: 'Construir infraestructura de trading digital confiable a nivel mundial',
-    ecoTitle: 'Ecosistema',
-    ecoDesc: 'Desarrollar un nuevo ecosistema de trading de criptomonedas',
-    missionTitle: 'Misión',
-    missionDesc: 'Impulsar la circulación global del valor digital',
-    purposeTitle: 'Propósito',
-    purposeDesc: 'Facilitar la gestión e inversión en activos criptográficos a los usuarios',
-    heroImageAlt: 'Plataforma de trading iBit',
-    aboutImageAlt: 'Sobre Nosotros',
+    heroTitle: "Seguro · Eficiente · Plataforma Global\nde Activos Digitales",
+    heroDesc:
+      "iBit brinda servicios de trading estables, transparentes y profesionales para usuarios globales con arquitectura tecnológica líder y estrictos controles de riesgo.",
+    register: "Registrarse",
+    viewMarket: "Ver Mercados",
+    downloadApp: "Descargar App",
+    coreAdvantages: "Ventajas Principales",
+    assetSafetyTitle: "Seguridad de Activos",
+    assetSafetyDesc:
+      "Carteras frías/calientes separadas, firma múltiple y control de permisos con monitoreo 24h para proteger tus fondos.",
+    highPerfTitle: "Alto Rendimiento",
+    highPerfDesc:
+      "Motor de emparejamiento propio con procesamiento en milésimas de segundo para operaciones fluidas y estables.",
+    globalComplianceTitle: "Cumplimiento Global",
+    globalComplianceDesc:
+      "Cumplimos normativas internacionales para ofrecer un entorno de trading confiable en todo el mundo.",
+    transparentFeeTitle: "Comisiones Transparentes",
+    transparentFeeDesc:
+      "Estructura de tarifas clara sin costos ocultos para optimizar tus gastos en trading.",
+    aboutUs: "Sobre Nosotros",
+    aboutDesc:
+      "iBit es una plataforma global de intercambio de activos digitales enfocada en seguridad, estabilidad y eficiencia mediante innovación y regulación.",
+    foundedYear: "Fundada en 2023",
+    headquarters:
+      "Sede y registro en Dubái, contamos con licencias en EE.UU., Canadá, Australia y Dubái.",
+    ourVision: "Nuestra Visión",
+    visionSubtitle:
+      "Construir infraestructura de trading digital confiable a nivel mundial",
+    ecoTitle: "Ecosistema",
+    ecoDesc: "Desarrollar un nuevo ecosistema de trading de criptomonedas",
+    missionTitle: "Misión",
+    missionDesc: "Impulsar la circulación global del valor digital",
+    purposeTitle: "Propósito",
+    purposeDesc:
+      "Facilitar la gestión e inversión en activos criptográficos a los usuarios",
+    heroImageAlt: "Plataforma de trading iBit",
+    aboutImageAlt: "Sobre Nosotros",
   },
   market: {
-    title: 'Mercado en Vivo',
-    desc: 'Precios en tiempo real, volúmenes y variaciones para monitorear la evolución del mercado.',
-    hot: 'Populares',
-    topVolume: 'Mayor Volumen',
-    gainers: 'Subidas',
-    losers: 'Bajadas',
-    perpetual: 'Perpetuo',
-    name: 'Nombre',
-    latestPrice: 'Precio',
-    change24h: 'Var. 24h',
-    turnover: 'Volumen',
-    searchPair: 'Buscar pares',
-    searchMarket: 'Buscar monedas, pares, futuros',
-    price: 'Precio',
-    change24hShort: 'Var 24h',
-    high24h: 'Máx 24h',
-    low24h: 'Mín 24h',
-    volume24hLabel: 'Volumen 24h',
+    title: "Mercado en Vivo",
+    desc: "Precios en tiempo real, volúmenes y variaciones para monitorear la evolución del mercado.",
+    hot: "Populares",
+    topVolume: "Mayor Volumen",
+    gainers: "Subidas",
+    losers: "Bajadas",
+    perpetual: "Perpetuo",
+    name: "Nombre",
+    latestPrice: "Precio",
+    change24h: "Var. 24h",
+    turnover: "Volumen",
+    searchPair: "Buscar pares",
+    searchMarket: "Buscar monedas, pares, futuros",
+    price: "Precio",
+    change24hShort: "Var 24h",
+    high24h: "Máx 24h",
+    low24h: "Mín 24h",
+    volume24hLabel: "Volumen 24h",
   },
   auth: {
-    loginTitle: 'Iniciar Sesión',
-    emailLogin: 'Acceso por Correo',
-    emailPlaceholder: 'Ingresa tu correo',
-    password: 'Contraseña',
-    passwordPlaceholder: 'Ingresa tu contraseña',
-    forgotPassword: '¿Olvidaste tu contraseña?',
-    loginBtn: 'Ingresar',
-    noAccount: '¿No tienes cuenta?',
-    registerNow: 'Regístrate',
-    verifyTitle: 'Ingresa Código de Verificación',
-    codeSentDesc: 'Código enviado a {email}, revisa tu bandeja de entrada.',
-    codeSendDesc: 'Pulsa el botón para enviar código a {email}.',
-    countdownResend: 'Reenviar en {n}s',
-    resendCode: 'Reenviar Código',
-    confirmBtn: 'Confirmar',
-    sendCode: 'Enviar Código',
-    forgotVerify: '¿Olvidaste método de verificación?',
-    loginSuccess: 'Sesión iniciada correctamente',
-    codeSentAgain: 'Código reenviado',
-    registerTitle: 'Registro',
-    emailRegister: 'Registro por Correo',
-    inviteCodeLabel: 'Código Invitación (opcional)',
-    inviteCodePlaceholder: 'Ingresa código de invitación',
-    hasAccount: '¿Ya tienes cuenta?',
-    loginNow: 'Inicia Sesión',
-    verifyPageTitle: 'Verificación de Seguridad',
-    emailVerifyLabel: 'Verificación por Correo',
-    codePlaceholder: 'Ingresa código',
-    sendBtn: 'Enviar',
-    passwordTitle: 'Crear Contraseña',
-    backBtn: '‹ Volver',
-    inputPasswordLabel: 'Contraseña',
-    confirmPasswordLabel: 'Confirmar Contraseña',
-    confirmPasswordPlaceholder: 'Repite tu contraseña',
-    doneBtn: 'Listo',
-    resetSuccess: 'Contraseña restablecida, accede con tu nueva clave.',
-    registerSuccess: 'Registro Exitoso',
-    welcomeJoin: 'Bienvenido a iBit',
-    loginNowBtn: 'Iniciar Sesión',
-    forgotPasswordTitle: 'Restablecer Contraseña',
-    emailLabel: 'Correo',
-    emailRegisteredPlaceholder: 'Ingresa tu correo registrado',
-    codeSentToast: 'Código enviado',
+    loginTitle: "Iniciar Sesión",
+    emailLogin: "Acceso por Correo",
+    emailPlaceholder: "Ingresa tu correo",
+    password: "Contraseña",
+    passwordPlaceholder: "Ingresa tu contraseña",
+    forgotPassword: "¿Olvidaste tu contraseña?",
+    loginBtn: "Ingresar",
+    noAccount: "¿No tienes cuenta?",
+    registerNow: "Regístrate",
+    verifyTitle: "Ingresa Código de Verificación",
+    codeSentDesc: "Código enviado a {email}, revisa tu bandeja de entrada.",
+    codeSendDesc: "Pulsa el botón para enviar código a {email}.",
+    countdownResend: "Reenviar en {n}s",
+    resendCode: "Reenviar Código",
+    confirmBtn: "Confirmar",
+    sendCode: "Enviar Código",
+    forgotVerify: "¿Olvidaste método de verificación?",
+    loginSuccess: "Sesión iniciada correctamente",
+    codeSentAgain: "Código reenviado",
+    registerTitle: "Registro",
+    emailRegister: "Registro por Correo",
+    inviteCodeLabel: "Código Invitación (opcional)",
+    inviteCodePlaceholder: "Ingresa código de invitación",
+    hasAccount: "¿Ya tienes cuenta?",
+    loginNow: "Inicia Sesión",
+    verifyPageTitle: "Verificación de Seguridad",
+    emailVerifyLabel: "Verificación por Correo",
+    codePlaceholder: "Ingresa código",
+    sendBtn: "Enviar",
+    passwordTitle: "Crear Contraseña",
+    backBtn: "‹ Volver",
+    inputPasswordLabel: "Contraseña",
+    confirmPasswordLabel: "Confirmar Contraseña",
+    confirmPasswordPlaceholder: "Repite tu contraseña",
+    doneBtn: "Listo",
+    resetSuccess: "Contraseña restablecida, accede con tu nueva clave.",
+    registerSuccess: "Registro Exitoso",
+    welcomeJoin: "Bienvenido a iBit",
+    loginNowBtn: "Iniciar Sesión",
+    forgotPasswordTitle: "Restablecer Contraseña",
+    emailLabel: "Correo",
+    emailRegisteredPlaceholder: "Ingresa tu correo registrado",
+    codeSentToast: "Código enviado",
   },
   error: {
-    emailRequired: 'Ingresa tu correo',
-    emailInvalid: 'Formato de correo inválido',
-    passwordRequired: 'Ingresa contraseña',
-    code6Required: 'Ingresa código de 6 dígitos',
-    codeRequired: 'Ingresa código de verificación',
-    loginFailed: 'Correo o contraseña incorrectos',
-    networkError: 'Fallo de red, inténtalo luego',
-    emailAlreadyRegistered: 'Este correo ya está registrado, inicia sesión',
-    confirmPasswordRequired: 'Repite tu contraseña',
-    passwordMismatch: 'Las contraseñas no coinciden',
-    loadFailed: 'No se pudo cargar datos de seguridad',
-    refreshFailed: 'Error al actualizar',
-    statusUpdated: 'Estado actualizado',
-    currentPasswordRequired: 'Ingresa contraseña actual',
-    sixDigitCode: 'Ingresa código de 6 dígitos del correo',
-    sixDigitGoogleCode: 'Ingresa código de 6 dígitos de Google',
-    sendFailed: 'Fallo al enviar',
-    operationFailed: 'Operación fallida',
+    emailRequired: "Ingresa tu correo",
+    emailInvalid: "Formato de correo inválido",
+    passwordRequired: "Ingresa contraseña",
+    code6Required: "Ingresa código de 6 dígitos",
+    codeRequired: "Ingresa código de verificación",
+    loginFailed: "Correo o contraseña incorrectos",
+    networkError: "Fallo de red, inténtalo luego",
+    emailAlreadyRegistered: "Este correo ya está registrado, inicia sesión",
+    confirmPasswordRequired: "Repite tu contraseña",
+    passwordMismatch: "Las contraseñas no coinciden",
+    loadFailed: "No se pudo cargar datos de seguridad",
+    refreshFailed: "Error al actualizar",
+    statusUpdated: "Estado actualizado",
+    currentPasswordRequired: "Ingresa contraseña actual",
+    sixDigitCode: "Ingresa código de 6 dígitos del correo",
+    sixDigitGoogleCode: "Ingresa código de 6 dígitos de Google",
+    sendFailed: "Fallo al enviar",
+    operationFailed: "Operación fallida",
   },
   security: {
-    title: 'Configuración de Seguridad',
-    back: '‹ Volver',
-    warningBanner: 'Completa verificación de correo, Google Authenticator y contraseña de fondos para proteger tu cuenta.',
-    accountSecurity: 'Seguridad de Cuenta',
-    loginPassword: 'Contraseña de Acceso',
-    loginPasswordDesc: 'Cambia tu clave periódicamente para mayor seguridad',
-    emailVerify: 'Verificación de Correo',
-    emailVerifyDesc: 'Vincula correo para recuperación y validaciones',
-    googleAuth: 'Autenticación Google',
-    googleAuthDesc: 'Vincula Google Authenticator para reforzar la seguridad',
-    fundPassword: 'Contraseña de Fondos',
-    fundPasswordDesc: 'Establece clave exclusiva para operaciones de retiro y transferencia',
-    set: 'Config',
-    notSet: 'Sin config',
-    change: 'Modificar',
-    bind: 'Vincular',
-    set2: 'Establecer',
-    statusUpdated: 'Estado actualizado',
-    loadFailed: 'Fallo carga datos seguridad',
-    refreshFailed: 'Error refrescar',
-    bound: 'Vinculado',
-    notBound: 'Sin vincular',
-    refresh: 'Refrescar',
-    googleHelpTitle: 'Ayuda Google Authenticator',
-    googleHelpDesc: 'Si no recibes código o quieres desvincular, contacta soporte.',
-    changeLoginPassword: 'Cambiar Contraseña de Acceso',
-    changePasswordHint: 'Tras modificar usa la nueva contraseña, código enviado al correo vinculado.',
-    currentPassword: 'Contraseña Actual',
-    newPassword: 'Nueva Contraseña',
-    confirmNewPassword: 'Confirmar Nueva Clave',
-    emailCode: 'Código Correo',
-    sendCode: 'Enviar Código',
-    codeSent: 'Código enviado al correo',
-    changeSuccess: 'Contraseña modificada correctamente',
-    confirmChange: 'Confirmar Cambio',
-    submitting: 'Enviando…',
-    setFundPassword: 'Establecer Clave de Fondos',
-    resetFundPassword: 'Restablecer Clave de Fondos',
-    fundPasswordHint: 'Clave requerida para retiros y movimientos, guárdala bien.',
-    fundPasswordResetHint: 'Restablece tu clave, código enviado al correo registrado.',
-    newFundPassword: 'Nueva Clave Fondos',
-    confirmFundPassword: 'Confirmar Clave',
-    fundPasswordUpdated: 'Clave fondos actualizada',
-    fundPasswordSet: 'Clave fondos configurada',
-    bindGoogle: 'Vincular Google Authenticator',
-    boundEmail: 'Correo vinculado:',
-    googleQrStep: '1. Escanea QR o ingresa clave manual',
-    googleCodeStep: '2. Código dinámico Google (6 dígitos)',
-    emailCodeStep: '3. Código de correo',
-    copyKey: 'Copiar Clave',
-    keyCopied: 'Clave copiada',
-    copyFailed: 'No se pudo copiar, selecciona el texto manualmente',
-    clipboardDeniedMac: 'Sin permiso portapapeles: configura permisos desde el candado de la URL',
-    clipboardDenied: 'Permiso portapapeles denegado, habilítalo en ajustes del navegador',
-    invalidSecret: 'Clave inválida, refresca página',
-    googleCodeRequired: 'Ingresa código Google de 6 dígitos',
-    emailCodeSent: 'Código correo enviado',
-    bindSuccess: 'Vinculación completada',
-    confirmBind: 'Confirmar Vinculación',
-    googleAuthLead: 'Descarga Google Authenticator o Microsoft Authenticator desde tienda de apps.',
-    googleAuthTip1: 'Tras vincular necesitarás el código de 6 dígitos en accesos y operaciones sensibles.',
-    googleAuthTip2: 'Conserva tu dispositivo seguro; si pierdes acceso contacta soporte.',
-    googleAuthStart: 'Lo tengo instalado, vincular ahora',
+    title: "Configuración de Seguridad",
+    back: "‹ Volver",
+    warningBanner:
+      "Completa verificación de correo, Google Authenticator y contraseña de fondos para proteger tu cuenta.",
+    accountSecurity: "Seguridad de Cuenta",
+    loginPassword: "Contraseña de Acceso",
+    loginPasswordDesc: "Cambia tu clave periódicamente para mayor seguridad",
+    emailVerify: "Verificación de Correo",
+    emailVerifyDesc: "Vincula correo para recuperación y validaciones",
+    googleAuth: "Autenticación Google",
+    googleAuthDesc: "Vincula Google Authenticator para reforzar la seguridad",
+    fundPassword: "Contraseña de Fondos",
+    fundPasswordDesc:
+      "Establece clave exclusiva para operaciones de retiro y transferencia",
+    set: "Config",
+    notSet: "Sin config",
+    change: "Modificar",
+    bind: "Vincular",
+    set2: "Establecer",
+    statusUpdated: "Estado actualizado",
+    loadFailed: "Fallo carga datos seguridad",
+    refreshFailed: "Error refrescar",
+    bound: "Vinculado",
+    notBound: "Sin vincular",
+    refresh: "Refrescar",
+    googleHelpTitle: "Ayuda Google Authenticator",
+    googleHelpDesc:
+      "Si no recibes código o quieres desvincular, contacta soporte.",
+    changeLoginPassword: "Cambiar Contraseña de Acceso",
+    changePasswordHint:
+      "Tras modificar usa la nueva contraseña, código enviado al correo vinculado.",
+    currentPassword: "Contraseña Actual",
+    newPassword: "Nueva Contraseña",
+    confirmNewPassword: "Confirmar Nueva Clave",
+    emailCode: "Código Correo",
+    sendCode: "Enviar Código",
+    codeSent: "Código enviado al correo",
+    changeSuccess: "Contraseña modificada correctamente",
+    confirmChange: "Confirmar Cambio",
+    submitting: "Enviando…",
+    setFundPassword: "Establecer Clave de Fondos",
+    resetFundPassword: "Restablecer Clave de Fondos",
+    fundPasswordHint:
+      "Clave requerida para retiros y movimientos, guárdala bien.",
+    fundPasswordResetHint:
+      "Restablece tu clave, código enviado al correo registrado.",
+    newFundPassword: "Nueva Clave Fondos",
+    confirmFundPassword: "Confirmar Clave",
+    fundPasswordUpdated: "Clave fondos actualizada",
+    fundPasswordSet: "Clave fondos configurada",
+    bindGoogle: "Vincular Google Authenticator",
+    boundEmail: "Correo vinculado:",
+    googleQrStep: "1. Escanea QR o ingresa clave manual",
+    googleCodeStep: "2. Código dinámico Google (6 dígitos)",
+    emailCodeStep: "3. Código de correo",
+    copyKey: "Copiar Clave",
+    keyCopied: "Clave copiada",
+    copyFailed: "No se pudo copiar, selecciona el texto manualmente",
+    clipboardDeniedMac:
+      "Sin permiso portapapeles: configura permisos desde el candado de la URL",
+    clipboardDenied:
+      "Permiso portapapeles denegado, habilítalo en ajustes del navegador",
+    invalidSecret: "Clave inválida, refresca página",
+    googleCodeRequired: "Ingresa código Google de 6 dígitos",
+    emailCodeSent: "Código correo enviado",
+    bindSuccess: "Vinculación completada",
+    confirmBind: "Confirmar Vinculación",
+    googleAuthLead:
+      "Descarga Google Authenticator o Microsoft Authenticator desde tienda de apps.",
+    googleAuthTip1:
+      "Tras vincular necesitarás el código de 6 dígitos en accesos y operaciones sensibles.",
+    googleAuthTip2:
+      "Conserva tu dispositivo seguro; si pierdes acceso contacta soporte.",
+    googleAuthStart: "Lo tengo instalado, vincular ahora",
   },
   assets: {
-    title: 'Mis Activos',
-    totalAssets: 'Valor Total Activos',
-    todayPnl: 'Gan/Pér Hoy',
-    deposit: 'Depositar',
-    withdraw: 'Retirar',
-    transfer: 'Transferir',
-    history: 'Historial',
-    spot: 'Spot',
-    futures: 'Futuros',
-    copyTrade: 'Copy',
-    fund: 'Retirable',
-    walletBalance: 'Saldo Billetera',
-    unrealizedPnl: 'Gan/Pér No Realizada',
-    positions: 'Posiciones',
-    noPositions: 'Sin posiciones',
-    assetBalance: 'Saldo Activo',
-    unavailable: 'No Disponible',
-    depositCoin: 'Depósito',
-    withdrawCoin: 'Retiro',
-    depositRecord: 'Historial Depósitos',
-    withdrawRecord: 'Historial Retiros',
-    transferRecord: 'Historial Transferencias',
-    assetRecord: 'Movimientos',
-    overview: 'Resumen',
-    spotAccount: 'Cuenta Spot',
-    swapAccount: 'Cuenta Futuros',
-    followAccount: 'Cuenta Copy',
-    fundAccount: 'Cuenta Retirable',
-    spotTradingAccount: 'Cuenta Trading Spot',
-    ibitAccount: 'Cuenta iBit',
-    lockedStakingAccount: 'Cuenta Bloqueada',
-    stakingTab: 'Bloqueos',
-    ibitUnit: 'iBit',
-    releaseTotal: 'Total Liberado',
-    totalLockedBalance: 'Saldo Total Bloqueado(iBit)',
-    myStakingOrders: 'Mis Órdenes Bloqueo',
-    stakingOrderNo: 'Nº Orden',
-    purchaseQty: 'Cantidad Comprada',
-    stakingTotal: 'Total Bloqueado',
-    released: 'Liberado',
-    pendingRelease: 'Pendiente Liberación',
-    startTime: 'Fecha Inicio',
-    subscribing: 'En Suscripción',
-    releasing: 'En Liberación',
-    completed: 'Finalizado',
-    pullToRefresh: 'Desliza abajo para actualizar',
-    releaseToRefresh: 'Suelta para refrescar',
-    refreshing: 'Actualizando...',
-    totalAccount: 'Valor Total Cuenta',
-    showBalance: 'Mostrar Saldo',
-    hideBalance: 'Ocultar Saldo',
-    followBalance: 'Saldo Copy',
-    accountTransfer: 'Transferencia entre Cuentas',
-    transferFrom: 'Origen',
-    transferTo: 'Destino',
-    available: 'Disponible',
-    freeTransfer: 'Transferencia gratuita, abono instantáneo',
-    followPositions: 'Posiciones Copy Activas',
-    noFollowPositions: 'Sin posiciones copy',
-    followLoading: 'Cargando…',
-    long: 'Largo',
-    short: 'Corto',
-    trader: 'Trader',
-    openPrice: 'Precio Apertura',
-    currentPrice: 'Precio Actual',
-    amountLever: 'Cantidad · Apalancamiento',
-    closing: 'Cerrando…',
-    closePosition: 'Cerrar',
-    noLossPosition: 'Las órdenes copy sin pérdida no se pueden cerrar manualmente',
-    invalidPosition: 'Datos posición erróneos, no cerrar',
-    confirmClose: '¿Cerrar esta posición? Perderás acceso a beneficios finales de la orden.',
-    closeSuccess: 'Posición cerrada correctamente',
-    closeFailed: 'Fallo al cerrar posición',
-    sameAccountError: 'Origen y destino no pueden ser la misma cuenta',
-    amountError: 'Ingresa cantidad válida',
-    insufficientBalance: 'Saldo disponible insuficiente',
-    transferSuccess: 'Transferencia exitosa',
-    transferFailed: 'Fallo transferencia',
-    goCopyTrade: 'Copy Trading',
-    goSpotTrade: 'Ir a Trading',
-    hideZeroBalance: 'Ocultar activos sin saldo',
-    depositRecord2: 'Historial Depósitos',
-    amountUsdt: 'Cantidad (USDT)',
-    amountCoin: 'Cantidad ({coin})',
-    availableCoin: 'Disponible: {available} {coin}',
-    transferring: 'Transfiriendo…',
-    confirmTransferBtn: 'Confirmar Transferencia',
-    statementPageTitle: 'Extracto de Movimientos',
-    statementStartDate: 'Fecha Inicio',
-    statementEndDate: 'Fecha Fin',
-    statementReset: 'Restablecer',
-    statementSearch: 'Buscar',
-    statementSearching: 'Buscando…',
-    statementEmpty: 'Sin registros',
-    statementDirectionOpen: 'Apertura',
-    statementDirectionClose: 'Cierre',
+    title: "Mis Activos",
+    totalAssets: "Valor Total Activos",
+    todayPnl: "Gan/Pér Hoy",
+    deposit: "Depositar",
+    withdraw: "Retirar",
+    transfer: "Transferir",
+    history: "Historial",
+    spot: "Spot",
+    futures: "Futuros",
+    copyTrade: "Copy",
+    fund: "Retirable",
+    walletBalance: "Saldo Billetera",
+    unrealizedPnl: "Gan/Pér No Realizada",
+    positions: "Posiciones",
+    noPositions: "Sin posiciones",
+    assetBalance: "Saldo Activo",
+    unavailable: "No Disponible",
+    depositCoin: "Depósito",
+    withdrawCoin: "Retiro",
+    depositRecord: "Historial Depósitos",
+    withdrawRecord: "Historial Retiros",
+    transferRecord: "Historial Transferencias",
+    assetRecord: "Movimientos",
+    overview: "Resumen",
+    spotAccount: "Cuenta Spot",
+    swapAccount: "Cuenta Futuros",
+    followAccount: "Cuenta Copy",
+    fundAccount: "Cuenta Retirable",
+    spotTradingAccount: "Cuenta Trading Spot",
+    ibitAccount: "Cuenta iBit",
+    lockedStakingAccount: "Cuenta Bloqueada",
+    stakingTab: "Bloqueos",
+    ibitUnit: "iBit",
+    releaseTotal: "Total Liberado",
+    totalLockedBalance: "Saldo Total Bloqueado(iBit)",
+    myStakingOrders: "Mis Órdenes Bloqueo",
+    stakingOrderNo: "Nº Orden",
+    purchaseQty: "Cantidad Comprada",
+    stakingTotal: "Total Bloqueado",
+    released: "Liberado",
+    pendingRelease: "Pendiente Liberación",
+    startTime: "Fecha Inicio",
+    subscribing: "En Suscripción",
+    releasing: "En Liberación",
+    completed: "Finalizado",
+    pullToRefresh: "Desliza abajo para actualizar",
+    releaseToRefresh: "Suelta para refrescar",
+    refreshing: "Actualizando...",
+    totalAccount: "Valor Total Cuenta",
+    showBalance: "Mostrar Saldo",
+    hideBalance: "Ocultar Saldo",
+    followBalance: "Saldo Copy",
+    accountTransfer: "Transferencia entre Cuentas",
+    transferFrom: "Origen",
+    transferTo: "Destino",
+    available: "Disponible",
+    freeTransfer: "Transferencia gratuita, abono instantáneo",
+    followPositions: "Posiciones Copy Activas",
+    noFollowPositions: "Sin posiciones copy",
+    followLoading: "Cargando…",
+    long: "Largo",
+    short: "Corto",
+    trader: "Trader",
+    openPrice: "Precio Apertura",
+    currentPrice: "Precio Actual",
+    amountLever: "Cantidad · Apalancamiento",
+    closing: "Cerrando…",
+    closePosition: "Cerrar",
+    noLossPosition:
+      "Las órdenes copy sin pérdida no se pueden cerrar manualmente",
+    invalidPosition: "Datos posición erróneos, no cerrar",
+    confirmClose:
+      "¿Cerrar esta posición? Perderás acceso a beneficios finales de la orden.",
+    closeSuccess: "Posición cerrada correctamente",
+    closeFailed: "Fallo al cerrar posición",
+    sameAccountError: "Origen y destino no pueden ser la misma cuenta",
+    amountError: "Ingresa cantidad válida",
+    insufficientBalance: "Saldo disponible insuficiente",
+    transferSuccess: "Transferencia exitosa",
+    transferFailed: "Fallo transferencia",
+    goCopyTrade: "Copy Trading",
+    goSpotTrade: "Ir a Trading",
+    hideZeroBalance: "Ocultar activos sin saldo",
+    depositRecord2: "Historial Depósitos",
+    amountUsdt: "Cantidad (USDT)",
+    amountCoin: "Cantidad ({coin})",
+    availableCoin: "Disponible: {available} {coin}",
+    transferring: "Transfiriendo…",
+    confirmTransferBtn: "Confirmar Transferencia",
+    statementPageTitle: "Extracto de Movimientos",
+    statementStartDate: "Fecha Inicio",
+    statementEndDate: "Fecha Fin",
+    statementReset: "Restablecer",
+    statementSearch: "Buscar",
+    statementSearching: "Buscando…",
+    statementEmpty: "Sin registros",
+    statementDirectionOpen: "Apertura",
+    statementDirectionClose: "Cierre",
     statementTypes: {
-      '43': 'Ganancia Spot',
-      '44': 'Pérdida Spot',
-      '45': 'Comisión Spot',
-      '46': 'Reembolso Spot',
-      '48': 'Operación Spot',
-      '49': 'Staking',
-      '50': 'Desbloqueo Staking',
-      '51': 'Recompensa Airdrop',
-      '52': 'Ingreso cartera staking',
-      '53': 'Salida cartera staking',
+      "43": "Ganancia Spot",
+      "44": "Pérdida Spot",
+      "45": "Comisión Spot",
+      "46": "Reembolso Spot",
+      "48": "Operación Spot",
+      "49": "Staking",
+      "50": "Desbloqueo Staking",
+      "51": "Recompensa Airdrop",
+      "52": "Ingreso cartera staking",
+      "53": "Salida cartera staking",
     },
   },
   finance: {
     ...financePageByLocale.es,
   },
   copyTrade: {
-    comprehensive: 'General',
-    winRate14d: 'Tasa Gan. 14d',
-    profit14d: 'Rentab.14d',
-    normal: 'Copy Normal',
-    lossless: 'Copy Sin Pérdida',
-    favorite: 'Favoritos',
-    topTraders: 'Mejores Traders',
-    twoWeekReturn: 'Rentab. 2 Sem',
-    followers: 'Seguidores',
-    days: 'Días',
-    applyTrader: 'Ser Trader Líder',
-    myFollowing: 'Mis Copias',
-    myTrading: 'Mis Operaciones',
-    traderIdentity: 'Trader Líder',
-    myFollowingAccount: 'Mi Cuenta Copy',
-    leadManage: 'Panel Líder',
-    applyLead: 'Solicitar Ser Líder',
-    pageTitle: 'Copy Trading',
-    heroDesc: 'Copia operaciones de traders expertos con un clic para rentabilizar tu inversión.',
-    traderOverview: 'Resumen Trader',
-    copyFollowersCount: 'Seguidores Copy',
-    cumulativeTradingDays: 'Días totales operando',
-    cumulativeLeadProfit: 'Ganancia total copy',
-    goLeadManage: 'Ir al panel líder →',
-    copyWalletTitle: 'Saldo Cuenta Copy',
-    cumulativePnlUsdt: 'Ganancia total Copy (USDT)',
-    availableUsdt: 'Disponible (USDT)',
-    unrealizedPnlUsdtShort: 'Gan/Pér No Real.(USDT)',
-    followingTradersSummary: 'Siguiendo a {n} traders',
-    newBadge: 'NUEVO',
-    losslessShieldTitle: 'Protección Sin Pérdida',
-    losslessShieldDesc: ': Si tu copy genera pérdidas la plataforma compensa dentro de los límites definidos.',
-    learnHowItWorks: 'Saber más →',
-    myStarredTraders: 'Traders Guardados',
-    traderTotalCount: '{count} traders disponibles',
-    filterLoadingShort: 'Cargando…',
-    loadTraderListFailed: 'Fallo al cargar lista traders',
-    loadFavoritesFailed: 'No se pudo cargar favoritos',
-    favoritedToast: 'Añadido a favoritos',
-    defaultTraderName: 'Trader',
-    levelJunior: 'Junior',
-    badgeLossless: 'Sin Pérdida',
-    metaDaysTrades: '{days}d · {trades} ops',
-    followAction: 'Copiar',
-    profitUsdtBracket: 'Ganancia (USDT)',
-    profitShareRate: '% Reparto Ganancias',
-    trend14Days: 'Gráfico 14 días',
-    emptyFavoriteHint: 'Sin favoritos aún, descubre traders',
-    emptyTraderListDefault: 'Sin traders disponibles',
-    emptyTraderListLossless: 'Sin traders copy sin pérdida',
-    browseTraders: 'Ver Traders',
-    losslessInfoHeading: 'Funcionamiento Copy Sin Pérdida',
-    llInfoCard1Title: 'Protección Condicional',
-    llInfoCard1Body: 'La compensación se activa solo al cumplir reglas definidas por control de riesgos.',
-    llInfoCard2Title: 'Responsabilidad Limitada',
-    llInfoCard2Body: 'La plataforma solo compensa hasta el límite fijado por cada operación copy.',
-    llInfoCard3Title: 'Prioridad Gestión Riesgo',
-    llInfoCard3Body: 'Ante pérdidas extremas se activa sistema de protección para equidad del copy.',
-    llInfoCard4Title: 'Aviso Riesgo',
-    llInfoCard4Body: 'El trading cripto es de alto riesgo; copy sin pérdida no es garantía de ganancia.',
-    followingPlaza: 'Plaza Copy',
-    followingWalletFail: 'Error carga datos cuenta copy',
-    followingTabPositions: 'Posiciones Abiertas',
-    followingTabTraders: 'Mis Traders',
-    followingTabHistory: 'Historial Copy',
-    followingHistEmpty: 'Sin historial copy',
-    followingNoTradersYet: 'No sigues ningún trader',
-    followingGoPlaza: 'Ir a plaza copy',
+    comprehensive: "General",
+    winRate14d: "Tasa Gan. 14d",
+    profit14d: "Rentab.14d",
+    normal: "Copy Normal",
+    lossless: "Copy Sin Pérdida",
+    favorite: "Favoritos",
+    topTraders: "Mejores Traders",
+    twoWeekReturn: "Rentab. 2 Sem",
+    followers: "Seguidores",
+    days: "Días",
+    applyTrader: "Ser Trader Líder",
+    myFollowing: "Mis Copias",
+    myTrading: "Mis Operaciones",
+    traderIdentity: "Trader Líder",
+    myFollowingAccount: "Mi Cuenta Copy",
+    leadManage: "Panel Líder",
+    applyLead: "Solicitar Ser Líder",
+    pageTitle: "Copy Trading",
+    heroDesc:
+      "Copia operaciones de traders expertos con un clic para rentabilizar tu inversión.",
+    traderOverview: "Resumen Trader",
+    copyFollowersCount: "Seguidores Copy",
+    cumulativeTradingDays: "Días totales operando",
+    cumulativeLeadProfit: "Ganancia total copy",
+    goLeadManage: "Ir al panel líder →",
+    copyWalletTitle: "Saldo Cuenta Copy",
+    cumulativePnlUsdt: "Ganancia total Copy (USDT)",
+    availableUsdt: "Disponible (USDT)",
+    unrealizedPnlUsdtShort: "Gan/Pér No Real.(USDT)",
+    followingTradersSummary: "Siguiendo a {n} traders",
+    newBadge: "NUEVO",
+    losslessShieldTitle: "Protección Sin Pérdida",
+    losslessShieldDesc:
+      ": Si tu copy genera pérdidas la plataforma compensa dentro de los límites definidos.",
+    learnHowItWorks: "Saber más →",
+    myStarredTraders: "Traders Guardados",
+    traderTotalCount: "{count} traders disponibles",
+    filterLoadingShort: "Cargando…",
+    loadTraderListFailed: "Fallo al cargar lista traders",
+    loadFavoritesFailed: "No se pudo cargar favoritos",
+    favoritedToast: "Añadido a favoritos",
+    defaultTraderName: "Trader",
+    levelJunior: "Junior",
+    badgeLossless: "Sin Pérdida",
+    metaDaysTrades: "{days}d · {trades} ops",
+    followAction: "Copiar",
+    profitUsdtBracket: "Ganancia (USDT)",
+    profitShareRate: "% Reparto Ganancias",
+    trend14Days: "Gráfico 14 días",
+    emptyFavoriteHint: "Sin favoritos aún, descubre traders",
+    emptyTraderListDefault: "Sin traders disponibles",
+    emptyTraderListLossless: "Sin traders copy sin pérdida",
+    browseTraders: "Ver Traders",
+    losslessInfoHeading: "Funcionamiento Copy Sin Pérdida",
+    llInfoCard1Title: "Protección Condicional",
+    llInfoCard1Body:
+      "La compensación se activa solo al cumplir reglas definidas por control de riesgos.",
+    llInfoCard2Title: "Responsabilidad Limitada",
+    llInfoCard2Body:
+      "La plataforma solo compensa hasta el límite fijado por cada operación copy.",
+    llInfoCard3Title: "Prioridad Gestión Riesgo",
+    llInfoCard3Body:
+      "Ante pérdidas extremas se activa sistema de protección para equidad del copy.",
+    llInfoCard4Title: "Aviso Riesgo",
+    llInfoCard4Body:
+      "El trading cripto es de alto riesgo; copy sin pérdida no es garantía de ganancia.",
+    followingPlaza: "Plaza Copy",
+    followingWalletFail: "Error carga datos cuenta copy",
+    followingTabPositions: "Posiciones Abiertas",
+    followingTabTraders: "Mis Traders",
+    followingTabHistory: "Historial Copy",
+    followingHistEmpty: "Sin historial copy",
+    followingNoTradersYet: "No sigues ningún trader",
+    followingGoPlaza: "Ir a plaza copy",
     confirmStopFollow: '¿Dejar de seguir a "{name}"?',
-    noLossManualCloseTooltip: 'Copy sin pérdida no admite cierre manual',
-    followingThContract: 'Contrato',
-    followingThDirection: 'Sentido',
-    followingThOpenPrice: 'Precio Apertura',
-    followingThCurPrice: 'Precio Actual',
-    followingThQty: 'Cantidad',
-    followingThLever: 'Apalanc.',
-    followingThUnrealized: 'Gan/Pér No Real',
-    followingThOpenTime: 'Fecha Apertura',
-    followingThAction: 'Acción',
-    followingOpenLong: 'Apertura Larga',
-    followingOpenShort: 'Apertura Corta',
-    closeQtyWithBase: 'Cantidad Cierre({base})',
-    followingRealizedPnlUsdt: 'Gan/Pér Real(USDT)',
-    followingYieldRate: 'Rentabilidad',
-    followingAvgOpenUsdt: 'Precio Medio Apertura(USDT)',
-    followingAvgCloseUsdt: 'Precio Medio Cierre(USDT)',
-    marginCrossMode: 'Todo en común',
-    marginIsolatedMode: 'Apalanc. Aislado',
-    stopFollowing: 'Dejar de Seguir',
+    noLossManualCloseTooltip: "Copy sin pérdida no admite cierre manual",
+    followingThContract: "Contrato",
+    followingThDirection: "Sentido",
+    followingThOpenPrice: "Precio Apertura",
+    followingThCurPrice: "Precio Actual",
+    followingThQty: "Cantidad",
+    followingThLever: "Apalanc.",
+    followingThUnrealized: "Gan/Pér No Real",
+    followingThOpenTime: "Fecha Apertura",
+    followingThAction: "Acción",
+    followingOpenLong: "Apertura Larga",
+    followingOpenShort: "Apertura Corta",
+    closeQtyWithBase: "Cantidad Cierre({base})",
+    followingRealizedPnlUsdt: "Gan/Pér Real(USDT)",
+    followingYieldRate: "Rentabilidad",
+    followingAvgOpenUsdt: "Precio Medio Apertura(USDT)",
+    followingAvgCloseUsdt: "Precio Medio Cierre(USDT)",
+    marginCrossMode: "Todo en común",
+    marginIsolatedMode: "Apalanc. Aislado",
+    stopFollowing: "Dejar de Seguir",
     lead: {
-      pageTitle: 'Mis Operaciones Líder',
-      navMyFollowing: 'Mis Copias →',
-      becomeTitle: 'Conviértete en Trader Líder',
-      becomeDesc: 'Cumple los requisitos para enviar tu solicitud.',
-      condMinBalance: 'Saldo cuenta futuros ≥ {min} USDT',
-      goTransfer: 'Transferir',
-      condNotFollowing: 'No puedes seguir a otro trader',
-      agreePrefix: 'He leído y acepto el',
-      agreeLink: 'Acuerdo de Trader',
-      submitting: 'Enviando…',
-      submitApply: 'Enviar Solicitud',
-      applyFailed: 'Solicitud fallida, reintenta luego',
-      reviewingTitle: 'Solicitud en Revisión',
-      reviewingDesc: 'Tu solicitud está en proceso, podrás liderar tras aprobación.',
-      agreementTitle: 'Acuerdo de Trader',
-      agreementEmpty: 'No se pudo cargar el acuerdo, inténtalo después.',
-      leadingBadge: 'Liderando',
-      noBio: 'Sin descripción',
-      cancelLeadProcessing: 'Procesando…',
-      cancelLeadApply: 'Solicitar dejar de liderar',
-      confirmCancelLead: '¿Dejar de ser líder? Se cancelarán todas las copias activas.',
-      operationFailed: 'Operación fallida',
-      statFollowers: 'Seguidores actuales',
-      statRegisterDays: 'Días en plataforma',
-      statCapital: 'Solvencia',
-      statCumulativeProfit: 'Ganancia total copy(USDT)',
-      statTotalFollowers: 'Total seguidores históricos',
-      statTradingDays: 'Días totales operando',
-      tabFollowers: 'Seguidores ({n})',
-      tabCurrent: 'Operaciones Activas',
-      tabHistory: 'Historial Liderazgo',
-      tabSettings: 'Ajustes Trader',
-      emptyFollowers: 'Sin seguidores',
-      removeFollower: 'Eliminar',
-      followerEquity: 'Saldo Cuenta(USDT)',
-      followerTotalShare: 'Reparto total ganancias(USDT)',
-      followerLastShare: 'Último reparto',
-      followerSince: 'Sigue desde: {time}',
-      emptyCurrent: 'Sin operaciones activas',
-      emptyHistory: 'Sin historial liderazgo',
-      settingsBasic: 'Datos Básicos',
-      avatar: 'Foto Perfil',
-      nickname: 'Alias',
-      nicknamePlaceholder: 'Máx 10 caracteres',
-      bio: 'Descripción',
-      bioPlaceholder: 'Máx 25 caracteres',
-      saveSuccess: 'Guardado correctamente',
-      saveBasicProcessing: 'Guardando…',
-      saveBasic: 'Guardar Datos',
-      leadSymbols: 'Contratos para Liderar',
-      saveProcessing: 'Guardando…',
-      save: 'Guardar',
-      tagsTitle: 'Etiquetas (máx 4)',
+      pageTitle: "Mis Operaciones Líder",
+      navMyFollowing: "Mis Copias →",
+      becomeTitle: "Conviértete en Trader Líder",
+      becomeDesc: "Cumple los requisitos para enviar tu solicitud.",
+      condMinBalance: "Saldo cuenta futuros ≥ {min} USDT",
+      goTransfer: "Transferir",
+      condNotFollowing: "No puedes seguir a otro trader",
+      agreePrefix: "He leído y acepto el",
+      agreeLink: "Acuerdo de Trader",
+      submitting: "Enviando…",
+      submitApply: "Enviar Solicitud",
+      applyFailed: "Solicitud fallida, reintenta luego",
+      reviewingTitle: "Solicitud en Revisión",
+      reviewingDesc:
+        "Tu solicitud está en proceso, podrás liderar tras aprobación.",
+      agreementTitle: "Acuerdo de Trader",
+      agreementEmpty: "No se pudo cargar el acuerdo, inténtalo después.",
+      leadingBadge: "Liderando",
+      noBio: "Sin descripción",
+      cancelLeadProcessing: "Procesando…",
+      cancelLeadApply: "Solicitar dejar de liderar",
+      confirmCancelLead:
+        "¿Dejar de ser líder? Se cancelarán todas las copias activas.",
+      operationFailed: "Operación fallida",
+      statFollowers: "Seguidores actuales",
+      statRegisterDays: "Días en plataforma",
+      statCapital: "Solvencia",
+      statCumulativeProfit: "Ganancia total copy(USDT)",
+      statTotalFollowers: "Total seguidores históricos",
+      statTradingDays: "Días totales operando",
+      tabFollowers: "Seguidores ({n})",
+      tabCurrent: "Operaciones Activas",
+      tabHistory: "Historial Liderazgo",
+      tabSettings: "Ajustes Trader",
+      emptyFollowers: "Sin seguidores",
+      removeFollower: "Eliminar",
+      followerEquity: "Saldo Cuenta(USDT)",
+      followerTotalShare: "Reparto total ganancias(USDT)",
+      followerLastShare: "Último reparto",
+      followerSince: "Sigue desde: {time}",
+      emptyCurrent: "Sin operaciones activas",
+      emptyHistory: "Sin historial liderazgo",
+      settingsBasic: "Datos Básicos",
+      avatar: "Foto Perfil",
+      nickname: "Alias",
+      nicknamePlaceholder: "Máx 10 caracteres",
+      bio: "Descripción",
+      bioPlaceholder: "Máx 25 caracteres",
+      saveSuccess: "Guardado correctamente",
+      saveBasicProcessing: "Guardando…",
+      saveBasic: "Guardar Datos",
+      leadSymbols: "Contratos para Liderar",
+      saveProcessing: "Guardando…",
+      save: "Guardar",
+      tagsTitle: "Etiquetas (máx 4)",
       confirmRemoveFollower: '¿Eliminar seguidor "{name}"?',
-      saveFailed: 'Fallo al guardar',
-      uploadFailed: 'Error subir archivo',
-      defaultFollower: 'Seguidor',
-      defaultUser: 'Usuario',
+      saveFailed: "Fallo al guardar",
+      uploadFailed: "Error subir archivo",
+      defaultFollower: "Seguidor",
+      defaultUser: "Usuario",
     },
   },
   footer: {
-    aboutSection: 'Sobre Nosotros',
-    companyIntro: 'Presentación Empresa',
-    brand: 'Marca',
-    community: 'Únete a nuestra Comunidad',
-    riskWarning: 'Aviso de Riesgo',
-    terms: 'Términos de Servicio',
-    privacy: 'Política Privacidad',
-    futuresTrade: 'Trading Futuros',
-    spotTrade: 'Trading Spot',
-    losslessCopy: 'Copy Sin Pérdida',
-    beginnerGuide: 'Guía Principiantes',
-    helpCenter: 'Centro Ayuda',
-    glossary: 'Glosario',
-    compliance: 'Normativa Legal',
-    products: 'Productos',
-    resources: 'Recursos',
+    aboutSection: "Sobre Nosotros",
+    companyIntro: "Presentación Empresa",
+    brand: "Marca",
+    community: "Únete a nuestra Comunidad",
+    riskWarning: "Aviso de Riesgo",
+    terms: "Términos de Servicio",
+    privacy: "Política Privacidad",
+    futuresTrade: "Trading Futuros",
+    spotTrade: "Trading Spot",
+    losslessCopy: "Copy Sin Pérdida",
+    beginnerGuide: "Guía Principiantes",
+    helpCenter: "Centro Ayuda",
+    glossary: "Glosario",
+    compliance: "Normativa Legal",
+    products: "Productos",
+    resources: "Recursos",
   },
   announcements: {
-    title: 'Anuncios del Sistema',
-    noAnnouncements: 'Sin anuncios',
-    back: 'Volver',
-    backToList: 'Volver Lista',
-    loadMore: 'Cargar Más',
+    title: "Anuncios del Sistema",
+    noAnnouncements: "Sin anuncios",
+    back: "Volver",
+    backToList: "Volver Lista",
+    loadMore: "Cargar Más",
   },
   download: {
-    title: 'Descargar iBit',
-    heroTitle: 'Mercado en Tiempo Real\nOpera en Cualquier Momento',
-    desc: 'Controla cotizaciones y opera desde cualquier lugar',
-    appDesc: 'Todas las funciones disponibles en app, trading desde móvil',
-    latestVersion: 'Última Versión',
-    updateNotes: 'Notas Actualización',
-    ios: 'Descargar iOS',
-    iosNotReleased: 'iOS no disponible',
-    android: 'Descargar Android',
-    androidNotReleased: 'Android no disponible',
-    scanToDownload: 'Escanea para descargar',
+    title: "Descargar iBit",
+    heroTitle: "Mercado en Tiempo Real\nOpera en Cualquier Momento",
+    desc: "Controla cotizaciones y opera desde cualquier lugar",
+    appDesc: "Todas las funciones disponibles en app, trading desde móvil",
+    latestVersion: "Última Versión",
+    updateNotes: "Notas Actualización",
+    ios: "Descargar iOS",
+    iosNotReleased: "iOS no disponible",
+    android: "Descargar Android",
+    androidNotReleased: "Android no disponible",
+    scanToDownload: "Escanea para descargar",
   },
   account: {
-    title: 'Centro de Cuenta',
-    uid: 'UID',
-    email: 'Correo',
-    profile: 'Perfil',
-    security: 'Seguridad',
-    securityDesc: 'Contraseñas, verificaciones y clave fondos',
-    assets: 'Mis Activos',
-    assetsDesc: 'Depósito, retiro y transferencias',
-    inviteCode: 'Código Invitación',
-    inviteFriends: 'Invitar Amigos',
-    inviteDesc: 'Invita usuarios y obtén comisiones por sus operaciones',
-    helpSupport: 'Ayuda y Soporte',
-    helpDesc: 'Preguntas frecuentes y tickets',
-    broker: 'Broker',
-    brokerDesc: 'Gestión comisiones y equipo',
-    logout: 'Cerrar Sesión',
-    securityScore: 'Puntuación Seguridad',
-    twofa: 'Autenticación Google',
-    supportTitle: 'Contactar Soporte',
-    supportHours: 'Atención 7×24h',
-    onlineSupport: 'Chat Online',
-    instantChat: 'Chat Directo',
-    telegramSupport: 'Soporte Telegram',
-    emailSupport: 'Soporte Correo',
-    applySubmitted: 'Solicitud enviada, pendiente aprobación',
-    scoreHigh: 'Excelente',
-    scoreMedium: 'Regular',
-    scoreLow: 'Mejorable',
+    title: "Centro de Cuenta",
+    uid: "UID",
+    email: "Correo",
+    profile: "Perfil",
+    security: "Seguridad",
+    securityDesc: "Contraseñas, verificaciones y clave fondos",
+    assets: "Mis Activos",
+    assetsDesc: "Depósito, retiro y transferencias",
+    inviteCode: "Código Invitación",
+    inviteFriends: "Invitar Amigos",
+    inviteDesc: "Invita usuarios y obtén comisiones por sus operaciones",
+    helpSupport: "Ayuda y Soporte",
+    helpDesc: "Preguntas frecuentes y tickets",
+    broker: "Broker",
+    brokerDesc: "Gestión comisiones y equipo",
+    logout: "Cerrar Sesión",
+    securityScore: "Puntuación Seguridad",
+    twofa: "Autenticación Google",
+    supportTitle: "Contactar Soporte",
+    supportHours: "Atención 7×24h",
+    onlineSupport: "Chat Online",
+    instantChat: "Chat Directo",
+    telegramSupport: "Soporte Telegram",
+    emailSupport: "Soporte Correo",
+    applySubmitted: "Solicitud enviada, pendiente aprobación",
+    scoreHigh: "Excelente",
+    scoreMedium: "Regular",
+    scoreLow: "Mejorable",
   },
   transfer: {
-    title: 'Transferencia',
-    amount: 'Cantidad a Transferir',
-    amountPlaceholder: 'Ingresa cantidad',
-    maxTransferable: 'Máximo Transferible',
-    success: 'Transferencia Exitosa',
-    selectCoin: 'Seleccionar Moneda',
-    enterAmount: 'Ingresa importe',
-    histEmpty: 'Sin registros transferencia',
-    balanceLabel: 'Saldo',
+    title: "Transferencia",
+    amount: "Cantidad a Transferir",
+    amountPlaceholder: "Ingresa cantidad",
+    maxTransferable: "Máximo Transferible",
+    success: "Transferencia Exitosa",
+    selectCoin: "Seleccionar Moneda",
+    enterAmount: "Ingresa importe",
+    histEmpty: "Sin registros transferencia",
+    balanceLabel: "Saldo",
   },
   withdraw: {
-    title: 'Retirar Fondos',
-    network: 'Red',
-    networkTip: 'Confirma coincidencia de red con plataforma destino o puedes perder tus activos.',
-    address: 'Dirección Retiro',
-    addressPlaceholder: 'Ingresa dirección destino',
-    amount: 'Cantidad Retiro',
-    received: 'Importe Recibido',
-    fee: 'Comisión',
-    submitted: 'Solicitud de retiro enviada',
-    fundPassword: 'Clave Fondos',
-    emailCode: 'Código Correo',
-    googleCode: 'Código Google',
-    securityVerification: 'Verificación Seguridad',
-    recordTitle: 'Historial Retiros',
-    recordEmpty: 'Sin retiros registrados',
-    confirmCancelApply: '¿Cancelar esta solicitud de retiro?',
-    withdrawCancelledToast: 'Cancelado',
-    withdrawCancelFailedToast: 'Fallo al cancelar',
-    statusPending: 'En revisión',
-    statusReleasing: 'En proceso de pago',
-    statusWithdrawFailed: 'Fallido',
-    statusWithdrawSuccess: 'Completado',
-    statusWithdrawCancelled: 'Cancelado',
-    typeInternalTransfer: 'Transferencia Interna',
-    typeOnChainWithdraw: 'Retiro en Cadena',
-    cancelApplyBtn: 'Cancelar',
-    initFailed: 'Error inicialización',
-    submitOnChainFailed: 'Fallo envío retiro cadena',
-    transferSubmitFailed: 'Fallo transferencia interna',
-    availWithdrawBalance: 'Saldo retirable:',
-    availTransferBalance: 'Saldo transferible:',
-    coinLabel: 'Moneda',
-    subCoin: 'Submoneda',
-    mainCoinLabel: 'Moneda Principal',
-    transferMainCoinHint: 'Transferencia interna solo monedas principales, no tokens derivados (TUSDT/EUSDT).',
-    withdrawNetworkLabel: 'Red Retiro',
-    withdrawAmountUsdt: 'Cantidad Retiro (USDT)',
-    withdrawAmountCoin: 'Cantidad Retiro ({coin})',
-    transferAmountUsdt: 'Cantidad Transferencia (USDT)',
-    transferAmountCoin: 'Cantidad Transferencia ({coin})',
-    addressForCoin: 'Ingresa dirección {coin}',
-    expectedArrival: 'Estimado recibo',
-    minWithdrawRowLabel: 'Retiro Mínimo',
-    internalTransferFeeLabel: 'Comisión Transfer. Interna',
-    free: 'Gratis',
-    minTransferRowLabel: 'Transferencia Mínima',
-    recipientUidLabel: 'UID Destino',
-    recipientUidPlaceholder: 'Ingresa UID del destinatario',
-    addressForNetwork: 'Dirección USDT-{network}',
-    codePlaceholder6Digits: 'Código 6 dígitos',
-    googlePlaceholder6: 'Código autenticador 6 dígitos',
-    sendVerificationCode: 'Enviar Código',
-    confirmWithdrawSubmit: 'Confirmar Retiro',
-    confirmTransferSubmit: 'Confirmar Transferencia',
-    codeSentToEmailToast: 'Código enviado al correo',
-    onchainSubmittedPendingToast: 'Retiro enviado, pendiente revisión',
-    transferSubmittedToast: 'Transferencia interna enviada',
-    submitFailed: 'Fallo envío',
-    detailTitleOnChain: 'Detalle Retiro Cadena',
-    detailTitleTransfer: 'Detalle Transferencia Interna',
-    amountHeroWithdraw: 'Cantidad Retirada',
-    amountHeroTransfer: 'Cantidad Transferida',
-    stepApplied: 'Enviada',
-    stepDone: 'Finalizada',
-    recipientLabel: 'Destinatario',
-    appliedAt: 'Fecha Envío',
-    finishedAt: 'Fecha Finalización',
-    cancelApplyFull: 'Anular Solicitud',
-    copyBtn: 'Copiar',
-    bindGoogleFirst: 'Primero vincula autenticación Google',
-    errFillAddressBeforeCode: 'Completa dirección antes de pedir código',
-    errFillAmountBeforeCode: 'Ingresa importe antes de solicitar código',
-    errFillUidBeforeCode: 'Completa UID destino antes de código',
-    errFillTransferAmtBeforeCode: 'Ingresa importe transferencia primero',
-    errEnterWithdrawAddress: 'Escribe dirección retiro',
-    errEnterWithdrawAmount: 'Ingresa cantidad a retirar',
-    errMinWithdrawWithAmt: 'Retiro mínimo {min} {coin}',
-    errMinWithdrawWithAmtUsdt: 'Retiro mínimo {min} USDT',
-    errExceedWithdrawBalance: 'Supera saldo retirable',
-    errEnterFundPassword: 'Ingresa clave fondos',
-    errEnterEmailCode: 'Ingresa código correo',
-    errEnterGoogleCode: 'Ingresa código Google',
-    errEnterRecipientUid: 'Escribe UID destinatario',
-    errEnterTransferAmount: 'Ingresa importe transferencia',
-    errMinTransferWithAmt: 'Transferencia mínima {min} {coin}',
-    errMinTransferWithAmtUsdt: 'Transferencia mínima {min} USDT',
-    errExceedTransferBalance: 'Supera saldo transferible',
+    title: "Retirar Fondos",
+    network: "Red",
+    networkTip:
+      "Confirma coincidencia de red con plataforma destino o puedes perder tus activos.",
+    address: "Dirección Retiro",
+    addressPlaceholder: "Ingresa dirección destino",
+    amount: "Cantidad Retiro",
+    received: "Importe Recibido",
+    fee: "Comisión",
+    submitted: "Solicitud de retiro enviada",
+    fundPassword: "Clave Fondos",
+    emailCode: "Código Correo",
+    googleCode: "Código Google",
+    securityVerification: "Verificación Seguridad",
+    recordTitle: "Historial Retiros",
+    recordEmpty: "Sin retiros registrados",
+    confirmCancelApply: "¿Cancelar esta solicitud de retiro?",
+    withdrawCancelledToast: "Cancelado",
+    withdrawCancelFailedToast: "Fallo al cancelar",
+    statusPending: "En revisión",
+    statusReleasing: "En proceso de pago",
+    statusWithdrawFailed: "Fallido",
+    statusWithdrawSuccess: "Completado",
+    statusWithdrawCancelled: "Cancelado",
+    typeInternalTransfer: "Transferencia Interna",
+    typeOnChainWithdraw: "Retiro en Cadena",
+    cancelApplyBtn: "Cancelar",
+    initFailed: "Error inicialización",
+    submitOnChainFailed: "Fallo envío retiro cadena",
+    transferSubmitFailed: "Fallo transferencia interna",
+    availWithdrawBalance: "Saldo retirable:",
+    availTransferBalance: "Saldo transferible:",
+    coinLabel: "Moneda",
+    subCoin: "Submoneda",
+    mainCoinLabel: "Moneda Principal",
+    transferMainCoinHint:
+      "Transferencia interna solo monedas principales, no tokens derivados (TUSDT/EUSDT).",
+    withdrawNetworkLabel: "Red Retiro",
+    withdrawAmountUsdt: "Cantidad Retiro (USDT)",
+    withdrawAmountCoin: "Cantidad Retiro ({coin})",
+    transferAmountUsdt: "Cantidad Transferencia (USDT)",
+    transferAmountCoin: "Cantidad Transferencia ({coin})",
+    addressForCoin: "Ingresa dirección {coin}",
+    expectedArrival: "Estimado recibo",
+    minWithdrawRowLabel: "Retiro Mínimo",
+    internalTransferFeeLabel: "Comisión Transfer. Interna",
+    free: "Gratis",
+    minTransferRowLabel: "Transferencia Mínima",
+    recipientUidLabel: "UID Destino",
+    recipientUidPlaceholder: "Ingresa UID del destinatario",
+    addressForNetwork: "Dirección USDT-{network}",
+    codePlaceholder6Digits: "Código 6 dígitos",
+    googlePlaceholder6: "Código autenticador 6 dígitos",
+    sendVerificationCode: "Enviar Código",
+    confirmWithdrawSubmit: "Confirmar Retiro",
+    confirmTransferSubmit: "Confirmar Transferencia",
+    codeSentToEmailToast: "Código enviado al correo",
+    onchainSubmittedPendingToast: "Retiro enviado, pendiente revisión",
+    transferSubmittedToast: "Transferencia interna enviada",
+    submitFailed: "Fallo envío",
+    detailTitleOnChain: "Detalle Retiro Cadena",
+    detailTitleTransfer: "Detalle Transferencia Interna",
+    amountHeroWithdraw: "Cantidad Retirada",
+    amountHeroTransfer: "Cantidad Transferida",
+    stepApplied: "Enviada",
+    stepDone: "Finalizada",
+    recipientLabel: "Destinatario",
+    appliedAt: "Fecha Envío",
+    finishedAt: "Fecha Finalización",
+    cancelApplyFull: "Anular Solicitud",
+    copyBtn: "Copiar",
+    bindGoogleFirst: "Primero vincula autenticación Google",
+    errFillAddressBeforeCode: "Completa dirección antes de pedir código",
+    errFillAmountBeforeCode: "Ingresa importe antes de solicitar código",
+    errFillUidBeforeCode: "Completa UID destino antes de código",
+    errFillTransferAmtBeforeCode: "Ingresa importe transferencia primero",
+    errEnterWithdrawAddress: "Escribe dirección retiro",
+    errEnterWithdrawAmount: "Ingresa cantidad a retirar",
+    errMinWithdrawWithAmt: "Retiro mínimo {min} {coin}",
+    errMinWithdrawWithAmtUsdt: "Retiro mínimo {min} USDT",
+    errExceedWithdrawBalance: "Supera saldo retirable",
+    errEnterFundPassword: "Ingresa clave fondos",
+    errEnterEmailCode: "Ingresa código correo",
+    errEnterGoogleCode: "Ingresa código Google",
+    errEnterRecipientUid: "Escribe UID destinatario",
+    errEnterTransferAmount: "Ingresa importe transferencia",
+    errMinTransferWithAmt: "Transferencia mínima {min} {coin}",
+    errMinTransferWithAmtUsdt: "Transferencia mínima {min} USDT",
+    errExceedTransferBalance: "Supera saldo transferible",
   },
   deposit: {
-    title: 'Depositar',
-    address: 'Dirección Depósito',
-    network: 'Red',
-    saveQrCode: 'Guardar Código QR',
-    addressCopied: 'Dirección Copiada',
-    minDeposit: 'Depósito Mínimo',
-    arrivals: 'Confirmaciones',
-    coin: 'Moneda',
-    protocol: 'Red / Protocolo',
-    subCoin: 'Submoneda',
-    contract: 'Contrato',
-    depositAmount: 'Importe Depósito',
-    amountPlaceholder: 'Ingresa cantidad',
-    generateOrder: 'Crear Orden',
-    generating: 'Generando…',
-    notice: 'Aviso',
-    notice1: 'Crea orden antes de transferir, usa dirección e importe de la orden.',
-    notice2: 'No envíes fondos a red o contrato erróneo, pérdida irreversible.',
-    notice3: 'Tras transferir envía hash de transacción para confirmar abono.',
-    intro: 'Explicación',
-    introText: 'Elige moneda y red, define importe, genera orden con dirección exclusiva; tras transferir en cadena adjunta TxHash.',
-    newDeposit: '← Nuevo Depósito',
-    orderInfo: 'Datos Orden',
-    orderNo: 'Nº Orden',
-    status: 'Estado',
-    coinLabel: 'Moneda',
-    networkLabel: 'Red',
-    amount: 'Importe',
-    payAddress: 'Dirección Recepción',
-    payAddressHint: 'Transfiere el importe exacto con red y moneda igual a la orden',
-    qrTitle: 'Pago QR',
-    qrHint: 'Escanea con tu billetera, no modifiques dirección ni valor',
-    contractAddress: 'Dirección Contrato',
-    copy: '⎘ Copiar',
-    copyAddress: 'Copiar Dirección',
-    submitHash: 'Enviar Hash Transacción',
-    submittingHash: 'Enviando…',
-    hashPlaceholder: 'Pega Hash cadena / TxID Tron',
-    orSubmitHash: 'O envía hash tras completar transferencia',
-    hashRequired: 'Ingresa hash de transacción',
-    statusNotSubmittable: 'No admite envío hash en este estado',
-    orderCreated: 'Orden creada, transfiere a la dirección indicada',
-    orderFailed: 'Fallo creación orden',
-    addressCopy: 'Dirección copiada',
-    orderNoCopy: 'Número orden copiado',
-    hashSubmitted: 'Enviado, esperando confirmación cadena',
-    hashFailed: 'Fallo envío hash',
-    broadcastSuccess: 'Transacción emitida, hash registrado',
-    tronBroadcastSuccess: 'Tx Tron emitida, TxID registrado',
-    noNetwork: 'Sin redes disponibles',
-    noSubCoin: 'Sin submonedas en esta red',
-    amountRequired: 'Ingresa importe depósito',
-    amountPositive: 'El valor debe ser superior a 0',
-    submittedHash: 'Hash enviado: ',
-    manualDepositTab: 'Depósito Manual',
-    walletDepositTab: 'Depósito con Billetera',
-    walletPayEvm: 'Conectar billetera EVM y pagar',
-    walletPayingEvm: 'Procesando billetera EVM…',
-    walletPayTron: 'Conectar billetera Tron y pagar',
-    walletPayingTron: 'Procesando billetera Tron…',
-    histLink: 'Historial Depósitos',
-    retryBtn: 'Reintentar',
-    backWithArrow: '‹ Volver',
-    rechargeStatus0: 'Pendiente Pago',
-    rechargeStatus1: 'Pendiente Confirmación Cadena',
-    rechargeStatus2: 'Completado',
-    rechargeStatus3: 'Cancelado',
-    rechargeStatus4: 'Fallido',
-    statusUnknown: 'Estado {status}',
-    qrAlt: 'QR dirección depósito',
-    loadNetworksFailed: 'Fallo carga redes',
+    title: "Depositar",
+    address: "Dirección Depósito",
+    network: "Red",
+    saveQrCode: "Guardar Código QR",
+    addressCopied: "Dirección Copiada",
+    minDeposit: "Depósito Mínimo",
+    arrivals: "Confirmaciones",
+    coin: "Moneda",
+    protocol: "Red / Protocolo",
+    subCoin: "Submoneda",
+    contract: "Contrato",
+    depositAmount: "Importe Depósito",
+    amountPlaceholder: "Ingresa cantidad",
+    generateOrder: "Crear Orden",
+    generating: "Generando…",
+    notice: "Aviso",
+    notice1:
+      "Crea orden antes de transferir, usa dirección e importe de la orden.",
+    notice2: "No envíes fondos a red o contrato erróneo, pérdida irreversible.",
+    notice3: "Tras transferir envía hash de transacción para confirmar abono.",
+    intro: "Explicación",
+    introText:
+      "Elige moneda y red, define importe, genera orden con dirección exclusiva; tras transferir en cadena adjunta TxHash.",
+    newDeposit: "← Nuevo Depósito",
+    orderInfo: "Datos Orden",
+    orderNo: "Nº Orden",
+    status: "Estado",
+    coinLabel: "Moneda",
+    networkLabel: "Red",
+    amount: "Importe",
+    payAddress: "Dirección Recepción",
+    payAddressHint:
+      "Transfiere el importe exacto con red y moneda igual a la orden",
+    qrTitle: "Pago QR",
+    qrHint: "Escanea con tu billetera, no modifiques dirección ni valor",
+    contractAddress: "Dirección Contrato",
+    copy: "⎘ Copiar",
+    copyAddress: "Copiar Dirección",
+    submitHash: "Enviar Hash Transacción",
+    submittingHash: "Enviando…",
+    hashPlaceholder: "Pega Hash cadena / TxID Tron",
+    orSubmitHash: "O envía hash tras completar transferencia",
+    hashRequired: "Ingresa hash de transacción",
+    statusNotSubmittable: "No admite envío hash en este estado",
+    orderCreated: "Orden creada, transfiere a la dirección indicada",
+    orderFailed: "Fallo creación orden",
+    addressCopy: "Dirección copiada",
+    orderNoCopy: "Número orden copiado",
+    hashSubmitted: "Enviado, esperando confirmación cadena",
+    hashFailed: "Fallo envío hash",
+    broadcastSuccess: "Transacción emitida, hash registrado",
+    tronBroadcastSuccess: "Tx Tron emitida, TxID registrado",
+    noNetwork: "Sin redes disponibles",
+    noSubCoin: "Sin submonedas en esta red",
+    amountRequired: "Ingresa importe depósito",
+    amountPositive: "El valor debe ser superior a 0",
+    submittedHash: "Hash enviado: ",
+    manualDepositTab: "Depósito Manual",
+    walletDepositTab: "Depósito con Billetera",
+    walletPayEvm: "Conectar billetera EVM y pagar",
+    walletPayingEvm: "Procesando billetera EVM…",
+    walletPayTron: "Conectar billetera Tron y pagar",
+    walletPayingTron: "Procesando billetera Tron…",
+    histLink: "Historial Depósitos",
+    retryBtn: "Reintentar",
+    backWithArrow: "‹ Volver",
+    rechargeStatus0: "Pendiente Pago",
+    rechargeStatus1: "Pendiente Confirmación Cadena",
+    rechargeStatus2: "Completado",
+    rechargeStatus3: "Cancelado",
+    rechargeStatus4: "Fallido",
+    statusUnknown: "Estado {status}",
+    qrAlt: "QR dirección depósito",
+    loadNetworksFailed: "Fallo carga redes",
     wcHintEvmConfigured:
-      'Conecta WalletConnect EVM para pagar automáticamente, verifica red y moneda coincidan.',
+      "Conecta WalletConnect EVM para pagar automáticamente, verifica red y moneda coincidan.",
     wcHintEvmUnconfigured:
-      'Falta VITE_WALLETCONNECT_PROJECT_ID, usa depósito manual y envía hash.',
+      "Falta VITE_WALLETCONNECT_PROJECT_ID, usa depósito manual y envía hash.",
     wcHintTronConfigured:
-      'WalletConnect Tron firma y envía operación, adjunta TxID Tron sin prefijo 0x.',
+      "WalletConnect Tron firma y envía operación, adjunta TxID Tron sin prefijo 0x.",
     wcHintTronUnconfigured:
-      'Sin configuración WalletConnect Tron, usa depósito manual con TxID.',
+      "Sin configuración WalletConnect Tron, usa depósito manual con TxID.",
     wcHintTronManualOnly:
-      'No soporta conexión automática para esta red, usa depósito manual.',
-    walletPayFallback: 'Fallo pago billetera EVM',
-    tronWalletPayFallback: 'Fallo pago billetera Tron',
-    currentPrefix: 'Actual:',
-    histEmpty: 'Sin registros depósito',
-    histOrderNo: 'Nº Orden',
-    histTx: 'TX:',
-    histLoadMore: 'Cargar más',
-    histLoadedAll: 'Todos los registros cargados',
+      "No soporta conexión automática para esta red, usa depósito manual.",
+    walletPayFallback: "Fallo pago billetera EVM",
+    tronWalletPayFallback: "Fallo pago billetera Tron",
+    currentPrefix: "Actual:",
+    histEmpty: "Sin registros depósito",
+    histOrderNo: "Nº Orden",
+    histTx: "TX:",
+    histLoadMore: "Cargar más",
+    histLoadedAll: "Todos los registros cargados",
   },
   broker: {
-    title: 'Centro Broker',
-    applyTitle: 'Solicitar Ser Broker',
-    myBrokerCode: 'Mi Código Broker',
-    referralCount: 'Usuarios Referidos',
-    totalCommission: 'Comisión Total',
-    applyStatus: 'Estado Solicitud',
-    pending: 'En Revisión',
-    approved: 'Aprobado',
-    rejected: 'Rechazado',
-    defaultName: 'Broker',
-    greeting: 'Hola, {name}',
-    uidLabel: 'UID: {uid}',
-    introBanner: 'Gana comisiones por cada operación de tus invitados, abono diario instantáneo.',
-    statNewToday: 'Nuevos hoy (usuarios)',
-    statTradeToday: 'Operantes hoy (usuarios)',
-    statRebateToday: 'Comisión hoy (USDT)',
-    inviteList: 'Lista Invitados',
-    emptyInviteList: 'Sin invitados',
-    thAccount: 'Cuenta',
-    thLevel: 'Nivel',
-    thPerpCopy: 'Perpetuo / Copy',
-    levelBroker: 'Broker',
-    levelNormal: 'Estándar',
-    editRateTooltip: 'Modificar % comisión',
-    todayRebate: 'Comisiones Hoy',
-    emptyTodayRebate: 'Sin comisiones hoy',
-    thId: 'ID',
-    rebateUsdt: 'Comisión (USDT)',
-    teamDetails: 'Detalles Equipo',
-    filterAll: 'Todo',
-    filterWeek: 'Últimos 7 días',
-    filterToday: 'Hoy',
-    filterMonth: 'Este Mes',
-    teamTotalAssets: 'Activos Totales Equipo',
-    rebateHistory: 'Historial Comisiones',
-    emptyRebateHistory: 'Sin registros comisión',
-    amountUsdt: 'Importe (USDT)',
-    loadMore: 'Cargar más',
-    loadingMore: 'Cargando…',
-    loadedAll: 'Todos cargados',
-    editModalTitle: 'Editar % Comisión',
-    perpRebateRate: '% Comisión Futuros Perpetuos',
-    copyRebateRate: '% Comisión Copy Trading',
-    editTip: 'Los cambios aplican inmediatamente, modifica con precaución.',
-    perpRateError: '% perpetuo debe ser entero entre 0 y 100',
-    copyRateError: '% copy debe ser entero entre 0 y 100',
-    setSuccess: 'Guardado, cambios activos',
+    title: "Centro Broker",
+    applyTitle: "Solicitar Ser Broker",
+    myBrokerCode: "Mi Código Broker",
+    referralCount: "Usuarios Referidos",
+    totalCommission: "Comisión Total",
+    applyStatus: "Estado Solicitud",
+    pending: "En Revisión",
+    approved: "Aprobado",
+    rejected: "Rechazado",
+    defaultName: "Broker",
+    greeting: "Hola, {name}",
+    uidLabel: "UID: {uid}",
+    introBanner:
+      "Gana comisiones por cada operación de tus invitados, abono diario instantáneo.",
+    statNewToday: "Nuevos hoy (usuarios)",
+    statTradeToday: "Operantes hoy (usuarios)",
+    statRebateToday: "Comisión hoy (USDT)",
+    inviteList: "Lista Invitados",
+    emptyInviteList: "Sin invitados",
+    thAccount: "Cuenta",
+    thLevel: "Nivel",
+    thPerpCopy: "Perpetuo / Copy",
+    levelBroker: "Broker",
+    levelNormal: "Estándar",
+    editRateTooltip: "Modificar % comisión",
+    todayRebate: "Comisiones Hoy",
+    emptyTodayRebate: "Sin comisiones hoy",
+    thId: "ID",
+    rebateUsdt: "Comisión (USDT)",
+    teamDetails: "Detalles Equipo",
+    filterAll: "Todo",
+    filterWeek: "Últimos 7 días",
+    filterToday: "Hoy",
+    filterMonth: "Este Mes",
+    teamTotalAssets: "Activos Totales Equipo",
+    rebateHistory: "Historial Comisiones",
+    emptyRebateHistory: "Sin registros comisión",
+    amountUsdt: "Importe (USDT)",
+    loadMore: "Cargar más",
+    loadingMore: "Cargando…",
+    loadedAll: "Todos cargados",
+    editModalTitle: "Editar % Comisión",
+    perpRebateRate: "% Comisión Futuros Perpetuos",
+    copyRebateRate: "% Comisión Copy Trading",
+    editTip: "Los cambios aplican inmediatamente, modifica con precaución.",
+    perpRateError: "% perpetuo debe ser entero entre 0 y 100",
+    copyRateError: "% copy debe ser entero entre 0 y 100",
+    setSuccess: "Guardado, cambios activos",
   },
   help: {
-    title: 'Centro de Ayuda',
-    supportTitle: 'Ayuda y Soporte',
-    search: 'Buscar',
-    searchPlaceholder: 'Palabras clave',
-    telegramSupport: 'Soporte Telegram',
-    quickResponse: 'Respuesta Rápida',
-    emailSupport: 'Soporte Correo',
-    docs: 'Documentación',
-    viewFullGuide: 'Ver Guía Completa',
-    detailTitle: 'Detalle Ayuda',
-    backToHelp: 'Volver Centro Ayuda',
+    title: "Centro de Ayuda",
+    supportTitle: "Ayuda y Soporte",
+    search: "Buscar",
+    searchPlaceholder: "Palabras clave",
+    telegramSupport: "Soporte Telegram",
+    quickResponse: "Respuesta Rápida",
+    emailSupport: "Soporte Correo",
+    docs: "Documentación",
+    viewFullGuide: "Ver Guía Completa",
+    detailTitle: "Detalle Ayuda",
+    backToHelp: "Volver Centro Ayuda",
   },
   invite: {
-    title: 'Invitar Amigos',
-    myCode: 'Mi Código Invitación',
-    copy: 'Copiar Código',
-    copied: 'Código Copiado',
-    share: 'Compartir Enlace',
-    shareLink: 'Copiar Enlace',
-    linkCopied: 'Enlace Copiado',
-    desc: 'Invita amigos y obtén comisiones por sus operaciones',
-    totalInvited: 'Total Invitados',
-    totalReward: 'Comisión Total',
-    noRecord: 'Sin registros invitación',
-    heroLine1: 'Invita Amigos',
-    heroLine2: 'Gana Comisiones',
+    title: "Invitar Amigos",
+    myCode: "Mi Código Invitación",
+    copy: "Copiar Código",
+    copied: "Código Copiado",
+    share: "Compartir Enlace",
+    shareLink: "Copiar Enlace",
+    linkCopied: "Enlace Copiado",
+    desc: "Invita amigos y obtén comisiones por sus operaciones",
+    totalInvited: "Total Invitados",
+    totalReward: "Comisión Total",
+    noRecord: "Sin registros invitación",
+    heroLine1: "Invita Amigos",
+    heroLine2: "Gana Comisiones",
     heroDesc:
-      'Cada usuario registrado por tu enlace te habilita para el plan de comisiones según reglas oficiales.',
-    myInviteInfo: 'Mis Datos Invitación',
-    inviteCodeLabel: 'Código Invitación',
-    inviteLinkShort: 'Enlace Invitación',
-    qrCodeLabel: 'Código QR',
-    copyShort: 'Copiar',
-    copiedDone: 'Copiado ✓',
-    qrInviteAlt: 'QR Invitación',
-    scanToRegister: 'Escanea para registrarse',
-    rebateRulesTitle: 'Normativa Comisiones',
-    step1Title: 'Comparte tu código',
-    step1Desc: 'Envía código o enlace exclusivo a tus contactos',
-    step2Title: 'Registro Amigo',
-    step2Desc: 'El usuario completa registro desde tu enlace',
-    step3Title: 'Obtén Comisión',
-    step3Desc: 'Recibes porcentaje de las comisiones generadas por sus operaciones',
+      "Cada usuario registrado por tu enlace te habilita para el plan de comisiones según reglas oficiales.",
+    myInviteInfo: "Mis Datos Invitación",
+    inviteCodeLabel: "Código Invitación",
+    inviteLinkShort: "Enlace Invitación",
+    qrCodeLabel: "Código QR",
+    copyShort: "Copiar",
+    copiedDone: "Copiado ✓",
+    qrInviteAlt: "QR Invitación",
+    scanToRegister: "Escanea para registrarse",
+    rebateRulesTitle: "Normativa Comisiones",
+    step1Title: "Comparte tu código",
+    step1Desc: "Envía código o enlace exclusivo a tus contactos",
+    step2Title: "Registro Amigo",
+    step2Desc: "El usuario completa registro desde tu enlace",
+    step3Title: "Obtén Comisión",
+    step3Desc:
+      "Recibes porcentaje de las comisiones generadas por sus operaciones",
   },
   futuresPage: futuresPageByLocale.es,
   spot: {
-    tag: 'Spot',
-    side: { buy: 'Comprar', sell: 'Vender' },
-    orderType: { limit: 'Limitada', market: 'Mercado' },
+    tag: "Spot",
+    side: { buy: "Comprar", sell: "Vender" },
+    orderType: { limit: "Limitada", market: "Mercado" },
     orderStatus: {
-      pending: 'Abierta',
-      partial: 'Parcialmente Ejecutada',
-      filled: 'Ejecutada',
-      cancelled: 'Cancelada',
-      pending_cancel: 'Cancelando',
-      expired: 'Expirada',
-      init: 'Inicializando',
+      pending: "Abierta",
+      partial: "Parcialmente Ejecutada",
+      filled: "Ejecutada",
+      cancelled: "Cancelada",
+      pending_cancel: "Cancelando",
+      expired: "Expirada",
+      init: "Inicializando",
     },
     recordType: {
-      transferIn: 'Ingreso Fondos',
-      transferOut: 'Salida Fondos',
-      orderFreeze: 'Bloqueo por Orden',
-      cancelUnfreeze: 'Desbloqueo Cancelación',
-      trade: 'Operación',
-      fee: 'Comisión',
-      unfreeze: 'Desbloqueo',
-      unknown: 'Tipo {type}',
+      transferIn: "Ingreso Fondos",
+      transferOut: "Salida Fondos",
+      orderFreeze: "Bloqueo por Orden",
+      cancelUnfreeze: "Desbloqueo Cancelación",
+      trade: "Operación",
+      fee: "Comisión",
+      unfreeze: "Desbloqueo",
+      unknown: "Tipo {type}",
     },
     tabs: {
-      currentOrders: 'Órdenes Abiertas',
-      historyOrders: 'Historial Órdenes',
-      trades: 'Historial Operaciones',
-      funding: 'Movimientos Fondos',
+      currentOrders: "Órdenes Abiertas",
+      historyOrders: "Historial Órdenes",
+      trades: "Historial Operaciones",
+      funding: "Movimientos Fondos",
     },
     table: {
-      pair: 'Par',
-      side: 'Sentido',
-      type: 'Tipo',
-      price: 'Precio',
-      orderPrice: 'Precio Orden',
-      amount: 'Cantidad',
-      orderAmount: 'Cantidad Orden',
-      filled: 'Ejecutado',
-      status: 'Estado',
-      time: 'Fecha',
-      action: 'Acción',
-      dealPrice: 'Precio Ejecución',
-      dealVolume: 'Volumen Ejecutado',
-      turnover: 'Volumen Total',
-      recordType: 'Tipo Mov.',
-      quantity: 'Cantidad',
-      coin: 'Moneda',
+      pair: "Par",
+      side: "Sentido",
+      type: "Tipo",
+      price: "Precio",
+      orderPrice: "Precio Orden",
+      amount: "Cantidad",
+      orderAmount: "Cantidad Orden",
+      filled: "Ejecutado",
+      status: "Estado",
+      time: "Fecha",
+      action: "Acción",
+      dealPrice: "Precio Ejecución",
+      dealVolume: "Volumen Ejecutado",
+      turnover: "Volumen Total",
+      recordType: "Tipo Mov.",
+      quantity: "Cantidad",
+      coin: "Moneda",
     },
     trade: {
-      buy: 'Comprar',
-      sell: 'Vender',
-      limit: 'Limitada',
-      market: 'Mercado',
-      processing: 'Procesando...',
-      buySymbol: 'Comprar {symbol}',
-      sellSymbol: 'Vender {symbol}',
-      priceUsdt: 'Precio (USDT)',
-      limitPlaceholder: 'Precio límite',
-      marketHint: 'Compra/venta al mejor precio disponible',
-      amountUsdt: 'Importe (USDT)',
-      amountBase: 'Cantidad ({base})',
-      available: 'Disponible',
-      transfer: 'Transferir',
-      loginForBalance: 'Inicia sesión para ver saldo',
-      spotAssets: 'Saldo Spot',
+      buy: "Comprar",
+      sell: "Vender",
+      limit: "Limitada",
+      market: "Mercado",
+      processing: "Procesando...",
+      buySymbol: "Comprar {symbol}",
+      sellSymbol: "Vender {symbol}",
+      priceUsdt: "Precio (USDT)",
+      limitPlaceholder: "Precio límite",
+      marketHint: "Compra/venta al mejor precio disponible",
+      amountUsdt: "Importe (USDT)",
+      amountBase: "Cantidad ({base})",
+      available: "Disponible",
+      transfer: "Transferir",
+      loginForBalance: "Inicia sesión para ver saldo",
+      spotAssets: "Saldo Spot",
     },
-    order: { cancel: 'Cancelar', cancelAll: 'Cancelar Todas' },
+    order: { cancel: "Cancelar", cancelAll: "Cancelar Todas" },
     empty: {
-      loginLink: 'Iniciar Sesión',
-      loginOrdersPrompt: '{link} para ver órdenes',
-      loginViewPrompt: '{link} para consultar',
-      noOrders: 'Sin órdenes abiertas',
-      noHistoryOrders: 'Sin historial órdenes',
-      noTrades: 'Sin operaciones',
-      noFunding: 'Sin registros',
+      loginLink: "Iniciar Sesión",
+      loginOrdersPrompt: "{link} para ver órdenes",
+      loginViewPrompt: "{link} para consultar",
+      noOrders: "Sin órdenes abiertas",
+      noHistoryOrders: "Sin historial órdenes",
+      noTrades: "Sin operaciones",
+      noFunding: "Sin registros",
     },
     errors: {
-      symbolNotReady: 'Par de cotización no disponible',
-      invalidAmount: 'Ingresa cantidad válida',
-      invalidPrice: 'Precio no válido',
-      minLimitVolume: 'Cantidad mínima {min}',
-      minMarketBuy: 'Compra mercado mínimo {min} USDT',
-      minMarketSell: 'Venta mercado mínima {min}',
-      orderSubmitted: 'Orden enviada',
-      orderFailed: 'Fallo envío orden',
-      cancelSuccess: 'Orden cancelada',
-      cancelFailed: 'Fallo cancelación',
-      cancelAllSuccess: 'Todas canceladas',
-      cancelAllPartialFailed: 'Algunas no pudieron cancelarse',
+      symbolNotReady: "Par de cotización no disponible",
+      invalidAmount: "Ingresa cantidad válida",
+      invalidPrice: "Precio no válido",
+      minLimitVolume: "Cantidad mínima {min}",
+      minMarketBuy: "Compra mercado mínimo {min} USDT",
+      minMarketSell: "Venta mercado mínima {min}",
+      orderSubmitted: "Orden enviada",
+      orderFailed: "Fallo envío orden",
+      cancelSuccess: "Orden cancelada",
+      cancelFailed: "Fallo cancelación",
+      cancelAllSuccess: "Todas canceladas",
+      cancelAllPartialFailed: "Algunas no pudieron cancelarse",
     },
-    loadedAll: 'Todos cargados',
+    loadedAll: "Todos cargados",
     ticker: {
-      change24h: 'Var.24h',
-      high24h: 'Máx 24h',
-      low24h: 'Mín 24h',
-      turnover24h: 'Volumen 24h',
+      change24h: "Var.24h",
+      high24h: "Máx 24h",
+      low24h: "Mín 24h",
+      turnover24h: "Volumen 24h",
     },
-    chartSub: { chart: 'Gráfico', coinInfo: 'Datos Moneda' },
+    chartSub: { chart: "Gráfico", coinInfo: "Datos Moneda" },
     tf: {
-    	m1: '1m', 
-    	m5: '5m', 
-    	m15: '15m', 
-    	m30: '30m', 
-    	h1: '1h', 
-    	h4: '4h', 
-    	d1: '1d',
-    	w1: '1w',
-    	mo1: '1mon',
-    	mo3: '3mon'
+      m1: "1m",
+      m5: "5m",
+      m15: "15m",
+      m30: "30m",
+      h1: "1h",
+      h4: "4h",
+      d1: "1d",
+      w1: "1w",
+      mo1: "1mon",
+      mo3: "3mon",
     },
     ohlcv: {
-      spotLabel: 'Spot',
-      open: 'Apert',
-      high: 'Máx',
-      low: 'Mín',
-      close: 'Cierr',
-      volume: 'Vol',
-      changePct: 'Var%',
+      spotLabel: "Spot",
+      open: "Apert",
+      high: "Máx",
+      low: "Mín",
+      close: "Cierr",
+      volume: "Vol",
+      changePct: "Var%",
     },
     draw: {
-      cursor: 'Cursor',
-      trend: 'Línea Tendencia',
-      hline: 'Línea Horizontal',
-      ray: 'Rayo',
-      channel: 'Canal',
-      fib: 'Fibonacci',
-      text: 'Texto',
-      clearAll: 'Borrar Todo',
-      zoomOut: 'Alejar',
+      cursor: "Cursor",
+      trend: "Línea Tendencia",
+      hline: "Línea Horizontal",
+      ray: "Rayo",
+      channel: "Canal",
+      fib: "Fibonacci",
+      text: "Texto",
+      clearAll: "Borrar Todo",
+      zoomOut: "Alejar",
+    },
+    mobileTab: { chart: "Mercado", trade: "Operar" },
+    pair: {
+      search: "Buscar",
+      loading: "Cargando…",
+      noMatch: "Sin resultados",
+      retryLater: ", reintenta más tarde",
+    },
+    book: {
+      waiting: "Esperando datos…",
+      orderbook: "Libro de órdenes",
+      trades: "Operaciones",
+      priceUsdt: "Precio (USDT)",
+      amountBase: "Cantidad ({base})",
+      total: "Total",
+      buyRatio: "Compra {n}%",
+      sellRatio: "{n}% Venta",
+      price: "Precio",
+      amount: "Cantidad",
+      time: "Fecha",
+      pricePrecision: "Precisión de precio",
     },
-    mobileTab: { chart: 'Mercado', trade: 'Operar' },
-        pair: {
-          search: 'Buscar',
-          loading: 'Cargando…',
-          noMatch: 'Sin resultados',
-          retryLater: ', reintenta más tarde'
-        },
-        book: {
-          waiting: 'Esperando datos…',
-          orderbook: 'Libro de órdenes',
-          trades: 'Operaciones',
-          priceUsdt: 'Precio (USDT)',
-          amountBase: 'Cantidad ({base})',
-          total: 'Total',
-          buyRatio: 'Compra {n}%',
-          sellRatio: '{n}% Venta',
-          price: 'Precio',
-          amount: 'Cantidad',
-          time: 'Fecha',
-          pricePrecision: 'Precisión de precio'
-        },
-        coinInfo: {
-          marketCap: 'Capitalización',
-          circulating: 'Suministro circulante',
-          issuePrice: 'Precio de emisión',
-          ath: 'Máximo histórico',
-          athDate: 'Fecha máximo histórico',
-          whitepaper: 'Libro blanco',
-          empty: 'Sin datos de la moneda',
-          reload: 'Recargar'
-        },
-        transferModal: {
-          title: 'Transferencia',
-          selectCoin: 'Moneda',
-          amount: 'Cantidad',
-          amountPlaceholder: 'Ingresa importe',
-          availableUsdt: 'Disponible USDT:',
-          availableCoin: 'Disponible {coin}:',
-          transferring: 'Transfiriendo...',
-          invalidAmount: 'Ingresa un importe válido',
-          insufficientBalance: 'El importe supera el saldo disponible',
-          transferFailed: 'Fallo de transferencia, reintenta'
-        },
-      },
-    }
+    coinInfo: {
+      marketCap: "Capitalización",
+      circulating: "Suministro circulante",
+      issuePrice: "Precio de emisión",
+      ath: "Máximo histórico",
+      athDate: "Fecha máximo histórico",
+      whitepaper: "Libro blanco",
+      empty: "Sin datos de la moneda",
+      reload: "Recargar",
+    },
+    transferModal: {
+      title: "Transferencia",
+      selectCoin: "Moneda",
+      amount: "Cantidad",
+      amountPlaceholder: "Ingresa importe",
+      availableUsdt: "Disponible USDT:",
+      availableCoin: "Disponible {coin}:",
+      transferring: "Transfiriendo...",
+      invalidAmount: "Ingresa un importe válido",
+      insufficientBalance: "El importe supera el saldo disponible",
+      transferFailed: "Fallo de transferencia, reintenta",
+    },
+  },
+};

+ 2023 - 1879
code/src/locales/futuresPage.i18n.ts

@@ -1,1935 +1,2079 @@
-import { deepMerge } from '@/utils/deepMerge'
-import { koUiOverlay } from './futuresPage/overlays/ko'
-import { jaUiOverlay } from './futuresPage/overlays/ja'
-import { hiUiOverlay } from './futuresPage/overlays/hi'
-import { idUiOverlay } from './futuresPage/overlays/id'
-import { esUiOverlay } from './futuresPage/overlays/es'
-import { ruUiOverlay } from './futuresPage/overlays/ru'
-import { ptUiOverlay } from './futuresPage/overlays/pt'
-import { deUiOverlay } from './futuresPage/overlays/de'
-import { frUiOverlay } from './futuresPage/overlays/fr'
-import { trUiOverlay } from './futuresPage/overlays/tr'
-import { viUiOverlay } from './futuresPage/overlays/vi'
+import { deepMerge } from "@/utils/deepMerge";
+import { koUiOverlay } from "./futuresPage/overlays/ko";
+import { jaUiOverlay } from "./futuresPage/overlays/ja";
+import { hiUiOverlay } from "./futuresPage/overlays/hi";
+import { idUiOverlay } from "./futuresPage/overlays/id";
+import { esUiOverlay } from "./futuresPage/overlays/es";
+import { ruUiOverlay } from "./futuresPage/overlays/ru";
+import { ptUiOverlay } from "./futuresPage/overlays/pt";
+import { deUiOverlay } from "./futuresPage/overlays/de";
+import { frUiOverlay } from "./futuresPage/overlays/fr";
+import { trUiOverlay } from "./futuresPage/overlays/tr";
+import { viUiOverlay } from "./futuresPage/overlays/vi";
 
 /** 深度可选(用于各语言 overlay 局部覆盖) */
 export type DeepPartial<T> = {
-	[P in keyof T]?: T[P] extends Record<string, unknown> ? DeepPartial<T[P]> : T[P]
-}
+  [P in keyof T]?: T[P] extends Record<string, unknown>
+    ? DeepPartial<T[P]>
+    : T[P];
+};
 
 /** 合约页(FuturesView)文案:供各语言入口复用,禁止在组件内硬编码用户可见中文。 */
 export type FuturesPageMessages = {
-	perpetual : string
-	/** 资金流水币种后缀,如 USDT + 永续 */
-	perpetualTag : string
-	pairSearchPlaceholder : string
-	pairSearchTag:{
-		oneType: string,
-		twoType: string,
-		threeType: string,
-		fourType: string,
-	},
-	pairEmpty : string
-	stats : {
-		change24h : string
-		markPrice : string
-		high24h : string
-		low24h : string
-		volume24h : string
-		fundingCountdown : string
-	}
-	mobileTabs : { chart : string; trade : string }
-	chartSub : { chart : string; coinInfo : string; fundingHistory : string }
-	tf : { m1 : string; m5 : string; m15 : string; m30 : string; h1 : string; h4 : string; d1 : string, w1 : string, mo1 : string, mo3 : string }
-	chartTools : { fullscreen : string; alert : string }
-	draw : {
-		cursor : string
-		trend : string
-		hline : string
-		ray : string
-		channel : string
-		fib : string
-		text : string
-		clearAll : string
-		zoomOut : string
-	}
-	ohlcv : { open : string; high : string; low : string; close : string; volume : string; changePct : string; amplitude : string }
-	coinInfo : {
-		marketCap : string
-		circulating : string
-		issuePrice : string
-		ath : string
-		athDate : string
-		whitepaper : string
-		empty : string
-		reload : string
-	}
-	fundingPanel : {
-		rate : string
-		period : string
-		nextCountdown : string
-		noChart : string
-		settleTime : string
-		rateCol : string
-		empty7d : string
-	}
-	book : {
-		orderBook : string
-		trades : string
-		priceQuote : string
-		amountBase : string
-		totalBase : string
-		time : string
-		buy : string
-		sell : string
-		buyRatio : string
-		sellRatio : string
-		noTrades : string
-	}
-	margin : { cross : string; split : string; experience : string }
-	amountUnit : { lots : string; usdt : string }
-	leverage : { adjustTitle : string }
-	order : {
-		limit : string
-		market : string
-		conditional : string
-		condMarket : string
-		condLimit : string
-		available : string
-		maxOpen : string
-		triggerPriceLabel : string
-		priceLabel : string
-		latestBtn : string
-		marketExe : string
-		condMarketExe : string
-		qtyLabel : string
-		transferTitle : string
-		openLong : string
-		openShort : string
-		contractInfoTitle : string
-		indexSource : string
-		marginCoin : string
-		maxLeverage : string
-		maintMargin : string
-		openFee : string
-		closeFee : string
-		contractValue : string
-		minOrder : string
-		maxOrder : string
-	}
-	placeholders : {
-		searchPair : string
-		triggerPrice : string
-		price : string
-		amount : string
-	}
-	bottom : {
-		positions : string
-		openOrders : string
-		historyOrders : string
-		historyPositions : string
-		tradeDetails : string
-		fundingFlow : string
-		assets : string
-		closeAllPositions : string
-		cancelAllOrders : string
-		loginPromptOr : string
-		registerNow : string
-		startTrading : string
-	}
-	table : {
-		contract : string
-		dirLeverage : string
-		openPrice : string
-		markPrice : string
-		positionSize : string
-		margin : string
-		marginRate : string
-		unrealizedPnl : string
-		roe : string
-		liqPrice : string
-		openTime : string
-		action : string
-		type : string
-		orderPrice : string
-		entrustPriceHist : string
-		triggerPrice : string
-		orderAmt : string
-		filled : string
-		tpPrice : string
-		slPrice : string
-		time : string
-		orderTime : string
-		fillTime : string
-		profitUsdt : string
-		tradedVol : string
-		closeAvg : string
-		profitRate : string
-		closeTime : string
-		directionOpenClose : string
-		dealPrice : string
-		fee : string
-		fundType : string
-		amount : string
-		coin : string
-		settlementTime : string
-		fundingRate : string
-		totalBal : string
-		availMargin : string
-		usedMargin : string
-		unrealized : string
-		spotWalletBal : string
-		fundTransfer : string
-		avgOpenPrice : string
-		feeHint : string
-		estimatedPnlRow : string
-		triggerUsdt : string
-		orderPriceUsdt : string
-		openAvgUsdt : string
-		closeAvgUsdt : string
-		tpUsdt : string
-		slUsdt : string
-		marginUsdtBracket : string
-		notionalUsdt : string
-		estLiqPx : string
-		profitBracketUsdt : string
-		entrustVolCoin : string
-		filledVolCoin : string
-		closeAvail : string
-		markPriceBtn : string
-	}
-	empty : {
-		noPositions : string
-		noOrders : string
-		noHistPositions : string
-		noHistOrders : string
-		noTradeRecords : string
-		noFunding : string
-	}
-	modal : {
-		confirmDefaultTitle : string
-		positionDetailTitle : string
-		orderDetailTitle : string
-		histPositionDetailTitle : string
-		histOrderDetailTitle : string
-		closePositionTitlePrefix : string
-		modifyTpSl : string
-		setTpSl : string
-		posQtyLabel : string
-		currentTpSlSection : string
-		modifyToSection : string
-		setPricesSection : string
-		tpTriggerLabel : string
-		tpHintOptionalClear : string
-		slTriggerLabel : string
-		slHintOptionalClear : string
-		placeholderTpTrigger : string
-		placeholderSlTrigger : string
-		confirmCloseBtn : string
-		ok : string
-		closeTypeLiquidation : string
-		tpBadge : string
-		slBadge : string
-		tpPriceWord : string
-		slPriceWord : string
-		volLabel : string
-		marginSplitMode : string
-		directionLabel : string
-		entrustTypeLabel : string
-		leverageLabel : string
-	}
-	actions : {
-		tpSl : string
-		reverse : string
-		close : string
-		marketCloseAll : string
-		cancelOrder : string
-	}
-	positionRow : {
-		hintCross : string
-		hintExperience : string
-	}
-	errors : {
-		enterTriggerPrice : string
-		enterPrice : string
-		priceNotReadyConvert : string
-		invalidQtyCheckMin : string
-		priceNotReadyRetry : string
-		enterQty : string
-		qtyExceedAvail : string
-		closeFailed : string
-		modifyTpSlFailed : string
-		txFallback : string
-	}
-	confirm : {
-		reverseTitle : string
-		reverseBody : string
-		cancelAllTitle : string
-		cancelAllBody : string
-		closeAllTitle : string
-		closeAllBody : string
-		sideLongWord : string
-		sideShortWord : string
-	}
-	directions : {
-		long : string
-		short : string
-		openLong : string
-		openShort : string
-		closeShort : string
-		closeLong : string
-		openTag : string
-		closeTag : string
-	}
-	orderTypes : {
-		limit : string
-		plan : string
-		takeProfit : string
-		stopLoss : string
-		marketShort : string
-	}
-	orderStatus : {
-		filled : string
-		open : string
-		cancelled : string
-		failed : string
-	}
-	closeTypes : {
-		market : string
-		oneClick : string
-		reverseOpen : string
-		tpSl : string
-		liquidation : string
-		admin : string
-	}
-	fundingTx : Record<string, string>
-}
+  perpetual: string;
+  /** 资金流水币种后缀,如 USDT + 永续 */
+  perpetualTag: string;
+  pairSearchPlaceholder: string;
+  pairSearchTag: {
+    oneType: string;
+    twoType: string;
+    threeType: string;
+    fourType: string;
+  };
+  pairEmpty: string;
+  stats: {
+    change24h: string;
+    markPrice: string;
+    high24h: string;
+    low24h: string;
+    volume24h: string;
+    fundingCountdown: string;
+  };
+  mobileTabs: { chart: string; trade: string };
+  chartSub: { chart: string; coinInfo: string; fundingHistory: string };
+  tf: {
+    m1: string;
+    m5: string;
+    m15: string;
+    m30: string;
+    h1: string;
+    h4: string;
+    d1: string;
+    w1: string;
+    mo1: string;
+    mo3: string;
+  };
+  chartTools: { fullscreen: string; alert: string };
+  draw: {
+    cursor: string;
+    trend: string;
+    hline: string;
+    ray: string;
+    channel: string;
+    fib: string;
+    text: string;
+    clearAll: string;
+    zoomOut: string;
+  };
+  ohlcv: {
+    open: string;
+    high: string;
+    low: string;
+    close: string;
+    volume: string;
+    changePct: string;
+    amplitude: string;
+  };
+  coinInfo: {
+    marketCap: string;
+    circulating: string;
+    issuePrice: string;
+    ath: string;
+    athDate: string;
+    whitepaper: string;
+    empty: string;
+    reload: string;
+  };
+  fundingPanel: {
+    rate: string;
+    period: string;
+    nextCountdown: string;
+    noChart: string;
+    settleTime: string;
+    rateCol: string;
+    empty7d: string;
+  };
+  book: {
+    orderBook: string;
+    trades: string;
+    priceQuote: string;
+    amountBase: string;
+    totalBase: string;
+    time: string;
+    buy: string;
+    sell: string;
+    buyRatio: string;
+    sellRatio: string;
+    noTrades: string;
+  };
+  margin: { cross: string; split: string; experience: string };
+  amountUnit: { lots: string; usdt: string };
+  leverage: { adjustTitle: string };
+  order: {
+    limit: string;
+    market: string;
+    conditional: string;
+    condMarket: string;
+    condLimit: string;
+    available: string;
+    maxOpen: string;
+    triggerPriceLabel: string;
+    priceLabel: string;
+    latestBtn: string;
+    marketExe: string;
+    condMarketExe: string;
+    qtyLabel: string;
+    transferTitle: string;
+    openLong: string;
+    openShort: string;
+    contractInfoTitle: string;
+    indexSource: string;
+    marginCoin: string;
+    maxLeverage: string;
+    maintMargin: string;
+    openFee: string;
+    closeFee: string;
+    contractValue: string;
+    minOrder: string;
+    maxOrder: string;
+  };
+  placeholders: {
+    searchPair: string;
+    triggerPrice: string;
+    price: string;
+    amount: string;
+  };
+  bottom: {
+    positions: string;
+    openOrders: string;
+    historyOrders: string;
+    historyPositions: string;
+    tradeDetails: string;
+    fundingFlow: string;
+    assets: string;
+    closeAllPositions: string;
+    cancelAllOrders: string;
+    loginPromptOr: string;
+    registerNow: string;
+    startTrading: string;
+  };
+  table: {
+    contract: string;
+    dirLeverage: string;
+    openPrice: string;
+    markPrice: string;
+    positionSize: string;
+    margin: string;
+    marginRate: string;
+    unrealizedPnl: string;
+    roe: string;
+    liqPrice: string;
+    openTime: string;
+    action: string;
+    type: string;
+    orderPrice: string;
+    entrustPriceHist: string;
+    triggerPrice: string;
+    orderAmt: string;
+    filled: string;
+    tpPrice: string;
+    slPrice: string;
+    time: string;
+    orderTime: string;
+    fillTime: string;
+    profitUsdt: string;
+    tradedVol: string;
+    closeAvg: string;
+    profitRate: string;
+    closeTime: string;
+    directionOpenClose: string;
+    dealPrice: string;
+    fee: string;
+    fundType: string;
+    amount: string;
+    coin: string;
+    settlementTime: string;
+    fundingRate: string;
+    totalBal: string;
+    availMargin: string;
+    usedMargin: string;
+    unrealized: string;
+    spotWalletBal: string;
+    fundTransfer: string;
+    avgOpenPrice: string;
+    feeHint: string;
+    estimatedPnlRow: string;
+    triggerUsdt: string;
+    orderPriceUsdt: string;
+    openAvgUsdt: string;
+    closeAvgUsdt: string;
+    tpUsdt: string;
+    slUsdt: string;
+    marginUsdtBracket: string;
+    notionalUsdt: string;
+    estLiqPx: string;
+    profitBracketUsdt: string;
+    entrustVolCoin: string;
+    filledVolCoin: string;
+    closeAvail: string;
+    markPriceBtn: string;
+  };
+  empty: {
+    noPositions: string;
+    noOrders: string;
+    noHistPositions: string;
+    noHistOrders: string;
+    noTradeRecords: string;
+    noFunding: string;
+  };
+  modal: {
+    confirmDefaultTitle: string;
+    positionDetailTitle: string;
+    orderDetailTitle: string;
+    histPositionDetailTitle: string;
+    histOrderDetailTitle: string;
+    closePositionTitlePrefix: string;
+    modifyTpSl: string;
+    setTpSl: string;
+    posQtyLabel: string;
+    currentTpSlSection: string;
+    modifyToSection: string;
+    setPricesSection: string;
+    tpTriggerLabel: string;
+    tpHintOptionalClear: string;
+    slTriggerLabel: string;
+    slHintOptionalClear: string;
+    placeholderTpTrigger: string;
+    placeholderSlTrigger: string;
+    confirmCloseBtn: string;
+    ok: string;
+    closeTypeLiquidation: string;
+    tpBadge: string;
+    slBadge: string;
+    tpPriceWord: string;
+    slPriceWord: string;
+    volLabel: string;
+    marginSplitMode: string;
+    directionLabel: string;
+    entrustTypeLabel: string;
+    leverageLabel: string;
+  };
+  actions: {
+    tpSl: string;
+    reverse: string;
+    close: string;
+    marketCloseAll: string;
+    cancelOrder: string;
+  };
+  positionRow: {
+    hintCross: string;
+    hintExperience: string;
+  };
+  errors: {
+    enterTriggerPrice: string;
+    enterPrice: string;
+    priceNotReadyConvert: string;
+    invalidQtyCheckMin: string;
+    priceNotReadyRetry: string;
+    enterQty: string;
+    qtyExceedAvail: string;
+    closeFailed: string;
+    modifyTpSlFailed: string;
+    txFallback: string;
+  };
+  confirm: {
+    reverseTitle: string;
+    reverseBody: string;
+    cancelAllTitle: string;
+    cancelAllBody: string;
+    closeAllTitle: string;
+    closeAllBody: string;
+    sideLongWord: string;
+    sideShortWord: string;
+  };
+  directions: {
+    long: string;
+    short: string;
+    openLong: string;
+    openShort: string;
+    closeShort: string;
+    closeLong: string;
+    openTag: string;
+    closeTag: string;
+  };
+  orderTypes: {
+    limit: string;
+    plan: string;
+    takeProfit: string;
+    stopLoss: string;
+    marketShort: string;
+  };
+  orderStatus: {
+    filled: string;
+    open: string;
+    cancelled: string;
+    failed: string;
+  };
+  closeTypes: {
+    market: string;
+    oneClick: string;
+    reverseOpen: string;
+    tpSl: string;
+    liquidation: string;
+    admin: string;
+  };
+  fundingTx: Record<string, string>;
+};
 
-const fundingTxZh : Record<string, string> = {
-	'0': '充值',
-	'1': '提现',
-	'2': '转账',
-	'3': '币币交易',
-	'4': '法币买入',
-	'5': '法币卖出',
-	'6': '签到奖励',
-	'7': '推广奖励',
-	'8': '合约跟单奖励',
-	'9': '投票',
-	'10': '人工充值',
-	'11': '配对',
-	'12': '交易奖励',
-	'13': 'CTC买入',
-	'14': 'CTC卖出',
-	'15': '红包发出',
-	'16': '红包领取',
-	'17': '提现码提现',
-	'18': '提现码充值',
-	'19': '永续合约手续费',
-	'20': '永续合约盈利',
-	'21': '永续合约亏损',
-	'22': '期权合约失败',
-	'23': '期权合约手续费',
-	'24': '期权合约奖金',
-	'25': '合约返佣',
-	'26': '合约资金费率',
-	'27': '永续合约爆仓',
-	'28': '活动手续费',
-	'29': '活动盈利',
-	'30': '活动亏损',
-	'31': '活动返佣',
-	'32': '平级奖励',
-	'33': '平台手续费收入',
-	'34': '秒合约失败',
-	'35': '秒合约奖金',
-	'36': '理财利息',
-	'37': '合约跟单手续费',
-	'38': '合约跟单盈利',
-	'39': '合约跟单亏损',
-	'40': '合约跟单分润',
-	'41': '合约跟单返佣',
-	'42': '跟单资金费率',
-	'47': '体验金提现',
-	'49': '质押',
-	'50': '质押解冻释放',
-	'51': '空投奖励',
-	'52': '划入质押钱包',
-	'53': '质押钱包划出',
-}
+const fundingTxZh: Record<string, string> = {
+  "0": "充值",
+  "1": "提现",
+  "2": "转账",
+  "3": "币币交易",
+  "4": "法币买入",
+  "5": "法币卖出",
+  "6": "签到奖励",
+  "7": "推广奖励",
+  "8": "合约跟单奖励",
+  "9": "投票",
+  "10": "人工充值",
+  "11": "配对",
+  "12": "交易奖励",
+  "13": "CTC买入",
+  "14": "CTC卖出",
+  "15": "红包发出",
+  "16": "红包领取",
+  "17": "提现码提现",
+  "18": "提现码充值",
+  "19": "永续合约手续费",
+  "20": "永续合约盈利",
+  "21": "永续合约亏损",
+  "22": "期权合约失败",
+  "23": "期权合约手续费",
+  "24": "期权合约奖金",
+  "25": "合约返佣",
+  "26": "合约资金费率",
+  "27": "永续合约爆仓",
+  "28": "活动手续费",
+  "29": "活动盈利",
+  "30": "活动亏损",
+  "31": "活动返佣",
+  "32": "平级奖励",
+  "33": "平台手续费收入",
+  "34": "秒合约失败",
+  "35": "秒合约奖金",
+  "36": "理财利息",
+  "37": "合约跟单手续费",
+  "38": "合约跟单盈利",
+  "39": "合约跟单亏损",
+  "40": "合约跟单分润",
+  "41": "合约跟单返佣",
+  "42": "跟单资金费率",
+  "47": "体验金提现",
+  "49": "质押",
+  "50": "质押解冻释放",
+  "51": "空投奖励",
+  "52": "划入质押钱包",
+  "53": "质押钱包划出",
+};
 
-const fundingTxEn : Record<string, string> = {
-	'0': 'Deposit',
-	'1': 'Withdrawal',
-	'2': 'Transfer',
-	'3': 'Spot trade',
-	'4': 'Fiat buy',
-	'5': 'Fiat sell',
-	'6': 'Check-in reward',
-	'7': 'Referral reward',
-	'8': 'Copy-trading reward',
-	'9': 'Vote',
-	'10': 'Manual deposit',
-	'11': 'Pairing',
-	'12': 'Trading reward',
-	'13': 'CTC buy',
-	'14': 'CTC sell',
-	'15': 'Red packet sent',
-	'16': 'Red packet received',
-	'17': 'Withdrawal code payout',
-	'18': 'Withdrawal code deposit',
-	'19': 'Perp trading fee',
-	'20': 'Perp profit',
-	'21': 'Perp loss',
-	'22': 'Option failure',
-	'23': 'Option fee',
-	'24': 'Option bonus',
-	'25': 'Contract rebate',
-	'26': 'Funding fee',
-	'27': 'Perp liquidation',
-	'28': 'Campaign fee',
-	'29': 'Campaign profit',
-	'30': 'Campaign loss',
-	'31': 'Campaign rebate',
-	'32': 'Peer reward',
-	'33': 'Platform fee income',
-	'34': 'Quick contract failure',
-	'35': 'Quick contract bonus',
-	'36': 'Wealth interest',
-	'37': 'Copy-trading fee',
-	'38': 'Copy-trading profit',
-	'39': 'Copy-trading loss',
-	'40': 'Copy-trading profit share',
-	'41': 'Copy-trading rebate',
-	'42': 'Copy funding fee',
-	'47': 'Bonus withdrawal',
-	'49': 'Staking',
-	'50': 'Staking unlock release',
-	'51': 'Airdrop reward',
-	'52': 'Transfer to staking wallet',
-	'53': 'Transfer from staking wallet',
-}
+const fundingTxEn: Record<string, string> = {
+  "0": "Deposit",
+  "1": "Withdrawal",
+  "2": "Transfer",
+  "3": "Spot trade",
+  "4": "Fiat buy",
+  "5": "Fiat sell",
+  "6": "Check-in reward",
+  "7": "Referral reward",
+  "8": "Copy-trading reward",
+  "9": "Vote",
+  "10": "Manual deposit",
+  "11": "Pairing",
+  "12": "Trading reward",
+  "13": "CTC buy",
+  "14": "CTC sell",
+  "15": "Red packet sent",
+  "16": "Red packet received",
+  "17": "Withdrawal code payout",
+  "18": "Withdrawal code deposit",
+  "19": "Perp trading fee",
+  "20": "Perp profit",
+  "21": "Perp loss",
+  "22": "Option failure",
+  "23": "Option fee",
+  "24": "Option bonus",
+  "25": "Contract rebate",
+  "26": "Funding fee",
+  "27": "Perp liquidation",
+  "28": "Campaign fee",
+  "29": "Campaign profit",
+  "30": "Campaign loss",
+  "31": "Campaign rebate",
+  "32": "Peer reward",
+  "33": "Platform fee income",
+  "34": "Quick contract failure",
+  "35": "Quick contract bonus",
+  "36": "Wealth interest",
+  "37": "Copy-trading fee",
+  "38": "Copy-trading profit",
+  "39": "Copy-trading loss",
+  "40": "Copy-trading profit share",
+  "41": "Copy-trading rebate",
+  "42": "Copy funding fee",
+  "47": "Bonus withdrawal",
+  "49": "Staking",
+  "50": "Staking unlock release",
+  "51": "Airdrop reward",
+  "52": "Transfer to staking wallet",
+  "53": "Transfer from staking wallet",
+};
 
-const fundingTw : Record<string, string> = {
-	'0': '儲值',
-	'1': '提現',
-	'2': '轉帳',
-	'3': '幣幣交易',
-	'4': '法幣買入',
-	'5': '法幣賣出',
-	'6': '簽到獎勵',
-	'7': '推廣獎勵',
-	'8': '合約跟單獎勵',
-	'9': '投票',
-	'10': '人工儲值',
-	'11': '配對',
-	'12': '交易獎勵',
-	'13': 'CTC買入',
-	'14': 'CTC賣出',
-	'15': '紅包發出',
-	'16': '紅包領取',
-	'17': '提現碼提現',
-	'18': '提現碼充值',
-	'19': '永續合約手續費',
-	'20': '永續合約盈利',
-	'21': '永續合約虧損',
-	'22': '選擇權合約失敗',
-	'23': '選擇權合約手續費',
-	'24': '選擇權合約獎金',
-	'25': '合約返佣',
-	'26': '合約資金費率',
-	'27': '永續合約爆倉',
-	'28': '活動手續費',
-	'29': '活動盈利',
-	'30': '活動虧損',
-	'31': '活動返佣',
-	'32': '平級獎勵',
-	'33': '平台手續費收入',
-	'34': '秒合約失敗',
-	'35': '秒合約獎金',
-	'36': '理財利息',
-	'37': '合約跟單手續費',
-	'38': '合約跟單盈利',
-	'39': '合約跟單虧損',
-	'40': '合約跟單分潤',
-	'41': '合約跟單返佣',
-	'42': '跟單資金費率',
-	'47': '體驗金提現',
-	'49': '質押',
-	'50': '質押解凍釋放',
-	'51': '空投獎勵',
-	'52': '劃入質押錢包',
-	'53': '質押錢包劃出',
-}
+const fundingTw: Record<string, string> = {
+  "0": "儲值",
+  "1": "提現",
+  "2": "轉帳",
+  "3": "幣幣交易",
+  "4": "法幣買入",
+  "5": "法幣賣出",
+  "6": "簽到獎勵",
+  "7": "推廣獎勵",
+  "8": "合約跟單獎勵",
+  "9": "投票",
+  "10": "人工儲值",
+  "11": "配對",
+  "12": "交易獎勵",
+  "13": "CTC買入",
+  "14": "CTC賣出",
+  "15": "紅包發出",
+  "16": "紅包領取",
+  "17": "提現碼提現",
+  "18": "提現碼充值",
+  "19": "永續合約手續費",
+  "20": "永續合約盈利",
+  "21": "永續合約虧損",
+  "22": "選擇權合約失敗",
+  "23": "選擇權合約手續費",
+  "24": "選擇權合約獎金",
+  "25": "合約返佣",
+  "26": "合約資金費率",
+  "27": "永續合約爆倉",
+  "28": "活動手續費",
+  "29": "活動盈利",
+  "30": "活動虧損",
+  "31": "活動返佣",
+  "32": "平級獎勵",
+  "33": "平台手續費收入",
+  "34": "秒合約失敗",
+  "35": "秒合約獎金",
+  "36": "理財利息",
+  "37": "合約跟單手續費",
+  "38": "合約跟單盈利",
+  "39": "合約跟單虧損",
+  "40": "合約跟單分潤",
+  "41": "合約跟單返佣",
+  "42": "跟單資金費率",
+  "47": "體驗金提現",
+  "49": "質押",
+  "50": "質押解凍釋放",
+  "51": "空投獎勵",
+  "52": "劃入質押錢包",
+  "53": "質押錢包劃出",
+};
 
-const fundingTxKo : Record<string, string> = {
-	'0': '입금',
-	'1': '출금',
-	'2': '이체',
-	'3': '현물 거래',
-	'4': '법정화폐 매수',
-	'5': '법정화폐 매도',
-	'6': '출석 보상',
-	'7': '추천 보상',
-	'8': '카피 트레이딩 보상',
-	'9': '투표',
-	'10': '수동 입금',
-	'11': '페어링',
-	'12': '거래 보상',
-	'13': 'CTC 매수',
-	'14': 'CTC 매도',
-	'15': '홍바오 발송',
-	'16': '홍바오 수령',
-	'17': '출금 코드 출금',
-	'18': '출금 코드 입금',
-	'19': '영구 계약 수수료',
-	'20': '영구 계약 수익',
-	'21': '영구 계약 손실',
-	'22': '옵션 실패',
-	'23': '옵션 수수료',
-	'24': '옵션 보너스',
-	'25': '계약 리베이트',
-	'26': '펀딩비',
-	'27': '영구 계약 청산',
-	'28': '이벤트 수수료',
-	'29': '이벤트 수익',
-	'30': '이벤트 손실',
-	'31': '이벤트 리베이트',
-	'32': '동급 보상',
-	'33': '플랫폼 수수료 수입',
-	'34': '초단기 계약 실패',
-	'35': '초단기 계약 보너스',
-	'36': '재테크 이자',
-	'37': '카피 트레이딩 수수료',
-	'38': '카피 트레이딩 수익',
-	'39': '카피 트레이딩 손실',
-	'40': '카피 트레이딩 분배',
-	'41': '카피 트레이딩 리베이트',
-	'42': '카피 펀딩비',
-	'47': '체험금 출금',
-	'49': '스테이킹',
-	'50': '스테이킹 잠금 해제',
-	'51': '에어드롭 보상',
-	'52': '스테이킹 지갑 입금',
-	'53': '스테이킹 지갑 출금',
-}
+const fundingTxKo: Record<string, string> = {
+  "0": "입금",
+  "1": "출금",
+  "2": "이체",
+  "3": "현물 거래",
+  "4": "법정화폐 매수",
+  "5": "법정화폐 매도",
+  "6": "출석 보상",
+  "7": "추천 보상",
+  "8": "카피 트레이딩 보상",
+  "9": "투표",
+  "10": "수동 입금",
+  "11": "페어링",
+  "12": "거래 보상",
+  "13": "CTC 매수",
+  "14": "CTC 매도",
+  "15": "홍바오 발송",
+  "16": "홍바오 수령",
+  "17": "출금 코드 출금",
+  "18": "출금 코드 입금",
+  "19": "영구 계약 수수료",
+  "20": "영구 계약 수익",
+  "21": "영구 계약 손실",
+  "22": "옵션 실패",
+  "23": "옵션 수수료",
+  "24": "옵션 보너스",
+  "25": "계약 리베이트",
+  "26": "펀딩비",
+  "27": "영구 계약 청산",
+  "28": "이벤트 수수료",
+  "29": "이벤트 수익",
+  "30": "이벤트 손실",
+  "31": "이벤트 리베이트",
+  "32": "동급 보상",
+  "33": "플랫폼 수수료 수입",
+  "34": "초단기 계약 실패",
+  "35": "초단기 계약 보너스",
+  "36": "재테크 이자",
+  "37": "카피 트레이딩 수수료",
+  "38": "카피 트레이딩 수익",
+  "39": "카피 트레이딩 손실",
+  "40": "카피 트레이딩 분배",
+  "41": "카피 트레이딩 리베이트",
+  "42": "카피 펀딩비",
+  "47": "체험금 출금",
+  "49": "스테이킹",
+  "50": "스테이킹 잠금 해제",
+  "51": "에어드롭 보상",
+  "52": "스테이킹 지갑 입금",
+  "53": "스테이킹 지갑 출금",
+};
 
-const fundingTxJa : Record<string, string> = {
-	'0': '入金',
-	'1': '出金',
-	'2': '振替',
-	'3': '現物取引',
-	'4': '法定通貨購入',
-	'5': '法定通貨売却',
-	'6': 'チェックイン報酬',
-	'7': '紹介報酬',
-	'8': 'コピートレード報酬',
-	'9': '投票',
-	'10': '手動入金',
-	'11': 'ペアリング',
-	'12': '取引報酬',
-	'13': 'CTC購入',
-	'14': 'CTC売却',
-	'15': 'お年玉送信',
-	'16': 'お年玉受取',
-	'17': '出金コード出金',
-	'18': '出金コード入金',
-	'19': '無期限契約手数料',
-	'20': '無期限契約利益',
-	'21': '無期限契約損失',
-	'22': 'オプション失敗',
-	'23': 'オプション手数料',
-	'24': 'オプションボーナス',
-	'25': '契約リベート',
-	'26': '資金調達率',
-	'27': '無期限契約強制決済',
-	'28': 'キャンペーン手数料',
-	'29': 'キャンペーン利益',
-	'30': 'キャンペーン損失',
-	'31': 'キャンペーンリベート',
-	'32': '同級報酬',
-	'33': 'プラットフォーム手数料収入',
-	'34': '秒契約失敗',
-	'35': '秒契約ボーナス',
-	'36': '運用利息',
-	'37': 'コピートレード手数料',
-	'38': 'コピートレード利益',
-	'39': 'コピートレード損失',
-	'40': 'コピートレード分配',
-	'41': 'コピートレードリベート',
-	'42': 'コピー資金調達率',
-	'47': '体験金出金',
-	'49': 'ステーキング',
-	'50': 'ステーキング解除',
-	'51': 'エアドロップ報酬',
-	'52': 'ステーキングウォレット入金',
-	'53': 'ステーキングウォレット出金',
-}
+const fundingTxJa: Record<string, string> = {
+  "0": "入金",
+  "1": "出金",
+  "2": "振替",
+  "3": "現物取引",
+  "4": "法定通貨購入",
+  "5": "法定通貨売却",
+  "6": "チェックイン報酬",
+  "7": "紹介報酬",
+  "8": "コピートレード報酬",
+  "9": "投票",
+  "10": "手動入金",
+  "11": "ペアリング",
+  "12": "取引報酬",
+  "13": "CTC購入",
+  "14": "CTC売却",
+  "15": "お年玉送信",
+  "16": "お年玉受取",
+  "17": "出金コード出金",
+  "18": "出金コード入金",
+  "19": "無期限契約手数料",
+  "20": "無期限契約利益",
+  "21": "無期限契約損失",
+  "22": "オプション失敗",
+  "23": "オプション手数料",
+  "24": "オプションボーナス",
+  "25": "契約リベート",
+  "26": "資金調達率",
+  "27": "無期限契約強制決済",
+  "28": "キャンペーン手数料",
+  "29": "キャンペーン利益",
+  "30": "キャンペーン損失",
+  "31": "キャンペーンリベート",
+  "32": "同級報酬",
+  "33": "プラットフォーム手数料収入",
+  "34": "秒契約失敗",
+  "35": "秒契約ボーナス",
+  "36": "運用利息",
+  "37": "コピートレード手数料",
+  "38": "コピートレード利益",
+  "39": "コピートレード損失",
+  "40": "コピートレード分配",
+  "41": "コピートレードリベート",
+  "42": "コピー資金調達率",
+  "47": "体験金出金",
+  "49": "ステーキング",
+  "50": "ステーキング解除",
+  "51": "エアドロップ報酬",
+  "52": "ステーキングウォレット入金",
+  "53": "ステーキングウォレット出金",
+};
 
-const fundingTxHi : Record<string, string> = {
-	'0': 'जमा',
-	'1': 'निकासी',
-	'2': 'ट्रांसफर',
-	'3': 'स्पॉट ट्रेड',
-	'4': 'फिएट खरीद',
-	'5': 'फिएट बिक्री',
-	'6': 'चेक-इन इनाम',
-	'7': 'रेफरल इनाम',
-	'8': 'कॉपी ट्रेडिंग इनाम',
-	'9': 'वोट',
-	'10': 'मैन्युअल जमा',
-	'11': 'पेयरिंग',
-	'12': 'ट्रेडिंग इनाम',
-	'13': 'CTC खरीद',
-	'14': 'CTC बिक्री',
-	'15': 'रेड पैकेट भेजा',
-	'16': 'रेड पैकेट प्राप्त',
-	'17': 'निकासी कोड भुगतान',
-	'18': 'निकासी कोड जमा',
-	'19': 'परपेचुअल ट्रेडिंग शुल्क',
-	'20': 'परपेचुअल लाभ',
-	'21': 'परपेचुअल हानि',
-	'22': 'ऑप्शन विफल',
-	'23': 'ऑप्शन शुल्क',
-	'24': 'ऑप्शन बोनस',
-	'25': 'कॉन्ट्रैक्ट रिबेट',
-	'26': 'फंडिंग शुल्क',
-	'27': 'परपेचुअल लिक्विडेशन',
-	'28': 'अभियान शुल्क',
-	'29': 'अभियान लाभ',
-	'30': 'अभियान हानि',
-	'31': 'अभियान रिबेट',
-	'32': 'सहकर्मी इनाम',
-	'33': 'प्लेटफॉर्म शुल्क आय',
-	'34': 'त्वरित कॉन्ट्रैक्ट विफल',
-	'35': 'त्वरित कॉन्ट्रैक्ट बोनस',
-	'36': 'वेल्थ ब्याज',
-	'37': 'कॉपी ट्रेडिंग शुल्क',
-	'38': 'कॉपी ट्रेडिंग लाभ',
-	'39': 'कॉपी ट्रेडिंग हानि',
-	'40': 'कॉपी ट्रेडिंग लाभांश',
-	'41': 'कॉपी ट्रेडिंग रिबेट',
-	'42': 'कॉपी फंडिंग शुल्क',
-	'47': 'बोनस निकासी',
-	'49': 'स्टेकिंग',
-	'50': 'स्टेकिंग अनलॉक रिलीज',
-	'51': 'एयरड्रॉप इनाम',
-	'52': 'स्टेकिंग वॉलेट में ट्रांसफर',
-	'53': 'स्टेकिंग वॉलेट से ट्रांसफर',
-}
+const fundingTxHi: Record<string, string> = {
+  "0": "जमा",
+  "1": "निकासी",
+  "2": "ट्रांसफर",
+  "3": "स्पॉट ट्रेड",
+  "4": "फिएट खरीद",
+  "5": "फिएट बिक्री",
+  "6": "चेक-इन इनाम",
+  "7": "रेफरल इनाम",
+  "8": "कॉपी ट्रेडिंग इनाम",
+  "9": "वोट",
+  "10": "मैन्युअल जमा",
+  "11": "पेयरिंग",
+  "12": "ट्रेडिंग इनाम",
+  "13": "CTC खरीद",
+  "14": "CTC बिक्री",
+  "15": "रेड पैकेट भेजा",
+  "16": "रेड पैकेट प्राप्त",
+  "17": "निकासी कोड भुगतान",
+  "18": "निकासी कोड जमा",
+  "19": "परपेचुअल ट्रेडिंग शुल्क",
+  "20": "परपेचुअल लाभ",
+  "21": "परपेचुअल हानि",
+  "22": "ऑप्शन विफल",
+  "23": "ऑप्शन शुल्क",
+  "24": "ऑप्शन बोनस",
+  "25": "कॉन्ट्रैक्ट रिबेट",
+  "26": "फंडिंग शुल्क",
+  "27": "परपेचुअल लिक्विडेशन",
+  "28": "अभियान शुल्क",
+  "29": "अभियान लाभ",
+  "30": "अभियान हानि",
+  "31": "अभियान रिबेट",
+  "32": "सहकर्मी इनाम",
+  "33": "प्लेटफॉर्म शुल्क आय",
+  "34": "त्वरित कॉन्ट्रैक्ट विफल",
+  "35": "त्वरित कॉन्ट्रैक्ट बोनस",
+  "36": "वेल्थ ब्याज",
+  "37": "कॉपी ट्रेडिंग शुल्क",
+  "38": "कॉपी ट्रेडिंग लाभ",
+  "39": "कॉपी ट्रेडिंग हानि",
+  "40": "कॉपी ट्रेडिंग लाभांश",
+  "41": "कॉपी ट्रेडिंग रिबेट",
+  "42": "कॉपी फंडिंग शुल्क",
+  "47": "बोनस निकासी",
+  "49": "स्टेकिंग",
+  "50": "स्टेकिंग अनलॉक रिलीज",
+  "51": "एयरड्रॉप इनाम",
+  "52": "स्टेकिंग वॉलेट में ट्रांसफर",
+  "53": "स्टेकिंग वॉलेट से ट्रांसफर",
+};
 
-const fundingTxId : Record<string, string> = {
-	'0': 'Deposit',
-	'1': 'Penarikan',
-	'2': 'Transfer',
-	'3': 'Perdagangan spot',
-	'4': 'Beli fiat',
-	'5': 'Jual fiat',
-	'6': 'Hadiah check-in',
-	'7': 'Hadiah referral',
-	'8': 'Hadiah copy trading',
-	'9': 'Voting',
-	'10': 'Deposit manual',
-	'11': 'Pairing',
-	'12': 'Hadiah trading',
-	'13': 'Beli CTC',
-	'14': 'Jual CTC',
-	'15': 'Angpao terkirim',
-	'16': 'Angpao diterima',
-	'17': 'Penarikan kode',
-	'18': 'Deposit kode',
-	'19': 'Biaya perdagangan perpetual',
-	'20': 'Laba perpetual',
-	'21': 'Rugi perpetual',
-	'22': 'Opsi gagal',
-	'23': 'Biaya opsi',
-	'24': 'Bonus opsi',
-	'25': 'Rebate kontrak',
-	'26': 'Biaya funding',
-	'27': 'Likuidasi perpetual',
-	'28': 'Biaya kampanye',
-	'29': 'Laba kampanye',
-	'30': 'Rugi kampanye',
-	'31': 'Rebate kampanye',
-	'32': 'Hadiah sejawat',
-	'33': 'Pendapatan biaya platform',
-	'34': 'Kontrak cepat gagal',
-	'35': 'Bonus kontrak cepat',
-	'36': 'Bunga wealth',
-	'37': 'Biaya copy trading',
-	'38': 'Laba copy trading',
-	'39': 'Rugi copy trading',
-	'40': 'Bagi hasil copy trading',
-	'41': 'Rebate copy trading',
-	'42': 'Biaya funding copy',
-	'47': 'Penarikan bonus',
-	'49': 'Staking',
-	'50': 'Pembukaan staking',
-	'51': 'Hadiah airdrop',
-	'52': 'Transfer ke dompet staking',
-	'53': 'Transfer dari dompet staking',
-}
+const fundingTxId: Record<string, string> = {
+  "0": "Deposit",
+  "1": "Penarikan",
+  "2": "Transfer",
+  "3": "Perdagangan spot",
+  "4": "Beli fiat",
+  "5": "Jual fiat",
+  "6": "Hadiah check-in",
+  "7": "Hadiah referral",
+  "8": "Hadiah copy trading",
+  "9": "Voting",
+  "10": "Deposit manual",
+  "11": "Pairing",
+  "12": "Hadiah trading",
+  "13": "Beli CTC",
+  "14": "Jual CTC",
+  "15": "Angpao terkirim",
+  "16": "Angpao diterima",
+  "17": "Penarikan kode",
+  "18": "Deposit kode",
+  "19": "Biaya perdagangan perpetual",
+  "20": "Laba perpetual",
+  "21": "Rugi perpetual",
+  "22": "Opsi gagal",
+  "23": "Biaya opsi",
+  "24": "Bonus opsi",
+  "25": "Rebate kontrak",
+  "26": "Biaya funding",
+  "27": "Likuidasi perpetual",
+  "28": "Biaya kampanye",
+  "29": "Laba kampanye",
+  "30": "Rugi kampanye",
+  "31": "Rebate kampanye",
+  "32": "Hadiah sejawat",
+  "33": "Pendapatan biaya platform",
+  "34": "Kontrak cepat gagal",
+  "35": "Bonus kontrak cepat",
+  "36": "Bunga wealth",
+  "37": "Biaya copy trading",
+  "38": "Laba copy trading",
+  "39": "Rugi copy trading",
+  "40": "Bagi hasil copy trading",
+  "41": "Rebate copy trading",
+  "42": "Biaya funding copy",
+  "47": "Penarikan bonus",
+  "49": "Staking",
+  "50": "Pembukaan staking",
+  "51": "Hadiah airdrop",
+  "52": "Transfer ke dompet staking",
+  "53": "Transfer dari dompet staking",
+};
 
-const fundingTxEs : Record<string, string> = {
-	'0': 'Depósito',
-	'1': 'Retiro',
-	'2': 'Transferencia',
-	'3': 'Operación al contado',
-	'4': 'Compra fiat',
-	'5': 'Venta fiat',
-	'6': 'Recompensa por inicio de sesión',
-	'7': 'Recompensa por referido',
-	'8': 'Recompensa por copy trading',
-	'9': 'Votación',
-	'10': 'Depósito manual',
-	'11': 'Emparejamiento',
-	'12': 'Recompensa por operación',
-	'13': 'Compra CTC',
-	'14': 'Venta CTC',
-	'15': 'Sobre rojo enviado',
-	'16': 'Sobre rojo recibido',
-	'17': 'Pago por código de retiro',
-	'18': 'Depósito por código de retiro',
-	'19': 'Comisión de perpetuos',
-	'20': 'Beneficio de perpetuos',
-	'21': 'Pérdida de perpetuos',
-	'22': 'Opción fallida',
-	'23': 'Comisión de opción',
-	'24': 'Bono de opción',
-	'25': 'Reembolso de contrato',
-	'26': 'Comisión de financiación',
-	'27': 'Liquidación de perpetuos',
-	'28': 'Comisión de campaña',
-	'29': 'Beneficio de campaña',
-	'30': 'Pérdida de campaña',
-	'31': 'Reembolso de campaña',
-	'32': 'Recompensa de igual nivel',
-	'33': 'Ingreso por comisión de plataforma',
-	'34': 'Contrato rápido fallido',
-	'35': 'Bono de contrato rápido',
-	'36': 'Interés de inversión',
-	'37': 'Comisión de copy trading',
-	'38': 'Beneficio de copy trading',
-	'39': 'Pérdida de copy trading',
-	'40': 'Participación en beneficios de copy trading',
-	'41': 'Reembolso de copy trading',
-	'42': 'Comisión de financiación de copy',
-	'47': 'Retiro de bono',
-	'49': 'Staking',
-	'50': 'Liberación de staking',
-	'51': 'Recompensa de airdrop',
-	'52': 'Transferencia a monedero de staking',
-	'53': 'Transferencia desde monedero de staking',
-}
+const fundingTxEs: Record<string, string> = {
+  "0": "Depósito",
+  "1": "Retiro",
+  "2": "Transferencia",
+  "3": "Operación al contado",
+  "4": "Compra fiat",
+  "5": "Venta fiat",
+  "6": "Recompensa por inicio de sesión",
+  "7": "Recompensa por referido",
+  "8": "Recompensa por copy trading",
+  "9": "Votación",
+  "10": "Depósito manual",
+  "11": "Emparejamiento",
+  "12": "Recompensa por operación",
+  "13": "Compra CTC",
+  "14": "Venta CTC",
+  "15": "Sobre rojo enviado",
+  "16": "Sobre rojo recibido",
+  "17": "Pago por código de retiro",
+  "18": "Depósito por código de retiro",
+  "19": "Comisión de perpetuos",
+  "20": "Beneficio de perpetuos",
+  "21": "Pérdida de perpetuos",
+  "22": "Opción fallida",
+  "23": "Comisión de opción",
+  "24": "Bono de opción",
+  "25": "Reembolso de contrato",
+  "26": "Comisión de financiación",
+  "27": "Liquidación de perpetuos",
+  "28": "Comisión de campaña",
+  "29": "Beneficio de campaña",
+  "30": "Pérdida de campaña",
+  "31": "Reembolso de campaña",
+  "32": "Recompensa de igual nivel",
+  "33": "Ingreso por comisión de plataforma",
+  "34": "Contrato rápido fallido",
+  "35": "Bono de contrato rápido",
+  "36": "Interés de inversión",
+  "37": "Comisión de copy trading",
+  "38": "Beneficio de copy trading",
+  "39": "Pérdida de copy trading",
+  "40": "Participación en beneficios de copy trading",
+  "41": "Reembolso de copy trading",
+  "42": "Comisión de financiación de copy",
+  "47": "Retiro de bono",
+  "49": "Staking",
+  "50": "Liberación de staking",
+  "51": "Recompensa de airdrop",
+  "52": "Transferencia a monedero de staking",
+  "53": "Transferencia desde monedero de staking",
+};
 
 // 俄语
-const fundingTxRu : Record<string, string> = {
-	'0': 'Депозит',
-	'1': 'Вывод',
-	'2': 'Перевод',
-	'3': 'Спот-торговля',
-	'4': 'Покупка фиата',
-	'5': 'Продажа фиата',
-	'6': 'Награда за посещение',
-	'7': 'Реферальная награда',
-	'8': 'Награда за копи-трейдинг',
-	'9': 'Голосование',
-	'10': 'Ручной депозит',
-	'11': 'Сопоставление',
-	'12': 'Торговая награда',
-	'13': 'Покупка CTC',
-	'14': 'Продажа CTC',
-	'15': 'Красный конверт отправлен',
-	'16': 'Красный конверт получен',
-	'17': 'Вывод по коду',
-	'18': 'Депозит по коду',
-	'19': 'Комиссия за бессрочный контракт',
-	'20': 'Прибыль по бессрочному контракту',
-	'21': 'Убыток по бессрочному контракту',
-	'22': 'Опцион не выполнен',
-	'23': 'Комиссия за опцион',
-	'24': 'Бонус за опцион',
-	'25': 'Ребейт по контракту',
-	'26': 'Фандинг-сбор',
-	'27': 'Ликвидация бессрочного контракта',
-	'28': 'Комиссия за кампанию',
-	'29': 'Прибыль по кампании',
-	'30': 'Убыток по кампании',
-	'31': 'Ребейт по кампании',
-	'32': 'Награда равного уровня',
-	'33': 'Доход от платформенных комиссий',
-	'34': 'Моментальный контракт не выполнен',
-	'35': 'Бонус моментального контракта',
-	'36': 'Проценты по вкладам',
-	'37': 'Комиссия за копи-трейдинг',
-	'38': 'Прибыль от копи-трейдинга',
-	'39': 'Убыток от копи-трейдинга',
-	'40': 'Доля прибыли копи-трейдинга',
-	'41': 'Ребейт копи-трейдинга',
-	'42': 'Фандинг-сбор копи-трейдинга',
-	'47': 'Вывод бонусов',
-	'49': 'Стейкинг',
-	'50': 'Разблокировка стейкинга',
-	'51': 'Бонус за аэродроп',
-	'52': 'Перевод в кошелек стейкинга',
-	'53': 'Перевод из кошелька стейкинга',
-}
+const fundingTxRu: Record<string, string> = {
+  "0": "Депозит",
+  "1": "Вывод",
+  "2": "Перевод",
+  "3": "Спот-торговля",
+  "4": "Покупка фиата",
+  "5": "Продажа фиата",
+  "6": "Награда за посещение",
+  "7": "Реферальная награда",
+  "8": "Награда за копи-трейдинг",
+  "9": "Голосование",
+  "10": "Ручной депозит",
+  "11": "Сопоставление",
+  "12": "Торговая награда",
+  "13": "Покупка CTC",
+  "14": "Продажа CTC",
+  "15": "Красный конверт отправлен",
+  "16": "Красный конверт получен",
+  "17": "Вывод по коду",
+  "18": "Депозит по коду",
+  "19": "Комиссия за бессрочный контракт",
+  "20": "Прибыль по бессрочному контракту",
+  "21": "Убыток по бессрочному контракту",
+  "22": "Опцион не выполнен",
+  "23": "Комиссия за опцион",
+  "24": "Бонус за опцион",
+  "25": "Ребейт по контракту",
+  "26": "Фандинг-сбор",
+  "27": "Ликвидация бессрочного контракта",
+  "28": "Комиссия за кампанию",
+  "29": "Прибыль по кампании",
+  "30": "Убыток по кампании",
+  "31": "Ребейт по кампании",
+  "32": "Награда равного уровня",
+  "33": "Доход от платформенных комиссий",
+  "34": "Моментальный контракт не выполнен",
+  "35": "Бонус моментального контракта",
+  "36": "Проценты по вкладам",
+  "37": "Комиссия за копи-трейдинг",
+  "38": "Прибыль от копи-трейдинга",
+  "39": "Убыток от копи-трейдинга",
+  "40": "Доля прибыли копи-трейдинга",
+  "41": "Ребейт копи-трейдинга",
+  "42": "Фандинг-сбор копи-трейдинга",
+  "47": "Вывод бонусов",
+  "49": "Стейкинг",
+  "50": "Разблокировка стейкинга",
+  "51": "Бонус за аэродроп",
+  "52": "Перевод в кошелек стейкинга",
+  "53": "Перевод из кошелька стейкинга",
+};
 
 // 葡萄牙语
-const fundingTxPt : Record<string, string> = {
-	'0': 'Depósito',
-	'1': 'Saque',
-	'2': 'Transferência',
-	'3': 'Negociação à vista',
-	'4': 'Compra de fiat',
-	'5': 'Venda de fiat',
-	'6': 'Recompensa de check-in',
-	'7': 'Recompensa de indicação',
-	'8': 'Recompensa de copy trading',
-	'9': 'Votação',
-	'10': 'Depósito manual',
-	'11': 'Emparelhamento',
-	'12': 'Recompensa de negociação',
-	'13': 'Compra CTC',
-	'14': 'Venda CTC',
-	'15': 'Pacote vermelho enviado',
-	'16': 'Pacote vermelho recebido',
-	'17': 'Saque por código',
-	'18': 'Depósito por código',
-	'19': 'Taxa de contrato perpétuo',
-	'20': 'Lucro de contrato perpétuo',
-	'21': 'Prejuízo de contrato perpétuo',
-	'22': 'Opção falhou',
-	'23': 'Taxa de opção',
-	'24': 'Bônus de opção',
-	'25': 'Reembolso de contrato',
-	'26': 'Taxa de financiamento',
-	'27': 'Liquidação de contrato perpétuo',
-	'28': 'Taxa de campanha',
-	'29': 'Lucro de campanha',
-	'30': 'Prejuízo de campanha',
-	'31': 'Reembolso de campanha',
-	'32': 'Recompensa de mesmo nível',
-	'33': 'Renda de taxa de plataforma',
-	'34': 'Contrato rápido falhou',
-	'35': 'Bônus de contrato rápido',
-	'36': 'Juros de investimento',
-	'37': 'Taxa de copy trading',
-	'38': 'Lucro de copy trading',
-	'39': 'Prejuízo de copy trading',
-	'40': 'Participação nos lucros de copy trading',
-	'41': 'Reembolso de copy trading',
-	'42': 'Taxa de financiamento de copy trading',
-	'47': 'Saque de bônus',
-	'49': 'Staking',
-	'50': 'Liberação de staking',
-	'51': 'Recompensa de airdrop',
-	'52': 'Transferência para carteira de staking',
-	'53': 'Transferência da carteira de staking',
-}
+const fundingTxPt: Record<string, string> = {
+  "0": "Depósito",
+  "1": "Saque",
+  "2": "Transferência",
+  "3": "Negociação à vista",
+  "4": "Compra de fiat",
+  "5": "Venda de fiat",
+  "6": "Recompensa de check-in",
+  "7": "Recompensa de indicação",
+  "8": "Recompensa de copy trading",
+  "9": "Votação",
+  "10": "Depósito manual",
+  "11": "Emparelhamento",
+  "12": "Recompensa de negociação",
+  "13": "Compra CTC",
+  "14": "Venda CTC",
+  "15": "Pacote vermelho enviado",
+  "16": "Pacote vermelho recebido",
+  "17": "Saque por código",
+  "18": "Depósito por código",
+  "19": "Taxa de contrato perpétuo",
+  "20": "Lucro de contrato perpétuo",
+  "21": "Prejuízo de contrato perpétuo",
+  "22": "Opção falhou",
+  "23": "Taxa de opção",
+  "24": "Bônus de opção",
+  "25": "Reembolso de contrato",
+  "26": "Taxa de financiamento",
+  "27": "Liquidação de contrato perpétuo",
+  "28": "Taxa de campanha",
+  "29": "Lucro de campanha",
+  "30": "Prejuízo de campanha",
+  "31": "Reembolso de campanha",
+  "32": "Recompensa de mesmo nível",
+  "33": "Renda de taxa de plataforma",
+  "34": "Contrato rápido falhou",
+  "35": "Bônus de contrato rápido",
+  "36": "Juros de investimento",
+  "37": "Taxa de copy trading",
+  "38": "Lucro de copy trading",
+  "39": "Prejuízo de copy trading",
+  "40": "Participação nos lucros de copy trading",
+  "41": "Reembolso de copy trading",
+  "42": "Taxa de financiamento de copy trading",
+  "47": "Saque de bônus",
+  "49": "Staking",
+  "50": "Liberação de staking",
+  "51": "Recompensa de airdrop",
+  "52": "Transferência para carteira de staking",
+  "53": "Transferência da carteira de staking",
+};
 
 // 德语
-const fundingTxDe : Record<string, string> = {
-	'0': 'Einzahlung',
-	'1': 'Auszahlung',
-	'2': 'Überweisung',
-	'3': 'Spot-Handel',
-	'4': 'Fiat-Kauf',
-	'5': 'Fiat-Verkauf',
-	'6': 'Check-in-Belohnung',
-	'7': 'Empfehlungsbelohnung',
-	'8': 'Copy-Trading-Belohnung',
-	'9': 'Abstimmung',
-	'10': 'Manuelle Einzahlung',
-	'11': 'Paarung',
-	'12': 'Handelsbelohnung',
-	'13': 'CTC-Kauf',
-	'14': 'CTC-Verkauf',
-	'15': 'Rotumschlag gesendet',
-	'16': 'Rotumschlag erhalten',
-	'17': 'Auszahlung per Code',
-	'18': 'Einzahlung per Code',
-	'19': 'Ewiger Vertragsgebühr',
-	'20': 'Ewiger Vertragsgewinn',
-	'21': 'Ewiger Vertragsverlust',
-	'22': 'Option fehlgeschlagen',
-	'23': 'Optionsgebühr',
-	'24': 'Optionsbonus',
-	'25': 'Vertragsrabatt',
-	'26': 'Finanzierungsgebühr',
-	'27': 'Ewige Vertragsliquidation',
-	'28': 'Kampagnengebühr',
-	'29': 'Kampagnengewinn',
-	'30': 'Kampagnenverlust',
-	'31': 'Kampagnenrabatt',
-	'32': 'Gleichstufige Belohnung',
-	'33': 'Plattformgebühreinnahmen',
-	'34': 'Schnellvertrag fehlgeschlagen',
-	'35': 'Schnellvertragsbonus',
-	'36': 'Vermögenszinsen',
-	'37': 'Copy-Trading-Gebühr',
-	'38': 'Copy-Trading-Gewinn',
-	'39': 'Copy-Trading-Verlust',
-	'40': 'Copy-Trading-Gewinnbeteiligung',
-	'41': 'Copy-Trading-Rabatt',
-	'42': 'Copy-Finanzierungsgebühr',
-	'47': 'Bonusauszahlung',
-	'49': 'Staking',
-	'50': 'Staking-Freigabe',
-	'51': 'Airdrop-Belohnung',
-	'52': 'Überweisung zum Staking-Wallet',
-	'53': 'Überweisung vom Staking-Wallet',
-}
+const fundingTxDe: Record<string, string> = {
+  "0": "Einzahlung",
+  "1": "Auszahlung",
+  "2": "Überweisung",
+  "3": "Spot-Handel",
+  "4": "Fiat-Kauf",
+  "5": "Fiat-Verkauf",
+  "6": "Check-in-Belohnung",
+  "7": "Empfehlungsbelohnung",
+  "8": "Copy-Trading-Belohnung",
+  "9": "Abstimmung",
+  "10": "Manuelle Einzahlung",
+  "11": "Paarung",
+  "12": "Handelsbelohnung",
+  "13": "CTC-Kauf",
+  "14": "CTC-Verkauf",
+  "15": "Rotumschlag gesendet",
+  "16": "Rotumschlag erhalten",
+  "17": "Auszahlung per Code",
+  "18": "Einzahlung per Code",
+  "19": "Ewiger Vertragsgebühr",
+  "20": "Ewiger Vertragsgewinn",
+  "21": "Ewiger Vertragsverlust",
+  "22": "Option fehlgeschlagen",
+  "23": "Optionsgebühr",
+  "24": "Optionsbonus",
+  "25": "Vertragsrabatt",
+  "26": "Finanzierungsgebühr",
+  "27": "Ewige Vertragsliquidation",
+  "28": "Kampagnengebühr",
+  "29": "Kampagnengewinn",
+  "30": "Kampagnenverlust",
+  "31": "Kampagnenrabatt",
+  "32": "Gleichstufige Belohnung",
+  "33": "Plattformgebühreinnahmen",
+  "34": "Schnellvertrag fehlgeschlagen",
+  "35": "Schnellvertragsbonus",
+  "36": "Vermögenszinsen",
+  "37": "Copy-Trading-Gebühr",
+  "38": "Copy-Trading-Gewinn",
+  "39": "Copy-Trading-Verlust",
+  "40": "Copy-Trading-Gewinnbeteiligung",
+  "41": "Copy-Trading-Rabatt",
+  "42": "Copy-Finanzierungsgebühr",
+  "47": "Bonusauszahlung",
+  "49": "Staking",
+  "50": "Staking-Freigabe",
+  "51": "Airdrop-Belohnung",
+  "52": "Überweisung zum Staking-Wallet",
+  "53": "Überweisung vom Staking-Wallet",
+};
 
 // 法语
-const fundingTxFr : Record<string, string> = {
-	'0': 'Dépôt',
-	'1': 'Retrait',
-	'2': 'Transfert',
-	'3': 'Trading au comptant',
-	'4': 'Achat de fiat',
-	'5': 'Vente de fiat',
-	'6': 'Récompense de connexion',
-	'7': 'Récompense de parrainage',
-	'8': 'Récompense de copy trading',
-	'9': 'Vote',
-	'10': 'Dépôt manuel',
-	'11': 'Appariement',
-	'12': 'Récompense de trading',
-	'13': 'Achat CTC',
-	'14': 'Vente CTC',
-	'15': 'Paquet rouge envoyé',
-	'16': 'Paquet rouge reçu',
-	'17': 'Retrait par code',
-	'18': 'Dépôt par code',
-	'19': 'Frais de contrat perpétuel',
-	'20': 'Profit de contrat perpétuel',
-	'21': 'Perte de contrat perpétuel',
-	'22': 'Option échouée',
-	'23': 'Frais d\'option',
-	'24': 'Bonus d\'option',
-	'25': 'Remboursement de contrat',
-	'26': 'Frais de financement',
-	'27': 'Liquidation de contrat perpétuel',
-	'28': 'Frais de campagne',
-	'29': 'Profit de campagne',
-	'30': 'Perte de campagne',
-	'31': 'Remboursement de campagne',
-	'32': 'Récompense de même niveau',
-	'33': 'Revenu de frais de plateforme',
-	'34': 'Contrat rapide échoué',
-	'35': 'Bonus de contrat rapide',
-	'36': 'Intérêts de placement',
-	'37': 'Frais de copy trading',
-	'38': 'Profit de copy trading',
-	'39': 'Perte de copy trading',
-	'40': 'Partage des bénéfices de copy trading',
-	'41': 'Remboursement de copy trading',
-	'42': 'Frais de financement de copy trading',
-	'47': 'Retrait de bonus',
-	'49': 'Staking',
-	'50': 'Libération de staking',
-	'51': 'Récompense d\'airdrop',
-	'52': 'Transfert vers portefeuille de staking',
-	'53': 'Transfert depuis portefeuille de staking',
-}
+const fundingTxFr: Record<string, string> = {
+  "0": "Dépôt",
+  "1": "Retrait",
+  "2": "Transfert",
+  "3": "Trading au comptant",
+  "4": "Achat de fiat",
+  "5": "Vente de fiat",
+  "6": "Récompense de connexion",
+  "7": "Récompense de parrainage",
+  "8": "Récompense de copy trading",
+  "9": "Vote",
+  "10": "Dépôt manuel",
+  "11": "Appariement",
+  "12": "Récompense de trading",
+  "13": "Achat CTC",
+  "14": "Vente CTC",
+  "15": "Paquet rouge envoyé",
+  "16": "Paquet rouge reçu",
+  "17": "Retrait par code",
+  "18": "Dépôt par code",
+  "19": "Frais de contrat perpétuel",
+  "20": "Profit de contrat perpétuel",
+  "21": "Perte de contrat perpétuel",
+  "22": "Option échouée",
+  "23": "Frais d'option",
+  "24": "Bonus d'option",
+  "25": "Remboursement de contrat",
+  "26": "Frais de financement",
+  "27": "Liquidation de contrat perpétuel",
+  "28": "Frais de campagne",
+  "29": "Profit de campagne",
+  "30": "Perte de campagne",
+  "31": "Remboursement de campagne",
+  "32": "Récompense de même niveau",
+  "33": "Revenu de frais de plateforme",
+  "34": "Contrat rapide échoué",
+  "35": "Bonus de contrat rapide",
+  "36": "Intérêts de placement",
+  "37": "Frais de copy trading",
+  "38": "Profit de copy trading",
+  "39": "Perte de copy trading",
+  "40": "Partage des bénéfices de copy trading",
+  "41": "Remboursement de copy trading",
+  "42": "Frais de financement de copy trading",
+  "47": "Retrait de bonus",
+  "49": "Staking",
+  "50": "Libération de staking",
+  "51": "Récompense d'airdrop",
+  "52": "Transfert vers portefeuille de staking",
+  "53": "Transfert depuis portefeuille de staking",
+};
 
 // 土耳其语
-const fundingTxTr : Record<string, string> = {
-	'0': 'Yatırma',
-	'1': 'Çekme',
-	'2': 'Transfer',
-	'3': 'Spot işlem',
-	'4': 'Fiat alımı',
-	'5': 'Fiat satımı',
-	'6': 'Giriş ödülü',
-	'7': 'Referans ödülü',
-	'8': 'Kopya işlem ödülü',
-	'9': 'Oylama',
-	'10': 'Manuel yatırma',
-	'11': 'Eşleştirme',
-	'12': 'İşlem ödülü',
-	'13': 'CTC alımı',
-	'14': 'CTC satımı',
-	'15': 'Kırmızı zarf gönderildi',
-	'16': 'Kırmızı zarf alındı',
-	'17': 'Kod ile çekme',
-	'18': 'Kod ile yatırma',
-	'19': 'Sürekli sözleşme ücreti',
-	'20': 'Sürekli sözleşme karı',
-	'21': 'Sürekli sözleşme zararı',
-	'22': 'Seçenek başarısız',
-	'23': 'Seçenek ücreti',
-	'24': 'Seçenek bonusu',
-	'25': 'Sözleşme indirimi',
-	'26': 'Finansman ücreti',
-	'27': 'Sürekli sözleşme likidasyonu',
-	'28': 'Kampanya ücreti',
-	'29': 'Kampanya karı',
-	'30': 'Kampanya zararı',
-	'31': 'Kampanya indirimi',
-	'32': 'Eş düzey ödülü',
-	'33': 'Platform ücreti geliri',
-	'34': 'Hızlı sözleşme başarısız',
-	'35': 'Hızlı sözleşme bonusu',
-	'36': 'Servet faizi',
-	'37': 'Kopya işlem ücreti',
-	'38': 'Kopya işlem karı',
-	'39': 'Kopya işlem zararı',
-	'40': 'Kopya işlem kar payı',
-	'41': 'Kopya işlem indirimi',
-	'42': 'Kopya finansman ücreti',
-	'47': 'Bonus çekme',
-	'49': 'Staking',
-	'50': 'Staking serbest bırakma',
-	'51': 'Hava düşü ödülü',
-	'52': 'Staking cüzdanına transfer',
-	'53': 'Staking cüzdanından transfer',
-}
+const fundingTxTr: Record<string, string> = {
+  "0": "Yatırma",
+  "1": "Çekme",
+  "2": "Transfer",
+  "3": "Spot işlem",
+  "4": "Fiat alımı",
+  "5": "Fiat satımı",
+  "6": "Giriş ödülü",
+  "7": "Referans ödülü",
+  "8": "Kopya işlem ödülü",
+  "9": "Oylama",
+  "10": "Manuel yatırma",
+  "11": "Eşleştirme",
+  "12": "İşlem ödülü",
+  "13": "CTC alımı",
+  "14": "CTC satımı",
+  "15": "Kırmızı zarf gönderildi",
+  "16": "Kırmızı zarf alındı",
+  "17": "Kod ile çekme",
+  "18": "Kod ile yatırma",
+  "19": "Sürekli sözleşme ücreti",
+  "20": "Sürekli sözleşme karı",
+  "21": "Sürekli sözleşme zararı",
+  "22": "Seçenek başarısız",
+  "23": "Seçenek ücreti",
+  "24": "Seçenek bonusu",
+  "25": "Sözleşme indirimi",
+  "26": "Finansman ücreti",
+  "27": "Sürekli sözleşme likidasyonu",
+  "28": "Kampanya ücreti",
+  "29": "Kampanya karı",
+  "30": "Kampanya zararı",
+  "31": "Kampanya indirimi",
+  "32": "Eş düzey ödülü",
+  "33": "Platform ücreti geliri",
+  "34": "Hızlı sözleşme başarısız",
+  "35": "Hızlı sözleşme bonusu",
+  "36": "Servet faizi",
+  "37": "Kopya işlem ücreti",
+  "38": "Kopya işlem karı",
+  "39": "Kopya işlem zararı",
+  "40": "Kopya işlem kar payı",
+  "41": "Kopya işlem indirimi",
+  "42": "Kopya finansman ücreti",
+  "47": "Bonus çekme",
+  "49": "Staking",
+  "50": "Staking serbest bırakma",
+  "51": "Hava düşü ödülü",
+  "52": "Staking cüzdanına transfer",
+  "53": "Staking cüzdanından transfer",
+};
 
 // 越南语
-const fundingTxVi : Record<string, string> = {
-	'0': 'Nạp tiền',
-	'1': 'Rút tiền',
-	'2': 'Chuyển khoản',
-	'3': 'Giao dịch spot',
-	'4': 'Mua fiat',
-	'5': 'Bán fiat',
-	'6': 'Thưởng đăng nhập',
-	'7': 'Thưởng giới thiệu',
-	'8': 'Thưởng copy trading',
-	'9': 'Bình chọn',
-	'10': 'Nạp tiền thủ công',
-	'11': 'Ghép cặp',
-	'12': 'Thưởng giao dịch',
-	'13': 'Mua CTC',
-	'14': 'Bán CTC',
-	'15': 'Thư đỏ đã gửi',
-	'16': 'Thư đỏ đã nhận',
-	'17': 'Rút tiền bằng mã',
-	'18': 'Nạp tiền bằng mã',
-	'19': 'Phí hợp đồng vĩnh viễn',
-	'20': 'Lợi nhuận hợp đồng vĩnh viễn',
-	'21': 'Thua lỗ hợp đồng vĩnh viễn',
-	'22': 'Lựa chọn thất bại',
-	'23': 'Phí lựa chọn',
-	'24': 'Thưởng lựa chọn',
-	'25': 'Hoàn phí hợp đồng',
-	'26': 'Phí tài trợ',
-	'27': 'Thanh lý hợp đồng vĩnh viễn',
-	'28': 'Phí chiến dịch',
-	'29': 'Lợi nhuận chiến dịch',
-	'30': 'Thua lỗ chiến dịch',
-	'31': 'Hoàn phí chiến dịch',
-	'32': 'Thưởng cấp bằng',
-	'33': 'Thu nhập phí nền tảng',
-	'34': 'Hợp đồng nhanh thất bại',
-	'35': 'Thưởng hợp đồng nhanh',
-	'36': 'Lãi suất tài chính',
-	'37': 'Phí copy trading',
-	'38': 'Lợi nhuận copy trading',
-	'39': 'Thua lỗ copy trading',
-	'40': 'Chia sẻ lợi nhuận copy trading',
-	'41': 'Hoàn phí copy trading',
-	'42': 'Phí tài trợ copy trading',
-	'47': 'Rút thưởng',
-	'49': 'Staking',
-	'50': 'Giải phóng staking',
-	'51': 'Thưởng airdrop',
-	'52': 'Chuyển đến ví staking',
-	'53': 'Chuyển từ ví staking',
-}
+const fundingTxVi: Record<string, string> = {
+  "0": "Nạp tiền",
+  "1": "Rút tiền",
+  "2": "Chuyển khoản",
+  "3": "Giao dịch spot",
+  "4": "Mua fiat",
+  "5": "Bán fiat",
+  "6": "Thưởng đăng nhập",
+  "7": "Thưởng giới thiệu",
+  "8": "Thưởng copy trading",
+  "9": "Bình chọn",
+  "10": "Nạp tiền thủ công",
+  "11": "Ghép cặp",
+  "12": "Thưởng giao dịch",
+  "13": "Mua CTC",
+  "14": "Bán CTC",
+  "15": "Thư đỏ đã gửi",
+  "16": "Thư đỏ đã nhận",
+  "17": "Rút tiền bằng mã",
+  "18": "Nạp tiền bằng mã",
+  "19": "Phí hợp đồng vĩnh viễn",
+  "20": "Lợi nhuận hợp đồng vĩnh viễn",
+  "21": "Thua lỗ hợp đồng vĩnh viễn",
+  "22": "Lựa chọn thất bại",
+  "23": "Phí lựa chọn",
+  "24": "Thưởng lựa chọn",
+  "25": "Hoàn phí hợp đồng",
+  "26": "Phí tài trợ",
+  "27": "Thanh lý hợp đồng vĩnh viễn",
+  "28": "Phí chiến dịch",
+  "29": "Lợi nhuận chiến dịch",
+  "30": "Thua lỗ chiến dịch",
+  "31": "Hoàn phí chiến dịch",
+  "32": "Thưởng cấp bằng",
+  "33": "Thu nhập phí nền tảng",
+  "34": "Hợp đồng nhanh thất bại",
+  "35": "Thưởng hợp đồng nhanh",
+  "36": "Lãi suất tài chính",
+  "37": "Phí copy trading",
+  "38": "Lợi nhuận copy trading",
+  "39": "Thua lỗ copy trading",
+  "40": "Chia sẻ lợi nhuận copy trading",
+  "41": "Hoàn phí copy trading",
+  "42": "Phí tài trợ copy trading",
+  "47": "Rút thưởng",
+  "49": "Staking",
+  "50": "Giải phóng staking",
+  "51": "Thưởng airdrop",
+  "52": "Chuyển đến ví staking",
+  "53": "Chuyển từ ví staking",
+};
 
-function buildZhCN() : FuturesPageMessages {
-	return {
-		perpetual: '永续合约',
-		perpetualTag: '永续',
-		pairSearchPlaceholder: '搜索',
-		pairSearchTag:{
-			oneType: '加密货币',
-			twoType: '大宗商品',
-			threeType: '贵金属',
-			fourType: '外汇',
-		},
-		pairEmpty: '无匹配结果',
-		stats: {
-			change24h: '24h涨跌',
-			markPrice: '标记价格',
-			high24h: '24h最高价',
-			low24h: '24h最低价',
-			volume24h: '24h成交量',
-			fundingCountdown: '资金费率 / 倒计时',
-		},
-		mobileTabs: { chart: '行情', trade: '交易' },
-		chartSub: { chart: '图表', coinInfo: '币种资料', fundingHistory: '历史资金费率' },
-		tf: {
-			m1: '1分',
-			m5: '5分',
-			m15: '15分',
-			m30: '30分',
-			h1: '1小时',
-			h4: '4小时',
-			d1: '1日',
-			w1: '1周',
-			mo1: '1月',
-			mo3: '3月',
-		},
-		chartTools: { fullscreen: '全屏', alert: '提醒' },
-		draw: {
-			cursor: '光标',
-			trend: '趋势线',
-			hline: '水平线',
-			ray: '射线',
-			channel: '通道线',
-			fib: '斐波那契回撤',
-			text: '文字标注',
-			clearAll: '删除所有标注',
-			zoomOut: '缩小',
-		},
-		ohlcv: {
-			open: '开',
-			high: '高',
-			low: '低',
-			close: '收',
-			volume: '成交量',
-			changePct: '涨幅',
-			amplitude: '振幅',
-		},
-		coinInfo: {
-			marketCap: '市值',
-			circulating: '流通量',
-			issuePrice: '发行价',
-			ath: '历史最高',
-			athDate: 'ATH 日期',
-			whitepaper: '白皮书',
-			empty: '暂无币种资料',
-			reload: '重新加载',
-		},
-		fundingPanel: {
-			rate: '资金费率',
-			period: '结算周期',
-			nextCountdown: '下次结算倒计时',
-			noChart: '暂无图表数据',
-			settleTime: '结算时间',
-			rateCol: '资金费率',
-			empty7d: '暂无近7天数据',
-		},
-		book: {
-			orderBook: '订单簿',
-			trades: '最新成交',
-			priceQuote: '价格(USDT)',
-			amountBase: '数量({base})',
-			totalBase: '总量({base})',
-			time: '时间',
-			buy: '买',
-			sell: '卖',
-			buyRatio: '买 {n}%',
-			sellRatio: '{n}% 卖',
-			noTrades: '暂无成交数据',
-		},
-		margin: { cross: '全仓', split: '分仓', experience: '体验金' },
-		amountUnit: { lots: '张', usdt: 'USDT' },
-		leverage: { adjustTitle: '调整杠杆' },
-		order: {
-			limit: '限价',
-			market: '市价',
-			conditional: '条件委托',
-			condMarket: '市价委托',
-			condLimit: '限价委托',
-			available: '可用',
-			maxOpen: '最大可开',
-			triggerPriceLabel: '触发价 ({q})',
-			priceLabel: '价格 ({q})',
-			latestBtn: '最新',
-			marketExe: '市价成交',
-			condMarketExe: '触发后市价成交',
-			qtyLabel: '数量 ({u})',
-			transferTitle: '划转',
-			openLong: '开多',
-			openShort: '开空',
-			contractInfoTitle: '合约信息',
-			indexSource: '指数来源',
-			marginCoin: '保证金币种',
-			maxLeverage: '最大杠杆',
-			maintMargin: '维持保证金率',
-			openFee: '开仓手续费',
-			closeFee: '平仓手续费',
-			contractValue: '合约面值',
-			minOrder: '最小下单量',
-			maxOrder: '最大下单量',
-		},
-		placeholders: { searchPair: '搜索', triggerPrice: '请输入触发价', price: '请输入价格', amount: '请输入数量' },
-		bottom: {
-			positions: '仓位',
-			openOrders: '当前委托',
-			historyOrders: '历史委托',
-			historyPositions: '历史仓位',
-			tradeDetails: '成交明细',
-			fundingFlow: '资金流水',
-			assets: '资产',
-			closeAllPositions: '一键平仓',
-			cancelAllOrders: '全部撤单',
-			loginPromptOr: '或',
-			registerNow: '立即注册',
-			startTrading: '开始交易',
-		},
-		table: {
-			contract: '合约',
-			dirLeverage: '方向/杠杆',
-			openPrice: '开仓价',
-			markPrice: '标记价',
-			positionSize: '持仓量',
-			margin: '保证金',
-			marginRate: '保证金率',
-			unrealizedPnl: '浮动盈亏',
-			roe: '收益率',
-			liqPrice: '强平价',
-			openTime: '开仓时间',
-			action: '操作',
-			type: '类型',
-			orderPrice: '委托价',
-			entrustPriceHist: '委托价格',
-			triggerPrice: '触发价',
-			orderAmt: '委托量',
-			filled: '已成交',
-			tpPrice: '止盈价',
-			slPrice: '止损价',
-			time: '时间',
-			orderTime: '委托时间',
-			fillTime: '成交时间',
-			profitUsdt: '收益(USDT)',
-			tradedVol: '已成交量',
-			closeAvg: '平仓均价',
-			profitRate: '收益率',
-			closeTime: '平仓时间',
-			directionOpenClose: '方向/开平',
-			dealPrice: '成交价',
-			fee: '手续费',
-			fundType: '类型',
-			amount: '数量',
-			coin: '币种',
-			settlementTime: '结算时间',
-			fundingRate: '资金费率',
-			totalBal: '合约账户总余额',
-			availMargin: '可用保证金',
-			usedMargin: '已用保证金',
-			unrealized: '未实现盈亏',
-			spotWalletBal: '可提现账户余额',
-			fundTransfer: '资金划转',
-			avgOpenPrice: '开仓均价',
-			feeHint: '手续费(USDT)',
-			estimatedPnlRow: '预计盈亏',
-			triggerUsdt: '触发价(USDT)',
-			orderPriceUsdt: '委托价(USDT)',
-			openAvgUsdt: '开仓均价(USDT)',
-			closeAvgUsdt: '平仓均价(USDT)',
-			tpUsdt: '止盈价(USDT)',
-			slUsdt: '止损价(USDT)',
-			marginUsdtBracket: '保证金(USDT)',
-			notionalUsdt: '仓位价值(USDT)',
-			estLiqPx: '预估强平价',
-			profitBracketUsdt: '收益(USDT)',
-			entrustVolCoin: '委托量({base})',
-			filledVolCoin: '已成交量({base})',
-			closeAvail: '可平:',
-			markPriceBtn: '标记价',
-		},
-		empty: {
-			noPositions: '暂无持仓',
-			noOrders: '暂无委托',
-			noHistPositions: '暂无历史仓位',
-			noHistOrders: '暂无历史委托',
-			noTradeRecords: '暂无成交记录',
-			noFunding: '暂无资金流水',
-		},
-		modal: {
-			confirmDefaultTitle: '请确认',
-			positionDetailTitle: '仓位详情',
-			orderDetailTitle: '委托详情',
-			histPositionDetailTitle: '历史仓位详情',
-			histOrderDetailTitle: '历史委托详情',
-			closePositionTitlePrefix: '平仓',
-			modifyTpSl: '修改止盈止损',
-			setTpSl: '设置止盈止损',
-			posQtyLabel: '持仓量:',
-			currentTpSlSection: '当前止盈止损委托',
-			modifyToSection: '修改为',
-			setPricesSection: '设置价格',
-			tpTriggerLabel: '止盈触发价 ',
-			tpHintOptionalClear: '(不填则清除止盈)',
-			slTriggerLabel: '止损触发价 ',
-			slHintOptionalClear: '(不填则清除止损)',
-			placeholderTpTrigger: '输入止盈触发价',
-			placeholderSlTrigger: '输入止损触发价',
-			confirmCloseBtn: '确认平仓',
-			ok: '确定',
-			closeTypeLiquidation: '爆仓',
-			tpBadge: '止盈',
-			slBadge: '止损',
-			tpPriceWord: '止盈价 ',
-			slPriceWord: '止损价 ',
-			volLabel: '数量:',
-			marginSplitMode: '全仓/分仓',
-			directionLabel: '方向',
-			entrustTypeLabel: '委托类型',
-			leverageLabel: '杠杆',
-		},
-		actions: { tpSl: '止盈止损', reverse: '反手', close: '平仓', marketCloseAll: '市价全平', cancelOrder: '撤单' },
-		positionRow: { hintCross: '全仓', hintExperience: '体验金' },
-		errors: {
-			enterTriggerPrice: '请输入触发价',
-			enterPrice: '请输入价格',
-			priceNotReadyConvert: '价格未就绪,无法换算数量',
-			invalidQtyCheckMin: '数量无效,请检查精度与最小下单量',
-			priceNotReadyRetry: '价格未就绪,请稍后重试',
-			enterQty: '请输入数量',
-			qtyExceedAvail: '数量超出可平量',
-			closeFailed: '平仓失败',
-			modifyTpSlFailed: '修改失败,请稍后重试',
-			txFallback: '类型{n}',
-		},
-		confirm: {
-			reverseTitle: '一键反手',
-			reverseBody: '确认对 {pair} {side} 仓位执行一键反手吗?',
-			cancelAllTitle: '全部撤单',
-			cancelAllBody: '确认撤销当前 {n} 个委托吗?',
-			closeAllTitle: '一键平仓',
-			closeAllBody: '确认对当前 {n} 个持仓执行一键平仓吗?',
-			sideLongWord: '做多',
-			sideShortWord: '做空',
-		},
-		directions: {
-			long: '做多',
-			short: '做空',
-			openLong: '开多',
-			openShort: '开空',
-			closeShort: '平空',
-			closeLong: '平多',
-			openTag: '开',
-			closeTag: '平',
-		},
-		orderTypes: { limit: '限价', plan: '计划委托', takeProfit: '止盈', stopLoss: '止损', marketShort: '市价' },
-		orderStatus: { filled: '已成交', open: '委托中', cancelled: '已撤销', failed: '失败' },
-		closeTypes: {
-			market: '市价平仓',
-			oneClick: '一键平仓',
-			reverseOpen: '反向开仓',
-			tpSl: '止盈止损',
-			liquidation: '爆仓',
-			admin: '管理员平仓',
-		},
-		fundingTx: fundingTxZh,
-	}
+function buildZhCN(): FuturesPageMessages {
+  return {
+    perpetual: "永续合约",
+    perpetualTag: "永续",
+    pairSearchPlaceholder: "搜索",
+    pairSearchTag: {
+      oneType: "加密代币",
+      twoType: "股票",
+      threeType: "大宗贵金属",
+      fourType: "外汇",
+    },
+    pairEmpty: "无匹配结果",
+    stats: {
+      change24h: "24h涨跌",
+      markPrice: "标记价格",
+      high24h: "24h最高价",
+      low24h: "24h最低价",
+      volume24h: "24h成交量",
+      fundingCountdown: "资金费率 / 倒计时",
+    },
+    mobileTabs: { chart: "行情", trade: "交易" },
+    chartSub: {
+      chart: "图表",
+      coinInfo: "币种资料",
+      fundingHistory: "历史资金费率",
+    },
+    tf: {
+      m1: "1分",
+      m5: "5分",
+      m15: "15分",
+      m30: "30分",
+      h1: "1小时",
+      h4: "4小时",
+      d1: "1日",
+      w1: "1周",
+      mo1: "1月",
+      mo3: "3月",
+    },
+    chartTools: { fullscreen: "全屏", alert: "提醒" },
+    draw: {
+      cursor: "光标",
+      trend: "趋势线",
+      hline: "水平线",
+      ray: "射线",
+      channel: "通道线",
+      fib: "斐波那契回撤",
+      text: "文字标注",
+      clearAll: "删除所有标注",
+      zoomOut: "缩小",
+    },
+    ohlcv: {
+      open: "开",
+      high: "高",
+      low: "低",
+      close: "收",
+      volume: "成交量",
+      changePct: "涨幅",
+      amplitude: "振幅",
+    },
+    coinInfo: {
+      marketCap: "市值",
+      circulating: "流通量",
+      issuePrice: "发行价",
+      ath: "历史最高",
+      athDate: "ATH 日期",
+      whitepaper: "白皮书",
+      empty: "暂无币种资料",
+      reload: "重新加载",
+    },
+    fundingPanel: {
+      rate: "资金费率",
+      period: "结算周期",
+      nextCountdown: "下次结算倒计时",
+      noChart: "暂无图表数据",
+      settleTime: "结算时间",
+      rateCol: "资金费率",
+      empty7d: "暂无近7天数据",
+    },
+    book: {
+      orderBook: "订单簿",
+      trades: "最新成交",
+      priceQuote: "价格(USDT)",
+      amountBase: "数量({base})",
+      totalBase: "总量({base})",
+      time: "时间",
+      buy: "买",
+      sell: "卖",
+      buyRatio: "买 {n}%",
+      sellRatio: "{n}% 卖",
+      noTrades: "暂无成交数据",
+    },
+    margin: { cross: "全仓", split: "分仓", experience: "体验金" },
+    amountUnit: { lots: "张", usdt: "USDT" },
+    leverage: { adjustTitle: "调整杠杆" },
+    order: {
+      limit: "限价",
+      market: "市价",
+      conditional: "条件委托",
+      condMarket: "市价委托",
+      condLimit: "限价委托",
+      available: "可用",
+      maxOpen: "最大可开",
+      triggerPriceLabel: "触发价 ({q})",
+      priceLabel: "价格 ({q})",
+      latestBtn: "最新",
+      marketExe: "市价成交",
+      condMarketExe: "触发后市价成交",
+      qtyLabel: "数量 ({u})",
+      transferTitle: "划转",
+      openLong: "开多",
+      openShort: "开空",
+      contractInfoTitle: "合约信息",
+      indexSource: "指数来源",
+      marginCoin: "保证金币种",
+      maxLeverage: "最大杠杆",
+      maintMargin: "维持保证金率",
+      openFee: "开仓手续费",
+      closeFee: "平仓手续费",
+      contractValue: "合约面值",
+      minOrder: "最小下单量",
+      maxOrder: "最大下单量",
+    },
+    placeholders: {
+      searchPair: "搜索",
+      triggerPrice: "请输入触发价",
+      price: "请输入价格",
+      amount: "请输入数量",
+    },
+    bottom: {
+      positions: "仓位",
+      openOrders: "当前委托",
+      historyOrders: "历史委托",
+      historyPositions: "历史仓位",
+      tradeDetails: "成交明细",
+      fundingFlow: "资金流水",
+      assets: "资产",
+      closeAllPositions: "一键平仓",
+      cancelAllOrders: "全部撤单",
+      loginPromptOr: "或",
+      registerNow: "立即注册",
+      startTrading: "开始交易",
+    },
+    table: {
+      contract: "合约",
+      dirLeverage: "方向/杠杆",
+      openPrice: "开仓价",
+      markPrice: "标记价",
+      positionSize: "持仓量",
+      margin: "保证金",
+      marginRate: "保证金率",
+      unrealizedPnl: "浮动盈亏",
+      roe: "收益率",
+      liqPrice: "强平价",
+      openTime: "开仓时间",
+      action: "操作",
+      type: "类型",
+      orderPrice: "委托价",
+      entrustPriceHist: "委托价格",
+      triggerPrice: "触发价",
+      orderAmt: "委托量",
+      filled: "已成交",
+      tpPrice: "止盈价",
+      slPrice: "止损价",
+      time: "时间",
+      orderTime: "委托时间",
+      fillTime: "成交时间",
+      profitUsdt: "收益(USDT)",
+      tradedVol: "已成交量",
+      closeAvg: "平仓均价",
+      profitRate: "收益率",
+      closeTime: "平仓时间",
+      directionOpenClose: "方向/开平",
+      dealPrice: "成交价",
+      fee: "手续费",
+      fundType: "类型",
+      amount: "数量",
+      coin: "币种",
+      settlementTime: "结算时间",
+      fundingRate: "资金费率",
+      totalBal: "合约账户总余额",
+      availMargin: "可用保证金",
+      usedMargin: "已用保证金",
+      unrealized: "未实现盈亏",
+      spotWalletBal: "可提现账户余额",
+      fundTransfer: "资金划转",
+      avgOpenPrice: "开仓均价",
+      feeHint: "手续费(USDT)",
+      estimatedPnlRow: "预计盈亏",
+      triggerUsdt: "触发价(USDT)",
+      orderPriceUsdt: "委托价(USDT)",
+      openAvgUsdt: "开仓均价(USDT)",
+      closeAvgUsdt: "平仓均价(USDT)",
+      tpUsdt: "止盈价(USDT)",
+      slUsdt: "止损价(USDT)",
+      marginUsdtBracket: "保证金(USDT)",
+      notionalUsdt: "仓位价值(USDT)",
+      estLiqPx: "预估强平价",
+      profitBracketUsdt: "收益(USDT)",
+      entrustVolCoin: "委托量({base})",
+      filledVolCoin: "已成交量({base})",
+      closeAvail: "可平:",
+      markPriceBtn: "标记价",
+    },
+    empty: {
+      noPositions: "暂无持仓",
+      noOrders: "暂无委托",
+      noHistPositions: "暂无历史仓位",
+      noHistOrders: "暂无历史委托",
+      noTradeRecords: "暂无成交记录",
+      noFunding: "暂无资金流水",
+    },
+    modal: {
+      confirmDefaultTitle: "请确认",
+      positionDetailTitle: "仓位详情",
+      orderDetailTitle: "委托详情",
+      histPositionDetailTitle: "历史仓位详情",
+      histOrderDetailTitle: "历史委托详情",
+      closePositionTitlePrefix: "平仓",
+      modifyTpSl: "修改止盈止损",
+      setTpSl: "设置止盈止损",
+      posQtyLabel: "持仓量:",
+      currentTpSlSection: "当前止盈止损委托",
+      modifyToSection: "修改为",
+      setPricesSection: "设置价格",
+      tpTriggerLabel: "止盈触发价 ",
+      tpHintOptionalClear: "(不填则清除止盈)",
+      slTriggerLabel: "止损触发价 ",
+      slHintOptionalClear: "(不填则清除止损)",
+      placeholderTpTrigger: "输入止盈触发价",
+      placeholderSlTrigger: "输入止损触发价",
+      confirmCloseBtn: "确认平仓",
+      ok: "确定",
+      closeTypeLiquidation: "爆仓",
+      tpBadge: "止盈",
+      slBadge: "止损",
+      tpPriceWord: "止盈价 ",
+      slPriceWord: "止损价 ",
+      volLabel: "数量:",
+      marginSplitMode: "全仓/分仓",
+      directionLabel: "方向",
+      entrustTypeLabel: "委托类型",
+      leverageLabel: "杠杆",
+    },
+    actions: {
+      tpSl: "止盈止损",
+      reverse: "反手",
+      close: "平仓",
+      marketCloseAll: "市价全平",
+      cancelOrder: "撤单",
+    },
+    positionRow: { hintCross: "全仓", hintExperience: "体验金" },
+    errors: {
+      enterTriggerPrice: "请输入触发价",
+      enterPrice: "请输入价格",
+      priceNotReadyConvert: "价格未就绪,无法换算数量",
+      invalidQtyCheckMin: "数量无效,请检查精度与最小下单量",
+      priceNotReadyRetry: "价格未就绪,请稍后重试",
+      enterQty: "请输入数量",
+      qtyExceedAvail: "数量超出可平量",
+      closeFailed: "平仓失败",
+      modifyTpSlFailed: "修改失败,请稍后重试",
+      txFallback: "类型{n}",
+    },
+    confirm: {
+      reverseTitle: "一键反手",
+      reverseBody: "确认对 {pair} {side} 仓位执行一键反手吗?",
+      cancelAllTitle: "全部撤单",
+      cancelAllBody: "确认撤销当前 {n} 个委托吗?",
+      closeAllTitle: "一键平仓",
+      closeAllBody: "确认对当前 {n} 个持仓执行一键平仓吗?",
+      sideLongWord: "做多",
+      sideShortWord: "做空",
+    },
+    directions: {
+      long: "做多",
+      short: "做空",
+      openLong: "开多",
+      openShort: "开空",
+      closeShort: "平空",
+      closeLong: "平多",
+      openTag: "开",
+      closeTag: "平",
+    },
+    orderTypes: {
+      limit: "限价",
+      plan: "计划委托",
+      takeProfit: "止盈",
+      stopLoss: "止损",
+      marketShort: "市价",
+    },
+    orderStatus: {
+      filled: "已成交",
+      open: "委托中",
+      cancelled: "已撤销",
+      failed: "失败",
+    },
+    closeTypes: {
+      market: "市价平仓",
+      oneClick: "一键平仓",
+      reverseOpen: "反向开仓",
+      tpSl: "止盈止损",
+      liquidation: "爆仓",
+      admin: "管理员平仓",
+    },
+    fundingTx: fundingTxZh,
+  };
 }
 
-function buildEn() : FuturesPageMessages {
-	const b = buildZhCN()
-	return {
-		...b,
-		perpetual: 'Perpetual',
-		perpetualTag: 'Perpetual',
-		pairSearchPlaceholder: 'Search',
-		pairEmpty: 'No matching pairs',
-		stats: {
-			change24h: '24h Change',
-			markPrice: 'Mark',
-			high24h: '24h High',
-			low24h: '24h Low',
-			volume24h: '24h Volume',
-			fundingCountdown: 'Funding / Countdown',
-		},
-		mobileTabs: { chart: 'Chart', trade: 'Trade' },
-		chartSub: { chart: 'Chart', coinInfo: 'Coin Info', fundingHistory: 'Funding History' },
-		tf: {
-			m1: '1m',
-			m5: '5m',
-			m15: '15m',
-			m30: '30m',
-			h1: '1h',
-			h4: '4h',
-			d1: '1d',
-			w1: '1w',
-			mo1: '1mon',
-			mo3: '3mon'
-		},
-		chartTools: { fullscreen: 'Fullscreen', alert: 'Alerts' },
-		draw: {
-			cursor: 'Cursor',
-			trend: 'Trend line',
-			hline: 'Horizontal',
-			ray: 'Ray',
-			channel: 'Channel',
-			fib: 'Fib retracement',
-			text: 'Text',
-			clearAll: 'Clear drawings',
-			zoomOut: 'Zoom out',
-		},
-		ohlcv: {
-			open: 'O',
-			high: 'H',
-			low: 'L',
-			close: 'C',
-			volume: 'Volume',
-			changePct: 'Change',
-			amplitude: 'Range',
-		},
-		coinInfo: {
-			marketCap: 'Market cap',
-			circulating: 'Circulating supply',
-			issuePrice: 'Issue price',
-			ath: 'All-time high',
-			athDate: 'ATH date',
-			whitepaper: 'Whitepaper',
-			empty: 'No coin info',
-			reload: 'Reload',
-		},
-		fundingPanel: {
-			rate: 'Funding rate',
-			period: 'Settlement period',
-			nextCountdown: 'Next countdown',
-			noChart: 'No chart data',
-			settleTime: 'Settlement',
-			rateCol: 'Funding rate',
-			empty7d: 'No last-7-days data',
-		},
-		book: {
-			orderBook: 'Order book',
-			trades: 'Trades',
-			priceQuote: 'Price (USDT)',
-			amountBase: 'Amount ({base})',
-			totalBase: 'Total ({base})',
-			time: 'Time',
-			buy: 'Buy',
-			sell: 'Sell',
-			buyRatio: 'Buy {n}%',
-			sellRatio: '{n}% Sell',
-			noTrades: 'No trades',
-		},
-		margin: { cross: 'Cross', split: 'Isolated', experience: 'Bonus' },
-		amountUnit: { lots: 'Cont', usdt: 'USDT' },
-		leverage: { adjustTitle: 'Adjust leverage' },
-		order: {
-			limit: 'Limit',
-			market: 'Market',
-			conditional: 'Conditional',
-			condMarket: 'Market conditional',
-			condLimit: 'Limit conditional',
-			available: 'Available',
-			maxOpen: 'Max to open',
-			triggerPriceLabel: 'Trigger ({q})',
-			priceLabel: 'Price ({q})',
-			latestBtn: 'Last',
-			marketExe: 'Market',
-			condMarketExe: 'Market after trigger',
-			qtyLabel: 'Amount ({u})',
-			transferTitle: 'Transfer',
-			openLong: 'Buy / Long',
-			openShort: 'Sell / Short',
-			contractInfoTitle: 'Contract info',
-			indexSource: 'Index sources',
-			marginCoin: 'Margin asset',
-			maxLeverage: 'Max leverage',
-			maintMargin: 'Maint. margin rate',
-			openFee: 'Open fee',
-			closeFee: 'Close fee',
-			contractValue: 'Contract value',
-			minOrder: 'Min order size',
-			maxOrder: 'Max order size',
-		},
-		placeholders: {
-			searchPair: 'Search',
-			triggerPrice: 'Enter trigger price',
-			price: 'Enter price',
-			amount: 'Enter amount',
-		},
-		bottom: {
-			positions: 'Positions',
-			openOrders: 'Open orders',
-			historyOrders: 'Order history',
-			historyPositions: 'Position history',
-			tradeDetails: 'Trades',
-			fundingFlow: 'Funding',
-			assets: 'Assets',
-			closeAllPositions: 'Close all',
-			cancelAllOrders: 'Cancel all',
-			loginPromptOr: 'or',
-			registerNow: 'Register now',
-			startTrading: 'to start trading',
-		},
-		table: {
-			contract: 'Contract',
-			dirLeverage: 'Dir./Lev.',
-			openPrice: 'Open',
-			markPrice: 'Mark',
-			positionSize: 'Size',
-			margin: 'Margin',
-			marginRate: 'Margin ratio',
-			unrealizedPnl: 'UPnL',
-			roe: 'ROE',
-			liqPrice: 'Liq. price',
-			openTime: 'Open time',
-			action: 'Action',
-			type: 'Type',
-			orderPrice: 'Price',
-			entrustPriceHist: 'Order price',
-			triggerPrice: 'Trigger',
-			orderAmt: 'Order qty',
-			filled: 'Filled',
-			tpPrice: 'Take profit',
-			slPrice: 'Stop loss',
-			time: 'Time',
-			orderTime: 'Order time',
-			fillTime: 'Fill time',
-			profitUsdt: 'P&L (USDT)',
-			tradedVol: 'Filled qty',
-			closeAvg: 'Close avg.',
-			profitRate: 'ROE',
-			closeTime: 'Close time',
-			directionOpenClose: 'Side/O-C',
-			dealPrice: 'Fill price',
-			fee: 'Fee',
-			fundType: 'Type',
-			amount: 'Amount',
-			coin: 'Coin',
-			settlementTime: 'Settlement',
-			fundingRate: 'Funding rate',
-			totalBal: 'Futures balance',
-			availMargin: 'Available margin',
-			usedMargin: 'Used margin',
-			unrealized: 'Unrealized P&L',
-			spotWalletBal: 'Withdrawable account balance',
-			fundTransfer: 'Transfer',
-			avgOpenPrice: 'Avg. open',
-			feeHint: 'Fee (USDT)',
-			estimatedPnlRow: 'Est. P&L',
-			triggerUsdt: 'Trigger (USDT)',
-			orderPriceUsdt: 'Order price (USDT)',
-			openAvgUsdt: 'Avg. entry (USDT)',
-			closeAvgUsdt: 'Avg. exit (USDT)',
-			tpUsdt: 'TP (USDT)',
-			slUsdt: 'SL (USDT)',
-			marginUsdtBracket: 'Margin (USDT)',
-			notionalUsdt: 'Position value (USDT)',
-			estLiqPx: 'Est. liq. price',
-			profitBracketUsdt: 'P&L (USDT)',
-			entrustVolCoin: 'Order qty ({base})',
-			filledVolCoin: 'Filled ({base})',
-			closeAvail: 'Closable:',
-			markPriceBtn: 'Mark',
-		},
-		empty: {
-			noPositions: 'No positions',
-			noOrders: 'No orders',
-			noHistPositions: 'No position history',
-			noHistOrders: 'No historical orders',
-			noTradeRecords: 'No fills',
-			noFunding: 'No funding records',
-		},
-		modal: {
-			confirmDefaultTitle: 'Please confirm',
-			positionDetailTitle: 'Position detail',
-			orderDetailTitle: 'Order detail',
-			histPositionDetailTitle: 'Historical position',
-			histOrderDetailTitle: 'Historical order',
-			closePositionTitlePrefix: 'Close',
-			modifyTpSl: 'Edit TP/SL',
-			setTpSl: 'Set TP/SL',
-			posQtyLabel: 'Size:',
-			currentTpSlSection: 'Active TP/SL orders',
-			modifyToSection: 'Change to',
-			setPricesSection: 'Prices',
-			tpTriggerLabel: 'Take-profit trigger ',
-			tpHintOptionalClear: '(Leave empty to clear TP)',
-			slTriggerLabel: 'Stop-loss trigger ',
-			slHintOptionalClear: '(Leave empty to clear SL)',
-			placeholderTpTrigger: 'TP trigger price',
-			placeholderSlTrigger: 'SL trigger price',
-			confirmCloseBtn: 'Confirm close',
-			ok: 'OK',
-			closeTypeLiquidation: 'Liquidated',
-			tpBadge: 'TP',
-			slBadge: 'SL',
-			tpPriceWord: 'TP ',
-			slPriceWord: 'SL ',
-			volLabel: 'Qty:',
-			marginSplitMode: 'Cross / Isolated',
-			directionLabel: 'Side',
-			entrustTypeLabel: 'Order type',
-			leverageLabel: 'Leverage',
-		},
-		actions: { tpSl: 'TP/SL', reverse: 'Reverse', close: 'Close', marketCloseAll: 'Market close all', cancelOrder: 'Cancel' },
-		positionRow: { hintCross: 'Cross', hintExperience: 'Bonus' },
-		errors: {
-			enterTriggerPrice: 'Enter trigger price',
-			enterPrice: 'Enter price',
-			priceNotReadyConvert: 'Price not ready — cannot convert size',
-			invalidQtyCheckMin: 'Invalid size — check precision and minimum order',
-			priceNotReadyRetry: 'Price not ready, please retry',
-			enterQty: 'Enter quantity',
-			qtyExceedAvail: 'Qty exceeds closeable amount',
-			closeFailed: 'Close failed',
-			modifyTpSlFailed: 'Update failed — try later',
-			txFallback: 'Type {n}',
-		},
-		confirm: {
-			reverseTitle: 'Reverse position',
-			reverseBody: 'Reverse {pair} {side}?',
-			cancelAllTitle: 'Cancel all',
-			cancelAllBody: 'Cancel {n} orders?',
-			closeAllTitle: 'Close all',
-			closeAllBody: 'Market-close {n} positions?',
-			sideLongWord: 'long',
-			sideShortWord: 'short',
-		},
-		directions: {
-			long: 'Long',
-			short: 'Short',
-			openLong: 'Open long',
-			openShort: 'Open short',
-			closeShort: 'Close short',
-			closeLong: 'Close long',
-			openTag: 'O',
-			closeTag: 'C',
-		},
-		orderTypes: { limit: 'Limit', plan: 'Trigger', takeProfit: 'Take profit', stopLoss: 'Stop loss', marketShort: 'Market' },
-		orderStatus: { filled: 'Filled', open: 'Open', cancelled: 'Cancelled', failed: 'Failed' },
-		closeTypes: {
-			market: 'Market close',
-			oneClick: 'Bulk close',
-			reverseOpen: 'Reverse open',
-			tpSl: 'TP/SL',
-			liquidation: 'Liquidation',
-			admin: 'Admin close',
-		},
-		fundingTx: fundingTxEn,
-	}
+function buildEn(): FuturesPageMessages {
+  const b = buildZhCN();
+  return {
+    ...b,
+    perpetual: "Perpetual",
+    perpetualTag: "Perpetual",
+    pairSearchPlaceholder: "Search",
+    pairSearchTag: {
+      oneType: "Crypto",
+      twoType: "Stock",
+      threeType: "Commodity",
+      fourType: "Forex",
+    },
+    pairEmpty: "No matching pairs",
+    stats: {
+      change24h: "24h Change",
+      markPrice: "Mark",
+      high24h: "24h High",
+      low24h: "24h Low",
+      volume24h: "24h Volume",
+      fundingCountdown: "Funding / Countdown",
+    },
+    mobileTabs: { chart: "Chart", trade: "Trade" },
+    chartSub: {
+      chart: "Chart",
+      coinInfo: "Coin Info",
+      fundingHistory: "Funding History",
+    },
+    tf: {
+      m1: "1m",
+      m5: "5m",
+      m15: "15m",
+      m30: "30m",
+      h1: "1h",
+      h4: "4h",
+      d1: "1d",
+      w1: "1w",
+      mo1: "1mon",
+      mo3: "3mon",
+    },
+    chartTools: { fullscreen: "Fullscreen", alert: "Alerts" },
+    draw: {
+      cursor: "Cursor",
+      trend: "Trend line",
+      hline: "Horizontal",
+      ray: "Ray",
+      channel: "Channel",
+      fib: "Fib retracement",
+      text: "Text",
+      clearAll: "Clear drawings",
+      zoomOut: "Zoom out",
+    },
+    ohlcv: {
+      open: "O",
+      high: "H",
+      low: "L",
+      close: "C",
+      volume: "Volume",
+      changePct: "Change",
+      amplitude: "Range",
+    },
+    coinInfo: {
+      marketCap: "Market cap",
+      circulating: "Circulating supply",
+      issuePrice: "Issue price",
+      ath: "All-time high",
+      athDate: "ATH date",
+      whitepaper: "Whitepaper",
+      empty: "No coin info",
+      reload: "Reload",
+    },
+    fundingPanel: {
+      rate: "Funding rate",
+      period: "Settlement period",
+      nextCountdown: "Next countdown",
+      noChart: "No chart data",
+      settleTime: "Settlement",
+      rateCol: "Funding rate",
+      empty7d: "No last-7-days data",
+    },
+    book: {
+      orderBook: "Order book",
+      trades: "Trades",
+      priceQuote: "Price (USDT)",
+      amountBase: "Amount ({base})",
+      totalBase: "Total ({base})",
+      time: "Time",
+      buy: "Buy",
+      sell: "Sell",
+      buyRatio: "Buy {n}%",
+      sellRatio: "{n}% Sell",
+      noTrades: "No trades",
+    },
+    margin: { cross: "Cross", split: "Isolated", experience: "Bonus" },
+    amountUnit: { lots: "Cont", usdt: "USDT" },
+    leverage: { adjustTitle: "Adjust leverage" },
+    order: {
+      limit: "Limit",
+      market: "Market",
+      conditional: "Conditional",
+      condMarket: "Market conditional",
+      condLimit: "Limit conditional",
+      available: "Available",
+      maxOpen: "Max to open",
+      triggerPriceLabel: "Trigger ({q})",
+      priceLabel: "Price ({q})",
+      latestBtn: "Last",
+      marketExe: "Market",
+      condMarketExe: "Market after trigger",
+      qtyLabel: "Amount ({u})",
+      transferTitle: "Transfer",
+      openLong: "Buy / Long",
+      openShort: "Sell / Short",
+      contractInfoTitle: "Contract info",
+      indexSource: "Index sources",
+      marginCoin: "Margin asset",
+      maxLeverage: "Max leverage",
+      maintMargin: "Maint. margin rate",
+      openFee: "Open fee",
+      closeFee: "Close fee",
+      contractValue: "Contract value",
+      minOrder: "Min order size",
+      maxOrder: "Max order size",
+    },
+    placeholders: {
+      searchPair: "Search",
+      triggerPrice: "Enter trigger price",
+      price: "Enter price",
+      amount: "Enter amount",
+    },
+    bottom: {
+      positions: "Positions",
+      openOrders: "Open orders",
+      historyOrders: "Order history",
+      historyPositions: "Position history",
+      tradeDetails: "Trades",
+      fundingFlow: "Funding",
+      assets: "Assets",
+      closeAllPositions: "Close all",
+      cancelAllOrders: "Cancel all",
+      loginPromptOr: "or",
+      registerNow: "Register now",
+      startTrading: "to start trading",
+    },
+    table: {
+      contract: "Contract",
+      dirLeverage: "Dir./Lev.",
+      openPrice: "Open",
+      markPrice: "Mark",
+      positionSize: "Size",
+      margin: "Margin",
+      marginRate: "Margin ratio",
+      unrealizedPnl: "UPnL",
+      roe: "ROE",
+      liqPrice: "Liq. price",
+      openTime: "Open time",
+      action: "Action",
+      type: "Type",
+      orderPrice: "Price",
+      entrustPriceHist: "Order price",
+      triggerPrice: "Trigger",
+      orderAmt: "Order qty",
+      filled: "Filled",
+      tpPrice: "Take profit",
+      slPrice: "Stop loss",
+      time: "Time",
+      orderTime: "Order time",
+      fillTime: "Fill time",
+      profitUsdt: "P&L (USDT)",
+      tradedVol: "Filled qty",
+      closeAvg: "Close avg.",
+      profitRate: "ROE",
+      closeTime: "Close time",
+      directionOpenClose: "Side/O-C",
+      dealPrice: "Fill price",
+      fee: "Fee",
+      fundType: "Type",
+      amount: "Amount",
+      coin: "Coin",
+      settlementTime: "Settlement",
+      fundingRate: "Funding rate",
+      totalBal: "Futures balance",
+      availMargin: "Available margin",
+      usedMargin: "Used margin",
+      unrealized: "Unrealized P&L",
+      spotWalletBal: "Withdrawable account balance",
+      fundTransfer: "Transfer",
+      avgOpenPrice: "Avg. open",
+      feeHint: "Fee (USDT)",
+      estimatedPnlRow: "Est. P&L",
+      triggerUsdt: "Trigger (USDT)",
+      orderPriceUsdt: "Order price (USDT)",
+      openAvgUsdt: "Avg. entry (USDT)",
+      closeAvgUsdt: "Avg. exit (USDT)",
+      tpUsdt: "TP (USDT)",
+      slUsdt: "SL (USDT)",
+      marginUsdtBracket: "Margin (USDT)",
+      notionalUsdt: "Position value (USDT)",
+      estLiqPx: "Est. liq. price",
+      profitBracketUsdt: "P&L (USDT)",
+      entrustVolCoin: "Order qty ({base})",
+      filledVolCoin: "Filled ({base})",
+      closeAvail: "Closable:",
+      markPriceBtn: "Mark",
+    },
+    empty: {
+      noPositions: "No positions",
+      noOrders: "No orders",
+      noHistPositions: "No position history",
+      noHistOrders: "No historical orders",
+      noTradeRecords: "No fills",
+      noFunding: "No funding records",
+    },
+    modal: {
+      confirmDefaultTitle: "Please confirm",
+      positionDetailTitle: "Position detail",
+      orderDetailTitle: "Order detail",
+      histPositionDetailTitle: "Historical position",
+      histOrderDetailTitle: "Historical order",
+      closePositionTitlePrefix: "Close",
+      modifyTpSl: "Edit TP/SL",
+      setTpSl: "Set TP/SL",
+      posQtyLabel: "Size:",
+      currentTpSlSection: "Active TP/SL orders",
+      modifyToSection: "Change to",
+      setPricesSection: "Prices",
+      tpTriggerLabel: "Take-profit trigger ",
+      tpHintOptionalClear: "(Leave empty to clear TP)",
+      slTriggerLabel: "Stop-loss trigger ",
+      slHintOptionalClear: "(Leave empty to clear SL)",
+      placeholderTpTrigger: "TP trigger price",
+      placeholderSlTrigger: "SL trigger price",
+      confirmCloseBtn: "Confirm close",
+      ok: "OK",
+      closeTypeLiquidation: "Liquidated",
+      tpBadge: "TP",
+      slBadge: "SL",
+      tpPriceWord: "TP ",
+      slPriceWord: "SL ",
+      volLabel: "Qty:",
+      marginSplitMode: "Cross / Isolated",
+      directionLabel: "Side",
+      entrustTypeLabel: "Order type",
+      leverageLabel: "Leverage",
+    },
+    actions: {
+      tpSl: "TP/SL",
+      reverse: "Reverse",
+      close: "Close",
+      marketCloseAll: "Market close all",
+      cancelOrder: "Cancel",
+    },
+    positionRow: { hintCross: "Cross", hintExperience: "Bonus" },
+    errors: {
+      enterTriggerPrice: "Enter trigger price",
+      enterPrice: "Enter price",
+      priceNotReadyConvert: "Price not ready — cannot convert size",
+      invalidQtyCheckMin: "Invalid size — check precision and minimum order",
+      priceNotReadyRetry: "Price not ready, please retry",
+      enterQty: "Enter quantity",
+      qtyExceedAvail: "Qty exceeds closeable amount",
+      closeFailed: "Close failed",
+      modifyTpSlFailed: "Update failed — try later",
+      txFallback: "Type {n}",
+    },
+    confirm: {
+      reverseTitle: "Reverse position",
+      reverseBody: "Reverse {pair} {side}?",
+      cancelAllTitle: "Cancel all",
+      cancelAllBody: "Cancel {n} orders?",
+      closeAllTitle: "Close all",
+      closeAllBody: "Market-close {n} positions?",
+      sideLongWord: "long",
+      sideShortWord: "short",
+    },
+    directions: {
+      long: "Long",
+      short: "Short",
+      openLong: "Open long",
+      openShort: "Open short",
+      closeShort: "Close short",
+      closeLong: "Close long",
+      openTag: "O",
+      closeTag: "C",
+    },
+    orderTypes: {
+      limit: "Limit",
+      plan: "Trigger",
+      takeProfit: "Take profit",
+      stopLoss: "Stop loss",
+      marketShort: "Market",
+    },
+    orderStatus: {
+      filled: "Filled",
+      open: "Open",
+      cancelled: "Cancelled",
+      failed: "Failed",
+    },
+    closeTypes: {
+      market: "Market close",
+      oneClick: "Bulk close",
+      reverseOpen: "Reverse open",
+      tpSl: "TP/SL",
+      liquidation: "Liquidation",
+      admin: "Admin close",
+    },
+    fundingTx: fundingTxEn,
+  };
 }
 
-function buildZhTW() : FuturesPageMessages {
-	const cn = buildZhCN()
-	return {
-		...cn,
-		perpetual: '永續合約',
-		perpetualTag: '永續',
-		pairSearchPlaceholder: '搜尋',
-		pairEmpty: '無符合結果',
-		stats: {
-			change24h: '24h漲跌',
-			markPrice: '標記價格',
-			high24h: '24h最高價',
-			low24h: '24h最低價',
-			volume24h: '24h成交量',
-			fundingCountdown: '資金費率 / 倒計時',
-		},
-		mobileTabs: { chart: '行情', trade: '交易' },
-		chartSub: { chart: '圖表', coinInfo: '幣種資料', fundingHistory: '歷史資金費率' },
-		tf: {
-			m1: '1分',
-			m5: '5分',
-			m15: '15分',
-			m30: '30分',
-			h1: '1小時',
-			h4: '4小時',
-			d1: '1日',
-			w1: '1週',
-			mo1: '1月',
-			mo3: '3月'
-		},
-		chartTools: { fullscreen: '全螢幕', alert: '提醒' },
-		draw: {
-			cursor: '游標',
-			trend: '趨勢線',
-			hline: '水平線',
-			ray: '射線',
-			channel: '通道線',
-			fib: '斐波那契回撤',
-			text: '文字標註',
-			clearAll: '刪除所有標註',
-			zoomOut: '縮小',
-		},
-		ohlcv: { ...cn.ohlcv, volume: '成交量', changePct: '漲幅', amplitude: '振幅' },
-		coinInfo: {
-			marketCap: '市值',
-			circulating: '流通量',
-			issuePrice: '發行價',
-			ath: '歷史最高',
-			athDate: 'ATH 日期',
-			whitepaper: '白皮書',
-			empty: '暫無幣種資料',
-			reload: '重新載入',
-		},
-		fundingPanel: {
-			rate: '資金費率',
-			period: '結算週期',
-			nextCountdown: '下次結算倒計時',
-			noChart: '暫無圖表數據',
-			settleTime: '結算時間',
-			rateCol: '資金費率',
-			empty7d: '暫無近7天數據',
-		},
-		book: {
-			orderBook: '訂單簿',
-			trades: '最新成交',
-			priceQuote: '價格(USDT)',
-			amountBase: '數量({base})',
-			totalBase: '總量({base})',
-			time: '時間',
-			buy: '買',
-			sell: '賣',
-			buyRatio: '買 {n}%',
-			sellRatio: '{n}% 賣',
-			noTrades: '暫無成交資料',
-		},
-		margin: { cross: '全倉', split: '分倉', experience: '體驗金' },
-		amountUnit: { lots: '張', usdt: 'USDT' },
-		leverage: { adjustTitle: '調整槓桿' },
-		order: {
-			limit: '限價',
-			market: '市價',
-			conditional: '條件委託',
-			condMarket: '市價委託',
-			condLimit: '限價委託',
-			available: '可用',
-			maxOpen: '最大可開',
-			triggerPriceLabel: '觸發價 ({q})',
-			priceLabel: '價格 ({q})',
-			latestBtn: '最新',
-			marketExe: '市價成交',
-			condMarketExe: '觸發後市價成交',
-			qtyLabel: '數量 ({u})',
-			transferTitle: '劃轉',
-			openLong: '開多',
-			openShort: '開空',
-			contractInfoTitle: '合約資訊',
-			indexSource: '指數來源',
-			marginCoin: '保證金幣種',
-			maxLeverage: '最大槓桿',
-			maintMargin: '維持保證金率',
-			openFee: '開倉手續費',
-			closeFee: '平倉手續費',
-			contractValue: '合約面值',
-			minOrder: '最小下單量',
-			maxOrder: '最大下單量',
-		},
-		placeholders: { searchPair: '搜尋', triggerPrice: '請輸入觸發價', price: '請輸入價格', amount: '請輸入數量' },
-		bottom: {
-			positions: '倉位',
-			openOrders: '當前委託',
-			historyOrders: '歷史委託',
-			historyPositions: '歷史倉位',
-			tradeDetails: '成交明細',
-			fundingFlow: '資金流水',
-			assets: '資產',
-			closeAllPositions: '一鍵平倉',
-			cancelAllOrders: '全部撤單',
-			loginPromptOr: '或',
-			registerNow: '立即註冊',
-			startTrading: '開始交易',
-		},
-		table: {
-			contract: '合約',
-			dirLeverage: '方向/槓桿',
-			openPrice: '開倉價',
-			markPrice: '標記價',
-			positionSize: '持倉量',
-			margin: '保證金',
-			marginRate: '保證金率',
-			unrealizedPnl: '浮動盈虧',
-			roe: '收益率',
-			liqPrice: '強平價',
-			openTime: '開倉時間',
-			action: '操作',
-			type: '類型',
-			orderPrice: '委託價',
-			entrustPriceHist: '委託價格',
-			triggerPrice: '觸發價',
-			orderAmt: '委託量',
-			filled: '已成交',
-			tpPrice: '止盈價',
-			slPrice: '止損價',
-			time: '時間',
-			orderTime: '委託時間',
-			fillTime: '成交時間',
-			profitUsdt: '收益(USDT)',
-			tradedVol: '已成交量',
-			closeAvg: '平倉均價',
-			profitRate: '收益率',
-			closeTime: '平倉時間',
-			directionOpenClose: '方向/開平',
-			dealPrice: '成交價',
-			fee: '手續費',
-			fundType: '類型',
-			amount: '數量',
-			coin: '幣種',
-			settlementTime: '結算時間',
-			fundingRate: '資金費率',
-			totalBal: '合約帳戶總餘額',
-			availMargin: '可用保證金',
-			usedMargin: '已用保證金',
-			unrealized: '未實現盈虧',
-			spotWalletBal: '可提現帳戶餘額',
-			fundTransfer: '資金劃轉',
-			avgOpenPrice: '開倉均價',
-			feeHint: '手續費(USDT)',
-			estimatedPnlRow: '預計盈虧',
-			triggerUsdt: '觸發價(USDT)',
-			orderPriceUsdt: '委託價(USDT)',
-			openAvgUsdt: '開倉均價(USDT)',
-			closeAvgUsdt: '平倉均價(USDT)',
-			tpUsdt: '止盈價(USDT)',
-			slUsdt: '止損價(USDT)',
-			marginUsdtBracket: '保證金(USDT)',
-			notionalUsdt: '倉位價值(USDT)',
-			estLiqPx: '預估強平價',
-			profitBracketUsdt: '收益(USDT)',
-			entrustVolCoin: '委託量({base})',
-			filledVolCoin: '已成交量({base})',
-			closeAvail: '可平:',
-			markPriceBtn: '標記價',
-		},
-		empty: {
-			noPositions: '暫無持倉',
-			noOrders: '暫無委託',
-			noHistPositions: '暫無歷史倉位',
-			noHistOrders: '暫無歷史委託',
-			noTradeRecords: '暫無成交記錄',
-			noFunding: '暫無資金流水',
-		},
-		modal: {
-			confirmDefaultTitle: '請確認',
-			positionDetailTitle: '倉位詳情',
-			orderDetailTitle: '委託詳情',
-			histPositionDetailTitle: '歷史倉位詳情',
-			histOrderDetailTitle: '歷史委託詳情',
-			closePositionTitlePrefix: '平倉',
-			modifyTpSl: '修改止盈止損',
-			setTpSl: '設置止盈止損',
-			posQtyLabel: '持倉量:',
-			currentTpSlSection: '當前止盈止損委託',
-			modifyToSection: '修改為',
-			setPricesSection: '設置價格',
-			tpTriggerLabel: '止盈觸發價 ',
-			tpHintOptionalClear: '(不填則清除止盈)',
-			slTriggerLabel: '止損觸發價 ',
-			slHintOptionalClear: '(不填則清除止損)',
-			placeholderTpTrigger: '輸入止盈觸發價',
-			placeholderSlTrigger: '輸入止損觸發價',
-			confirmCloseBtn: '確認平倉',
-			ok: '確定',
-			closeTypeLiquidation: '爆倉',
-			tpBadge: '止盈',
-			slBadge: '止損',
-			tpPriceWord: '止盈價 ',
-			slPriceWord: '止損價 ',
-			volLabel: '數量:',
-			marginSplitMode: '全倉/分倉',
-			directionLabel: '方向',
-			entrustTypeLabel: '委託類型',
-			leverageLabel: '槓桿',
-		},
-		actions: { tpSl: '止盈止損', reverse: '反手', close: '平倉', marketCloseAll: '市價全平', cancelOrder: '撤單' },
-		positionRow: { hintCross: '全倉', hintExperience: '體驗金' },
-		errors: {
-			enterTriggerPrice: '請輸入觸發價',
-			enterPrice: '請輸入價格',
-			priceNotReadyConvert: '價格未就緒,無法換算數量',
-			invalidQtyCheckMin: '數量無效,請檢查精度與最小下單量',
-			priceNotReadyRetry: '價格未就緒,請稍後重試',
-			enterQty: '請輸入數量',
-			qtyExceedAvail: '數量超出可平量',
-			closeFailed: '平倉失敗',
-			modifyTpSlFailed: '修改失敗,請稍後重試',
-			txFallback: '類型{n}',
-		},
-		confirm: {
-			reverseTitle: '一鍵反手',
-			reverseBody: '確認對 {pair} {side} 倉位執行一鍵反手嗎?',
-			cancelAllTitle: '全部撤單',
-			cancelAllBody: '確認撤銷當前 {n} 個委託嗎?',
-			closeAllTitle: '一鍵平倉',
-			closeAllBody: '確認對當前 {n} 個持倉執行一鍵平倉嗎?',
-			sideLongWord: '做多',
-			sideShortWord: '做空',
-		},
-		directions: {
-			long: '做多',
-			short: '做空',
-			openLong: '開多',
-			openShort: '開空',
-			closeShort: '平空',
-			closeLong: '平多',
-			openTag: '開',
-			closeTag: '平',
-		},
-		orderTypes: { limit: '限價', plan: '計畫委託', takeProfit: '止盈', stopLoss: '止損', marketShort: '市價' },
-		orderStatus: { filled: '已成交', open: '委託中', cancelled: '已撤銷', failed: '失敗' },
-		closeTypes: {
-			market: '市價平倉',
-			oneClick: '一鍵平倉',
-			reverseOpen: '反向開倉',
-			tpSl: '止盈止損',
-			liquidation: '爆倉',
-			admin: '管理員平倉',
-		},
-		fundingTx: fundingTw,
-	}
+function buildZhTW(): FuturesPageMessages {
+  const cn = buildZhCN();
+  return {
+    ...cn,
+    perpetual: "永續合約",
+    perpetualTag: "永續",
+    pairSearchPlaceholder: "搜尋",
+    pairSearchTag: {
+      oneType: "加密代幣",
+      twoType: "股票",
+      threeType: "大宗貴金屬",
+      fourType: "外匯",
+    },
+    pairEmpty: "無符合結果",
+    stats: {
+      change24h: "24h漲跌",
+      markPrice: "標記價格",
+      high24h: "24h最高價",
+      low24h: "24h最低價",
+      volume24h: "24h成交量",
+      fundingCountdown: "資金費率 / 倒計時",
+    },
+    mobileTabs: { chart: "行情", trade: "交易" },
+    chartSub: {
+      chart: "圖表",
+      coinInfo: "幣種資料",
+      fundingHistory: "歷史資金費率",
+    },
+    tf: {
+      m1: "1分",
+      m5: "5分",
+      m15: "15分",
+      m30: "30分",
+      h1: "1小時",
+      h4: "4小時",
+      d1: "1日",
+      w1: "1週",
+      mo1: "1月",
+      mo3: "3月",
+    },
+    chartTools: { fullscreen: "全螢幕", alert: "提醒" },
+    draw: {
+      cursor: "游標",
+      trend: "趨勢線",
+      hline: "水平線",
+      ray: "射線",
+      channel: "通道線",
+      fib: "斐波那契回撤",
+      text: "文字標註",
+      clearAll: "刪除所有標註",
+      zoomOut: "縮小",
+    },
+    ohlcv: {
+      ...cn.ohlcv,
+      volume: "成交量",
+      changePct: "漲幅",
+      amplitude: "振幅",
+    },
+    coinInfo: {
+      marketCap: "市值",
+      circulating: "流通量",
+      issuePrice: "發行價",
+      ath: "歷史最高",
+      athDate: "ATH 日期",
+      whitepaper: "白皮書",
+      empty: "暫無幣種資料",
+      reload: "重新載入",
+    },
+    fundingPanel: {
+      rate: "資金費率",
+      period: "結算週期",
+      nextCountdown: "下次結算倒計時",
+      noChart: "暫無圖表數據",
+      settleTime: "結算時間",
+      rateCol: "資金費率",
+      empty7d: "暫無近7天數據",
+    },
+    book: {
+      orderBook: "訂單簿",
+      trades: "最新成交",
+      priceQuote: "價格(USDT)",
+      amountBase: "數量({base})",
+      totalBase: "總量({base})",
+      time: "時間",
+      buy: "買",
+      sell: "賣",
+      buyRatio: "買 {n}%",
+      sellRatio: "{n}% 賣",
+      noTrades: "暫無成交資料",
+    },
+    margin: { cross: "全倉", split: "分倉", experience: "體驗金" },
+    amountUnit: { lots: "張", usdt: "USDT" },
+    leverage: { adjustTitle: "調整槓桿" },
+    order: {
+      limit: "限價",
+      market: "市價",
+      conditional: "條件委託",
+      condMarket: "市價委託",
+      condLimit: "限價委託",
+      available: "可用",
+      maxOpen: "最大可開",
+      triggerPriceLabel: "觸發價 ({q})",
+      priceLabel: "價格 ({q})",
+      latestBtn: "最新",
+      marketExe: "市價成交",
+      condMarketExe: "觸發後市價成交",
+      qtyLabel: "數量 ({u})",
+      transferTitle: "劃轉",
+      openLong: "開多",
+      openShort: "開空",
+      contractInfoTitle: "合約資訊",
+      indexSource: "指數來源",
+      marginCoin: "保證金幣種",
+      maxLeverage: "最大槓桿",
+      maintMargin: "維持保證金率",
+      openFee: "開倉手續費",
+      closeFee: "平倉手續費",
+      contractValue: "合約面值",
+      minOrder: "最小下單量",
+      maxOrder: "最大下單量",
+    },
+    placeholders: {
+      searchPair: "搜尋",
+      triggerPrice: "請輸入觸發價",
+      price: "請輸入價格",
+      amount: "請輸入數量",
+    },
+    bottom: {
+      positions: "倉位",
+      openOrders: "當前委託",
+      historyOrders: "歷史委託",
+      historyPositions: "歷史倉位",
+      tradeDetails: "成交明細",
+      fundingFlow: "資金流水",
+      assets: "資產",
+      closeAllPositions: "一鍵平倉",
+      cancelAllOrders: "全部撤單",
+      loginPromptOr: "或",
+      registerNow: "立即註冊",
+      startTrading: "開始交易",
+    },
+    table: {
+      contract: "合約",
+      dirLeverage: "方向/槓桿",
+      openPrice: "開倉價",
+      markPrice: "標記價",
+      positionSize: "持倉量",
+      margin: "保證金",
+      marginRate: "保證金率",
+      unrealizedPnl: "浮動盈虧",
+      roe: "收益率",
+      liqPrice: "強平價",
+      openTime: "開倉時間",
+      action: "操作",
+      type: "類型",
+      orderPrice: "委託價",
+      entrustPriceHist: "委託價格",
+      triggerPrice: "觸發價",
+      orderAmt: "委託量",
+      filled: "已成交",
+      tpPrice: "止盈價",
+      slPrice: "止損價",
+      time: "時間",
+      orderTime: "委託時間",
+      fillTime: "成交時間",
+      profitUsdt: "收益(USDT)",
+      tradedVol: "已成交量",
+      closeAvg: "平倉均價",
+      profitRate: "收益率",
+      closeTime: "平倉時間",
+      directionOpenClose: "方向/開平",
+      dealPrice: "成交價",
+      fee: "手續費",
+      fundType: "類型",
+      amount: "數量",
+      coin: "幣種",
+      settlementTime: "結算時間",
+      fundingRate: "資金費率",
+      totalBal: "合約帳戶總餘額",
+      availMargin: "可用保證金",
+      usedMargin: "已用保證金",
+      unrealized: "未實現盈虧",
+      spotWalletBal: "可提現帳戶餘額",
+      fundTransfer: "資金劃轉",
+      avgOpenPrice: "開倉均價",
+      feeHint: "手續費(USDT)",
+      estimatedPnlRow: "預計盈虧",
+      triggerUsdt: "觸發價(USDT)",
+      orderPriceUsdt: "委託價(USDT)",
+      openAvgUsdt: "開倉均價(USDT)",
+      closeAvgUsdt: "平倉均價(USDT)",
+      tpUsdt: "止盈價(USDT)",
+      slUsdt: "止損價(USDT)",
+      marginUsdtBracket: "保證金(USDT)",
+      notionalUsdt: "倉位價值(USDT)",
+      estLiqPx: "預估強平價",
+      profitBracketUsdt: "收益(USDT)",
+      entrustVolCoin: "委託量({base})",
+      filledVolCoin: "已成交量({base})",
+      closeAvail: "可平:",
+      markPriceBtn: "標記價",
+    },
+    empty: {
+      noPositions: "暫無持倉",
+      noOrders: "暫無委託",
+      noHistPositions: "暫無歷史倉位",
+      noHistOrders: "暫無歷史委託",
+      noTradeRecords: "暫無成交記錄",
+      noFunding: "暫無資金流水",
+    },
+    modal: {
+      confirmDefaultTitle: "請確認",
+      positionDetailTitle: "倉位詳情",
+      orderDetailTitle: "委託詳情",
+      histPositionDetailTitle: "歷史倉位詳情",
+      histOrderDetailTitle: "歷史委託詳情",
+      closePositionTitlePrefix: "平倉",
+      modifyTpSl: "修改止盈止損",
+      setTpSl: "設置止盈止損",
+      posQtyLabel: "持倉量:",
+      currentTpSlSection: "當前止盈止損委託",
+      modifyToSection: "修改為",
+      setPricesSection: "設置價格",
+      tpTriggerLabel: "止盈觸發價 ",
+      tpHintOptionalClear: "(不填則清除止盈)",
+      slTriggerLabel: "止損觸發價 ",
+      slHintOptionalClear: "(不填則清除止損)",
+      placeholderTpTrigger: "輸入止盈觸發價",
+      placeholderSlTrigger: "輸入止損觸發價",
+      confirmCloseBtn: "確認平倉",
+      ok: "確定",
+      closeTypeLiquidation: "爆倉",
+      tpBadge: "止盈",
+      slBadge: "止損",
+      tpPriceWord: "止盈價 ",
+      slPriceWord: "止損價 ",
+      volLabel: "數量:",
+      marginSplitMode: "全倉/分倉",
+      directionLabel: "方向",
+      entrustTypeLabel: "委託類型",
+      leverageLabel: "槓桿",
+    },
+    actions: {
+      tpSl: "止盈止損",
+      reverse: "反手",
+      close: "平倉",
+      marketCloseAll: "市價全平",
+      cancelOrder: "撤單",
+    },
+    positionRow: { hintCross: "全倉", hintExperience: "體驗金" },
+    errors: {
+      enterTriggerPrice: "請輸入觸發價",
+      enterPrice: "請輸入價格",
+      priceNotReadyConvert: "價格未就緒,無法換算數量",
+      invalidQtyCheckMin: "數量無效,請檢查精度與最小下單量",
+      priceNotReadyRetry: "價格未就緒,請稍後重試",
+      enterQty: "請輸入數量",
+      qtyExceedAvail: "數量超出可平量",
+      closeFailed: "平倉失敗",
+      modifyTpSlFailed: "修改失敗,請稍後重試",
+      txFallback: "類型{n}",
+    },
+    confirm: {
+      reverseTitle: "一鍵反手",
+      reverseBody: "確認對 {pair} {side} 倉位執行一鍵反手嗎?",
+      cancelAllTitle: "全部撤單",
+      cancelAllBody: "確認撤銷當前 {n} 個委託嗎?",
+      closeAllTitle: "一鍵平倉",
+      closeAllBody: "確認對當前 {n} 個持倉執行一鍵平倉嗎?",
+      sideLongWord: "做多",
+      sideShortWord: "做空",
+    },
+    directions: {
+      long: "做多",
+      short: "做空",
+      openLong: "開多",
+      openShort: "開空",
+      closeShort: "平空",
+      closeLong: "平多",
+      openTag: "開",
+      closeTag: "平",
+    },
+    orderTypes: {
+      limit: "限價",
+      plan: "計畫委託",
+      takeProfit: "止盈",
+      stopLoss: "止損",
+      marketShort: "市價",
+    },
+    orderStatus: {
+      filled: "已成交",
+      open: "委託中",
+      cancelled: "已撤銷",
+      failed: "失敗",
+    },
+    closeTypes: {
+      market: "市價平倉",
+      oneClick: "一鍵平倉",
+      reverseOpen: "反向開倉",
+      tpSl: "止盈止損",
+      liquidation: "爆倉",
+      admin: "管理員平倉",
+    },
+    fundingTx: fundingTw,
+  };
 }
 
-function buildKo() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...koUiOverlay, fundingTx: fundingTxKo }) as FuturesPageMessages
+function buildKo(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...koUiOverlay,
+    fundingTx: fundingTxKo,
+  }) as FuturesPageMessages;
 }
 
-function buildJa() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...jaUiOverlay, fundingTx: fundingTxJa }) as FuturesPageMessages
+function buildJa(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...jaUiOverlay,
+    fundingTx: fundingTxJa,
+  }) as FuturesPageMessages;
 }
 
-function buildHi() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...hiUiOverlay, fundingTx: fundingTxHi }) as FuturesPageMessages
+function buildHi(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...hiUiOverlay,
+    fundingTx: fundingTxHi,
+  }) as FuturesPageMessages;
 }
 
-function buildId() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...idUiOverlay, fundingTx: fundingTxId }) as FuturesPageMessages
+function buildId(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...idUiOverlay,
+    fundingTx: fundingTxId,
+  }) as FuturesPageMessages;
 }
 
-function buildEs() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...esUiOverlay, fundingTx: fundingTxEs }) as FuturesPageMessages
+function buildEs(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...esUiOverlay,
+    fundingTx: fundingTxEs,
+  }) as FuturesPageMessages;
 }
 
-function buildRu() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...ruUiOverlay, fundingTx: fundingTxRu }) as FuturesPageMessages
+function buildRu(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...ruUiOverlay,
+    fundingTx: fundingTxRu,
+  }) as FuturesPageMessages;
 }
 
-function buildPt() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...ptUiOverlay, fundingTx: fundingTxPt }) as FuturesPageMessages
+function buildPt(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...ptUiOverlay,
+    fundingTx: fundingTxPt,
+  }) as FuturesPageMessages;
 }
 
-function buildDe() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...deUiOverlay, fundingTx: fundingTxDe }) as FuturesPageMessages
+function buildDe(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...deUiOverlay,
+    fundingTx: fundingTxDe,
+  }) as FuturesPageMessages;
 }
 
-function buildFr() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...frUiOverlay, fundingTx: fundingTxFr }) as FuturesPageMessages
+function buildFr(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...frUiOverlay,
+    fundingTx: fundingTxFr,
+  }) as FuturesPageMessages;
 }
 
-function buildTr() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...trUiOverlay, fundingTx: fundingTxTr }) as FuturesPageMessages
+function buildTr(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...trUiOverlay,
+    fundingTx: fundingTxTr,
+  }) as FuturesPageMessages;
 }
 
-function buildVi() : FuturesPageMessages {
-	return deepMerge(buildEn(), { ...viUiOverlay, fundingTx: fundingTxVi }) as FuturesPageMessages
+function buildVi(): FuturesPageMessages {
+  return deepMerge(buildEn(), {
+    ...viUiOverlay,
+    fundingTx: fundingTxVi,
+  }) as FuturesPageMessages;
 }
 
 export const futuresPageByLocale = {
-	'zh-CN': buildZhCN(),
-	'zh-TW': buildZhTW(),
-	en: buildEn(),
-	ko: buildKo(),
-	ja: buildJa(),
-	hi: buildHi(),
-	id: buildId(),
-	es: buildEs(),
-	ru: buildRu(),
-	pt: buildPt(),
-	de: buildDe(),
-	fr: buildFr(),
-	tr: buildTr(),
-	vi: buildVi(),
-} as const
+  "zh-CN": buildZhCN(),
+  "zh-TW": buildZhTW(),
+  en: buildEn(),
+  ko: buildKo(),
+  ja: buildJa(),
+  hi: buildHi(),
+  id: buildId(),
+  es: buildEs(),
+  ru: buildRu(),
+  pt: buildPt(),
+  de: buildDe(),
+  fr: buildFr(),
+  tr: buildTr(),
+  vi: buildVi(),
+} as const;

+ 6 - 0
code/src/locales/futuresPage/overlays/de.ts

@@ -4,6 +4,12 @@ export const deUiOverlay: DeepPartial<FuturesPageMessages> = {
   perpetual: 'Perpetual Futures',
   perpetualTag: 'Perpetual',
   pairSearchPlaceholder: 'Suchen',
+  pairSearchTag: {
+    oneType: 'Krypto',
+    twoType: 'Aktien',
+    threeType: 'Edelmetalle',
+    fourType: 'Forex',
+  },
   pairEmpty: 'Keine Treffer',
   stats: {
     change24h: '24h Änderung',

+ 260 - 233
code/src/locales/futuresPage/overlays/es.ts

@@ -1,268 +1,295 @@
-import type { DeepPartial, FuturesPageMessages } from '../../futuresPage.i18n'
+import type { DeepPartial, FuturesPageMessages } from "../../futuresPage.i18n";
 
 /** 合约页 UI:在 buildEn 基础上覆盖为西班牙语 */
 export const esUiOverlay: DeepPartial<FuturesPageMessages> = {
-  perpetual: 'Contratos perpetuos',
-  perpetualTag: 'Perpetuo',
-  pairSearchPlaceholder: 'Buscar',
-  pairEmpty: 'Sin coincidencias',
+  perpetual: "Contratos perpetuos",
+  perpetualTag: "Perpetuo",
+  pairSearchPlaceholder: "Buscar",
+  pairSearchTag: {
+    oneType: "Cripto",
+    twoType: "Acciones",
+    threeType: "Metales",
+    fourType: "Forex",
+  },
+  pairEmpty: "Sin coincidencias",
   stats: {
-    change24h: 'Cambio 24h',
-    markPrice: 'Marca',
-    high24h: 'Máx 24h',
-    low24h: 'Mín 24h',
-    volume24h: 'Volumen 24h',
-    fundingCountdown: 'Financiación / Cuenta atrás',
+    change24h: "Cambio 24h",
+    markPrice: "Marca",
+    high24h: "Máx 24h",
+    low24h: "Mín 24h",
+    volume24h: "Volumen 24h",
+    fundingCountdown: "Financiación / Cuenta atrás",
+  },
+  mobileTabs: { chart: "Gráfico", trade: "Operar" },
+  chartSub: {
+    chart: "Gráfico",
+    coinInfo: "Info moneda",
+    fundingHistory: "Historial financiación",
   },
-  mobileTabs: { chart: 'Gráfico', trade: 'Operar' },
-  chartSub: { chart: 'Gráfico', coinInfo: 'Info moneda', fundingHistory: 'Historial financiación' },
-  chartTools: { fullscreen: 'Pantalla completa', alert: 'Alertas' },
+  chartTools: { fullscreen: "Pantalla completa", alert: "Alertas" },
   draw: {
-    cursor: 'Cursor',
-    trend: 'Línea tendencia',
-    hline: 'Horizontal',
-    ray: 'Ray',
-    channel: 'Canal',
-    fib: 'Fibonacci',
-    text: 'Texto',
-    clearAll: 'Borrar dibujos',
-    zoomOut: 'Alejar',
+    cursor: "Cursor",
+    trend: "Línea tendencia",
+    hline: "Horizontal",
+    ray: "Ray",
+    channel: "Canal",
+    fib: "Fibonacci",
+    text: "Texto",
+    clearAll: "Borrar dibujos",
+    zoomOut: "Alejar",
   },
   ohlcv: {
-    open: 'A',
-    high: 'M',
-    low: 'm',
-    close: 'C',
-    volume: 'Volumen',
-    changePct: 'Cambio',
-    amplitude: 'Rango',
+    open: "A",
+    high: "M",
+    low: "m",
+    close: "C",
+    volume: "Volumen",
+    changePct: "Cambio",
+    amplitude: "Rango",
   },
   coinInfo: {
-    marketCap: 'Cap. mercado',
-    circulating: 'Suministro circulante',
-    issuePrice: 'Precio emisión',
-    ath: 'Máx histórico',
-    athDate: 'Fecha ATH',
-    whitepaper: 'Whitepaper',
-    empty: 'Sin info de moneda',
-    reload: 'Recargar',
+    marketCap: "Cap. mercado",
+    circulating: "Suministro circulante",
+    issuePrice: "Precio emisión",
+    ath: "Máx histórico",
+    athDate: "Fecha ATH",
+    whitepaper: "Whitepaper",
+    empty: "Sin info de moneda",
+    reload: "Recargar",
   },
   fundingPanel: {
-    rate: 'Tasa financiación',
-    period: 'Período liquidación',
-    nextCountdown: 'Próxima cuenta atrás',
-    noChart: 'Sin datos de gráfico',
-    settleTime: 'Liquidación',
-    rateCol: 'Tasa financiación',
-    empty7d: 'Sin datos últimos 7 días',
+    rate: "Tasa financiación",
+    period: "Período liquidación",
+    nextCountdown: "Próxima cuenta atrás",
+    noChart: "Sin datos de gráfico",
+    settleTime: "Liquidación",
+    rateCol: "Tasa financiación",
+    empty7d: "Sin datos últimos 7 días",
   },
   book: {
-    orderBook: 'Libro órdenes',
-    trades: 'Operaciones',
-    priceQuote: 'Precio (USDT)',
-    amountBase: 'Cantidad ({base})',
-    totalBase: 'Total ({base})',
-    time: 'Hora',
-    buy: 'Compra',
-    sell: 'Venta',
-    buyRatio: 'Compra {n}%',
-    sellRatio: '{n}% Venta',
-    noTrades: 'Sin operaciones',
+    orderBook: "Libro órdenes",
+    trades: "Operaciones",
+    priceQuote: "Precio (USDT)",
+    amountBase: "Cantidad ({base})",
+    totalBase: "Total ({base})",
+    time: "Hora",
+    buy: "Compra",
+    sell: "Venta",
+    buyRatio: "Compra {n}%",
+    sellRatio: "{n}% Venta",
+    noTrades: "Sin operaciones",
   },
-  margin: { cross: 'Cruzado', split: 'Aislado', experience: 'Bonus' },
-  amountUnit: { lots: 'Contratos', usdt: 'USDT' },
-  leverage: { adjustTitle: 'Ajustar apalancamiento' },
+  margin: { cross: "Cruzado", split: "Aislado", experience: "Bonus" },
+  amountUnit: { lots: "Contratos", usdt: "USDT" },
+  leverage: { adjustTitle: "Ajustar apalancamiento" },
   order: {
-    limit: 'Límite',
-    market: 'Mercado',
-    conditional: 'Condicional',
-    condMarket: 'Mercado condicional',
-    condLimit: 'Límite condicional',
-    available: 'Disponible',
-    maxOpen: 'Máx a abrir',
-    triggerPriceLabel: 'Disparador ({q})',
-    priceLabel: 'Precio ({q})',
-    latestBtn: 'Último',
-    marketExe: 'Mercado',
-    condMarketExe: 'Mercado después disparador',
-    qtyLabel: 'Cantidad ({u})',
-    transferTitle: 'Transferir',
-    openLong: 'Comprar / Long',
-    openShort: 'Vender / Short',
-    contractInfoTitle: 'Info contrato',
-    indexSource: 'Fuentes índice',
-    marginCoin: 'Activo margen',
-    maxLeverage: 'Apalancamiento máx',
-    maintMargin: 'Tasa margen mantenimiento',
-    openFee: 'Comisión apertura',
-    closeFee: 'Comisión cierre',
-    contractValue: 'Valor contrato',
-    minOrder: 'Mín. orden',
-    maxOrder: 'Máx. orden',
+    limit: "Límite",
+    market: "Mercado",
+    conditional: "Condicional",
+    condMarket: "Mercado condicional",
+    condLimit: "Límite condicional",
+    available: "Disponible",
+    maxOpen: "Máx a abrir",
+    triggerPriceLabel: "Disparador ({q})",
+    priceLabel: "Precio ({q})",
+    latestBtn: "Último",
+    marketExe: "Mercado",
+    condMarketExe: "Mercado después disparador",
+    qtyLabel: "Cantidad ({u})",
+    transferTitle: "Transferir",
+    openLong: "Comprar / Long",
+    openShort: "Vender / Short",
+    contractInfoTitle: "Info contrato",
+    indexSource: "Fuentes índice",
+    marginCoin: "Activo margen",
+    maxLeverage: "Apalancamiento máx",
+    maintMargin: "Tasa margen mantenimiento",
+    openFee: "Comisión apertura",
+    closeFee: "Comisión cierre",
+    contractValue: "Valor contrato",
+    minOrder: "Mín. orden",
+    maxOrder: "Máx. orden",
   },
   placeholders: {
-    searchPair: 'Buscar',
-    triggerPrice: 'Ingresar precio disparador',
-    price: 'Ingresar precio',
-    amount: 'Ingresar cantidad',
+    searchPair: "Buscar",
+    triggerPrice: "Ingresar precio disparador",
+    price: "Ingresar precio",
+    amount: "Ingresar cantidad",
   },
   bottom: {
-    positions: 'Posiciones',
-    openOrders: 'Órdenes abiertas',
-    historyOrders: 'Historial órdenes',
-    historyPositions: 'Historial posiciones',
-    tradeDetails: 'Operaciones',
-    fundingFlow: 'Flujo fondos',
-    assets: 'Activos',
-    closeAllPositions: 'Cerrar todas',
-    cancelAllOrders: 'Cancelar todas',
-    loginPromptOr: 'o',
-    registerNow: 'Registrarse',
-    startTrading: 'para operar',
+    positions: "Posiciones",
+    openOrders: "Órdenes abiertas",
+    historyOrders: "Historial órdenes",
+    historyPositions: "Historial posiciones",
+    tradeDetails: "Operaciones",
+    fundingFlow: "Flujo fondos",
+    assets: "Activos",
+    closeAllPositions: "Cerrar todas",
+    cancelAllOrders: "Cancelar todas",
+    loginPromptOr: "o",
+    registerNow: "Registrarse",
+    startTrading: "para operar",
   },
   table: {
-    contract: 'Contrato',
-    dirLeverage: 'Dir./Ap.',
-    openPrice: 'Apertura',
-    markPrice: 'Marca',
-    positionSize: 'Tamaño',
-    margin: 'Margen',
-    marginRate: 'Tasa margen',
-    unrealizedPnl: 'PnL no realizado',
-    roe: 'ROE',
-    liqPrice: 'Precio liquidación',
-    openTime: 'Hora apertura',
-    action: 'Acción',
-    type: 'Tipo',
-    orderPrice: 'Precio',
-    entrustPriceHist: 'Precio orden',
-    triggerPrice: 'Disparador',
-    orderAmt: 'Cantidad orden',
-    filled: 'Ejecutada',
-    tpPrice: 'Take profit',
-    slPrice: 'Stop loss',
-    time: 'Hora',
-    orderTime: 'Hora orden',
-    fillTime: 'Hora ejecución',
-    profitUsdt: 'PnL (USDT)',
-    tradedVol: 'Cantidad ejecutada',
-    closeAvg: 'Media cierre',
-    profitRate: 'ROE',
-    closeTime: 'Hora cierre',
-    directionOpenClose: 'Lado/A-C',
-    dealPrice: 'Precio ejecución',
-    fee: 'Comisión',
-    fundType: 'Tipo',
-    amount: 'Cantidad',
-    coin: 'Moneda',
-    settlementTime: 'Liquidación',
-    fundingRate: 'Tasa financiación',
-    totalBal: 'Saldo futuros',
-    availMargin: 'Margen disponible',
-    usedMargin: 'Margen usado',
-    unrealized: 'PnL no realizado',
-    spotWalletBal: 'Saldo cuenta retirable',
-    fundTransfer: 'Transferir',
-    avgOpenPrice: 'Media apertura',
-    feeHint: 'Comisión (USDT)',
-    estimatedPnlRow: 'PnL estimado',
-    triggerUsdt: 'Disparador (USDT)',
-    orderPriceUsdt: 'Precio orden (USDT)',
-    openAvgUsdt: 'Media entrada (USDT)',
-    closeAvgUsdt: 'Media salida (USDT)',
-    tpUsdt: 'TP (USDT)',
-    slUsdt: 'SL (USDT)',
-    marginUsdtBracket: 'Margen (USDT)',
-    notionalUsdt: 'Valor posición (USDT)',
-    estLiqPx: 'Liq. estimada',
-    profitBracketUsdt: 'PnL (USDT)',
-    entrustVolCoin: 'Orden ({base})',
-    filledVolCoin: 'Ejecutada ({base})',
-    closeAvail: 'Cerrable:',
-    markPriceBtn: 'Marca',
+    contract: "Contrato",
+    dirLeverage: "Dir./Ap.",
+    openPrice: "Apertura",
+    markPrice: "Marca",
+    positionSize: "Tamaño",
+    margin: "Margen",
+    marginRate: "Tasa margen",
+    unrealizedPnl: "PnL no realizado",
+    roe: "ROE",
+    liqPrice: "Precio liquidación",
+    openTime: "Hora apertura",
+    action: "Acción",
+    type: "Tipo",
+    orderPrice: "Precio",
+    entrustPriceHist: "Precio orden",
+    triggerPrice: "Disparador",
+    orderAmt: "Cantidad orden",
+    filled: "Ejecutada",
+    tpPrice: "Take profit",
+    slPrice: "Stop loss",
+    time: "Hora",
+    orderTime: "Hora orden",
+    fillTime: "Hora ejecución",
+    profitUsdt: "PnL (USDT)",
+    tradedVol: "Cantidad ejecutada",
+    closeAvg: "Media cierre",
+    profitRate: "ROE",
+    closeTime: "Hora cierre",
+    directionOpenClose: "Lado/A-C",
+    dealPrice: "Precio ejecución",
+    fee: "Comisión",
+    fundType: "Tipo",
+    amount: "Cantidad",
+    coin: "Moneda",
+    settlementTime: "Liquidación",
+    fundingRate: "Tasa financiación",
+    totalBal: "Saldo futuros",
+    availMargin: "Margen disponible",
+    usedMargin: "Margen usado",
+    unrealized: "PnL no realizado",
+    spotWalletBal: "Saldo cuenta retirable",
+    fundTransfer: "Transferir",
+    avgOpenPrice: "Media apertura",
+    feeHint: "Comisión (USDT)",
+    estimatedPnlRow: "PnL estimado",
+    triggerUsdt: "Disparador (USDT)",
+    orderPriceUsdt: "Precio orden (USDT)",
+    openAvgUsdt: "Media entrada (USDT)",
+    closeAvgUsdt: "Media salida (USDT)",
+    tpUsdt: "TP (USDT)",
+    slUsdt: "SL (USDT)",
+    marginUsdtBracket: "Margen (USDT)",
+    notionalUsdt: "Valor posición (USDT)",
+    estLiqPx: "Liq. estimada",
+    profitBracketUsdt: "PnL (USDT)",
+    entrustVolCoin: "Orden ({base})",
+    filledVolCoin: "Ejecutada ({base})",
+    closeAvail: "Cerrable:",
+    markPriceBtn: "Marca",
   },
   empty: {
-    noPositions: 'Sin posiciones',
-    noOrders: 'Sin órdenes',
-    noHistPositions: 'Sin historial posiciones',
-    noHistOrders: 'Sin historial órdenes',
-    noTradeRecords: 'Sin ejecuciones',
-    noFunding: 'Sin registros financiación',
+    noPositions: "Sin posiciones",
+    noOrders: "Sin órdenes",
+    noHistPositions: "Sin historial posiciones",
+    noHistOrders: "Sin historial órdenes",
+    noTradeRecords: "Sin ejecuciones",
+    noFunding: "Sin registros financiación",
   },
   modal: {
-    confirmDefaultTitle: 'Confirmar',
-    positionDetailTitle: 'Detalle posición',
-    orderDetailTitle: 'Detalle orden',
-    histPositionDetailTitle: 'Posición histórica',
-    histOrderDetailTitle: 'Orden histórica',
-    closePositionTitlePrefix: 'Cerrar',
-    modifyTpSl: 'Editar TP/SL',
-    setTpSl: 'Configurar TP/SL',
-    posQtyLabel: 'Tamaño:',
-    currentTpSlSection: 'Órdenes TP/SL activas',
-    modifyToSection: 'Cambiar a',
-    setPricesSection: 'Precios',
-    tpTriggerLabel: 'Disparador take-profit ',
-    tpHintOptionalClear: '(Vacío para borrar TP)',
-    slTriggerLabel: 'Disparador stop-loss ',
-    slHintOptionalClear: '(Vacío para borrar SL)',
-    placeholderTpTrigger: 'Precio disparador TP',
-    placeholderSlTrigger: 'Precio disparador SL',
-    confirmCloseBtn: 'Confirmar cierre',
-    ok: 'OK',
-    closeTypeLiquidation: 'Liquidado',
-    tpBadge: 'TP',
-    slBadge: 'SL',
-    tpPriceWord: 'TP ',
-    slPriceWord: 'SL ',
-    volLabel: 'Cantidad:',
-    marginSplitMode: 'Cruzado / Aislado',
-    directionLabel: 'Lado',
-    entrustTypeLabel: 'Tipo orden',
-    leverageLabel: 'Apalancamiento',
+    confirmDefaultTitle: "Confirmar",
+    positionDetailTitle: "Detalle posición",
+    orderDetailTitle: "Detalle orden",
+    histPositionDetailTitle: "Posición histórica",
+    histOrderDetailTitle: "Orden histórica",
+    closePositionTitlePrefix: "Cerrar",
+    modifyTpSl: "Editar TP/SL",
+    setTpSl: "Configurar TP/SL",
+    posQtyLabel: "Tamaño:",
+    currentTpSlSection: "Órdenes TP/SL activas",
+    modifyToSection: "Cambiar a",
+    setPricesSection: "Precios",
+    tpTriggerLabel: "Disparador take-profit ",
+    tpHintOptionalClear: "(Vacío para borrar TP)",
+    slTriggerLabel: "Disparador stop-loss ",
+    slHintOptionalClear: "(Vacío para borrar SL)",
+    placeholderTpTrigger: "Precio disparador TP",
+    placeholderSlTrigger: "Precio disparador SL",
+    confirmCloseBtn: "Confirmar cierre",
+    ok: "OK",
+    closeTypeLiquidation: "Liquidado",
+    tpBadge: "TP",
+    slBadge: "SL",
+    tpPriceWord: "TP ",
+    slPriceWord: "SL ",
+    volLabel: "Cantidad:",
+    marginSplitMode: "Cruzado / Aislado",
+    directionLabel: "Lado",
+    entrustTypeLabel: "Tipo orden",
+    leverageLabel: "Apalancamiento",
+  },
+  actions: {
+    tpSl: "TP/SL",
+    reverse: "Invertir",
+    close: "Cerrar",
+    marketCloseAll: "Cerrar todas mercado",
+    cancelOrder: "Cancelar",
   },
-  actions: { tpSl: 'TP/SL', reverse: 'Invertir', close: 'Cerrar', marketCloseAll: 'Cerrar todas mercado', cancelOrder: 'Cancelar' },
-  positionRow: { hintCross: 'Cruzado', hintExperience: 'Bonus' },
+  positionRow: { hintCross: "Cruzado", hintExperience: "Bonus" },
   errors: {
-    enterTriggerPrice: 'Ingresar precio disparador',
-    enterPrice: 'Ingresar precio',
-    priceNotReadyConvert: 'Precio no disponible — no se puede convertir',
-    invalidQtyCheckMin: 'Cantidad inválida — revisar mínimo',
-    priceNotReadyRetry: 'Precio no disponible, inténtelo de nuevo',
-    enterQty: 'Ingresar cantidad',
-    qtyExceedAvail: 'Cantidad excede límite cierre',
-    closeFailed: 'Error al cerrar',
-    modifyTpSlFailed: 'Error al actualizar — inténtelo más tarde',
-    txFallback: 'Tipo {n}',
+    enterTriggerPrice: "Ingresar precio disparador",
+    enterPrice: "Ingresar precio",
+    priceNotReadyConvert: "Precio no disponible — no se puede convertir",
+    invalidQtyCheckMin: "Cantidad inválida — revisar mínimo",
+    priceNotReadyRetry: "Precio no disponible, inténtelo de nuevo",
+    enterQty: "Ingresar cantidad",
+    qtyExceedAvail: "Cantidad excede límite cierre",
+    closeFailed: "Error al cerrar",
+    modifyTpSlFailed: "Error al actualizar — inténtelo más tarde",
+    txFallback: "Tipo {n}",
   },
   confirm: {
-    reverseTitle: 'Invertir posición',
-    reverseBody: 'Invertir {pair} {side}?',
-    cancelAllTitle: 'Cancelar todas',
-    cancelAllBody: 'Cancelar {n} órdenes?',
-    closeAllTitle: 'Cerrar todas',
-    closeAllBody: 'Cerrar {n} posiciones en mercado?',
-    sideLongWord: 'long',
-    sideShortWord: 'short',
+    reverseTitle: "Invertir posición",
+    reverseBody: "Invertir {pair} {side}?",
+    cancelAllTitle: "Cancelar todas",
+    cancelAllBody: "Cancelar {n} órdenes?",
+    closeAllTitle: "Cerrar todas",
+    closeAllBody: "Cerrar {n} posiciones en mercado?",
+    sideLongWord: "long",
+    sideShortWord: "short",
   },
   directions: {
-    long: 'Long',
-    short: 'Short',
-    openLong: 'Abrir long',
-    openShort: 'Abrir short',
-    closeShort: 'Cerrar short',
-    closeLong: 'Cerrar long',
-    openTag: 'A',
-    closeTag: 'C',
+    long: "Long",
+    short: "Short",
+    openLong: "Abrir long",
+    openShort: "Abrir short",
+    closeShort: "Cerrar short",
+    closeLong: "Cerrar long",
+    openTag: "A",
+    closeTag: "C",
+  },
+  orderTypes: {
+    limit: "Límite",
+    plan: "Disparador",
+    takeProfit: "Take profit",
+    stopLoss: "Stop loss",
+    marketShort: "Mercado",
+  },
+  orderStatus: {
+    filled: "Ejecutada",
+    open: "Abierta",
+    cancelled: "Cancelada",
+    failed: "Fallida",
   },
-  orderTypes: { limit: 'Límite', plan: 'Disparador', takeProfit: 'Take profit', stopLoss: 'Stop loss', marketShort: 'Mercado' },
-  orderStatus: { filled: 'Ejecutada', open: 'Abierta', cancelled: 'Cancelada', failed: 'Fallida' },
   closeTypes: {
-    market: 'Cierre mercado',
-    oneClick: 'Cierre un clic',
-    reverseOpen: 'Abrir opuesta',
-    tpSl: 'TP/SL',
-    liquidation: 'Liquidación',
-    admin: 'Cierre admin',
+    market: "Cierre mercado",
+    oneClick: "Cierre un clic",
+    reverseOpen: "Abrir opuesta",
+    tpSl: "TP/SL",
+    liquidation: "Liquidación",
+    admin: "Cierre admin",
   },
-}
+};

+ 6 - 0
code/src/locales/futuresPage/overlays/fr.ts

@@ -4,6 +4,12 @@ export const frUiOverlay: DeepPartial<FuturesPageMessages> = {
   perpetual: 'Contrats perpétuels',
   perpetualTag: 'Perpétuel',
   pairSearchPlaceholder: 'Rechercher',
+  pairSearchTag: {
+    oneType: 'Crypto',
+    twoType: 'Actions',
+    threeType: 'Métaux',
+    fourType: 'Forex',
+  },
   pairEmpty: 'Aucun résultat',
   stats: {
     change24h: 'Variation 24h',

+ 260 - 233
code/src/locales/futuresPage/overlays/hi.ts

@@ -1,268 +1,295 @@
-import type { DeepPartial, FuturesPageMessages } from '../../futuresPage.i18n'
+import type { DeepPartial, FuturesPageMessages } from "../../futuresPage.i18n";
 
 /** 合约页 UI:在 buildEn 基础上覆盖为印地语 */
 export const hiUiOverlay: DeepPartial<FuturesPageMessages> = {
-  perpetual: 'परपेचुअल कॉन्ट्रैक्ट',
-  perpetualTag: 'परपेचुअल',
-  pairSearchPlaceholder: 'खोजें',
-  pairEmpty: 'कोई पेयर नहीं',
+  perpetual: "परपेचुअल कॉन्ट्रैक्ट",
+  perpetualTag: "परपेचुअल",
+  pairSearchPlaceholder: "खोजें",
+  pairSearchTag: {
+    oneType: "क्रिप्टोकरेंसी",
+    twoType: "स्टॉक",
+    threeType: "कीमती धातुएं",
+    fourType: "विदेशी मुद्रा",
+  },
+  pairEmpty: "कोई पेयर नहीं",
   stats: {
-    change24h: '24घं परिवर्तन',
-    markPrice: 'मार्क',
-    high24h: '24घं उच्च',
-    low24h: '24घं निम्न',
-    volume24h: '24घं वॉल्यूम',
-    fundingCountdown: 'फंडिंग / काउंटडाउन',
+    change24h: "24घं परिवर्तन",
+    markPrice: "मार्क",
+    high24h: "24घं उच्च",
+    low24h: "24घं निम्न",
+    volume24h: "24घं वॉल्यूम",
+    fundingCountdown: "फंडिंग / काउंटडाउन",
+  },
+  mobileTabs: { chart: "चार्ट", trade: "ट्रेड" },
+  chartSub: {
+    chart: "चार्ट",
+    coinInfo: "कॉइन जानकारी",
+    fundingHistory: "फंडिंग इतिहास",
   },
-  mobileTabs: { chart: 'चार्ट', trade: 'ट्रेड' },
-  chartSub: { chart: 'चार्ट', coinInfo: 'कॉइन जानकारी', fundingHistory: 'फंडिंग इतिहास' },
-  chartTools: { fullscreen: 'पूर्ण स्क्रीन', alert: 'अलर्ट' },
+  chartTools: { fullscreen: "पूर्ण स्क्रीन", alert: "अलर्ट" },
   draw: {
-    cursor: 'कर्सर',
-    trend: 'ट्रेंड लाइन',
-    hline: 'क्षैतिज',
-    ray: 'रे',
-    channel: 'चैनल',
-    fib: 'फिबोनाची',
-    text: 'टेक्स्ट',
-    clearAll: 'ड्रॉइंग साफ़',
-    zoomOut: 'ज़ूम आउट',
+    cursor: "कर्सर",
+    trend: "ट्रेंड लाइन",
+    hline: "क्षैतिज",
+    ray: "रे",
+    channel: "चैनल",
+    fib: "फिबोनाची",
+    text: "टेक्स्ट",
+    clearAll: "ड्रॉइंग साफ़",
+    zoomOut: "ज़ूम आउट",
   },
   ohlcv: {
-    open: 'खुला',
-    high: 'उच्च',
-    low: 'निम्न',
-    close: 'बंद',
-    volume: 'वॉल्यूम',
-    changePct: 'परिवर्तन',
-    amplitude: 'रेंज',
+    open: "खुला",
+    high: "उच्च",
+    low: "निम्न",
+    close: "बंद",
+    volume: "वॉल्यूम",
+    changePct: "परिवर्तन",
+    amplitude: "रेंज",
   },
   coinInfo: {
-    marketCap: 'मार्केट कैप',
-    circulating: 'परिचालन आपूर्ति',
-    issuePrice: 'जारी मूल्य',
-    ath: 'सर्वकालिक उच्च',
-    athDate: 'ATH तिथि',
-    whitepaper: 'व्हाइटपेपर',
-    empty: 'कॉइन जानकारी नहीं',
-    reload: 'पुनः लोड',
+    marketCap: "मार्केट कैप",
+    circulating: "परिचालन आपूर्ति",
+    issuePrice: "जारी मूल्य",
+    ath: "सर्वकालिक उच्च",
+    athDate: "ATH तिथि",
+    whitepaper: "व्हाइटपेपर",
+    empty: "कॉइन जानकारी नहीं",
+    reload: "पुनः लोड",
   },
   fundingPanel: {
-    rate: 'फंडिंग दर',
-    period: 'निपटान अवधि',
-    nextCountdown: 'अगला काउंटडाउन',
-    noChart: 'चार्ट डेटा नहीं',
-    settleTime: 'निपटान',
-    rateCol: 'फंडिंग दर',
-    empty7d: 'पिछले 7 दिन का डेटा नहीं',
+    rate: "फंडिंग दर",
+    period: "निपटान अवधि",
+    nextCountdown: "अगला काउंटडाउन",
+    noChart: "चार्ट डेटा नहीं",
+    settleTime: "निपटान",
+    rateCol: "फंडिंग दर",
+    empty7d: "पिछले 7 दिन का डेटा नहीं",
   },
   book: {
-    orderBook: 'ऑर्डर बुक',
-    trades: 'ट्रेड',
-    priceQuote: 'मूल्य (USDT)',
-    amountBase: 'मात्रा ({base})',
-    totalBase: 'कुल ({base})',
-    time: 'समय',
-    buy: 'खरीद',
-    sell: 'बिक्री',
-    buyRatio: 'खरीद {n}%',
-    sellRatio: '{n}% बिक्री',
-    noTrades: 'कोई ट्रेड नहीं',
+    orderBook: "ऑर्डर बुक",
+    trades: "ट्रेड",
+    priceQuote: "मूल्य (USDT)",
+    amountBase: "मात्रा ({base})",
+    totalBase: "कुल ({base})",
+    time: "समय",
+    buy: "खरीद",
+    sell: "बिक्री",
+    buyRatio: "खरीद {n}%",
+    sellRatio: "{n}% बिक्री",
+    noTrades: "कोई ट्रेड नहीं",
   },
-  margin: { cross: 'क्रॉस', split: 'आइसोलेटेड', experience: 'बोनस' },
-  amountUnit: { lots: 'कॉन्ट्रैक्ट', usdt: 'USDT' },
-  leverage: { adjustTitle: 'लेवरेज समायोजित' },
+  margin: { cross: "क्रॉस", split: "आइसोलेटेड", experience: "बोनस" },
+  amountUnit: { lots: "कॉन्ट्रैक्ट", usdt: "USDT" },
+  leverage: { adjustTitle: "लेवरेज समायोजित" },
   order: {
-    limit: 'लिमिट',
-    market: 'मार्केट',
-    conditional: 'सशर्त',
-    condMarket: 'सशर्त मार्केट',
-    condLimit: 'सशर्त लिमिट',
-    available: 'उपलब्ध',
-    maxOpen: 'अधिकतम खोलें',
-    triggerPriceLabel: 'ट्रिगर ({q})',
-    priceLabel: 'मूल्य ({q})',
-    latestBtn: 'नवीनतम',
-    marketExe: 'मार्केट',
-    condMarketExe: 'ट्रिगर के बाद मार्केट',
-    qtyLabel: 'मात्रा ({u})',
-    transferTitle: 'ट्रांसफर',
-    openLong: 'खरीद / लॉन्ग',
-    openShort: 'बिक्री / शॉर्ट',
-    contractInfoTitle: 'कॉन्ट्रैक्ट जानकारी',
-    indexSource: 'इंडेक्स स्रोत',
-    marginCoin: 'मार्जिन संपत्ति',
-    maxLeverage: 'अधिकतम लेवरेज',
-    maintMargin: 'रखरखाव मार्जिन दर',
-    openFee: 'खोलने की फीस',
-    closeFee: 'बंद करने की फीस',
-    contractValue: 'कॉन्ट्रैक्ट मूल्य',
-    minOrder: 'न्यूनतम ऑर्डर',
-    maxOrder: 'अधिकतम ऑर्डर',
+    limit: "लिमिट",
+    market: "मार्केट",
+    conditional: "सशर्त",
+    condMarket: "सशर्त मार्केट",
+    condLimit: "सशर्त लिमिट",
+    available: "उपलब्ध",
+    maxOpen: "अधिकतम खोलें",
+    triggerPriceLabel: "ट्रिगर ({q})",
+    priceLabel: "मूल्य ({q})",
+    latestBtn: "नवीनतम",
+    marketExe: "मार्केट",
+    condMarketExe: "ट्रिगर के बाद मार्केट",
+    qtyLabel: "मात्रा ({u})",
+    transferTitle: "ट्रांसफर",
+    openLong: "खरीद / लॉन्ग",
+    openShort: "बिक्री / शॉर्ट",
+    contractInfoTitle: "कॉन्ट्रैक्ट जानकारी",
+    indexSource: "इंडेक्स स्रोत",
+    marginCoin: "मार्जिन संपत्ति",
+    maxLeverage: "अधिकतम लेवरेज",
+    maintMargin: "रखरखाव मार्जिन दर",
+    openFee: "खोलने की फीस",
+    closeFee: "बंद करने की फीस",
+    contractValue: "कॉन्ट्रैक्ट मूल्य",
+    minOrder: "न्यूनतम ऑर्डर",
+    maxOrder: "अधिकतम ऑर्डर",
   },
   placeholders: {
-    searchPair: 'खोजें',
-    triggerPrice: 'ट्रिगर मूल्य दर्ज करें',
-    price: 'मूल्य दर्ज करें',
-    amount: 'मात्रा दर्ज करें',
+    searchPair: "खोजें",
+    triggerPrice: "ट्रिगर मूल्य दर्ज करें",
+    price: "मूल्य दर्ज करें",
+    amount: "मात्रा दर्ज करें",
   },
   bottom: {
-    positions: 'पोज़िशन',
-    openOrders: 'खुले ऑर्डर',
-    historyOrders: 'ऑर्डर इतिहास',
-    historyPositions: 'पोज़िशन इतिहास',
-    tradeDetails: 'ट्रेड',
-    fundingFlow: 'फंडिंग',
-    assets: 'संपत्ति',
-    closeAllPositions: 'सभी बंद',
-    cancelAllOrders: 'सभी रद्द',
-    loginPromptOr: 'या',
-    registerNow: 'अभी रजिस्टर',
-    startTrading: 'ट्रेड शुरू',
+    positions: "पोज़िशन",
+    openOrders: "खुले ऑर्डर",
+    historyOrders: "ऑर्डर इतिहास",
+    historyPositions: "पोज़िशन इतिहास",
+    tradeDetails: "ट्रेड",
+    fundingFlow: "फंडिंग",
+    assets: "संपत्ति",
+    closeAllPositions: "सभी बंद",
+    cancelAllOrders: "सभी रद्द",
+    loginPromptOr: "या",
+    registerNow: "अभी रजिस्टर",
+    startTrading: "ट्रेड शुरू",
   },
   table: {
-    contract: 'कॉन्ट्रैक्ट',
-    dirLeverage: 'दिशा/लेव',
-    openPrice: 'प्रवेश',
-    markPrice: 'मार्क',
-    positionSize: 'आकार',
-    margin: 'मार्जिन',
-    marginRate: 'मार्जिन दर',
-    unrealizedPnl: 'अप्राप्त PnL',
-    roe: 'ROE',
-    liqPrice: 'लिक्विडेशन',
-    openTime: 'प्रवेश समय',
-    action: 'कार्रवाई',
-    type: 'प्रकार',
-    orderPrice: 'मूल्य',
-    entrustPriceHist: 'ऑर्डर मूल्य',
-    triggerPrice: 'ट्रिगर',
-    orderAmt: 'ऑर्डर मात्रा',
-    filled: 'भरा',
-    tpPrice: 'टेक प्रॉफिट',
-    slPrice: 'स्टॉप लॉस',
-    time: 'समय',
-    orderTime: 'ऑर्डर समय',
-    fillTime: 'भरण समय',
-    profitUsdt: 'PnL (USDT)',
-    tradedVol: 'भरी मात्रा',
-    closeAvg: 'बंद औसत',
-    profitRate: 'ROE',
-    closeTime: 'बंद समय',
-    directionOpenClose: 'दिशा/खुला-बंद',
-    dealPrice: 'भरण मूल्य',
-    fee: 'शुल्क',
-    fundType: 'प्रकार',
-    amount: 'राशि',
-    coin: 'कॉइन',
-    settlementTime: 'निपटान',
-    fundingRate: 'फंडिंग दर',
-    totalBal: 'फ्यूचर्स बैलेंस',
-    availMargin: 'उपलब्ध मार्जिन',
-    usedMargin: 'उपयोग में मार्जिन',
-    unrealized: 'अप्राप्त PnL',
-    spotWalletBal: 'निकासी योग्य खाता शेष',
-    fundTransfer: 'ट्रांसफर',
-    avgOpenPrice: 'औसत प्रवेश',
-    feeHint: 'शुल्क (USDT)',
-    estimatedPnlRow: 'अनुमानित PnL',
-    triggerUsdt: 'ट्रिगर (USDT)',
-    orderPriceUsdt: 'ऑर्डर मूल्य (USDT)',
-    openAvgUsdt: 'औसत प्रवेश (USDT)',
-    closeAvgUsdt: 'औसत बंद (USDT)',
-    tpUsdt: 'TP (USDT)',
-    slUsdt: 'SL (USDT)',
-    marginUsdtBracket: 'मार्जिन (USDT)',
-    notionalUsdt: 'पोज़िशन मूल्य (USDT)',
-    estLiqPx: 'अनुमानित लिक्विडेशन',
-    profitBracketUsdt: 'PnL (USDT)',
-    entrustVolCoin: 'ऑर्डर ({base})',
-    filledVolCoin: 'भरा ({base})',
-    closeAvail: 'बंद करने योग्य:',
-    markPriceBtn: 'मार्क',
+    contract: "कॉन्ट्रैक्ट",
+    dirLeverage: "दिशा/लेव",
+    openPrice: "प्रवेश",
+    markPrice: "मार्क",
+    positionSize: "आकार",
+    margin: "मार्जिन",
+    marginRate: "मार्जिन दर",
+    unrealizedPnl: "अप्राप्त PnL",
+    roe: "ROE",
+    liqPrice: "लिक्विडेशन",
+    openTime: "प्रवेश समय",
+    action: "कार्रवाई",
+    type: "प्रकार",
+    orderPrice: "मूल्य",
+    entrustPriceHist: "ऑर्डर मूल्य",
+    triggerPrice: "ट्रिगर",
+    orderAmt: "ऑर्डर मात्रा",
+    filled: "भरा",
+    tpPrice: "टेक प्रॉफिट",
+    slPrice: "स्टॉप लॉस",
+    time: "समय",
+    orderTime: "ऑर्डर समय",
+    fillTime: "भरण समय",
+    profitUsdt: "PnL (USDT)",
+    tradedVol: "भरी मात्रा",
+    closeAvg: "बंद औसत",
+    profitRate: "ROE",
+    closeTime: "बंद समय",
+    directionOpenClose: "दिशा/खुला-बंद",
+    dealPrice: "भरण मूल्य",
+    fee: "शुल्क",
+    fundType: "प्रकार",
+    amount: "राशि",
+    coin: "कॉइन",
+    settlementTime: "निपटान",
+    fundingRate: "फंडिंग दर",
+    totalBal: "फ्यूचर्स बैलेंस",
+    availMargin: "उपलब्ध मार्जिन",
+    usedMargin: "उपयोग में मार्जिन",
+    unrealized: "अप्राप्त PnL",
+    spotWalletBal: "निकासी योग्य खाता शेष",
+    fundTransfer: "ट्रांसफर",
+    avgOpenPrice: "औसत प्रवेश",
+    feeHint: "शुल्क (USDT)",
+    estimatedPnlRow: "अनुमानित PnL",
+    triggerUsdt: "ट्रिगर (USDT)",
+    orderPriceUsdt: "ऑर्डर मूल्य (USDT)",
+    openAvgUsdt: "औसत प्रवेश (USDT)",
+    closeAvgUsdt: "औसत बंद (USDT)",
+    tpUsdt: "TP (USDT)",
+    slUsdt: "SL (USDT)",
+    marginUsdtBracket: "मार्जिन (USDT)",
+    notionalUsdt: "पोज़िशन मूल्य (USDT)",
+    estLiqPx: "अनुमानित लिक्विडेशन",
+    profitBracketUsdt: "PnL (USDT)",
+    entrustVolCoin: "ऑर्डर ({base})",
+    filledVolCoin: "भरा ({base})",
+    closeAvail: "बंद करने योग्य:",
+    markPriceBtn: "मार्क",
   },
   empty: {
-    noPositions: 'कोई पोज़िशन नहीं',
-    noOrders: 'कोई ऑर्डर नहीं',
-    noHistPositions: 'कोई पोज़िशन इतिहास नहीं',
-    noHistOrders: 'कोई ऑर्डर इतिहास नहीं',
-    noTradeRecords: 'कोई ट्रेड नहीं',
-    noFunding: 'कोई फंडिंग रिकॉर्ड नहीं',
+    noPositions: "कोई पोज़िशन नहीं",
+    noOrders: "कोई ऑर्डर नहीं",
+    noHistPositions: "कोई पोज़िशन इतिहास नहीं",
+    noHistOrders: "कोई ऑर्डर इतिहास नहीं",
+    noTradeRecords: "कोई ट्रेड नहीं",
+    noFunding: "कोई फंडिंग रिकॉर्ड नहीं",
   },
   modal: {
-    confirmDefaultTitle: 'पुष्टि',
-    positionDetailTitle: 'पोज़िशन विवरण',
-    orderDetailTitle: 'ऑर्डर विवरण',
-    histPositionDetailTitle: 'पिछली पोज़िशन',
-    histOrderDetailTitle: 'पिछला ऑर्डर',
-    closePositionTitlePrefix: 'बंद',
-    modifyTpSl: 'TP/SL संपादित',
-    setTpSl: 'TP/SL सेट',
-    posQtyLabel: 'मात्रा:',
-    currentTpSlSection: 'सक्रिय TP/SL',
-    modifyToSection: 'बदलें',
-    setPricesSection: 'मूल्य',
-    tpTriggerLabel: 'TP ट्रिगर ',
-    tpHintOptionalClear: '(खाली = TP हटाएं)',
-    slTriggerLabel: 'SL ट्रिगर ',
-    slHintOptionalClear: '(खाली = SL हटाएं)',
-    placeholderTpTrigger: 'TP ट्रिगर मूल्य',
-    placeholderSlTrigger: 'SL ट्रिगर मूल्य',
-    confirmCloseBtn: 'बंद की पुष्टि',
-    ok: 'ठीक',
-    closeTypeLiquidation: 'लिक्विडेट',
-    tpBadge: 'TP',
-    slBadge: 'SL',
-    tpPriceWord: 'TP ',
-    slPriceWord: 'SL ',
-    volLabel: 'मात्रा:',
-    marginSplitMode: 'क्रॉस / आइसोलेटेड',
-    directionLabel: 'दिशा',
-    entrustTypeLabel: 'ऑर्डर प्रकार',
-    leverageLabel: 'लेवरेज',
+    confirmDefaultTitle: "पुष्टि",
+    positionDetailTitle: "पोज़िशन विवरण",
+    orderDetailTitle: "ऑर्डर विवरण",
+    histPositionDetailTitle: "पिछली पोज़िशन",
+    histOrderDetailTitle: "पिछला ऑर्डर",
+    closePositionTitlePrefix: "बंद",
+    modifyTpSl: "TP/SL संपादित",
+    setTpSl: "TP/SL सेट",
+    posQtyLabel: "मात्रा:",
+    currentTpSlSection: "सक्रिय TP/SL",
+    modifyToSection: "बदलें",
+    setPricesSection: "मूल्य",
+    tpTriggerLabel: "TP ट्रिगर ",
+    tpHintOptionalClear: "(खाली = TP हटाएं)",
+    slTriggerLabel: "SL ट्रिगर ",
+    slHintOptionalClear: "(खाली = SL हटाएं)",
+    placeholderTpTrigger: "TP ट्रिगर मूल्य",
+    placeholderSlTrigger: "SL ट्रिगर मूल्य",
+    confirmCloseBtn: "बंद की पुष्टि",
+    ok: "ठीक",
+    closeTypeLiquidation: "लिक्विडेट",
+    tpBadge: "TP",
+    slBadge: "SL",
+    tpPriceWord: "TP ",
+    slPriceWord: "SL ",
+    volLabel: "मात्रा:",
+    marginSplitMode: "क्रॉस / आइसोलेटेड",
+    directionLabel: "दिशा",
+    entrustTypeLabel: "ऑर्डर प्रकार",
+    leverageLabel: "लेवरेज",
+  },
+  actions: {
+    tpSl: "TP/SL",
+    reverse: "रिवर्स",
+    close: "बंद",
+    marketCloseAll: "मार्केट सभी बंद",
+    cancelOrder: "रद्द",
   },
-  actions: { tpSl: 'TP/SL', reverse: 'रिवर्स', close: 'बंद', marketCloseAll: 'मार्केट सभी बंद', cancelOrder: 'रद्द' },
-  positionRow: { hintCross: 'क्रॉस', hintExperience: 'बोनस' },
+  positionRow: { hintCross: "क्रॉस", hintExperience: "बोनस" },
   errors: {
-    enterTriggerPrice: 'ट्रिगर मूल्य दर्ज करें',
-    enterPrice: 'मूल्य दर्ज करें',
-    priceNotReadyConvert: 'मूल्य तैयार नहीं — रूपांतरण नहीं',
-    invalidQtyCheckMin: 'अमान्य मात्रा — न्यूनतम जाँचें',
-    priceNotReadyRetry: 'मूल्य तैयार नहीं, पुनः प्रयास',
-    enterQty: 'मात्रा दर्ज करें',
-    qtyExceedAvail: 'बंद करने योग्य से अधिक',
-    closeFailed: 'बंद करना विफल',
-    modifyTpSlFailed: 'अपडेट विफल — बाद में प्रयास',
-    txFallback: 'प्रकार {n}',
+    enterTriggerPrice: "ट्रिगर मूल्य दर्ज करें",
+    enterPrice: "मूल्य दर्ज करें",
+    priceNotReadyConvert: "मूल्य तैयार नहीं — रूपांतरण नहीं",
+    invalidQtyCheckMin: "अमान्य मात्रा — न्यूनतम जाँचें",
+    priceNotReadyRetry: "मूल्य तैयार नहीं, पुनः प्रयास",
+    enterQty: "मात्रा दर्ज करें",
+    qtyExceedAvail: "बंद करने योग्य से अधिक",
+    closeFailed: "बंद करना विफल",
+    modifyTpSlFailed: "अपडेट विफल — बाद में प्रयास",
+    txFallback: "प्रकार {n}",
   },
   confirm: {
-    reverseTitle: 'पोज़िशन रिवर्स',
-    reverseBody: '{pair} {side} रिवर्स करें?',
-    cancelAllTitle: 'सभी रद्द',
-    cancelAllBody: '{n} ऑर्डर रद्द करें?',
-    closeAllTitle: 'सभी बंद',
-    closeAllBody: '{n} पोज़िशन मार्केट बंद?',
-    sideLongWord: 'लॉन्ग',
-    sideShortWord: 'शॉर्ट',
+    reverseTitle: "पोज़िशन रिवर्स",
+    reverseBody: "{pair} {side} रिवर्स करें?",
+    cancelAllTitle: "सभी रद्द",
+    cancelAllBody: "{n} ऑर्डर रद्द करें?",
+    closeAllTitle: "सभी बंद",
+    closeAllBody: "{n} पोज़िशन मार्केट बंद?",
+    sideLongWord: "लॉन्ग",
+    sideShortWord: "शॉर्ट",
   },
   directions: {
-    long: 'लॉन्ग',
-    short: 'शॉर्ट',
-    openLong: 'लॉन्ग खोलें',
-    openShort: 'शॉर्ट खोलें',
-    closeShort: 'शॉर्ट बंद',
-    closeLong: 'लॉन्ग बंद',
-    openTag: 'खु',
-    closeTag: 'बं',
+    long: "लॉन्ग",
+    short: "शॉर्ट",
+    openLong: "लॉन्ग खोलें",
+    openShort: "शॉर्ट खोलें",
+    closeShort: "शॉर्ट बंद",
+    closeLong: "लॉन्ग बंद",
+    openTag: "खु",
+    closeTag: "बं",
+  },
+  orderTypes: {
+    limit: "लिमिट",
+    plan: "ट्रिगर",
+    takeProfit: "TP",
+    stopLoss: "SL",
+    marketShort: "मार्केट",
+  },
+  orderStatus: {
+    filled: "भरा",
+    open: "खुला",
+    cancelled: "रद्द",
+    failed: "विफल",
   },
-  orderTypes: { limit: 'लिमिट', plan: 'ट्रिगर', takeProfit: 'TP', stopLoss: 'SL', marketShort: 'मार्केट' },
-  orderStatus: { filled: 'भरा', open: 'खुला', cancelled: 'रद्द', failed: 'विफल' },
   closeTypes: {
-    market: 'मार्केट बंद',
-    oneClick: 'एक क्लिक बंद',
-    reverseOpen: 'रिवर्स खोल',
-    tpSl: 'TP/SL',
-    liquidation: 'लिक्विडेशन',
-    admin: 'एडमिन बंद',
+    market: "मार्केट बंद",
+    oneClick: "एक क्लिक बंद",
+    reverseOpen: "रिवर्स खोल",
+    tpSl: "TP/SL",
+    liquidation: "लिक्विडेशन",
+    admin: "एडमिन बंद",
   },
-}
+};

+ 260 - 233
code/src/locales/futuresPage/overlays/id.ts

@@ -1,268 +1,295 @@
-import type { DeepPartial, FuturesPageMessages } from '../../futuresPage.i18n'
+import type { DeepPartial, FuturesPageMessages } from "../../futuresPage.i18n";
 
 /** 合约页 UI:在 buildEn 基础上覆盖为印尼语 */
 export const idUiOverlay: DeepPartial<FuturesPageMessages> = {
-  perpetual: 'Kontrak perpetual',
-  perpetualTag: 'Perpetual',
-  pairSearchPlaceholder: 'Cari',
-  pairEmpty: 'Tidak ada pasangan',
+  perpetual: "Kontrak perpetual",
+  perpetualTag: "Perpetual",
+  pairSearchPlaceholder: "Cari",
+  pairSearchTag: {
+    oneType: "Kripto",
+    twoType: "Saham",
+    threeType: "Logam Mulia",
+    fourType: "Forex",
+  },
+  pairEmpty: "Tidak ada pasangan",
   stats: {
-    change24h: 'Perubahan 24j',
-    markPrice: 'Mark',
-    high24h: 'Tertinggi 24j',
-    low24h: 'Terendah 24j',
-    volume24h: 'Volume 24j',
-    fundingCountdown: 'Funding / Hitung mundur',
+    change24h: "Perubahan 24j",
+    markPrice: "Mark",
+    high24h: "Tertinggi 24j",
+    low24h: "Terendah 24j",
+    volume24h: "Volume 24j",
+    fundingCountdown: "Funding / Hitung mundur",
+  },
+  mobileTabs: { chart: "Grafik", trade: "Trading" },
+  chartSub: {
+    chart: "Grafik",
+    coinInfo: "Info koin",
+    fundingHistory: "Riwayat funding",
   },
-  mobileTabs: { chart: 'Grafik', trade: 'Trading' },
-  chartSub: { chart: 'Grafik', coinInfo: 'Info koin', fundingHistory: 'Riwayat funding' },
-  chartTools: { fullscreen: 'Layar penuh', alert: 'Peringatan' },
+  chartTools: { fullscreen: "Layar penuh", alert: "Peringatan" },
   draw: {
-    cursor: 'Kursor',
-    trend: 'Garis tren',
-    hline: 'Horizontal',
-    ray: 'Sinar',
-    channel: 'Saluran',
-    fib: 'Fibonacci',
-    text: 'Teks',
-    clearAll: 'Hapus gambar',
-    zoomOut: 'Perkecil',
+    cursor: "Kursor",
+    trend: "Garis tren",
+    hline: "Horizontal",
+    ray: "Sinar",
+    channel: "Saluran",
+    fib: "Fibonacci",
+    text: "Teks",
+    clearAll: "Hapus gambar",
+    zoomOut: "Perkecil",
   },
   ohlcv: {
-    open: 'Buka',
-    high: 'Tinggi',
-    low: 'Rendah',
-    close: 'Tutup',
-    volume: 'Volume',
-    changePct: 'Perubahan',
-    amplitude: 'Rentang',
+    open: "Buka",
+    high: "Tinggi",
+    low: "Rendah",
+    close: "Tutup",
+    volume: "Volume",
+    changePct: "Perubahan",
+    amplitude: "Rentang",
   },
   coinInfo: {
-    marketCap: 'Kapitalisasi pasar',
-    circulating: 'Suplai beredar',
-    issuePrice: 'Harga terbit',
-    ath: 'Tertinggi sepanjang masa',
-    athDate: 'Tanggal ATH',
-    whitepaper: 'Whitepaper',
-    empty: 'Tidak ada info koin',
-    reload: 'Muat ulang',
+    marketCap: "Kapitalisasi pasar",
+    circulating: "Suplai beredar",
+    issuePrice: "Harga terbit",
+    ath: "Tertinggi sepanjang masa",
+    athDate: "Tanggal ATH",
+    whitepaper: "Whitepaper",
+    empty: "Tidak ada info koin",
+    reload: "Muat ulang",
   },
   fundingPanel: {
-    rate: 'Tingkat funding',
-    period: 'Periode penyelesaian',
-    nextCountdown: 'Hitung mundur berikut',
-    noChart: 'Tidak ada data grafik',
-    settleTime: 'Penyelesaian',
-    rateCol: 'Tingkat funding',
-    empty7d: 'Tidak ada data 7 hari',
+    rate: "Tingkat funding",
+    period: "Periode penyelesaian",
+    nextCountdown: "Hitung mundur berikut",
+    noChart: "Tidak ada data grafik",
+    settleTime: "Penyelesaian",
+    rateCol: "Tingkat funding",
+    empty7d: "Tidak ada data 7 hari",
   },
   book: {
-    orderBook: 'Buku order',
-    trades: 'Perdagangan',
-    priceQuote: 'Harga (USDT)',
-    amountBase: 'Jumlah ({base})',
-    totalBase: 'Total ({base})',
-    time: 'Waktu',
-    buy: 'Beli',
-    sell: 'Jual',
-    buyRatio: 'Beli {n}%',
-    sellRatio: '{n}% Jual',
-    noTrades: 'Tidak ada perdagangan',
+    orderBook: "Buku order",
+    trades: "Perdagangan",
+    priceQuote: "Harga (USDT)",
+    amountBase: "Jumlah ({base})",
+    totalBase: "Total ({base})",
+    time: "Waktu",
+    buy: "Beli",
+    sell: "Jual",
+    buyRatio: "Beli {n}%",
+    sellRatio: "{n}% Jual",
+    noTrades: "Tidak ada perdagangan",
   },
-  margin: { cross: 'Cross', split: 'Isolated', experience: 'Bonus' },
-  amountUnit: { lots: 'Kontrak', usdt: 'USDT' },
-  leverage: { adjustTitle: 'Sesuaikan leverage' },
+  margin: { cross: "Cross", split: "Isolated", experience: "Bonus" },
+  amountUnit: { lots: "Kontrak", usdt: "USDT" },
+  leverage: { adjustTitle: "Sesuaikan leverage" },
   order: {
-    limit: 'Limit',
-    market: 'Market',
-    conditional: 'Bersyarat',
-    condMarket: 'Market bersyarat',
-    condLimit: 'Limit bersyarat',
-    available: 'Tersedia',
-    maxOpen: 'Maks buka',
-    triggerPriceLabel: 'Pemicu ({q})',
-    priceLabel: 'Harga ({q})',
-    latestBtn: 'Terbaru',
-    marketExe: 'Market',
-    condMarketExe: 'Market setelah pemicu',
-    qtyLabel: 'Jumlah ({u})',
-    transferTitle: 'Transfer',
-    openLong: 'Beli / Long',
-    openShort: 'Jual / Short',
-    contractInfoTitle: 'Info kontrak',
-    indexSource: 'Sumber indeks',
-    marginCoin: 'Aset margin',
-    maxLeverage: 'Leverage maks',
-    maintMargin: 'Rasio margin pemeliharaan',
-    openFee: 'Biaya buka',
-    closeFee: 'Biaya tutup',
-    contractValue: 'Nilai kontrak',
-    minOrder: 'Order minimum',
-    maxOrder: 'Order maksimum',
+    limit: "Limit",
+    market: "Market",
+    conditional: "Bersyarat",
+    condMarket: "Market bersyarat",
+    condLimit: "Limit bersyarat",
+    available: "Tersedia",
+    maxOpen: "Maks buka",
+    triggerPriceLabel: "Pemicu ({q})",
+    priceLabel: "Harga ({q})",
+    latestBtn: "Terbaru",
+    marketExe: "Market",
+    condMarketExe: "Market setelah pemicu",
+    qtyLabel: "Jumlah ({u})",
+    transferTitle: "Transfer",
+    openLong: "Beli / Long",
+    openShort: "Jual / Short",
+    contractInfoTitle: "Info kontrak",
+    indexSource: "Sumber indeks",
+    marginCoin: "Aset margin",
+    maxLeverage: "Leverage maks",
+    maintMargin: "Rasio margin pemeliharaan",
+    openFee: "Biaya buka",
+    closeFee: "Biaya tutup",
+    contractValue: "Nilai kontrak",
+    minOrder: "Order minimum",
+    maxOrder: "Order maksimum",
   },
   placeholders: {
-    searchPair: 'Cari',
-    triggerPrice: 'Masukkan harga pemicu',
-    price: 'Masukkan harga',
-    amount: 'Masukkan jumlah',
+    searchPair: "Cari",
+    triggerPrice: "Masukkan harga pemicu",
+    price: "Masukkan harga",
+    amount: "Masukkan jumlah",
   },
   bottom: {
-    positions: 'Posisi',
-    openOrders: 'Order terbuka',
-    historyOrders: 'Riwayat order',
-    historyPositions: 'Riwayat posisi',
-    tradeDetails: 'Perdagangan',
-    fundingFlow: 'Arus dana',
-    assets: 'Aset',
-    closeAllPositions: 'Tutup semua',
-    cancelAllOrders: 'Batalkan semua',
-    loginPromptOr: 'atau',
-    registerNow: 'Daftar sekarang',
-    startTrading: 'mulai trading',
+    positions: "Posisi",
+    openOrders: "Order terbuka",
+    historyOrders: "Riwayat order",
+    historyPositions: "Riwayat posisi",
+    tradeDetails: "Perdagangan",
+    fundingFlow: "Arus dana",
+    assets: "Aset",
+    closeAllPositions: "Tutup semua",
+    cancelAllOrders: "Batalkan semua",
+    loginPromptOr: "atau",
+    registerNow: "Daftar sekarang",
+    startTrading: "mulai trading",
   },
   table: {
-    contract: 'Kontrak',
-    dirLeverage: 'Arah/Lev',
-    openPrice: 'Buka',
-    markPrice: 'Mark',
-    positionSize: 'Ukuran',
-    margin: 'Margin',
-    marginRate: 'Rasio margin',
-    unrealizedPnl: 'PnL belum terealisasi',
-    roe: 'ROE',
-    liqPrice: 'Harga likuidasi',
-    openTime: 'Waktu buka',
-    action: 'Aksi',
-    type: 'Jenis',
-    orderPrice: 'Harga',
-    entrustPriceHist: 'Harga order',
-    triggerPrice: 'Pemicu',
-    orderAmt: 'Jumlah order',
-    filled: 'Terisi',
-    tpPrice: 'Take profit',
-    slPrice: 'Stop loss',
-    time: 'Waktu',
-    orderTime: 'Waktu order',
-    fillTime: 'Waktu isi',
-    profitUsdt: 'PnL (USDT)',
-    tradedVol: 'Volume terisi',
-    closeAvg: 'Rata-rata tutup',
-    profitRate: 'ROE',
-    closeTime: 'Waktu tutup',
-    directionOpenClose: 'Arah/Buka-Tutup',
-    dealPrice: 'Harga isi',
-    fee: 'Biaya',
-    fundType: 'Jenis',
-    amount: 'Jumlah',
-    coin: 'Koin',
-    settlementTime: 'Penyelesaian',
-    fundingRate: 'Tingkat funding',
-    totalBal: 'Saldo futures',
-    availMargin: 'Margin tersedia',
-    usedMargin: 'Margin terpakai',
-    unrealized: 'PnL belum terealisasi',
-    spotWalletBal: 'Saldo akun dapat ditarik',
-    fundTransfer: 'Transfer',
-    avgOpenPrice: 'Rata-rata buka',
-    feeHint: 'Biaya (USDT)',
-    estimatedPnlRow: 'Perkiraan PnL',
-    triggerUsdt: 'Pemicu (USDT)',
-    orderPriceUsdt: 'Harga order (USDT)',
-    openAvgUsdt: 'Rata-rata buka (USDT)',
-    closeAvgUsdt: 'Rata-rata tutup (USDT)',
-    tpUsdt: 'TP (USDT)',
-    slUsdt: 'SL (USDT)',
-    marginUsdtBracket: 'Margin (USDT)',
-    notionalUsdt: 'Nilai posisi (USDT)',
-    estLiqPx: 'Perkiraan likuidasi',
-    profitBracketUsdt: 'PnL (USDT)',
-    entrustVolCoin: 'Order ({base})',
-    filledVolCoin: 'Terisi ({base})',
-    closeAvail: 'Dapat ditutup:',
-    markPriceBtn: 'Mark',
+    contract: "Kontrak",
+    dirLeverage: "Arah/Lev",
+    openPrice: "Buka",
+    markPrice: "Mark",
+    positionSize: "Ukuran",
+    margin: "Margin",
+    marginRate: "Rasio margin",
+    unrealizedPnl: "PnL belum terealisasi",
+    roe: "ROE",
+    liqPrice: "Harga likuidasi",
+    openTime: "Waktu buka",
+    action: "Aksi",
+    type: "Jenis",
+    orderPrice: "Harga",
+    entrustPriceHist: "Harga order",
+    triggerPrice: "Pemicu",
+    orderAmt: "Jumlah order",
+    filled: "Terisi",
+    tpPrice: "Take profit",
+    slPrice: "Stop loss",
+    time: "Waktu",
+    orderTime: "Waktu order",
+    fillTime: "Waktu isi",
+    profitUsdt: "PnL (USDT)",
+    tradedVol: "Volume terisi",
+    closeAvg: "Rata-rata tutup",
+    profitRate: "ROE",
+    closeTime: "Waktu tutup",
+    directionOpenClose: "Arah/Buka-Tutup",
+    dealPrice: "Harga isi",
+    fee: "Biaya",
+    fundType: "Jenis",
+    amount: "Jumlah",
+    coin: "Koin",
+    settlementTime: "Penyelesaian",
+    fundingRate: "Tingkat funding",
+    totalBal: "Saldo futures",
+    availMargin: "Margin tersedia",
+    usedMargin: "Margin terpakai",
+    unrealized: "PnL belum terealisasi",
+    spotWalletBal: "Saldo akun dapat ditarik",
+    fundTransfer: "Transfer",
+    avgOpenPrice: "Rata-rata buka",
+    feeHint: "Biaya (USDT)",
+    estimatedPnlRow: "Perkiraan PnL",
+    triggerUsdt: "Pemicu (USDT)",
+    orderPriceUsdt: "Harga order (USDT)",
+    openAvgUsdt: "Rata-rata buka (USDT)",
+    closeAvgUsdt: "Rata-rata tutup (USDT)",
+    tpUsdt: "TP (USDT)",
+    slUsdt: "SL (USDT)",
+    marginUsdtBracket: "Margin (USDT)",
+    notionalUsdt: "Nilai posisi (USDT)",
+    estLiqPx: "Perkiraan likuidasi",
+    profitBracketUsdt: "PnL (USDT)",
+    entrustVolCoin: "Order ({base})",
+    filledVolCoin: "Terisi ({base})",
+    closeAvail: "Dapat ditutup:",
+    markPriceBtn: "Mark",
   },
   empty: {
-    noPositions: 'Tidak ada posisi',
-    noOrders: 'Tidak ada order',
-    noHistPositions: 'Tidak ada riwayat posisi',
-    noHistOrders: 'Tidak ada riwayat order',
-    noTradeRecords: 'Tidak ada perdagangan',
-    noFunding: 'Tidak ada riwayat funding',
+    noPositions: "Tidak ada posisi",
+    noOrders: "Tidak ada order",
+    noHistPositions: "Tidak ada riwayat posisi",
+    noHistOrders: "Tidak ada riwayat order",
+    noTradeRecords: "Tidak ada perdagangan",
+    noFunding: "Tidak ada riwayat funding",
   },
   modal: {
-    confirmDefaultTitle: 'Konfirmasi',
-    positionDetailTitle: 'Detail posisi',
-    orderDetailTitle: 'Detail order',
-    histPositionDetailTitle: 'Posisi lama',
-    histOrderDetailTitle: 'Order lama',
-    closePositionTitlePrefix: 'Tutup',
-    modifyTpSl: 'Edit TP/SL',
-    setTpSl: 'Atur TP/SL',
-    posQtyLabel: 'Jumlah:',
-    currentTpSlSection: 'TP/SL aktif',
-    modifyToSection: 'Ubah ke',
-    setPricesSection: 'Harga',
-    tpTriggerLabel: 'Pemicu TP ',
-    tpHintOptionalClear: '(Kosongkan untuk hapus TP)',
-    slTriggerLabel: 'Pemicu SL ',
-    slHintOptionalClear: '(Kosongkan untuk hapus SL)',
-    placeholderTpTrigger: 'Harga pemicu TP',
-    placeholderSlTrigger: 'Harga pemicu SL',
-    confirmCloseBtn: 'Konfirmasi tutup',
-    ok: 'OK',
-    closeTypeLiquidation: 'Likuidasi',
-    tpBadge: 'TP',
-    slBadge: 'SL',
-    tpPriceWord: 'TP ',
-    slPriceWord: 'SL ',
-    volLabel: 'Jumlah:',
-    marginSplitMode: 'Cross / Isolated',
-    directionLabel: 'Arah',
-    entrustTypeLabel: 'Jenis order',
-    leverageLabel: 'Leverage',
+    confirmDefaultTitle: "Konfirmasi",
+    positionDetailTitle: "Detail posisi",
+    orderDetailTitle: "Detail order",
+    histPositionDetailTitle: "Posisi lama",
+    histOrderDetailTitle: "Order lama",
+    closePositionTitlePrefix: "Tutup",
+    modifyTpSl: "Edit TP/SL",
+    setTpSl: "Atur TP/SL",
+    posQtyLabel: "Jumlah:",
+    currentTpSlSection: "TP/SL aktif",
+    modifyToSection: "Ubah ke",
+    setPricesSection: "Harga",
+    tpTriggerLabel: "Pemicu TP ",
+    tpHintOptionalClear: "(Kosongkan untuk hapus TP)",
+    slTriggerLabel: "Pemicu SL ",
+    slHintOptionalClear: "(Kosongkan untuk hapus SL)",
+    placeholderTpTrigger: "Harga pemicu TP",
+    placeholderSlTrigger: "Harga pemicu SL",
+    confirmCloseBtn: "Konfirmasi tutup",
+    ok: "OK",
+    closeTypeLiquidation: "Likuidasi",
+    tpBadge: "TP",
+    slBadge: "SL",
+    tpPriceWord: "TP ",
+    slPriceWord: "SL ",
+    volLabel: "Jumlah:",
+    marginSplitMode: "Cross / Isolated",
+    directionLabel: "Arah",
+    entrustTypeLabel: "Jenis order",
+    leverageLabel: "Leverage",
+  },
+  actions: {
+    tpSl: "TP/SL",
+    reverse: "Balik",
+    close: "Tutup",
+    marketCloseAll: "Tutup semua market",
+    cancelOrder: "Batal",
   },
-  actions: { tpSl: 'TP/SL', reverse: 'Balik', close: 'Tutup', marketCloseAll: 'Tutup semua market', cancelOrder: 'Batal' },
-  positionRow: { hintCross: 'Cross', hintExperience: 'Bonus' },
+  positionRow: { hintCross: "Cross", hintExperience: "Bonus" },
   errors: {
-    enterTriggerPrice: 'Masukkan harga pemicu',
-    enterPrice: 'Masukkan harga',
-    priceNotReadyConvert: 'Harga belum siap — tidak dapat konversi',
-    invalidQtyCheckMin: 'Jumlah tidak valid — periksa minimum',
-    priceNotReadyRetry: 'Harga belum siap, coba lagi',
-    enterQty: 'Masukkan jumlah',
-    qtyExceedAvail: 'Melebihi jumlah yang dapat ditutup',
-    closeFailed: 'Gagal menutup',
-    modifyTpSlFailed: 'Gagal memperbarui — coba lagi',
-    txFallback: 'Jenis {n}',
+    enterTriggerPrice: "Masukkan harga pemicu",
+    enterPrice: "Masukkan harga",
+    priceNotReadyConvert: "Harga belum siap — tidak dapat konversi",
+    invalidQtyCheckMin: "Jumlah tidak valid — periksa minimum",
+    priceNotReadyRetry: "Harga belum siap, coba lagi",
+    enterQty: "Masukkan jumlah",
+    qtyExceedAvail: "Melebihi jumlah yang dapat ditutup",
+    closeFailed: "Gagal menutup",
+    modifyTpSlFailed: "Gagal memperbarui — coba lagi",
+    txFallback: "Jenis {n}",
   },
   confirm: {
-    reverseTitle: 'Balik posisi',
-    reverseBody: 'Balik posisi {pair} {side}?',
-    cancelAllTitle: 'Batalkan semua',
-    cancelAllBody: 'Batalkan {n} order?',
-    closeAllTitle: 'Tutup semua',
-    closeAllBody: 'Tutup {n} posisi di market?',
-    sideLongWord: 'long',
-    sideShortWord: 'short',
+    reverseTitle: "Balik posisi",
+    reverseBody: "Balik posisi {pair} {side}?",
+    cancelAllTitle: "Batalkan semua",
+    cancelAllBody: "Batalkan {n} order?",
+    closeAllTitle: "Tutup semua",
+    closeAllBody: "Tutup {n} posisi di market?",
+    sideLongWord: "long",
+    sideShortWord: "short",
   },
   directions: {
-    long: 'Long',
-    short: 'Short',
-    openLong: 'Buka long',
-    openShort: 'Buka short',
-    closeShort: 'Tutup short',
-    closeLong: 'Tutup long',
-    openTag: 'B',
-    closeTag: 'T',
+    long: "Long",
+    short: "Short",
+    openLong: "Buka long",
+    openShort: "Buka short",
+    closeShort: "Tutup short",
+    closeLong: "Tutup long",
+    openTag: "B",
+    closeTag: "T",
+  },
+  orderTypes: {
+    limit: "Limit",
+    plan: "Pemicu",
+    takeProfit: "Take profit",
+    stopLoss: "Stop loss",
+    marketShort: "Market",
+  },
+  orderStatus: {
+    filled: "Terisi",
+    open: "Terbuka",
+    cancelled: "Dibatalkan",
+    failed: "Gagal",
   },
-  orderTypes: { limit: 'Limit', plan: 'Pemicu', takeProfit: 'Take profit', stopLoss: 'Stop loss', marketShort: 'Market' },
-  orderStatus: { filled: 'Terisi', open: 'Terbuka', cancelled: 'Dibatalkan', failed: 'Gagal' },
   closeTypes: {
-    market: 'Tutup market',
-    oneClick: 'Tutup sekali klik',
-    reverseOpen: 'Buka berlawanan',
-    tpSl: 'TP/SL',
-    liquidation: 'Likuidasi',
-    admin: 'Tutup admin',
+    market: "Tutup market",
+    oneClick: "Tutup sekali klik",
+    reverseOpen: "Buka berlawanan",
+    tpSl: "TP/SL",
+    liquidation: "Likuidasi",
+    admin: "Tutup admin",
   },
-}
+};

+ 6 - 0
code/src/locales/futuresPage/overlays/ja.ts

@@ -5,6 +5,12 @@ export const jaUiOverlay: DeepPartial<FuturesPageMessages> = {
   perpetual: '無期限契約',
   perpetualTag: '永続',
   pairSearchPlaceholder: '検索',
+  pairSearchTag: {
+    oneType: '暗号資産',
+    twoType: '株式',
+    threeType: '貴金属',
+    fourType: '外国為替',
+  },
   pairEmpty: '該当ペアなし',
   stats: {
     change24h: '24h変動',

+ 260 - 233
code/src/locales/futuresPage/overlays/ko.ts

@@ -1,268 +1,295 @@
-import type { DeepPartial, FuturesPageMessages } from '../../futuresPage.i18n'
+import type { DeepPartial, FuturesPageMessages } from "../../futuresPage.i18n";
 
 /** 合约页 UI:在 buildEn 基础上覆盖为韩文 */
 export const koUiOverlay: DeepPartial<FuturesPageMessages> = {
-  perpetual: '영구 계약',
-  perpetualTag: '영구',
-  pairSearchPlaceholder: '검색',
-  pairEmpty: '일치하는 페어 없음',
+  perpetual: "영구 계약",
+  perpetualTag: "영구",
+  pairSearchPlaceholder: "검색",
+  pairSearchTag: {
+    oneType: "암호화폐",
+    twoType: "주식",
+    threeType: "귀금속",
+    fourType: "외환",
+  },
+  pairEmpty: "일치하는 페어 없음",
   stats: {
-    change24h: '24시간 변동',
-    markPrice: '마크',
-    high24h: '24시간 고가',
-    low24h: '24시간 저가',
-    volume24h: '24시간 거래량',
-    fundingCountdown: '펀딩비 / 카운트다운',
+    change24h: "24시간 변동",
+    markPrice: "마크",
+    high24h: "24시간 고가",
+    low24h: "24시간 저가",
+    volume24h: "24시간 거래량",
+    fundingCountdown: "펀딩비 / 카운트다운",
+  },
+  mobileTabs: { chart: "차트", trade: "거래" },
+  chartSub: {
+    chart: "차트",
+    coinInfo: "코인 정보",
+    fundingHistory: "펀딩비 내역",
   },
-  mobileTabs: { chart: '차트', trade: '거래' },
-  chartSub: { chart: '차트', coinInfo: '코인 정보', fundingHistory: '펀딩비 내역' },
-  chartTools: { fullscreen: '전체 화면', alert: '알림' },
+  chartTools: { fullscreen: "전체 화면", alert: "알림" },
   draw: {
-    cursor: '커서',
-    trend: '추세선',
-    hline: '수평선',
-    ray: '광선',
-    channel: '채널',
-    fib: '피보나치',
-    text: '텍스트',
-    clearAll: '그리기 지우기',
-    zoomOut: '축소',
+    cursor: "커서",
+    trend: "추세선",
+    hline: "수평선",
+    ray: "광선",
+    channel: "채널",
+    fib: "피보나치",
+    text: "텍스트",
+    clearAll: "그리기 지우기",
+    zoomOut: "축소",
   },
   ohlcv: {
-    open: '시',
-    high: '고',
-    low: '저',
-    close: '종',
-    volume: '거래량',
-    changePct: '변동',
-    amplitude: '진폭',
+    open: "시",
+    high: "고",
+    low: "저",
+    close: "종",
+    volume: "거래량",
+    changePct: "변동",
+    amplitude: "진폭",
   },
   coinInfo: {
-    marketCap: '시가총액',
-    circulating: '유통량',
-    issuePrice: '발행가',
-    ath: '역대 최고가',
-    athDate: '최고가 일자',
-    whitepaper: '백서',
-    empty: '코인 정보 없음',
-    reload: '다시 불러오기',
+    marketCap: "시가총액",
+    circulating: "유통량",
+    issuePrice: "발행가",
+    ath: "역대 최고가",
+    athDate: "최고가 일자",
+    whitepaper: "백서",
+    empty: "코인 정보 없음",
+    reload: "다시 불러오기",
   },
   fundingPanel: {
-    rate: '펀딩비율',
-    period: '정산 주기',
-    nextCountdown: '다음 카운트다운',
-    noChart: '차트 데이터 없음',
-    settleTime: '정산',
-    rateCol: '펀딩비율',
-    empty7d: '최근 7일 데이터 없음',
+    rate: "펀딩비율",
+    period: "정산 주기",
+    nextCountdown: "다음 카운트다운",
+    noChart: "차트 데이터 없음",
+    settleTime: "정산",
+    rateCol: "펀딩비율",
+    empty7d: "최근 7일 데이터 없음",
   },
   book: {
-    orderBook: '호가',
-    trades: '체결',
-    priceQuote: '가격 (USDT)',
-    amountBase: '수량 ({base})',
-    totalBase: '합계 ({base})',
-    time: '시간',
-    buy: '매수',
-    sell: '매도',
-    buyRatio: '매수 {n}%',
-    sellRatio: '{n}% 매도',
-    noTrades: '체결 없음',
+    orderBook: "호가",
+    trades: "체결",
+    priceQuote: "가격 (USDT)",
+    amountBase: "수량 ({base})",
+    totalBase: "합계 ({base})",
+    time: "시간",
+    buy: "매수",
+    sell: "매도",
+    buyRatio: "매수 {n}%",
+    sellRatio: "{n}% 매도",
+    noTrades: "체결 없음",
   },
-  margin: { cross: '교차', split: '격리', experience: '체험금' },
-  amountUnit: { lots: '계약', usdt: 'USDT' },
-  leverage: { adjustTitle: '레버리지 조정' },
+  margin: { cross: "교차", split: "격리", experience: "체험금" },
+  amountUnit: { lots: "계약", usdt: "USDT" },
+  leverage: { adjustTitle: "레버리지 조정" },
   order: {
-    limit: '지정가',
-    market: '시장가',
-    conditional: '조건부',
-    condMarket: '조건 시장가',
-    condLimit: '조건 지정가',
-    available: '사용 가능',
-    maxOpen: '최대 개시',
-    triggerPriceLabel: '트리거 ({q})',
-    priceLabel: '가격 ({q})',
-    latestBtn: '최신',
-    marketExe: '시장가',
-    condMarketExe: '트리거 후 시장가',
-    qtyLabel: '수량 ({u})',
-    transferTitle: '이체',
-    openLong: '매수 / 롱',
-    openShort: '매도 / 숏',
-    contractInfoTitle: '계약 정보',
-    indexSource: '지수 출처',
-    marginCoin: '증거금 자산',
-    maxLeverage: '최대 레버리지',
-    maintMargin: '유지 증거금률',
-    openFee: '개시 수수료',
-    closeFee: '청산 수수료',
-    contractValue: '계약 가치',
-    minOrder: '최소 주문량',
-    maxOrder: '최대 주문량',
+    limit: "지정가",
+    market: "시장가",
+    conditional: "조건부",
+    condMarket: "조건 시장가",
+    condLimit: "조건 지정가",
+    available: "사용 가능",
+    maxOpen: "최대 개시",
+    triggerPriceLabel: "트리거 ({q})",
+    priceLabel: "가격 ({q})",
+    latestBtn: "최신",
+    marketExe: "시장가",
+    condMarketExe: "트리거 후 시장가",
+    qtyLabel: "수량 ({u})",
+    transferTitle: "이체",
+    openLong: "매수 / 롱",
+    openShort: "매도 / 숏",
+    contractInfoTitle: "계약 정보",
+    indexSource: "지수 출처",
+    marginCoin: "증거금 자산",
+    maxLeverage: "최대 레버리지",
+    maintMargin: "유지 증거금률",
+    openFee: "개시 수수료",
+    closeFee: "청산 수수료",
+    contractValue: "계약 가치",
+    minOrder: "최소 주문량",
+    maxOrder: "최대 주문량",
   },
   placeholders: {
-    searchPair: '검색',
-    triggerPrice: '트리거 가격 입력',
-    price: '가격 입력',
-    amount: '수량 입력',
+    searchPair: "검색",
+    triggerPrice: "트리거 가격 입력",
+    price: "가격 입력",
+    amount: "수량 입력",
   },
   bottom: {
-    positions: '포지션',
-    openOrders: '미체결',
-    historyOrders: '주문 내역',
-    historyPositions: '포지션 내역',
-    tradeDetails: '체결',
-    fundingFlow: '자금 흐름',
-    assets: '자산',
-    closeAllPositions: '전량 청산',
-    cancelAllOrders: '전량 취소',
-    loginPromptOr: '또는',
-    registerNow: '지금 가입',
-    startTrading: '거래 시작',
+    positions: "포지션",
+    openOrders: "미체결",
+    historyOrders: "주문 내역",
+    historyPositions: "포지션 내역",
+    tradeDetails: "체결",
+    fundingFlow: "자금 흐름",
+    assets: "자산",
+    closeAllPositions: "전량 청산",
+    cancelAllOrders: "전량 취소",
+    loginPromptOr: "또는",
+    registerNow: "지금 가입",
+    startTrading: "거래 시작",
   },
   table: {
-    contract: '계약',
-    dirLeverage: '방향/레버',
-    openPrice: '진입가',
-    markPrice: '마크',
-    positionSize: '수량',
-    margin: '증거금',
-    marginRate: '증거금률',
-    unrealizedPnl: '미실현 손익',
-    roe: 'ROE',
-    liqPrice: '청산가',
-    openTime: '진입 시간',
-    action: '작업',
-    type: '유형',
-    orderPrice: '가격',
-    entrustPriceHist: '주문가',
-    triggerPrice: '트리거',
-    orderAmt: '주문 수량',
-    filled: '체결',
-    tpPrice: '익절',
-    slPrice: '손절',
-    time: '시간',
-    orderTime: '주문 시간',
-    fillTime: '체결 시간',
-    profitUsdt: '손익 (USDT)',
-    tradedVol: '체결 수량',
-    closeAvg: '청산 평균',
-    profitRate: 'ROE',
-    closeTime: '청산 시간',
-    directionOpenClose: '방향/개폐',
-    dealPrice: '체결가',
-    fee: '수수료',
-    fundType: '유형',
-    amount: '금액',
-    coin: '코인',
-    settlementTime: '정산',
-    fundingRate: '펀딩비율',
-    totalBal: '계약 잔액',
-    availMargin: '사용 가능 증거금',
-    usedMargin: '사용 중 증거금',
-    unrealized: '미실현 손익',
-    spotWalletBal: '출금 가능 계정 잔액',
-    fundTransfer: '이체',
-    avgOpenPrice: '평균 진입',
-    feeHint: '수수료 (USDT)',
-    estimatedPnlRow: '예상 손익',
-    triggerUsdt: '트리거 (USDT)',
-    orderPriceUsdt: '주문가 (USDT)',
-    openAvgUsdt: '평균 진입 (USDT)',
-    closeAvgUsdt: '평균 청산 (USDT)',
-    tpUsdt: '익절 (USDT)',
-    slUsdt: '손절 (USDT)',
-    marginUsdtBracket: '증거금 (USDT)',
-    notionalUsdt: '포지션 가치 (USDT)',
-    estLiqPx: '예상 청산가',
-    profitBracketUsdt: '손익 (USDT)',
-    entrustVolCoin: '주문 수량 ({base})',
-    filledVolCoin: '체결 ({base})',
-    closeAvail: '청산 가능:',
-    markPriceBtn: '마크',
+    contract: "계약",
+    dirLeverage: "방향/레버",
+    openPrice: "진입가",
+    markPrice: "마크",
+    positionSize: "수량",
+    margin: "증거금",
+    marginRate: "증거금률",
+    unrealizedPnl: "미실현 손익",
+    roe: "ROE",
+    liqPrice: "청산가",
+    openTime: "진입 시간",
+    action: "작업",
+    type: "유형",
+    orderPrice: "가격",
+    entrustPriceHist: "주문가",
+    triggerPrice: "트리거",
+    orderAmt: "주문 수량",
+    filled: "체결",
+    tpPrice: "익절",
+    slPrice: "손절",
+    time: "시간",
+    orderTime: "주문 시간",
+    fillTime: "체결 시간",
+    profitUsdt: "손익 (USDT)",
+    tradedVol: "체결 수량",
+    closeAvg: "청산 평균",
+    profitRate: "ROE",
+    closeTime: "청산 시간",
+    directionOpenClose: "방향/개폐",
+    dealPrice: "체결가",
+    fee: "수수료",
+    fundType: "유형",
+    amount: "금액",
+    coin: "코인",
+    settlementTime: "정산",
+    fundingRate: "펀딩비율",
+    totalBal: "계약 잔액",
+    availMargin: "사용 가능 증거금",
+    usedMargin: "사용 중 증거금",
+    unrealized: "미실현 손익",
+    spotWalletBal: "출금 가능 계정 잔액",
+    fundTransfer: "이체",
+    avgOpenPrice: "평균 진입",
+    feeHint: "수수료 (USDT)",
+    estimatedPnlRow: "예상 손익",
+    triggerUsdt: "트리거 (USDT)",
+    orderPriceUsdt: "주문가 (USDT)",
+    openAvgUsdt: "평균 진입 (USDT)",
+    closeAvgUsdt: "평균 청산 (USDT)",
+    tpUsdt: "익절 (USDT)",
+    slUsdt: "손절 (USDT)",
+    marginUsdtBracket: "증거금 (USDT)",
+    notionalUsdt: "포지션 가치 (USDT)",
+    estLiqPx: "예상 청산가",
+    profitBracketUsdt: "손익 (USDT)",
+    entrustVolCoin: "주문 수량 ({base})",
+    filledVolCoin: "체결 ({base})",
+    closeAvail: "청산 가능:",
+    markPriceBtn: "마크",
   },
   empty: {
-    noPositions: '포지션 없음',
-    noOrders: '주문 없음',
-    noHistPositions: '포지션 내역 없음',
-    noHistOrders: '주문 내역 없음',
-    noTradeRecords: '체결 없음',
-    noFunding: '자금 흐름 없음',
+    noPositions: "포지션 없음",
+    noOrders: "주문 없음",
+    noHistPositions: "포지션 내역 없음",
+    noHistOrders: "주문 내역 없음",
+    noTradeRecords: "체결 없음",
+    noFunding: "자금 흐름 없음",
   },
   modal: {
-    confirmDefaultTitle: '확인',
-    positionDetailTitle: '포지션 상세',
-    orderDetailTitle: '주문 상세',
-    histPositionDetailTitle: '과거 포지션',
-    histOrderDetailTitle: '과거 주문',
-    closePositionTitlePrefix: '청산',
-    modifyTpSl: 'TP/SL 수정',
-    setTpSl: 'TP/SL 설정',
-    posQtyLabel: '수량:',
-    currentTpSlSection: '활성 TP/SL',
-    modifyToSection: '변경',
-    setPricesSection: '가격',
-    tpTriggerLabel: '익절 트리거 ',
-    tpHintOptionalClear: '(비우면 익절 해제)',
-    slTriggerLabel: '손절 트리거 ',
-    slHintOptionalClear: '(비우면 손절 해제)',
-    placeholderTpTrigger: '익절 트리거 가격',
-    placeholderSlTrigger: '손절 트리거 가격',
-    confirmCloseBtn: '청산 확인',
-    ok: '확인',
-    closeTypeLiquidation: '강제 청산',
-    tpBadge: 'TP',
-    slBadge: 'SL',
-    tpPriceWord: '익절 ',
-    slPriceWord: '손절 ',
-    volLabel: '수량:',
-    marginSplitMode: '교차 / 격리',
-    directionLabel: '방향',
-    entrustTypeLabel: '주문 유형',
-    leverageLabel: '레버리지',
+    confirmDefaultTitle: "확인",
+    positionDetailTitle: "포지션 상세",
+    orderDetailTitle: "주문 상세",
+    histPositionDetailTitle: "과거 포지션",
+    histOrderDetailTitle: "과거 주문",
+    closePositionTitlePrefix: "청산",
+    modifyTpSl: "TP/SL 수정",
+    setTpSl: "TP/SL 설정",
+    posQtyLabel: "수량:",
+    currentTpSlSection: "활성 TP/SL",
+    modifyToSection: "변경",
+    setPricesSection: "가격",
+    tpTriggerLabel: "익절 트리거 ",
+    tpHintOptionalClear: "(비우면 익절 해제)",
+    slTriggerLabel: "손절 트리거 ",
+    slHintOptionalClear: "(비우면 손절 해제)",
+    placeholderTpTrigger: "익절 트리거 가격",
+    placeholderSlTrigger: "손절 트리거 가격",
+    confirmCloseBtn: "청산 확인",
+    ok: "확인",
+    closeTypeLiquidation: "강제 청산",
+    tpBadge: "TP",
+    slBadge: "SL",
+    tpPriceWord: "익절 ",
+    slPriceWord: "손절 ",
+    volLabel: "수량:",
+    marginSplitMode: "교차 / 격리",
+    directionLabel: "방향",
+    entrustTypeLabel: "주문 유형",
+    leverageLabel: "레버리지",
+  },
+  actions: {
+    tpSl: "TP/SL",
+    reverse: "반전",
+    close: "청산",
+    marketCloseAll: "시장가 전량 청산",
+    cancelOrder: "취소",
   },
-  actions: { tpSl: 'TP/SL', reverse: '반전', close: '청산', marketCloseAll: '시장가 전량 청산', cancelOrder: '취소' },
-  positionRow: { hintCross: '교차', hintExperience: '체험금' },
+  positionRow: { hintCross: "교차", hintExperience: "체험금" },
   errors: {
-    enterTriggerPrice: '트리거 가격을 입력하세요',
-    enterPrice: '가격을 입력하세요',
-    priceNotReadyConvert: '가격 미준비 — 수량 환산 불가',
-    invalidQtyCheckMin: '수량 오류 — 정밀도·최소 주문량 확인',
-    priceNotReadyRetry: '가격 미준비, 잠시 후 다시 시도',
-    enterQty: '수량을 입력하세요',
-    qtyExceedAvail: '청산 가능 수량 초과',
-    closeFailed: '청산 실패',
-    modifyTpSlFailed: '수정 실패 — 나중에 다시 시도',
-    txFallback: '유형 {n}',
+    enterTriggerPrice: "트리거 가격을 입력하세요",
+    enterPrice: "가격을 입력하세요",
+    priceNotReadyConvert: "가격 미준비 — 수량 환산 불가",
+    invalidQtyCheckMin: "수량 오류 — 정밀도·최소 주문량 확인",
+    priceNotReadyRetry: "가격 미준비, 잠시 후 다시 시도",
+    enterQty: "수량을 입력하세요",
+    qtyExceedAvail: "청산 가능 수량 초과",
+    closeFailed: "청산 실패",
+    modifyTpSlFailed: "수정 실패 — 나중에 다시 시도",
+    txFallback: "유형 {n}",
   },
   confirm: {
-    reverseTitle: '포지션 반전',
-    reverseBody: '{pair} {side} 포지션을 반전하시겠습니까?',
-    cancelAllTitle: '전량 취소',
-    cancelAllBody: '주문 {n}건을 취소하시겠습니까?',
-    closeAllTitle: '전량 청산',
-    closeAllBody: '포지션 {n}건을 시장가 청산하시겠습니까?',
-    sideLongWord: '롱',
-    sideShortWord: '숏',
+    reverseTitle: "포지션 반전",
+    reverseBody: "{pair} {side} 포지션을 반전하시겠습니까?",
+    cancelAllTitle: "전량 취소",
+    cancelAllBody: "주문 {n}건을 취소하시겠습니까?",
+    closeAllTitle: "전량 청산",
+    closeAllBody: "포지션 {n}건을 시장가 청산하시겠습니까?",
+    sideLongWord: "롱",
+    sideShortWord: "숏",
   },
   directions: {
-    long: '롱',
-    short: '숏',
-    openLong: '롱 진입',
-    openShort: '숏 진입',
-    closeShort: '숏 청산',
-    closeLong: '롱 청산',
-    openTag: '진',
-    closeTag: '청',
+    long: "롱",
+    short: "숏",
+    openLong: "롱 진입",
+    openShort: "숏 진입",
+    closeShort: "숏 청산",
+    closeLong: "롱 청산",
+    openTag: "진",
+    closeTag: "청",
+  },
+  orderTypes: {
+    limit: "지정가",
+    plan: "조건",
+    takeProfit: "익절",
+    stopLoss: "손절",
+    marketShort: "시장가",
+  },
+  orderStatus: {
+    filled: "체결",
+    open: "미체결",
+    cancelled: "취소됨",
+    failed: "실패",
   },
-  orderTypes: { limit: '지정가', plan: '조건', takeProfit: '익절', stopLoss: '손절', marketShort: '시장가' },
-  orderStatus: { filled: '체결', open: '미체결', cancelled: '취소됨', failed: '실패' },
   closeTypes: {
-    market: '시장가 청산',
-    oneClick: '일괄 청산',
-    reverseOpen: '반대 진입',
-    tpSl: 'TP/SL',
-    liquidation: '강제 청산',
-    admin: '관리자 청산',
+    market: "시장가 청산",
+    oneClick: "일괄 청산",
+    reverseOpen: "반대 진입",
+    tpSl: "TP/SL",
+    liquidation: "강제 청산",
+    admin: "관리자 청산",
   },
-}
+};

+ 260 - 233
code/src/locales/futuresPage/overlays/pt.ts

@@ -1,267 +1,294 @@
-import type { DeepPartial, FuturesPageMessages } from '../../futuresPage.i18n'
+import type { DeepPartial, FuturesPageMessages } from "../../futuresPage.i18n";
 
 export const ptUiOverlay: DeepPartial<FuturesPageMessages> = {
-  perpetual: 'Contrato Perpétuo',
-  perpetualTag: 'Perpétuo',
-  pairSearchPlaceholder: 'Buscar',
-  pairEmpty: 'Sem resultados',
+  perpetual: "Contrato Perpétuo",
+  perpetualTag: "Perpétuo",
+  pairSearchPlaceholder: "Buscar",
+  pairSearchTag: {
+    oneType: "Cripto",
+    twoType: "Ações",
+    threeType: "Metais",
+    fourType: "Forex",
+  },
+  pairEmpty: "Sem resultados",
   stats: {
-    change24h: 'Variação 24h',
-    markPrice: 'Preço marca',
-    high24h: 'Máx 24h',
-    low24h: 'Mín 24h',
-    volume24h: 'Volume 24h',
-    fundingCountdown: 'Funding / Contagem regressiva',
+    change24h: "Variação 24h",
+    markPrice: "Preço marca",
+    high24h: "Máx 24h",
+    low24h: "Mín 24h",
+    volume24h: "Volume 24h",
+    fundingCountdown: "Funding / Contagem regressiva",
+  },
+  mobileTabs: { chart: "Gráfico", trade: "Negociar" },
+  chartSub: {
+    chart: "Gráfico",
+    coinInfo: "Info moeda",
+    fundingHistory: "Histórico funding",
   },
-  mobileTabs: { chart: 'Gráfico', trade: 'Negociar' },
-  chartSub: { chart: 'Gráfico', coinInfo: 'Info moeda', fundingHistory: 'Histórico funding' },
-  chartTools: { fullscreen: 'Tela cheia', alert: 'Alertas' },
+  chartTools: { fullscreen: "Tela cheia", alert: "Alertas" },
   draw: {
-    cursor: 'Cursor',
-    trend: 'Linha de tendência',
-    hline: 'Horizontal',
-    ray: 'Raio',
-    channel: 'Canal',
-    fib: 'Fibonacci',
-    text: 'Texto',
-    clearAll: 'Apagar desenhos',
-    zoomOut: 'Afastar',
+    cursor: "Cursor",
+    trend: "Linha de tendência",
+    hline: "Horizontal",
+    ray: "Raio",
+    channel: "Canal",
+    fib: "Fibonacci",
+    text: "Texto",
+    clearAll: "Apagar desenhos",
+    zoomOut: "Afastar",
   },
   ohlcv: {
-    open: 'Abert',
-    high: 'Máx',
-    low: 'Mín',
-    close: 'Fech',
-    volume: 'Volume',
-    changePct: 'Variação',
-    amplitude: 'Amplitude',
+    open: "Abert",
+    high: "Máx",
+    low: "Mín",
+    close: "Fech",
+    volume: "Volume",
+    changePct: "Variação",
+    amplitude: "Amplitude",
   },
   coinInfo: {
-    marketCap: 'Cap mercado',
-    circulating: 'Oferta circulante',
-    issuePrice: 'Preço emissão',
-    ath: 'Máximo histórico',
-    athDate: 'Data ATH',
-    whitepaper: 'Whitepaper',
-    empty: 'Sem dados da moeda',
-    reload: 'Recarregar',
+    marketCap: "Cap mercado",
+    circulating: "Oferta circulante",
+    issuePrice: "Preço emissão",
+    ath: "Máximo histórico",
+    athDate: "Data ATH",
+    whitepaper: "Whitepaper",
+    empty: "Sem dados da moeda",
+    reload: "Recarregar",
   },
   fundingPanel: {
-    rate: 'Taxa funding',
-    period: 'Período liquidação',
-    nextCountdown: 'Próxima contagem',
-    noChart: 'Sem dados gráfico',
-    settleTime: 'Liquidação',
-    rateCol: 'Taxa funding',
-    empty7d: 'Sem dados 7 dias',
+    rate: "Taxa funding",
+    period: "Período liquidação",
+    nextCountdown: "Próxima contagem",
+    noChart: "Sem dados gráfico",
+    settleTime: "Liquidação",
+    rateCol: "Taxa funding",
+    empty7d: "Sem dados 7 dias",
   },
   book: {
-    orderBook: 'Livro de ordens',
-    trades: 'Negociações',
-    priceQuote: 'Preço (USDT)',
-    amountBase: 'Quant. ({base})',
-    totalBase: 'Total ({base})',
-    time: 'Horário',
-    buy: 'Compra',
-    sell: 'Venda',
-    buyRatio: 'Compra {n}%',
-    sellRatio: '{n}% Venda',
-    noTrades: 'Sem negociações',
+    orderBook: "Livro de ordens",
+    trades: "Negociações",
+    priceQuote: "Preço (USDT)",
+    amountBase: "Quant. ({base})",
+    totalBase: "Total ({base})",
+    time: "Horário",
+    buy: "Compra",
+    sell: "Venda",
+    buyRatio: "Compra {n}%",
+    sellRatio: "{n}% Venda",
+    noTrades: "Sem negociações",
   },
-  margin: { cross: 'Cruzada', split: 'Isolada', experience: 'Bônus' },
-  amountUnit: { lots: 'Contrato', usdt: 'USDT' },
-  leverage: { adjustTitle: 'Ajustar alavancagem' },
+  margin: { cross: "Cruzada", split: "Isolada", experience: "Bônus" },
+  amountUnit: { lots: "Contrato", usdt: "USDT" },
+  leverage: { adjustTitle: "Ajustar alavancagem" },
   order: {
-    limit: 'Limite',
-    market: 'Mercado',
-    conditional: 'Condicional',
-    condMarket: 'Mercado condicional',
-    condLimit: 'Limite condicional',
-    available: 'Disponível',
-    maxOpen: 'Máx abrir',
-    triggerPriceLabel: 'Gatilho ({q})',
-    priceLabel: 'Preço ({q})',
-    latestBtn: 'Último',
-    marketExe: 'Mercado',
-    condMarketExe: 'Mercado após gatilho',
-    qtyLabel: 'Quant. ({u})',
-    transferTitle: 'Transferir',
-    openLong: 'Comprar / Long',
-    openShort: 'Vender / Short',
-    contractInfoTitle: 'Info contrato',
-    indexSource: 'Fonte índice',
-    marginCoin: 'Ativo margem',
-    maxLeverage: 'Alavancagem máx',
-    maintMargin: 'Taxa margem manutenção',
-    openFee: 'Taxa abertura',
-    closeFee: 'Taxa fechamento',
-    contractValue: 'Valor contrato',
-    minOrder: 'Mín ordem',
-    maxOrder: 'Máx ordem',
+    limit: "Limite",
+    market: "Mercado",
+    conditional: "Condicional",
+    condMarket: "Mercado condicional",
+    condLimit: "Limite condicional",
+    available: "Disponível",
+    maxOpen: "Máx abrir",
+    triggerPriceLabel: "Gatilho ({q})",
+    priceLabel: "Preço ({q})",
+    latestBtn: "Último",
+    marketExe: "Mercado",
+    condMarketExe: "Mercado após gatilho",
+    qtyLabel: "Quant. ({u})",
+    transferTitle: "Transferir",
+    openLong: "Comprar / Long",
+    openShort: "Vender / Short",
+    contractInfoTitle: "Info contrato",
+    indexSource: "Fonte índice",
+    marginCoin: "Ativo margem",
+    maxLeverage: "Alavancagem máx",
+    maintMargin: "Taxa margem manutenção",
+    openFee: "Taxa abertura",
+    closeFee: "Taxa fechamento",
+    contractValue: "Valor contrato",
+    minOrder: "Mín ordem",
+    maxOrder: "Máx ordem",
   },
   placeholders: {
-    searchPair: 'Buscar',
-    triggerPrice: 'Informe preço gatilho',
-    price: 'Informe preço',
-    amount: 'Informe quantidade',
+    searchPair: "Buscar",
+    triggerPrice: "Informe preço gatilho",
+    price: "Informe preço",
+    amount: "Informe quantidade",
   },
   bottom: {
-    positions: 'Posições',
-    openOrders: 'Ordens abertas',
-    historyOrders: 'Histórico ordens',
-    historyPositions: 'Histórico posições',
-    tradeDetails: 'Negociações',
-    fundingFlow: 'Movimento fundos',
-    assets: 'Ativos',
-    closeAllPositions: 'Fechar todas',
-    cancelAllOrders: 'Cancelar todas',
-    loginPromptOr: 'ou',
-    registerNow: 'Cadastre-se',
-    startTrading: 'iniciar negociação',
+    positions: "Posições",
+    openOrders: "Ordens abertas",
+    historyOrders: "Histórico ordens",
+    historyPositions: "Histórico posições",
+    tradeDetails: "Negociações",
+    fundingFlow: "Movimento fundos",
+    assets: "Ativos",
+    closeAllPositions: "Fechar todas",
+    cancelAllOrders: "Cancelar todas",
+    loginPromptOr: "ou",
+    registerNow: "Cadastre-se",
+    startTrading: "iniciar negociação",
   },
   table: {
-    contract: 'Contrato',
-    dirLeverage: 'Sent./Alav.',
-    openPrice: 'Abertura',
-    markPrice: 'Marca',
-    positionSize: 'Tamanho',
-    margin: 'Margem',
-    marginRate: 'Taxa margem',
-    unrealizedPnl: 'Lucro não realizado',
-    roe: 'ROE',
-    liqPrice: 'Preço liquidação',
-    openTime: 'Hora abertura',
-    action: 'Ação',
-    type: 'Tipo',
-    orderPrice: 'Preço ordem',
-    entrustPriceHist: 'Preço pedido',
-    triggerPrice: 'Gatilho',
-    orderAmt: 'Qtd ordem',
-    filled: 'Executado',
-    tpPrice: 'Take Profit',
-    slPrice: 'Stop Loss',
-    time: 'Hora',
-    orderTime: 'Hora ordem',
-    fillTime: 'Hora execução',
-    profitUsdt: 'Lucro (USDT)',
-    tradedVol: 'Qtd executada',
-    closeAvg: 'Média fech',
-    profitRate: 'ROE',
-    closeTime: 'Hora fechamento',
-    directionOpenClose: 'Sent./A-F',
-    dealPrice: 'Preço exec',
-    fee: 'Taxa',
-    fundType: 'Tipo',
-    amount: 'Quantidade',
-    coin: 'Moeda',
-    settlementTime: 'Liquidação',
-    fundingRate: 'Taxa funding',
-    totalBal: 'Saldo futuro',
-    availMargin: 'Margem disp',
-    usedMargin: 'Margem usada',
-    unrealized: 'Lucro não realizado',
-    spotWalletBal: 'Saldo sacável',
-    fundTransfer: 'Transferir',
-    avgOpenPrice: 'Média abertura',
-    feeHint: 'Taxa (USDT)',
-    estimatedPnlRow: 'Lucro estimado',
-    triggerUsdt: 'Gatilho (USDT)',
-    orderPriceUsdt: 'Preço ordem (USDT)',
-    openAvgUsdt: 'Média entrada (USDT)',
-    closeAvgUsdt: 'Média saída (USDT)',
-    tpUsdt: 'TP (USDT)',
-    slUsdt: 'SL (USDT)',
-    marginUsdtBracket: 'Margem (USDT)',
-    notionalUsdt: 'Valor posição (USDT)',
-    estLiqPx: 'Preço liq estimado',
-    profitBracketUsdt: 'Lucro (USDT)',
-    entrustVolCoin: 'Ordem ({base})',
-    filledVolCoin: 'Executado ({base})',
-    closeAvail: 'Fechável:',
-    markPriceBtn: 'Marca',
+    contract: "Contrato",
+    dirLeverage: "Sent./Alav.",
+    openPrice: "Abertura",
+    markPrice: "Marca",
+    positionSize: "Tamanho",
+    margin: "Margem",
+    marginRate: "Taxa margem",
+    unrealizedPnl: "Lucro não realizado",
+    roe: "ROE",
+    liqPrice: "Preço liquidação",
+    openTime: "Hora abertura",
+    action: "Ação",
+    type: "Tipo",
+    orderPrice: "Preço ordem",
+    entrustPriceHist: "Preço pedido",
+    triggerPrice: "Gatilho",
+    orderAmt: "Qtd ordem",
+    filled: "Executado",
+    tpPrice: "Take Profit",
+    slPrice: "Stop Loss",
+    time: "Hora",
+    orderTime: "Hora ordem",
+    fillTime: "Hora execução",
+    profitUsdt: "Lucro (USDT)",
+    tradedVol: "Qtd executada",
+    closeAvg: "Média fech",
+    profitRate: "ROE",
+    closeTime: "Hora fechamento",
+    directionOpenClose: "Sent./A-F",
+    dealPrice: "Preço exec",
+    fee: "Taxa",
+    fundType: "Tipo",
+    amount: "Quantidade",
+    coin: "Moeda",
+    settlementTime: "Liquidação",
+    fundingRate: "Taxa funding",
+    totalBal: "Saldo futuro",
+    availMargin: "Margem disp",
+    usedMargin: "Margem usada",
+    unrealized: "Lucro não realizado",
+    spotWalletBal: "Saldo sacável",
+    fundTransfer: "Transferir",
+    avgOpenPrice: "Média abertura",
+    feeHint: "Taxa (USDT)",
+    estimatedPnlRow: "Lucro estimado",
+    triggerUsdt: "Gatilho (USDT)",
+    orderPriceUsdt: "Preço ordem (USDT)",
+    openAvgUsdt: "Média entrada (USDT)",
+    closeAvgUsdt: "Média saída (USDT)",
+    tpUsdt: "TP (USDT)",
+    slUsdt: "SL (USDT)",
+    marginUsdtBracket: "Margem (USDT)",
+    notionalUsdt: "Valor posição (USDT)",
+    estLiqPx: "Preço liq estimado",
+    profitBracketUsdt: "Lucro (USDT)",
+    entrustVolCoin: "Ordem ({base})",
+    filledVolCoin: "Executado ({base})",
+    closeAvail: "Fechável:",
+    markPriceBtn: "Marca",
   },
   empty: {
-    noPositions: 'Sem posições',
-    noOrders: 'Sem ordens',
-    noHistPositions: 'Sem histórico posições',
-    noHistOrders: 'Sem histórico ordens',
-    noTradeRecords: 'Sem negociações',
-    noFunding: 'Sem registros funding',
+    noPositions: "Sem posições",
+    noOrders: "Sem ordens",
+    noHistPositions: "Sem histórico posições",
+    noHistOrders: "Sem histórico ordens",
+    noTradeRecords: "Sem negociações",
+    noFunding: "Sem registros funding",
   },
   modal: {
-    confirmDefaultTitle: 'Confirmar',
-    positionDetailTitle: 'Detalhe posição',
-    orderDetailTitle: 'Detalhe ordem',
-    histPositionDetailTitle: 'Posição histórica',
-    histOrderDetailTitle: 'Ordem histórica',
-    closePositionTitlePrefix: 'Fechar',
-    modifyTpSl: 'Editar TP/SL',
-    setTpSl: 'Config TP/SL',
-    posQtyLabel: 'Quant.:',
-    currentTpSlSection: 'Ordens TP/SL ativas',
-    modifyToSection: 'Alterar para',
-    setPricesSection: 'Preços',
-    tpTriggerLabel: 'Gatilho TP ',
-    tpHintOptionalClear: '(vazio = apagar TP)',
-    slTriggerLabel: 'Gatilho SL ',
-    slHintOptionalClear: '(vazio = apagar SL)',
-    placeholderTpTrigger: 'Preço gatilho TP',
-    placeholderSlTrigger: 'Preço gatilho SL',
-    confirmCloseBtn: 'Confirmar fechamento',
-    ok: 'OK',
-    closeTypeLiquidation: 'Liquidado',
-    tpBadge: 'TP',
-    slBadge: 'SL',
-    tpPriceWord: 'TP ',
-    slPriceWord: 'SL ',
-    volLabel: 'Quant.:',
-    marginSplitMode: 'Cruzada / Isolada',
-    directionLabel: 'Sentido',
-    entrustTypeLabel: 'Tipo ordem',
-    leverageLabel: 'Alavancagem',
+    confirmDefaultTitle: "Confirmar",
+    positionDetailTitle: "Detalhe posição",
+    orderDetailTitle: "Detalhe ordem",
+    histPositionDetailTitle: "Posição histórica",
+    histOrderDetailTitle: "Ordem histórica",
+    closePositionTitlePrefix: "Fechar",
+    modifyTpSl: "Editar TP/SL",
+    setTpSl: "Config TP/SL",
+    posQtyLabel: "Quant.:",
+    currentTpSlSection: "Ordens TP/SL ativas",
+    modifyToSection: "Alterar para",
+    setPricesSection: "Preços",
+    tpTriggerLabel: "Gatilho TP ",
+    tpHintOptionalClear: "(vazio = apagar TP)",
+    slTriggerLabel: "Gatilho SL ",
+    slHintOptionalClear: "(vazio = apagar SL)",
+    placeholderTpTrigger: "Preço gatilho TP",
+    placeholderSlTrigger: "Preço gatilho SL",
+    confirmCloseBtn: "Confirmar fechamento",
+    ok: "OK",
+    closeTypeLiquidation: "Liquidado",
+    tpBadge: "TP",
+    slBadge: "SL",
+    tpPriceWord: "TP ",
+    slPriceWord: "SL ",
+    volLabel: "Quant.:",
+    marginSplitMode: "Cruzada / Isolada",
+    directionLabel: "Sentido",
+    entrustTypeLabel: "Tipo ordem",
+    leverageLabel: "Alavancagem",
+  },
+  actions: {
+    tpSl: "TP/SL",
+    reverse: "Reverter",
+    close: "Fechar",
+    marketCloseAll: "Fechar tudo mercado",
+    cancelOrder: "Cancelar",
   },
-  actions: { tpSl: 'TP/SL', reverse: 'Reverter', close: 'Fechar', marketCloseAll: 'Fechar tudo mercado', cancelOrder: 'Cancelar' },
-  positionRow: { hintCross: 'Cruzada', hintExperience: 'Bônus' },
+  positionRow: { hintCross: "Cruzada", hintExperience: "Bônus" },
   errors: {
-    enterTriggerPrice: 'Informe preço gatilho',
-    enterPrice: 'Informe preço',
-    priceNotReadyConvert: 'Preço indisponível, conversão falha',
-    invalidQtyCheckMin: 'Qtd inválida, verifique mínimo',
-    priceNotReadyRetry: 'Preço indisponível, tente depois',
-    enterQty: 'Informe quantidade',
-    qtyExceedAvail: 'Qtd maior que disponível para fechar',
-    closeFailed: 'Falha fechamento',
-    modifyTpSlFailed: 'Falha alteração, tente novamente',
-    txFallback: 'Tipo {n}',
+    enterTriggerPrice: "Informe preço gatilho",
+    enterPrice: "Informe preço",
+    priceNotReadyConvert: "Preço indisponível, conversão falha",
+    invalidQtyCheckMin: "Qtd inválida, verifique mínimo",
+    priceNotReadyRetry: "Preço indisponível, tente depois",
+    enterQty: "Informe quantidade",
+    qtyExceedAvail: "Qtd maior que disponível para fechar",
+    closeFailed: "Falha fechamento",
+    modifyTpSlFailed: "Falha alteração, tente novamente",
+    txFallback: "Tipo {n}",
   },
   confirm: {
-    reverseTitle: 'Reverter posição',
-    reverseBody: 'Reverter {pair} {side}?',
-    cancelAllTitle: 'Cancelar todas',
-    cancelAllBody: 'Cancelar {n} ordens?',
-    closeAllTitle: 'Fechar todas',
-    closeAllBody: 'Fechar {n} posições a mercado?',
-    sideLongWord: 'long',
-    sideShortWord: 'short',
+    reverseTitle: "Reverter posição",
+    reverseBody: "Reverter {pair} {side}?",
+    cancelAllTitle: "Cancelar todas",
+    cancelAllBody: "Cancelar {n} ordens?",
+    closeAllTitle: "Fechar todas",
+    closeAllBody: "Fechar {n} posições a mercado?",
+    sideLongWord: "long",
+    sideShortWord: "short",
   },
   directions: {
-    long: 'Long',
-    short: 'Short',
-    openLong: 'Abrir long',
-    openShort: 'Abrir short',
-    closeShort: 'Fechar short',
-    closeLong: 'Fechar long',
-    openTag: 'A',
-    closeTag: 'F',
+    long: "Long",
+    short: "Short",
+    openLong: "Abrir long",
+    openShort: "Abrir short",
+    closeShort: "Fechar short",
+    closeLong: "Fechar long",
+    openTag: "A",
+    closeTag: "F",
+  },
+  orderTypes: {
+    limit: "Limite",
+    plan: "Gatilho",
+    takeProfit: "Take Profit",
+    stopLoss: "Stop Loss",
+    marketShort: "Mercado",
+  },
+  orderStatus: {
+    filled: "Executada",
+    open: "Aberta",
+    cancelled: "Cancelada",
+    failed: "Falha",
   },
-  orderTypes: { limit: 'Limite', plan: 'Gatilho', takeProfit: 'Take Profit', stopLoss: 'Stop Loss', marketShort: 'Mercado' },
-  orderStatus: { filled: 'Executada', open: 'Aberta', cancelled: 'Cancelada', failed: 'Falha' },
   closeTypes: {
-    market: 'Fechamento mercado',
-    oneClick: 'Fechar um clique',
-    reverseOpen: 'Abertura inversa',
-    tpSl: 'TP/SL',
-    liquidation: 'Liquidação',
-    admin: 'Fechamento admin',
+    market: "Fechamento mercado",
+    oneClick: "Fechar um clique",
+    reverseOpen: "Abertura inversa",
+    tpSl: "TP/SL",
+    liquidation: "Liquidação",
+    admin: "Fechamento admin",
   },
-}
+};

+ 260 - 233
code/src/locales/futuresPage/overlays/ru.ts

@@ -1,267 +1,294 @@
-import type { DeepPartial, FuturesPageMessages } from '../../futuresPage.i18n'
+import type { DeepPartial, FuturesPageMessages } from "../../futuresPage.i18n";
 
 export const ruUiOverlay: DeepPartial<FuturesPageMessages> = {
-  perpetual: 'Бессрочные фьючерсы',
-  perpetualTag: 'Бессрочный',
-  pairSearchPlaceholder: 'Поиск',
-  pairEmpty: 'Совпадений не найдено',
+  perpetual: "Бессрочные фьючерсы",
+  perpetualTag: "Бессрочный",
+  pairSearchPlaceholder: "Поиск",
+  pairSearchTag: {
+    oneType: "Крипто",
+    twoType: "Акции",
+    threeType: "Металлы",
+    fourType: "Форекс",
+  },
+  pairEmpty: "Совпадений не найдено",
   stats: {
-    change24h: 'Изменение за 24ч',
-    markPrice: 'Маркер',
-    high24h: 'Макс. за 24ч',
-    low24h: 'Мин. за 24ч',
-    volume24h: 'Объём за 24ч',
-    fundingCountdown: 'Фандинг / Обратный отсчёт',
+    change24h: "Изменение за 24ч",
+    markPrice: "Маркер",
+    high24h: "Макс. за 24ч",
+    low24h: "Мин. за 24ч",
+    volume24h: "Объём за 24ч",
+    fundingCountdown: "Фандинг / Обратный отсчёт",
+  },
+  mobileTabs: { chart: "График", trade: "Торговля" },
+  chartSub: {
+    chart: "График",
+    coinInfo: "О монете",
+    fundingHistory: "История фандинга",
   },
-  mobileTabs: { chart: 'График', trade: 'Торговля' },
-  chartSub: { chart: 'График', coinInfo: 'О монете', fundingHistory: 'История фандинга' },
-  chartTools: { fullscreen: 'Полный экран', alert: 'Оповещения' },
+  chartTools: { fullscreen: "Полный экран", alert: "Оповещения" },
   draw: {
-    cursor: 'Курсор',
-    trend: 'Трендовая линия',
-    hline: 'Горизонталь',
-    ray: 'Луч',
-    channel: 'Канал',
-    fib: 'Фибоначчи',
-    text: 'Надпись',
-    clearAll: 'Удалить рисунки',
-    zoomOut: 'Уменьшить',
+    cursor: "Курсор",
+    trend: "Трендовая линия",
+    hline: "Горизонталь",
+    ray: "Луч",
+    channel: "Канал",
+    fib: "Фибоначчи",
+    text: "Надпись",
+    clearAll: "Удалить рисунки",
+    zoomOut: "Уменьшить",
   },
   ohlcv: {
-    open: 'Откр',
-    high: 'Макс',
-    low: 'Мин',
-    close: 'Закр',
-    volume: 'Объём',
-    changePct: 'Изменение',
-    amplitude: 'Диапазон',
+    open: "Откр",
+    high: "Макс",
+    low: "Мин",
+    close: "Закр",
+    volume: "Объём",
+    changePct: "Изменение",
+    amplitude: "Диапазон",
   },
   coinInfo: {
-    marketCap: 'Капитализация',
-    circulating: 'Циркулирующий запас',
-    issuePrice: 'Цена выпуска',
-    ath: 'Исторический максимум',
-    athDate: 'Дата ATH',
-    whitepaper: 'Вайтпейпер',
-    empty: 'Данных по монете нет',
-    reload: 'Обновить',
+    marketCap: "Капитализация",
+    circulating: "Циркулирующий запас",
+    issuePrice: "Цена выпуска",
+    ath: "Исторический максимум",
+    athDate: "Дата ATH",
+    whitepaper: "Вайтпейпер",
+    empty: "Данных по монете нет",
+    reload: "Обновить",
   },
   fundingPanel: {
-    rate: 'Ставка фандинга',
-    period: 'Период расчёта',
-    nextCountdown: 'До следующего расчёта',
-    noChart: 'Нет данных графика',
-    settleTime: 'Время расчёта',
-    rateCol: 'Ставка фандинга',
-    empty7d: 'Нет данных за 7 дней',
+    rate: "Ставка фандинга",
+    period: "Период расчёта",
+    nextCountdown: "До следующего расчёта",
+    noChart: "Нет данных графика",
+    settleTime: "Время расчёта",
+    rateCol: "Ставка фандинга",
+    empty7d: "Нет данных за 7 дней",
   },
   book: {
-    orderBook: 'Стакан',
-    trades: 'Сделки',
-    priceQuote: 'Цена (USDT)',
-    amountBase: 'Кол-во ({base})',
-    totalBase: 'Итого ({base})',
-    time: 'Время',
-    buy: 'Покупка',
-    sell: 'Продажа',
-    buyRatio: 'Покупка {n}%',
-    sellRatio: '{n}% Продажа',
-    noTrades: 'Нет сделок',
+    orderBook: "Стакан",
+    trades: "Сделки",
+    priceQuote: "Цена (USDT)",
+    amountBase: "Кол-во ({base})",
+    totalBase: "Итого ({base})",
+    time: "Время",
+    buy: "Покупка",
+    sell: "Продажа",
+    buyRatio: "Покупка {n}%",
+    sellRatio: "{n}% Продажа",
+    noTrades: "Нет сделок",
   },
-  margin: { cross: 'Кросс', split: 'Изолированный', experience: 'Бонус' },
-  amountUnit: { lots: 'Контракт', usdt: 'USDT' },
-  leverage: { adjustTitle: 'Изменить плечо' },
+  margin: { cross: "Кросс", split: "Изолированный", experience: "Бонус" },
+  amountUnit: { lots: "Контракт", usdt: "USDT" },
+  leverage: { adjustTitle: "Изменить плечо" },
   order: {
-    limit: 'Лимит',
-    market: 'Рынок',
-    conditional: 'Условный',
-    condMarket: 'Рыночный условный',
-    condLimit: 'Лимит условный',
-    available: 'Доступно',
-    maxOpen: 'Макс к открытию',
-    triggerPriceLabel: 'Срабатывание ({q})',
-    priceLabel: 'Цена ({q})',
-    latestBtn: 'Последняя',
-    marketExe: 'По рынку',
-    condMarketExe: 'Рынок после срабатывания',
-    qtyLabel: 'Кол-во ({u})',
-    transferTitle: 'Перевод',
-    openLong: 'Купить / Лонг',
-    openShort: 'Продать / Шорт',
-    contractInfoTitle: 'Данные контракта',
-    indexSource: 'Источник индекса',
-    marginCoin: 'Актив маржи',
-    maxLeverage: 'Макс плечо',
-    maintMargin: 'Ставка поддерж. маржи',
-    openFee: 'Комиссия открытия',
-    closeFee: 'Комиссия закрытия',
-    contractValue: 'Стоимость контракта',
-    minOrder: 'Мин ордер',
-    maxOrder: 'Макс ордер',
+    limit: "Лимит",
+    market: "Рынок",
+    conditional: "Условный",
+    condMarket: "Рыночный условный",
+    condLimit: "Лимит условный",
+    available: "Доступно",
+    maxOpen: "Макс к открытию",
+    triggerPriceLabel: "Срабатывание ({q})",
+    priceLabel: "Цена ({q})",
+    latestBtn: "Последняя",
+    marketExe: "По рынку",
+    condMarketExe: "Рынок после срабатывания",
+    qtyLabel: "Кол-во ({u})",
+    transferTitle: "Перевод",
+    openLong: "Купить / Лонг",
+    openShort: "Продать / Шорт",
+    contractInfoTitle: "Данные контракта",
+    indexSource: "Источник индекса",
+    marginCoin: "Актив маржи",
+    maxLeverage: "Макс плечо",
+    maintMargin: "Ставка поддерж. маржи",
+    openFee: "Комиссия открытия",
+    closeFee: "Комиссия закрытия",
+    contractValue: "Стоимость контракта",
+    minOrder: "Мин ордер",
+    maxOrder: "Макс ордер",
   },
   placeholders: {
-    searchPair: 'Поиск',
-    triggerPrice: 'Введите цену срабатывания',
-    price: 'Введите цену',
-    amount: 'Введите количество',
+    searchPair: "Поиск",
+    triggerPrice: "Введите цену срабатывания",
+    price: "Введите цену",
+    amount: "Введите количество",
   },
   bottom: {
-    positions: 'Позиции',
-    openOrders: 'Активные ордера',
-    historyOrders: 'История ордеров',
-    historyPositions: 'История позиций',
-    tradeDetails: 'Сделки',
-    fundingFlow: 'Движение средств',
-    assets: 'Активы',
-    closeAllPositions: 'Закрыть всё',
-    cancelAllOrders: 'Отменить всё',
-    loginPromptOr: 'или',
-    registerNow: 'Зарегистрироваться',
-    startTrading: 'начать торговлю',
+    positions: "Позиции",
+    openOrders: "Активные ордера",
+    historyOrders: "История ордеров",
+    historyPositions: "История позиций",
+    tradeDetails: "Сделки",
+    fundingFlow: "Движение средств",
+    assets: "Активы",
+    closeAllPositions: "Закрыть всё",
+    cancelAllOrders: "Отменить всё",
+    loginPromptOr: "или",
+    registerNow: "Зарегистрироваться",
+    startTrading: "начать торговлю",
   },
   table: {
-    contract: 'Контракт',
-    dirLeverage: 'Напр./Плечо',
-    openPrice: 'Открытие',
-    markPrice: 'Маркер',
-    positionSize: 'Объём',
-    margin: 'Маржа',
-    marginRate: 'Ставка маржи',
-    unrealizedPnl: 'Нереал. прибыль',
-    roe: 'ROE',
-    liqPrice: 'Цена ликвидации',
-    openTime: 'Время откр.',
-    action: 'Действие',
-    type: 'Тип',
-    orderPrice: 'Цена ордера',
-    entrustPriceHist: 'Цена заявки',
-    triggerPrice: 'Срабатывание',
-    orderAmt: 'Объём заявки',
-    filled: 'Исполнено',
-    tpPrice: 'Тейк-профит',
-    slPrice: 'Стоп-лосс',
-    time: 'Время',
-    orderTime: 'Время заявки',
-    fillTime: 'Время исполн.',
-    profitUsdt: 'Прибыль (USDT)',
-    tradedVol: 'Исполн. объём',
-    closeAvg: 'Сред. закр.',
-    profitRate: 'ROE',
-    closeTime: 'Время закрытия',
-    directionOpenClose: 'Напр./Откр-Закр',
-    dealPrice: 'Цена исполн.',
-    fee: 'Комиссия',
-    fundType: 'Тип',
-    amount: 'Кол-во',
-    coin: 'Монета',
-    settlementTime: 'Расчёт',
-    fundingRate: 'Ставка фандинга',
-    totalBal: 'Баланс фьючерс',
-    availMargin: 'Доступная маржа',
-    usedMargin: 'Использ. маржа',
-    unrealized: 'Нереал. прибыль',
-    spotWalletBal: 'Выводимый баланс',
-    fundTransfer: 'Перевод',
-    avgOpenPrice: 'Сред. открытия',
-    feeHint: 'Комиссия (USDT)',
-    estimatedPnlRow: 'Ожид. прибыль',
-    triggerUsdt: 'Срабатывание (USDT)',
-    orderPriceUsdt: 'Цена ордера (USDT)',
-    openAvgUsdt: 'Сред вход (USDT)',
-    closeAvgUsdt: 'Сред выход (USDT)',
-    tpUsdt: 'TP (USDT)',
-    slUsdt: 'SL (USDT)',
-    marginUsdtBracket: 'Маржа (USDT)',
-    notionalUsdt: 'Стоим. поз. (USDT)',
-    estLiqPx: 'Оцен. ликв цена',
-    profitBracketUsdt: 'Прибыль (USDT)',
-    entrustVolCoin: 'Заявка ({base})',
-    filledVolCoin: 'Исполнено ({base})',
-    closeAvail: 'Доступно к закр:',
-    markPriceBtn: 'Маркер',
+    contract: "Контракт",
+    dirLeverage: "Напр./Плечо",
+    openPrice: "Открытие",
+    markPrice: "Маркер",
+    positionSize: "Объём",
+    margin: "Маржа",
+    marginRate: "Ставка маржи",
+    unrealizedPnl: "Нереал. прибыль",
+    roe: "ROE",
+    liqPrice: "Цена ликвидации",
+    openTime: "Время откр.",
+    action: "Действие",
+    type: "Тип",
+    orderPrice: "Цена ордера",
+    entrustPriceHist: "Цена заявки",
+    triggerPrice: "Срабатывание",
+    orderAmt: "Объём заявки",
+    filled: "Исполнено",
+    tpPrice: "Тейк-профит",
+    slPrice: "Стоп-лосс",
+    time: "Время",
+    orderTime: "Время заявки",
+    fillTime: "Время исполн.",
+    profitUsdt: "Прибыль (USDT)",
+    tradedVol: "Исполн. объём",
+    closeAvg: "Сред. закр.",
+    profitRate: "ROE",
+    closeTime: "Время закрытия",
+    directionOpenClose: "Напр./Откр-Закр",
+    dealPrice: "Цена исполн.",
+    fee: "Комиссия",
+    fundType: "Тип",
+    amount: "Кол-во",
+    coin: "Монета",
+    settlementTime: "Расчёт",
+    fundingRate: "Ставка фандинга",
+    totalBal: "Баланс фьючерс",
+    availMargin: "Доступная маржа",
+    usedMargin: "Использ. маржа",
+    unrealized: "Нереал. прибыль",
+    spotWalletBal: "Выводимый баланс",
+    fundTransfer: "Перевод",
+    avgOpenPrice: "Сред. открытия",
+    feeHint: "Комиссия (USDT)",
+    estimatedPnlRow: "Ожид. прибыль",
+    triggerUsdt: "Срабатывание (USDT)",
+    orderPriceUsdt: "Цена ордера (USDT)",
+    openAvgUsdt: "Сред вход (USDT)",
+    closeAvgUsdt: "Сред выход (USDT)",
+    tpUsdt: "TP (USDT)",
+    slUsdt: "SL (USDT)",
+    marginUsdtBracket: "Маржа (USDT)",
+    notionalUsdt: "Стоим. поз. (USDT)",
+    estLiqPx: "Оцен. ликв цена",
+    profitBracketUsdt: "Прибыль (USDT)",
+    entrustVolCoin: "Заявка ({base})",
+    filledVolCoin: "Исполнено ({base})",
+    closeAvail: "Доступно к закр:",
+    markPriceBtn: "Маркер",
   },
   empty: {
-    noPositions: 'Нет позиций',
-    noOrders: 'Нет ордеров',
-    noHistPositions: 'Нет истории позиций',
-    noHistOrders: 'Нет истории ордеров',
-    noTradeRecords: 'Нет сделок',
-    noFunding: 'Нет движений средств',
+    noPositions: "Нет позиций",
+    noOrders: "Нет ордеров",
+    noHistPositions: "Нет истории позиций",
+    noHistOrders: "Нет истории ордеров",
+    noTradeRecords: "Нет сделок",
+    noFunding: "Нет движений средств",
   },
   modal: {
-    confirmDefaultTitle: 'Подтвердите',
-    positionDetailTitle: 'Детали позиции',
-    orderDetailTitle: 'Детали ордера',
-    histPositionDetailTitle: 'История позиции',
-    histOrderDetailTitle: 'История ордера',
-    closePositionTitlePrefix: 'Закрыть',
-    modifyTpSl: 'Редакт TP/SL',
-    setTpSl: 'Установить TP/SL',
-    posQtyLabel: 'Объём:',
-    currentTpSlSection: 'Актив TP/SL ордера',
-    modifyToSection: 'Изменить на',
-    setPricesSection: 'Цены',
-    tpTriggerLabel: 'Сраб TP ',
-    tpHintOptionalClear: '(пусто = удалить TP)',
-    slTriggerLabel: 'Сраб SL ',
-    slHintOptionalClear: '(пусто = удалить SL)',
-    placeholderTpTrigger: 'Цена сраб TP',
-    placeholderSlTrigger: 'Цена сраб SL',
-    confirmCloseBtn: 'Подтвердить закр',
-    ok: 'Ок',
-    closeTypeLiquidation: 'Ликвидация',
-    tpBadge: 'TP',
-    slBadge: 'SL',
-    tpPriceWord: 'TP ',
-    slPriceWord: 'SL ',
-    volLabel: 'Кол-во:',
-    marginSplitMode: 'Кросс / Изолир',
-    directionLabel: 'Направление',
-    entrustTypeLabel: 'Тип ордера',
-    leverageLabel: 'Плечо',
+    confirmDefaultTitle: "Подтвердите",
+    positionDetailTitle: "Детали позиции",
+    orderDetailTitle: "Детали ордера",
+    histPositionDetailTitle: "История позиции",
+    histOrderDetailTitle: "История ордера",
+    closePositionTitlePrefix: "Закрыть",
+    modifyTpSl: "Редакт TP/SL",
+    setTpSl: "Установить TP/SL",
+    posQtyLabel: "Объём:",
+    currentTpSlSection: "Актив TP/SL ордера",
+    modifyToSection: "Изменить на",
+    setPricesSection: "Цены",
+    tpTriggerLabel: "Сраб TP ",
+    tpHintOptionalClear: "(пусто = удалить TP)",
+    slTriggerLabel: "Сраб SL ",
+    slHintOptionalClear: "(пусто = удалить SL)",
+    placeholderTpTrigger: "Цена сраб TP",
+    placeholderSlTrigger: "Цена сраб SL",
+    confirmCloseBtn: "Подтвердить закр",
+    ok: "Ок",
+    closeTypeLiquidation: "Ликвидация",
+    tpBadge: "TP",
+    slBadge: "SL",
+    tpPriceWord: "TP ",
+    slPriceWord: "SL ",
+    volLabel: "Кол-во:",
+    marginSplitMode: "Кросс / Изолир",
+    directionLabel: "Направление",
+    entrustTypeLabel: "Тип ордера",
+    leverageLabel: "Плечо",
+  },
+  actions: {
+    tpSl: "TP/SL",
+    reverse: "Разворот",
+    close: "Закрыть",
+    marketCloseAll: "Закр всё по рынку",
+    cancelOrder: "Отменить",
   },
-  actions: { tpSl: 'TP/SL', reverse: 'Разворот', close: 'Закрыть', marketCloseAll: 'Закр всё по рынку', cancelOrder: 'Отменить' },
-  positionRow: { hintCross: 'Кросс', hintExperience: 'Бонус' },
+  positionRow: { hintCross: "Кросс", hintExperience: "Бонус" },
   errors: {
-    enterTriggerPrice: 'Укажите цену срабатывания',
-    enterPrice: 'Укажите цену',
-    priceNotReadyConvert: 'Цена не готова, расчёт невозможен',
-    invalidQtyCheckMin: 'Некоррект объём, проверьте мин лимит',
-    priceNotReadyRetry: 'Цена недоступна, повторите позже',
-    enterQty: 'Укажите количество',
-    qtyExceedAvail: 'Объём выше доступного для закрытия',
-    closeFailed: 'Ошибка закрытия',
-    modifyTpSlFailed: 'Ошибка изменения, повторите позже',
-    txFallback: 'Тип {n}',
+    enterTriggerPrice: "Укажите цену срабатывания",
+    enterPrice: "Укажите цену",
+    priceNotReadyConvert: "Цена не готова, расчёт невозможен",
+    invalidQtyCheckMin: "Некоррект объём, проверьте мин лимит",
+    priceNotReadyRetry: "Цена недоступна, повторите позже",
+    enterQty: "Укажите количество",
+    qtyExceedAvail: "Объём выше доступного для закрытия",
+    closeFailed: "Ошибка закрытия",
+    modifyTpSlFailed: "Ошибка изменения, повторите позже",
+    txFallback: "Тип {n}",
   },
   confirm: {
-    reverseTitle: 'Разворот позиции',
-    reverseBody: 'Развернуть {pair} {side}?',
-    cancelAllTitle: 'Отменить все',
-    cancelAllBody: 'Отменить {n} ордеров?',
-    closeAllTitle: 'Закрыть все',
-    closeAllBody: 'Закрыть {n} поз по рынку?',
-    sideLongWord: 'лонг',
-    sideShortWord: 'шорт',
+    reverseTitle: "Разворот позиции",
+    reverseBody: "Развернуть {pair} {side}?",
+    cancelAllTitle: "Отменить все",
+    cancelAllBody: "Отменить {n} ордеров?",
+    closeAllTitle: "Закрыть все",
+    closeAllBody: "Закрыть {n} поз по рынку?",
+    sideLongWord: "лонг",
+    sideShortWord: "шорт",
   },
   directions: {
-    long: 'Лонг',
-    short: 'Шорт',
-    openLong: 'Откр лонг',
-    openShort: 'Откр шорт',
-    closeShort: 'Закр шорт',
-    closeLong: 'Закр лонг',
-    openTag: 'О',
-    closeTag: 'З',
+    long: "Лонг",
+    short: "Шорт",
+    openLong: "Откр лонг",
+    openShort: "Откр шорт",
+    closeShort: "Закр шорт",
+    closeLong: "Закр лонг",
+    openTag: "О",
+    closeTag: "З",
+  },
+  orderTypes: {
+    limit: "Лимит",
+    plan: "Срабатывание",
+    takeProfit: "Тейк-профит",
+    stopLoss: "Стоп-лосс",
+    marketShort: "Рынок",
+  },
+  orderStatus: {
+    filled: "Исполнено",
+    open: "Активно",
+    cancelled: "Отменено",
+    failed: "Ошибка",
   },
-  orderTypes: { limit: 'Лимит', plan: 'Срабатывание', takeProfit: 'Тейк-профит', stopLoss: 'Стоп-лосс', marketShort: 'Рынок' },
-  orderStatus: { filled: 'Исполнено', open: 'Активно', cancelled: 'Отменено', failed: 'Ошибка' },
   closeTypes: {
-    market: 'Закр по рынку',
-    oneClick: 'Закр в один клик',
-    reverseOpen: 'Встречное открытие',
-    tpSl: 'TP/SL',
-    liquidation: 'Ликвидация',
-    admin: 'Закр админом',
+    market: "Закр по рынку",
+    oneClick: "Закр в один клик",
+    reverseOpen: "Встречное открытие",
+    tpSl: "TP/SL",
+    liquidation: "Ликвидация",
+    admin: "Закр админом",
   },
-}
+};

+ 260 - 233
code/src/locales/futuresPage/overlays/tr.ts

@@ -1,267 +1,294 @@
-import type { DeepPartial, FuturesPageMessages } from '../../futuresPage.i18n'
+import type { DeepPartial, FuturesPageMessages } from "../../futuresPage.i18n";
 
 export const trUiOverlay: DeepPartial<FuturesPageMessages> = {
-  perpetual: 'Sürekli Vadeli',
-  perpetualTag: 'Sürekli',
-  pairSearchPlaceholder: 'Ara',
-  pairEmpty: 'Sonuç bulunamadı',
+  perpetual: "Sürekli Vadeli",
+  perpetualTag: "Sürekli",
+  pairSearchPlaceholder: "Ara",
+  pairSearchTag: {
+    oneType: "Kripto Para",
+    twoType: "Hisse Senedi",
+    threeType: "Madenler",
+    fourType: "Foreks",
+  },
+  pairEmpty: "Sonuç bulunamadı",
   stats: {
-    change24h: '24s Değişim',
-    markPrice: 'İşaret Fiyatı',
-    high24h: '24s En Yüksek',
-    low24h: '24s En Düşük',
-    volume24h: '24s Hacim',
-    fundingCountdown: 'Funding / Geri Sayım',
+    change24h: "24s Değişim",
+    markPrice: "İşaret Fiyatı",
+    high24h: "24s En Yüksek",
+    low24h: "24s En Düşük",
+    volume24h: "24s Hacim",
+    fundingCountdown: "Funding / Geri Sayım",
+  },
+  mobileTabs: { chart: "Grafik", trade: "Alım Satım" },
+  chartSub: {
+    chart: "Grafik",
+    coinInfo: "Para Bilgisi",
+    fundingHistory: "Funding Geçmişi",
   },
-  mobileTabs: { chart: 'Grafik', trade: 'Alım Satım' },
-  chartSub: { chart: 'Grafik', coinInfo: 'Para Bilgisi', fundingHistory: 'Funding Geçmişi' },
-  chartTools: { fullscreen: 'Tam Ekran', alert: 'Bildirimler' },
+  chartTools: { fullscreen: "Tam Ekran", alert: "Bildirimler" },
   draw: {
-    cursor: 'İmleç',
-    trend: 'Trend Çizgisi',
-    hline: 'Yatay Çizgi',
-    ray: 'Işın',
-    channel: 'Kanal',
-    fib: 'Fibonacci',
-    text: 'Metin',
-    clearAll: 'Çizimleri Sil',
-    zoomOut: 'Uzaklaştır',
+    cursor: "İmleç",
+    trend: "Trend Çizgisi",
+    hline: "Yatay Çizgi",
+    ray: "Işın",
+    channel: "Kanal",
+    fib: "Fibonacci",
+    text: "Metin",
+    clearAll: "Çizimleri Sil",
+    zoomOut: "Uzaklaştır",
   },
   ohlcv: {
-    open: 'Açılış',
-    high: 'En Yüksek',
-    low: 'En Düşük',
-    close: 'Kapanış',
-    volume: 'Hacim',
-    changePct: 'Değişim',
-    amplitude: 'Aralık',
+    open: "Açılış",
+    high: "En Yüksek",
+    low: "En Düşük",
+    close: "Kapanış",
+    volume: "Hacim",
+    changePct: "Değişim",
+    amplitude: "Aralık",
   },
   coinInfo: {
-    marketCap: 'Piyasa Değeri',
-    circulating: 'Dolaşım Arzı',
-    issuePrice: 'Çıkış Fiyatı',
-    ath: 'Tüm Zamanların En Yükseği',
-    athDate: 'ATH Tarihi',
-    whitepaper: 'Teknik Belge',
-    empty: 'Veri bulunmamaktadır',
-    reload: 'Yenile',
+    marketCap: "Piyasa Değeri",
+    circulating: "Dolaşım Arzı",
+    issuePrice: "Çıkış Fiyatı",
+    ath: "Tüm Zamanların En Yükseği",
+    athDate: "ATH Tarihi",
+    whitepaper: "Teknik Belge",
+    empty: "Veri bulunmamaktadır",
+    reload: "Yenile",
   },
   fundingPanel: {
-    rate: 'Funding Oranı',
-    period: 'Hesaplama Periyodu',
-    nextCountdown: 'Sonraki Ödeme Geri Sayımı',
-    noChart: 'Grafik Verisi Yok',
-    settleTime: 'Ödeme Zamanı',
-    rateCol: 'Funding Oranı',
-    empty7d: '7 Günlük Veri Yok',
+    rate: "Funding Oranı",
+    period: "Hesaplama Periyodu",
+    nextCountdown: "Sonraki Ödeme Geri Sayımı",
+    noChart: "Grafik Verisi Yok",
+    settleTime: "Ödeme Zamanı",
+    rateCol: "Funding Oranı",
+    empty7d: "7 Günlük Veri Yok",
   },
   book: {
-    orderBook: 'Emir Defteri',
-    trades: 'İşlemler',
-    priceQuote: 'Fiyat (USDT)',
-    amountBase: 'Miktar ({base})',
-    totalBase: 'Toplam ({base})',
-    time: 'Saat',
-    buy: 'Alış',
-    sell: 'Satış',
-    buyRatio: 'Alım %{n}',
-    sellRatio: 'Satım %{n}',
-    noTrades: 'Gerçekleşen İşlem Yok',
+    orderBook: "Emir Defteri",
+    trades: "İşlemler",
+    priceQuote: "Fiyat (USDT)",
+    amountBase: "Miktar ({base})",
+    totalBase: "Toplam ({base})",
+    time: "Saat",
+    buy: "Alış",
+    sell: "Satış",
+    buyRatio: "Alım %{n}",
+    sellRatio: "Satım %{n}",
+    noTrades: "Gerçekleşen İşlem Yok",
   },
-  margin: { cross: 'Çapraz Marj', split: 'Ayrık Marj', experience: 'Bonus' },
-  amountUnit: { lots: 'Kontrat', usdt: 'USDT' },
-  leverage: { adjustTitle: 'Kaldıraç Ayarla' },
+  margin: { cross: "Çapraz Marj", split: "Ayrık Marj", experience: "Bonus" },
+  amountUnit: { lots: "Kontrat", usdt: "USDT" },
+  leverage: { adjustTitle: "Kaldıraç Ayarla" },
   order: {
-    limit: 'Limit',
-    market: 'Piyasa',
-    conditional: 'Koşullu',
-    condMarket: 'Koşullu Piyasa',
-    condLimit: 'Koşullu Limit',
-    available: 'Kullanılabilir',
-    maxOpen: 'Maks Açılış',
-    triggerPriceLabel: 'Tetikleme ({q})',
-    priceLabel: 'Fiyat ({q})',
-    latestBtn: 'Son Fiyat',
-    marketExe: 'Piyasa Fiyatı',
-    condMarketExe: 'Tetikten Sonra Piyasa',
-    qtyLabel: 'Miktar ({u})',
-    transferTitle: 'Transfer',
-    openLong: 'Al / Long',
-    openShort: 'Sat / Short',
-    contractInfoTitle: 'Kontrat Bilgisi',
-    indexSource: 'Endeks Kaynağı',
-    marginCoin: 'Marj Varlığı',
-    maxLeverage: 'Maks Kaldıraç',
-    maintMargin: 'Bakım Marj Oranı',
-    openFee: 'Açılış Komisyonu',
-    closeFee: 'Kapanış Komisyonu',
-    contractValue: 'Kontrat Değeri',
-    minOrder: 'Min Emir',
-    maxOrder: 'Maks Emir',
+    limit: "Limit",
+    market: "Piyasa",
+    conditional: "Koşullu",
+    condMarket: "Koşullu Piyasa",
+    condLimit: "Koşullu Limit",
+    available: "Kullanılabilir",
+    maxOpen: "Maks Açılış",
+    triggerPriceLabel: "Tetikleme ({q})",
+    priceLabel: "Fiyat ({q})",
+    latestBtn: "Son Fiyat",
+    marketExe: "Piyasa Fiyatı",
+    condMarketExe: "Tetikten Sonra Piyasa",
+    qtyLabel: "Miktar ({u})",
+    transferTitle: "Transfer",
+    openLong: "Al / Long",
+    openShort: "Sat / Short",
+    contractInfoTitle: "Kontrat Bilgisi",
+    indexSource: "Endeks Kaynağı",
+    marginCoin: "Marj Varlığı",
+    maxLeverage: "Maks Kaldıraç",
+    maintMargin: "Bakım Marj Oranı",
+    openFee: "Açılış Komisyonu",
+    closeFee: "Kapanış Komisyonu",
+    contractValue: "Kontrat Değeri",
+    minOrder: "Min Emir",
+    maxOrder: "Maks Emir",
   },
   placeholders: {
-    searchPair: 'Arama',
-    triggerPrice: 'Tetikleme fiyatı girin',
-    price: 'Fiyat girin',
-    amount: 'Miktar girin',
+    searchPair: "Arama",
+    triggerPrice: "Tetikleme fiyatı girin",
+    price: "Fiyat girin",
+    amount: "Miktar girin",
   },
   bottom: {
-    positions: 'Pozisyonlar',
-    openOrders: 'Açık Emirler',
-    historyOrders: 'Emir Geçmişi',
-    historyPositions: 'Pozisyon Geçmişi',
-    tradeDetails: 'İşlem Detayları',
-    fundingFlow: 'Para Akışı',
-    assets: 'Varlıklar',
-    closeAllPositions: 'Tümünü Kapat',
-    cancelAllOrders: 'Tüm Emirleri İptal Et',
-    loginPromptOr: 'veya',
-    registerNow: 'Kayıt Ol',
-    startTrading: 'Ticarete Başla',
+    positions: "Pozisyonlar",
+    openOrders: "Açık Emirler",
+    historyOrders: "Emir Geçmişi",
+    historyPositions: "Pozisyon Geçmişi",
+    tradeDetails: "İşlem Detayları",
+    fundingFlow: "Para Akışı",
+    assets: "Varlıklar",
+    closeAllPositions: "Tümünü Kapat",
+    cancelAllOrders: "Tüm Emirleri İptal Et",
+    loginPromptOr: "veya",
+    registerNow: "Kayıt Ol",
+    startTrading: "Ticarete Başla",
   },
   table: {
-    contract: 'Kontrat',
-    dirLeverage: 'Yön/Kaldıraç',
-    openPrice: 'Açılış Fiyatı',
-    markPrice: 'İşaret Fiyatı',
-    positionSize: 'Pozisyon Büyüklüğü',
-    margin: 'Marj',
-    marginRate: 'Marj Oranı',
-    unrealizedPnl: 'Gerçekleşmemiş Kar/Zarar',
-    roe: 'ROE',
-    liqPrice: 'Likidasyon Fiyatı',
-    openTime: 'Açılış Saati',
-    action: 'İşlem',
-    type: 'Tür',
-    orderPrice: 'Emir Fiyatı',
-    entrustPriceHist: 'Talep Fiyatı',
-    triggerPrice: 'Tetikleme',
-    orderAmt: 'Emir Miktarı',
-    filled: 'Gerçekleşen',
-    tpPrice: 'Kar Alım(TP)',
-    slPrice: 'Zarar Durdur(SL)',
-    time: 'Saat',
-    orderTime: 'Emir Saati',
-    fillTime: 'Gerçekleşme Saati',
-    profitUsdt: 'Kar (USDT)',
-    tradedVol: 'İşlem Hacmi',
-    closeAvg: 'Ortalama Kapanış',
-    profitRate: 'ROE',
-    closeTime: 'Kapanış Saati',
-    directionOpenClose: 'Yön/Aç-Kapat',
-    dealPrice: 'İşlem Fiyatı',
-    fee: 'Komisyon',
-    fundType: 'Tür',
-    amount: 'Miktar',
-    coin: 'Para Birimi',
-    settlementTime: 'Ödeme Zamanı',
-    fundingRate: 'Funding Oranı',
-    totalBal: 'Vadeli Bakiye',
-    availMargin: 'Kullanılabilir Marj',
-    usedMargin: 'Kullanılan Marj',
-    unrealized: 'Gerçekleşmemiş Kar/Zarar',
-    spotWalletBal: 'Çekilebilir Bakiye',
-    fundTransfer: 'Transfer',
-    avgOpenPrice: 'Ortalama Açılış',
-    feeHint: 'Komisyon (USDT)',
-    estimatedPnlRow: 'Tahmini Kar/Zarar',
-    triggerUsdt: 'Tetikleme (USDT)',
-    orderPriceUsdt: 'Emir Fiyatı (USDT)',
-    openAvgUsdt: 'Ortalama Giriş (USDT)',
-    closeAvgUsdt: 'Ortalama Çıkış (USDT)',
-    tpUsdt: 'TP (USDT)',
-    slUsdt: 'SL (USDT)',
-    marginUsdtBracket: 'Marj (USDT)',
-    notionalUsdt: 'Pozisyon Değeri (USDT)',
-    estLiqPx: 'Tahmini Likidasyon Fiyatı',
-    profitBracketUsdt: 'Kar/Zarar (USDT)',
-    entrustVolCoin: 'Talep ({base})',
-    filledVolCoin: 'Gerçekleşen ({base})',
-    closeAvail: 'Kapatılabilir:',
-    markPriceBtn: 'İşaret Fiyatı',
+    contract: "Kontrat",
+    dirLeverage: "Yön/Kaldıraç",
+    openPrice: "Açılış Fiyatı",
+    markPrice: "İşaret Fiyatı",
+    positionSize: "Pozisyon Büyüklüğü",
+    margin: "Marj",
+    marginRate: "Marj Oranı",
+    unrealizedPnl: "Gerçekleşmemiş Kar/Zarar",
+    roe: "ROE",
+    liqPrice: "Likidasyon Fiyatı",
+    openTime: "Açılış Saati",
+    action: "İşlem",
+    type: "Tür",
+    orderPrice: "Emir Fiyatı",
+    entrustPriceHist: "Talep Fiyatı",
+    triggerPrice: "Tetikleme",
+    orderAmt: "Emir Miktarı",
+    filled: "Gerçekleşen",
+    tpPrice: "Kar Alım(TP)",
+    slPrice: "Zarar Durdur(SL)",
+    time: "Saat",
+    orderTime: "Emir Saati",
+    fillTime: "Gerçekleşme Saati",
+    profitUsdt: "Kar (USDT)",
+    tradedVol: "İşlem Hacmi",
+    closeAvg: "Ortalama Kapanış",
+    profitRate: "ROE",
+    closeTime: "Kapanış Saati",
+    directionOpenClose: "Yön/Aç-Kapat",
+    dealPrice: "İşlem Fiyatı",
+    fee: "Komisyon",
+    fundType: "Tür",
+    amount: "Miktar",
+    coin: "Para Birimi",
+    settlementTime: "Ödeme Zamanı",
+    fundingRate: "Funding Oranı",
+    totalBal: "Vadeli Bakiye",
+    availMargin: "Kullanılabilir Marj",
+    usedMargin: "Kullanılan Marj",
+    unrealized: "Gerçekleşmemiş Kar/Zarar",
+    spotWalletBal: "Çekilebilir Bakiye",
+    fundTransfer: "Transfer",
+    avgOpenPrice: "Ortalama Açılış",
+    feeHint: "Komisyon (USDT)",
+    estimatedPnlRow: "Tahmini Kar/Zarar",
+    triggerUsdt: "Tetikleme (USDT)",
+    orderPriceUsdt: "Emir Fiyatı (USDT)",
+    openAvgUsdt: "Ortalama Giriş (USDT)",
+    closeAvgUsdt: "Ortalama Çıkış (USDT)",
+    tpUsdt: "TP (USDT)",
+    slUsdt: "SL (USDT)",
+    marginUsdtBracket: "Marj (USDT)",
+    notionalUsdt: "Pozisyon Değeri (USDT)",
+    estLiqPx: "Tahmini Likidasyon Fiyatı",
+    profitBracketUsdt: "Kar/Zarar (USDT)",
+    entrustVolCoin: "Talep ({base})",
+    filledVolCoin: "Gerçekleşen ({base})",
+    closeAvail: "Kapatılabilir:",
+    markPriceBtn: "İşaret Fiyatı",
   },
   empty: {
-    noPositions: 'Pozisyon Bulunmamaktadır',
-    noOrders: 'Açık Emir Yok',
-    noHistPositions: 'Pozisyon Geçmişi Yok',
-    noHistOrders: 'Emir Geçmişi Yok',
-    noTradeRecords: 'İşlem Kaydı Yok',
-    noFunding: 'Funding Kaydı Yok',
+    noPositions: "Pozisyon Bulunmamaktadır",
+    noOrders: "Açık Emir Yok",
+    noHistPositions: "Pozisyon Geçmişi Yok",
+    noHistOrders: "Emir Geçmişi Yok",
+    noTradeRecords: "İşlem Kaydı Yok",
+    noFunding: "Funding Kaydı Yok",
   },
   modal: {
-    confirmDefaultTitle: 'Onayla',
-    positionDetailTitle: 'Pozisyon Detayı',
-    orderDetailTitle: 'Emir Detayı',
-    histPositionDetailTitle: 'Geçmiş Pozisyon',
-    histOrderDetailTitle: 'Geçmiş Emir',
-    closePositionTitlePrefix: 'Kapat',
-    modifyTpSl: 'TP/SL Düzenle',
-    setTpSl: 'TP/SL Ayarla',
-    posQtyLabel: 'Miktar:',
-    currentTpSlSection: 'Aktif TP/SL Emirleri',
-    modifyToSection: 'Yeni Değer',
-    setPricesSection: 'Fiyatlar',
-    tpTriggerLabel: 'TP Tetikleme ',
-    tpHintOptionalClear: '(Boş bırak = TP sil)',
-    slTriggerLabel: 'SL Tetikleme ',
-    slHintOptionalClear: '(Boş bırak = SL sil)',
-    placeholderTpTrigger: 'TP tetik fiyatı',
-    placeholderSlTrigger: 'SL tetik fiyatı',
-    confirmCloseBtn: 'Kapatmayı Onayla',
-    ok: 'Tamam',
-    closeTypeLiquidation: 'Likide Edildi',
-    tpBadge: 'TP',
-    slBadge: 'SL',
-    tpPriceWord: 'TP ',
-    slPriceWord: 'SL ',
-    volLabel: 'Miktar:',
-    marginSplitMode: 'Çapraz / Ayrık Marj',
-    directionLabel: 'Yön',
-    entrustTypeLabel: 'Emir Türü',
-    leverageLabel: 'Kaldıraç',
+    confirmDefaultTitle: "Onayla",
+    positionDetailTitle: "Pozisyon Detayı",
+    orderDetailTitle: "Emir Detayı",
+    histPositionDetailTitle: "Geçmiş Pozisyon",
+    histOrderDetailTitle: "Geçmiş Emir",
+    closePositionTitlePrefix: "Kapat",
+    modifyTpSl: "TP/SL Düzenle",
+    setTpSl: "TP/SL Ayarla",
+    posQtyLabel: "Miktar:",
+    currentTpSlSection: "Aktif TP/SL Emirleri",
+    modifyToSection: "Yeni Değer",
+    setPricesSection: "Fiyatlar",
+    tpTriggerLabel: "TP Tetikleme ",
+    tpHintOptionalClear: "(Boş bırak = TP sil)",
+    slTriggerLabel: "SL Tetikleme ",
+    slHintOptionalClear: "(Boş bırak = SL sil)",
+    placeholderTpTrigger: "TP tetik fiyatı",
+    placeholderSlTrigger: "SL tetik fiyatı",
+    confirmCloseBtn: "Kapatmayı Onayla",
+    ok: "Tamam",
+    closeTypeLiquidation: "Likide Edildi",
+    tpBadge: "TP",
+    slBadge: "SL",
+    tpPriceWord: "TP ",
+    slPriceWord: "SL ",
+    volLabel: "Miktar:",
+    marginSplitMode: "Çapraz / Ayrık Marj",
+    directionLabel: "Yön",
+    entrustTypeLabel: "Emir Türü",
+    leverageLabel: "Kaldıraç",
+  },
+  actions: {
+    tpSl: "TP/SL",
+    reverse: "Yön Çevir",
+    close: "Kapat",
+    marketCloseAll: "Tümünü Piyasadan Kapat",
+    cancelOrder: "İptal",
   },
-  actions: { tpSl: 'TP/SL', reverse: 'Yön Çevir', close: 'Kapat', marketCloseAll: 'Tümünü Piyasadan Kapat', cancelOrder: 'İptal' },
-  positionRow: { hintCross: 'Çapraz', hintExperience: 'Bonus' },
+  positionRow: { hintCross: "Çapraz", hintExperience: "Bonus" },
   errors: {
-    enterTriggerPrice: 'Tetikleme fiyatı giriniz',
-    enterPrice: 'Fiyat giriniz',
-    priceNotReadyConvert: 'Fiyat verisi hazır değil, hesaplama yapılamaz',
-    invalidQtyCheckMin: 'Miktar geçersiz, minimum kontrol edin',
-    priceNotReadyRetry: 'Fiyat erişilemez, daha sonra deneyin',
-    enterQty: 'Miktar giriniz',
-    qtyExceedAvail: 'Miktar kapatılabilir tutardan fazla',
-    closeFailed: 'Kapatma Başarısız',
-    modifyTpSlFailed: 'Güncelleme başarısız, tekrar deneyin',
-    txFallback: 'Tür {n}',
+    enterTriggerPrice: "Tetikleme fiyatı giriniz",
+    enterPrice: "Fiyat giriniz",
+    priceNotReadyConvert: "Fiyat verisi hazır değil, hesaplama yapılamaz",
+    invalidQtyCheckMin: "Miktar geçersiz, minimum kontrol edin",
+    priceNotReadyRetry: "Fiyat erişilemez, daha sonra deneyin",
+    enterQty: "Miktar giriniz",
+    qtyExceedAvail: "Miktar kapatılabilir tutardan fazla",
+    closeFailed: "Kapatma Başarısız",
+    modifyTpSlFailed: "Güncelleme başarısız, tekrar deneyin",
+    txFallback: "Tür {n}",
   },
   confirm: {
-    reverseTitle: 'Pozisyonu Yön Çevir',
-    reverseBody: '{pair} {side} pozisyonu çevirilsin mi?',
-    cancelAllTitle: 'Tümünü İptal Et',
-    cancelAllBody: '{n} adet emir iptal edilsin mi?',
-    closeAllTitle: 'Tüm Pozisyonları Kapat',
-    closeAllBody: '{n} pozisyon piyasadan kapatılsın mı?',
-    sideLongWord: 'Long',
-    sideShortWord: 'Short',
+    reverseTitle: "Pozisyonu Yön Çevir",
+    reverseBody: "{pair} {side} pozisyonu çevirilsin mi?",
+    cancelAllTitle: "Tümünü İptal Et",
+    cancelAllBody: "{n} adet emir iptal edilsin mi?",
+    closeAllTitle: "Tüm Pozisyonları Kapat",
+    closeAllBody: "{n} pozisyon piyasadan kapatılsın mı?",
+    sideLongWord: "Long",
+    sideShortWord: "Short",
   },
   directions: {
-    long: 'Long',
-    short: 'Short',
-    openLong: 'Long Aç',
-    openShort: 'Short Aç',
-    closeShort: 'Short Kapat',
-    closeLong: 'Long Kapat',
-    openTag: 'A',
-    closeTag: 'K',
+    long: "Long",
+    short: "Short",
+    openLong: "Long Aç",
+    openShort: "Short Aç",
+    closeShort: "Short Kapat",
+    closeLong: "Long Kapat",
+    openTag: "A",
+    closeTag: "K",
+  },
+  orderTypes: {
+    limit: "Limit",
+    plan: "Tetiklemeli",
+    takeProfit: "TP",
+    stopLoss: "SL",
+    marketShort: "Piyasa",
+  },
+  orderStatus: {
+    filled: "Gerçekleşti",
+    open: "Açık",
+    cancelled: "İptal",
+    failed: "Hata",
   },
-  orderTypes: { limit: 'Limit', plan: 'Tetiklemeli', takeProfit: 'TP', stopLoss: 'SL', marketShort: 'Piyasa' },
-  orderStatus: { filled: 'Gerçekleşti', open: 'Açık', cancelled: 'İptal', failed: 'Hata' },
   closeTypes: {
-    market: 'Piyasa Kapanışı',
-    oneClick: 'Tek Tıkla Kapat',
-    reverseOpen: 'Karşı Pozisyon Açma',
-    tpSl: 'TP/SL',
-    liquidation: 'Likidasyon',
-    admin: 'Yönetim Kapatması',
+    market: "Piyasa Kapanışı",
+    oneClick: "Tek Tıkla Kapat",
+    reverseOpen: "Karşı Pozisyon Açma",
+    tpSl: "TP/SL",
+    liquidation: "Likidasyon",
+    admin: "Yönetim Kapatması",
   },
-}
+};

+ 260 - 233
code/src/locales/futuresPage/overlays/vi.ts

@@ -1,267 +1,294 @@
-import type { DeepPartial, FuturesPageMessages } from '../../futuresPage.i18n'
+import type { DeepPartial, FuturesPageMessages } from "../../futuresPage.i18n";
 
 export const viUiOverlay: DeepPartial<FuturesPageMessages> = {
-  perpetual: 'Hợp đồng vĩnh viễn',
-  perpetualTag: 'Vĩnh viễn',
-  pairSearchPlaceholder: 'Tìm kiếm',
-  pairEmpty: 'Không tìm thấy kết quả',
+  perpetual: "Hợp đồng vĩnh viễn",
+  perpetualTag: "Vĩnh viễn",
+  pairSearchPlaceholder: "Tìm kiếm",
+  pairSearchTag: {
+    oneType: "Tiền Điện Tử",
+    twoType: "Cổ Phiếu",
+    threeType: "Kim Loại Quý",
+    fourType: "Ngoại Hối",
+  },
+  pairEmpty: "Không tìm thấy kết quả",
   stats: {
-    change24h: 'Thay đổi 24h',
-    markPrice: 'Giá tham chiếu',
-    high24h: 'Cao nhất 24h',
-    low24h: 'Thấp nhất 24h',
-    volume24h: 'Khối lượng 24h',
-    fundingCountdown: 'Funding / Đếm ngược',
+    change24h: "Thay đổi 24h",
+    markPrice: "Giá tham chiếu",
+    high24h: "Cao nhất 24h",
+    low24h: "Thấp nhất 24h",
+    volume24h: "Khối lượng 24h",
+    fundingCountdown: "Funding / Đếm ngược",
+  },
+  mobileTabs: { chart: "Biểu đồ", trade: "Giao dịch" },
+  chartSub: {
+    chart: "Biểu đồ",
+    coinInfo: "Thông tin coin",
+    fundingHistory: "Lịch sử funding",
   },
-  mobileTabs: { chart: 'Biểu đồ', trade: 'Giao dịch' },
-  chartSub: { chart: 'Biểu đồ', coinInfo: 'Thông tin coin', fundingHistory: 'Lịch sử funding' },
-  chartTools: { fullscreen: 'Toàn màn hình', alert: 'Thông báo' },
+  chartTools: { fullscreen: "Toàn màn hình", alert: "Thông báo" },
   draw: {
-    cursor: 'Con trỏ',
-    trend: 'Đường xu hướng',
-    hline: 'Đường ngang',
-    ray: 'Tia',
-    channel: 'Kênh giá',
-    fib: 'Fibonacci',
-    text: 'Chữ viết',
-    clearAll: 'Xóa tất cả nét vẽ',
-    zoomOut: 'Thu nhỏ',
+    cursor: "Con trỏ",
+    trend: "Đường xu hướng",
+    hline: "Đường ngang",
+    ray: "Tia",
+    channel: "Kênh giá",
+    fib: "Fibonacci",
+    text: "Chữ viết",
+    clearAll: "Xóa tất cả nét vẽ",
+    zoomOut: "Thu nhỏ",
   },
   ohlcv: {
-    open: 'Mở',
-    high: 'Cao',
-    low: 'Thấp',
-    close: 'Đóng',
-    volume: 'Khối lượng',
-    changePct: 'Tỷ lệ đổi',
-    amplitude: 'Biên độ',
+    open: "Mở",
+    high: "Cao",
+    low: "Thấp",
+    close: "Đóng",
+    volume: "Khối lượng",
+    changePct: "Tỷ lệ đổi",
+    amplitude: "Biên độ",
   },
   coinInfo: {
-    marketCap: 'Vốn hóa thị trường',
-    circulating: 'Nguồn cung lưu hành',
-    issuePrice: 'Giá phát hành',
-    ath: 'Đỉnh cao nhất mọi thời đại',
-    athDate: 'Ngày ATH',
-    whitepaper: 'Tài liệu trắng',
-    empty: 'Không có dữ liệu coin',
-    reload: 'Tải lại',
+    marketCap: "Vốn hóa thị trường",
+    circulating: "Nguồn cung lưu hành",
+    issuePrice: "Giá phát hành",
+    ath: "Đỉnh cao nhất mọi thời đại",
+    athDate: "Ngày ATH",
+    whitepaper: "Tài liệu trắng",
+    empty: "Không có dữ liệu coin",
+    reload: "Tải lại",
   },
   fundingPanel: {
-    rate: 'Tỷ lệ funding',
-    period: 'Chu kỳ thanh toán',
-    nextCountdown: 'Đếm ngược kỳ tiếp theo',
-    noChart: 'Không có dữ liệu biểu đồ',
-    settleTime: 'Thời gian thanh toán',
-    rateCol: 'Tỷ lệ funding',
-    empty7d: 'Không có dữ liệu 7 ngày',
+    rate: "Tỷ lệ funding",
+    period: "Chu kỳ thanh toán",
+    nextCountdown: "Đếm ngược kỳ tiếp theo",
+    noChart: "Không có dữ liệu biểu đồ",
+    settleTime: "Thời gian thanh toán",
+    rateCol: "Tỷ lệ funding",
+    empty7d: "Không có dữ liệu 7 ngày",
   },
   book: {
-    orderBook: 'Sổ lệnh',
-    trades: 'Giao dịch khớp',
-    priceQuote: 'Giá (USDT)',
-    amountBase: 'Số lượng ({base})',
-    totalBase: 'Tổng ({base})',
-    time: 'Thời gian',
-    buy: 'Mua',
-    sell: 'Bán',
-    buyRatio: 'Mua {n}%',
-    sellRatio: 'Bán {n}%',
-    noTrades: 'Chưa có giao dịch',
+    orderBook: "Sổ lệnh",
+    trades: "Giao dịch khớp",
+    priceQuote: "Giá (USDT)",
+    amountBase: "Số lượng ({base})",
+    totalBase: "Tổng ({base})",
+    time: "Thời gian",
+    buy: "Mua",
+    sell: "Bán",
+    buyRatio: "Mua {n}%",
+    sellRatio: "Bán {n}%",
+    noTrades: "Chưa có giao dịch",
   },
-  margin: { cross: 'Ký quỹ chéo', split: 'Ký quỹ riêng', experience: 'Thưởng' },
-  amountUnit: { lots: 'Hợp đồng', usdt: 'USDT' },
-  leverage: { adjustTitle: 'Điều chỉnh đòn bẩy' },
+  margin: { cross: "Ký quỹ chéo", split: "Ký quỹ riêng", experience: "Thưởng" },
+  amountUnit: { lots: "Hợp đồng", usdt: "USDT" },
+  leverage: { adjustTitle: "Điều chỉnh đòn bẩy" },
   order: {
-    limit: 'Lệnh giới hạn',
-    market: 'Lệnh thị trường',
-    conditional: 'Lệnh có điều kiện',
-    condMarket: 'Thị trường có điều kiện',
-    condLimit: 'Giới hạn có điều kiện',
-    available: 'Có sẵn',
-    maxOpen: 'Tối đa mở lệnh',
-    triggerPriceLabel: 'Giá kích hoạt ({q})',
-    priceLabel: 'Giá ({q})',
-    latestBtn: 'Giá mới nhất',
-    marketExe: 'Khớp thị trường',
-    condMarketExe: 'Khớp thị trường sau kích hoạt',
-    qtyLabel: 'Số lượng ({u})',
-    transferTitle: 'Chuyển tiền',
-    openLong: 'Mua / Long',
-    openShort: 'Bán / Short',
-    contractInfoTitle: 'Thông tin hợp đồng',
-    indexSource: 'Nguồn chỉ số',
-    marginCoin: 'Tài sản ký quỹ',
-    maxLeverage: 'Đòn bẩy tối đa',
-    maintMargin: 'Tỷ lệ ký quỹ duy trì',
-    openFee: 'Phí mở lệnh',
-    closeFee: 'Phí đóng lệnh',
-    contractValue: 'Giá trị hợp đồng',
-    minOrder: 'Lệnh tối thiểu',
-    maxOrder: 'Lệnh tối đa',
+    limit: "Lệnh giới hạn",
+    market: "Lệnh thị trường",
+    conditional: "Lệnh có điều kiện",
+    condMarket: "Thị trường có điều kiện",
+    condLimit: "Giới hạn có điều kiện",
+    available: "Có sẵn",
+    maxOpen: "Tối đa mở lệnh",
+    triggerPriceLabel: "Giá kích hoạt ({q})",
+    priceLabel: "Giá ({q})",
+    latestBtn: "Giá mới nhất",
+    marketExe: "Khớp thị trường",
+    condMarketExe: "Khớp thị trường sau kích hoạt",
+    qtyLabel: "Số lượng ({u})",
+    transferTitle: "Chuyển tiền",
+    openLong: "Mua / Long",
+    openShort: "Bán / Short",
+    contractInfoTitle: "Thông tin hợp đồng",
+    indexSource: "Nguồn chỉ số",
+    marginCoin: "Tài sản ký quỹ",
+    maxLeverage: "Đòn bẩy tối đa",
+    maintMargin: "Tỷ lệ ký quỹ duy trì",
+    openFee: "Phí mở lệnh",
+    closeFee: "Phí đóng lệnh",
+    contractValue: "Giá trị hợp đồng",
+    minOrder: "Lệnh tối thiểu",
+    maxOrder: "Lệnh tối đa",
   },
   placeholders: {
-    searchPair: 'Tìm kiếm',
-    triggerPrice: 'Nhập giá kích hoạt',
-    price: 'Nhập giá',
-    amount: 'Nhập số lượng',
+    searchPair: "Tìm kiếm",
+    triggerPrice: "Nhập giá kích hoạt",
+    price: "Nhập giá",
+    amount: "Nhập số lượng",
   },
   bottom: {
-    positions: 'Vị thế',
-    openOrders: 'Lệnh đang mở',
-    historyOrders: 'Lịch sử lệnh',
-    historyPositions: 'Lịch sử vị thế',
-    tradeDetails: 'Chi tiết giao dịch',
-    fundingFlow: 'Lịch sử funding',
-    assets: 'Tài sản',
-    closeAllPositions: 'Đóng tất cả',
-    cancelAllOrders: 'Hủy toàn bộ lệnh',
-    loginPromptOr: 'hoặc',
-    registerNow: 'Đăng ký',
-    startTrading: 'Bắt đầu giao dịch',
+    positions: "Vị thế",
+    openOrders: "Lệnh đang mở",
+    historyOrders: "Lịch sử lệnh",
+    historyPositions: "Lịch sử vị thế",
+    tradeDetails: "Chi tiết giao dịch",
+    fundingFlow: "Lịch sử funding",
+    assets: "Tài sản",
+    closeAllPositions: "Đóng tất cả",
+    cancelAllOrders: "Hủy toàn bộ lệnh",
+    loginPromptOr: "hoặc",
+    registerNow: "Đăng ký",
+    startTrading: "Bắt đầu giao dịch",
   },
   table: {
-    contract: 'Hợp đồng',
-    dirLeverage: 'Hướng/Đòn bẩy',
-    openPrice: 'Giá mở',
-    markPrice: 'Giá tham chiếu',
-    positionSize: 'Quy mô vị thế',
-    margin: 'Ký quỹ',
-    marginRate: 'Tỷ lệ ký quỹ',
-    unrealizedPnl: 'Lãi lỗ chưa thực hiện',
-    roe: 'ROE',
-    liqPrice: 'Giá thanh lý',
-    openTime: 'Thời gian mở',
-    action: 'Thao tác',
-    type: 'Loại',
-    orderPrice: 'Giá lệnh',
-    entrustPriceHist: 'Giá đặt lệnh',
-    triggerPrice: 'Giá kích hoạt',
-    orderAmt: 'Khối lượng lệnh',
-    filled: 'Đã khớp',
-    tpPrice: 'Chốt lời TP',
-    slPrice: 'Cắt lỗ SL',
-    time: 'Thời gian',
-    orderTime: 'Thời gian đặt lệnh',
-    fillTime: 'Thời gian khớp',
-    profitUsdt: 'Lãi lỗ (USDT)',
-    tradedVol: 'Khối lượng khớp',
-    closeAvg: 'Giá đóng trung bình',
-    profitRate: 'ROE',
-    closeTime: 'Thời gian đóng',
-    directionOpenClose: 'Hướng/Mở-Đóng',
-    dealPrice: 'Giá khớp',
-    fee: 'Phí',
-    fundType: 'Loại',
-    amount: 'Số lượng',
-    coin: 'Tiền tệ',
-    settlementTime: 'Ngày thanh toán',
-    fundingRate: 'Tỷ lệ funding',
-    totalBal: 'Số dư hợp đồng tương lai',
-    availMargin: 'Ký quỹ khả dụng',
-    usedMargin: 'Ký quỹ đã dùng',
-    unrealized: 'Lãi lỗ chưa thực hiện',
-    spotWalletBal: 'Số dư có thể rút',
-    fundTransfer: 'Chuyển quỹ',
-    avgOpenPrice: 'Giá mở trung bình',
-    feeHint: 'Phí (USDT)',
-    estimatedPnlRow: 'Lãi lỗ dự kiến',
-    triggerUsdt: 'Kích hoạt (USDT)',
-    orderPriceUsdt: 'Giá lệnh (USDT)',
-    openAvgUsdt: 'Vào lệnh TB (USDT)',
-    closeAvgUsdt: 'Ra lệnh TB (USDT)',
-    tpUsdt: 'TP (USDT)',
-    slUsdt: 'SL (USDT)',
-    marginUsdtBracket: 'Ký quỹ (USDT)',
-    notionalUsdt: 'Giá trị vị thế (USDT)',
-    estLiqPx: 'Giá thanh lý dự tính',
-    profitBracketUsdt: 'Lãi lỗ (USDT)',
-    entrustVolCoin: 'Đặt lệnh ({base})',
-    filledVolCoin: 'Đã khớp ({base})',
-    closeAvail: 'Có thể đóng:',
-    markPriceBtn: 'Giá tham chiếu',
+    contract: "Hợp đồng",
+    dirLeverage: "Hướng/Đòn bẩy",
+    openPrice: "Giá mở",
+    markPrice: "Giá tham chiếu",
+    positionSize: "Quy mô vị thế",
+    margin: "Ký quỹ",
+    marginRate: "Tỷ lệ ký quỹ",
+    unrealizedPnl: "Lãi lỗ chưa thực hiện",
+    roe: "ROE",
+    liqPrice: "Giá thanh lý",
+    openTime: "Thời gian mở",
+    action: "Thao tác",
+    type: "Loại",
+    orderPrice: "Giá lệnh",
+    entrustPriceHist: "Giá đặt lệnh",
+    triggerPrice: "Giá kích hoạt",
+    orderAmt: "Khối lượng lệnh",
+    filled: "Đã khớp",
+    tpPrice: "Chốt lời TP",
+    slPrice: "Cắt lỗ SL",
+    time: "Thời gian",
+    orderTime: "Thời gian đặt lệnh",
+    fillTime: "Thời gian khớp",
+    profitUsdt: "Lãi lỗ (USDT)",
+    tradedVol: "Khối lượng khớp",
+    closeAvg: "Giá đóng trung bình",
+    profitRate: "ROE",
+    closeTime: "Thời gian đóng",
+    directionOpenClose: "Hướng/Mở-Đóng",
+    dealPrice: "Giá khớp",
+    fee: "Phí",
+    fundType: "Loại",
+    amount: "Số lượng",
+    coin: "Tiền tệ",
+    settlementTime: "Ngày thanh toán",
+    fundingRate: "Tỷ lệ funding",
+    totalBal: "Số dư hợp đồng tương lai",
+    availMargin: "Ký quỹ khả dụng",
+    usedMargin: "Ký quỹ đã dùng",
+    unrealized: "Lãi lỗ chưa thực hiện",
+    spotWalletBal: "Số dư có thể rút",
+    fundTransfer: "Chuyển quỹ",
+    avgOpenPrice: "Giá mở trung bình",
+    feeHint: "Phí (USDT)",
+    estimatedPnlRow: "Lãi lỗ dự kiến",
+    triggerUsdt: "Kích hoạt (USDT)",
+    orderPriceUsdt: "Giá lệnh (USDT)",
+    openAvgUsdt: "Vào lệnh TB (USDT)",
+    closeAvgUsdt: "Ra lệnh TB (USDT)",
+    tpUsdt: "TP (USDT)",
+    slUsdt: "SL (USDT)",
+    marginUsdtBracket: "Ký quỹ (USDT)",
+    notionalUsdt: "Giá trị vị thế (USDT)",
+    estLiqPx: "Giá thanh lý dự tính",
+    profitBracketUsdt: "Lãi lỗ (USDT)",
+    entrustVolCoin: "Đặt lệnh ({base})",
+    filledVolCoin: "Đã khớp ({base})",
+    closeAvail: "Có thể đóng:",
+    markPriceBtn: "Giá tham chiếu",
   },
   empty: {
-    noPositions: 'Chưa có vị thế',
-    noOrders: 'Không có lệnh',
-    noHistPositions: 'Không có lịch sử vị thế',
-    noHistOrders: 'Không có lịch sử lệnh',
-    noTradeRecords: 'Không có giao dịch',
-    noFunding: 'Không có dữ liệu funding',
+    noPositions: "Chưa có vị thế",
+    noOrders: "Không có lệnh",
+    noHistPositions: "Không có lịch sử vị thế",
+    noHistOrders: "Không có lịch sử lệnh",
+    noTradeRecords: "Không có giao dịch",
+    noFunding: "Không có dữ liệu funding",
   },
   modal: {
-    confirmDefaultTitle: 'Xác nhận',
-    positionDetailTitle: 'Chi tiết vị thế',
-    orderDetailTitle: 'Chi tiết lệnh',
-    histPositionDetailTitle: 'Vị thế lịch sử',
-    histOrderDetailTitle: 'Lệnh lịch sử',
-    closePositionTitlePrefix: 'Đóng',
-    modifyTpSl: 'Sửa TP/SL',
-    setTpSl: 'Cài TP/SL',
-    posQtyLabel: 'Số lượng:',
-    currentTpSlSection: 'Lệnh TP/SL đang hiệu lực',
-    modifyToSection: 'Đổi thành',
-    setPricesSection: 'Bảng giá',
-    tpTriggerLabel: 'Kích hoạt TP ',
-    tpHintOptionalClear: '(để trống = xóa TP)',
-    slTriggerLabel: 'Kích hoạt SL ',
-    slHintOptionalClear: '(để trống = xóa SL)',
-    placeholderTpTrigger: 'Giá kích hoạt TP',
-    placeholderSlTrigger: 'Giá kích hoạt SL',
-    confirmCloseBtn: 'Xác nhận đóng',
-    ok: 'OK',
-    closeTypeLiquidation: 'Bị thanh lý',
-    tpBadge: 'TP',
-    slBadge: 'SL',
-    tpPriceWord: 'TP ',
-    slPriceWord: 'SL ',
-    volLabel: 'Số lượng:',
-    marginSplitMode: 'Ký quỹ chéo / Riêng',
-    directionLabel: 'Hướng',
-    entrustTypeLabel: 'Loại lệnh',
-    leverageLabel: 'Đòn bẩy',
+    confirmDefaultTitle: "Xác nhận",
+    positionDetailTitle: "Chi tiết vị thế",
+    orderDetailTitle: "Chi tiết lệnh",
+    histPositionDetailTitle: "Vị thế lịch sử",
+    histOrderDetailTitle: "Lệnh lịch sử",
+    closePositionTitlePrefix: "Đóng",
+    modifyTpSl: "Sửa TP/SL",
+    setTpSl: "Cài TP/SL",
+    posQtyLabel: "Số lượng:",
+    currentTpSlSection: "Lệnh TP/SL đang hiệu lực",
+    modifyToSection: "Đổi thành",
+    setPricesSection: "Bảng giá",
+    tpTriggerLabel: "Kích hoạt TP ",
+    tpHintOptionalClear: "(để trống = xóa TP)",
+    slTriggerLabel: "Kích hoạt SL ",
+    slHintOptionalClear: "(để trống = xóa SL)",
+    placeholderTpTrigger: "Giá kích hoạt TP",
+    placeholderSlTrigger: "Giá kích hoạt SL",
+    confirmCloseBtn: "Xác nhận đóng",
+    ok: "OK",
+    closeTypeLiquidation: "Bị thanh lý",
+    tpBadge: "TP",
+    slBadge: "SL",
+    tpPriceWord: "TP ",
+    slPriceWord: "SL ",
+    volLabel: "Số lượng:",
+    marginSplitMode: "Ký quỹ chéo / Riêng",
+    directionLabel: "Hướng",
+    entrustTypeLabel: "Loại lệnh",
+    leverageLabel: "Đòn bẩy",
+  },
+  actions: {
+    tpSl: "TP/SL",
+    reverse: "Đảo lệnh",
+    close: "Đóng",
+    marketCloseAll: "Đóng tất thị trường",
+    cancelOrder: "Hủy",
   },
-  actions: { tpSl: 'TP/SL', reverse: 'Đảo lệnh', close: 'Đóng', marketCloseAll: 'Đóng tất thị trường', cancelOrder: 'Hủy' },
-  positionRow: { hintCross: 'Chéo', hintExperience: 'Thưởng' },
+  positionRow: { hintCross: "Chéo", hintExperience: "Thưởng" },
   errors: {
-    enterTriggerPrice: 'Vui lòng nhập giá kích hoạt',
-    enterPrice: 'Vui lòng nhập giá',
-    priceNotReadyConvert: 'Chưa có giá, không tính được',
-    invalidQtyCheckMin: 'Số lượng không hợp lệ, kiểm tra mức tối thiểu',
-    priceNotReadyRetry: 'Không lấy được giá, thử lại sau',
-    enterQty: 'Nhập số lượng',
-    qtyExceedAvail: 'Số lượng lớn hơn lượng có thể đóng',
-    closeFailed: 'Đóng lệnh thất bại',
-    modifyTpSlFailed: 'Sửa lỗi, thử lại sau',
-    txFallback: 'Loại {n}',
+    enterTriggerPrice: "Vui lòng nhập giá kích hoạt",
+    enterPrice: "Vui lòng nhập giá",
+    priceNotReadyConvert: "Chưa có giá, không tính được",
+    invalidQtyCheckMin: "Số lượng không hợp lệ, kiểm tra mức tối thiểu",
+    priceNotReadyRetry: "Không lấy được giá, thử lại sau",
+    enterQty: "Nhập số lượng",
+    qtyExceedAvail: "Số lượng lớn hơn lượng có thể đóng",
+    closeFailed: "Đóng lệnh thất bại",
+    modifyTpSlFailed: "Sửa lỗi, thử lại sau",
+    txFallback: "Loại {n}",
   },
   confirm: {
-    reverseTitle: 'Đảo chiều vị thế',
-    reverseBody: 'Đảo {pair} {side}?',
-    cancelAllTitle: 'Hủy tất cả',
-    cancelAllBody: 'Hủy {n} lệnh?',
-    closeAllTitle: 'Đóng toàn bộ',
-    closeAllBody: 'Đóng {n} vị thế theo giá thị trường?',
-    sideLongWord: 'Long',
-    sideShortWord: 'Short',
+    reverseTitle: "Đảo chiều vị thế",
+    reverseBody: "Đảo {pair} {side}?",
+    cancelAllTitle: "Hủy tất cả",
+    cancelAllBody: "Hủy {n} lệnh?",
+    closeAllTitle: "Đóng toàn bộ",
+    closeAllBody: "Đóng {n} vị thế theo giá thị trường?",
+    sideLongWord: "Long",
+    sideShortWord: "Short",
   },
   directions: {
-    long: 'Long',
-    short: 'Short',
-    openLong: 'Mở Long',
-    openShort: 'Mở Short',
-    closeShort: 'Đóng Short',
-    closeLong: 'Đóng Long',
-    openTag: 'M',
-    closeTag: 'Đ',
+    long: "Long",
+    short: "Short",
+    openLong: "Mở Long",
+    openShort: "Mở Short",
+    closeShort: "Đóng Short",
+    closeLong: "Đóng Long",
+    openTag: "M",
+    closeTag: "Đ",
+  },
+  orderTypes: {
+    limit: "Giới hạn",
+    plan: "Kích hoạt",
+    takeProfit: "TP",
+    stopLoss: "SL",
+    marketShort: "Thị trường",
+  },
+  orderStatus: {
+    filled: "Đã khớp",
+    open: "Đang mở",
+    cancelled: "Đã hủy",
+    failed: "Thất bại",
   },
-  orderTypes: { limit: 'Giới hạn', plan: 'Kích hoạt', takeProfit: 'TP', stopLoss: 'SL', marketShort: 'Thị trường' },
-  orderStatus: { filled: 'Đã khớp', open: 'Đang mở', cancelled: 'Đã hủy', failed: 'Thất bại' },
   closeTypes: {
-    market: 'Đóng theo thị trường',
-    oneClick: 'Đóng một chạm',
-    reverseOpen: 'Mở lệnh ngược',
-    tpSl: 'TP/SL',
-    liquidation: 'Thanh lý',
-    admin: 'Quản trị đóng',
+    market: "Đóng theo thị trường",
+    oneClick: "Đóng một chạm",
+    reverseOpen: "Mở lệnh ngược",
+    tpSl: "TP/SL",
+    liquidation: "Thanh lý",
+    admin: "Quản trị đóng",
   },
-}
+};

+ 1 - 1
code/src/locales/hi.ts

@@ -15,7 +15,7 @@ export default {
 		download: 'डाउनलोड',
 	},
 	lang: {
-		title: '语言',
+		title: 'भाषा',
 		zhCN: '简体中文',
 		zhTW: '繁體中文',
 		en: 'English',

+ 173 - 141
code/src/stores/coins.ts

@@ -1,112 +1,119 @@
-import { defineStore } from 'pinia'
-import { ref, computed } from 'vue'
-import { get } from '@/utils/request'
-import type { Ticker } from './futures'
+import { defineStore } from "pinia";
+import { ref, computed } from "vue";
+import { get } from "@/utils/request";
+import type { Ticker } from "./futures";
 
-const WS_URL = import.meta.env.VITE_WS_MARKET_URL as string
+const WS_URL = import.meta.env.VITE_WS_MARKET_URL as string;
 
 // 本地图标映射(API icon 字段目前均为 null)
 const COIN_ICONS: Record<string, string> = {
-  BTC:   '/coins/btc.png',
-  ETH:   '/coins/eth.png',
-  BNB:   '/coins/bnb.png',
-  SOL:   '/coins/sol.png',
-  XRP:   '/coins/xrp.png',
-  ADA:   '/coins/ada.png',
-  DOGE:  '/coins/doge.png',
-  LTC:   '/coins/ltc.png',
-  TRX:   '/coins/trx.png',
-  DOT:   '/coins/dot.png',
-  LINK:  '/coins/link.png',
-  AVAX:  '/coins/avax.png',
-  MATIC: '/coins/matic.png',
-  UNI:   '/coins/uni.png',
-  ATOM:  '/coins/atom.png',
-  ETC:   '/coins/etc.png',
-  FIL:   '/coins/fil.png',
-  NEAR:  '/coins/near.png',
-  OP:    '/coins/op.png',
-  ARB:   '/coins/arb.png',
-  BCH:   '/coins/bch.png',
-  AAVE:  '/coins/aave.png',
-  ALGO:  '/coins/algo.png',
-  APE:   '/coins/ape.png',
-  AXS:   '/coins/axs.png',
-  CHZ:   '/coins/chz.png',
-  SUSHI: '/coins/sushi.png',
-  TRUMP: '/coins/trump.png',
-}
+  BTC: "/coins/btc.png",
+  ETH: "/coins/eth.png",
+  BNB: "/coins/bnb.png",
+  SOL: "/coins/sol.png",
+  XRP: "/coins/xrp.png",
+  ADA: "/coins/ada.png",
+  DOGE: "/coins/doge.png",
+  LTC: "/coins/ltc.png",
+  TRX: "/coins/trx.png",
+  DOT: "/coins/dot.png",
+  LINK: "/coins/link.png",
+  AVAX: "/coins/avax.png",
+  MATIC: "/coins/matic.png",
+  UNI: "/coins/uni.png",
+  ATOM: "/coins/atom.png",
+  ETC: "/coins/etc.png",
+  FIL: "/coins/fil.png",
+  NEAR: "/coins/near.png",
+  OP: "/coins/op.png",
+  ARB: "/coins/arb.png",
+  BCH: "/coins/bch.png",
+  AAVE: "/coins/aave.png",
+  ALGO: "/coins/algo.png",
+  APE: "/coins/ape.png",
+  AXS: "/coins/axs.png",
+  CHZ: "/coins/chz.png",
+  SUSHI: "/coins/sushi.png",
+  TRUMP: "/coins/trump.png",
+};
 
 // /swap/coin/enabled-list 返回的原始数据结构
 interface RawCoinInfo {
-  id: number
-  name: string
-  symbol: string       // "BTC/USDT"
-  coinSymbol: string   // "BTC"
-  baseSymbol: string   // "USDT"
-  sort: number
-  icon: string | null
-  coinScale: number
-  baseCoinScale: number
-  stockType: number
+  id: number;
+  name: string;
+  symbol: string; // "BTC/USDT"
+  coinSymbol: string; // "BTC"
+  baseSymbol: string; // "USDT"
+  sort: number;
+  icon: string | null;
+  coinScale: number;
+  baseCoinScale: number;
+  stockType: number;
 }
 
 // 内部维护的交易对对象
 export interface CoinContract {
-  id: number
-  symbol: string       // "BTC/USDT"
-  coinSymbol: string   // "BTC"
-  baseSymbol: string   // "USDT"
-  name: string
-  icon: string
-  sort: number
-  coinScale: number
-  baseCoinScale: number
+  id: number;
+  symbol: string; // "BTC/USDT"
+  coinSymbol: string; // "BTC"
+  baseSymbol: string; // "USDT"
+  name: string;
+  icon: string;
+  sort: number;
+  coinScale: number;
+  baseCoinScale: number;
   // 实时价格(WebSocket 更新)
-  open: string
-  high: string
-  low: string
-  close: string
-  chg: string
-  change: string
-  volume: string
-  turnover: string
-  stockType: number
+  open: string;
+  high: string;
+  low: string;
+  close: string;
+  chg: string;
+  change: string;
+  volume: string;
+  turnover: string;
+  stockType: number;
 }
 
-export const useCoinsStore = defineStore('coins', () => {
-  const coins = ref<CoinContract[]>([])
-  const loading = ref(false)
-  const fetched = ref(false)
+export const useCoinsStore = defineStore("coins", () => {
+  const coins = ref<CoinContract[]>([]);
+  const loading = ref(false);
+  const fetched = ref(false);
 
-  let ws: WebSocket | null = null
-  let wsDestroyed = false
-  let pingTimer: ReturnType<typeof setInterval> | null = null
-  let lastMsgTs = 0
+  let ws: WebSocket | null = null;
+  let wsDestroyed = false;
+  let pingTimer: ReturnType<typeof setInterval> | null = null;
+  let lastMsgTs = 0;
 
   function startHeartbeat() {
-    if (pingTimer !== null) clearInterval(pingTimer)
-    lastMsgTs = Date.now()
+    if (pingTimer !== null) clearInterval(pingTimer);
+    lastMsgTs = Date.now();
     pingTimer = setInterval(() => {
       if (Date.now() - lastMsgTs > 30_000) {
         // 30s 无任何消息,触发重连
-        stopHeartbeat()
-        if (ws) { ws.onclose = null; ws.close(); ws = null }
-        if (!wsDestroyed) startLivePrices()
-        return
+        stopHeartbeat();
+        if (ws) {
+          ws.onclose = null;
+          ws.close();
+          ws = null;
+        }
+        if (!wsDestroyed) startLivePrices();
+        return;
       }
       if (ws?.readyState === WebSocket.OPEN) {
-        ws.send(JSON.stringify({ ping: Date.now() }))
+        ws.send(JSON.stringify({ ping: Date.now() }));
       }
-    }, 15_000)
+    }, 15_000);
   }
 
   function stopHeartbeat() {
-    if (pingTimer !== null) { clearInterval(pingTimer); pingTimer = null }
+    if (pingTimer !== null) {
+      clearInterval(pingTimer);
+      pingTimer = null;
+    }
   }
 
   function symSlug(sym: string) {
-    return sym.toLowerCase().replace(/[/-]/g, '')
+    return sym.toLowerCase().replace(/[/-]/g, "");
   }
 
   // Step 1: 请求接口获取交易对列表(名称、图标等静态信息)
@@ -114,98 +121,123 @@ export const useCoinsStore = defineStore('coins', () => {
     if (fetched.value && coins.value.length > 0) {
       // 允许外部在 stopLivePrices 后通过 fetchCoins 重新拉起订阅
       if (!ws || ws.readyState === WebSocket.CLOSED) {
-        startLivePrices()
+        startLivePrices();
       }
-      return
+      return;
     }
-    loading.value = true
+    loading.value = true;
     try {
-      const data = await get<{ data: RawCoinInfo[] }>('/swap/coin/enabled-list')
-      const list = data?.data ?? (Array.isArray(data) ? (data as RawCoinInfo[]) : [])
+      const data = await get<{ data: RawCoinInfo[] }>(
+        "/swap/coin/enabled-list",
+      );
+      const list =
+        data?.data ?? (Array.isArray(data) ? (data as RawCoinInfo[]) : []);
       if (list.length > 0) {
         coins.value = list
           .sort((a, b) => a.sort - b.sort)
-          .map(raw => ({
+          .map((raw) => ({
             id: raw.id,
             symbol: raw.symbol,
             coinSymbol: raw.coinSymbol,
             baseSymbol: raw.baseSymbol,
             name: raw.name,
-            icon: raw.icon ?? COIN_ICONS[raw.coinSymbol] ?? '',
+            icon: raw.icon ?? COIN_ICONS[raw.coinSymbol] ?? "",
             sort: raw.sort,
             coinScale: raw.coinScale ?? 2,
             baseCoinScale: raw.baseCoinScale ?? 4,
             // 价格字段初始为空,等 WebSocket 推送
-            open: '0', high: '0', low: '0', close: '0',
-            chg: '0', change: '0', volume: '0', turnover: '0',
-			stockType: raw.stockType,
-          }))
-        fetched.value = true
+            open: "0",
+            high: "0",
+            low: "0",
+            close: "0",
+            chg: "0",
+            change: "0",
+            volume: "0",
+            turnover: "0",
+            stockType: raw.stockType,
+          }));
+        fetched.value = true;
         // Step 2: 订阅 WebSocket 获取实时价格和涨跌幅
-        startLivePrices()
-		// console.log("搜索列表数据:",coins.value)
+        startLivePrices();
+        // console.log("搜索列表数据:",coins.value)
       }
-    } catch { /* silent */ }
-    loading.value = false
+    } catch {
+      /* silent */
+    }
+    loading.value = false;
   }
 
   // Step 2: WebSocket 订阅所有交易对的 ticker 数据
   function startLivePrices() {
-    if (ws) { ws.onclose = null; ws.close() }
-    wsDestroyed = false
-    ws = new WebSocket(WS_URL)
-    ws.onopen = () => {
-      const topics = coins.value.map(c => `market.${symSlug(c.symbol)}.ticket`)
-      if (topics.length) ws!.send(JSON.stringify({ sub: topics, id: 'coins-tickers' }))
-      startHeartbeat()
+    if (ws) {
+      ws.onclose = null;
+      ws.close();
     }
+    wsDestroyed = false;
+    ws = new WebSocket(WS_URL);
+    ws.onopen = () => {
+      const topics = coins.value.map(
+        (c) => `market.${symSlug(c.symbol)}.ticket`,
+      );
+      if (topics.length)
+        ws!.send(JSON.stringify({ sub: topics, id: "coins-tickers" }));
+      startHeartbeat();
+    };
     ws.onmessage = (e) => {
-      lastMsgTs = Date.now()
-      let msg: any
-      try { msg = JSON.parse(e.data) } catch { return }
+      lastMsgTs = Date.now();
+      let msg: any;
+      try {
+        msg = JSON.parse(e.data);
+      } catch {
+        return;
+      }
       // 处理服务器 pong 回包
-      if (msg.pong !== undefined) return
-      const ch: string = msg.ch ?? ''
-      const tick = msg.tick
-      if (!ch.includes('.ticket') || !tick) return
-      const coin = coins.value.find(c => `market.${symSlug(c.symbol)}.ticket` === ch)
-      if (!coin) return
-      const closeN = parseFloat(tick.c)
-      const openN = parseFloat(tick.o)
-      coin.close = tick.c
-      coin.open = tick.o
-      coin.high = tick.h
-      coin.low = tick.l
-      coin.volume = tick.v
-      coin.turnover = tick.q
-      coin.chg = openN > 0 ? String((closeN - openN) / openN) : '0'
-      coin.change = openN > 0 ? String(closeN - openN) : '0'
-    }
-    ws.onerror = () => {}
+      if (msg.pong !== undefined) return;
+      const ch: string = msg.ch ?? "";
+      const tick = msg.tick;
+      if (!ch.includes(".ticket") || !tick) return;
+      const coin = coins.value.find(
+        (c) => `market.${symSlug(c.symbol)}.ticket` === ch,
+      );
+      if (!coin) return;
+      const closeN = parseFloat(tick.c);
+      const openN = parseFloat(tick.o);
+      coin.close = tick.c;
+      coin.open = tick.o;
+      coin.high = tick.h;
+      coin.low = tick.l;
+      coin.volume = tick.v;
+      coin.turnover = tick.q;
+      coin.chg = openN > 0 ? String((closeN - openN) / openN) : "0";
+      coin.change = openN > 0 ? String(closeN - openN) : "0";
+    };
+    ws.onerror = () => {};
     ws.onclose = () => {
-      stopHeartbeat()
-      if (wsDestroyed) return
-      setTimeout(startLivePrices, 3000)
-    }
+      stopHeartbeat();
+      if (wsDestroyed) return;
+      setTimeout(startLivePrices, 3000);
+    };
   }
 
   function stopLivePrices() {
-    wsDestroyed = true
-    stopHeartbeat()
+    wsDestroyed = true;
+    stopHeartbeat();
     if (ws) {
       if (ws.readyState === WebSocket.OPEN && coins.value.length > 0) {
-        const topics = coins.value.map(c => `market.${symSlug(c.symbol)}.ticket`)
-        ws.send(JSON.stringify({ unsub: topics, id: 'coins-tickers-unsub' }))
+        const topics = coins.value.map(
+          (c) => `market.${symSlug(c.symbol)}.ticket`,
+        );
+        ws.send(JSON.stringify({ unsub: topics, id: "coins-tickers-unsub" }));
       }
-      ws.onclose = null
-      ws.close()
-      ws = null
+      ws.onclose = null;
+      ws.close();
+      ws = null;
     }
   }
 
   // 转为 Ticker[] 格式,供 futures store 使用
   const asTickers = computed<Ticker[]>(() =>
-    coins.value.map(c => ({
+    coins.value.map((c) => ({
       symbol: c.symbol,
       open: c.open,
       high: c.high,
@@ -215,9 +247,9 @@ export const useCoinsStore = defineStore('coins', () => {
       change: c.change,
       volume: c.volume,
       turnover: c.turnover,
-	  stockType: c.stockType,
-    }))
-  )
+      stockType: c.stockType,
+    })),
+  );
 
-  return { coins, loading, fetched, asTickers, fetchCoins, stopLivePrices }
-})
+  return { coins, loading, fetched, asTickers, fetchCoins, stopLivePrices };
+});

+ 194 - 135
code/src/stores/market.ts

@@ -1,260 +1,319 @@
-import { defineStore } from 'pinia'
-import { ref, computed } from 'vue'
-import type { MarketType, CoinDetail, ChartRange, MarketItem } from '@/types'
-import { useCoinsStore } from './coins'
-import { useSpotStore } from './spot'
+import { defineStore } from "pinia";
+import { ref, computed } from "vue";
+import type { MarketType, CoinDetail, ChartRange, MarketItem } from "@/types";
+import { useCoinsStore } from "./coins";
+import { useSpotStore } from "./spot";
 
-const SPOT_WS_URL = import.meta.env.VITE_WS_SPOT_URL as string
+const SPOT_WS_URL = import.meta.env.VITE_WS_SPOT_URL as string;
 
-export const useMarketStore = defineStore('market', () => {
-  const coinsStore = useCoinsStore()
-  const spotStore  = useSpotStore()
+export const useMarketStore = defineStore("market", () => {
+  const coinsStore = useCoinsStore();
+  const spotStore = useSpotStore();
 
   // ── State ──────────────────────────────────────────
-  const activeTab = ref<MarketType>('futures')
-  const searchQuery = ref('')
+  const activeTab = ref<MarketType>("futures");
+  const searchQuery = ref("");
 
   // ── 现货实时价格缓存 ────────────────────────────────
   interface SpotTick {
-    close: number; open: number; high: number; low: number; turnover: number
+    close: number;
+    open: number;
+    high: number;
+    low: number;
+    turnover: number;
   }
-  const spotTicks = ref<Map<string, SpotTick>>(new Map())
-  const spotLoading = ref(false)
-  let spotWs: WebSocket | null = null
-  let spotWsDestroyed = false
-  let spotPingTimer: ReturnType<typeof setInterval> | null = null
-  let spotLastMsgTs = 0
+  const spotTicks = ref<Map<string, SpotTick>>(new Map());
+  const spotLoading = ref(false);
+  let spotWs: WebSocket | null = null;
+  let spotWsDestroyed = false;
+  let spotPingTimer: ReturnType<typeof setInterval> | null = null;
+  let spotLastMsgTs = 0;
 
   function spotSymSlug(sym: string) {
-    return sym.toUpperCase().replace(/[/\s-]/g, '').toLowerCase()
+    return sym
+      .toUpperCase()
+      .replace(/[/\s-]/g, "")
+      .toLowerCase();
   }
 
   function spotTickerChannel(sym: string) {
-    return `market_${spotSymSlug(sym)}_ticker`
+    return `market_${spotSymSlug(sym)}_ticker`;
   }
 
   function stopSpotWs() {
-    spotWsDestroyed = true
-    if (spotPingTimer !== null) { clearInterval(spotPingTimer); spotPingTimer = null }
+    spotWsDestroyed = true;
+    if (spotPingTimer !== null) {
+      clearInterval(spotPingTimer);
+      spotPingTimer = null;
+    }
     if (spotWs) {
-      if (spotWs.readyState === WebSocket.OPEN && spotStore.symbolList.length > 0) {
+      if (
+        spotWs.readyState === WebSocket.OPEN &&
+        spotStore.symbolList.length > 0
+      ) {
         for (const s of spotStore.symbolList) {
-          spotWs.send(JSON.stringify({ event: 'unsub', params: { channel: spotTickerChannel(s.symbol) } }))
+          spotWs.send(
+            JSON.stringify({
+              event: "unsub",
+              params: { channel: spotTickerChannel(s.symbol) },
+            }),
+          );
         }
       }
-      spotWs.onclose = null
-      spotWs.close()
-      spotWs = null
+      spotWs.onclose = null;
+      spotWs.close();
+      spotWs = null;
     }
   }
 
   function startSpotWs(symbols: string[]) {
-    if (!symbols.length || !SPOT_WS_URL) return
-    stopSpotWs()
-    spotWsDestroyed = false
-    spotWs = new WebSocket(SPOT_WS_URL)
+    if (!symbols.length || !SPOT_WS_URL) return;
+    stopSpotWs();
+    spotWsDestroyed = false;
+    spotWs = new WebSocket(SPOT_WS_URL);
     spotWs.onopen = () => {
       for (const s of symbols) {
-        spotWs!.send(JSON.stringify({ event: 'sub', params: { channel: spotTickerChannel(s) } }))
+        spotWs!.send(
+          JSON.stringify({
+            event: "sub",
+            params: { channel: spotTickerChannel(s) },
+          }),
+        );
       }
-      spotLastMsgTs = Date.now()
+      spotLastMsgTs = Date.now();
       spotPingTimer = setInterval(() => {
         if (Date.now() - spotLastMsgTs > 30_000) {
-          stopSpotWs()
-          if (!spotWsDestroyed) startSpotWs(symbols)
-          return
+          stopSpotWs();
+          if (!spotWsDestroyed) startSpotWs(symbols);
+          return;
         }
-      }, 15_000)
-    }
+      }, 15_000);
+    };
     spotWs.onmessage = (e) => {
-      spotLastMsgTs = Date.now()
-      let msg: any
-      try { msg = JSON.parse(e.data) } catch { return }
+      spotLastMsgTs = Date.now();
+      let msg: any;
+      try {
+        msg = JSON.parse(e.data);
+      } catch {
+        return;
+      }
       if (msg.ping !== undefined) {
-        spotWs?.send(JSON.stringify({ pong: msg.ping }))
-        return
+        spotWs?.send(JSON.stringify({ pong: msg.ping }));
+        return;
       }
-      const ch: string = msg.channel ?? msg.ch ?? ''
-      const rawTick = msg.tick ?? msg.data
-      const tick = rawTick && !Array.isArray(rawTick) && typeof rawTick === 'object' ? rawTick : null
-      if (!ch.includes('_ticker') || !tick) return
-      const sym = symbols.find(s => spotTickerChannel(s) === ch)
-      if (!sym) return
+      const ch: string = msg.channel ?? msg.ch ?? "";
+      const rawTick = msg.tick ?? msg.data;
+      const tick =
+        rawTick && !Array.isArray(rawTick) && typeof rawTick === "object"
+          ? rawTick
+          : null;
+      if (!ch.includes("_ticker") || !tick) return;
+      const sym = symbols.find((s) => spotTickerChannel(s) === ch);
+      if (!sym) return;
       spotTicks.value.set(sym, {
-        close: parseFloat(String((tick as any).close ?? (tick as any).last ?? (tick as any).price ?? 0)),
+        close: parseFloat(
+          String(
+            (tick as any).close ??
+              (tick as any).last ??
+              (tick as any).price ??
+              0,
+          ),
+        ),
         open: parseFloat(String((tick as any).open ?? 0)),
         high: parseFloat(String((tick as any).high ?? 0)),
         low: parseFloat(String((tick as any).low ?? 0)),
-        turnover: parseFloat(String((tick as any).amount ?? (tick as any).quoteVolume ?? 0)),
-      })
-    }
-    spotWs.onerror = () => {}
+        turnover: parseFloat(
+          String((tick as any).amount ?? (tick as any).quoteVolume ?? 0),
+        ),
+      });
+    };
+    spotWs.onerror = () => {};
     spotWs.onclose = () => {
-      if (spotPingTimer !== null) { clearInterval(spotPingTimer); spotPingTimer = null }
-      if (spotWsDestroyed) return
-      setTimeout(() => startSpotWs(symbols), 3000)
-    }
+      if (spotPingTimer !== null) {
+        clearInterval(spotPingTimer);
+        spotPingTimer = null;
+      }
+      if (spotWsDestroyed) return;
+      setTimeout(() => startSpotWs(symbols), 3000);
+    };
   }
 
   async function loadSpotSymbols() {
     if (spotStore.symbolList.length > 0) {
-      void spotStore.fetchCoinIcons()
-      startSpotWs(spotStore.symbolList.map(s => s.symbol))
-      return
+      void spotStore.fetchCoinIcons();
+      startSpotWs(spotStore.symbolList.map((s) => s.symbol));
+      return;
     }
-    spotLoading.value = true
+    spotLoading.value = true;
     try {
-      await spotStore.loadSymbols()
-      void spotStore.fetchCoinIcons()
+      await spotStore.loadSymbols();
+      void spotStore.fetchCoinIcons();
       if (spotStore.symbolList.length > 0) {
-        startSpotWs(spotStore.symbolList.map(s => s.symbol))
+        startSpotWs(spotStore.symbolList.map((s) => s.symbol));
       }
-    } catch { /* silent */ } finally {
-      spotLoading.value = false
+    } catch {
+      /* silent */
+    } finally {
+      spotLoading.value = false;
     }
   }
 
   // list is derived from coins store (real-time via WebSocket)
   const futuresList = computed<MarketItem[]>(() =>
-    coinsStore.coins.map(c => {
-      const price = parseFloat(c.close)
-      const open = parseFloat(c.open)
-      const change24h = open > 0 ? ((price - open) / open) * 100 : parseFloat(c.chg) * 100
+    coinsStore.coins.map((c) => {
+      const price = parseFloat(c.close);
+      const open = parseFloat(c.open);
+      const change24h =
+        open > 0 ? ((price - open) / open) * 100 : parseFloat(c.chg) * 100;
       return {
         symbol: c.symbol,
         name: c.name,
-        type: 'futures' as const,
+        type: "futures" as const,
         icon: c.icon,
         price,
         change24h,
         high24h: parseFloat(c.high),
         low24h: parseFloat(c.low),
         volume24h: parseFloat(c.turnover),
-      }
-    })
-  )
+        stockType: c.stockType,
+      };
+    }),
+  );
 
   const spotList = computed<MarketItem[]>(() =>
-    spotStore.symbolList.map(s => {
-      const tick = spotTicks.value.get(s.symbol)
-      const price  = tick?.close ?? 0
-      const open   = tick?.open  ?? 0
-      const change24h = open > 0 ? ((price - open) / open) * 100 : 0
-      const base = s.base.toLowerCase()
+    spotStore.symbolList.map((s) => {
+      const tick = spotTicks.value.get(s.symbol);
+      const price = tick?.close ?? 0;
+      const open = tick?.open ?? 0;
+      const change24h = open > 0 ? ((price - open) / open) * 100 : 0;
+      const base = s.base.toLowerCase();
       const COIN_ICONS: Record<string, string> = {
-        btc: '/coins/btc.png', eth: '/coins/eth.png', bnb: '/coins/bnb.png',
-        sol: '/coins/sol.png', xrp: '/coins/xrp.png', ada: '/coins/ada.png',
-        doge: '/coins/doge.png', ltc: '/coins/ltc.png', trx: '/coins/trx.png',
-        dot: '/coins/dot.png', link: '/coins/link.png',
-      }
-      const fromSymbolList = (s.icon && s.icon.trim()) || ''
-      const fromCoinMap = spotStore.coinIconMap.get(s.base.toUpperCase()) ?? ''
-      const localPng = COIN_ICONS[base] ?? ''
+        btc: "/coins/btc.png",
+        eth: "/coins/eth.png",
+        bnb: "/coins/bnb.png",
+        sol: "/coins/sol.png",
+        xrp: "/coins/xrp.png",
+        ada: "/coins/ada.png",
+        doge: "/coins/doge.png",
+        ltc: "/coins/ltc.png",
+        trx: "/coins/trx.png",
+        dot: "/coins/dot.png",
+        link: "/coins/link.png",
+      };
+      const fromSymbolList = (s.icon && s.icon.trim()) || "";
+      const fromCoinMap = spotStore.coinIconMap.get(s.base.toUpperCase()) ?? "";
+      const localPng = COIN_ICONS[base] ?? "";
       return {
         symbol: `${s.base}/${s.quote}`,
         name: s.base,
-        type: 'spot' as const,
+        type: "spot" as const,
         icon: fromSymbolList || fromCoinMap || localPng,
         price,
         change24h,
         high24h: tick?.high ?? 0,
-        low24h:  tick?.low  ?? 0,
+        low24h: tick?.low ?? 0,
         volume24h: tick?.turnover ?? 0,
-      }
-    })
-  )
+        stockType: 0, // 现货无类型,给默认值0
+      };
+    }),
+  );
 
-  const list = computed<MarketItem[]>(() => [...futuresList.value, ...spotList.value])
+  const list = computed<MarketItem[]>(() => [
+    ...futuresList.value,
+    ...spotList.value,
+  ]);
 
-  const loading = computed(() => coinsStore.loading || spotLoading.value)
-  const error = ref('')
+  const loading = computed(() => coinsStore.loading || spotLoading.value);
+  const error = ref("");
 
-  const currentCoin = ref<CoinDetail | null>(null)
-  const chartRange = ref<ChartRange>('1m')
-  const coinLoading = ref(false)
+  const currentCoin = ref<CoinDetail | null>(null);
+  const chartRange = ref<ChartRange>("1m");
+  const coinLoading = ref(false);
 
   // ── Getters ────────────────────────────────────────
   const filteredList = computed(() => {
     let result =
-      activeTab.value === 'futures' ? futuresList.value : spotList.value
+      activeTab.value === "futures" ? futuresList.value : spotList.value;
 
     if (searchQuery.value.trim()) {
-      const q = searchQuery.value.trim().toUpperCase()
-      result = result.filter(item => item.symbol.toUpperCase().includes(q))
+      const q = searchQuery.value.trim().toUpperCase();
+      result = result.filter((item) => item.symbol.toUpperCase().includes(q));
     }
 
-    return result
-  })
+    return result;
+  });
 
-  const hotList = computed(() => futuresList.value.slice(0, 3))
+  const hotList = computed(() => futuresList.value.slice(0, 3));
 
   const topVolumeList = computed(() =>
-    [...futuresList.value].sort((a, b) => b.volume24h - a.volume24h).slice(0, 3)
-  )
+    [...futuresList.value]
+      .sort((a, b) => b.volume24h - a.volume24h)
+      .slice(0, 3),
+  );
 
   // ── Actions ────────────────────────────────────────
   async function fetchList() {
-    error.value = ''
+    error.value = "";
     try {
-      await coinsStore.fetchCoins()
+      await coinsStore.fetchCoins();
     } catch (e) {
-      error.value = e instanceof Error ? e.message : '获取行情失败'
+      error.value = e instanceof Error ? e.message : "获取行情失败";
     }
   }
 
   function setTab(tab: MarketType) {
-    activeTab.value = tab
-    if (tab === 'spot') {
+    activeTab.value = tab;
+    if (tab === "spot") {
       // 切到现货:取消合约行情订阅
-      coinsStore.stopLivePrices()
-      void loadSpotSymbols()
-      return
+      coinsStore.stopLivePrices();
+      void loadSpotSymbols();
+      return;
     }
     // 切到合约:取消现货行情订阅并恢复合约行情
-    stopSpotWs()
-    void coinsStore.fetchCoins()
+    stopSpotWs();
+    void coinsStore.fetchCoins();
   }
 
   function setSearch(query: string) {
-    searchQuery.value = query
+    searchQuery.value = query;
   }
 
   async function fetchCoinDetail(symbol: string) {
-    coinLoading.value = true
-    currentCoin.value = null
+    coinLoading.value = true;
+    currentCoin.value = null;
     try {
-      const coin = coinsStore.coins.find(c => c.symbol === symbol)
+      const coin = coinsStore.coins.find((c) => c.symbol === symbol);
       if (coin) {
-        const price = parseFloat(coin.close || '0')
-        const open = parseFloat(coin.open || '0')
+        const price = parseFloat(coin.close || "0");
+        const open = parseFloat(coin.open || "0");
         currentCoin.value = {
           symbol: coin.symbol,
           name: coin.name,
-          icon: coin.icon ?? '',
-          marketCap: '--',
-          circulatingSupply: '--',
-          totalSupply: '--',
+          icon: coin.icon ?? "",
+          marketCap: "--",
+          circulatingSupply: "--",
+          totalSupply: "--",
           allTimeHigh: 0,
           currentPrice: price,
           priceChange: open > 0 ? price - open : 0,
           priceChangePct: open > 0 ? ((price - open) / open) * 100 : 0,
           stats: [],
           chartData: [],
-        }
+        };
       }
     } finally {
-      coinLoading.value = false
+      coinLoading.value = false;
     }
   }
 
   function setChartRange(range: ChartRange) {
-    chartRange.value = range
+    chartRange.value = range;
   }
 
   // 离开行情页时统一关闭,避免顶部导航切页后残留订阅
   function stopAllWs() {
-    stopSpotWs()
-    coinsStore.stopLivePrices()
+    stopSpotWs();
+    coinsStore.stopLivePrices();
   }
 
   // ── Return ALL state ───────────────────────────────
@@ -278,5 +337,5 @@ export const useMarketStore = defineStore('market', () => {
     loadSpotSymbols,
     stopSpotWs,
     stopAllWs,
-  }
-})
+  };
+});

+ 58 - 57
code/src/types/index.ts

@@ -1,106 +1,107 @@
 // ── Vue Router meta 类型扩展 ───────────────────────────
-declare module 'vue-router' {
+declare module "vue-router" {
   interface RouteMeta {
-    title?: string
-    requiresAuth?: boolean
-    guestOnly?: boolean
+    title?: string;
+    requiresAuth?: boolean;
+    guestOnly?: boolean;
   }
 }
 
 // ── 用户 ──────────────────────────────────────────────
 
 export interface User {
-  email: string
-  token: string
-  uid?: string
+  email: string;
+  token: string;
+  uid?: string;
 }
 
 // ── 行情 ──────────────────────────────────────────────
 
-export type MarketType = 'futures' | 'spot'
+export type MarketType = "futures" | "spot";
 
 export interface MarketItem {
-  symbol: string       // e.g. "BTC/USDT"
-  name: string         // e.g. "比特币"
-  type: 'futures' | 'spot'
-  icon: string         // coin icon url
-  price: number
-  change24h: number    // 百分比,如 +21.26
-  high24h: number
-  low24h: number
-  volume24h: number    // 成交量
+  symbol: string; // e.g. "BTC/USDT"
+  name: string; // e.g. "比特币"
+  type: "futures" | "spot";
+  icon: string; // coin icon url
+  price: number;
+  change24h: number; // 百分比,如 +21.26
+  high24h: number;
+  low24h: number;
+  volume24h: number; // 成交量
+  stockType: number; // 股票类型
 }
 
 export interface CoinDetail {
-  symbol: string
-  name: string
-  icon: string
-  marketCap: string
-  circulatingSupply: string
-  totalSupply: string
-  allTimeHigh: number
-  currentPrice: number
-  priceChange: number
-  priceChangePct: number
-  stats: PeriodStat[]
-  chartData: ChartPoint[]
+  symbol: string;
+  name: string;
+  icon: string;
+  marketCap: string;
+  circulatingSupply: string;
+  totalSupply: string;
+  allTimeHigh: number;
+  currentPrice: number;
+  priceChange: number;
+  priceChangePct: number;
+  stats: PeriodStat[];
+  chartData: ChartPoint[];
 }
 
 export interface PeriodStat {
-  label: string   // 近1年 / 3个月 / 30天 / 7天
-  changePct: number
-  price: number
+  label: string; // 近1年 / 3个月 / 30天 / 7天
+  changePct: number;
+  price: number;
 }
 
 export interface ChartPoint {
-  time: string
-  price: number
+  time: string;
+  price: number;
 }
 
-export type ChartRange = '24h' | '1w' | '1m' | '1y'
+export type ChartRange = "24h" | "1w" | "1m" | "1y";
 
 // ── 公告 ──────────────────────────────────────────────
 
 export interface Announcement {
-  id: string | number
-  title: string
-  content?: string
-  publishedAt: string  // ISO string
-  author?: string
+  id: string | number;
+  title: string;
+  content?: string;
+  publishedAt: string; // ISO string
+  author?: string;
 }
 
 // ── VIP 费率 ──────────────────────────────────────────
 
 export interface VipTier {
-  level: string        // VIP1 ~ VIP5
-  minHolding: number   // 最低持仓 USDT
-  spotMaker: number
-  spotTaker: number
-  futuresMaker: number
-  futuresTaker: number
+  level: string; // VIP1 ~ VIP5
+  minHolding: number; // 最低持仓 USDT
+  spotMaker: number;
+  spotTaker: number;
+  futuresMaker: number;
+  futuresTaker: number;
 }
 
 // ── 导航 ──────────────────────────────────────────────
 
 export interface NavItem {
-  label: string
-  to: string
+  label: string;
+  to: string;
 }
 
 // ── 资产 ──────────────────────────────────────────────
 
 export interface AssetItem {
-  coin: string         // e.g. "BTC"
-  name: string         // e.g. "比特币"
-  available: number    // 可用
-  frozen: number       // 冻结
-  usdtValue: number    // 折合 USDT
+  coin: string; // e.g. "BTC"
+  name: string; // e.g. "比特币"
+  available: number; // 可用
+  frozen: number; // 冻结
+  usdtValue: number; // 折合 USDT
 }
 
 export interface AssetOverview {
-  totalUsdt: number
-  totalCny: number
-  assets: AssetItem[]
+  totalUsdt: number;
+  totalCny: number;
+  assets: AssetItem[];
 }
 
-export type TransferAccount = 'fund' | 'futures' | 'copy'
+export type TransferAccount = "fund" | "futures" | "copy";

+ 3 - 2
code/src/utils/stakingDisplay.ts

@@ -1,10 +1,11 @@
 import type { StakingConfig } from '@/api/staking'
 
-const DAYS_PER_MONTH = 30
+// const DAYS_PER_MONTH = 30
 
 /** 天数转展示月数(30 天/月截断取整,不足 1 个月显示 1) */
 export function daysToDisplayMonths(days: number): number {
-  return Math.max(1, Math.floor(days / DAYS_PER_MONTH))
+  // return Math.max(1, Math.floor(days / DAYS_PER_MONTH))
+  return days
 }
 
 /** 锁定月数(lockDays 为天数) */

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 857 - 605
code/src/views/FuturesView.vue


+ 253 - 93
code/src/views/HomeView.vue

@@ -1,40 +1,68 @@
 <script setup lang="ts">
-import { computed } from 'vue'
-import { useI18n } from 'vue-i18n'
-import { storeToRefs } from 'pinia'
-import { useAuthStore } from '@/stores/auth'
-import { AUTH_ENABLED } from '@/utils/featureFlags'
-import aboutMountain from '@/assets/home/about-mountain.png'
-import visionBlackhole from '@/assets/home/vision-blackhole.png'
-import iconAsset from '@/assets/home/icon-asset.png'
-import iconSpeed from '@/assets/home/icon-speed.png'
-import iconGlobal from '@/assets/home/icon-global.png'
-import iconFee from '@/assets/home/icon-fee.png'
-import iconEco from '@/assets/home/icon-eco.png'
-import iconMission from '@/assets/home/icon-mission.png'
-import iconPurpose from '@/assets/home/icon-purpose.png'
-import cardGlow1 from '@/assets/home/card-glow-1.png'
-import cardGlow2 from '@/assets/home/card-glow-2.png'
-import cardGlow3 from '@/assets/home/card-glow-3.png'
-import cardGlow4 from '@/assets/home/card-glow-4.png'
-import authVisual from '@/assets/auth/auth-visual.png'
-
-const { t } = useI18n()
+import { computed } from "vue";
+import { useI18n } from "vue-i18n";
+import { storeToRefs } from "pinia";
+import { useAuthStore } from "@/stores/auth";
+import { AUTH_ENABLED } from "@/utils/featureFlags";
+import aboutMountain from "@/assets/home/about-mountain.png";
+// import visionBlackhole from "@/assets/home/vision-blackhole.png";
+import iconAsset from "@/assets/home/icon-asset.png";
+import iconSpeed from "@/assets/home/icon-speed.png";
+import iconGlobal from "@/assets/home/icon-global.png";
+import iconFee from "@/assets/home/icon-fee.png";
+import iconEco from "@/assets/home/icon-eco.png";
+import iconMission from "@/assets/home/icon-mission.png";
+import iconPurpose from "@/assets/home/icon-purpose.png";
+import cardGlow1 from "@/assets/home/card-glow-1.png";
+import cardGlow2 from "@/assets/home/card-glow-2.png";
+import cardGlow3 from "@/assets/home/card-glow-3.png";
+import cardGlow4 from "@/assets/home/card-glow-4.png";
+import authVisual from "@/assets/auth/auth-visual.png";
+
+const { t } = useI18n();
 
 const advantages = computed(() => [
-  { icon: iconAsset, glow: cardGlow1, titleKey: 'home.assetSafetyTitle', descKey: 'home.assetSafetyDesc' },
-  { icon: iconSpeed, glow: cardGlow2, titleKey: 'home.highPerfTitle',    descKey: 'home.highPerfDesc' },
-  { icon: iconGlobal, glow: cardGlow3, titleKey: 'home.globalComplianceTitle', descKey: 'home.globalComplianceDesc' },
-  { icon: iconFee,   glow: cardGlow4, titleKey: 'home.transparentFeeTitle', descKey: 'home.transparentFeeDesc' },
-])
+  {
+    icon: iconAsset,
+    glow: cardGlow1,
+    titleKey: "home.assetSafetyTitle",
+    descKey: "home.assetSafetyDesc",
+  },
+  {
+    icon: iconSpeed,
+    glow: cardGlow2,
+    titleKey: "home.highPerfTitle",
+    descKey: "home.highPerfDesc",
+  },
+  {
+    icon: iconGlobal,
+    glow: cardGlow3,
+    titleKey: "home.globalComplianceTitle",
+    descKey: "home.globalComplianceDesc",
+  },
+  {
+    icon: iconFee,
+    glow: cardGlow4,
+    titleKey: "home.transparentFeeTitle",
+    descKey: "home.transparentFeeDesc",
+  },
+]);
 
 const visionItems = computed(() => [
-  { icon: iconEco,     titleKey: 'home.ecoTitle',     descKey: 'home.ecoDesc' },
-  { icon: iconMission, titleKey: 'home.missionTitle', descKey: 'home.missionDesc' },
-  { icon: iconPurpose, titleKey: 'home.purposeTitle', descKey: 'home.purposeDesc' },
-])
-
-const { isLoggedIn } = storeToRefs(useAuthStore())
+  { icon: iconEco, titleKey: "home.ecoTitle", descKey: "home.ecoDesc" },
+  {
+    icon: iconMission,
+    titleKey: "home.missionTitle",
+    descKey: "home.missionDesc",
+  },
+  {
+    icon: iconPurpose,
+    titleKey: "home.purposeTitle",
+    descKey: "home.purposeDesc",
+  },
+]);
+
+const { isLoggedIn } = storeToRefs(useAuthStore());
 </script>
 
 <template>
@@ -43,16 +71,29 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
     <section class="hero">
       <div class="page-container hero-inner">
         <div class="hero-text">
-          <h1 class="hero-title">{{ t('home.heroTitle') }}</h1>
-          <p class="hero-desc">{{ t('home.heroDesc') }}</p>
+          <h1 class="hero-title">{{ t("home.heroTitle") }}</h1>
+          <p class="hero-desc">{{ t("home.heroDesc") }}</p>
           <div class="hero-actions">
-            <RouterLink v-if="AUTH_ENABLED && !isLoggedIn" to="/register" class="btn btn-primary">{{ t('home.register') }}</RouterLink>
+            <RouterLink
+              v-if="AUTH_ENABLED && !isLoggedIn"
+              to="/register"
+              class="btn btn-primary"
+              >{{ t("home.register") }}</RouterLink
+            >
             <RouterLink
               to="/market"
               class="btn"
-              :class="AUTH_ENABLED && !isLoggedIn ? 'btn-outline' : 'btn-primary'"
-            >{{ t('home.viewMarket') }}</RouterLink>
-            <RouterLink v-if="!AUTH_ENABLED" to="/download" class="btn btn-outline">{{ t('home.downloadApp') }}</RouterLink>
+              :class="
+                AUTH_ENABLED && !isLoggedIn ? 'btn-outline' : 'btn-primary'
+              "
+              >{{ t("home.viewMarket") }}</RouterLink
+            >
+            <RouterLink
+              v-if="!AUTH_ENABLED"
+              to="/download"
+              class="btn btn-outline"
+              >{{ t("home.downloadApp") }}</RouterLink
+            >
           </div>
         </div>
         <div class="hero-visual">
@@ -62,7 +103,7 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
             class="hero-visual-img"
             loading="eager"
             decoding="async"
-          >
+          />
         </div>
       </div>
     </section>
@@ -70,7 +111,7 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
     <!-- 平台核心优势 -->
     <section class="section advantages-section">
       <div class="page-container">
-        <h2 class="section-title">{{ t('home.coreAdvantages') }}</h2>
+        <h2 class="section-title">{{ t("home.coreAdvantages") }}</h2>
         <div class="advantages-grid">
           <div
             v-for="item in advantages"
@@ -78,7 +119,11 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
             class="advantage-card"
             :style="{ backgroundImage: `url(${item.glow})` }"
           >
-            <img :src="item.icon" :alt="t(item.titleKey)" class="advantage-icon" />
+            <img
+              :src="item.icon"
+              :alt="t(item.titleKey)"
+              class="advantage-icon"
+            />
             <h3 class="advantage-title">{{ t(item.titleKey) }}</h3>
             <p class="advantage-desc">{{ t(item.descKey) }}</p>
           </div>
@@ -91,13 +136,17 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
     <section class="about-section">
       <div class="page-container about-inner">
         <div class="about-visual">
-          <img :src="aboutMountain" :alt="t('home.aboutImageAlt')" class="about-image" />
+          <img
+            :src="aboutMountain"
+            :alt="t('home.aboutImageAlt')"
+            class="about-image"
+          />
         </div>
         <div class="about-content">
-          <h2 class="about-title">{{ t('home.aboutUs') }}</h2>
-          <p class="about-desc">{{ t('home.aboutDesc') }}</p>
-          <p class="about-meta">{{ t('home.foundedYear') }}</p>
-          <p class="about-meta">{{ t('home.headquarters') }}</p>
+          <h2 class="about-title">{{ t("home.aboutUs") }}</h2>
+          <p class="about-desc">{{ t("home.aboutDesc") }}</p>
+          <p class="about-meta">{{ t("home.foundedYear") }}</p>
+          <p class="about-meta">{{ t("home.headquarters") }}</p>
         </div>
       </div>
     </section>
@@ -105,14 +154,18 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
     <!-- 我们的愿景 -->
     <section class="vision-section">
       <div class="page-container">
-        <h2 class="section-title">{{ t('home.ourVision') }}</h2>
-        <p class="vision-subtitle">{{ t('home.visionSubtitle') }}</p>
-        <div
+        <h2 class="section-title">{{ t("home.ourVision") }}</h2>
+        <p class="vision-subtitle">{{ t("home.visionSubtitle") }}</p>
+        <!-- <div
           class="vision-deco"
           :style="{ backgroundImage: `url(${visionBlackhole})` }"
-        />
+        /> -->
         <div class="vision-grid">
-          <div v-for="item in visionItems" :key="item.titleKey" class="vision-card">
+          <div
+            v-for="item in visionItems"
+            :key="item.titleKey"
+            class="vision-card"
+          >
             <img :src="item.icon" :alt="t(item.titleKey)" class="vision-icon" />
             <h3 class="vision-title">{{ t(item.titleKey) }}</h3>
             <p class="vision-desc">{{ t(item.descKey) }}</p>
@@ -136,7 +189,11 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
   position: relative;
   overflow: hidden;
   background:
-    radial-gradient(ellipse 65% 45% at 50% 28%, rgba(240, 185, 11, 0.12) 0%, transparent 60%),
+    radial-gradient(
+      ellipse 65% 45% at 50% 28%,
+      rgba(240, 185, 11, 0.12) 0%,
+      transparent 60%
+    ),
     #0a0a0a;
 }
 
@@ -256,7 +313,9 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
   border: 1px solid rgba(255, 255, 255, 0.05);
   border-radius: 14px;
   overflow: hidden;
-  transition: transform 0.25s ease, border-color 0.25s ease;
+  transition:
+    transform 0.25s ease,
+    border-color 0.25s ease;
 }
 .advantage-card:hover {
   transform: translateY(-2px);
@@ -288,9 +347,25 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
   inset: 0;
   pointer-events: none;
   background:
-    radial-gradient(circle at 50% 50%, rgba(240, 185, 11, 0.35) 0%, transparent 12%),
-    linear-gradient(to right, transparent calc(50% - 0.5px), rgba(240, 185, 11, 0.25) calc(50% - 0.5px), rgba(240, 185, 11, 0.25) calc(50% + 0.5px), transparent calc(50% + 0.5px)),
-    linear-gradient(to bottom, transparent calc(50% - 0.5px), rgba(240, 185, 11, 0.25) calc(50% - 0.5px), rgba(240, 185, 11, 0.25) calc(50% + 0.5px), transparent calc(50% + 0.5px));
+    radial-gradient(
+      circle at 50% 50%,
+      rgba(240, 185, 11, 0.35) 0%,
+      transparent 12%
+    ),
+    linear-gradient(
+      to right,
+      transparent calc(50% - 0.5px),
+      rgba(240, 185, 11, 0.25) calc(50% - 0.5px),
+      rgba(240, 185, 11, 0.25) calc(50% + 0.5px),
+      transparent calc(50% + 0.5px)
+    ),
+    linear-gradient(
+      to bottom,
+      transparent calc(50% - 0.5px),
+      rgba(240, 185, 11, 0.25) calc(50% - 0.5px),
+      rgba(240, 185, 11, 0.25) calc(50% + 0.5px),
+      transparent calc(50% + 0.5px)
+    );
 }
 
 /* ==========================================================================
@@ -385,7 +460,9 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
   background: linear-gradient(180deg, #1a1a1a 0%, #0e0e0e 100%);
   border: 1px solid rgba(255, 255, 255, 0.06);
   border-radius: 14px;
-  transition: transform 0.25s ease, border-color 0.25s ease;
+  transition:
+    transform 0.25s ease,
+    border-color 0.25s ease;
 }
 .vision-card:hover {
   transform: translateY(-2px);
@@ -423,20 +500,38 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
     text-align: center;
     gap: var(--space-8);
   }
-  .hero-title { font-size: 36px; }
-  .hero-desc { margin-left: auto; margin-right: auto; }
-  .hero-actions { justify-content: center; }
-  .hero-visual-img { max-width: 420px; margin: 0 auto; }
+  .hero-title {
+    font-size: 36px;
+  }
+  .hero-desc {
+    margin-left: auto;
+    margin-right: auto;
+  }
+  .hero-actions {
+    justify-content: center;
+  }
+  .hero-visual-img {
+    max-width: 420px;
+    margin: 0 auto;
+  }
 
   .about-inner {
     grid-template-columns: 1fr;
     gap: var(--space-8);
     text-align: center;
   }
-  .about-desc { margin-left: auto; margin-right: auto; }
-  .about-image { max-width: 360px; }
+  .about-desc {
+    margin-left: auto;
+    margin-right: auto;
+  }
+  .about-image {
+    max-width: 360px;
+  }
 
-  .vision-grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
+  .vision-grid {
+    grid-template-columns: repeat(3, 1fr);
+    gap: var(--space-4);
+  }
 }
 
 /* ==========================================================================
@@ -445,7 +540,11 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
 @media (max-width: 640px) {
   .hero {
     background:
-      radial-gradient(ellipse 80% 40% at 50% 25%, rgba(240, 185, 11, 0.15) 0%, transparent 65%),
+      radial-gradient(
+        ellipse 80% 40% at 50% 25%,
+        rgba(240, 185, 11, 0.15) 0%,
+        transparent 65%
+      ),
       #0a0a0a;
   }
   .hero-inner {
@@ -453,33 +552,94 @@ const { isLoggedIn } = storeToRefs(useAuthStore())
     padding-bottom: var(--space-10);
     gap: var(--space-6);
   }
-  .hero-title { font-size: 26px; line-height: 1.35; }
-  .hero-desc { font-size: 13px; line-height: 1.8; }
-  .btn { min-width: 120px; height: 40px; font-size: 14px; }
-  .hero-visual-img { max-width: min(100%, 320px); }
-
-  .section-title { font-size: 24px; margin-bottom: var(--space-8); }
-
-  .advantages-section { padding: var(--space-12) 0; }
-  .advantages-grid { gap: var(--space-3); }
-  .advantage-card { padding: var(--space-6) var(--space-4); }
-  .advantage-icon { width: 44px; height: 44px; margin-bottom: var(--space-3); }
-  .advantage-title { font-size: 16px; margin-bottom: var(--space-2); }
-  .advantage-desc { font-size: 12px; line-height: 1.7; }
-
-  .about-section { padding: var(--space-12) 0; }
-  .about-title { font-size: 24px; }
-  .about-desc { font-size: 13px; }
-  .about-meta { font-size: 14px; }
-  .about-image { max-width: 280px; }
-
-  .vision-section { padding: var(--space-12) 0; }
-  .vision-subtitle { font-size: 13px; padding: 0 var(--space-4); margin-top: calc(-1 * var(--space-6)); }
-  .vision-deco { height: 120px; }
-  .vision-grid { grid-template-columns: 1fr; gap: var(--space-3); }
-  .vision-card { padding: var(--space-6) var(--space-5); }
-  .vision-icon { width: 48px; height: 48px; }
-  .vision-title { font-size: 16px; }
-  .vision-desc { font-size: 12px; }
+  .hero-title {
+    font-size: 26px;
+    line-height: 1.35;
+  }
+  .hero-desc {
+    font-size: 13px;
+    line-height: 1.8;
+  }
+  .btn {
+    min-width: 120px;
+    height: 40px;
+    font-size: 14px;
+  }
+  .hero-visual-img {
+    max-width: min(100%, 320px);
+  }
+
+  .section-title {
+    font-size: 24px;
+    margin-bottom: var(--space-8);
+  }
+
+  .advantages-section {
+    padding: var(--space-12) 0;
+  }
+  .advantages-grid {
+    gap: var(--space-3);
+  }
+  .advantage-card {
+    padding: var(--space-6) var(--space-4);
+  }
+  .advantage-icon {
+    width: 44px;
+    height: 44px;
+    margin-bottom: var(--space-3);
+  }
+  .advantage-title {
+    font-size: 16px;
+    margin-bottom: var(--space-2);
+  }
+  .advantage-desc {
+    font-size: 12px;
+    line-height: 1.7;
+  }
+
+  .about-section {
+    padding: var(--space-12) 0;
+  }
+  .about-title {
+    font-size: 24px;
+  }
+  .about-desc {
+    font-size: 13px;
+  }
+  .about-meta {
+    font-size: 14px;
+  }
+  .about-image {
+    max-width: 280px;
+  }
+
+  .vision-section {
+    padding: var(--space-12) 0;
+  }
+  .vision-subtitle {
+    font-size: 13px;
+    padding: 0 var(--space-4);
+    margin-top: calc(-1 * var(--space-6));
+  }
+  .vision-deco {
+    height: 120px;
+  }
+  .vision-grid {
+    grid-template-columns: 1fr;
+    gap: var(--space-3);
+  }
+  .vision-card {
+    padding: var(--space-6) var(--space-5);
+  }
+  .vision-icon {
+    width: 48px;
+    height: 48px;
+  }
+  .vision-title {
+    font-size: 16px;
+  }
+  .vision-desc {
+    font-size: 12px;
+  }
 }
 </style>

+ 36 - 36
code/src/views/assets/DepositView.vue

@@ -200,15 +200,15 @@ function copyOrderNo() {
   })
 }
 
-function validateTxHash(): boolean {
-  txHashError.value = ''
-  const s = txHashInput.value.trim()
-  if (!s) {
-    txHashError.value = t('deposit.hashRequired')
-    return false
-  }
-  return true
-}
+// function validateTxHash(): boolean {
+//   txHashError.value = ''
+//   const s = txHashInput.value.trim()
+//   if (!s) {
+//     txHashError.value = t('deposit.hashRequired')
+//     return false
+//   }
+//   return true
+// }
 
 onBeforeUnmount(() => {
   resetPendingWalletUi()
@@ -237,25 +237,25 @@ function isWalletConnectCancelError(e: unknown): boolean {
   )
 }
 
-async function onSubmitHash() {
-  const o = currentOrder.value
-  if (!o?.orderNo) {
-    return
-  }
-  if (Number(o.status) !== 0) {
-    toast.error(t('deposit.statusNotSubmittable'))
-    return
-  }
-  if (!validateTxHash()) {
-    return
-  }
-  try {
-    await store.submitTxHash(o.orderNo, txHashInput.value)
-    toast.success(t('deposit.hashSubmitted'))
-  } catch {
-    toast.error(store.error ?? t('deposit.hashFailed'))
-  }
-}
+// async function onSubmitHash() {
+//   const o = currentOrder.value
+//   if (!o?.orderNo) {
+//     return
+//   }
+//   if (Number(o.status) !== 0) {
+//     toast.error(t('deposit.statusNotSubmittable'))
+//     return
+//   }
+//   if (!validateTxHash()) {
+//     return
+//   }
+//   try {
+//     await store.submitTxHash(o.orderNo, txHashInput.value)
+//     toast.success(t('deposit.hashSubmitted'))
+//   } catch {
+//     toast.error(store.error ?? t('deposit.hashFailed'))
+//   }
+// }
 
 async function onWalletPay() {
   const o = currentOrder.value
@@ -436,7 +436,7 @@ function statusLabel(status: number) {
                 </template>
               </div>
 
-              <div v-if="Number(currentOrder.status) === 0" class="hash-block">
+              <!-- <div v-if="Number(currentOrder.status) === 0" class="hash-block">
                 <p class="form-label hash-label">{{ t('deposit.orSubmitHash') }}</p>
                 <input
                   v-model="txHashInput"
@@ -457,7 +457,7 @@ function statusLabel(status: number) {
               </div>
               <p v-else-if="currentOrder.txHash" class="hash-done">
                 {{ t('deposit.submittedHash') }}<span class="mono">{{ currentOrder.txHash }}</span>
-              </p>
+              </p> -->
           </div>
         </template>
 
@@ -469,18 +469,18 @@ function statusLabel(status: number) {
                 <button
                   type="button"
                   class="mode-tab"
-                  :class="{ active: depositMode === 'manual' }"
-                  @click="depositMode = 'manual'"
+                  :class="{ active: depositMode === 'wallet' }"
+                  @click="depositMode = 'wallet'"
                 >
-                  {{ t('deposit.manualDepositTab') }}
+                  {{ t('deposit.walletDepositTab') }}
                 </button>
                 <button
                   type="button"
                   class="mode-tab"
-                  :class="{ active: depositMode === 'wallet' }"
-                  @click="depositMode = 'wallet'"
+                  :class="{ active: depositMode === 'manual' }"
+                  @click="depositMode = 'manual'"
                 >
-                  {{ t('deposit.walletDepositTab') }}
+                  {{ t('deposit.manualDepositTab') }}
                 </button>
               </div>
 

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 841 - 600
code/src/views/spot/SpotView.vue


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů