Files
thebet365/apps/admin/src/i18n/pages/en.ts
2026-06-13 17:38:25 +08:00

1020 lines
53 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const adminPages: Record<string, string> = {
'common.detail': 'Details',
'common.create': 'Create',
'common.create_btn': '+ New',
'common.save': 'Save',
'common.close': 'Close',
'common.import': 'Import',
'common.publish': 'Publish',
'common.topup': 'Top up',
'common.adjust_credit': 'Adjust credit',
'common.freeze': 'Freeze',
'common.unfreeze': 'Unfreeze',
'common.settle': 'Settle',
'common.resettle': 'Resettle',
'common.close_betting': 'Close',
'common.reopen_betting': 'Reopen betting',
'common.never_login': 'Never signed in',
'common.optional': 'Optional',
'common.to': 'To',
'common.module': 'Module',
'common.col_id': 'ID',
'common.times': 'times',
'common.bets_count_unit': 'bets',
'user.create_btn': '+ New player',
'user.filter.username_ph': 'Username',
'user.filter.agent': 'Agent',
'user.filter.agent_ph': 'All',
'user.col.username': 'Username',
'user.col.agent': 'Agent',
'user.col.agent_cashback': 'Agent cashback',
'user.col.player_cashback': 'Player cashback',
'user.col.invite_code': 'Invite code',
'user.col.balance': 'Available / Frozen',
'user.col.bets': 'Bets',
'user.col.stake_payout': 'Stake / Payout',
'user.col.last_login': 'Last login',
'user.col.created': 'Registered',
'user.status.ACTIVE': 'Active',
'user.status.SUSPENDED': 'Suspended',
'user.dialog.create': 'New player',
'user.dialog.edit': 'Edit player',
'user.dialog.deposit': 'Top up player',
'user.dialog.detail': 'Player details',
'user.field.password': 'Password',
'user.field.confirm_password': 'Confirm password',
'user.field.initial_balance': 'Initial balance',
'user.field.deposit_remark': 'Top-up note',
'user.field.initial_deposit_kind': 'Ledger note',
'user.initial_deposit_kind.daily': 'Regular top-up',
'user.initial_deposit_kind.opening_bonus': 'Opening bonus',
'user.initial_deposit_kind.custom': 'Custom',
'user.ph.initial_deposit_custom': 'Enter ledger note (min. 2 characters)',
'user.field.amount': 'Amount',
'user.field.remark': 'Note',
'user.field.account_status': 'Account status',
'user.field.available': 'Available balance',
'user.field.frozen_balance': 'Frozen balance',
'user.field.bets_summary': 'Bets / stake',
'user.field.total_payout': 'Total payout',
'user.field.login_fail': 'Failed logins',
'user.field.phone': 'Phone',
'user.field.email': 'Email',
'user.field.allow_password_change': 'Allow player password change',
'user.field.allow_username_change': 'Allow player username change',
'user.field.view_password': 'Login password',
'user.field.reset_password': 'Reset password',
'user.password_not_stored': 'Not stored (player changed it or never saved)',
'user.btn.show_password': 'Show',
'user.btn.hide_password': 'Hide',
'user.ph.reset_password': 'Leave empty to keep; new value will be viewable',
'user.ph.reset_password_short': 'Leave empty to keep',
'user.page_settings': 'Global settings',
'user.global_settings': 'Password & account (global)',
'user.global_settings_hint': 'Controls whether all players can change password or username in the app',
'user.reset_database': 'Reset database',
'user.reset_database_hint': 'Wipes all business data and restores initial demo seed (users, matches, bets, ledger, etc.). This cannot be undone.',
'user.reset_database_confirm_label': 'Type RESET to confirm',
'user.reset_database_confirm_ph': 'RESET',
'user.reset_database_btn': 'Reset to initial data',
'user.reset_database_disabled_prod': 'Disabled in production unless ALLOW_DB_RESET=true is set on the server',
'user.reset_database_success': 'Database reset complete. Sign in again with demo accounts.',
'user.reset_database_accounts': 'Demo accounts',
'user.section.basic_info': 'Basic info',
'user.section.affiliation': 'Affiliation',
'user.section.contact': 'Contact',
'user.section.account_overview': 'Account overview',
'user.section.password_mgmt': 'Password management',
'user.field.current_password': 'Current password',
'user.msg.created_with_password': 'Player created. Login password: {password}',
'user.msg.password_saved': 'Password updated. Viewable password: {password}',
'user.hint.password_reset_to_view': 'No stored password. Set one below under Reset password and save to view it here.',
'user.ph.username_unique': 'Unique login username',
'user.ph.username_player': 'Letters and digits, 332 chars',
'user.hint.username_player': 'English letters and digits only; no Chinese or special characters',
'user.ph.no_agent': 'None (platform direct)',
'user.hint.no_agent': 'Leave empty for platform-managed player',
'user.hint.platform_direct_player': 'This player belongs to the platform (admin direct).',
'user.hint.initial_balance': 'Auto top-up on create; 0 = no initial top-up',
'user.hint.deposit_remark': 'Written to ledger when initial balance > 0',
'user.hint.freeze_in_list': 'Freeze/unfreeze from the list actions',
'user.hint.agent_change': 'Empty = platform direct; changes recalc agent credit',
'user.hint.agent_readonly': 'Agent assignment cannot be changed after creation',
'user.hint.allow_password_change': 'When off, no player can change password in the app',
'user.hint.allow_username_change': 'When on, all players can change login username in profile',
'user.hint.view_password': 'Only passwords set on create/reset; cleared after player self-change',
'user.hint.reset_password': 'Takes effect immediately and updates viewable password above',
'user.btn.create': 'Create',
'user.btn.save_profile': 'Save',
'user.btn.confirm_deposit': 'Confirm top-up',
'user.deposit_remark_default': 'Admin top-up',
'user.withdraw_remark_default': 'Admin withdraw',
'user.field.account_type': 'Account type',
'user.type.player': 'Player',
'user.type.tier1_agent': 'Tier-1 agent',
'user.type.sub_agent': 'Tier-2 agent',
'user.hint.account_type': 'Agents use credit limits; players can belong to an agent and receive top-ups',
'agent.create_btn': '+ New tier-1 agent',
'agent.create_sub_btn': '+ New tier-2 agent',
'agent.create_sub': 'Create tier-2 agent',
'agent.create_child_btn': '+ New sub-agent',
'agent.dialog.create_child_agent': 'New sub-agent',
'agent.create_level_agent': 'Create L{level} agent',
'agent.create_level_agent_btn': '+ New L{level} agent',
'agent.level_name': 'Tier-{level} agent',
'agent.level_tab': 'L{level} agents',
'agent.dialog.create_level_agent': 'New L{level} agent',
'agent.hint.select_parent_for_level': 'Select a level-{level} agent as parent',
'agent.err.parent_level_mismatch': 'Invalid parent level for creating a level-{level} agent',
'agent.hint.creating_under_agent': 'Create account under this agent',
'agent.filter.username_ph': 'Username',
'agent_mgr.tab.players': 'Players',
'agent_mgr.tab.agents': 'Agents',
'agent.col.level': 'Level',
'agent.col.credit': 'Limit / Used / Available',
'agent.col.direct_players': 'Direct players',
'agent.direct_players_title': 'Direct players · {name}',
'agent.platform_row_name': 'Platform',
'agent.col.sub_agents': 'Sub-agents',
'agent.col.cashback': 'Cashback rate',
'agent.col.phone': 'Phone',
'agent.col.created': 'Created',
'agent.dialog.create': 'New tier-1 agent',
'agent.dialog.edit': 'Edit agent',
'agent.dialog.credit': 'Adjust credit limit',
'agent.field.agent_id': 'Agent ID',
'agent.dialog.detail': 'Agent details',
'agent.field.credit_limit': 'Credit limit',
'agent.field.cashback_rate': 'Cashback rate',
'agent.field.adjust_amount': 'Adjustment',
'agent.field.used_credit': 'Used credit',
'agent.field.available_credit': 'Available credit',
'agent.field.player_liability': 'Player liability',
'agent.field.sub_agent_exposure': 'Sub-agent exposure',
'agent.hint.credit_limit': 'Max total top-up capacity for direct players',
'agent.hint.cashback_example': 'e.g. enter 1 for 1%',
'agent.field.max_single_deposit': 'Max single top-up',
'agent.field.max_daily_deposit': 'Max daily top-up',
'agent.hint.deposit_limit_empty': '0 = unlimited; sub-agents cannot exceed parent limits',
'agent.hint.credit_adjust': 'Positive increases, negative decreases',
'agent.hint.credit_remark': 'Optional, written to credit ledger',
'agent.section.credit_log': 'Recent credit changes',
'agent.credit.increase': 'Increase',
'agent.credit.decrease': 'Decrease',
'agent.col.credit_type': 'Type',
'agent.col.credit_change': 'Change',
'agent.col.credit_before': 'Before',
'agent.col.credit_after': 'After',
'agent.credit_tx.filter_agent_ph': 'Agent username',
'agent.credit_tx.filter_agent_id': 'Agent ID',
'agent.credit_tx.filter_agent_id_ph': 'User ID',
'agent.credit_tx.col.operator': 'Operator',
'agent.credit_tx.view_all': 'View all credit ledger',
'finance.tab.credit': 'Credit ledger',
'finance.tab.transfer': 'Transfer ledger',
'finance.tab.wallet': 'Wallet ledger',
'finance.filter.type_category': 'Transaction type',
'finance.filter.type_category_all': 'All',
'finance.filter.type_category_deposit': 'Transfers',
'finance.filter.type_category_bet': 'Bets',
'finance.filter.type_category_cashback': 'Cashback',
'finance.col.frozen_before': 'Frozen before',
'finance.col.frozen_after': 'Frozen after',
'finance.col.reference': 'Related bet',
'finance.tx.adjust': 'Balance adjustment',
'finance.tx.bet_freeze': 'Bet freeze',
'finance.tx.bet_deduct': 'Bet deduct',
'finance.tx.bet_win': 'Bet payout',
'finance.tx.bet_lose': 'Bet settlement',
'finance.tx.bet_push': 'Push refund',
'finance.tx.bet_refund': 'Bet refund',
'finance.tx.bet_void': 'Bet void',
'finance.tx.cashback': 'Cashback',
'finance.tx.resettle': 'Resettlement',
'user.action.view_wallet_ledger': 'View wallet ledger',
'user.action.ledger_short': 'Ledger',
'user.wallet_ledger_dialog_title': 'Wallet ledger — {name}',
'agent.hierarchy.settings_title': 'Agent hierarchy',
'agent.hierarchy.settings_hint': '0 means unlimited levels. Agents at the cap cannot create sub-agents.',
'agent.hierarchy.max_level': 'Max agent level',
'agent.hierarchy.default_sub_credit_ratio': 'Default sub-agent credit ratio',
'agent.hierarchy.default_sub_credit_ratio_hint': 'When creating a sub-agent, pre-fill credit as parent available × this ratio',
'agent.hierarchy.create_credit_default_hint': 'Default {ratio}% ({amount}), capped by parent available credit; adjustable',
'agent.hierarchy.create_credit_quick_hint': 'Parent available {amount} — click a ratio to fill',
'agent.hierarchy.create_level_hint': 'Will be created as level {n} agent',
'agent.field.parent_agent': 'Parent agent',
'agent.col.parent_chain': 'Parent chain',
'role.agent_level': 'Level {n} agent',
'finance.filter.date_range': 'Date range',
'finance.filter.player_ph': 'Player username',
'finance.filter.parent_agent_ph': 'Parent agent username or ID',
'finance.filter.operator_ph': 'Operator username',
'finance.col.player': 'Player',
'finance.col.parent_agent': 'Parent agent',
'finance.col.tx_id': 'Transaction ID',
'finance.col.balance_change': 'Balance change',
'finance.col.balance_before': 'Balance before',
'finance.col.balance_after': 'Balance after',
'finance.col.tx_type': 'Type',
'finance.col.deposit_method': 'Deposit method',
'finance.deposit_method.manual_admin': 'Admin manual deposit',
'finance.deposit_method.manual_agent': 'Agent manual deposit',
'finance.deposit_method.manual': 'Manual deposit',
'finance.tx.deposit': 'Deposit',
'finance.tx.admin_deposit': 'Admin top-up',
'finance.tx.agent_deposit': 'Agent top-up',
'finance.tx.player_deposit': 'Self deposit',
'finance.tx.withdraw': 'Withdraw',
'finance.tx.admin_withdraw': 'Admin withdraw',
'finance.tx.agent_withdraw': 'Agent withdraw',
'finance.tx.request_id': 'Request ID',
'finance.remark.agent_deposit': 'Agent deposit',
'finance.remark.agent_withdraw': 'Agent withdraw',
'finance.remark.admin_deposit': 'Admin deposit',
'finance.remark.admin_withdraw': 'Admin withdraw',
'finance.remark.initial_balance': 'Initial account balance',
'agent.col.no_records': 'No records',
'agent.btn.confirm_adjust': 'Confirm',
'agent.field.select_user': 'Select user',
'agent.ph.select_user': 'Search player username',
'agent.hint.select_user': 'Pick an existing player account to promote to tier-1 agent (no new login)',
'agent.freeze.confirm_freeze_title': 'Confirm suspend agent',
'agent.freeze.confirm_freeze_body': 'Suspend agent "{name}"? They will not be able to sign in to the agent portal.',
'agent.freeze.confirm_unfreeze_body': 'Restore agent "{name}" to active status?',
'agent.freeze.opt_freeze_direct_players': 'Also freeze direct players',
'agent.freeze.opt_block_player_login': 'Block direct player login',
'agent.unfreeze.confirm_title': 'Confirm restore agent',
'agent.unfreeze.opt_unfreeze_direct_players': 'Also unfreeze direct players',
'agent.msg.cascade_freeze_done': 'Agent suspended and direct players frozen',
'agent.msg.cascade_unfreeze_done': 'Agent restored and direct players unfrozen',
'agent.msg.freeze_done': '{action} completed',
'match.create_btn': '+ New league',
'match.create_fixture_btn': '+ Add match',
'match.btn.markets': 'Markets',
'match.filter.keyword_ph': 'Tournament / team code',
'match.filter.status_hint': 'Filters fixtures inside a league and the fixture count column; empty leagues stay visible',
'match.col.league': 'Tournament',
'match.col.league_en': 'League (EN)',
'match.col.fixture_count': 'Fixtures',
'match.col.bet_count': 'Bets',
'match.col.total_stake': 'Total stake',
'match.col.pending_bets': 'Pending',
'match.col.league_code': 'Code',
'match.col.matchup': 'Matchup',
'match.col.kickoff': 'Kickoff',
'match.dialog.create_league': 'New tournament',
'match.dialog.edit_league': 'Edit tournament',
'match.dialog.create_fixture': 'New fixture',
'match.dialog.create': 'New fixture',
'match.dialog.edit': 'Edit fixture',
'match.dialog.import': 'Import matches',
'match.field.league_en': 'League (EN)',
'match.field.league_zh': 'League (ZH)',
'match.field.league_ms': 'League (MS)',
'match.field.league_logo': 'Tournament logo',
'match.field.lang_zh': 'ZH',
'match.field.lang_en': 'EN',
'match.field.lang_ms': 'MS',
'match.field.kickoff': 'Kickoff time',
'match.timezone.platform_hint': 'Saved as Malaysia time (UTC+8)',
'match.field.home_team': 'Home team',
'match.field.away_team': 'Away team',
'match.field.home_en': 'Home (EN)',
'match.field.home_zh': 'Home (ZH)',
'match.field.home_ms': 'Home (MS)',
'match.field.away_en': 'Away (EN)',
'match.field.away_zh': 'Away (ZH)',
'match.field.away_ms': 'Away (MS)',
'match.field.featured': 'Featured',
'match.hint.create_draft': 'Saved as draft; expand the tournament and publish each fixture to open markets.',
'match.hint.create_league': 'New tournaments are unpublished by default; use Publish in the list for player visibility, then expand to add fixtures.',
'league.status.PUBLISHED': 'Published',
'league.status.UNPUBLISHED': 'Unpublished',
'league.btn.unpublish': 'Unpublish',
'league.confirm_unpublish': 'Players will no longer see this tournament; you can still edit and republish in admin. Continue?',
'msg.league_published': 'Tournament published',
'msg.league_unpublished': 'Tournament unpublished',
'match.btn.unpublish': 'Unpublish',
'match.confirm_unpublish': 'The fixture will return to draft: hidden from players and no new bets; existing unsettled bets remain. Continue?',
'msg.match_unpublished': 'Fixture unpublished',
'match.hint.edit_published': 'Published: edit kickoff, featured, display names; closed/settled are locked.',
'match.expand_league_hint': 'Expand a league to manage fixtures; use Outright odds for winner markets.',
'match.expand_outright_hint': 'Expand a league to edit winner odds; fixture teams sync automatically, and you can add teams not yet on the schedule.',
'outright.odds_only_hint': 'Teams from fixtures are added automatically; add extra teams manually and edit winner odds here. Outright follows league publish—no separate publish step.',
'outright.league_unpublished_hint': 'League is not published yet. Set the league to Published on this page to open outright betting automatically.',
'outright.unsettled_fixtures_hint': '{n} fixture(s) in this league are still unsettled. Settle them before settling the outright market.',
'outright.btn.reopen': 'Reopen betting',
'outright.confirm_reopen': 'Reopening will accept new outright bets again. Continue?',
'outright.fixture_sync_added': '{n} team(s) synced automatically from fixtures',
'outright.col.teams_from_fixtures': 'Teams (from fixtures)',
'outright.col.teams_total': 'Outright teams',
'outright.empty_no_teams': 'No teams yet — add fixtures under Fixtures or click Add team.',
'match.outright.setup': 'Set up',
'match.outright.section_hint': 'Winner market for this league; fixtures are listed below',
'match.expand_markets_hint': 'Click Markets on a fixture to open the dedicated markets page.',
'match.no_fixtures': 'No fixtures under this tournament yet.',
'match.ph.league_ms': 'World Cup 2027',
'bet.filter.keyword_ph': 'Bet no. / username',
'bet.filter.date_from': 'Placed from',
'bet.filter.date_start_ph': 'Start',
'bet.filter.date_end_ph': 'End',
'bet.col.serial': 'No.',
'bet.col.bet_no': 'Bet no.',
'bet.col.player': 'Player',
'bet.col.agent': 'Agent',
'bet.col.selection': 'Pick',
'bet.col.content': 'Selections',
'bet.content.bet_counts': '{singles} single · {parlays} parlay',
'bet.col.match': 'Match',
'bet.legs_more': '+{n} more…',
'bet.col.selection_count': 'Legs',
'bet.col.stake': 'Stake',
'bet.col.odds': 'Odds',
'bet.col.payout': 'Payout',
'bet.col.placed_at': 'Placed at',
'bet.col.cashbacked': 'Cashbacked',
'bet.dialog.detail': 'Bet details',
'bet.field.total_odds': 'Total odds',
'bet.field.currency': 'Currency',
'bet.field.potential_win': 'Potential win',
'bet.field.actual_payout': 'Actual payout',
'bet.field.bet_status': 'Bet status',
'bet.field.settlement_status': 'Settlement',
'bet.field.settled_at': 'Settled at',
'bet.field.request_id': 'Request ID',
'bet.selections_title': 'Selections ({n})',
'bet.col.market': 'Market',
'bet.col.period': 'Period',
'bet.col.line': 'Line',
'bet.col.result': 'Result',
'audit.module_ph': 'e.g. USERS, AGENTS',
'audit.col.action': 'Action',
'audit.col.module': 'Module',
'audit.col.target_id': 'Target ID',
'audit.col.time': 'Time',
'audit.action.CREATE_PLAYER': 'Create player',
'audit.action.UPDATE_PLAYER': 'Update player',
'audit.action.RESET_DATABASE': 'Reset database',
'audit.action.CREATE_AGENT': 'Create agent',
'audit.action.UPDATE_AGENT': 'Update agent',
'audit.action.UPDATE_PLAYER_ACCOUNT_SETTINGS': 'Update player account settings',
'audit.action.UPDATE_AGENT_SUSPEND_SETTINGS': 'Update agent suspend settings',
'audit.action.UPDATE_BETTING_LIMITS': 'Update betting limits',
'audit.action.CONFIRM_SETTLEMENT': 'Confirm settlement',
'audit.action.CONFIRM_RESETTLE': 'Confirm resettlement',
'audit.action.CONFIRM_CASHBACK': 'Confirm cashback payout',
'audit.action.CANCEL_CASHBACK': 'Cancel cashback batch',
'audit.module.USERS': 'Players',
'audit.module.AGENTS': 'Agents',
'audit.module.SYSTEM': 'System',
'audit.module.SETTINGS': 'Settings',
'audit.module.SETTLEMENT': 'Settlement',
'audit.module.CASHBACK': 'Cashback',
'cashback.start_date': 'Start date',
'cashback.end_date': 'End date',
'cashback.preview_btn': 'Preview',
'cashback.preview_title': 'Cashback preview',
'cashback.stat.players': 'Players',
'cashback.stat.total': 'Total cashback',
'cashback.stat.lines': 'Line items',
'cashback.stat.effective_stake': 'Total effective stake',
'cashback.stat.bet_count': 'Eligible bets',
'cashback.stat.avg_rate': 'Average rate',
'cashback.batch_no': 'Batch no.',
'cashback.history_title': 'Cashback history',
'cashback.history_empty': 'No cashback batches yet',
'cashback.filter_status': 'Status',
'cashback.status.PREVIEW': 'Pending',
'cashback.status.CONFIRMED': 'Paid out',
'cashback.col.period': 'Period',
'cashback.col.status': 'Status',
'cashback.col.bet_count': 'Bets',
'cashback.col.created_at': 'Created',
'cashback.col.confirmed_at': 'Paid at',
'cashback.col.operator': 'Operator',
'cashback.view_detail': 'Details',
'cashback.detail_title': 'Batch breakdown',
'cashback.detail_summary': 'Batch summary',
'cashback.table_title': 'Player cashback breakdown',
'cashback.table_total': 'Total',
'cashback.empty_items': 'No eligible cashback in this period',
'cashback.col.index': '#',
'cashback.col.player': 'Player',
'cashback.col.agent': 'Agent',
'cashback.col.balance': 'Balance',
'cashback.col.effective_stake': 'Effective stake',
'cashback.col.rate': 'Rate',
'cashback.col.amount': 'Cashback',
'cashback.confirm_issue': 'Confirm payout',
'cashback.cancel_issue': 'Void',
'cashback.confirm_prompt': 'Pay out this cashback batch to player wallets? Cashback is credited by the platform directly and is not deducted from agents. This cannot be undone.',
'cashback.cancel_prompt': 'Void this pending batch? No wallet credit will be made; you can preview again.',
'cashback.status.CANCELLED': 'Voided',
'cashback.rules_title': 'Cashback rules',
'cashback.rule_period': 'Pick a date range. Bets are included by settlement time within that period.',
'cashback.rule_eligible': 'Included: settled bets with result WON or LOST (singles by stake; parlays counted once by parlay stake). Excluded: pending, cancelled, void, push, zero-rate bets, and bets already paid cashback.',
'cashback.rule_formula': 'Per bet: stake × applicable cashback rate. Amounts are summed per player into one line item.',
'cashback.rule_rate': 'Rate priority: player rule > agent rule > global rule > default rate (agent-line players use their agent default; platform-direct players use the rate under Global settings; override per player in player management). Enter as percent, e.g. 1 = 1%.',
'cashback.rule_flow': 'Flow: preview (one pending batch per period) → review → confirm payout; void if not needed. Paid periods cannot be previewed again.',
'cashback.rule_platform': 'Payout: cashback is credited to player cash balance by the platform; it is not deducted from agent credit or balance.',
'cashback.rule_note_zero': 'If preview is 0, check for settled WON/LOST bets in the period and a cashback rate above 0 (including platform-direct default in Global settings and per-player/agent overrides).',
'cashback.use_custom_rate': 'Custom cashback rate',
'cashback.use_default_rate': 'Use default rate {rate}',
'cashback.settings_title': 'Cashback settings',
'cashback.platform_direct_default_rate': 'Platform-direct default cashback rate',
'cashback.admin_invite_default_rate': 'Admin invite cashback rate',
'cashback.admin_invite_default_hint': 'Used when players register with an admin invite code; defaults to platform-direct rate. Agent invites use the rate set for that agent under Agent management.',
'cashback.platform_direct_default_hint': 'Used for self-registration without an invite code unless overridden per player.',
'user.field.player_id': 'Player ID',
'user.field.bet_count': 'Bet count',
'user.field.total_stake': 'Total stake',
'user.field.registered_at': 'Registered',
'user.ph.remark_initial': 'Ledger note when initial balance > 0',
'user.bets_edit_value': '{n} bets / {stake}',
'user.login_fail_value': '{n} times',
'match.import_hint': 'Paste JSON with matches array. Imports as draft; publish from the list.',
'match.import_start': 'Import',
'match.import_json_ph': '{"matches":[...]}',
'match.delete_confirm_title': 'Delete match',
'match.delete_confirm_body': 'Delete "{title}"? Draft with no bets only.',
'archive.match_title': 'Delete match',
'archive.league_title': 'Delete league',
'archive.target': 'Match: {title}',
'archive.league_target': 'League: {name}',
'archive.soft_delete_hint': 'Soft delete: data remains, hidden from admin and player lists.',
'archive.pending_summary': '{count} pending bet(s), stake {stake}',
'archive.refund_pending': 'Refund pending bet stakes',
'archive.parlay_void_hint': 'Parlay slips touching this match are voided in full.',
'archive.force_delete': 'Force delete',
'archive.msg_done': 'Deleted',
'archive.msg_done_refund': 'Deleted; refunded {n} bet(s)',
'archive.league_hint': 'League can be deleted only when all fixtures and outrights are settled with no pending bets.',
'archive.league_blocked': 'Unsettled fixtures or pending bets remain under this league.',
'archive.league_ready': 'This league can be deleted; all child events will be hidden.',
'archive.league_confirm': 'Delete league',
'archive.league_done': 'League deleted',
'archive.warning.PENDING_BETS': 'Pending bets exist',
'archive.warning.UNSETTLED_MATCH': 'Match is not in a terminal state',
'archive.warning.PREVIEW_BATCH': 'A settlement preview batch is pending',
'match.ph.league_en': 'FIFA World Cup 2026',
'match.ph.league_zh': '2026 World Cup',
'match.ph.kickoff': '2026-06-11T19:00:00Z',
'match.ph.home_en': 'Mexico',
'match.ph.home_zh': 'Mexico',
'match.ph.home_ms': 'Mexico',
'match.ph.away_en': 'South Africa',
'match.ph.away_zh': 'South Africa',
'match.ph.away_ms': 'Afrika Selatan',
'matchEditor.manage_btn': 'Basic info',
'matchEditor.back': 'Back to list',
'matchEditor.title': 'Edit basic info',
'matchEditor.section_info': 'Basic info',
'matchEditor.section_markets': 'Markets & odds',
'matchEditor.field.league_logo': 'Logo',
'matchEditor.field.home_logo': 'Logo',
'matchEditor.field.away_logo': 'Logo',
'matchEditor.field.pick_flag': 'Pick flag',
'matchEditor.field.custom_logo_url': 'Custom image URL',
'matchEditor.ph.logo_url': 'https://...',
'matchEditor.field.match_name': 'Display name',
'matchEditor.field.stage': 'Stage',
'matchEditor.field.group': 'Group',
'matchEditor.field.display_order': 'Sort order',
'matchEditor.field.promo_label': 'Promo label',
'matchEditor.field.promo_label_optional': 'Promo label (optional)',
'matchEditor.field.line_value': 'Line',
'matchEditor.field.player_visible': 'Show on player',
'matchEditor.ph.kickoff': 'Select kickoff date & time (Malaysia time)',
'matchEditor.group.league': 'League',
'matchEditor.hint.league_readonly': 'Edit league name and logo from the tournament list; shown here read-only.',
'matchEditor.group.home': 'Home team',
'matchEditor.group.away': 'Away team',
'matchEditor.group.schedule': 'Schedule & display',
'matchEditor.save_info': 'Save info',
'matchEditor.save_market': 'Save market',
'matchEditor.save_odds': 'Save odds',
'matchEditor.generate_templates': 'Generate templates',
'matchEditor.templates_generated': 'Market templates created',
'matchEditor.no_markets': 'No markets yet — publish the match or generate templates.',
'matchEditor.market.FT_1X2': 'FT 1X2',
'matchEditor.market.FT_HANDICAP': 'FT handicap',
'matchEditor.market.FT_OVER_UNDER': 'FT O/U',
'matchEditor.market.FT_ODD_EVEN': 'FT odd/even',
'matchEditor.market.HT_1X2': 'HT 1X2',
'matchEditor.market.HT_HANDICAP': 'HT handicap',
'matchEditor.market.HT_OVER_UNDER': 'HT O/U',
'matchEditor.market.FT_CORRECT_SCORE': 'FT correct score',
'matchEditor.market.HT_CORRECT_SCORE': '1H correct score',
'matchEditor.market.SH_CORRECT_SCORE': '2H correct score',
'matchEditor.period.FT': 'Full time',
'matchEditor.period.HT': 'Half time',
'matchEditor.period.SH': 'Second half',
'matchEditor.period.OUTRIGHT': 'Outright',
'matchEditor.selection.HOME': 'Home',
'matchEditor.selection.DRAW': 'Draw',
'matchEditor.selection.AWAY': 'Away',
'matchEditor.selection.OVER': 'Over',
'matchEditor.selection.UNDER': 'Under',
'matchEditor.selection.ODD': 'Odd',
'matchEditor.selection.EVEN': 'Even',
'matchEditor.selection.OTHER_DRAW': 'Draw (other score)',
'matchEditor.selection.OTHER_HOME': 'Home win (other score)',
'matchEditor.selection.OTHER_AWAY': 'Away win (other score)',
'matchEditor.col.selection_code': 'Option',
'matchEditor.col.selection_name': 'Display name',
'matchEditor.col.odds': 'Odds',
'matchEditor.ph.selection_name': 'Name shown to players',
'err.username_required': 'Username is required',
'err.username_player_invalid': 'Player username must be 332 English letters or digits only',
'err.password_min': 'Password must be at least 8 characters',
'err.password_mismatch': 'Passwords do not match',
'err.credit_negative': 'Credit limit cannot be negative',
'err.insufficient_credit': 'Insufficient available credit. Reduce the amount or request a limit increase.',
'err.kickoff_required': 'Kickoff time is required',
'err.team_country_required': 'Select home and away teams',
'err.teams_required': 'Enter home and away team names (ZH or EN)',
'err.teams_same': 'Home and away teams must be different',
'err.league_required': 'League name is required',
'err.user_required': 'Please select a user',
'err.agent_no_parent': 'Tier-1 agents cannot have a parent player',
'err.agent_no_initial_deposit': 'Do not set initial player balance when creating an agent',
'err.initial_deposit_kind_required': 'Select a ledger note when initial balance > 0',
'err.initial_deposit_custom_required': 'Custom ledger note must be at least 2 characters',
'settlement.back': 'Back to matches',
'settlement.kickoff': 'Kick-off',
'settlement.stats_title': 'Betting statistics',
'settlement.stats_total_bets': 'Bets',
'settlement.stats_single': 'Singles',
'settlement.stats_parlay': 'Parlays',
'settlement.stats_total_stake': 'Total stake',
'settlement.stats_potential': 'Max potential win',
'settlement.chart.bet_type': 'Single vs parlay',
'settlement.chart.status': 'Bet status mix',
'settlement.chart.stake_by_selection': 'Top selections by single stake',
'settlement.stats_by_market': 'By market / selection',
'settlement.bet_list': 'Related bets',
'settlement.bet_list_hint': 'Grouped by bet; same-match parlays show ×legs',
'settlement.no_bets': 'No bets on this match',
'settlement.col.market': 'Market',
'settlement.col.selection': 'Selection',
'settlement.col.legs': 'Legs',
'settlement.col.single_stake': 'Single stake',
'settlement.col.parlay_legs': 'Parlay legs',
'settlement.ht_score': 'Half-time score',
'settlement.ft_score': 'Full-time score',
'settlement.stats_facts': 'Match facts',
'settlement.corners': 'Corners',
'settlement.cards': 'Cards',
'settlement.yellow_cards': 'Yellow cards',
'settlement.red_cards': 'Red cards',
'settlement.home_stat': 'Home',
'settlement.away_stat': 'Away',
'settlement.record_score': 'Save score',
'settlement.preview_hint': 'Preview moves the match to pending settlement and calculates payouts (scores are saved on confirm; you can reopen betting before confirming)',
'settlement.preview_btn': 'Preview settlement',
'settlement.preview_failed': 'Failed to generate settlement preview',
'settlement.err_score_not_recorded': 'Enter half-time and full-time scores before preview',
'settlement.must_close_first': 'Close betting before settlement',
'settlement.outright.page_title': 'Outright settlement',
'settlement.outright.title': 'Outright winner',
'settlement.outright.winner': 'Winning team',
'settlement.outright.winner_ph': 'Select champion',
'settlement.outright.preview_hint': 'Select the winner, preview payouts, then confirm settlement',
'settlement.outright.winner_required': 'Please select the winning team first',
'settlement.preview_title': 'Settlement preview',
'settlement.single_count': 'Single bets',
'settlement.preview_pending_bets': 'Pending bets',
'settlement.preview_bet_mix': 'Single / parlay',
'settlement.preview_items_title': 'Per-bet preview ({n})',
'settlement.preview_items_scroll_hint': 'Scroll when the list is long',
'settlement.preview_col.result': 'Match result',
'settlement.preview_zero_parlay_hint':
'Est. payout is 0: {pending} cross-match parlay bet(s) must wait for every fixture before final settlement.',
'settlement.preview_zero_lost_hint':
'Est. payout is 0: {count} parlay(s) are ready for final settlement and lost; other bets did not win here either.',
'settlement.preview_zero_default_hint':
'Est. payout is 0: no winning or refundable outcome on this match yet.',
'settlement.preview.result.WIN': 'Win',
'settlement.preview.result.LOSE': 'Lose',
'settlement.preview.result.LOST': 'Parlay lost',
'settlement.preview.result.WON': 'Parlay won',
'settlement.preview.result.PUSH': 'Push',
'settlement.preview.result.PENDING_OTHER_MATCHES': 'Awaiting other matches',
'settlement.est_payout': 'Est. payout',
'settlement.refund_amount': 'Refund amount',
'settlement.confirm_btn': 'Confirm settlement',
'settlement.resettle_reason': 'Resettle reason',
'settlement.resettle_preview': 'Resettle preview',
'settlement.resettle_preview_title': 'Resettle preview',
'settlement.resettle_affected': 'Affected bets',
'settlement.resettle_topup': 'Top-up required',
'settlement.resettle_clawback': 'Clawback required',
'settlement.resettle_confirm': 'Confirm resettle',
'user.betting_limits': 'Betting limits',
'user.betting_limits_hint': 'Global stake/payout/daily limits for player bets',
'user.limit.min_stake': 'Min stake',
'user.limit.max_stake_single': 'Max single stake',
'user.limit.max_stake_parlay': 'Max parlay stake',
'user.limit.max_payout_single': 'Max single payout',
'user.limit.max_payout_parlay': 'Max parlay payout',
'user.limit.daily_stake': 'Daily stake limit',
'settlement.smart.btn': 'Smart score',
'settlement.smart.title': 'Smart score suggestions',
'settlement.smart.hint': 'Enumerates valid scores from pending single bets and estimates payout. Parlays are excluded. Click a card to apply.',
'settlement.smart.target_hold': 'Target house hold',
'settlement.smart.recalc': 'Recalculate',
'settlement.smart.apply': 'Apply score',
'settlement.smart.applied': 'Score applied',
'settlement.smart.no_bets': 'No pending single bets',
'settlement.smart.empty': 'No suggestion found',
'settlement.smart.meta': 'Singles {singles}, parlays {parlays} skipped, {n} scores compared',
'settlement.smart.hold': 'Hold',
'settlement.smart.payout': 'Payout',
'settlement.smart.win_stake': 'Win stake %',
'settlement.smart.wl': 'W/L bets',
'settlement.smart.strategy.MIN_PAYOUT': 'Max house hold (min payout)',
'settlement.smart.strategy.MAX_PAYOUT': 'Max player payout',
'settlement.smart.strategy.BALANCED': 'Balanced (~50% win stake)',
'settlement.smart.strategy.TARGET_HOLD': 'Target hold rate',
'msg.score_recorded': 'Score saved',
'msg.settlement_confirmed': 'Settlement confirmed',
'msg.resettle_confirmed': 'Resettle confirmed',
'agent_portal.create_player_section': 'Create player',
'agent_portal.deposit_section': 'Top up',
'agent_portal.create_player_btn': '+ New player',
'agent_portal.create_tier2_btn': '+ New tier-2 agent',
'agent_portal.username_ph': 'Enter username',
'agent_portal.agent_username_ph': 'Agent username',
'agent_portal.player_id_ph': 'Player ID',
'agent_portal.withdraw_btn': 'Withdraw {amount}',
'agent_portal.withdraw_btn_label': 'Withdraw',
'agent_portal.transfer_title_deposit': 'Top up {name}',
'agent_portal.transfer_title_withdraw': 'Withdraw from {name}',
'transfer.context.player_section': 'Player balance',
'transfer.context.agent_section': 'Credit agent · {name} (L{level})',
'transfer.context.withdrawable': 'Withdrawable',
'transfer.context.deposit_cap': 'Max top-up this time',
'transfer.context.daily_used': 'Topped up today',
'transfer.context.unlimited': 'No limit',
'transfer.context.no_agent': 'Platform-direct player — not limited by agent credit',
'transfer.context.admin_credit_only': 'Admin top-up is capped by parent available credit only (not single/daily limits)',
'transfer.context.withdraw_exceed': 'Withdrawal cannot exceed player available balance',
'credit.context.target_section': 'Target agent credit',
'credit.context.parent_section': 'Parent agent · {name}',
'credit.context.max_increase': 'Max increase',
'credit.context.no_parent': 'Tier-1 agents are platform-managed; increases are not capped by a parent',
'credit.context.after_adjust': 'Credit limit after adjustment',
'credit.context.direct_liability': 'Direct player exposure',
'credit.context.child_exposure': 'Sub-agent exposure',
'credit.context.acting_agent': 'Current agent',
'agent_portal.create_player_dialog': 'New direct player',
'agent_portal.edit_player_dialog': 'Edit direct player',
'agent_portal.my_cashback_rate': 'Cashback rate',
'agent_portal.credit_available_hint': 'Available credit: {amount} (top-ups deduct from your limit)',
'agent_portal.sub_agent_players_readonly': 'Players under this sub-agent are read-only here. Account opening and top-ups are handled by the sub-agent.',
'agent_portal.sub_agent_downline_readonly': 'All subordinate agents and players below this sub-agent are read-only. You may only operate direct sub-agents; account opening and top-ups are handled by each level.',
'agent_portal.sub_agent_downline_readonly_level': 'All agents and players below this L{level} agent are read-only. You may only operate direct sub-agents; account opening and top-ups are handled by each level.',
'agent_portal.downline_agents_title': 'Subordinate agents',
'agent_portal.downline_players_title': 'Subordinate players',
'agent_portal.no_downline_agents': 'No subordinate agents',
'agent_portal.no_downline_players': 'No subordinate players',
'agent_portal.initial_deposit_hint': 'Optional. Initial top-up from your credit at account creation',
'agent_portal.search_player_ph': 'Username or ID',
'agent_portal.no_players': 'No direct players yet. Use the button above to create one.',
'invite.title': 'Invitation code & register link',
'invite.menu_btn': 'Invite',
'invite.dialog_title': 'Invitations',
'invite.tab_generate': 'Generate',
'invite.tab_history': 'History',
'invite.hint': 'Generate an invite code and register link. Players may enter the code to register; blank registers as platform-direct.',
'invite.generate_btn': 'Generate code / link',
'invite.regenerate_btn': 'Regenerate',
'invite.generate_ok': 'Invitation code generated',
'invite.generate_failed': 'Failed to generate — please retry',
'invite.not_generated': 'No invitation code yet',
'invite.code': 'Code',
'invite.cashback_rate': 'Cashback rate',
'invite.cashback_rate_hint': 'Players registering with this code use this rate. Defaults to the global admin-invite cashback rate.',
'invite.link': 'Register link',
'invite.copy_code': 'Copy code',
'invite.copy_code_short': 'Copy',
'invite.copy_link': 'Copy register link',
'invite.copy_link_short': 'Copy link',
'invite.copy_code_ok': 'Invitation code copied',
'invite.copy_link_ok': 'Register link copied',
'invite.copy_failed': 'Copy failed — please copy manually',
'invite.unavailable': 'Invitation code unavailable',
'invite.history_title': 'Invitation history',
'invite.view_history': 'View history',
'invite.history_hint': 'Admins see all codes; agents see their own and sub-agents codes.',
'invite.page_desc': 'View all invitation codes, status, and registration counts.',
'invite.history_load_failed': 'Failed to load invitation history',
'invite.filter_status': 'Status',
'invite.filter_sponsor': 'Sponsor',
'invite.filter_code': 'Code',
'invite.filter_code_ph': 'Enter code',
'invite.col_status': 'Status',
'invite.col_sponsor': 'Sponsor',
'invite.col_registrant': 'Registrant',
'invite.not_registered': 'Not registered',
'invite.col_cashback_rate': 'Cashback',
'invite.col_created': 'Created',
'invite.col_revoked': 'Revoked',
'invite.status.ACTIVE': 'Active',
'invite.status.USED': 'Used',
'invite.status.REVOKED': 'Revoked',
'invite.revoke_btn': 'Revoke',
'invite.revoke_title': 'Revoke invitation code',
'invite.revoke_confirm': 'Revoke code {code}? It will no longer work for registration.',
'invite.revoke_ok': 'Invitation code revoked',
'invite.revoke_failed': 'Failed to revoke — please retry',
'invite.delete_title': 'Delete invitation record',
'invite.delete_confirm': 'Delete history for code {code}? This cannot be undone.',
'invite.delete_ok': 'Invitation record deleted',
'invite.delete_failed': 'Failed to delete — please retry',
'agent_portal.search_sub_agent_ph': 'Username or ID',
'agent_portal.no_sub_agents': 'No tier-2 agents yet. Use the button above to create one.',
'agent_portal.no_sub_agents_level': 'No L{level} agents yet. Use the button above to create one.',
'agent_portal.sub_agent_players_readonly_level': 'Direct players under this L{level} agent are read-only here. Account opening and top-ups are handled by that agent.',
'agent_portal.create_sub_agent_dialog': 'New tier-2 agent',
'agent_portal.sub_agent_credit_hint': 'Initial credit is allocated from your available limit',
'agent_portal.adjust_credit_dialog': 'Adjust credit for {name}',
'agent_portal.credit_adjust_hint': 'Positive to increase, negative to decrease',
'msg.agent_sub_created': 'Sub-agent created',
'msg.withdraw_ok': 'Withdrawal successful',
'msg.form_invalid': 'Please check the form',
'msg.player_created': 'Player created',
'msg.agent_created': 'Agent created',
'msg.create_failed': 'Create failed',
'msg.saved': 'Saved',
'msg.save_failed': 'Save failed',
'msg.deleted': 'Deleted',
'msg.delete_failed': 'Delete failed',
'msg.league_created': 'Tournament created',
'msg.league_updated': 'Tournament updated',
'msg.match_created_draft': 'Fixture created (draft)',
'msg.published': 'Published with markets',
'msg.closed': 'Betting closed',
'msg.reopened': 'Betting reopened',
'match.reopen_kickoff_title': 'Set new kickoff time',
'match.reopen_kickoff_hint': 'Kickoff has passed. Choose a new future start time before reopening.',
'match.reopen_kickoff_invalid': 'Please choose a future kickoff time',
'msg.invalid_json': 'Invalid JSON',
'msg.import_failed': 'Import failed',
'msg.import_done': 'Import: {imported} ok, {skipped} skipped, {failed} failed / {total} total',
'msg.topup_ok': 'Top-up successful',
'msg.topup_failed': 'Top-up failed',
'msg.transfer_failed': 'Operation failed',
'msg.amount_gt_zero': 'Amount must be greater than 0',
'msg.credit_zero': 'Adjustment cannot be 0',
'msg.credit_adjusted': 'Credit updated',
'msg.credit_adjust_failed': 'Adjustment failed',
'msg.outright_no_edit': 'Outright cannot be edited here',
'msg.outright_odds_saved': 'Outright odds saved',
'msg.load_failed': 'Load failed',
'content.btn.create': 'New content',
'content.btn.enable': 'Enable',
'content.btn.disable': 'Disable',
'content.dialog.create': 'New public content',
'content.dialog.edit': 'Edit public content',
'content.confirm_delete': 'Delete "{title}"?',
'content.type.BANNER': 'Home banners',
'content.type.ANNOUNCEMENT': 'Announcements',
'content.hint.announcement': 'Shown in the player top marquee; fill title or body (body recommended)',
'content.status.DRAFT': 'Draft',
'content.status.ACTIVE': 'Active',
'content.status.INACTIVE': 'Inactive',
'content.col.sort': 'Sort',
'content.col.preview': 'Preview',
'content.col.title': 'Title / summary',
'content.col.player_visible': 'Player visible',
'content.col.schedule': 'Schedule',
'content.col.link': 'Link',
'content.field.link_type': 'Link type',
'content.field.link_target': 'Link target',
'content.field.start_time': 'Start time',
'content.field.end_time': 'End time',
'content.field.title': 'Title',
'content.field.title_ph': 'Optional; can match body',
'content.field.body': 'Body',
'content.field.announce_text': 'Marquee text',
'content.field.image_url': 'Image URL',
'content.upload.upload_btn': 'Upload Image',
'content.upload.uploading': 'Uploading…',
'content.upload.success': 'Image uploaded',
'content.upload.failed': 'Upload failed',
'content.upload.size_error': 'Image must be under 5 MB',
'content.upload.remove': 'Remove image',
'content.upload.pick_media': 'Pick from library',
'content.upload.pick_media_title': 'Select Banner Image',
'content.upload.no_media': 'No banner images in library — upload one first',
'content.upload.url_placeholder': 'Or paste image URL',
'content.upload.recommended_size': 'Recommended size: 860 x 360 px, or any 43:18 image. The player carousel keeps the full image visible and fills extra space.',
'content.link.none': 'No link',
'content.locale.zh-CN': 'Chinese (Simplified)',
'content.locale.en-US': 'English',
'content.locale.ms-MY': 'Malay',
'content.hidden_reason.NOT_ACTIVE': 'Not active or draft',
'content.hidden_reason.NOT_STARTED': 'Not started yet',
'content.hidden_reason.EXPIRED': 'Expired',
'content.hidden_reason.INCOMPLETE': 'Incomplete translations',
'content.batch.selected': '{n} selected',
'content.batch.enable': 'Enable selected',
'content.batch.disable': 'Disable selected',
'content.batch.delete': 'Delete selected',
'content.confirm_batch_enable': 'Enable {n} selected item(s)?',
'content.confirm_batch_disable': 'Disable {n} selected item(s)?',
'content.confirm_batch_delete': 'Delete {n} selected item(s)?',
'content.batch.all_ok': '{n} item(s) processed',
'content.batch.partial': '{ok} succeeded, {fail} failed',
'page.outrights.title': 'Outrights',
'page.outrights.desc': 'Create and edit any winner market; WC 2026 has one-click baseline import',
'outright.col.rank': 'Rank',
'outright.col.team_zh': 'Team (ZH)',
'outright.col.team_en': 'Team (EN)',
'outright.col.code': 'Code',
'outright.col.country': 'Country',
'outright.col.odds': 'Winner odds',
'outright.country_ph': 'Search or select country',
'teamLogo.kind.flag': 'Flag',
'teamLogo.kind.crest': 'Crest',
'outright.err_country': 'Please select a country',
'outright.btn.save_odds': 'Save all odds',
'outright.btn.close': 'Close betting',
'outright.btn.settle': 'Settle',
'outright.confirm_close': 'Closing will stop new outright bets. Continue?',
'outright.btn.save_meta': 'Save event info',
'outright.btn.publish': 'Publish',
'outright.btn.unpublish': 'Unpublish',
'outright.back_list': 'Back to list',
'outright.section.edit': 'Edit outright',
'outright.col.teams': 'Teams',
'outright.col.player_visible': 'Player',
'outright.col.league_en': 'League (EN)',
'outright.expand_no_teams': 'No teams — open Edit to add',
'outright.fixtures_sync_hint': 'Teams come from league fixtures; adjust odds and publish status only.',
'outright.empty_no_fixtures': 'No fixtures in this league — add matches under Fixtures first.',
'outright.btn.add_team': 'Add team',
'outright.add.filter_fixture': 'From fixtures',
'outright.add.filter_all': 'All built-in',
'outright.add.filter_custom': 'Custom',
'outright.add.custom_hint': 'Enter team code and Chinese/English names; logo via upload or URL.',
'outright.add.field_code': 'Team code',
'outright.add.field_logo': 'Logo',
'outright.add.ph_code': 'e.g. TEAM01',
'outright.add.ph_name_zh': 'Chinese name',
'outright.add.ph_name_en': 'English name',
'outright.add.err_code_required': 'Team code is required',
'outright.add.err_name_required': 'Enter at least Chinese or English name',
'outright.add.err_duplicate': 'This team code is already on the outright market',
'outright.add.select_all': 'Select all',
'outright.add.clear_selection': 'Clear selection',
'outright.add.selected_count': '{n} selected',
'outright.add.empty_fixture': 'No fixture teams to add (teams in matches but not yet on the outright market)',
'outright.add.empty_all': 'All built-in teams are already on the outright market',
'outright.add.default_odds': 'Default odds',
'outright.add.search_ph': 'Search name or code',
'outright.add.err_none': 'Select at least one team',
'outright.batch.mode': 'Batch manage',
'outright.batch.exit': 'Exit batch',
'outright.batch.apply_odds': 'Apply odds',
'outright.batch.remove': 'Remove selected',
'outright.batch.confirm_remove': 'Remove {n} selected team(s)?',
'outright.batch.err_none': 'Select teams first',
'outright.batch.apply_ok': 'Updated odds for {n} team(s) — click Save all odds',
'outright.batch.remove_ok': 'Removed {n} team(s)',
'outright.batch.remove_partial': '{ok} removed, {fail} failed',
'outright.sort.label': 'Sort',
'outright.sort.rank': 'Rank',
'outright.sort.name': 'Team name',
'outright.sort.code': 'Code',
'outright.sort.odds': 'Odds (current)',
'outright.sort.saved_odds': 'Odds (saved)',
'outright.sort.asc': 'Ascending',
'outright.sort.desc': 'Descending',
'msg.outright_teams_added': 'Added {n} team(s) ({skipped} skipped)',
'outright.btn.create_event': 'New outright event',
'outright.btn.import_wc2026': 'Import WC 2026 (48)',
'outright.btn.apply_canonical': 'Apply WC baseline',
'outright.field.league': 'League',
'outright.section.settings': 'Event settings',
'outright.section.teams': 'Teams & odds',
'outright.field.title': 'Event title',
'outright.field.title_placeholder': 'Title shown on player outright tab',
'outright.field.title_zh': 'Title (ZH)',
'outright.field.title_en': 'Title (EN)',
'outright.field.title_ms': 'Title (MS)',
'outright.field.status': 'Status',
'outright.status.draft': 'Draft',
'outright.status.published': 'Published',
'msg.outright_canonical_applied': '48-team winner odds applied from baseline',
'outright.team_count': '{n} / {total} teams',
'outright.team_count_open': '{n} teams',
'outright.empty_events': 'No outright events',
'outright.empty_hint': 'Create an event or import WC 2026 baseline',
'outright.err_odds_min': 'Odds must be greater than 1.00',
'outright.err_team_code': 'Team code required',
'outright.err_league': 'Select a league',
'outright.confirm_remove': 'Remove "{name}"? (closes selection)',
'outright.not_on_player': 'Hidden on player',
'outright.player_hidden_title': 'Not visible on player app yet',
'outright.hidden_reason.NOT_PUBLISHED': 'Set status to Published and save event info.',
'outright.hidden_reason.NO_SELECTIONS': 'Add at least one open team selection.',
'outright.hidden_reason.MARKET_CLOSED': 'Winner market is not open.',
'msg.load_matches_failed': 'Failed to load matches',
'msg.cashback_issued': 'Cashback issued',
'msg.cashback_cancelled': 'Cashback batch voided',
'msg.cashback_preview_ready': 'Preview ready — review and confirm payout',
'msg.cashback_preview_replaced': 'Replaced {n} older preview(s) for this period',
'msg.freeze_confirm_title': '{action} account',
'msg.freeze_confirm_body': '{action} player "{name}"?{extra}',
'msg.freeze_extra': ' They will not be able to sign in.',
'msg.freeze_done': '{action} completed',
'msg.freeze_failed': '{action} failed',
'smoke.intro': 'Run automated smoke tests from the admin console: settlement, betting rules, agent credit logic, cashback rules, read-only DB probes, and bet→settle→wallet integration.',
'smoke.intro_rule': 'Rule cases reuse the same logic as Jest unit tests; no business data is written.',
'smoke.intro_db': 'The Database suite only checks connectivity and config (read-only).',
'smoke.intro_bet_flow': 'The Bet-flow suite creates temporary matches/players, verifies freeze/payout/agent credit, then cleans up.',
'smoke.intro_note': 'Covers most UAT regression; spot-check cashback payout manually if needed.',
'smoke.field.suites': 'Suites',
'smoke.ph.suites': 'Select suites to run',
'smoke.btn.run': 'Run tests',
'smoke.last_run': 'Last run',
'smoke.results_title': 'Case results',
'smoke.empty': 'No run yet. Click Run tests.',
'smoke.stat.pass': 'Pass',
'smoke.stat.fail': 'Fail',
'smoke.stat.total': 'Total',
'smoke.col.id': 'ID',
'smoke.col.suite': 'Suite',
'smoke.col.name': 'Case',
'smoke.col.uat': 'UAT',
'smoke.col.duration': 'Duration',
'smoke.col.steps': 'Steps',
'smoke.col.message': 'Message',
'smoke.no_steps': 'No step details',
'smoke.status.PASS': 'Pass',
'smoke.status.FAIL': 'Fail',
'smoke.status.SKIP': 'Skip',
'smoke.msg.all_passed': 'All passed ({n})',
'smoke.msg.has_failures': '{n} case(s) failed — see details',
'smoke.msg.run_failed': 'Failed to run tests',
'smoke.log_title': 'Detailed log',
'smoke.btn.copy_all': 'Copy full log',
'smoke.btn.copy_one': 'Copy',
'smoke.msg.copy_ok': 'Copied to clipboard',
'smoke.msg.copy_failed': 'Copy failed — select the log manually',
'audit.action.RUN_SMOKE_TESTS': 'Run smoke tests',
'media.title': 'Media Library',
'media.upload_btn': 'Upload File',
'media.category.all': 'All',
'media.category.banners': 'Banners',
'media.category.teams': 'Team Logos',
'media.category.contents': 'Content Images',
'media.col.preview': 'Preview',
'media.col.filename': 'Filename',
'media.col.category': 'Category',
'media.col.size': 'Size',
'media.col.status': 'Status',
'media.col.uploaded': 'Uploaded',
'media.col.actions': 'Actions',
'media.status.used': 'In Use',
'media.status.unused': 'Unused',
'media.purge_btn': 'Purge Unused',
'media.purge_confirm': 'Delete {n} unused file(s)? This cannot be undone.',
'media.purge_none': 'No unused files',
'media.purge_success': '{n} file(s) deleted',
'media.delete_confirm': 'Delete this file?',
'media.delete_success': 'Deleted',
'media.upload_success': 'Upload successful',
'media.upload_failed': 'Upload failed',
'media.copy_url': 'Copy URL',
'media.url_copied': 'URL copied',
'media.upload_dialog': 'Upload File',
'media.upload_hint': 'PNG, JPG, WEBP, GIF, SVG — max 5 MB',
'media.upload_category': 'Category',
'media.drop_hint': 'Drop file here or click to select',
'media.no_files': 'No files yet',
'media.refresh': 'Refresh',
'media.unused_count': '{n} unused',
};
export default adminPages;