const dict: Record = { "session.todo.title": "Todos", "session.todo.collapse": "Collapse todos", "session.todo.expand": "Expand todos", "session.revertDock.summary.one": "{{count}} rolled back message", "session.revertDock.summary.other": "{{count}} rolled back messages", "session.revertDock.collapse": "Collapse rolled back messages", "session.revertDock.expand": "Expand rolled back messages", "session.revertDock.restore": "Restore message", "prompt.loading": "Loading prompt...", "prompt.placeholder.normal": "Ask anything...", "prompt.placeholder.simple": "Ask anything...", "prompt.placeholder.shell": "Enter shell command... {{example}}", "prompt.placeholder.summarizeComment": "Summarize this comment", "prompt.placeholder.summarizeComments": "Summarize these comments", "prompt.action.attachFile": "Attach files", "prompt.action.send": "Send", "prompt.action.stop": "Stop", "prompt.attachment.remove": "Remove attachment", "prompt.dropzone.label": "Drop image to attach", "prompt.dropzone.file.label": "Drop file to attach", "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "dialog.model.select.title": "Select model", "dialog.model.unpaid.freeModels.title": "Free models provided by OpenCode", "dialog.model.unpaid.addMore.title": "Add more models from popular providers", "dialog.model.unpaid.viewMoreProviders": "See 70+ more providers", "dialog.provider.opencode.tagline": "Reliable optimized models", "dialog.provider.opencodeGo.tagline": "Low cost subscription for everyone", "dialog.provider.custom.label": "Custom OpenAI-compatible provider", "dialog.provider.search.placeholder": "Search providers", "dialog.provider.empty": "No providers found", "dialog.provider.group.popular": "Popular", "dialog.provider.group.other": "Other", "dialog.provider.tag.recommended": "Recommended", "settings.providers.tag.custom": "Custom", "command.provider.connect": "Connect provider", "provider.connect.title": "Connect {{provider}}", "provider.connect.selectMethod": "Select login method for {{provider}}.", "provider.connect.method.apiKey": "API key", "provider.connect.apiKey.description": "Enter your {{provider}} API key to connect your account and use {{provider}} models in OpenCode.", "provider.connect.apiKey.label": "{{provider}} API key", "provider.connect.apiKey.placeholder": "API key", "provider.connect.apiKey.required": "API key is required", "provider.connect.opencodeZen.line1": "OpenCode Zen gives you access to a curated set of reliable optimized models for coding agents.", "provider.connect.opencodeZen.line2": "With a single API key you'll get access to models such as Claude, GPT, Gemini, GLM and more.", "provider.connect.opencodeZen.visit.prefix": "Visit ", "provider.connect.opencodeZen.visit.link": "opencode.ai/zen", "provider.connect.opencodeZen.visit.suffix": " to collect your API key.", "provider.connect.oauth.code.visit.prefix": "Visit ", "provider.connect.oauth.code.visit.link": "this link", "provider.connect.oauth.code.visit.suffix": " to collect your authorization code to connect your account and use {{provider}} models in OpenCode.", "provider.connect.oauth.code.label": "{{method}} authorization code", "provider.connect.oauth.code.placeholder": "Authorization code", "provider.connect.oauth.code.required": "Authorization code is required", "provider.connect.oauth.code.invalid": "Invalid authorization code", "provider.connect.oauth.auto.visit.prefix": "Visit ", "provider.connect.oauth.auto.visit.link": "this link", "provider.connect.oauth.auto.visit.suffix": " and enter the code below to connect your account and use {{provider}} models in OpenCode.", "provider.connect.oauth.auto.confirmationCode": "Confirmation code", "provider.connect.status.inProgress": "Authorization in progress...", "provider.connect.status.waiting": "Waiting for authorization...", "provider.connect.status.failed": "Authorization failed: {{error}}", "provider.connect.toast.connected.title": "{{provider}} connected", "provider.connect.toast.connected.description": "{{provider}} models are now available to use.", "common.continue": "Continue", "model.tag.free": "Free", "model.tag.latest": "Latest", "model.input.text": "text", "model.input.image": "image", "model.input.audio": "audio", "model.input.video": "video", "model.input.pdf": "pdf", "model.tooltip.context.label": "Context", "model.tooltip.inputs": "Inputs", "model.tooltip.model": "Model", "model.tooltip.provider": "Provider", "model.tooltip.reasoning": "Reasoning", "model.tooltip.reasoning.allowed": "Allows reasoning", "model.tooltip.reasoning.none": "No reasoning", "common.close": "Close", "common.goBack": "Go back", "common.default": "Default", "common.key.esc": "Esc", "command.category.file": "File", "command.category.session": "Session", "command.agent.cycle": "Cycle agent", "command.model.choose": "Choose model", "command.model.variant.cycle": "Cycle model variant", "command.prompt.mode.shell": "Switch to shell mode", "command.prompt.mode.normal": "Switch to prompt mode", "command.permissions.autoaccept.enable": "Enable auto-accept", "command.permissions.autoaccept.disable": "Disable auto-accept", "prompt.example.1": "Refactor this function and keep behavior the same", "prompt.example.2": "Find the root cause of this error", "prompt.example.3": "Write tests for this module", "prompt.example.4": "Explain this diff", "prompt.example.5": "Optimize this query", "prompt.example.6": "Clean up this component", "prompt.example.7": "Summarize the recent changes", "prompt.example.8": "Add accessibility checks", "prompt.example.9": "Review this API design", "prompt.example.10": "Generate migration notes", "prompt.example.11": "Patch this bug", "prompt.example.12": "Make this animation smoother", "prompt.example.13": "Improve error handling", "prompt.example.14": "Document this feature", "prompt.example.15": "Refine these styles", "prompt.example.16": "Check edge cases", "prompt.example.17": "Help me write a commit message", "prompt.example.18": "Reduce re-renders in this component", "prompt.example.19": "Verify keyboard navigation", "prompt.example.20": "Make this copy clearer", "prompt.example.21": "Add telemetry for this flow", "prompt.example.22": "Compare these two implementations", "prompt.example.23": "Create a minimal reproduction", "prompt.example.24": "Suggest naming improvements", "prompt.example.25": "What should we test next?", } const plurals = new Intl.PluralRules("en-US") function render(template: string, params?: Record) { if (!params) return template return template.replace(/\{\{([^}]+)\}\}/g, (_, key: string) => { const value = params[key.trim()] if (value === undefined || value === null) return "" // oxlint-disable-next-line no-base-to-string -- value is Record, always coerced intentionally return String(value) }) } export function useLanguage() { return { locale: () => "en" as const, intl: () => "en-US", t(key: string, params?: Record) { return render(dict[key] ?? key, params) }, plural(key: string, count: number, params?: Record) { const value = dict[`${key}.${plurals.select(count)}`] ?? dict[`${key}.other`] ?? key return render(value, { ...params, count }) }, } }