diff --git a/packages/console/app/public/apple-touch-icon-v3.png b/packages/console/app/public/apple-touch-icon-v3.png new file mode 100644 index 0000000000000000000000000000000000000000..70fd01b0ea38ea8b3d0429a6438f5b8e85aba94a Binary files /dev/null and b/packages/console/app/public/apple-touch-icon-v3.png differ diff --git a/packages/console/app/public/apple-touch-icon.png b/packages/console/app/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..70fd01b0ea38ea8b3d0429a6438f5b8e85aba94a Binary files /dev/null and b/packages/console/app/public/apple-touch-icon.png differ diff --git a/packages/console/app/public/favicon-96x96-v3.png b/packages/console/app/public/favicon-96x96-v3.png new file mode 100644 index 0000000000000000000000000000000000000000..15266d28f159a74d5c54634d1b3ef548e97f6c8c Binary files /dev/null and b/packages/console/app/public/favicon-96x96-v3.png differ diff --git a/packages/console/app/public/favicon-96x96.png b/packages/console/app/public/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..15266d28f159a74d5c54634d1b3ef548e97f6c8c Binary files /dev/null and b/packages/console/app/public/favicon-96x96.png differ diff --git a/packages/console/app/public/favicon-v3.ico b/packages/console/app/public/favicon-v3.ico new file mode 100644 index 0000000000000000000000000000000000000000..34ca0b9c01b23ca30f64ed17bd0705bb08cca4b1 Binary files /dev/null and b/packages/console/app/public/favicon-v3.ico differ diff --git a/packages/console/app/public/favicon-v3.svg b/packages/console/app/public/favicon-v3.svg new file mode 100644 index 0000000000000000000000000000000000000000..157edc4d7522f38d3d34aff1317d304cb7958752 --- /dev/null +++ b/packages/console/app/public/favicon-v3.svg @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/packages/console/app/public/favicon.ico b/packages/console/app/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..34ca0b9c01b23ca30f64ed17bd0705bb08cca4b1 Binary files /dev/null and b/packages/console/app/public/favicon.ico differ diff --git a/packages/console/app/public/favicon.svg b/packages/console/app/public/favicon.svg new file mode 100644 index 0000000000000000000000000000000000000000..157edc4d7522f38d3d34aff1317d304cb7958752 --- /dev/null +++ b/packages/console/app/public/favicon.svg @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/packages/console/app/public/robots.txt b/packages/console/app/public/robots.txt new file mode 100644 index 0000000000000000000000000000000000000000..12850523e5eec1a1f1d443a5b820e8eb7a20f124 --- /dev/null +++ b/packages/console/app/public/robots.txt @@ -0,0 +1,9 @@ +User-agent: * +Allow: / + +# Disallow shared content pages +Disallow: /s/ +Disallow: /share/ + +Sitemap: https://opencode.ai/sitemap.xml +Sitemap: https://opencode.ai/data/sitemap.xml diff --git a/packages/console/app/public/site.webmanifest b/packages/console/app/public/site.webmanifest new file mode 100644 index 0000000000000000000000000000000000000000..427c3adf423df124d854c5d95149e40875a39010 --- /dev/null +++ b/packages/console/app/public/site.webmanifest @@ -0,0 +1,24 @@ +{ + "name": "OpenCode", + "short_name": "OpenCode", + "id": "/", + "start_url": "/", + "scope": "/", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#080808", + "background_color": "#080808", + "display": "standalone" +} diff --git a/packages/console/app/public/social-share-black.png b/packages/console/app/public/social-share-black.png new file mode 100644 index 0000000000000000000000000000000000000000..ab402cc6603a54903e37fbac6c120b0f3f896e79 Binary files /dev/null and b/packages/console/app/public/social-share-black.png differ diff --git a/packages/console/app/public/social-share-zen.png b/packages/console/app/public/social-share-zen.png new file mode 100644 index 0000000000000000000000000000000000000000..33e94144153e3c0549b94f238e70d6bad0fdc7a3 Binary files /dev/null and b/packages/console/app/public/social-share-zen.png differ diff --git a/packages/console/app/public/social-share.png b/packages/console/app/public/social-share.png new file mode 100644 index 0000000000000000000000000000000000000000..e3d5267a92b115b9124cea457645321db23ecfc0 Binary files /dev/null and b/packages/console/app/public/social-share.png differ diff --git a/packages/console/app/public/theme.json b/packages/console/app/public/theme.json new file mode 100644 index 0000000000000000000000000000000000000000..b3e97f7ca89743e2f89071a49535fae45910033a --- /dev/null +++ b/packages/console/app/public/theme.json @@ -0,0 +1,182 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "description": "JSON schema reference for configuration validation" + }, + "defs": { + "type": "object", + "description": "Color definitions that can be referenced in the theme", + "patternProperties": { + "^[a-zA-Z][a-zA-Z0-9_]*$": { + "oneOf": [ + { + "type": "string", + "pattern": "^#[0-9a-fA-F]{6}$", + "description": "Hex color value" + }, + { + "type": "integer", + "minimum": 0, + "maximum": 255, + "description": "ANSI color code (0-255)" + }, + { + "type": "string", + "enum": ["none"], + "description": "No color (uses terminal default)" + } + ] + } + }, + "additionalProperties": false + }, + "theme": { + "type": "object", + "description": "Theme color definitions", + "properties": { + "primary": { "$ref": "#/definitions/colorValue" }, + "secondary": { "$ref": "#/definitions/colorValue" }, + "accent": { "$ref": "#/definitions/colorValue" }, + "error": { "$ref": "#/definitions/colorValue" }, + "warning": { "$ref": "#/definitions/colorValue" }, + "success": { "$ref": "#/definitions/colorValue" }, + "info": { "$ref": "#/definitions/colorValue" }, + "text": { "$ref": "#/definitions/colorValue" }, + "textMuted": { "$ref": "#/definitions/colorValue" }, + "background": { "$ref": "#/definitions/colorValue" }, + "backgroundPanel": { "$ref": "#/definitions/colorValue" }, + "backgroundElement": { "$ref": "#/definitions/colorValue" }, + "border": { "$ref": "#/definitions/colorValue" }, + "borderActive": { "$ref": "#/definitions/colorValue" }, + "borderSubtle": { "$ref": "#/definitions/colorValue" }, + "diffAdded": { "$ref": "#/definitions/colorValue" }, + "diffRemoved": { "$ref": "#/definitions/colorValue" }, + "diffContext": { "$ref": "#/definitions/colorValue" }, + "diffHunkHeader": { "$ref": "#/definitions/colorValue" }, + "diffHighlightAdded": { "$ref": "#/definitions/colorValue" }, + "diffHighlightRemoved": { "$ref": "#/definitions/colorValue" }, + "diffAddedBg": { "$ref": "#/definitions/colorValue" }, + "diffRemovedBg": { "$ref": "#/definitions/colorValue" }, + "diffContextBg": { "$ref": "#/definitions/colorValue" }, + "diffLineNumber": { "$ref": "#/definitions/colorValue" }, + "diffAddedLineNumberBg": { "$ref": "#/definitions/colorValue" }, + "diffRemovedLineNumberBg": { "$ref": "#/definitions/colorValue" }, + "markdownText": { "$ref": "#/definitions/colorValue" }, + "markdownHeading": { "$ref": "#/definitions/colorValue" }, + "markdownLink": { "$ref": "#/definitions/colorValue" }, + "markdownLinkText": { "$ref": "#/definitions/colorValue" }, + "markdownCode": { "$ref": "#/definitions/colorValue" }, + "markdownBlockQuote": { "$ref": "#/definitions/colorValue" }, + "markdownEmph": { "$ref": "#/definitions/colorValue" }, + "markdownStrong": { "$ref": "#/definitions/colorValue" }, + "markdownHorizontalRule": { "$ref": "#/definitions/colorValue" }, + "markdownListItem": { "$ref": "#/definitions/colorValue" }, + "markdownListEnumeration": { "$ref": "#/definitions/colorValue" }, + "markdownImage": { "$ref": "#/definitions/colorValue" }, + "markdownImageText": { "$ref": "#/definitions/colorValue" }, + "markdownCodeBlock": { "$ref": "#/definitions/colorValue" }, + "syntaxComment": { "$ref": "#/definitions/colorValue" }, + "syntaxKeyword": { "$ref": "#/definitions/colorValue" }, + "syntaxFunction": { "$ref": "#/definitions/colorValue" }, + "syntaxVariable": { "$ref": "#/definitions/colorValue" }, + "syntaxString": { "$ref": "#/definitions/colorValue" }, + "syntaxNumber": { "$ref": "#/definitions/colorValue" }, + "syntaxType": { "$ref": "#/definitions/colorValue" }, + "syntaxOperator": { "$ref": "#/definitions/colorValue" }, + "syntaxPunctuation": { "$ref": "#/definitions/colorValue" } + }, + "required": ["primary", "secondary", "accent", "text", "textMuted", "background"], + "additionalProperties": false + } + }, + "required": ["theme"], + "additionalProperties": false, + "definitions": { + "colorValue": { + "oneOf": [ + { + "type": "string", + "pattern": "^#[0-9a-fA-F]{6}$", + "description": "Hex color value (same for dark and light)" + }, + { + "type": "integer", + "minimum": 0, + "maximum": 255, + "description": "ANSI color code (0-255, same for dark and light)" + }, + { + "type": "string", + "enum": ["none"], + "description": "No color (uses terminal default)" + }, + { + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$", + "description": "Reference to another color in the theme or defs" + }, + { + "type": "object", + "properties": { + "dark": { + "oneOf": [ + { + "type": "string", + "pattern": "^#[0-9a-fA-F]{6}$", + "description": "Hex color value for dark mode" + }, + { + "type": "integer", + "minimum": 0, + "maximum": 255, + "description": "ANSI color code for dark mode" + }, + { + "type": "string", + "enum": ["none"], + "description": "No color (uses terminal default)" + }, + { + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$", + "description": "Reference to another color for dark mode" + } + ] + }, + "light": { + "oneOf": [ + { + "type": "string", + "pattern": "^#[0-9a-fA-F]{6}$", + "description": "Hex color value for light mode" + }, + { + "type": "integer", + "minimum": 0, + "maximum": 255, + "description": "ANSI color code for light mode" + }, + { + "type": "string", + "enum": ["none"], + "description": "No color (uses terminal default)" + }, + { + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$", + "description": "Reference to another color for light mode" + } + ] + } + }, + "required": ["dark", "light"], + "additionalProperties": false, + "description": "Separate colors for dark and light modes" + } + ] + } + } +} diff --git a/packages/console/app/public/web-app-manifest-192x192.png b/packages/console/app/public/web-app-manifest-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..e637755490fb8b6f36252d6f740214c9203af27b Binary files /dev/null and b/packages/console/app/public/web-app-manifest-192x192.png differ diff --git a/packages/console/app/public/web-app-manifest-512x512.png b/packages/console/app/public/web-app-manifest-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..f6f0cf514e89b5a9fc7294eb2ab41388bf614b4e Binary files /dev/null and b/packages/console/app/public/web-app-manifest-512x512.png differ diff --git a/packages/console/app/script/generate-sitemap.ts b/packages/console/app/script/generate-sitemap.ts new file mode 100644 index 0000000000000000000000000000000000000000..1cf64d6e89d3e63b26ea94c04f33534d08f0c59b --- /dev/null +++ b/packages/console/app/script/generate-sitemap.ts @@ -0,0 +1,108 @@ +#!/usr/bin/env bun +import { readdir, writeFile } from "fs/promises" +import { join, dirname } from "path" +import { fileURLToPath } from "url" +import { config } from "../src/config.js" +import { LOCALES, route } from "../src/lib/language.js" + +const __dirname = dirname(fileURLToPath(import.meta.url)) +const BASE_URL = config.baseUrl +const PUBLIC_DIR = join(__dirname, "../public") +const DOCS_DIR = join(__dirname, "../../../web/src/content/docs") + +interface SitemapEntry { + url: string + priority: number + changefreq: string +} + +async function getMainRoutes(): Promise { + const routes: SitemapEntry[] = [] + + // Add main static routes + const staticRoutes = [ + { path: "/", priority: 1.0, changefreq: "daily" }, + { path: "/enterprise", priority: 0.8, changefreq: "weekly" }, + { path: "/brand", priority: 0.6, changefreq: "monthly" }, + { path: "/zen", priority: 0.8, changefreq: "weekly" }, + { path: "/go", priority: 0.8, changefreq: "weekly" }, + ] + + for (const item of staticRoutes) { + for (const locale of LOCALES) { + routes.push({ + url: `${BASE_URL}${route(locale, item.path)}`, + priority: item.priority, + changefreq: item.changefreq, + }) + } + } + + return routes +} + +async function getDocsRoutes(): Promise { + const routes: SitemapEntry[] = [] + + try { + const files = await readdir(DOCS_DIR) + + for (const file of files) { + if (!file.endsWith(".mdx")) continue + + const slug = file.replace(".mdx", "") + const path = slug === "index" ? "/docs/" : `/docs/${slug}` + + for (const locale of LOCALES) { + routes.push({ + url: `${BASE_URL}${route(locale, path)}`, + priority: slug === "index" ? 0.9 : 0.7, + changefreq: "weekly", + }) + } + } + } catch (error) { + console.error("Error reading docs directory:", error) + } + + return routes +} + +function generateSitemapXML(entries: SitemapEntry[]): string { + const urls = entries + .map( + (entry) => ` + ${entry.url} + ${entry.changefreq} + ${entry.priority} + `, + ) + .join("\n") + + return ` + +${urls} +` +} + +async function main() { + console.log("Generating sitemap...") + + const mainRoutes = await getMainRoutes() + const docsRoutes = await getDocsRoutes() + + const allRoutes = [...mainRoutes, ...docsRoutes] + + console.log(`Found ${mainRoutes.length} main routes`) + console.log(`Found ${docsRoutes.length} docs routes`) + console.log(`Total: ${allRoutes.length} routes`) + + const xml = generateSitemapXML(allRoutes) + + const outputPath = join(PUBLIC_DIR, "sitemap.xml") + await writeFile(outputPath, xml, "utf-8") + + console.log(`✓ Sitemap generated at ${outputPath}`) +} + +void main() diff --git a/packages/console/app/src/app.css b/packages/console/app/src/app.css new file mode 100644 index 0000000000000000000000000000000000000000..c0261c4221fa3a30786d00e21c50ab5c36db63e0 --- /dev/null +++ b/packages/console/app/src/app.css @@ -0,0 +1 @@ +@import "./style/index.css"; diff --git a/packages/console/app/src/app.tsx b/packages/console/app/src/app.tsx new file mode 100644 index 0000000000000000000000000000000000000000..1f1d0066ecc81880dcbbf369699b6137a858770e --- /dev/null +++ b/packages/console/app/src/app.tsx @@ -0,0 +1,44 @@ +import { MetaProvider, Title, Meta } from "@solidjs/meta" +import { Router } from "@solidjs/router" +import { FileRoutes } from "@solidjs/start/router" +import { Suspense } from "solid-js" +import { Favicon } from "@opencode-ai/ui/favicon" +import { Font } from "@opencode-ai/ui/font" +import "@ibm/plex/css/ibm-plex.css" +import "./app.css" +import { LanguageProvider } from "~/context/language" +import { I18nProvider, useI18n } from "~/context/i18n" +import { strip } from "~/lib/language" + +function AppMeta() { + const i18n = useI18n() + return ( + <> + opencode + + + + + ) +} + +export default function App() { + return ( + ( + + + + + {props.children} + + + + )} + > + + + ) +} diff --git a/packages/console/app/src/asset/go-ornate-dark.svg b/packages/console/app/src/asset/go-ornate-dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..9b617c6777f04f0fb3ba0db370bb882459481901 --- /dev/null +++ b/packages/console/app/src/asset/go-ornate-dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/console/app/src/asset/go-ornate-light.svg b/packages/console/app/src/asset/go-ornate-light.svg new file mode 100644 index 0000000000000000000000000000000000000000..79991973d6d97d6c6f4cf372d3384eb969cbe543 --- /dev/null +++ b/packages/console/app/src/asset/go-ornate-light.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/console/app/src/asset/logo-ornate-dark.svg b/packages/console/app/src/asset/logo-ornate-dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..a1582732423a3f4b8e733d1e9fa0f373fd561f56 --- /dev/null +++ b/packages/console/app/src/asset/logo-ornate-dark.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/packages/console/app/src/asset/logo-ornate-light.svg b/packages/console/app/src/asset/logo-ornate-light.svg new file mode 100644 index 0000000000000000000000000000000000000000..2a856dccefe81a7f95a97b0da28ee6e3386b9814 --- /dev/null +++ b/packages/console/app/src/asset/logo-ornate-light.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/packages/console/app/src/asset/logo.svg b/packages/console/app/src/asset/logo.svg new file mode 100644 index 0000000000000000000000000000000000000000..2a856dccefe81a7f95a97b0da28ee6e3386b9814 --- /dev/null +++ b/packages/console/app/src/asset/logo.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/packages/console/app/src/asset/zen-ornate-dark.svg b/packages/console/app/src/asset/zen-ornate-dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..cdc4485fc59dc2943542dc5d4f293549015b0ac2 --- /dev/null +++ b/packages/console/app/src/asset/zen-ornate-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/console/app/src/asset/zen-ornate-light.svg b/packages/console/app/src/asset/zen-ornate-light.svg new file mode 100644 index 0000000000000000000000000000000000000000..2a9ed13421e307345dc1b24a76a3eacab77e99d3 --- /dev/null +++ b/packages/console/app/src/asset/zen-ornate-light.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/console/app/src/component/desktop-promo.css b/packages/console/app/src/component/desktop-promo.css new file mode 100644 index 0000000000000000000000000000000000000000..5e9a4863c0135eab3efc3134effd24328d403bd2 --- /dev/null +++ b/packages/console/app/src/component/desktop-promo.css @@ -0,0 +1,103 @@ +[data-component="desktop-promo"] { + --promo-background: hsl(0, 20%, 99%); + --promo-background-weak: hsl(0, 8%, 97%); + --promo-text: hsl(0, 1%, 39%); + --promo-text-strong: hsl(0, 5%, 12%); + --promo-border: hsla(0, 100%, 3%, 0.12); + + position: fixed; + z-index: 20; + right: 1.5rem; + bottom: 1.5rem; + width: min(28rem, calc(100vw - 2rem)); + padding: 4px; + overflow: hidden; + color: var(--promo-text); + border: 1px solid var(--promo-border); + border-radius: 8px; + background: var(--promo-background); + box-shadow: 0 0.75rem 2rem rgb(0 0 0 / 15%); + font-family: var(--font-mono); + + @media (prefers-color-scheme: dark) { + --promo-background: hsl(0, 9%, 7%); + --promo-background-weak: hsl(0, 6%, 10%); + --promo-text: hsl(0, 4%, 71%); + --promo-text-strong: hsl(0, 15%, 94%); + --promo-border: hsl(0, 4%, 23%); + } + + @media (max-width: 40rem) { + right: 1rem; + bottom: 1rem; + } + + [data-slot="desktop-promo-link"] { + display: block; + color: var(--promo-text); + text-decoration: none; + } + + [data-slot="desktop-promo-link"]:focus-visible { + outline: 2px solid var(--promo-text-strong); + outline-offset: -3px; + } + + video { + display: block; + width: 100%; + aspect-ratio: 16 / 9; + object-fit: cover; + border-radius: 4px; + background: var(--promo-background-weak); + } + + [data-slot="desktop-promo-copy"] { + display: flex; + flex-direction: column; + gap: 0.35rem; + padding: 1rem; + font-size: 0.875rem; + line-height: 1.4; + } + + [data-slot="desktop-promo-copy"] strong { + color: var(--promo-text-strong); + font-weight: 500; + } + + [data-slot="desktop-promo-close"] { + position: absolute; + top: 0.5rem; + right: 0.5rem; + display: grid; + width: 2rem; + height: 2rem; + padding: 0; + place-items: center; + cursor: pointer; + color: white; + border: none; + border-radius: 0.25rem; + background: rgb(0 0 0 / 70%); + opacity: 0; + transition: + opacity 150ms ease, + background 150ms ease; + } + + &:hover [data-slot="desktop-promo-close"], + [data-slot="desktop-promo-close"]:focus-visible { + opacity: 1; + } + + [data-slot="desktop-promo-close"]:hover { + background: rgb(0 0 0 / 90%); + } + + @media (hover: none) { + [data-slot="desktop-promo-close"] { + opacity: 1; + } + } +} diff --git a/packages/console/app/src/component/desktop-promo.tsx b/packages/console/app/src/component/desktop-promo.tsx new file mode 100644 index 0000000000000000000000000000000000000000..504088e3c7c4b047676d1f2fda38f9097cebac5e --- /dev/null +++ b/packages/console/app/src/component/desktop-promo.tsx @@ -0,0 +1,60 @@ +import "./desktop-promo.css" +import { A, useLocation } from "@solidjs/router" +import { createSignal, Show } from "solid-js" +import { getRequestEvent } from "solid-js/web" +import desktopPromoVideo from "~/asset/lander/desktop-tabs-landscape.mp4" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import { strip } from "~/lib/language" + +const DISMISSED_COOKIE = "desktop_promo_dismissed" + +export function DesktopPromo() { + const i18n = useI18n() + const language = useLanguage() + const location = useLocation() + const request = getRequestEvent()?.request + const cookie = request?.headers.get("cookie") ?? (typeof document === "object" ? document.cookie : "") + const [visible, setVisible] = createSignal( + !cookie.split(";").some((value) => value.trim() === `${DISMISSED_COOKIE}=1`), + ) + const hostname = request ? new URL(request.url).hostname : typeof window === "object" ? window.location.hostname : "" + const primaryHost = + hostname === "opencode.ai" || hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" + + return ( + + + + ) +} diff --git a/packages/console/app/src/component/dropdown.css b/packages/console/app/src/component/dropdown.css new file mode 100644 index 0000000000000000000000000000000000000000..242940e6aa4bc7412623c7320cc105aa7c2674f8 --- /dev/null +++ b/packages/console/app/src/component/dropdown.css @@ -0,0 +1,80 @@ +[data-component="dropdown"] { + position: relative; + + [data-slot="trigger"] { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--space-2); + padding: var(--space-2) var(--space-3); + border: none; + border-radius: var(--border-radius-sm); + background-color: transparent; + color: var(--color-text); + font-size: var(--font-size-sm); + font-family: var(--font-sans); + cursor: pointer; + transition: all 0.15s ease; + + &:hover { + background-color: var(--color-surface-hover); + } + + span { + flex: 1; + text-align: left; + font-weight: 500; + } + } + + [data-slot="chevron"] { + flex-shrink: 0; + color: var(--color-text-secondary); + } + + [data-slot="dropdown"] { + position: absolute; + top: 100%; + z-index: 1000; + margin-top: var(--space-1); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + background-color: var(--color-bg); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + min-width: 160px; + + &[data-align="left"] { + left: 0; + } + + &[data-align="right"] { + right: 0; + } + + @media (prefers-color-scheme: dark) { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + } + } + + [data-slot="item"] { + display: block; + width: 100%; + padding: var(--space-2-5) var(--space-3); + border: none; + background: none; + color: var(--color-text); + font-size: var(--font-size-sm); + font-family: var(--font-sans); + text-align: left; + cursor: pointer; + transition: background-color 0.15s ease; + + &:hover { + background-color: var(--color-bg-surface); + } + + &[data-selected="true"] { + background-color: var(--color-accent-alpha); + } + } +} diff --git a/packages/console/app/src/component/dropdown.tsx b/packages/console/app/src/component/dropdown.tsx new file mode 100644 index 0000000000000000000000000000000000000000..de99d448151c61a23dbe58e7ef38e85c89cecc59 --- /dev/null +++ b/packages/console/app/src/component/dropdown.tsx @@ -0,0 +1,79 @@ +import { JSX, Show, createEffect, onCleanup } from "solid-js" +import { createStore } from "solid-js/store" +import { IconChevron } from "./icon" +import "./dropdown.css" + +interface DropdownProps { + trigger: JSX.Element | string + children: JSX.Element + open?: boolean + onOpenChange?: (open: boolean) => void + align?: "left" | "right" + class?: string +} + +export function Dropdown(props: DropdownProps) { + const [store, setStore] = createStore({ + isOpen: props.open ?? false, + }) + let dropdownRef: HTMLDivElement | undefined + + createEffect(() => { + if (props.open !== undefined) { + setStore("isOpen", props.open) + } + }) + + createEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (dropdownRef && !dropdownRef.contains(event.target as Node)) { + setStore("isOpen", false) + props.onOpenChange?.(false) + } + } + + document.addEventListener("click", handleClickOutside) + onCleanup(() => document.removeEventListener("click", handleClickOutside)) + }) + + const toggle = () => { + const newValue = !store.isOpen + setStore("isOpen", newValue) + props.onOpenChange?.(newValue) + } + + return ( +
+ + + +
+ {props.children} +
+
+
+ ) +} + +interface DropdownItemProps { + children: JSX.Element + selected?: boolean + onClick?: () => void + type?: "button" | "submit" | "reset" +} + +export function DropdownItem(props: DropdownItemProps) { + return ( + + ) +} diff --git a/packages/console/app/src/component/email-signup.tsx b/packages/console/app/src/component/email-signup.tsx new file mode 100644 index 0000000000000000000000000000000000000000..caedaf0f2e4c7ea9679ae5abfd38d48d367eb070 --- /dev/null +++ b/packages/console/app/src/component/email-signup.tsx @@ -0,0 +1,47 @@ +import { action, useSubmission } from "@solidjs/router" +import { Resource } from "@opencode-ai/console-resource" +import { Show } from "solid-js" +import { useI18n } from "~/context/i18n" + +const emailSignup = action(async (formData: FormData) => { + "use server" + const emailAddress = formData.get("email")! + const listId = "8b9bb82c-9d5f-11f0-975f-0df6fd1e4945" + const response = await fetch(`https://api.emailoctopus.com/lists/${listId}/contacts`, { + method: "PUT", + headers: { + Authorization: `Bearer ${Resource.EMAILOCTOPUS_API_KEY.value}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email_address: emailAddress, + }), + }) + console.log(response) + return true +}) + +export function EmailSignup() { + const submission = useSubmission(emailSignup) + const i18n = useI18n() + return ( +
+
+

{i18n.t("email.title")}

+

{i18n.t("email.subtitle")}

+
+
+ + +
+ +
{i18n.t("email.success")}
+
+ +
{submission.error}
+
+
+ ) +} diff --git a/packages/console/app/src/component/faq.tsx b/packages/console/app/src/component/faq.tsx new file mode 100644 index 0000000000000000000000000000000000000000..753a0dce4de735d9fe9abd9bb6954e26b3efd84f --- /dev/null +++ b/packages/console/app/src/component/faq.tsx @@ -0,0 +1,33 @@ +import { Collapsible } from "@kobalte/core/collapsible" +import { ParentProps } from "solid-js" + +export function Faq(props: ParentProps & { question: string }) { + return ( + + + + + + + + +
{props.question}
+
+ {props.children} +
+ ) +} diff --git a/packages/console/app/src/component/footer.tsx b/packages/console/app/src/component/footer.tsx new file mode 100644 index 0000000000000000000000000000000000000000..0ea370ac7895103dab4a1d15118ac8330a996b66 --- /dev/null +++ b/packages/console/app/src/component/footer.tsx @@ -0,0 +1,48 @@ +import { createAsync } from "@solidjs/router" +import { createMemo } from "solid-js" +import { github } from "~/lib/github" +import { config } from "~/config" +import { useLanguage } from "~/context/language" +import { useI18n } from "~/context/i18n" + +export function Footer() { + const language = useLanguage() + const i18n = useI18n() + const community = createMemo(() => { + const locale = language.locale() + return locale === "zh" || locale === "zht" + ? ({ key: "footer.feishu", link: language.route("/feishu") } as const) + : ({ key: "footer.discord", link: language.route("/discord") } as const) + }) + const githubData = createAsync(() => github()) + const starCount = createMemo(() => + githubData()?.stars + ? new Intl.NumberFormat(language.tag(language.locale()), { + notation: "compact", + compactDisplay: "short", + }).format(githubData()!.stars!) + : config.github.starsFormatted.compact, + ) + + return ( + + ) +} diff --git a/packages/console/app/src/component/go-models.ts b/packages/console/app/src/component/go-models.ts new file mode 100644 index 0000000000000000000000000000000000000000..6df79f4a39211ce895191f256483bcc6c8d5b27d --- /dev/null +++ b/packages/console/app/src/component/go-models.ts @@ -0,0 +1,53 @@ +// Requests are per 5 hours; allowances are monthly usage at official API prices. +export const goModels = [ + { id: "kimi-k3", name: "Kimi K3", requests: 110, allowance: 15, featured: true }, + { id: "qwen3.8-max", name: "Qwen3.8 Max", requests: 160, allowance: 15 }, + { id: "grok-4.6", name: "Grok 4.6", requests: 169, allowance: 15 }, + { id: "qwen3.7-max", name: "Qwen3.7 Max", requests: 170, allowance: 30 }, + { id: "glm-5.3", name: "GLM-5.3", requests: 220, allowance: 15 }, + { id: "glm-5.2", name: "GLM-5.2", requests: 880, allowance: 60 }, + { id: "glm-5.1", name: "GLM-5.1", requests: 880, allowance: 60 }, + { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", requests: 1050, allowance: 15 }, + { id: "kimi-k2.6", name: "Kimi K2.6", requests: 1150, allowance: 60 }, + { id: "kimi-k2.7-code", name: "Kimi K2.7 Code", requests: 1350, allowance: 60, featured: true }, + { id: "hy4-preview", name: "Hy4 preview", requests: 1350, allowance: 30 }, + { id: "gpt-5.6-luna", name: "GPT 5.6 Luna", requests: 2050, allowance: 15, featured: true }, + { id: "minimax-m3", name: "MiniMax M3", requests: 3200, allowance: 60, featured: true }, + { id: "mimo-v2.5-pro", name: "MiMo-V2.5-Pro", requests: 3250, allowance: 15 }, + { id: "qwen3.6-plus", name: "Qwen3.6 Plus", requests: 3300, allowance: 60 }, + { id: "minimax-m2.7", name: "MiniMax M2.7", requests: 3400, allowance: 60 }, + { id: "deepseek-v4-flash-vision-exp", name: "DeepSeek V4 Flash Vision Exp", requests: 6500, allowance: 15 }, + { id: "qwen3.7-plus", name: "Qwen3.7 Plus", requests: 4300, allowance: 60, featured: true }, + { id: "hy3", name: "Hy3", requests: 4300, allowance: 60 }, + { id: "qwen3.8-flash", name: "Qwen3.8 Flash", requests: 5400, allowance: 30 }, + { id: "glm-5.3-flash", name: "GLM-5.3-Flash", requests: 6320, allowance: 60, featured: true }, + { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", requests: 13000, allowance: 30, featured: true }, + { + id: "deepseek-flash", + name: "DeepSeek V4.1 Flash", + requests: 26000, + baseRequests: 6500, + allowance: 60, + baseAllowance: 15, + bonus: 4, + featured: true, + fresh: true, + }, + { id: "longcat-2.0", name: "LongCat-2.0", requests: 11400, allowance: 60 }, + { id: "mimo-v2.5", name: "MiMo-V2.5", requests: 30100, allowance: 60, featured: true }, + { + id: "muse-spark-1.3-contributor", + name: "Muse Spark 1.3 Contributor", + requests: 45300, + allowance: 60, + featured: true, + regions: true, + }, + { + id: "muse-spark-1.2-contributor", + name: "Muse Spark 1.2 Contributor", + requests: 45300, + allowance: 60, + regions: true, + }, +].sort((a, b) => a.requests - b.requests) diff --git a/packages/console/app/src/component/go-referral.css b/packages/console/app/src/component/go-referral.css new file mode 100644 index 0000000000000000000000000000000000000000..29595649c8fe8f489ae14cd44dba10a17cc4531b --- /dev/null +++ b/packages/console/app/src/component/go-referral.css @@ -0,0 +1,289 @@ +[data-component="go-credit-confirm"] { + display: flex; + flex-direction: column; + gap: var(--space-4); + min-width: min(34rem, calc(100vw - var(--space-8))); + + p { + margin: 0; + color: var(--color-text-secondary); + font-size: var(--font-size-sm); + line-height: 1.6; + } + + [data-slot="usage-preview"] { + display: flex; + flex-direction: column; + gap: var(--space-5); + padding: var(--space-4); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + background-color: var(--color-bg-surface); + } + + [data-slot="usage-preview-item"] { + display: flex; + flex-direction: column; + gap: var(--space-2); + } + + [data-slot="usage-preview-header"] { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: var(--space-3); + } + + [data-slot="usage-preview-label"] { + color: var(--color-text); + font-size: var(--font-size-sm); + font-weight: 500; + } + + [data-slot="usage-preview-value"] { + display: inline-flex; + align-items: center; + gap: var(--space-1); + color: var(--color-text-muted); + font-family: var(--font-mono); + font-size: var(--font-size-xs); + white-space: nowrap; + } + + [data-slot="usage-preview-after-value"] { + color: var(--color-accent); + font-weight: 600; + } + + [data-slot="usage-preview-progress"] { + position: relative; + height: 8px; + overflow: hidden; + border-radius: var(--border-radius-sm); + background-color: var(--color-bg); + } + + [data-slot="usage-preview-before"], + [data-slot="usage-preview-after"] { + position: absolute; + top: 0; + bottom: 0; + left: 0; + border-radius: var(--border-radius-sm); + } + + [data-slot="usage-preview-before"] { + background-color: var(--color-border); + } + + [data-slot="usage-preview-after"] { + background-color: var(--color-accent); + transition: width 0.35s ease; + } + + [data-slot="usage-preview-reset"] { + color: var(--color-text-muted); + font-size: var(--font-size-xs); + } + + [data-slot="modal-actions"] { + display: flex; + justify-content: flex-end; + gap: var(--space-3); + } +} + +[data-slot="invite-link-box"] { + display: flex; + flex-direction: column; + gap: var(--space-3); + + > div { + display: flex; + align-items: center; + gap: var(--space-3); + border-radius: var(--border-radius-sm); + + @media (max-width: 40rem) { + align-items: stretch; + flex-direction: column; + } + } + + code { + flex: 1; + min-width: 0; + padding: var(--space-3); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + background-color: var(--color-bg); + color: var(--color-text); + font-family: var(--font-mono); + font-size: var(--font-size-sm); + line-height: 1.4; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + @media (max-width: 40rem) { + padding: var(--space-2-5); + font-size: var(--font-size-xs); + } + } + + button { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--space-2); + min-width: 130px; + white-space: nowrap; + + @media (max-width: 40rem) { + min-width: 96px; + padding: var(--space-2-5) var(--space-3); + font-size: var(--font-size-xs); + } + } +} + +[data-slot="instructions"] { + display: flex; + flex-direction: column; + gap: var(--space-3); + + ol { + display: flex; + flex-direction: column; + gap: var(--space-2); + margin: 0; + padding-left: 0; + color: var(--color-text-secondary); + font-size: var(--font-size-md); + list-style-position: inside; + line-height: 1.5; + } +} + +[data-component="go-referral-section"] { + [data-component="go-referral-overview"] { + display: flex; + flex-direction: column; + gap: var(--space-8); + padding: var(--space-6); + border: 1px dashed var(--color-border); + border-radius: var(--border-radius-sm); + background-color: var(--color-bg-surface); + + @media (max-width: 30rem) { + gap: var(--space-8); + padding: var(--space-4); + } + } + + [data-component="go-referral-overview"] + [data-slot="section-title"] { + margin-top: var(--space-4); + } + + [data-slot="referrals-table"] { + overflow-x: auto; + } + + [data-component="empty-state"] { + padding: var(--space-4); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + background-color: var(--color-bg-surface); + color: var(--color-text-muted); + font-size: var(--font-size-sm); + } + + [data-slot="referrals-table-element"] { + width: 100%; + border-collapse: collapse; + font-size: var(--font-size-sm); + + thead { + border-bottom: 1px solid var(--color-border); + } + + th { + padding: var(--space-3) var(--space-4); + text-align: left; + font-weight: normal; + color: var(--color-text-muted); + text-transform: uppercase; + + &:nth-child(1) { + width: 120px; + } + + &:nth-child(3) { + width: 180px; + } + + &:nth-child(4) { + width: 140px; + } + } + + td { + padding: var(--space-3) var(--space-4); + border-bottom: 1px solid var(--color-border-muted); + color: var(--color-text-muted); + font-family: var(--font-mono); + + &[data-slot="referral-amount"] { + color: var(--color-text); + font-weight: 500; + } + + &[data-slot="referral-source"] { + color: var(--color-text-secondary); + font-family: var(--font-sans); + white-space: nowrap; + } + + &[data-slot="referral-action"] { + text-align: right; + font-family: var(--font-sans); + white-space: nowrap; + + button { + min-width: 96px; + } + } + } + + tbody tr { + &[data-status="applied"] { + td:not([data-slot="referral-action"]) { + opacity: 0.68; + } + } + + &[data-status="pending"] { + td[data-slot="referral-amount"], + td[data-slot="referral-date"] { + color: var(--color-text-muted); + } + + td[data-slot="referral-source"] { + color: var(--color-text); + } + } + + &:last-child td { + border-bottom: none; + } + } + + @media (max-width: 40rem) { + th, + td { + padding: var(--space-2) var(--space-3); + font-size: var(--font-size-xs); + } + } + } +} diff --git a/packages/console/app/src/component/go-referral.tsx b/packages/console/app/src/component/go-referral.tsx new file mode 100644 index 0000000000000000000000000000000000000000..4223dfd47c07c49daab7b41d4b902f42acef0e4a --- /dev/null +++ b/packages/console/app/src/component/go-referral.tsx @@ -0,0 +1,306 @@ +import { action, json, query, useAction, useSubmission } from "@solidjs/router" +import { createEffect, createMemo, createSignal, For, onCleanup, Show } from "solid-js" +import { getRequestEvent } from "solid-js/web" +import { Referral } from "@opencode-ai/console-core/referral.js" +import { withActor } from "~/context/auth.withActor" +import { Modal } from "~/component/modal" +import { IconCheck, IconCopy } from "~/component/icon" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import { formatResetTime, liteResetTimeKeys } from "~/lib/format-reset-time" +import { queryLiteSubscription } from "~/routes/workspace/[id]/go/lite-section" +import { createReferralFromCookie } from "~/lib/referral-invite" +import "./go-referral.css" + +type GoReferralSummary = Awaited> +type GoReferralReward = GoReferralSummary["rewards"][number] +type GoLiteSubscription = Awaited> +type GoReferralUsagePreview = NonNullable>> +type GoReferralUsagePreviewItem = GoReferralUsagePreview["rollingUsage"] + +const emptyUsagePreview = { + rollingUsage: { beforePercent: 0, afterPercent: 0, resetInSec: 0 }, + weeklyUsage: { beforePercent: 0, afterPercent: 0, resetInSec: 0 }, + monthlyUsage: { beforePercent: 0, afterPercent: 0, resetInSec: 0 }, +} satisfies GoReferralUsagePreview + +export const queryGoReferral = query(async (workspaceID: string) => { + "use server" + return withActor(async () => { + await createReferralFromCookie() + return Referral.summary() + }, workspaceID) +}, "go.referral.get") + +export const queryGoReferralUsagePreview = query(async (workspaceID: string, referralID?: string) => { + "use server" + if (!referralID) return null + return withActor(() => Referral.usagePreview({ referralID }), workspaceID) +}, "go.referral.usagePreview") + +export const applyGoReferralReward = action(async (workspaceID: string, referralID: string) => { + "use server" + return json(await withActor(() => Referral.applyReward({ referralID }), workspaceID), { + revalidate: [queryGoReferral.key, queryGoReferralUsagePreview.key, queryLiteSubscription.key], + }) +}, "go.referral.reward.apply") + +function currentUsagePreview(usage: { resetInSec: number; usagePercent: number }) { + return { + beforePercent: usage.usagePercent, + afterPercent: usage.usagePercent, + resetInSec: usage.resetInSec, + } +} + +function formatCurrency(amount: number) { + if (amount % 100 === 0) return `$${amount / 100}` + return `$${(amount / 100).toFixed(2)}` +} + +function formatDate(value: string | Date, locale: string) { + return new Intl.DateTimeFormat(locale, { month: "short", day: "numeric", year: "numeric" }).format(new Date(value)) +} + +function rewardDescriptionKey(source: GoReferralReward["source"]) { + if (source === "invitee") return "workspace.referral.reward.description.invitee" as const + return "workspace.referral.reward.description.inviter" as const +} + +function rewardActionKey(reward: GoReferralReward, hasActiveGo: boolean) { + if (reward.status === "applied") return "workspace.referral.reward.action.applied" as const + if (reward.status === "pending" && reward.source === "inviter") + return "workspace.referral.reward.source.pendingInviter" as const + if (reward.status === "pending" || !hasActiveGo) return "workspace.referral.reward.action.subscribeUnlock" as const + return "workspace.referral.reward.action.view" as const +} + +function CopyInviteLink(props: { summary: GoReferralSummary }) { + const i18n = useI18n() + const [copied, setCopied] = createSignal(false) + const event = getRequestEvent() + const origin = event + ? new URL(event.request.url).origin + : typeof window === "object" + ? window.location.origin + : undefined + const inviteUrl = createMemo(() => { + const path = `/go?ref=${props.summary.referralCode}` + if (!origin) return path + return new URL(path, origin).toString() + }) + + async function copy() { + if (typeof navigator !== "object") return + await navigator.clipboard.writeText(inviteUrl()) + setCopied(true) + window.setTimeout(() => setCopied(false), 1600) + } + + return ( +
+
+ {inviteUrl()} + +
+
+ ) +} + +export function GoReferralSection(props: { + workspaceID: string + summary: GoReferralSummary + lite: GoLiteSubscription | undefined +}) { + const i18n = useI18n() + const language = useLanguage() + const apply = useAction(applyGoReferralReward) + const submission = useSubmission(applyGoReferralReward) + const [selected, setSelected] = createSignal() + const [preview, setPreview] = createSignal() + const displayPreview = createMemo(() => { + const loaded = preview() + if (loaded) return loaded + const current = props.lite + if (!current) return emptyUsagePreview + return { + rollingUsage: currentUsagePreview(current.rollingUsage), + weeklyUsage: currentUsagePreview(current.weeklyUsage), + monthlyUsage: currentUsagePreview(current.monthlyUsage), + } satisfies GoReferralUsagePreview + }) + createEffect(() => { + const reward = selected() + if (!reward) { + setPreview(undefined) + return + } + + const request = { cancelled: false } + setPreview(undefined) + queryGoReferralUsagePreview(props.workspaceID, reward.id).then((result) => { + if (request.cancelled) return + setPreview(result) + }) + onCleanup(() => { + request.cancelled = true + }) + }) + + async function onApply() { + const reward = selected() + if (!reward) return + await apply(props.workspaceID, reward.id) + setSelected(undefined) + } + + return ( + <> + +
+ +
+

{i18n.t("workspace.referral.overview.title")}

+

{i18n.t("workspace.referral.overview.subtitle")}

+
+
+ +
+
    +
  1. {i18n.t("workspace.referral.instructions.share")}
  2. +
  3. {i18n.t("workspace.referral.instructions.subscribe")}
  4. +
  5. {i18n.t("workspace.referral.instructions.claim")}
  6. +
+
+
+
+ +
+

{i18n.t("workspace.referral.rewards.title")}

+

{i18n.t("workspace.referral.rewards.description")}

+
+
+ + + + + + + + + + + + {(reward) => { + const earnedAt = () => formatDate(reward.timeCreated, language.tag(language.locale())) + return ( + + + + + + + ) + }} + + +
{i18n.t("workspace.referral.table.reward")}{i18n.t("workspace.referral.table.referral")}{i18n.t("workspace.referral.table.date")}
{formatCurrency(reward.amount)} + {i18n.t(rewardDescriptionKey(reward.source), { email: reward.email ?? "" })} + + {earnedAt()} + + +
+
+
+
+
+ + setSelected(undefined)} + title={i18n.t("workspace.referral.apply.confirmTitle")} + > +
+

+ {i18n.t("workspace.referral.apply.confirmBody", { + amount: formatCurrency(selected()?.amount ?? 0), + })} +

+ +
+ + +
+
+
+ + ) +} + +function GoReferralUsagePreview(props: { preview: GoReferralUsagePreview }) { + const i18n = useI18n() + + return ( +
+ + + +
+ ) +} + +function GoReferralUsagePreviewRow(props: { label: string; usage: GoReferralUsagePreviewItem }) { + const i18n = useI18n() + + return ( +
+
+ {props.label} + + {props.usage.beforePercent}% + + {props.usage.afterPercent}% + +
+
+
+
+
+ + {i18n.t("workspace.lite.subscription.resetsIn")}{" "} + {formatResetTime(props.usage.resetInSec, i18n, liteResetTimeKeys)} + +
+ ) +} diff --git a/packages/console/app/src/component/header-context-menu.css b/packages/console/app/src/component/header-context-menu.css new file mode 100644 index 0000000000000000000000000000000000000000..34177457d118c4d8c284f7c447d81d648a41b417 --- /dev/null +++ b/packages/console/app/src/component/header-context-menu.css @@ -0,0 +1,63 @@ +.context-menu { + position: fixed; + z-index: 1000; + min-width: 160px; + border-radius: 8px; + background-color: var(--color-background); + box-shadow: + 0 0 0 1px rgba(19, 16, 16, 0.08), + 0 6px 8px -4px rgba(19, 16, 16, 0.12), + 0 4px 3px -2px rgba(19, 16, 16, 0.12), + 0 1px 2px -1px rgba(19, 16, 16, 0.12); + padding: 6px; + + @media (prefers-color-scheme: dark) { + box-shadow: 0 0 0 1px rgba(247, 237, 237, 0.1); + } +} + +.context-menu-item { + display: flex; + gap: 12px; + width: 100%; + padding: 8px 16px 8px 8px; + font-weight: 500; + cursor: pointer; + background: none; + border: none; + align-items: center; + color: var(--color-text); + font-size: var(--font-size-sm); + text-align: left; + border-radius: 2px; + transition: background-color 0.2s ease; + + [data-slot="copy dark"] { + display: none; + } + + @media (prefers-color-scheme: dark) { + [data-slot="copy light"] { + display: none; + } + [data-slot="copy dark"] { + display: block; + } + } + + &:hover { + background-color: var(--color-background-weak-hover); + color: var(--color-text-strong); + } + + img { + width: 22px; + height: 26px; + } +} + +.context-menu-divider { + border: none; + border-top: 1px solid var(--color-border); + margin: var(--space-1) 0; +} diff --git a/packages/console/app/src/component/header.tsx b/packages/console/app/src/component/header.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a0e5ffc0cabe502f5083932562e26ed12c7f4372 --- /dev/null +++ b/packages/console/app/src/component/header.tsx @@ -0,0 +1,288 @@ +import logoLight from "../asset/logo-ornate-light.svg" +import logoDark from "../asset/logo-ornate-dark.svg" +import copyLogoLight from "../asset/lander/logo-light.svg" +import copyLogoDark from "../asset/lander/logo-dark.svg" +import copyWordmarkLight from "../asset/lander/wordmark-light.svg" +import copyWordmarkDark from "../asset/lander/wordmark-dark.svg" +import copyBrandAssetsLight from "../asset/lander/brand-assets-light.svg" +import copyBrandAssetsDark from "../asset/lander/brand-assets-dark.svg" + +// SVG files for copying (separate from button icons) +// Replace these with your actual SVG files for copying +import copyLogoSvgLight from "../asset/lander/opencode-logo-light.svg" +import copyLogoSvgDark from "../asset/lander/opencode-logo-dark.svg" +import copyWordmarkSvgLight from "../asset/lander/opencode-wordmark-light.svg" +import copyWordmarkSvgDark from "../asset/lander/opencode-wordmark-dark.svg" +import { A, useNavigate } from "@solidjs/router" +import { createMemo, Match, Show, Switch } from "solid-js" +import { createStore } from "solid-js/store" +import { createEffect, onCleanup } from "solid-js" +import { config } from "~/config" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import "./header-context-menu.css" + +const isDarkMode = () => window.matchMedia("(prefers-color-scheme: dark)").matches + +const fetchSvgContent = async (svgPath: string): Promise => { + try { + const response = await fetch(svgPath) + const svgText = await response.text() + return svgText + } catch (err) { + console.error("Failed to fetch SVG content:", err) + throw err + } +} + +export function Header(props: { zen?: boolean; go?: boolean; hideGetStarted?: boolean }) { + const navigate = useNavigate() + const i18n = useI18n() + const language = useLanguage() + + const [store, setStore] = createStore({ + mobileMenuOpen: false, + contextMenuOpen: false, + contextMenuPosition: { x: 0, y: 0 }, + }) + + createEffect(() => { + const handleClickOutside = () => { + setStore("contextMenuOpen", false) + } + + const handleContextMenu = (event: MouseEvent) => { + event.preventDefault() + setStore("contextMenuOpen", false) + } + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape") { + setStore("contextMenuOpen", false) + } + } + + if (store.contextMenuOpen) { + document.addEventListener("click", handleClickOutside) + document.addEventListener("contextmenu", handleContextMenu) + document.addEventListener("keydown", handleKeyDown) + onCleanup(() => { + document.removeEventListener("click", handleClickOutside) + document.removeEventListener("contextmenu", handleContextMenu) + document.removeEventListener("keydown", handleKeyDown) + }) + } + }) + + const handleLogoContextMenu = (event: MouseEvent) => { + event.preventDefault() + const logoElement = (event.currentTarget as HTMLElement).querySelector("a") + if (logoElement) { + const rect = logoElement.getBoundingClientRect() + setStore("contextMenuPosition", { + x: rect.left - 16, + y: rect.bottom + 8, + }) + } + setStore("contextMenuOpen", true) + } + + const copyWordmarkToClipboard = async () => { + try { + const isDark = isDarkMode() + const wordmarkSvgPath = isDark ? copyWordmarkSvgDark : copyWordmarkSvgLight + const wordmarkSvg = await fetchSvgContent(wordmarkSvgPath) + await navigator.clipboard.writeText(wordmarkSvg) + } catch (err) { + console.error("Failed to copy wordmark to clipboard:", err) + } + } + + const copyLogoToClipboard = async () => { + try { + const isDark = isDarkMode() + const logoSvgPath = isDark ? copyLogoSvgDark : copyLogoSvgLight + const logoSvg = await fetchSvgContent(logoSvgPath) + await navigator.clipboard.writeText(logoSvg) + } catch (err) { + console.error("Failed to copy logo to clipboard:", err) + } + } + + return ( +
+ + + +
+ + + +
+
+ + +
+ ) +} diff --git a/packages/console/app/src/component/icon.tsx b/packages/console/app/src/component/icon.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ed83a1934b6d039165774a7eccad23693bde309d --- /dev/null +++ b/packages/console/app/src/component/icon.tsx @@ -0,0 +1,286 @@ +import { JSX } from "solid-js" + +export function IconZen(_props: JSX.SvgSVGAttributes) { + return ( + + + + + + + + + ) +} + +export function IconGo(_props: JSX.SvgSVGAttributes) { + return ( + + + + + + + ) +} + +export function IconCopy(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconCheck(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconCreditCard(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconStripe(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconAlipay(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} + +export function IconUpi(props: JSX.SvgSVGAttributes) { + return ( + + + + + + ) +} + +export function IconWechat(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconChevron(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconWorkspaceLogo(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconOpenAI(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconAnthropic(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} + +export function IconXai(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} + +export function IconAlibaba(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconMoonshotAI(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconZai(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconMiniMax(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconGemini(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconDeepSeek(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconMiMo(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconXiaomi(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconNvidia(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconArcee(props: JSX.SvgSVGAttributes) { + return ( + + + + + + + ) +} + +export function IconStealth(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconChevronLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconChevronRight(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconBreakdown(props: JSX.SvgSVGAttributes) { + return ( + + + + + + + ) +} diff --git a/packages/console/app/src/component/language-picker.css b/packages/console/app/src/component/language-picker.css new file mode 100644 index 0000000000000000000000000000000000000000..8ef2306d729153dfb2aa09f4024cea64f06a3b04 --- /dev/null +++ b/packages/console/app/src/component/language-picker.css @@ -0,0 +1,135 @@ +[data-component="language-picker"] { + width: auto; +} + +[data-component="footer"] [data-component="language-picker"] { + width: 100%; +} + +[data-component="footer"] [data-component="language-picker"] [data-component="dropdown"] { + width: 100%; +} + +/* Standard site footer (grid of cells) */ +[data-component="footer"] [data-slot="cell"] [data-component="language-picker"] { + height: 100%; +} + +[data-component="footer"] [data-slot="cell"] [data-component="language-picker"] [data-slot="trigger"] { + width: 100%; + padding: 2rem 0; + border-radius: 0; + justify-content: center; + gap: var(--space-2); + color: inherit; + font: inherit; +} + +[data-component="footer"] [data-slot="cell"] [data-component="language-picker"] [data-slot="trigger"] span { + flex: 0 0 auto; + text-align: center; + font-weight: inherit; +} + +[data-component="footer"] [data-slot="cell"] [data-component="language-picker"] [data-slot="trigger"]:hover { + background: var(--color-background-weak); + text-decoration: underline; + text-underline-offset: var(--space-1); + text-decoration-thickness: 1px; +} + +/* Footer dropdown should open upward */ +[data-component="footer"] [data-component="language-picker"] [data-slot="dropdown"] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: var(--space-2); + max-height: min(60vh, 420px); + overflow: auto; +} + +[data-component="legal"] { + flex-wrap: wrap; + row-gap: var(--space-2); +} + +[data-component="legal"] [data-component="language-picker"] { + width: auto; +} + +[data-component="legal"] [data-component="language-picker"] [data-slot="trigger"] { + padding: 0; + border-radius: 0; + background: transparent; + font: inherit; + color: var(--color-text-weak); + white-space: nowrap; +} + +[data-component="legal"] [data-component="language-picker"] [data-slot="trigger"] span { + font-weight: inherit; +} + +[data-component="legal"] [data-component="language-picker"] [data-slot="trigger"]:hover { + background: transparent; + color: var(--color-text); + text-decoration: underline; + text-underline-offset: var(--space-1); + text-decoration-thickness: 1px; +} + +[data-component="legal"] [data-component="language-picker"] [data-slot="dropdown"] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: var(--space-2); + max-height: min(60vh, 420px); + overflow: auto; +} + +/* Black pages footer */ +[data-page="black"] [data-component="language-picker"] { + width: auto; +} + +[data-page="black"] [data-component="language-picker"] [data-component="dropdown"] { + width: auto; +} + +[data-page="black"] [data-component="language-picker"] [data-slot="trigger"] { + padding: 0; + border-radius: 0; + background: transparent; + font: inherit; + color: rgba(255, 255, 255, 0.39); +} + +[data-page="black"] [data-component="language-picker"] [data-slot="trigger"]:hover { + background: transparent; + text-decoration: underline; + text-underline-offset: 4px; +} + +[data-page="black"] [data-component="language-picker"] [data-slot="dropdown"] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: 12px; + background-color: #0e0e10; + border-color: rgba(255, 255, 255, 0.14); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6); + max-height: min(60vh, 420px); + overflow: auto; +} + +[data-page="black"] [data-component="language-picker"] [data-slot="item"] { + color: rgba(255, 255, 255, 0.86); +} + +[data-page="black"] [data-component="language-picker"] [data-slot="item"]:hover { + background-color: rgba(255, 255, 255, 0.06); +} + +[data-page="black"] [data-component="language-picker"] [data-slot="item"][data-selected="true"] { + background-color: rgba(255, 255, 255, 0.1); +} diff --git a/packages/console/app/src/component/language-picker.tsx b/packages/console/app/src/component/language-picker.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f42fd806567b1c1d472e0bfc5a197031d0014fdf --- /dev/null +++ b/packages/console/app/src/component/language-picker.tsx @@ -0,0 +1,40 @@ +import { For, createSignal } from "solid-js" +import { useLocation, useNavigate } from "@solidjs/router" +import { Dropdown, DropdownItem } from "~/component/dropdown" +import { useLanguage } from "~/context/language" +import { route, strip } from "~/lib/language" +import "./language-picker.css" + +export function LanguagePicker(props: { align?: "left" | "right" } = {}) { + const language = useLanguage() + const navigate = useNavigate() + const location = useLocation() + const [open, setOpen] = createSignal(false) + + return ( +
+ + + {(locale) => ( + { + language.setLocale(locale) + const href = `${route(locale, strip(location.pathname))}${location.search}${location.hash}` + if (href !== `${location.pathname}${location.search}${location.hash}`) navigate(href) + setOpen(false) + }} + > + {language.label(locale)} + + )} + + +
+ ) +} diff --git a/packages/console/app/src/component/legal.tsx b/packages/console/app/src/component/legal.tsx new file mode 100644 index 0000000000000000000000000000000000000000..39c534bf2c0087ecf5ab309fc0847a21740c7bab --- /dev/null +++ b/packages/console/app/src/component/legal.tsx @@ -0,0 +1,28 @@ +import { A } from "@solidjs/router" +import { LanguagePicker } from "~/component/language-picker" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" + +export function Legal() { + const i18n = useI18n() + const language = useLanguage() + return ( +
+ + ©{new Date().getFullYear()} Anomaly + + + {i18n.t("legal.brand")} + + + {i18n.t("legal.privacy")} + + + {i18n.t("legal.terms")} + + + + +
+ ) +} diff --git a/packages/console/app/src/component/limits-graph.css b/packages/console/app/src/component/limits-graph.css new file mode 100644 index 0000000000000000000000000000000000000000..ddcf2dfece5217111ec24aa49a6bc94a5da79d86 --- /dev/null +++ b/packages/console/app/src/component/limits-graph.css @@ -0,0 +1,300 @@ +[data-component="go-usage"] { + --model-width: 16.5rem; + --request-width: 5.25rem; + --allowance-width: 6.75rem; + --column-gap: 1.5rem; + --bar-origin: left; + container-type: inline-size; + margin: 0; + padding: 3rem var(--padding) 2.5rem; + font-variant-numeric: tabular-nums; + scroll-margin-top: 6rem; + -webkit-font-smoothing: antialiased; + + &:dir(rtl) { + --bar-origin: right; + } + + [data-slot="heading"] { + padding-bottom: 1.5rem; + + h2 { + color: var(--color-text-strong); + font-size: 1rem; + font-weight: 600; + } + } + + s { + display: block; + color: var(--color-text-weak); + font-size: 0.6875rem; + font-weight: 400; + } + + [data-slot="columns"], + [data-slot="model-row"] { + display: grid; + grid-template-columns: var(--model-width) minmax(0, 1fr) var(--allowance-width); + align-items: center; + column-gap: var(--column-gap); + } + + [data-slot="columns"] { + padding-bottom: 0.875rem; + border-bottom: 1px solid var(--color-border-weak); + font-size: 0.6875rem; + color: var(--color-text); + overflow-wrap: anywhere; + } + + [data-slot="requests-heading"], + [data-slot="allowance-heading"] { + text-align: end; + } + + [data-slot="rows"] { + padding-top: 0.375rem; + } + + [data-slot="model-row"] { + min-height: 2.5rem; + font-size: 0.8125rem; + } + + [data-slot="model"] { + display: flex; + align-items: baseline; + flex-wrap: wrap; + gap: 0.375rem 0.5rem; + min-width: 0; + line-height: 1.5; + color: var(--color-text); + font-weight: 400; + } + + [data-slot="badge"] { + color: var(--color-text-strong); + font-size: 0.625rem; + line-height: 1.3; + border: 1px solid var(--color-border); + padding: 0.0625rem 0.25rem; + } + + [data-slot="region"] { + display: inline-flex; + align-self: center; + padding: 0.25rem; + color: var(--color-text); + text-decoration: none; + + &:hover { + color: var(--color-text-strong); + } + } + + [data-slot="usage-value"] { + display: grid; + grid-template-columns: minmax(0, 1fr) var(--request-width); + align-items: center; + gap: var(--column-gap); + align-self: stretch; + } + + [data-slot="track"] { + display: flex; + align-items: center; + align-self: stretch; + position: relative; + isolation: isolate; + } + + [data-slot="gridline"] { + position: absolute; + inset-block: 0; + inset-inline-start: var(--position); + border-inline-start: 1px dotted var(--color-border-weak); + z-index: -1; + } + + [data-slot="bar"] { + width: var(--width); + height: 0.375rem; + background: var(--color-go-2); + transform-origin: var(--bar-origin); + } + + &[data-visible] [data-slot="bar"] { + animation: go-usage-reveal 700ms cubic-bezier(0.22, 1, 0.36, 1) both; + animation-delay: var(--delay); + } + + [data-slot="requests"] { + text-align: end; + font-weight: 600; + color: var(--color-text-strong); + } + + [data-slot="allowance"] { + text-align: end; + color: var(--color-text); + + &[data-high] { + color: var(--color-text-strong); + } + } + + [data-slot="currency"] { + color: var(--color-text-weak); + } + + [data-slot="axis"] { + padding-inline-start: calc(var(--model-width) + var(--column-gap)); + padding-inline-end: calc(var(--request-width) + var(--allowance-width) + 2 * var(--column-gap)); + height: 2.5rem; + } + + [data-slot="ticks"] { + position: relative; + height: 100%; + font-size: 0.625rem; + color: var(--color-text-weak); + + span { + position: absolute; + inset-inline-start: var(--position); + top: 0.75rem; + transform: translateX(-50%); + + &:dir(rtl) { + transform: translateX(50%); + } + } + } + + [data-slot="expand"] { + display: flex; + justify-content: center; + align-items: center; + gap: 0.5rem; + min-height: 2.75rem; + padding: 0.75rem 0; + background: none; + border: none; + color: var(--color-text); + font-family: inherit; + font-size: 0.75rem; + cursor: pointer; + + &:hover { + color: var(--color-text-strong); + } + &[aria-expanded="true"] svg { + transform: rotate(180deg); + } + } + + :is(button, a):focus-visible { + outline: 1px solid var(--color-text-strong); + outline-offset: 4px; + } + + figcaption { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + gap: 1rem; + border-top: 1px solid var(--color-border-weak); + font-size: 0.75rem; + color: var(--color-text); + + a { + color: inherit; + white-space: nowrap; + } + } + + @container (max-width: 48rem) { + [data-slot="columns"], + [data-slot="model-row"], + [data-slot="axis"] { + --model-width: 13rem; + --request-width: 4rem; + --allowance-width: 6rem; + --column-gap: 1rem; + } + } + + @container (max-width: 38rem) { + [data-slot="columns"], + [data-slot="model-row"] { + --request-width: 5rem; + --allowance-width: 4.5rem; + --column-gap: 0.75rem; + grid-template-columns: minmax(0, 1fr) var(--request-width) var(--allowance-width); + } + + [data-slot="columns"] { + font-size: 0.625rem; + } + + [data-slot="model-row"] { + min-height: 4rem; + padding-block: 0.375rem; + row-gap: 0.25rem; + font-size: 1rem; + } + + [data-slot="model"] { + grid-column: 1 / -1; + } + [data-slot="usage-value"] { + display: contents; + } + + [data-slot="track"] { + grid-column: 1; + grid-row: 2; + align-self: center; + height: 4px; + } + + [data-slot="bar"] { + height: 4px; + } + [data-slot="requests"] { + grid-column: 2; + grid-row: 2; + } + [data-slot="allowance"] { + grid-column: 3; + grid-row: 2; + } + [data-slot="gridline"], + [data-slot="axis"] { + display: none; + } + [data-slot="expand"] { + font-size: 0.8125rem; + } + figcaption { + margin-top: 1rem; + } + } + + @media (prefers-reduced-motion: reduce) { + &[data-visible] [data-slot="bar"] { + animation: none; + } + } +} + +@keyframes go-usage-reveal { + from { + transform: scaleX(0); + } + to { + transform: scaleX(1); + } +} diff --git a/packages/console/app/src/component/limits-graph.tsx b/packages/console/app/src/component/limits-graph.tsx new file mode 100644 index 0000000000000000000000000000000000000000..410fd48e43929efcaa6d8f8f29a3cce4fe52f9a6 --- /dev/null +++ b/packages/console/app/src/component/limits-graph.tsx @@ -0,0 +1,166 @@ +import "./limits-graph.css" +import { For, Show, createMemo, createSignal, createUniqueId, onCleanup, onMount } from "solid-js" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import { goModels } from "./go-models" + +// Compress the request range, with the same domain in both views. +const max = Math.max(...goModels.map((model) => model.requests)) +const position = (requests: number) => + 4 + Math.pow(Math.log10(Math.max(requests / 100, 1)) / Math.log10(max / 100), 2.2) * 96 +const ticks = [100, 1000, 10000, 40000] + +export function LimitsGraph(props: { href: string }) { + const i18n = useI18n() + const language = useLanguage() + const id = createUniqueId() + const [expanded, setExpanded] = createSignal(false) + const [visible, setVisible] = createSignal(false) + const models = createMemo(() => goModels.filter((model) => expanded() || model.featured || model.fresh)) + const format = createMemo(() => new Intl.NumberFormat(language.tag(language.locale()))) + const compact = createMemo( + () => new Intl.NumberFormat(language.tag(language.locale()), { notation: "compact", maximumFractionDigits: 1 }), + ) + const currency = createMemo( + () => + new Intl.NumberFormat(language.tag(language.locale()), { + style: "currency", + currency: "USD", + currencyDisplay: "narrowSymbol", + maximumFractionDigits: 0, + }), + ) + let root!: HTMLElement + + onMount(() => { + if (!window.IntersectionObserver) return setVisible(true) + const observer = new IntersectionObserver( + (entries) => { + if (!entries.some((entry) => entry.isIntersecting)) return + setVisible(true) + observer.disconnect() + }, + { threshold: 0.1 }, + ) + observer.observe(root) + onCleanup(() => observer.disconnect()) + }) + + return ( +
+
+

{i18n.t("go.graph.period")}

+
+ +
+
+
+ {i18n.t("go.graph.model")} +
+
+ {i18n.t("go.graph.requests")} +
+
+ {i18n.t("go.graph.allowance")} +
+
+
+ + {(model, index) => ( +
+
+ {model.name} + + {i18n.t("go.graph.new")} + + + {i18n.t("go.graph.bonus", { count: model.bonus! })} + + + + + + +
+
+ +
= 60 ? "" : undefined}> + + {currency().format(model.baseAllowance!)}{" "} + + + + {(part) => ( + {part.value} + )} + + +
+
+ )} + +
+
+ + + +
+ + {i18n.t("go.graph.usageLimits")} +
+
+ ) +} diff --git a/packages/console/app/src/component/locale-links.tsx b/packages/console/app/src/component/locale-links.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f773bb885c088ebc880123278655e090d8aba6d1 --- /dev/null +++ b/packages/console/app/src/component/locale-links.tsx @@ -0,0 +1,36 @@ +import { Link } from "@solidjs/meta" +import { For } from "solid-js" +import { getRequestEvent } from "solid-js/web" +import { config } from "~/config" +import { useLanguage } from "~/context/language" +import { LOCALES, route, tag } from "~/lib/language" + +function skip(path: string) { + const evt = getRequestEvent() + if (!evt) return false + + const key = "__locale_links_seen" + const locals = evt.locals as Record + const seen = locals[key] instanceof Set ? (locals[key] as Set) : new Set() + locals[key] = seen + if (seen.has(path)) return true + seen.add(path) + return false +} + +export function LocaleLinks(props: { path: string }) { + const language = useLanguage() + if (skip(props.path)) return null + + return ( + <> + + + {(locale) => ( + + )} + + + + ) +} diff --git a/packages/console/app/src/component/modal.css b/packages/console/app/src/component/modal.css new file mode 100644 index 0000000000000000000000000000000000000000..ab7f222b021ea15e234ddc7205b7578a0c406b85 --- /dev/null +++ b/packages/console/app/src/component/modal.css @@ -0,0 +1,134 @@ +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes slideUp { + from { + opacity: 0; + transform: translateY(20px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +[data-component="modal"][data-slot="overlay"] { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(0, 0, 0, 0.5); + animation: fadeIn 0.2s ease; + + @media (prefers-color-scheme: dark) { + background-color: rgba(0, 0, 0, 0.7); + } + + [data-slot="content"] { + background-color: var(--color-bg); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-md); + padding: var(--space-6); + min-width: 400px; + max-width: 90vw; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2); + animation: slideUp 0.2s ease; + + @media (max-width: 30rem) { + min-width: 300px; + padding: var(--space-4); + } + + @media (prefers-color-scheme: dark) { + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); + } + + button { + display: inline-flex; + align-items: center; + justify-content: center; + padding: var(--space-3) var(--space-4); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + background-color: var(--color-bg); + color: var(--color-text); + font-size: var(--font-size-sm); + font-family: var(--font-sans); + font-weight: 500; + line-height: 1; + cursor: pointer; + transition: all 0.15s ease; + + &:hover:not(:disabled) { + background-color: var(--color-surface-hover); + border-color: var(--color-accent); + } + + &:active:not(:disabled) { + transform: translateY(1px); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + transform: none; + } + + &[data-color="primary"] { + background-color: var(--color-primary); + border-color: var(--color-primary); + color: var(--color-primary-text); + + &:hover:not(:disabled) { + background-color: var(--color-primary-hover); + border-color: var(--color-primary-hover); + } + } + + &[data-color="ghost"] { + background-color: transparent; + border-color: transparent; + color: var(--color-text-muted); + + &:hover:not(:disabled) { + background-color: var(--color-surface-hover); + border-color: var(--color-border); + color: var(--color-text); + } + } + } + } + + [data-slot="title"] { + margin: 0 0 var(--space-4) 0; + font-size: var(--font-size-lg); + font-weight: 600; + color: var(--color-text); + text-align: center; + } + + [data-slot="content"][data-variant="black"] { + background-color: #000; + border-color: rgba(255, 255, 255, 0.17); + color: rgba(255, 255, 255, 0.92); + font-family: var(--font-mono); + + [data-slot="title"] { + color: rgba(255, 255, 255, 0.92); + font-family: var(--font-mono); + } + } +} diff --git a/packages/console/app/src/component/modal.tsx b/packages/console/app/src/component/modal.tsx new file mode 100644 index 0000000000000000000000000000000000000000..8cac8c4ce79a33e82ee77c2f8dcd84f460b285e8 --- /dev/null +++ b/packages/console/app/src/component/modal.tsx @@ -0,0 +1,46 @@ +import { Dialog as Kobalte } from "@kobalte/core/dialog" +import { JSX, Show } from "solid-js" +import "./modal.css" + +interface ModalProps { + open: boolean + onClose: () => void + title?: string + variant?: "black" + children: JSX.Element +} + +export function Modal(props: ModalProps) { + return ( + + { + if (!open) props.onClose() + }} + > + + + e.stopPropagation()} + onOpenAutoFocus={(e) => { + e.preventDefault() + const target = e.currentTarget as HTMLElement | null + target?.focus({ preventScroll: true }) + }} + > + + {props.title} + + {props.children} + + + + + + ) +} diff --git a/packages/console/app/src/component/rolling-number.tsx b/packages/console/app/src/component/rolling-number.tsx new file mode 100644 index 0000000000000000000000000000000000000000..df1af6ca20cf8121ca8bf0f3ce488a85227819c7 --- /dev/null +++ b/packages/console/app/src/component/rolling-number.tsx @@ -0,0 +1,58 @@ +import NumberFlow from "number-flow" +import { continuous } from "number-flow/plugins" +import { createEffect, onCleanup, onMount } from "solid-js" + +export function RollingNumber(props: { + value: number + target: number + timing: () => { duration: number; easing: string; spinEasing: string } +}) { + let root!: HTMLSpanElement + // Keep the server-rendered text stable while the custom element owns its contents. + const initial = props.value.toLocaleString() + const growing = props.target.toLocaleString().length > initial.length + + onMount(() => { + if (new Intl.NumberFormat().resolvedOptions().numberingSystem !== "latn") { + createEffect(() => { + root.textContent = props.value.toLocaleString() + }) + return + } + + const flow = new NumberFlow() + flow.format = { useGrouping: true, maximumFractionDigits: 0 } + flow.trend = 1 + if (growing) flow.plugins = [continuous] + flow.opacityTiming = { duration: 180, easing: "ease-out" } + const motion = window.matchMedia("(prefers-reduced-motion: reduce)") + const updateMotion = () => { + flow.animated = !motion.matches + } + updateMotion() + motion.addEventListener("change", updateMotion) + onCleanup(() => motion.removeEventListener("change", updateMotion)) + root.replaceChildren(flow) + createEffect(() => { + const value = props.value + if (flow.value === value) return + const timing = props.timing() + flow.transformTiming = { duration: timing.duration, easing: timing.easing } + flow.spinTiming = { + duration: timing.duration, + easing: growing ? "cubic-bezier(0.45, 0, 0.55, 1)" : timing.spinEasing, + } + flow.update(value) + }) + }) + + return ( + + {initial} + + ) +} diff --git a/packages/console/app/src/component/spotlight.css b/packages/console/app/src/component/spotlight.css new file mode 100644 index 0000000000000000000000000000000000000000..4b311c3d02161ae6ab4f9e61d97e1dbed57cc7bb --- /dev/null +++ b/packages/console/app/src/component/spotlight.css @@ -0,0 +1,15 @@ +.spotlight-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 50dvh; + pointer-events: none; + overflow: hidden; +} + +.spotlight-container canvas { + display: block; + width: 100%; + height: 100%; +} diff --git a/packages/console/app/src/component/spotlight.tsx b/packages/console/app/src/component/spotlight.tsx new file mode 100644 index 0000000000000000000000000000000000000000..19accb88a6331090139f760cc2fed6bcf2b64ace --- /dev/null +++ b/packages/console/app/src/component/spotlight.tsx @@ -0,0 +1,820 @@ +import { createSignal, createEffect, onMount, onCleanup, Accessor } from "solid-js" +import "./spotlight.css" + +export interface ParticlesConfig { + enabled: boolean + amount: number + size: [number, number] + speed: number + opacity: number + drift: number +} + +export interface SpotlightConfig { + placement: [number, number] + color: string + speed: number + spread: number + length: number + width: number + pulsating: false | [number, number] + distance: number + saturation: number + noiseAmount: number + distortion: number + opacity: number + particles: ParticlesConfig +} + +export const defaultConfig: SpotlightConfig = { + placement: [0.5, -0.15], + color: "#ffffff", + speed: 0.8, + spread: 0.5, + length: 4.0, + width: 0.15, + pulsating: [0.95, 1.1], + distance: 3.5, + saturation: 0.35, + noiseAmount: 0.15, + distortion: 0.05, + opacity: 0.325, + particles: { + enabled: true, + amount: 70, + size: [1.25, 1.5], + speed: 0.75, + opacity: 0.9, + drift: 1.5, + }, +} + +export interface SpotlightAnimationState { + time: number + intensity: number + pulseValue: number +} + +interface SpotlightProps { + config: Accessor + class?: string + onAnimationFrame?: (state: SpotlightAnimationState) => void +} + +const hexToRgb = (hex: string): [number, number, number] => { + const m = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) + return m ? [parseInt(m[1], 16) / 255, parseInt(m[2], 16) / 255, parseInt(m[3], 16) / 255] : [1, 1, 1] +} + +const getAnchorAndDir = ( + placement: [number, number], + w: number, + h: number, +): { anchor: [number, number]; dir: [number, number] } => { + const [px, py] = placement + const outside = 0.2 + + let anchorX = px * w + let anchorY = py * h + let dirX = 0 + let dirY = 0 + + const centerX = 0.5 + const centerY = 0.5 + + if (py <= 0.25) { + anchorY = -outside * h + py * h + dirY = 1 + dirX = (centerX - px) * 0.5 + } else if (py >= 0.75) { + anchorY = (1 + outside) * h - (1 - py) * h + dirY = -1 + dirX = (centerX - px) * 0.5 + } else if (px <= 0.25) { + anchorX = -outside * w + px * w + dirX = 1 + dirY = (centerY - py) * 0.5 + } else if (px >= 0.75) { + anchorX = (1 + outside) * w - (1 - px) * w + dirX = -1 + dirY = (centerY - py) * 0.5 + } else { + dirY = 1 + } + + const len = Math.sqrt(dirX * dirX + dirY * dirY) + if (len > 0) { + dirX /= len + dirY /= len + } + + return { anchor: [anchorX, anchorY], dir: [dirX, dirY] } +} + +interface UniformData { + iTime: number + iResolution: [number, number] + lightPos: [number, number] + lightDir: [number, number] + color: [number, number, number] + speed: number + lightSpread: number + lightLength: number + sourceWidth: number + pulsating: number + pulsatingMin: number + pulsatingMax: number + fadeDistance: number + saturation: number + noiseAmount: number + distortion: number + particlesEnabled: number + particleAmount: number + particleSizeMin: number + particleSizeMax: number + particleSpeed: number + particleOpacity: number + particleDrift: number +} + +const WGSL_SHADER = ` + struct Uniforms { + iTime: f32, + _pad0: f32, + iResolution: vec2, + lightPos: vec2, + lightDir: vec2, + color: vec3, + speed: f32, + lightSpread: f32, + lightLength: f32, + sourceWidth: f32, + pulsating: f32, + pulsatingMin: f32, + pulsatingMax: f32, + fadeDistance: f32, + saturation: f32, + noiseAmount: f32, + distortion: f32, + particlesEnabled: f32, + particleAmount: f32, + particleSizeMin: f32, + particleSizeMax: f32, + particleSpeed: f32, + particleOpacity: f32, + particleDrift: f32, + _pad1: f32, + _pad2: f32, + }; + + @group(0) @binding(0) var uniforms: Uniforms; + + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) vUv: vec2, + }; + + @vertex + fn vertexMain(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput { + var positions = array, 3>( + vec2(-1.0, -1.0), + vec2(3.0, -1.0), + vec2(-1.0, 3.0) + ); + + var output: VertexOutput; + let pos = positions[vertexIndex]; + output.position = vec4(pos, 0.0, 1.0); + output.vUv = pos * 0.5 + 0.5; + return output; + } + + fn hash(p: vec2) -> f32 { + let p3 = fract(p.xyx * 0.1031); + return fract((p3.x + p3.y) * p3.z + dot(p3, p3.yzx + 33.33)); + } + + fn hash2(p: vec2) -> vec2 { + let n = sin(dot(p, vec2(41.0, 289.0))); + return fract(vec2(n * 262144.0, n * 32768.0)); + } + + fn fastNoise(st: vec2) -> f32 { + return fract(sin(dot(st, vec2(12.9898, 78.233))) * 43758.5453); + } + + fn lightStrengthCombined(lightSource: vec2, lightRefDirection: vec2, coord: vec2) -> f32 { + let sourceToCoord = coord - lightSource; + let distSq = dot(sourceToCoord, sourceToCoord); + let distance = sqrt(distSq); + + let baseSize = min(uniforms.iResolution.x, uniforms.iResolution.y); + let maxDistance = max(baseSize * uniforms.lightLength, 0.001); + if (distance > maxDistance) { + return 0.0; + } + + let invDist = 1.0 / max(distance, 0.001); + let dirNorm = sourceToCoord * invDist; + let cosAngle = dot(dirNorm, lightRefDirection); + + if (cosAngle < 0.0) { + return 0.0; + } + + let side = dot(dirNorm, vec2(-lightRefDirection.y, lightRefDirection.x)); + let time = uniforms.iTime; + let speed = uniforms.speed; + + let asymNoise = fastNoise(vec2(side * 6.0 + time * 0.12, distance * 0.004 + cosAngle * 2.0)); + let asymShift = (asymNoise - 0.5) * uniforms.distortion * 0.6; + + let distortPhase = time * 1.4 + distance * 0.006 + cosAngle * 4.5 + side * 1.7; + let distortedAngle = cosAngle + uniforms.distortion * sin(distortPhase) * 0.22 + asymShift; + + let flickerSeed = cosAngle * 9.0 + side * 4.0 + time * speed * 0.35; + let flicker = 0.86 + fastNoise(vec2(flickerSeed, distance * 0.01)) * 0.28; + + let asymSpread = max(uniforms.lightSpread * (0.9 + (asymNoise - 0.5) * 0.25), 0.001); + let spreadFactor = pow(max(distortedAngle, 0.0), 1.0 / asymSpread); + let lengthFalloff = clamp(1.0 - distance / maxDistance, 0.0, 1.0); + + let fadeMaxDist = max(baseSize * uniforms.fadeDistance, 0.001); + let fadeFalloff = clamp((fadeMaxDist - distance) / fadeMaxDist, 0.0, 1.0); + + var pulse: f32 = 1.0; + if (uniforms.pulsating > 0.5) { + let pulseCenter = (uniforms.pulsatingMin + uniforms.pulsatingMax) * 0.5; + let pulseAmplitude = (uniforms.pulsatingMax - uniforms.pulsatingMin) * 0.5; + pulse = pulseCenter + pulseAmplitude * sin(time * speed * 3.0); + } + + let timeSpeed = time * speed; + let wave = 0.5 + + 0.25 * sin(cosAngle * 28.0 + side * 8.0 + timeSpeed * 1.2) + + 0.18 * cos(cosAngle * 22.0 - timeSpeed * 0.95 + side * 6.0) + + 0.12 * sin(cosAngle * 35.0 + timeSpeed * 1.6 + asymNoise * 3.0); + let minStrength = 0.14 + asymNoise * 0.06; + let baseStrength = max(clamp(wave * (0.85 + asymNoise * 0.3), 0.0, 1.0), minStrength); + + let lightStrength = baseStrength * lengthFalloff * fadeFalloff * spreadFactor * pulse * flicker; + let ambientLight = (0.06 + asymNoise * 0.04) * lengthFalloff * fadeFalloff * spreadFactor; + + return max(lightStrength, ambientLight); + } + + fn particle(coord: vec2, particlePos: vec2, size: f32) -> f32 { + let delta = coord - particlePos; + let distSq = dot(delta, delta); + let sizeSq = size * size; + + if (distSq > sizeSq * 9.0) { + return 0.0; + } + + let d = sqrt(distSq); + let core = smoothstep(size, size * 0.35, d); + let glow = smoothstep(size * 3.0, 0.0, d) * 0.55; + return core + glow; + } + + fn renderParticles(coord: vec2, lightSource: vec2, lightDir: vec2) -> f32 { + if (uniforms.particlesEnabled < 0.5 || uniforms.particleAmount < 1.0) { + return 0.0; + } + + var particleSum: f32 = 0.0; + let particleCount = i32(uniforms.particleAmount); + let time = uniforms.iTime * uniforms.particleSpeed; + let perpDir = vec2(-lightDir.y, lightDir.x); + let baseSize = min(uniforms.iResolution.x, uniforms.iResolution.y); + let maxDist = max(baseSize * uniforms.lightLength, 1.0); + let spreadScale = uniforms.lightSpread * baseSize * 0.65; + let coneHalfWidth = uniforms.lightSpread * baseSize * 0.55; + + for (var i: i32 = 0; i < particleCount; i = i + 1) { + let fi = f32(i); + let seed = vec2(fi * 127.1, fi * 311.7); + let rnd = hash2(seed); + + let lifeDuration = 2.0 + hash(seed + vec2(19.0, 73.0)) * 3.0; + let lifeOffset = hash(seed + vec2(91.0, 37.0)) * lifeDuration; + let lifeProgress = fract((time + lifeOffset) / lifeDuration); + + let fadeIn = smoothstep(0.0, 0.2, lifeProgress); + let fadeOut = 1.0 - smoothstep(0.8, 1.0, lifeProgress); + let lifeFade = fadeIn * fadeOut; + if (lifeFade < 0.01) { + continue; + } + + let alongLight = rnd.x * maxDist * 0.8; + let perpOffset = (rnd.y - 0.5) * spreadScale; + + let floatPhase = rnd.y * 6.28318 + fi * 0.37; + let floatSpeed = 0.35 + rnd.x * 0.9; + let drift = vec2( + sin(time * floatSpeed + floatPhase), + cos(time * floatSpeed * 0.85 + floatPhase * 1.3) + ) * uniforms.particleDrift * baseSize * 0.08; + + let wobble = vec2( + sin(time * 1.4 + floatPhase * 2.1), + cos(time * 1.1 + floatPhase * 1.6) + ) * uniforms.particleDrift * baseSize * 0.03; + + let flowOffset = (rnd.x - 0.5) * baseSize * 0.12 + fract(time * 0.06 + rnd.y) * baseSize * 0.1; + + let basePos = lightSource + lightDir * (alongLight + flowOffset) + perpDir * perpOffset + drift + wobble; + + let toParticle = basePos - lightSource; + let projLen = dot(toParticle, lightDir); + if (projLen < 0.0 || projLen > maxDist) { + continue; + } + + let sideDist = abs(dot(toParticle, perpDir)); + if (sideDist > coneHalfWidth) { + continue; + } + + let size = mix(uniforms.particleSizeMin, uniforms.particleSizeMax, rnd.x); + let twinkle = 0.7 + 0.3 * sin(time * (1.5 + rnd.y * 2.0) + floatPhase); + let distFade = 1.0 - smoothstep(maxDist * 0.2, maxDist * 0.95, projLen); + if (distFade < 0.01) { + continue; + } + + let p = particle(coord, basePos, size); + if (p > 0.0) { + particleSum = particleSum + p * lifeFade * twinkle * distFade * uniforms.particleOpacity; + if (particleSum >= 1.0) { + break; + } + } + } + + return min(particleSum, 1.0); + } + + @fragment + fn fragmentMain(@builtin(position) fragCoord: vec4, @location(0) vUv: vec2) -> @location(0) vec4 { + let coord = vec2(fragCoord.x, fragCoord.y); + + let normalizedX = (coord.x / uniforms.iResolution.x) - 0.5; + let widthOffset = -normalizedX * uniforms.sourceWidth * uniforms.iResolution.x; + + let perpDir = vec2(-uniforms.lightDir.y, uniforms.lightDir.x); + let adjustedLightPos = uniforms.lightPos + perpDir * widthOffset; + + let lightValue = lightStrengthCombined(adjustedLightPos, uniforms.lightDir, coord); + + if (lightValue < 0.001) { + let particles = renderParticles(coord, adjustedLightPos, uniforms.lightDir); + if (particles < 0.001) { + return vec4(0.0, 0.0, 0.0, 0.0); + } + let particleBrightness = particles * 1.8; + return vec4(uniforms.color * particleBrightness, particles * 0.9); + } + + var fragColor = vec4(lightValue, lightValue, lightValue, lightValue); + + if (uniforms.noiseAmount > 0.01) { + let n = fastNoise(coord * 0.5 + uniforms.iTime * 0.5); + let grain = mix(1.0, n, uniforms.noiseAmount * 0.5); + fragColor = vec4(fragColor.rgb * grain, fragColor.a); + } + + let brightness = 1.0 - (coord.y / uniforms.iResolution.y); + fragColor = vec4( + fragColor.x * (0.15 + brightness * 0.85), + fragColor.y * (0.35 + brightness * 0.65), + fragColor.z * (0.55 + brightness * 0.45), + fragColor.a + ); + + if (abs(uniforms.saturation - 1.0) > 0.01) { + let gray = dot(fragColor.rgb, vec3(0.299, 0.587, 0.114)); + fragColor = vec4(mix(vec3(gray), fragColor.rgb, uniforms.saturation), fragColor.a); + } + + fragColor = vec4(fragColor.rgb * uniforms.color, fragColor.a); + + let particles = renderParticles(coord, adjustedLightPos, uniforms.lightDir); + if (particles > 0.001) { + let particleBrightness = particles * 1.8; + fragColor = vec4(fragColor.rgb + uniforms.color * particleBrightness, max(fragColor.a, particles * 0.9)); + } + + return fragColor; + } +` + +const UNIFORM_BUFFER_SIZE = 144 + +function updateUniformBuffer(buffer: Float32Array, data: UniformData): void { + buffer[0] = data.iTime + buffer[2] = data.iResolution[0] + buffer[3] = data.iResolution[1] + buffer[4] = data.lightPos[0] + buffer[5] = data.lightPos[1] + buffer[6] = data.lightDir[0] + buffer[7] = data.lightDir[1] + buffer[8] = data.color[0] + buffer[9] = data.color[1] + buffer[10] = data.color[2] + buffer[11] = data.speed + buffer[12] = data.lightSpread + buffer[13] = data.lightLength + buffer[14] = data.sourceWidth + buffer[15] = data.pulsating + buffer[16] = data.pulsatingMin + buffer[17] = data.pulsatingMax + buffer[18] = data.fadeDistance + buffer[19] = data.saturation + buffer[20] = data.noiseAmount + buffer[21] = data.distortion + buffer[22] = data.particlesEnabled + buffer[23] = data.particleAmount + buffer[24] = data.particleSizeMin + buffer[25] = data.particleSizeMax + buffer[26] = data.particleSpeed + buffer[27] = data.particleOpacity + buffer[28] = data.particleDrift +} + +export default function Spotlight(props: SpotlightProps) { + let containerRef: HTMLDivElement | undefined + let canvasRef: HTMLCanvasElement | null = null + let deviceRef: GPUDevice | null = null + let contextRef: GPUCanvasContext | null = null + let pipelineRef: GPURenderPipeline | null = null + let uniformBufferRef: GPUBuffer | null = null + let bindGroupRef: GPUBindGroup | null = null + let animationIdRef: number | null = null + let cleanupFunctionRef: (() => void) | null = null + let uniformDataRef: UniformData | null = null + let uniformArrayRef: Float32Array | null = null + let configRef: SpotlightConfig = props.config() + let frameCount = 0 + + const [isVisible, setIsVisible] = createSignal(false) + + createEffect(() => { + configRef = props.config() + }) + + onMount(() => { + if (!containerRef) return + + const observer = new IntersectionObserver( + (entries) => { + const entry = entries[0] + setIsVisible(entry.isIntersecting) + }, + { threshold: 0.1 }, + ) + + observer.observe(containerRef) + + onCleanup(() => { + observer.disconnect() + }) + }) + + createEffect(() => { + const visible = isVisible() + const config = props.config() + if (!visible || !containerRef) { + return + } + + if (cleanupFunctionRef) { + cleanupFunctionRef() + cleanupFunctionRef = null + } + + const initializeWebGPU = async () => { + if (!containerRef) { + return + } + + await new Promise((resolve) => setTimeout(resolve, 10)) + + if (!containerRef) { + return + } + + if (!navigator.gpu) { + console.warn("WebGPU is not supported in this browser") + return + } + + const adapter = await navigator.gpu.requestAdapter({ + powerPreference: "high-performance", + }) + if (!adapter) { + console.warn("Failed to get WebGPU adapter") + return + } + + const device = await adapter.requestDevice() + deviceRef = device + + const canvas = document.createElement("canvas") + canvas.style.width = "100%" + canvas.style.height = "100%" + canvasRef = canvas + + while (containerRef.firstChild) { + containerRef.removeChild(containerRef.firstChild) + } + containerRef.appendChild(canvas) + + const context = canvas.getContext("webgpu") + if (!context) { + console.warn("Failed to get WebGPU context") + return + } + contextRef = context + + const presentationFormat = navigator.gpu.getPreferredCanvasFormat() + context.configure({ + device, + format: presentationFormat, + alphaMode: "premultiplied", + }) + + const shaderModule = device.createShaderModule({ + code: WGSL_SHADER, + }) + + const uniformBuffer = device.createBuffer({ + size: UNIFORM_BUFFER_SIZE, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }) + uniformBufferRef = uniformBuffer + + const bindGroupLayout = device.createBindGroupLayout({ + entries: [ + { + binding: 0, + visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, + buffer: { type: "uniform" }, + }, + ], + }) + + const bindGroup = device.createBindGroup({ + layout: bindGroupLayout, + entries: [ + { + binding: 0, + resource: { buffer: uniformBuffer }, + }, + ], + }) + bindGroupRef = bindGroup + + const pipelineLayout = device.createPipelineLayout({ + bindGroupLayouts: [bindGroupLayout], + }) + + const pipeline = device.createRenderPipeline({ + layout: pipelineLayout, + vertex: { + module: shaderModule, + entryPoint: "vertexMain", + }, + fragment: { + module: shaderModule, + entryPoint: "fragmentMain", + targets: [ + { + format: presentationFormat, + blend: { + color: { + srcFactor: "src-alpha", + dstFactor: "one-minus-src-alpha", + operation: "add", + }, + alpha: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add", + }, + }, + }, + ], + }, + primitive: { + topology: "triangle-list", + }, + }) + pipelineRef = pipeline + + const { clientWidth: wCSS, clientHeight: hCSS } = containerRef + const dpr = Math.min(window.devicePixelRatio, 2) + const w = wCSS * dpr + const h = hCSS * dpr + const { anchor, dir } = getAnchorAndDir(config.placement, w, h) + + uniformDataRef = { + iTime: 0, + iResolution: [w, h], + lightPos: anchor, + lightDir: dir, + color: hexToRgb(config.color), + speed: config.speed, + lightSpread: config.spread, + lightLength: config.length, + sourceWidth: config.width, + pulsating: config.pulsating !== false ? 1.0 : 0.0, + pulsatingMin: config.pulsating !== false ? config.pulsating[0] : 1.0, + pulsatingMax: config.pulsating !== false ? config.pulsating[1] : 1.0, + fadeDistance: config.distance, + saturation: config.saturation, + noiseAmount: config.noiseAmount, + distortion: config.distortion, + particlesEnabled: config.particles.enabled ? 1.0 : 0.0, + particleAmount: config.particles.amount, + particleSizeMin: config.particles.size[0], + particleSizeMax: config.particles.size[1], + particleSpeed: config.particles.speed, + particleOpacity: config.particles.opacity, + particleDrift: config.particles.drift, + } + + const updatePlacement = () => { + if (!containerRef || !canvasRef || !uniformDataRef) { + return + } + + const dpr = Math.min(window.devicePixelRatio, 2) + const { clientWidth: wCSS, clientHeight: hCSS } = containerRef + const w = Math.floor(wCSS * dpr) + const h = Math.floor(hCSS * dpr) + + canvasRef.width = w + canvasRef.height = h + + uniformDataRef.iResolution = [w, h] + + const { anchor, dir } = getAnchorAndDir(configRef.placement, w, h) + uniformDataRef.lightPos = anchor + uniformDataRef.lightDir = dir + } + + const loop = (t: number) => { + if (!deviceRef || !contextRef || !pipelineRef || !uniformBufferRef || !bindGroupRef || !uniformDataRef) { + return + } + + const timeSeconds = t * 0.001 + uniformDataRef.iTime = timeSeconds + frameCount++ + + if (props.onAnimationFrame && frameCount % 2 === 0) { + const pulsatingMin = configRef.pulsating !== false ? configRef.pulsating[0] : 1.0 + const pulsatingMax = configRef.pulsating !== false ? configRef.pulsating[1] : 1.0 + const pulseCenter = (pulsatingMin + pulsatingMax) * 0.5 + const pulseAmplitude = (pulsatingMax - pulsatingMin) * 0.5 + const pulseValue = + configRef.pulsating !== false + ? pulseCenter + pulseAmplitude * Math.sin(timeSeconds * configRef.speed * 3.0) + : 1.0 + + const baseIntensity1 = 0.45 + 0.15 * Math.sin(timeSeconds * configRef.speed * 1.5) + const baseIntensity2 = 0.3 + 0.2 * Math.cos(timeSeconds * configRef.speed * 1.1) + const intensity = Math.max((baseIntensity1 + baseIntensity2) * pulseValue, 0.55) + + props.onAnimationFrame({ + time: timeSeconds, + intensity, + pulseValue: Math.max(pulseValue, 0.9), + }) + } + + try { + if (!uniformArrayRef) { + uniformArrayRef = new Float32Array(36) + } + updateUniformBuffer(uniformArrayRef, uniformDataRef) + deviceRef.queue.writeBuffer(uniformBufferRef, 0, uniformArrayRef.buffer) + + const commandEncoder = deviceRef.createCommandEncoder() + + const textureView = contextRef.getCurrentTexture().createView() + + const renderPass = commandEncoder.beginRenderPass({ + colorAttachments: [ + { + view: textureView, + clearValue: { r: 0, g: 0, b: 0, a: 0 }, + loadOp: "clear", + storeOp: "store", + }, + ], + }) + + renderPass.setPipeline(pipelineRef) + renderPass.setBindGroup(0, bindGroupRef) + renderPass.draw(3) + renderPass.end() + + deviceRef.queue.submit([commandEncoder.finish()]) + + animationIdRef = requestAnimationFrame(loop) + } catch (error) { + console.warn("WebGPU rendering error:", error) + return + } + } + + window.addEventListener("resize", updatePlacement) + updatePlacement() + animationIdRef = requestAnimationFrame(loop) + + cleanupFunctionRef = () => { + if (animationIdRef) { + cancelAnimationFrame(animationIdRef) + animationIdRef = null + } + + window.removeEventListener("resize", updatePlacement) + + if (uniformBufferRef) { + uniformBufferRef.destroy() + uniformBufferRef = null + } + + if (deviceRef) { + deviceRef.destroy() + deviceRef = null + } + + if (canvasRef && canvasRef.parentNode) { + canvasRef.parentNode.removeChild(canvasRef) + } + + canvasRef = null + contextRef = null + pipelineRef = null + bindGroupRef = null + uniformDataRef = null + } + } + + void initializeWebGPU() + + onCleanup(() => { + if (cleanupFunctionRef) { + cleanupFunctionRef() + cleanupFunctionRef = null + } + }) + }) + + createEffect(() => { + if (!uniformDataRef || !containerRef) { + return + } + + const config = props.config() + + uniformDataRef.color = hexToRgb(config.color) + uniformDataRef.speed = config.speed + uniformDataRef.lightSpread = config.spread + uniformDataRef.lightLength = config.length + uniformDataRef.sourceWidth = config.width + uniformDataRef.pulsating = config.pulsating !== false ? 1.0 : 0.0 + uniformDataRef.pulsatingMin = config.pulsating !== false ? config.pulsating[0] : 1.0 + uniformDataRef.pulsatingMax = config.pulsating !== false ? config.pulsating[1] : 1.0 + uniformDataRef.fadeDistance = config.distance + uniformDataRef.saturation = config.saturation + uniformDataRef.noiseAmount = config.noiseAmount + uniformDataRef.distortion = config.distortion + uniformDataRef.particlesEnabled = config.particles.enabled ? 1.0 : 0.0 + uniformDataRef.particleAmount = config.particles.amount + uniformDataRef.particleSizeMin = config.particles.size[0] + uniformDataRef.particleSizeMax = config.particles.size[1] + uniformDataRef.particleSpeed = config.particles.speed + uniformDataRef.particleOpacity = config.particles.opacity + uniformDataRef.particleDrift = config.particles.drift + + const dpr = Math.min(window.devicePixelRatio, 2) + const { clientWidth: wCSS, clientHeight: hCSS } = containerRef + const { anchor, dir } = getAnchorAndDir(config.placement, wCSS * dpr, hCSS * dpr) + uniformDataRef.lightPos = anchor + uniformDataRef.lightDir = dir + }) + + return ( +
+ ) +} diff --git a/packages/console/app/src/config.ts b/packages/console/app/src/config.ts new file mode 100644 index 0000000000000000000000000000000000000000..78da7eba312095a13b7e83de4011710550b0be56 --- /dev/null +++ b/packages/console/app/src/config.ts @@ -0,0 +1,29 @@ +/** + * Application-wide constants and configuration + */ +export const config = { + // Base URL + baseUrl: "https://opencode.ai", + + // GitHub + github: { + repoUrl: "https://github.com/anomalyco/opencode", + starsFormatted: { + compact: "195K", + full: "195,000", + }, + }, + + // Social links + social: { + twitter: "https://x.com/opencode", + discord: "https://discord.gg/opencode", + }, + + // Static stats (used on landing page) + stats: { + contributors: "950", + commits: "13,000", + monthlyUsers: "16M", + }, +} as const diff --git a/packages/console/app/src/context/auth.session.ts b/packages/console/app/src/context/auth.session.ts new file mode 100644 index 0000000000000000000000000000000000000000..336ce12bb9106afdf843063ee67c0c1970f70d37 --- /dev/null +++ b/packages/console/app/src/context/auth.session.ts @@ -0,0 +1 @@ +export {} diff --git a/packages/console/app/src/context/auth.ts b/packages/console/app/src/context/auth.ts new file mode 100644 index 0000000000000000000000000000000000000000..90669d7647037686f2173e8c842e10ef05b9e38b --- /dev/null +++ b/packages/console/app/src/context/auth.ts @@ -0,0 +1,133 @@ +import { getRequestEvent } from "solid-js/web" +import { and, Database, eq, inArray, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js" +import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js" +import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js" +import { redirect } from "@solidjs/router" +import { Actor } from "@opencode-ai/console-core/actor.js" + +import { createClient } from "@openauthjs/openauth/client" + +export const AuthClient = createClient({ + clientID: "app", + issuer: import.meta.env.VITE_AUTH_URL, +}) + +import { useSession } from "@solidjs/start/http" +import { Resource } from "@opencode-ai/console-resource" + +export interface AuthSession { + account?: Record< + string, + { + id: string + email: string + } + > + current?: string +} + +export function useAuthSession() { + return useSession({ + password: Resource.ZEN_SESSION_SECRET.value, + name: "auth", + maxAge: 60 * 60 * 24 * 365, + cookie: { + secure: false, + httpOnly: true, + }, + }) +} + +export const getActor = async (workspace?: string): Promise => { + "use server" + const evt = getRequestEvent() + if (!evt) throw new Error("No request event") + if (evt.locals.actor) return evt.locals.actor + evt.locals.actor = (async () => { + const auth = await useAuthSession() + if (!workspace) { + const account = auth.data.account ?? {} + const current = account[auth.data.current ?? ""] + if (current) { + return { + type: "account", + properties: { + email: current.email, + accountID: current.id, + }, + } + } + if (Object.keys(account).length > 0) { + const current = Object.values(account)[0] + await auth.update((val) => ({ + ...val, + current: current.id, + })) + return { + type: "account", + properties: { + email: current.email, + accountID: current.id, + }, + } + } + return { + type: "public", + properties: {}, + } + } + const accounts = Object.keys(auth.data.account ?? {}) + if (accounts.length) { + const user = await Database.use((tx) => + tx + .select({ + id: UserTable.id, + workspaceID: UserTable.workspaceID, + accountID: UserTable.accountID, + role: UserTable.role, + migratedAt: WorkspaceTable.migrated_at, + }) + .from(UserTable) + .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, UserTable.workspaceID)) + .where( + and( + eq(UserTable.workspaceID, workspace), + isNull(UserTable.timeDeleted), + inArray(UserTable.accountID, accounts), + ), + ) + .limit(1) + .execute() + .then((x) => x[0]), + ) + if (user) { + if (user.migratedAt) { + const destination = Resource.ConsoleMigration.consoleUrl + if (!destination) throw new Error("New Console URL is not configured") + evt.response.headers.set("Cache-Control", "no-store") + throw redirect(`${destination}/login`, { + status: evt.request.method === "GET" || evt.request.method === "HEAD" ? 302 : 303, + headers: { "Cache-Control": "no-store" }, + }) + } + await Database.use((tx) => + tx + .update(UserTable) + .set({ timeSeen: sql`now()` }) + .where(and(eq(UserTable.workspaceID, workspace), eq(UserTable.id, user.id))), + ) + return { + type: "user", + properties: { + userID: user.id, + workspaceID: user.workspaceID, + accountID: user.accountID, + role: user.role, + }, + } + } + } + throw redirect("/auth/authorize") + })() + return evt.locals.actor +} diff --git a/packages/console/app/src/context/auth.withActor.ts b/packages/console/app/src/context/auth.withActor.ts new file mode 100644 index 0000000000000000000000000000000000000000..ff377cda4602688b64772896c03e332cf60272d2 --- /dev/null +++ b/packages/console/app/src/context/auth.withActor.ts @@ -0,0 +1,7 @@ +import { Actor } from "@opencode-ai/console-core/actor.js" +import { getActor } from "./auth" + +export async function withActor(fn: () => T, workspace?: string) { + const actor = await getActor(workspace) + return Actor.provide(actor.type, actor.properties, fn) +} diff --git a/packages/console/app/src/context/i18n.tsx b/packages/console/app/src/context/i18n.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5d178c8b8d97af2b91295f8f46b8fcd0aab39a23 --- /dev/null +++ b/packages/console/app/src/context/i18n.tsx @@ -0,0 +1,27 @@ +import { createMemo } from "solid-js" +import { createSimpleContext } from "@opencode-ai/ui/context" +import { i18n, type Key } from "~/i18n" +import { useLanguage } from "~/context/language" + +function resolve(text: string, params?: Record) { + if (!params) return text + return text.replace(/\{\{(\w+)\}\}/g, (raw, key) => { + const value = params[key] + if (value === undefined || value === null) return raw + return String(value) + }) +} + +export const { use: useI18n, provider: I18nProvider } = createSimpleContext({ + name: "I18n", + init: () => { + const language = useLanguage() + const dict = createMemo(() => i18n(language.locale())) + + return { + t(key: Key, params?: Record) { + return resolve(dict()[key], params) + }, + } + }, +}) diff --git a/packages/console/app/src/context/language.tsx b/packages/console/app/src/context/language.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2999242f0ffebc005c88fe534bfac903ad8c7aa9 --- /dev/null +++ b/packages/console/app/src/context/language.tsx @@ -0,0 +1,72 @@ +import { createEffect } from "solid-js" +import { createStore } from "solid-js/store" +import { getRequestEvent } from "solid-js/web" +import { createSimpleContext } from "@opencode-ai/ui/context" +import { + LOCALES, + type Locale, + clearCookie, + cookie, + detectFromLanguages, + dir as localeDir, + label as localeLabel, + localeFromCookieHeader, + localeFromRequest, + parseLocale, + route as localeRoute, + tag as localeTag, +} from "~/lib/language" + +function initial() { + const evt = getRequestEvent() + if (evt) return localeFromRequest(evt.request) + + if (typeof document === "object") { + const fromDom = parseLocale(document.documentElement.dataset.locale) + if (fromDom) return fromDom + + const fromCookie = localeFromCookieHeader(document.cookie) + if (fromCookie) return fromCookie + } + + if (typeof navigator !== "object") return "en" satisfies Locale + + const languages = navigator.languages?.length ? navigator.languages : [navigator.language] + return detectFromLanguages(languages) +} + +export const { use: useLanguage, provider: LanguageProvider } = createSimpleContext({ + name: "Language", + init: () => { + const [store, setStore] = createStore({ + locale: initial(), + }) + + createEffect(() => { + if (typeof document !== "object") return + document.documentElement.lang = localeTag(store.locale) + document.documentElement.dir = localeDir(store.locale) + document.documentElement.dataset.locale = store.locale + }) + + return { + locale: () => store.locale, + locales: LOCALES, + label: localeLabel, + tag: localeTag, + dir: localeDir, + route(pathname: string) { + return localeRoute(store.locale, pathname) + }, + setLocale(next: Locale) { + setStore("locale", next) + if (typeof document !== "object") return + document.cookie = cookie(next) + }, + clear() { + if (typeof document !== "object") return + document.cookie = clearCookie() + }, + } + }, +}) diff --git a/packages/console/app/src/entry-client.tsx b/packages/console/app/src/entry-client.tsx new file mode 100644 index 0000000000000000000000000000000000000000..642deacf73ccde2028a65010288a074f58bf9e10 --- /dev/null +++ b/packages/console/app/src/entry-client.tsx @@ -0,0 +1,4 @@ +// @refresh reload +import { mount, StartClient } from "@solidjs/start/client" + +mount(() => , document.getElementById("app")!) diff --git a/packages/console/app/src/entry-server.tsx b/packages/console/app/src/entry-server.tsx new file mode 100644 index 0000000000000000000000000000000000000000..619a1925d554b6b7940c269158dcd2d45ac765aa --- /dev/null +++ b/packages/console/app/src/entry-server.tsx @@ -0,0 +1,37 @@ +// @refresh reload +import { createHandler, StartServer } from "@solidjs/start/server" +import { getRequestEvent } from "solid-js/web" +import { dir, localeFromRequest, tag } from "~/lib/language" + +const criticalCSS = `[data-component="top"]{min-height:80px;display:flex;align-items:center}` + +export default createHandler( + () => ( + { + const evt = getRequestEvent() + const locale = evt ? localeFromRequest(evt.request) : "en" + + return ( + + + + + + + + {assets} + + +
{children}
+ {scripts} + + + ) + }} + /> + ), + { + mode: "async", + }, +) diff --git a/packages/console/app/src/global.d.ts b/packages/console/app/src/global.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..4c2b0a1700e1b48eef7848fe6a37cde2a2a13d2a --- /dev/null +++ b/packages/console/app/src/global.d.ts @@ -0,0 +1,5 @@ +/// + +export declare module "@solidjs/start/server" { + export type APIEvent = { request: Request } +} diff --git a/packages/console/app/src/i18n/ar.ts b/packages/console/app/src/i18n/ar.ts new file mode 100644 index 0000000000000000000000000000000000000000..fac1d6475833662eac0bf2096ea24f6acf96260b --- /dev/null +++ b/packages/console/app/src/i18n/ar.ts @@ -0,0 +1,865 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "يحصل DeepSeek V4.1 Flash على حدود استخدام مضاعفة 4 مرات لفترة محدودة", + "go.graph.bonus": "استخدام مضاعف {{count}} مرات", + "nav.github": "GitHub", + "nav.docs": "الوثائق", + "nav.changelog": "سجل التغييرات", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "المؤسسات", + "nav.zen": "Zen", + "nav.login": "تسجيل الدخول", + "nav.free": "تحميل", + "nav.home": "الرئيسية", + "nav.openMenu": "فتح القائمة", + "nav.getStartedFree": "ابدأ مجانا", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "نسخ الشعار كـ SVG", + "nav.context.copyWordmark": "نسخ اسم العلامة كـ SVG", + "nav.context.brandAssets": "أصول العلامة التجارية", + + "footer.github": "GitHub", + "footer.docs": "الوثائق", + "footer.changelog": "سجل التغييرات", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "العلامة التجارية", + "legal.privacy": "الخصوصية", + "legal.terms": "الشروط", + + "email.title": "كن الأول في المعرفة عند إطلاق منتجات جديدة", + "email.subtitle": "انضم إلى قائمة الانتظار للحصول على وصول مبكر.", + "email.placeholder": "عنوان البريد الإلكتروني", + "email.subscribe": "اشتراك", + "email.success": "تبقّت خطوة واحدة: تحقق من بريدك وأكّد عنوانك", + + "notFound.title": "غير موجود | opencode", + "notFound.heading": "404 - الصفحة غير موجودة", + "notFound.home": "الرئيسية", + "notFound.docs": "الوثائق", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "شعار opencode الفاتح", + "notFound.logoDarkAlt": "شعار opencode الداكن", + + "user.logout": "تسجيل الخروج", + + "auth.callback.error.codeMissing": "لم يتم العثور على رمز التفويض.", + + "workspace.select": "اختر مساحة العمل", + "workspace.createNew": "+ إنشاء مساحة عمل جديدة", + "workspace.modal.title": "إنشاء مساحة عمل جديدة", + "workspace.modal.placeholder": "أدخل اسم مساحة العمل", + + "common.cancel": "إلغاء", + "common.creating": "جارٍ الإنشاء...", + "common.create": "إنشاء", + "common.contactUs": "اتصل بنا", + + "common.videoUnsupported": "متصفحك لا يدعم وسم الفيديو.", + "common.figure": "شكل {{n}}.", + "common.faq": "الأسئلة الشائعة", + "common.learnMore": "اعرف المزيد", + + "error.invalidPlan": "خطة غير صالحة", + "error.workspaceRequired": "معرف مساحة العمل مطلوب", + "error.alreadySubscribed": "مساحة العمل هذه لديها اشتراك بالفعل", + "error.limitRequired": "الحد مطلوب.", + "error.monthlyLimitInvalid": "قم بتعيين حد شهري صالح.", + "error.workspaceNameRequired": "اسم مساحة العمل مطلوب.", + "error.nameTooLong": "يجب أن يكون الاسم 255 حرفًا أو أقل.", + "error.emailRequired": "البريد الإلكتروني مطلوب", + "error.roleRequired": "الدور مطلوب", + "error.idRequired": "المعرف مطلوب", + "error.nameRequired": "الاسم مطلوب", + "error.providerRequired": "المزود مطلوب", + "error.apiKeyRequired": "مفتاح API مطلوب", + "error.modelRequired": "النموذج مطلوب", + "error.reloadAmountMin": "يجب أن يكون مبلغ الشحن ${{amount}} على الأقل", + "error.reloadTriggerMin": "يجب أن يكون حد الرصيد ${{amount}} على الأقل", + + "app.meta.description": "OpenCode - وكيل البرمجة مفتوح المصدر.", + + "home.title": "OpenCode | وكيل برمجة بالذكاء الاصطناعي مفتوح المصدر", + + "temp.title": "opencode | وكيل برمجة بالذكاء الاصطناعي مبني للطرفية", + "temp.hero.title": "وكيل البرمجة بالذكاء الاصطناعي المبني للطرفية", + "temp.zen": "opencode zen", + "temp.getStarted": "ابدأ", + "temp.feature.native.title": "واجهة طرفية أصلية", + "temp.feature.native.body": "واجهة مستخدم طرفية سريعة الاستجابة، أصلية، وقابلة للتخصيص", + "temp.feature.zen.beforeLink": "قائمة", + "temp.feature.zen.link": "منسقة من النماذج", + "temp.feature.zen.afterLink": "مقدمة من opencode", + "temp.feature.models.beforeLink": "يدعم أكثر من 75 مزود LLM من خلال", + "temp.feature.models.afterLink": "، بما في ذلك النماذج المحلية", + "temp.screenshot.caption": "واجهة OpenCode الطرفية مع سمة tokyonight", + "temp.screenshot.alt": "واجهة OpenCode الطرفية بسمة tokyonight", + "temp.logoLightAlt": "شعار opencode الفاتح", + "temp.logoDarkAlt": "شعار opencode الداكن", + + "home.banner.badge": "جديد", + "home.banner.text": "نقدّم علامات التبويب لتطبيق سطح المكتب.", + "home.banner.platforms": "متاحة على macOS وWindows وLinux", + "home.banner.downloadNow": "حمّل الآن", + "home.banner.downloadBetaNow": "حمّل النسخة التجريبية لتطبيق سطح المكتب الآن", + "home.promo.title": "نقدّم علامات التبويب لتطبيق سطح المكتب", + "home.promo.body": "نظّم عملك وجلساتك النشطة باستخدام علامات التبويب.", + "home.promo.cta": "نزّل أحدث إصدار للبدء.", + "home.promo.close": "إغلاق إعلان تطبيق سطح المكتب", + + "home.hero.title": "وكيل برمجة بالذكاء الاصطناعي مفتوح المصدر", + "home.hero.subtitle.a": "نماذج مجانية مضمّنة أو اربط أي نموذج من أي مزوّد،", + "home.hero.subtitle.b": "بما في ذلك Claude، GPT، Gemini وغيرها.", + + "home.install.ariaLabel": "خيارات التثبيت", + + "home.what.title": "ما هو OpenCode؟", + "home.what.body": "OpenCode وكيل مفتوح المصدر يساعدك على كتابة الكود في الطرفية، IDE، أو سطح المكتب.", + "home.what.lsp.title": "دعم LSP", + "home.what.lsp.body": "يحمّل تلقائيًا موافقات LSP المناسبة للـ LLM", + "home.what.multiSession.title": "جلسات متعددة", + "home.what.multiSession.body": "ابدأ عدة وكلاء بالتوازي على نفس المشروع", + "home.what.shareLinks.title": "روابط المشاركة", + "home.what.shareLinks.body": "شارك رابطًا لأي جلسة للرجوع إليها أو لتصحيح الأخطاء", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "سجّل الدخول بـ GitHub لاستخدام حسابك في Copilot", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "سجّل الدخول بـ OpenAI لاستخدام حسابك في ChatGPT Plus أو Pro", + "home.what.anyModel.title": "أي نموذج", + "home.what.anyModel.body": "75+ مزوّد LLM عبر Models.dev، بما في ذلك النماذج المحلية", + "home.what.anyEditor.title": "أي محرر", + "home.what.anyEditor.body": "متاح كواجهة طرفية، وتطبيق سطح مكتب، وامتداد IDE", + "home.what.readDocs": "اقرأ الوثائق", + + "home.growth.title": "وكيل برمجة بالذكاء الاصطناعي مفتوح المصدر", + "home.growth.body": + "مع أكثر من {{stars}} نجمة على GitHub، و{{contributors}} مساهمًا، وأكثر من {{commits}} Commit، يستخدم OpenCode ويثق به أكثر من {{monthlyUsers}} مطوّر كل شهر.", + "home.growth.githubStars": "نجوم GitHub", + "home.growth.contributors": "المساهمون", + "home.growth.monthlyDevs": "مطورون شهريًا", + + "home.privacy.title": "مصمم للخصوصية أولاً", + "home.privacy.body": "لا يخزّن OpenCode أي كود أو بيانات سياق، ليتمكن من العمل في بيئات حساسة للخصوصية.", + "home.privacy.learnMore": "اعرف المزيد عن", + "home.privacy.link": "الخصوصية", + + "home.faq.q1": "ما هو OpenCode؟", + "home.faq.a1": + "OpenCode وكيل مفتوح المصدر يساعدك على كتابة وتشغيل الكود مع أي نموذج ذكاء اصطناعي. متاح كواجهة طرفية، وتطبيق سطح مكتب، أو امتداد IDE.", + "home.faq.q2": "كيف أستخدم OpenCode؟", + "home.faq.a2.before": "أسهل طريقة للبدء هي قراءة", + "home.faq.a2.link": "المقدمة", + "home.faq.q3": "هل أحتاج لاشتراكات ذكاء اصطناعي إضافية لاستخدام OpenCode؟", + "home.faq.a3.p1": + "ليس بالضرورة، فـ OpenCode يأتي مع مجموعة من النماذج المجانية التي تستطيع استخدامها دون إنشاء حساب.", + "home.faq.a3.p2.beforeZen": "وبخلاف ذلك، يمكنك استخدام أي من نماذج البرمجة الشائعة بإنشاء حساب", + "home.faq.a3.p2.afterZen": ".", + "home.faq.a3.p3": + "مع أننا نشجّع المستخدمين على استخدام Zen، فإن OpenCode يعمل أيضًا مع كل المزودين الشائعين مثل OpenAI، Anthropic، xAI إلخ.", + "home.faq.a3.p4.beforeLocal": "ويمكنك أيضًا ربط", + "home.faq.a3.p4.localLink": "النماذج المحلية", + "home.faq.q4": "هل يمكنني استخدام اشتراكاتي الحالية مع OpenCode؟", + "home.faq.a4.p1": + "نعم، يدعم OpenCode خطط الاشتراك من كل المزودين الرئيسيين. يمكنك استخدام اشتراكات Claude Pro/Max، ChatGPT Plus/Pro، أو GitHub Copilot.", + "home.faq.q5": "هل يمكنني استخدام OpenCode في الطرفية فقط؟", + "home.faq.a5.beforeDesktop": "ليس بعد الآن! OpenCode متاح الآن كتطبيق لـ", + "home.faq.a5.desktop": "سطح المكتب", + "home.faq.a5.and": "و", + "home.faq.a5.web": "الويب", + "home.faq.q6": "كم تكلفة OpenCode؟", + "home.faq.a6": + "OpenCode مجاني 100% للاستخدام. كما يأتي مع مجموعة من النماذج المجانية. قد توجد تكاليف إضافية إذا ربطت مزوّدًا آخر.", + "home.faq.q7": "ماذا عن البيانات والخصوصية؟", + "home.faq.a7.p1": "لا يتم تخزين بياناتك ومعلوماتك إلا عندما تستخدم نماذجنا المجانية أو تنشئ روابط قابلة للمشاركة.", + "home.faq.a7.p2.beforeModels": "اعرف المزيد عن", + "home.faq.a7.p2.modelsLink": "نماذجنا", + "home.faq.a7.p2.and": "و", + "home.faq.a7.p2.shareLink": "صفحات المشاركة", + "home.faq.q8": "هل OpenCode مفتوح المصدر؟", + "home.faq.a8.p1": "نعم، OpenCode مفتوح المصدر بالكامل. الكود المصدري متاح علنًا على", + "home.faq.a8.p2": "بموجب", + "home.faq.a8.mitLicense": "رخصة MIT", + "home.faq.a8.p3": + "، مما يعني أن أي شخص يستطيع استخدامه أو تعديله أو المساهمة في تطويره. يمكن لأي شخص من المجتمع فتح قضايا، وتقديم طلبات سحب، وتوسيع الوظائف.", + + "home.zenCta.title": "وصول لنماذج محسنة وموثوقة لوكلاء البرمجة", + "home.zenCta.body": + "يمنحك Zen الوصول إلى مجموعة مختارة بعناية من نماذج الذكاء الاصطناعي التي اختبرها OpenCode وقاس أداءها خصيصًا لوكلاء البرمجة. لا حاجة للقلق بشأن اختلاف الأداء والجودة بين المزودين، استخدم نماذج محققة تعمل بكفاءة.", + "home.zenCta.link": "تعرف على Zen", + + "zen.title": "OpenCode Zen | مجموعة منسقة من النماذج المحسنة والموثوقة لوكلاء البرمجة", + "zen.hero.title": "نماذج محسنة وموثوقة لوكلاء البرمجة", + "zen.hero.body": + "يمنحك Zen الوصول إلى مجموعة منسقة من نماذج الذكاء الاصطناعي التي اختبرها OpenCode وقاس أداءها خصيصًا لوكلاء البرمجة. لا حاجة للقلق بشأن اختلاف الأداء والجودة، استخدم نماذج محققة تعمل بكفاءة.", + + "zen.faq.q1": "ما هو OpenCode Zen؟", + "zen.faq.a1": + "Zen هو مجموعة منسقة من نماذج الذكاء الاصطناعي التي تم اختبارها وقياس أدائها لوكلاء البرمجة، أنشأها الفريق المطور لـ OpenCode.", + "zen.faq.q2": "ما الذي يجعل Zen أكثر دقة؟", + "zen.faq.a2": + "يوفر Zen فقط النماذج التي تم اختبارها وقياس أدائها خصيصًا لوكلاء البرمجة. لن تستخدم سكين زبدة لقطع شريحة لحم، فلا تستخدم نماذج ضعيفة للبرمجة.", + "zen.faq.q3": "هل Zen أرخص؟", + "zen.faq.a3": + "Zen ليس للربح. يمرر Zen التكاليف من مزودي النماذج إليك مباشرة. كلما زاد استخدام Zen، تمكن OpenCode من التفاوض على أسعار أفضل وتمريرها إليك.", + "zen.faq.q4": "كم تكلفة Zen؟", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "يحاسب لكل طلب", + "zen.faq.a4.p1.afterPricing": "بدون أي هوامش ربح، لذا تدفع بالضبط ما يفرضه مزود النموذج.", + "zen.faq.a4.p2.beforeAccount": "تعتمد تكلفتك الإجمالية على الاستخدام، ويمكنك تعيين حدود إنفاق شهرية في", + "zen.faq.a4.p2.accountLink": "حسابك", + "zen.faq.a4.p3": + "لتغطية التكاليف، يضيف OpenCode فقط رسومًا صغيرة لمعالجة الدفع قدرها 1.23 دولار لكل إعادة شحن رصيد بقيمة 20 دولارًا.", + "zen.faq.q5": "ماذا عن البيانات والخصوصية؟", + "zen.faq.a5.beforeExceptions": + "تتم استضافة جميع نماذج Zen في الولايات المتحدة. يتبع المزودون سياسة عدم الاحتفاظ بالبيانات ولا يستخدمون بياناتك لتدريب النماذج، مع", + "zen.faq.a5.exceptionsLink": "الاستثناءات التالية", + "zen.faq.q6": "هل يمكنني تعيين حدود للإنفاق؟", + "zen.faq.a6": "نعم، يمكنك تعيين حدود إنفاق شهرية في حسابك.", + "zen.faq.q7": "هل يمكنني الإلغاء؟", + "zen.faq.a7": "نعم، يمكنك تعطيل الفوترة في أي وقت واستخدام رصيدك المتبقي.", + "zen.faq.q8": "هل يمكنني استخدام Zen مع وكلاء برمجة آخرين؟", + "zen.faq.a8": + "بينما يعمل Zen بشكل رائع مع OpenCode، يمكنك استخدام Zen مع أي وكيل. اتبع تعليمات الإعداد في وكيل البرمجة المفضل لديك.", + "zen.faq.q9": "هل يمكنني استرداد أموالي؟", + "zen.faq.a9": + "قد تكون مؤهلًا لاسترداد أموالك إذا تم الخصم خلال آخر 14 يومًا ولم تستخدم الرصيد الناتج عن عملية الشراء هذه. {{contact}} لطلب استرداد الأموال.", + + "zen.cta.start": "ابدأ مع Zen", + "zen.pricing.title": "أضف رصيد 20 دولار (دفع حسب الاستخدام)", + "zen.pricing.fee": "(+1.23 دولار رسوم معالجة البطاقة)", + "zen.pricing.body": "استخدمه مع أي وكيل. عيّن حدود الإنفاق الشهري. ألغِ في أي وقت.", + "zen.problem.title": "ما المشكلة التي يحلها Zen؟", + "zen.problem.body": + "هناك العديد من النماذج المتاحة، ولكن القليل منها فقط يعمل بشكل جيد مع وكلاء البرمجة. يقوم معظم مقدمي الخدمة بتكوينها بشكل مختلف مما يعطي نتائج متفاوتة.", + "zen.problem.subtitle": "نحن نعمل على إصلاح هذا للجميع، وليس فقط لمستخدمي OpenCode.", + "zen.problem.item1": "اختبار نماذج مختارة واستشارة فرقها", + "zen.problem.item2": "العمل مع مقدمي الخدمة لضمان تسليمها بشكل صحيح", + "zen.problem.item3": "قياس أداء جميع مجموعات النماذج والمزودين التي نوصي بها", + "zen.how.title": "كيف يعمل Zen", + "zen.how.body": "بينما نقترح عليك استخدام Zen مع OpenCode، يمكنك استخدام Zen مع أي وكيل.", + "zen.how.step1.title": "سجّل وأضف رصيدًا بقيمة 20 دولارًا", + "zen.how.step1.beforeLink": "اتبع", + "zen.how.step1.link": "تعليمات الإعداد", + "zen.how.step2.title": "استخدم Zen بتسعير شفاف", + "zen.how.step2.link": "ادفع لكل طلب", + "zen.how.step2.afterLink": "بدون أي هوامش ربح", + "zen.how.step3.title": "شحن تلقائي", + "zen.how.step3.body": "عندما يصل رصيدك إلى 5 دولارات، سنضيف تلقائيًا 20 دولارًا", + "zen.privacy.title": "خصوصيتك مهمة بالنسبة لنا", + "zen.privacy.beforeExceptions": + "تتم استضافة جميع نماذج Zen في الولايات المتحدة. يتبع المزودون سياسة عدم الاحتفاظ بالبيانات ولا يستخدمون بياناتك لتدريب النماذج، مع", + "zen.privacy.exceptionsLink": "الاستثناءات التالية", + + "go.title": "OpenCode Go | نماذج برمجة منخفضة التكلفة للجميع", + "go.meta.description": "يبلغ سعر Go ‏$10/شهر، مع حدود استخدام سخية ووصول موثوق إلى نماذج البرمجة الرائدة.", + "go.hero.title": "نماذج برمجة منخفضة التكلفة للجميع", + "go.hero.body": + "يجلب Go البرمجة الوكيلة للمبرمجين حول العالم. يوفر حدودًا سخية ووصولًا موثوقًا إلى أقوى النماذج مفتوحة المصدر، حتى تتمكن من البناء باستخدام وكلاء أقوياء دون القلق بشأن التكلفة أو التوفر.", + + "go.cta.start": "اشترك في Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "اشترك في Go", + "go.cta.price": "$10/شهر", + "go.pricing.body": "استخدمه مع أي وكيل. $10/شهر. قم بزيادة الرصيد إذا لزم الأمر. الإلغاء في أي وقت.", + "go.graph.free": "مجاني", + "go.graph.freePill": "Big Pickle ونماذج مجانية", + "go.graph.go": "Go", + "go.graph.label": "الطلبات كل 5 ساعات", + "go.graph.period": "الاستخدام", + "go.graph.model": "النموذج", + "go.graph.requests": "الطلبات المقدّرة / ٥ ساعات", + "go.graph.allowance": "الاستخدام الشهري", + "go.graph.new": "جديد", + "go.graph.scale": "مقياس غير خطي لعدد الطلبات", + "go.graph.showAll": "عرض جميع النماذج ({{count}})", + "go.graph.showLess": "عرض نماذج أقل", + "go.graph.limitedRegions": "مناطق محدودة", + "go.graph.limitedTime": "لفترة محدودة", + "go.graph.usageLimits": "حدود الاستخدام", + "go.graph.aria": "الطلبات كل 5 ساعات: {{free}} مقابل {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "الرئيس التنفيذي السابق، منتجات Terminal", + "go.testimonials.dax.quoteAfter": "كان تغييرًا جذريًا في الحياة، إنه قرار لا يحتاج لتفكير.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "مؤسس سابق، SEED، PM، Melt، Pop، Dapt، Cadmus، وViewPoint", + "go.testimonials.jay.quoteBefore": "4 من كل 5 أشخاص في فريقنا يحبون استخدام", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "بطل سابق، AWS", + "go.testimonials.adam.quoteBefore": "لا أستطيع التوصية بـ", + "go.testimonials.adam.quoteAfter": "بما فيه الكفاية. بجدية، إنه جيد حقًا.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "رئيس التصميم السابق، Laravel", + "go.testimonials.david.quoteBefore": "مع", + "go.testimonials.david.quoteAfter": "أعلم أن جميع النماذج مختبرة ومثالية لوكلاء البرمجة.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "متدرب سابق، Nvidia (4 مرات)", + "go.testimonials.frank.quote": "أتمنى لو كنت لا أزال في Nvidia.", + "go.problem.title": "ما المشكلة التي يحلها Go؟", + "go.problem.body": + "نحن نركز على تقديم تجربة OpenCode لأكبر عدد ممكن من الناس. OpenCode Go هو اشتراك منخفض التكلفة بسعر $10/شهر. يوفر حدودا سخية ووصولا موثوقا إلى نماذج المصدر المفتوح الأكثر قدرة.", + "go.problem.subtitle": " ", + "go.problem.item1": "أسعار اشتراك منخفضة التكلفة", + "go.problem.item2": "حدود سخية ووصول موثوق", + "go.problem.item3": "مصمم لأكبر عدد ممكن من المبرمجين", + "go.problem.item4": "مجموعة منسقة من النماذج المختبرة للبرمجة الوكيلة", + "go.how.title": "كيف يعمل Go", + "go.how.body": "يبلغ سعر Go ‏$10/شهر. يمكنك استخدامه مع OpenCode أو أي وكيل.", + "go.how.step1.title": "أنشئ حسابًا", + "go.how.step1.beforeLink": "اتبع", + "go.how.step1.link": "تعليمات الإعداد", + "go.how.step2.title": "اشترك في Go", + "go.how.step2.link": "$10/شهر", + "go.how.step2.afterLink": "مع حدود سخية", + "go.how.step3.title": "ابدأ البرمجة", + "go.how.step3.body": "مع وصول موثوق لنماذج مفتوحة المصدر", + "go.privacy.title": "خصوصيتك مهمة بالنسبة لنا", + "go.privacy.body": + "تم تصميم الخطة بشكل أساسي للمستخدمين الدوليين، مع استضافة النماذج في الولايات المتحدة والاتحاد الأوروبي وسنغافورة للحصول على وصول عالمي مستقر.", + "go.privacy.contactAfter": "إذا كان لديك أي أسئلة.", + "go.privacy.beforeExceptions": + "تتم استضافة نماذج Go في الولايات المتحدة. يتبع المزودون سياسة عدم الاحتفاظ بالبيانات ولا يستخدمون بياناتك لتدريب النماذج، مع", + "go.privacy.exceptionsLink": "الاستثناءات التالية", + "go.faq.q1": "ما هو OpenCode Go؟", + "go.faq.a1": "Go هو اشتراك منخفض التكلفة يمنحك وصولًا موثوقًا إلى نماذج مفتوحة المصدر قادرة على البرمجة الوكيلة.", + "go.faq.q2": "ما النماذج التي يتضمنها Go؟", + "go.faq.a2": "يتضمن Go النماذج المدرجة أدناه، مع حدود سخية وإتاحة موثوقة.", + "go.faq.q3": "هل Go هو نفسه Zen؟", + "go.faq.a3": + "لا. يعتمد Zen على الدفع حسب الاستخدام، بينما يبلغ سعر Go ‏$10/شهر، مع حدود سخية ووصول موثوق إلى مجموعة منسقة من النماذج.", + "go.faq.q4": "كم تكلفة Go؟", + "go.faq.a4.p1.beforePricing": "تكلفة Go", + "go.faq.a4.p1.pricingLink": "$10/شهر", + "go.faq.a4.p1.afterPricing": "مع حدود سخية.", + "go.faq.a4.p2.beforeAccount": "يمكنك إدارة اشتراكك في", + "go.faq.a4.p2.accountLink": "حسابك", + "go.faq.a4.p3": "ألغِ في أي وقت.", + "go.faq.q5": "ماذا عن البيانات والخصوصية؟", + "go.faq.a5.model": "النموذج", + "go.faq.a5.training": "تدريب النموذج", + "go.faq.a5.retention": "الاحتفاظ بالبيانات", + "go.faq.a5.retention30": "30 يومًا", + "go.faq.a5.retention0": "0 أيام", + "go.faq.a5.used": "مستخدَمة", + "go.faq.a5.notUsed": "غير مستخدَمة", + "go.faq.a5.noAgreement": "لا توجد اتفاقية", + "go.faq.a5.notZdr": "ليست ZDR", + "go.faq.a5.grokRetention": + "تعطّل ZDR ميزات API مهمة تعتمد على البيانات المخزنة، بما في ذلك Responses API ذات الحالة، وFiles and Collections، وBatch API.", + "go.faq.a5.gptRetention": + "تُنشأ سجلات مراقبة إساءة الاستخدام لكل استخدام لميزات API، ويُحتفظ بها لمدة تصل إلى 30 يومًا.", + "go.faq.a5.museRetention": + "أسعار توكنات مخفّضة للغاية مقابل منح الإذن باستخدام مطالباتك وإكمالات النموذج لتدريب نماذج Meta المستقبلية.", + "go.faq.a5.learnMore": "اعرف المزيد", + "go.faq.a5.deepseekRetention": "تُجدَّد اتفاقية ZDR شهريًا. الاتفاقية الحالية سارية حتى 30 سبتمبر 2026.", + "go.faq.a5.beforeExceptions": + "تتم استضافة نماذج Go في الولايات المتحدة. يتبع المزودون سياسة عدم الاحتفاظ بالبيانات ولا يستخدمون بياناتك لتدريب النماذج، مع", + "go.faq.a5.exceptionsLink": "الاستثناءات التالية", + "go.faq.q6": "هل يمكنني شحن رصيد إضافي؟", + "go.faq.a6": "إذا كنت بحاجة إلى مزيد من الاستخدام، يمكنك شحن رصيد في حسابك.", + "go.faq.q7": "هل يمكنني الإلغاء؟", + "go.faq.a7": "نعم، يمكنك الإلغاء في أي وقت.", + "go.faq.q8": "هل يمكنني استخدام Go مع وكلاء برمجة آخرين؟", + "go.faq.a8": "نعم، يمكنك استخدام Go مع أي وكيل. اتبع تعليمات الإعداد في وكيل البرمجة المفضل لديك.", + + "go.faq.q9": "ما الفرق بين النماذج المجانية وGo؟", + "go.faq.a9": + "تشمل النماذج المجانية Big Pickle بالإضافة إلى النماذج الترويجية المتاحة في ذلك الوقت، مع حصة قدرها 200 طلب/يوم. يقدّم Go مجموعة منسقة من النماذج مع حصص طلبات أعلى مطبقة عبر نوافذ متجددة (5 ساعات، وأسبوعية، وشهرية)، تعادل الحصص الأساسية فيها تقريبًا $12 لكل 5 ساعات و$30 في الأسبوع و$60 في الشهر؛ وقد تختلف الحصص حسب النموذج (تختلف أعداد الطلبات الفعلية حسب النموذج والاستخدام).", + "go.faq.q10": "هل يمكنني استرداد أموالي؟", + "go.faq.a10": + "قد تكون مؤهلًا لاسترداد أموالك إذا تم الخصم خلال آخر 14 يومًا ولم تستخدم مخصصات Go خلال فترة الفوترة تلك. {{contact}} لطلب استرداد الأموال.", + + "zen.api.error.rateLimitExceeded": "تم تجاوز حد الطلبات. يرجى المحاولة مرة أخرى لاحقًا.", + "zen.api.error.modelNotSupported": "النموذج {{model}} غير مدعوم", + "zen.api.error.modelFormatNotSupported": "النموذج {{model}} غير مدعوم للتنسيق {{format}}", + "zen.api.error.noProviderAvailable": "لا يوجد مزود متاح", + "zen.api.error.providerNotSupported": "المزود {{provider}} غير مدعوم", + "zen.api.error.missingApiKey": "مفتاح API مفقود.", + "zen.api.error.invalidApiKey": "مفتاح API غير صالح.", + "zen.api.error.requestBlockedByUpstreamProvider": "حظر المزود الخارجي الطلب.", + "zen.api.error.subscriptionQuotaExceeded": "تم تجاوز حصة الاشتراك. أعد المحاولة خلال {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "تم الوصول إلى حد الاستخدام لمدة 5 ساعات. تتم إعادة التعيين خلال {{retryIn}}. لمواصلة استخدام هذا النموذج الآن، فعّل الاستخدام من رصيدك المتاح: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "تم الوصول إلى حد الاستخدام الأسبوعي. تتم إعادة التعيين خلال {{retryIn}}. لمواصلة استخدام هذا النموذج الآن، فعّل الاستخدام من رصيدك المتاح: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "تم الوصول إلى حد الاستخدام الشهري. تتم إعادة التعيين خلال {{retryIn}}. لمواصلة استخدام هذا النموذج الآن، فعّل الاستخدام من رصيدك المتاح: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "لا توجد طريقة دفع. أضف طريقة دفع هنا: {{billingUrl}}", + "zen.api.error.insufficientBalance": "رصيد غير كاف. إدارة فواتيرك هنا: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "وصلت مساحة العمل الخاصة بك إلى حد الإنفاق الشهري البالغ ${{amount}}. إدارة حدودك هنا: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "لقد وصلت إلى حد الإنفاق الشهري البالغ ${{amount}}. إدارة حدودك هنا: {{membersUrl}}", + "zen.api.error.modelDisabled": "النموذج معطل", + "zen.api.error.regionNotAllowed": + "لا يتوفر أحدث إصدار من هذا النموذج إلا مستضافًا في الصين، ويتطلب تفعيلًا صريحًا: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "هذا النموذج غير متاح في بلدك.", + "zen.api.error.trainingNotAllowed": + "يجمع هذا النموذج بيانات تُستخدم لتحسين جودته، ويتطلب موافقتك الصريحة: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "انتهى العرض المجاني لـ {{model}}. يمكنك مواصلة استخدام النموذج بالاشتراك في OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | الوصول إلى أفضل نماذج البرمجة في العالم", + "black.meta.description": "احصل على وصول إلى Claude، GPT، Gemini والمزيد مع خطط اشتراك OpenCode Black.", + "black.hero.title": "الوصول إلى أفضل نماذج البرمجة في العالم", + "black.hero.subtitle": "بما في ذلك Claude، GPT، Gemini والمزيد", + "black.title": "OpenCode Black | الأسعار", + "black.paused": "التسجيل في خطة Black متوقف مؤقتًا.", + "black.plan.icon20": "خطة Black 20", + "black.plan.icon100": "خطة Black 100", + "black.plan.icon200": "خطة Black 200", + "black.plan.multiplier100": "استخدام أكثر بـ 5 أضعاف من Black 20", + "black.plan.multiplier200": "استخدام أكثر بـ 20 ضعفًا من Black 20", + "black.price.perMonth": "شهريًا", + "black.price.perPersonBilledMonthly": "للشخص الواحد، يُفوتر شهريًا", + "black.terms.1": "لن يبدأ اشتراكك على الفور", + "black.terms.2": "ستتم إضافتك إلى قائمة الانتظار وتفعيلك قريبًا", + "black.terms.3": "لن يتم خصم المبلغ من بطاقتك إلا عند تفعيل اشتراكك", + "black.terms.4": "تطبق حدود الاستخدام، وقد يصل الاستخدام المؤتمت بكثافة إلى الحدود بشكل أسرع", + "black.terms.5": "الاشتراكات للأفراد، تواصل مع قسم المؤسسات للفرق", + "black.terms.6": "قد يتم تعديل الحدود وقد يتم إيقاف الخطط في المستقبل", + "black.terms.7": "ألغِ اشتراكك في أي وقت", + "black.action.continue": "متابعة", + "black.finePrint.beforeTerms": "الأسعار المعروضة لا تشمل الضرائب المطبقة", + "black.finePrint.terms": "شروط الخدمة", + "black.workspace.title": "OpenCode Black | اختر مساحة العمل", + "black.workspace.selectPlan": "اختر مساحة عمل لهذه الخطة", + "black.workspace.name": "مساحة العمل {{n}}", + "black.subscribe.title": "اشترك في OpenCode Black", + "black.subscribe.paymentMethod": "طريقة الدفع", + "black.subscribe.loadingPaymentForm": "جارٍ تحميل نموذج الدفع...", + "black.subscribe.selectWorkspaceToContinue": "اختر مساحة عمل للمتابعة", + "black.subscribe.failurePrefix": "أوه لا!", + "black.subscribe.error.generic": "حدث خطأ", + "black.subscribe.error.invalidPlan": "خطة غير صالحة", + "black.subscribe.error.workspaceRequired": "معرف مساحة العمل مطلوب", + "black.subscribe.error.alreadySubscribed": "مساحة العمل هذه لديها اشتراك بالفعل", + "black.subscribe.processing": "جارٍ المعالجة...", + "black.subscribe.submit": "اشترك بمبلغ ${{plan}}", + "black.subscribe.form.chargeNotice": "لن يتم خصم المبلغ إلا عند تفعيل اشتراكك", + "black.subscribe.success.title": "أنت في قائمة انتظار OpenCode Black", + "black.subscribe.success.subscriptionPlan": "خطة الاشتراك", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "المبلغ", + "black.subscribe.success.amountValue": "${{plan}} شهريًا", + "black.subscribe.success.paymentMethod": "طريقة الدفع", + "black.subscribe.success.dateJoined": "تاريخ الانضمام", + "black.subscribe.success.chargeNotice": "سيتم خصم المبلغ من بطاقتك عند تفعيل اشتراكك", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "الاستخدام", + "workspace.nav.apiKeys": "مفاتيح API", + "workspace.nav.members": "الأعضاء", + "workspace.nav.billing": "الفوترة", + "workspace.nav.settings": "الإعدادات", + + "workspace.home.banner.beforeLink": "نماذج محسنة وموثوقة لوكلاء البرمجة.", + "workspace.lite.banner.beforeLink": "نماذج برمجة منخفضة التكلفة للجميع.", + "workspace.home.billing.loading": "جارٍ التحميل...", + "workspace.home.billing.enable": "تمكين الفوترة", + "workspace.home.billing.currentBalance": "الرصيد الحالي", + + "workspace.newUser.feature.tested.title": "نماذج مُختبرة ومحققة", + "workspace.newUser.feature.tested.body": "لقد قمنا بقياس واختبار النماذج خصيصًا لوكلاء البرمجة لضمان أفضل أداء.", + "workspace.newUser.feature.quality.title": "أعلى جودة", + "workspace.newUser.feature.quality.body": + "الوصول إلى النماذج التي تم تكوينها لتحقيق الأداء الأمثل - لا تقليل للجودة أو توجيه إلى موفري خدمة أرخص.", + "workspace.newUser.feature.lockin.title": "لا قيود على المزود", + "workspace.newUser.feature.lockin.body": + "استخدم Zen مع أي وكيل برمجة، واستمر في استخدام موفرين آخرين مع opencode وقتما تشاء.", + "workspace.newUser.copyApiKey": "نسخ مفتاح API", + "workspace.newUser.copyKey": "نسخ المفتاح", + "workspace.newUser.copied": "تم النسخ!", + "workspace.newUser.step.enableBilling": "تمكين الفوترة", + "workspace.newUser.step.login.before": "شغّل", + "workspace.newUser.step.login.after": "واختر opencode", + "workspace.newUser.step.pasteKey": "الصق مفتاح API الخاص بك", + "workspace.newUser.step.models.before": "ابدأ opencode ثم نفّذ", + "workspace.newUser.step.models.after": "لاختيار نموذج", + + "workspace.models.title": "النماذج", + "workspace.models.subtitle.beforeLink": "إدارة النماذج التي يمكن لأعضاء مساحة العمل الوصول إليها.", + "workspace.models.table.model": "النموذج", + "workspace.models.table.enabled": "ممكّن", + + "workspace.providers.title": "أحضر مفتاحك الخاص", + "workspace.providers.subtitle": "قم بتكوين مفاتيح API الخاصة بك من موفري الذكاء الاصطناعي.", + "workspace.providers.placeholder": "أدخل مفتاح API لـ {{provider}} ({{prefix}}...)", + "workspace.providers.configure": "تكوين", + "workspace.providers.edit": "تعديل", + "workspace.providers.delete": "حذف", + "workspace.providers.saving": "جارٍ الحفظ...", + "workspace.providers.save": "حفظ", + "workspace.providers.table.provider": "المزود", + "workspace.providers.table.apiKey": "مفتاح API", + + "workspace.usage.title": "تاريخ الاستخدام", + "workspace.usage.subtitle": "استخدام وتكاليف API الأخيرة.", + "workspace.usage.empty": "قم بإجراء أول استدعاء API للبدء.", + "workspace.usage.table.date": "التاريخ", + "workspace.usage.table.model": "النموذج", + "workspace.usage.table.input": "الدخل", + "workspace.usage.table.output": "الخرج", + "workspace.usage.table.cost": "التكلفة", + "workspace.usage.table.session": "الجلسة", + "workspace.usage.breakdown.input": "الدخل", + "workspace.usage.breakdown.cacheRead": "قراءة الكاش", + "workspace.usage.breakdown.cacheWrite": "كتابة الكاش", + "workspace.usage.breakdown.output": "الخرج", + "workspace.usage.breakdown.reasoning": "المنطق", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "التكلفة", + "workspace.cost.subtitle": "تكاليف الاستخدام مقسمة حسب النموذج.", + "workspace.cost.allModels": "جميع النماذج", + "workspace.cost.allKeys": "جميع المفاتيح", + "workspace.cost.deletedSuffix": "(محذوف)", + "workspace.cost.empty": "لا توجد بيانات استخدام متاحة للفترة المحددة.", + "workspace.cost.subscriptionShort": "اشتراك", + + "workspace.keys.title": "مفاتيح API", + "workspace.keys.subtitle": "إدارة مفاتيح API الخاصة بك للوصول إلى خدمات opencode.", + "workspace.keys.create": "إنشاء مفتاح API", + "workspace.keys.placeholder": "أدخل اسم المفتاح", + "workspace.keys.empty": "أنشئ مفتاح API لبوابة opencode", + "workspace.keys.table.name": "الاسم", + "workspace.keys.table.key": "المفتاح", + "workspace.keys.table.createdBy": "تم الإنشاء بواسطة", + "workspace.keys.table.lastUsed": "آخر استخدام", + "workspace.keys.copyApiKey": "نسخ مفتاح API", + "workspace.keys.delete": "حذف", + + "workspace.members.title": "الأعضاء", + "workspace.members.subtitle": "إدارة أعضاء مساحة العمل وأذوناتهم.", + "workspace.members.invite": "دعوة عضو", + "workspace.members.inviting": "جارٍ الدعوة...", + "workspace.members.beta.beforeLink": "مساحات العمل مجانية للفرق أثناء الفترة التجريبية.", + "workspace.members.form.invitee": "المدعو", + "workspace.members.form.emailPlaceholder": "أدخل البريد الإلكتروني", + "workspace.members.form.role": "الدور", + "workspace.members.form.monthlyLimit": "حد الإنفاق الشهري", + "workspace.members.noLimit": "لا يوجد حد", + "workspace.members.noLimitLowercase": "لا يوجد حد", + "workspace.members.invited": "تمت دعوته", + "workspace.members.edit": "تعديل", + "workspace.members.delete": "حذف", + "workspace.members.saving": "جارٍ الحفظ...", + "workspace.members.save": "حفظ", + "workspace.members.table.email": "البريد الإلكتروني", + "workspace.members.table.role": "الدور", + "workspace.members.table.monthLimit": "الحد الشهري", + "workspace.members.role.admin": "مسؤول", + "workspace.members.role.adminDescription": "يمكنه إدارة النماذج، والأعضاء، والفوترة", + "workspace.members.role.member": "عضو", + "workspace.members.role.memberDescription": "يمكنه فقط إنشاء مفاتيح API لنفسه", + + "workspace.settings.title": "الإعدادات", + "workspace.settings.subtitle": "حدّث اسم مساحة العمل وتفضيلاتك.", + "workspace.settings.workspaceName": "اسم مساحة العمل", + "workspace.settings.defaultName": "افتراضي", + "workspace.settings.updating": "جارٍ التحديث...", + "workspace.settings.save": "حفظ", + "workspace.settings.edit": "تعديل", + + "workspace.billing.title": "الفوترة", + "workspace.billing.subtitle.beforeLink": "إدارة طرق الدفع.", + "workspace.billing.contactUs": "اتصل بنا", + "workspace.billing.subtitle.afterLink": "إذا كان لديك أي أسئلة.", + "workspace.billing.currentBalance": "الرصيد الحالي", + "workspace.billing.add": "أضف $", + "workspace.billing.enterAmount": "أدخل المبلغ", + "workspace.billing.loading": "جارٍ التحميل...", + "workspace.billing.addAction": "إضافة", + "workspace.billing.addBalance": "إضافة رصيد", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "مرتبط بـ Stripe", + "workspace.billing.manage": "إدارة", + "workspace.billing.enable": "تمكين الفوترة", + + "workspace.monthlyLimit.title": "الحد الشهري", + "workspace.monthlyLimit.subtitle": "عيّن حد الاستخدام الشهري لحسابك.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "جارٍ التعيين...", + "workspace.monthlyLimit.set": "تعيين", + "workspace.monthlyLimit.edit": "تعديل الحد", + "workspace.monthlyLimit.noLimit": "لم يتم تعيين حد للاستخدام.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "الاستخدام الحالي لـ", + "workspace.monthlyLimit.currentUsage.beforeAmount": "هو $", + + "workspace.redeem.title": "استرداد قسيمة", + "workspace.redeem.subtitle": "استرد رمز القسيمة للحصول على رصيد أو مزايا.", + "workspace.redeem.placeholder": "أدخل رمز القسيمة", + "workspace.redeem.redeem": "استرداد", + "workspace.redeem.redeeming": "جارٍ الاسترداد...", + "workspace.redeem.success": "تم استرداد القسيمة بنجاح.", + + "workspace.reload.title": "إعادة الشحن التلقائي", + "workspace.reload.disabled.before": "إعادة الشحن التلقائي", + "workspace.reload.disabled.state": "معطّل", + "workspace.reload.disabled.after": "فعّلها لإعادة شحن الرصيد تلقائيًا عندما ينخفض.", + "workspace.reload.enabled.before": "إعادة الشحن التلقائي", + "workspace.reload.enabled.state": "ممكّن", + "workspace.reload.enabled.middle": "سنعيد شحن رصيدك بمبلغ", + "workspace.reload.processingFee": "رسوم معالجة", + "workspace.reload.enabled.after": "عندما يصل الرصيد إلى", + "workspace.reload.edit": "تعديل", + "workspace.reload.enable": "تفعيل", + "workspace.reload.enableAutoReload": "تفعيل إعادة الشحن التلقائي", + "workspace.reload.reloadAmount": "مبلغ الشحن $", + "workspace.reload.whenBalanceReaches": "عندما يصل الرصيد إلى $", + "workspace.reload.saving": "جارٍ الحفظ...", + "workspace.reload.save": "حفظ", + "workspace.reload.failedAt": "فشلت إعادة الشحن في", + "workspace.reload.reason": "السبب:", + "workspace.reload.updatePaymentMethod": "يرجى تحديث طريقة الدفع والمحاولة مرة أخرى.", + "workspace.reload.retrying": "جارٍ إعادة المحاولة...", + "workspace.reload.retry": "أعد المحاولة", + "workspace.reload.error.paymentFailed": "فشلت عملية الدفع.", + + "workspace.payments.title": "سجل المدفوعات", + "workspace.payments.subtitle": "معاملات الدفع الأخيرة.", + "workspace.payments.table.date": "التاريخ", + "workspace.payments.table.paymentId": "معرف الدفع", + "workspace.payments.table.amount": "المبلغ", + "workspace.payments.table.receipt": "الإيصال", + "workspace.payments.type.credit": "رصيد", + "workspace.payments.type.subscription": "اشتراك", + "workspace.payments.view": "عرض", + + "workspace.black.loading": "جارٍ التحميل...", + "workspace.black.time.day": "يوم", + "workspace.black.time.days": "أيام", + "workspace.black.time.hour": "ساعة", + "workspace.black.time.hours": "ساعات", + "workspace.black.time.minute": "دقيقة", + "workspace.black.time.minutes": "دقائق", + "workspace.black.time.fewSeconds": "بضع ثوان", + "workspace.black.subscription.title": "الاشتراك", + "workspace.black.subscription.message": "أنت مشترك في OpenCode Black مقابل ${{plan}} شهريًا.", + "workspace.black.subscription.manage": "إدارة الاشتراك", + "workspace.black.subscription.rollingUsage": "استخدام لمدة 5 ساعات", + "workspace.black.subscription.weeklyUsage": "الاستخدام الأسبوعي", + "workspace.black.subscription.resetsIn": "إعادة تعيين في", + "workspace.black.subscription.useBalance": "استخدم رصيدك المتوفر بعد الوصول إلى حدود الاستخدام", + "workspace.black.waitlist.title": "قائمة الانتظار", + "workspace.black.waitlist.joined": "أنت في قائمة الانتظار لخطة OpenCode Black بقيمة ${{plan}} شهريًا.", + "workspace.black.waitlist.ready": "نحن مستعدون لتسجيلك في خطة OpenCode Black بقيمة ${{plan}} شهريًا.", + "workspace.black.waitlist.leave": "ترك قائمة الانتظار", + "workspace.black.waitlist.leaving": "جارٍ المغادرة...", + "workspace.black.waitlist.left": "غادر", + "workspace.black.waitlist.enroll": "تسجيل", + "workspace.black.waitlist.enrolling": "جارٍ التسجيل...", + "workspace.black.waitlist.enrolled": "مسجل", + "workspace.black.waitlist.enrollNote": 'عند النقر فوق "تسجيل"، يبدأ اشتراكك على الفور وسيتم خصم الرسوم من بطاقتك.', + + "workspace.lite.loading": "جارٍ التحميل...", + "workspace.lite.time.day": "يوم", + "workspace.lite.time.days": "أيام", + "workspace.lite.time.hour": "ساعة", + "workspace.lite.time.hours": "ساعات", + "workspace.lite.time.minute": "دقيقة", + "workspace.lite.time.minutes": "دقائق", + "workspace.lite.time.fewSeconds": "بضع ثوان", + "workspace.lite.subscription.message": "أنت مشترك في OpenCode Go.", + "workspace.lite.subscription.manage": "إدارة الاشتراك", + "workspace.lite.subscription.rollingUsage": "الاستخدام خلال 5 ساعات", + "workspace.lite.subscription.rollingQuota": "الحصة خلال 5 ساعات", + "workspace.lite.subscription.weeklyUsage": "الاستخدام الأسبوعي", + "workspace.lite.subscription.weeklyQuota": "الحصة الأسبوعية", + "workspace.lite.subscription.monthlyUsage": "الاستخدام الشهري", + "workspace.lite.subscription.monthlyQuota": "الحصة الشهرية", + "workspace.lite.subscription.resetsIn": "إعادة تعيين في", + "workspace.lite.subscription.showDetails": "إظهار التفاصيل", + "workspace.lite.subscription.hideDetails": "إخفاء التفاصيل", + "workspace.lite.subscription.model": "النموذج", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "الإجمالي", + "workspace.lite.subscription.useBalance": "استخدم رصيدك المتوفر بعد الوصول إلى حدود الاستخدام", + "workspace.lite.subscription.selectProvider": + 'اختر "OpenCode Go" كمزود في إعدادات opencode الخاصة بك لاستخدام نماذج Go.', + "workspace.lite.providers.title": "المزودون", + "workspace.lite.providers.description": "تحكم في المزودين المستخدمين للتوجيه.", + "workspace.lite.providers.allowTraining": "السماح بالنماذج التي تتدرب على بيانات الطلبات", + "workspace.lite.providers.useChina": "تفعيل النماذج المستضافة في الصين", + "workspace.lite.black.message": + "أنت مشترك حاليًا في OpenCode Black أو في قائمة الانتظار. يرجى إلغاء الاشتراك أولاً إذا كنت ترغب في التبديل إلى Go.", + "workspace.lite.other.message": + "عضو آخر في مساحة العمل هذه مشترك بالفعل في OpenCode Go. يمكن لعضو واحد فقط لكل مساحة عمل الاشتراك.", + "workspace.lite.promo.description": + "يبلغ سعر OpenCode Go {{price}}، ويوفر وصولا موثوقا لنماذج البرمجة المفتوحة الشهيرة مع حدود استخدام سخية.", + "workspace.lite.promo.price": "$10/شهر", + "workspace.lite.promo.modelsTitle": "ما يتضمنه", + "workspace.lite.promo.footer": + "صُممت الخطة بشكل أساسي للمستخدمين الدوليين، وتوفر وصولًا عالميًا مستقرًا. قد تتغير الأسعار وحدود الاستخدام بينما نتعلم من الاستخدام المبكر والملاحظات.", + "workspace.lite.promo.subscribe": "الاشتراك في Go", + "workspace.lite.promo.subscribing": "جارٍ إعادة التوجيه...", + "workspace.lite.promo.otherMethods": "طرق دفع أخرى", + "workspace.lite.promo.selectMethod": "اختر طريقة الدفع", + + "workspace.referral.copyLink": "نسخ الرابط", + "workspace.referral.copied": "تم النسخ", + "workspace.referral.overview.title": "ادعُ أصدقاءك", + "workspace.referral.overview.subtitle": "احصل على $5 عند اشتراك صديق. وسيحصل هو أيضًا على $5.", + "workspace.referral.instructions.share": "شارك رابط الإحالة الخاص بك", + "workspace.referral.instructions.subscribe": "ينضم صديقك ويشترك في Go", + "workspace.referral.instructions.claim": "تحصلان كلاكما على رصيد استخدام بقيمة $5 لتطبيقه على حدود استخدام Go", + "workspace.referral.rewards.title": "مكافآت الإحالة", + "workspace.referral.rewards.description": "طبّق أرصدة الإحالة المتاحة على استخدامك لـ Go.", + "workspace.referral.rewards.subtitle": "تم تطبيق {{applied}} / {{total}} من المكافآت.", + "workspace.referral.rewards.empty": "لا توجد مكافآت إحالة بعد.", + "workspace.referral.table.reward": "المكافأة", + "workspace.referral.table.referral": "الوصف", + "workspace.referral.table.date": "التاريخ", + "workspace.referral.reward.description.inviter": "تمت دعوة {{email}}", + "workspace.referral.reward.description.invitee": "تمت دعوتك بواسطة {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "اشترك لإلغاء القفل", + "workspace.referral.reward.action.view": "عرض المكافأة", + "workspace.referral.reward.action.applied": "تم تطبيق المكافأة", + "workspace.referral.reward.source.pendingInviter": "بانتظار اشتراكه", + "workspace.referral.reward.source.pendingInvitee": "اشترك لإلغاء قفل المكافأة", + "workspace.referral.reward.source.available": "المكافأة جاهزة للتطبيق", + "workspace.referral.reward.source.applied": "تم تطبيق المكافأة", + "workspace.referral.reward.status.applied": "تم تطبيق المكافأة", + "workspace.referral.reward.status.pendingInviter": "اشترك لإلغاء القفل", + "workspace.referral.reward.status.pendingInvitee": "اشترك لإلغاء القفل", + "workspace.referral.apply.noGo": "اشترك لإلغاء القفل", + "workspace.referral.apply.preview": "عرض المكافأة", + "workspace.referral.apply.action": "تطبيق", + "workspace.referral.apply.confirmTitle": "تطبيق المكافأة", + "workspace.referral.apply.confirmBody": "طبِّق {{amount}} لتقليل الاستخدام الحالي في مساحة العمل هذه.", + "workspace.referral.apply.confirmAction": "تطبيق", + + "download.title": "OpenCode | تنزيل", + "download.meta.description": "نزّل OpenCode لـ macOS، Windows، وLinux", + "download.hero.title": "تنزيل OpenCode لسطح المكتب", + "download.hero.subtitle": "متاح في نسخة تجريبية لـ macOS، Windows، وLinux", + "download.hero.button": "تنزيل لـ {{os}}", + "download.section.terminal": "OpenCode للطرفية", + "download.section.desktop": "OpenCode لسطح المكتب", + "download.section.extensions": "امتدادات OpenCode", + "download.section.integrations": "تكاملات OpenCode", + "download.action.download": "تنزيل", + "download.action.install": "تثبيت", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "ليس بالضرورة، ولكن على الأرجح. ستحتاج إلى اشتراك ذكاء اصطناعي إذا كنت تريد ربط OpenCode بمزوّد مدفوع، رغم أنه يمكنك العمل مع", + "download.faq.a3.localLink": "النماذج المحلية", + "download.faq.a3.afterLocal.beforeZen": "مجانًا. بينما نشجع المستخدمين على استخدام", + "download.faq.a3.afterZen": "، فإن OpenCode يعمل مع جميع المزودين الشائعين مثل OpenAI، Anthropic، xAI إلخ.", + + "download.faq.a5.p1": "OpenCode مجاني 100% للاستخدام.", + "download.faq.a5.p2.beforeZen": + "أي تكاليف إضافية ستأتي من اشتراكك لدى مزود النماذج. بينما يعمل OpenCode مع أي مزود نماذج، نوصي باستخدام", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": "يتم حفظ بياناتك ومعلوماتك فقط عند إنشاء روابط قابلة للمشاركة في OpenCode.", + "download.faq.a6.p2.beforeShare": "اعرف المزيد عن", + "download.faq.a6.shareLink": "صفحات المشاركة", + + "enterprise.title": "OpenCode | حلول المؤسسات لمنظمتك", + "enterprise.meta.description": "تواصل مع OpenCode لحلول المؤسسات", + "enterprise.hero.title": "كودك ملكك", + "enterprise.hero.body1": + "يعمل OpenCode بأمان داخل مؤسستك دون تخزين أي بيانات أو سياق، ودون قيود ترخيص أو مطالبات ملكية. ابدأ تجربة مع فريقك، ثم انشره عبر مؤسستك من خلال دمجه مع SSO وبوابة الذكاء الاصطناعي الداخلية لديك.", + "enterprise.hero.body2": "أخبرنا كيف يمكننا المساعدة.", + "enterprise.form.name.label": "الاسم الكامل", + "enterprise.form.name.placeholder": "جيف بيزوس", + "enterprise.form.role.label": "المنصب", + "enterprise.form.role.placeholder": "رئيس مجلس الإدارة التنفيذي", + "enterprise.form.company.label": "الشركة", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "البريد الإلكتروني للشركة", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "رقم الهاتف", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "ما المشكلة التي تحاول حلها؟", + "enterprise.form.message.placeholder": "نحتاج مساعدة في...", + "enterprise.form.send": "إرسال", + "enterprise.form.sending": "جارٍ الإرسال...", + "enterprise.form.success": "تم إرسال الرسالة، سنتواصل معك قريبًا.", + "enterprise.form.success.submitted": "تم إرسال النموذج بنجاح.", + "enterprise.form.error.allFieldsRequired": "جميع الحقول مطلوبة.", + "enterprise.form.error.invalidEmailFormat": "تنسيق البريد الإلكتروني غير صالح.", + "enterprise.form.error.internalServer": "خطأ داخلي في الخادم.", + "enterprise.faq.title": "الأسئلة الشائعة", + "enterprise.faq.q1": "ما هو OpenCode Enterprise؟", + "enterprise.faq.a1": + "OpenCode Enterprise مخصص للمؤسسات التي تريد التأكد من أن الكود والبيانات لا تغادر بنيتها التحتية أبدًا. يتحقق ذلك عبر استخدام تكوين مركزي يندمج مع SSO وبوابة الذكاء الاصطناعي الداخلية لديك.", + "enterprise.faq.q2": "كيف أبدأ مع OpenCode Enterprise؟", + "enterprise.faq.a2": + "ابدأ ببساطة بتجربة داخلية مع فريقك. افتراضيًا، لا يقوم OpenCode بتخزين الكود أو بيانات السياق، مما يجعل البدء سهلاً. ثم اتصل بنا لمناقشة الأسعار وخيارات التنفيذ.", + "enterprise.faq.q3": "كيف تعمل تسعيرة المؤسسات؟", + "enterprise.faq.a3": + "نقدم تسعيرًا للمؤسسات حسب المقعد. إذا كان لديك بوابة LLM خاصة بك، فلن نفرض رسومًا على التوكنات المستخدمة. لمزيد من التفاصيل، اتصل بنا للحصول على عرض سعر مخصص بناءً على احتياجات مؤسستك.", + "enterprise.faq.q4": "هل بياناتي آمنة مع OpenCode Enterprise؟", + "enterprise.faq.a4": + "نعم. لا يقوم OpenCode بتخزين الكود أو بيانات السياق. تتم جميع المعالجة محليًا أو عبر استدعاءات API مباشرة إلى مزود الذكاء الاصطناعي لديك. مع التكوين المركزي وتكامل SSO، تظل بياناتك آمنة داخل البنية التحتية لمؤسستك.", + + "brand.title": "OpenCode | العلامة التجارية", + "brand.meta.description": "إرشادات العلامة التجارية لـ OpenCode", + "brand.heading": "إرشادات العلامة التجارية", + "brand.subtitle": "موارد وأصول لمساعدتك في العمل مع العلامة التجارية لـ OpenCode.", + "brand.downloadAll": "تنزيل جميع الأصول", + + "changelog.title": "OpenCode | سجل التغييرات", + "changelog.meta.description": "ملاحظات الإصدار وسجل التغييرات لـ OpenCode", + "changelog.hero.title": "سجل التغييرات", + "changelog.hero.subtitle": "تحديثات وتحسينات جديدة لـ OpenCode", + "changelog.empty": "لم يتم العثور على مدخلات في سجل التغييرات.", + "changelog.viewJson": "عرض JSON", + + "bench.list.title": "المعيار", + "bench.list.heading": "المعايير", + "bench.list.table.agent": "الوكيل", + "bench.list.table.model": "النموذج", + "bench.list.table.score": "الدرجة", + "bench.submission.error.allFieldsRequired": "جميع الحقول مطلوبة.", + + "bench.detail.title": "المعيار - {{task}}", + "bench.detail.notFound": "المهمة غير موجودة", + "bench.detail.na": "غير متاح", + "bench.detail.labels.agent": "الوكيل", + "bench.detail.labels.model": "النموذج", + "bench.detail.labels.task": "المهمة", + "bench.detail.labels.repo": "المستودع", + "bench.detail.labels.from": "من", + "bench.detail.labels.to": "إلى", + "bench.detail.labels.prompt": "الموجه", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "متوسط المدة", + "bench.detail.labels.averageScore": "متوسط الدرجة", + "bench.detail.labels.averageCost": "متوسط التكلفة", + "bench.detail.labels.summary": "الملخص", + "bench.detail.labels.runs": "تشغيلات", + "bench.detail.labels.score": "الدرجة", + "bench.detail.labels.base": "الأساس", + "bench.detail.labels.penalty": "الجزاء", + "bench.detail.labels.weight": "الوزن", + "bench.detail.table.run": "تشغيل", + "bench.detail.table.score": "الدرجة (الأساس - الجزاء)", + "bench.detail.table.cost": "التكلفة", + "bench.detail.table.duration": "المدة", + "bench.detail.run.title": "تشغيل {{n}}", + "bench.detail.rawJson": "JSON خام", +} satisfies Dict diff --git a/packages/console/app/src/i18n/br.ts b/packages/console/app/src/i18n/br.ts new file mode 100644 index 0000000000000000000000000000000000000000..a2e5867a63dcceae11a1c12933fa4378f84f5576 --- /dev/null +++ b/packages/console/app/src/i18n/br.ts @@ -0,0 +1,880 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash tem limites de uso 4x maiores por tempo limitado", + "go.graph.bonus": "{{count}}× mais uso", + "nav.github": "GitHub", + "nav.docs": "Documentação", + "nav.changelog": "Changelog", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Entrar", + "nav.free": "Download", + "nav.home": "Início", + "nav.openMenu": "Abrir menu", + "nav.getStartedFree": "Começar grátis", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Copiar logo como SVG", + "nav.context.copyWordmark": "Copiar marca como SVG", + "nav.context.brandAssets": "Recursos da marca", + + "footer.github": "GitHub", + "footer.docs": "Documentação", + "footer.changelog": "Changelog", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Marca", + "legal.privacy": "Privacidade", + "legal.terms": "Termos", + + "email.title": "Seja o primeiro a saber quando lançarmos novos produtos", + "email.subtitle": "Entre na lista de espera para acesso antecipado.", + "email.placeholder": "Endereço de e-mail", + "email.subscribe": "Inscrever-se", + "email.success": "Quase lá, verifique sua caixa de entrada e confirme seu e-mail", + + "notFound.title": "Não encontrado | opencode", + "notFound.heading": "404 - Página não encontrada", + "notFound.home": "Início", + "notFound.docs": "Documentação", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "logo opencode claro", + "notFound.logoDarkAlt": "logo opencode escuro", + + "user.logout": "Sair", + + "auth.callback.error.codeMissing": "Nenhum código de autorização encontrado.", + + "workspace.select": "Selecionar workspace", + "workspace.createNew": "+ Criar novo workspace", + "workspace.modal.title": "Criar novo workspace", + "workspace.modal.placeholder": "Digite o nome do workspace", + + "common.cancel": "Cancelar", + "common.creating": "Criando...", + "common.create": "Criar", + "common.contactUs": "Contate-nos", + + "common.videoUnsupported": "Seu navegador não suporta a tag de vídeo.", + "common.figure": "Fig {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Saiba mais", + + "error.invalidPlan": "Plano inválido", + "error.workspaceRequired": "ID do workspace é obrigatório", + "error.alreadySubscribed": "Este workspace já possui uma assinatura", + "error.limitRequired": "Limite é obrigatório.", + "error.monthlyLimitInvalid": "Defina um limite mensal válido.", + "error.workspaceNameRequired": "Nome do workspace é obrigatório.", + "error.nameTooLong": "O nome deve ter 255 caracteres ou menos.", + "error.emailRequired": "E-mail é obrigatório", + "error.roleRequired": "Função é obrigatória", + "error.idRequired": "ID é obrigatório", + "error.nameRequired": "Nome é obrigatório", + "error.providerRequired": "Provedor é obrigatório", + "error.apiKeyRequired": "Chave de API é obrigatória", + "error.modelRequired": "Modelo é obrigatório", + "error.reloadAmountMin": "O valor de recarga deve ser de pelo menos ${{amount}}", + "error.reloadTriggerMin": "O gatilho de saldo deve ser de pelo menos ${{amount}}", + + "app.meta.description": "OpenCode - O agente de codificação de código aberto.", + + "home.title": "OpenCode | O agente de codificação de código aberto com IA", + + "temp.title": "opencode | Agente de codificação com IA feito para o terminal", + "temp.hero.title": "O agente de codificação com IA feito para o terminal", + "temp.zen": "opencode zen", + "temp.getStarted": "Começar", + "temp.feature.native.title": "TUI Nativa", + "temp.feature.native.body": "Uma interface de terminal responsiva, nativa e personalizável", + "temp.feature.zen.beforeLink": "Uma", + "temp.feature.zen.link": "lista selecionada de modelos", + "temp.feature.zen.afterLink": "fornecida pela opencode", + "temp.feature.models.beforeLink": "Suporta mais de 75 provedores de LLM através do", + "temp.feature.models.afterLink": ", incluindo modelos locais", + "temp.screenshot.caption": "OpenCode TUI com o tema tokyonight", + "temp.screenshot.alt": "OpenCode TUI com tema tokyonight", + "temp.logoLightAlt": "logo opencode claro", + "temp.logoDarkAlt": "logo opencode escuro", + + "home.banner.badge": "Novo", + "home.banner.text": "Conheça as abas no app desktop.", + "home.banner.platforms": "Disponível no macOS, Windows e Linux", + "home.banner.downloadNow": "Baixar agora", + "home.banner.downloadBetaNow": "Baixe agora o beta do desktop", + "home.promo.title": "Conheça as abas no app desktop", + "home.promo.body": "Organize seu trabalho e suas sessões ativas com abas.", + "home.promo.cta": "Baixe a versão mais recente para começar.", + "home.promo.close": "Fechar anúncio do app desktop", + + "home.hero.title": "O agente de codificação de código aberto com IA", + "home.hero.subtitle.a": "Modelos grátis incluídos ou conecte qualquer modelo de qualquer provedor,", + "home.hero.subtitle.b": "incluindo Claude, GPT, Gemini e mais.", + + "home.install.ariaLabel": "Opções de instalação", + + "home.what.title": "O que é OpenCode?", + "home.what.body": + "OpenCode é um agente de código aberto que ajuda você a escrever código no seu terminal, IDE ou desktop.", + "home.what.lsp.title": "LSP habilitado", + "home.what.lsp.body": "Carrega automaticamente os LSPs certos para o LLM", + "home.what.multiSession.title": "Multissessão", + "home.what.multiSession.body": "Inicie vários agentes em paralelo no mesmo projeto", + "home.what.shareLinks.title": "Links compartilháveis", + "home.what.shareLinks.body": "Compartilhe um link para qualquer sessão para referência ou depuração", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Entre com o GitHub para usar sua conta do Copilot", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Entre com a OpenAI para usar sua conta do ChatGPT Plus ou Pro", + "home.what.anyModel.title": "Qualquer modelo", + "home.what.anyModel.body": "Mais de 75 provedores de LLM via Models.dev, incluindo modelos locais", + "home.what.anyEditor.title": "Qualquer editor", + "home.what.anyEditor.body": "Disponível como interface de terminal, app desktop e extensão de IDE", + "home.what.readDocs": "Ler documentação", + + "home.growth.title": "O agente de codificação de código aberto com IA", + "home.growth.body": + "Com mais de {{stars}} estrelas no GitHub, {{contributors}} colaboradores e mais de {{commits}} commits, OpenCode é usado e confiado por mais de {{monthlyUsers}} desenvolvedores todos os meses.", + "home.growth.githubStars": "Estrelas no GitHub", + "home.growth.contributors": "Colaboradores", + "home.growth.monthlyDevs": "Devs mensais", + + "home.privacy.title": "Feito com privacidade em primeiro lugar", + "home.privacy.body": + "OpenCode não armazena nenhum código seu nem dados de contexto, para que possa operar em ambientes sensíveis à privacidade.", + "home.privacy.learnMore": "Saiba mais sobre", + "home.privacy.link": "privacidade", + + "home.faq.q1": "O que é OpenCode?", + "home.faq.a1": + "OpenCode é um agente de código aberto que ajuda você a escrever e executar código com qualquer modelo de IA. Está disponível como interface de terminal, app desktop ou extensão de IDE.", + "home.faq.q2": "Como eu uso o OpenCode?", + "home.faq.a2.before": "A maneira mais fácil de começar é ler a", + "home.faq.a2.link": "introdução", + "home.faq.q3": "Preciso de assinaturas extras de IA para usar o OpenCode?", + "home.faq.a3.p1": + "Não necessariamente, OpenCode vem com um conjunto de modelos grátis que você pode usar sem criar conta.", + "home.faq.a3.p2.beforeZen": + "Além disso, você pode usar qualquer um dos modelos de codificação populares criando uma conta", + "home.faq.a3.p2.afterZen": ".", + "home.faq.a3.p3": + "Embora incentivemos os usuários a usar o Zen, OpenCode também funciona com todos os provedores populares, como OpenAI, Anthropic, xAI etc.", + "home.faq.a3.p4.beforeLocal": "Você pode até conectar seus", + "home.faq.a3.p4.localLink": "modelos locais", + "home.faq.q4": "Posso usar minhas assinaturas de IA existentes com o OpenCode?", + "home.faq.a4.p1": + "Sim, OpenCode suporta planos de assinatura de todos os principais provedores. Você pode usar suas assinaturas Claude Pro/Max, ChatGPT Plus/Pro ou GitHub Copilot.", + "home.faq.q5": "Posso usar o OpenCode apenas no terminal?", + "home.faq.a5.beforeDesktop": "Não mais! OpenCode agora está disponível como um app para o seu", + "home.faq.a5.desktop": "desktop", + "home.faq.a5.and": "e", + "home.faq.a5.web": "web", + "home.faq.q6": "Quanto custa o OpenCode?", + "home.faq.a6": + "OpenCode é 100% gratuito para usar. Ele também vem com um conjunto de modelos gratuitos. Pode haver custos adicionais se você conectar qualquer outro provedor.", + "home.faq.q7": "E sobre dados e privacidade?", + "home.faq.a7.p1": + "Seus dados e informações só são armazenados quando você usa nossos modelos gratuitos ou cria links compartilháveis.", + "home.faq.a7.p2.beforeModels": "Saiba mais sobre", + "home.faq.a7.p2.modelsLink": "nossos modelos", + "home.faq.a7.p2.and": "e", + "home.faq.a7.p2.shareLink": "páginas de compartilhamento", + "home.faq.q8": "OpenCode é código aberto?", + "home.faq.a8.p1": "Sim, OpenCode é totalmente open source. O código-fonte é público no", + "home.faq.a8.p2": "sob a", + "home.faq.a8.mitLicense": "Licença MIT", + "home.faq.a8.p3": + ", o que significa que qualquer pessoa pode usar, modificar ou contribuir para o seu desenvolvimento. Qualquer pessoa da comunidade pode abrir issues, enviar pull requests e estender a funcionalidade.", + + "home.zenCta.title": "Acesse modelos confiáveis e otimizados para agentes de codificação", + "home.zenCta.body": + "O Zen dá acesso a um conjunto selecionado de modelos de IA que a OpenCode testou e avaliou especificamente para agentes de codificação. Não precisa se preocupar com desempenho e qualidade inconsistentes entre provedores, use modelos validados que funcionam.", + "home.zenCta.link": "Saiba mais sobre o Zen", + + "zen.title": "OpenCode Zen | Um conjunto selecionado de modelos confiáveis e otimizados para agentes de codificação", + "zen.hero.title": "Modelos confiáveis e otimizados para agentes de codificação", + "zen.hero.body": + "O Zen dá acesso a um conjunto selecionado de modelos de IA que a OpenCode testou e avaliou especificamente para agentes de codificação. Não precisa se preocupar com desempenho e qualidade inconsistentes, use modelos validados que funcionam.", + + "zen.faq.q1": "O que é OpenCode Zen?", + "zen.faq.a1": + "Zen é um conjunto selecionado de modelos de IA testados e avaliados para agentes de codificação, criado pela equipe por trás do OpenCode.", + "zen.faq.q2": "O que torna o Zen mais preciso?", + "zen.faq.a2": + "O Zen fornece apenas modelos que foram especificamente testados e avaliados para agentes de codificação. Você não usaria uma faca de manteiga para cortar um bife, não use modelos ruins para programar.", + "zen.faq.q3": "O Zen é mais barato?", + "zen.faq.a3": + "O Zen não tem fins lucrativos. O Zen repassa os custos dos provedores de modelos para você. Quanto maior o uso do Zen, mais a OpenCode pode negociar melhores taxas e repassá-las para você.", + "zen.faq.q4": "Quanto custa o Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "cobra por requisição", + "zen.faq.a4.p1.afterPricing": "sem margens de lucro, então você paga exatamente o que o provedor do modelo cobra.", + "zen.faq.a4.p2.beforeAccount": "Seu custo total depende do uso, e você pode definir limites de gastos mensais em sua", + "zen.faq.a4.p2.accountLink": "conta", + "zen.faq.a4.p3": + "Para cobrir custos, a OpenCode adiciona apenas uma pequena taxa de processamento de pagamento de $1,23 por recarga de $20.", + "zen.faq.q5": "E sobre dados e privacidade?", + "zen.faq.a5.beforeExceptions": + "Todos os modelos Zen são hospedados nos EUA. Os provedores seguem uma política de retenção zero e não usam seus dados para treinamento de modelos, com as", + "zen.faq.a5.exceptionsLink": "seguintes exceções", + "zen.faq.q6": "Posso definir limites de gastos?", + "zen.faq.a6": "Sim, você pode definir limites de gastos mensais em sua conta.", + "zen.faq.q7": "Posso cancelar?", + "zen.faq.a7": "Sim, você pode desativar o faturamento a qualquer momento e usar seu saldo restante.", + "zen.faq.q8": "Posso usar o Zen com outros agentes de codificação?", + "zen.faq.a8": + "Embora o Zen funcione muito bem com o OpenCode, você pode usar o Zen com qualquer agente. Siga as instruções de configuração no seu agente de codificação preferido.", + "zen.faq.q9": "Posso receber um reembolso?", + "zen.faq.a9": + "Você pode ter direito a um reembolso se a cobrança foi feita nos últimos 14 dias e você não usou os créditos dessa compra. {{contact}} para solicitar um reembolso.", + + "zen.cta.start": "Comece com o Zen", + "zen.pricing.title": "Adicionar $20 de saldo pré-pago", + "zen.pricing.fee": "(+$1,23 taxa de processamento do cartão)", + "zen.pricing.body": "Use com qualquer agente. Defina limites de gastos mensais. Cancele a qualquer momento.", + "zen.problem.title": "Que problema o Zen resolve?", + "zen.problem.body": + "Existem muitos modelos disponíveis, mas apenas alguns funcionam bem com agentes de codificação. A maioria dos provedores os configura de maneira diferente, com resultados variados.", + "zen.problem.subtitle": "Estamos corrigindo isso para todos, não apenas para os usuários do OpenCode.", + "zen.problem.item1": "Testando modelos selecionados e consultando suas equipes", + "zen.problem.item2": "Trabalhando com provedores para garantir que sejam entregues corretamente", + "zen.problem.item3": "Avaliando todas as combinações de modelo-provedor que recomendamos", + "zen.how.title": "Como o Zen funciona", + "zen.how.body": "Embora sugerimos que você use o Zen com o OpenCode, você pode usá-lo com qualquer agente.", + "zen.how.step1.title": "Cadastre-se e adicione $20 de saldo", + "zen.how.step1.beforeLink": "siga as", + "zen.how.step1.link": "instruções de configuração", + "zen.how.step2.title": "Use o Zen com preços transparentes", + "zen.how.step2.link": "pague por requisição", + "zen.how.step2.afterLink": "sem margens de lucro", + "zen.how.step3.title": "Recarga automática", + "zen.how.step3.body": "quando seu saldo atingir $5, adicionaremos automaticamente $20", + "zen.privacy.title": "Sua privacidade é importante para nós", + "zen.privacy.beforeExceptions": + "Todos os modelos Zen são hospedados nos EUA. Os provedores seguem uma política de retenção zero e não usam seus dados para treinamento de modelo, com as", + "zen.privacy.exceptionsLink": "seguintes exceções", + + "go.title": "OpenCode Go | Modelos de codificação de baixo custo para todos", + "go.meta.description": + "O Go custa $10/mês, com limites generosos de uso e acesso confiável aos principais modelos de codificação.", + "go.hero.title": "Modelos de codificação de baixo custo para todos", + "go.hero.body": + "O Go traz a codificação com agentes para programadores em todo o mundo. Oferecendo limites generosos e acesso confiável aos modelos de código aberto mais capazes, para que você possa construir com agentes poderosos sem se preocupar com custos ou disponibilidade.", + + "go.cta.start": "Assinar o Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Assinar o Go", + "go.cta.price": "$10/mês", + "go.pricing.body": + "Use com qualquer agente. $10/mês. Recarregue o crédito se necessário. Cancele a qualquer momento.", + "go.graph.free": "Grátis", + "go.graph.freePill": "Big Pickle e modelos gratuitos", + "go.graph.go": "Go", + "go.graph.label": "Requisições por 5 horas", + "go.graph.period": "Uso", + "go.graph.model": "Modelo", + "go.graph.requests": "Requisições estimadas / 5 h", + "go.graph.allowance": "Uso mensal", + "go.graph.new": "Novo", + "go.graph.scale": "Escala não linear de requisições", + "go.graph.showAll": "Ver todos os {{count}} modelos", + "go.graph.showLess": "Mostrar menos modelos", + "go.graph.limitedRegions": "regiões limitadas", + "go.graph.limitedTime": "tempo limitado", + "go.graph.usageLimits": "Limites de uso", + "go.graph.aria": "Requisições por 5h: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "mudou minha vida, é realmente uma escolha óbvia.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Fundador, SEED, PM, Melt, Pop, Dapt, Cadmus e ViewPoint", + "go.testimonials.jay.quoteBefore": "4 de 5 pessoas em nossa equipe adoram usar", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "Eu não consigo recomendar o", + "go.testimonials.adam.quoteAfter": "o suficiente. Sério, é muito bom.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head de Design, Laravel", + "go.testimonials.david.quoteBefore": "Com o", + "go.testimonials.david.quoteAfter": + "eu sei que todos os modelos são testados e perfeitos para agentes de codificação.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Estagiário, Nvidia (4 vezes)", + "go.testimonials.frank.quote": "Eu queria ainda estar na Nvidia.", + "go.problem.title": "Que problema o Go resolve?", + "go.problem.body": + "Estamos focados em levar a experiência do OpenCode para o maior número de pessoas possível. OpenCode Go é uma assinatura de baixo custo de $10/mês. Oferece limites generosos e acesso confiável aos modelos open source mais capazes.", + "go.problem.subtitle": " ", + "go.problem.item1": "Preço de assinatura de baixo custo", + "go.problem.item2": "Limites generosos e acesso confiável", + "go.problem.item3": "Feito para o maior número possível de programadores", + "go.problem.item4": "Uma seleção de modelos testados para codificação com agentes", + "go.how.title": "Como o Go funciona", + "go.how.body": "O Go custa $10/mês. Você pode usá-lo com o OpenCode ou qualquer agente.", + "go.how.step1.title": "Crie uma conta", + "go.how.step1.beforeLink": "siga as", + "go.how.step1.link": "instruções de configuração", + "go.how.step2.title": "Assinar o Go", + "go.how.step2.link": "$10/mês", + "go.how.step2.afterLink": "com limites generosos", + "go.how.step3.title": "Comece a codificar", + "go.how.step3.body": "com acesso confiável a modelos de código aberto", + "go.privacy.title": "Sua privacidade é importante para nós", + "go.privacy.body": + "O plano é projetado principalmente para usuários internacionais, com modelos hospedados nos EUA, UE e Singapura para acesso global estável.", + "go.privacy.contactAfter": "se você tiver alguma dúvida.", + "go.privacy.beforeExceptions": + "Os modelos Go são hospedados nos EUA. Os provedores seguem uma política de retenção zero e não usam seus dados para treinamento de modelos, com as", + "go.privacy.exceptionsLink": "seguintes exceções", + "go.faq.q1": "O que é OpenCode Go?", + "go.faq.a1": + "Go é uma assinatura de baixo custo que oferece acesso confiável a modelos de código aberto capazes para codificação com agentes.", + "go.faq.q2": "Quais modelos o Go inclui?", + "go.faq.a2": "O Go inclui os modelos listados abaixo, com limites generosos e acesso confiável.", + "go.faq.q3": "O Go é o mesmo que o Zen?", + "go.faq.a3": + "Não. Zen é pay-as-you-go, enquanto o Go custa $10/mês, com limites generosos e acesso confiável a uma seleção de modelos.", + "go.faq.q4": "Quanto custa o Go?", + "go.faq.a4.p1.beforePricing": "O Go custa", + "go.faq.a4.p1.pricingLink": "$10/mês", + "go.faq.a4.p1.afterPricing": "com limites generosos.", + "go.faq.a4.p2.beforeAccount": "Você pode gerenciar sua assinatura em sua", + "go.faq.a4.p2.accountLink": "conta", + "go.faq.a4.p3": "Cancele a qualquer momento.", + "go.faq.q5": "E sobre dados e privacidade?", + "go.faq.a5.model": "Modelo", + "go.faq.a5.training": "Treinamento de modelos", + "go.faq.a5.retention": "Retenção de dados", + "go.faq.a5.retention30": "30 dias", + "go.faq.a5.retention0": "0 dias", + "go.faq.a5.used": "Usado", + "go.faq.a5.notUsed": "Não usado", + "go.faq.a5.noAgreement": "Sem acordo", + "go.faq.a5.notZdr": "Não é ZDR", + "go.faq.a5.grokRetention": + "O ZDR desativa recursos importantes da API que dependem de dados armazenados, incluindo a Responses API com estado, Files and Collections e a Batch API.", + "go.faq.a5.gptRetention": + "Logs de monitoramento de abuso são gerados para todo uso de recursos da API e retidos por até 30 dias.", + "go.faq.a5.museRetention": + "Preços de tokens com grandes descontos em troca da permissão para usar seus prompts e respostas geradas para treinar futuros modelos da Meta.", + "go.faq.a5.learnMore": "Saiba mais", + "go.faq.a5.deepseekRetention": + "O acordo de ZDR é renovado mensalmente. O acordo atual é válido até 30 de setembro de 2026.", + "go.faq.a5.beforeExceptions": + "Os modelos Go são hospedados nos EUA. Os provedores seguem uma política de retenção zero e não usam seus dados para treinamento de modelos, com as", + "go.faq.a5.exceptionsLink": "seguintes exceções", + "go.faq.q6": "Posso recarregar crédito?", + "go.faq.a6": "Se você precisar de mais uso, pode recarregar crédito em sua conta.", + "go.faq.q7": "Posso cancelar?", + "go.faq.a7": "Sim, você pode cancelar a qualquer momento.", + "go.faq.q8": "Posso usar o Go com outros agentes de codificação?", + "go.faq.a8": + "Sim, você pode usar o Go com qualquer agente. Siga as instruções de configuração no seu agente de codificação preferido.", + + "go.faq.q9": "Qual a diferença entre os modelos gratuitos e o Go?", + "go.faq.a9": + "Os modelos gratuitos incluem Big Pickle e modelos promocionais disponíveis no momento, com uma cota de 200 requisições/dia. O Go oferece uma seleção de modelos com cotas de requisição mais altas aplicadas em janelas móveis (5 horas, semanal e mensal), aproximadamente equivalentes a cotas básicas de $12 por 5 horas, $30 por semana e $60 por mês; as cotas específicas podem variar por modelo (as contagens reais de requisições variam de acordo com o modelo e o uso).", + "go.faq.q10": "Posso receber um reembolso?", + "go.faq.a10": + "Você pode ter direito a um reembolso se a cobrança foi feita nos últimos 14 dias e você não usou sua cota do Go durante esse período de faturamento. {{contact}} para solicitar um reembolso.", + + "zen.api.error.rateLimitExceeded": "Limite de taxa excedido. Por favor, tente novamente mais tarde.", + "zen.api.error.modelNotSupported": "Modelo {{model}} não suportado", + "zen.api.error.modelFormatNotSupported": "Modelo {{model}} não suportado para o formato {{format}}", + "zen.api.error.noProviderAvailable": "Nenhum provedor disponível", + "zen.api.error.providerNotSupported": "Provedor {{provider}} não suportado", + "zen.api.error.missingApiKey": "Chave de API ausente.", + "zen.api.error.invalidApiKey": "Chave de API inválida.", + "zen.api.error.requestBlockedByUpstreamProvider": "Solicitação bloqueada pelo provedor upstream.", + "zen.api.error.subscriptionQuotaExceeded": "Cota de assinatura excedida. Tente novamente em {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "Limite de uso de 5 horas atingido. Será reiniciado em {{retryIn}}. Para continuar usando este modelo agora, habilite o uso a partir do seu saldo disponível: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Limite de uso semanal atingido. Será reiniciado em {{retryIn}}. Para continuar usando este modelo agora, habilite o uso a partir do seu saldo disponível: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Limite de uso mensal atingido. Será reiniciado em {{retryIn}}. Para continuar usando este modelo agora, habilite o uso a partir do seu saldo disponível: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Nenhuma forma de pagamento. Adicione uma forma de pagamento aqui: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Saldo insuficiente. Gerencie seu faturamento aqui: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Seu workspace atingiu o limite de gastos mensais de ${{amount}}. Gerencie seus limites aqui: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Você atingiu seu limite de gastos mensais de ${{amount}}. Gerencie seus limites aqui: {{membersUrl}}", + "zen.api.error.modelDisabled": "O modelo está desabilitado", + "zen.api.error.regionNotAllowed": + "A versão mais recente deste modelo está disponível apenas com hospedagem na China e requer adesão explícita: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Este modelo não está disponível no seu país.", + "zen.api.error.trainingNotAllowed": + "Este modelo coleta dados usados para melhorar sua qualidade e exige seu consentimento explícito: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "A promoção gratuita do {{model}} terminou. Você pode continuar usando o modelo assinando o OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Acesse os melhores modelos de codificação do mundo", + "black.meta.description": "Tenha acesso ao Claude, GPT, Gemini e mais com os planos de assinatura OpenCode Black.", + "black.hero.title": "Acesse os melhores modelos de codificação do mundo", + "black.hero.subtitle": "Incluindo Claude, GPT, Gemini e mais", + "black.title": "OpenCode Black | Preços", + "black.paused": "A inscrição no plano Black está temporariamente pausada.", + "black.plan.icon20": "Plano Black 20", + "black.plan.icon100": "Plano Black 100", + "black.plan.icon200": "Plano Black 200", + "black.plan.multiplier100": "5x mais uso que o Black 20", + "black.plan.multiplier200": "20x mais uso que o Black 20", + "black.price.perMonth": "por mês", + "black.price.perPersonBilledMonthly": "por pessoa faturado mensalmente", + "black.terms.1": "Sua assinatura não começará imediatamente", + "black.terms.2": "Você será adicionado à lista de espera e ativado em breve", + "black.terms.3": "Seu cartão só será cobrado quando sua assinatura for ativada", + "black.terms.4": "Limites de uso se aplicam; uso fortemente automatizado pode atingir os limites mais cedo", + "black.terms.5": "Assinaturas são para indivíduos, contate Enterprise para equipes", + "black.terms.6": "Limites podem ser ajustados e planos podem ser descontinuados no futuro", + "black.terms.7": "Cancele sua assinatura a qualquer momento", + "black.action.continue": "Continuar", + "black.finePrint.beforeTerms": "Os preços mostrados não incluem impostos aplicáveis", + "black.finePrint.terms": "Termos de Serviço", + "black.workspace.title": "OpenCode Black | Selecionar Workspace", + "black.workspace.selectPlan": "Selecione um workspace para este plano", + "black.workspace.name": "Workspace {{n}}", + "black.subscribe.title": "Assinar OpenCode Black", + "black.subscribe.paymentMethod": "Forma de pagamento", + "black.subscribe.loadingPaymentForm": "Carregando formulário de pagamento...", + "black.subscribe.selectWorkspaceToContinue": "Selecione um workspace para continuar", + "black.subscribe.failurePrefix": "Ops!", + "black.subscribe.error.generic": "Ocorreu um erro", + "black.subscribe.error.invalidPlan": "Plano inválido", + "black.subscribe.error.workspaceRequired": "ID do workspace é obrigatório", + "black.subscribe.error.alreadySubscribed": "Este workspace já possui uma assinatura", + "black.subscribe.processing": "Processando...", + "black.subscribe.submit": "Assinar ${{plan}}", + "black.subscribe.form.chargeNotice": "Você só será cobrado quando sua assinatura for ativada", + "black.subscribe.success.title": "Você está na lista de espera do OpenCode Black", + "black.subscribe.success.subscriptionPlan": "Plano de assinatura", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Valor", + "black.subscribe.success.amountValue": "${{plan}} por mês", + "black.subscribe.success.paymentMethod": "Forma de pagamento", + "black.subscribe.success.dateJoined": "Data de entrada", + "black.subscribe.success.chargeNotice": "Seu cartão será cobrado quando sua assinatura for ativada", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Uso", + "workspace.nav.apiKeys": "Chaves de API", + "workspace.nav.members": "Membros", + "workspace.nav.billing": "Faturamento", + "workspace.nav.settings": "Configurações", + + "workspace.home.banner.beforeLink": "Modelos otimizados e confiáveis para agentes de codificação.", + "workspace.lite.banner.beforeLink": "Modelos de codificação de baixo custo para todos.", + "workspace.home.billing.loading": "Carregando...", + "workspace.home.billing.enable": "Ativar faturamento", + "workspace.home.billing.currentBalance": "Saldo atual", + + "workspace.newUser.feature.tested.title": "Modelos Testados e Verificados", + "workspace.newUser.feature.tested.body": + "Avaliamos e testamos modelos especificamente para agentes de codificação para garantir o melhor desempenho.", + "workspace.newUser.feature.quality.title": "Qualidade Máxima", + "workspace.newUser.feature.quality.body": + "Acesse modelos configurados para desempenho ideal - sem downgrades ou roteamento para provedores mais baratos.", + "workspace.newUser.feature.lockin.title": "Sem Fidelidade", + "workspace.newUser.feature.lockin.body": + "Use o Zen com qualquer agente de codificação e continue usando outros provedores com opencode sempre que quiser.", + "workspace.newUser.copyApiKey": "Copiar chave de API", + "workspace.newUser.copyKey": "Copiar Chave", + "workspace.newUser.copied": "Copiado!", + "workspace.newUser.step.enableBilling": "Ativar faturamento", + "workspace.newUser.step.login.before": "Execute", + "workspace.newUser.step.login.after": "e selecione opencode", + "workspace.newUser.step.pasteKey": "Cole sua chave de API", + "workspace.newUser.step.models.before": "Inicie o opencode e execute", + "workspace.newUser.step.models.after": "para selecionar um modelo", + + "workspace.models.title": "Modelos", + "workspace.models.subtitle.beforeLink": "Gerencie quais modelos os membros do workspace podem acessar.", + "workspace.models.table.model": "Modelo", + "workspace.models.table.enabled": "Habilitado", + + "workspace.providers.title": "Traga Sua Própria Chave", + "workspace.providers.subtitle": "Configure suas próprias chaves de API de provedores de IA.", + "workspace.providers.placeholder": "Insira a chave de API {{provider}} ({{prefix}}...)", + "workspace.providers.configure": "Configurar", + "workspace.providers.edit": "Editar", + "workspace.providers.delete": "Excluir", + "workspace.providers.saving": "Salvando...", + "workspace.providers.save": "Salvar", + "workspace.providers.table.provider": "Provedor", + "workspace.providers.table.apiKey": "Chave de API", + + "workspace.usage.title": "Histórico de Uso", + "workspace.usage.subtitle": "Uso recente da API e custos.", + "workspace.usage.empty": "Faça sua primeira chamada de API para começar.", + "workspace.usage.table.date": "Data", + "workspace.usage.table.model": "Modelo", + "workspace.usage.table.input": "Entrada", + "workspace.usage.table.output": "Saída", + "workspace.usage.table.cost": "Custo", + "workspace.usage.table.session": "Sessão", + "workspace.usage.breakdown.input": "Entrada", + "workspace.usage.breakdown.cacheRead": "Leitura de Cache", + "workspace.usage.breakdown.cacheWrite": "Escrita em Cache", + "workspace.usage.breakdown.output": "Saída", + "workspace.usage.breakdown.reasoning": "Raciocínio", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Custo", + "workspace.cost.subtitle": "Custos de uso discriminados por modelo.", + "workspace.cost.allModels": "Todos os Modelos", + "workspace.cost.allKeys": "Todas as Chaves", + "workspace.cost.deletedSuffix": "(excluído)", + "workspace.cost.empty": "Nenhum dado de uso disponível para o período selecionado.", + "workspace.cost.subscriptionShort": "ass", + + "workspace.keys.title": "Chaves de API", + "workspace.keys.subtitle": "Gerencie suas chaves de API para acessar os serviços opencode.", + "workspace.keys.create": "Criar Chave de API", + "workspace.keys.placeholder": "Digite o nome da chave", + "workspace.keys.empty": "Crie uma chave de API do opencode Gateway", + "workspace.keys.table.name": "Nome", + "workspace.keys.table.key": "Chave", + "workspace.keys.table.createdBy": "Criado Por", + "workspace.keys.table.lastUsed": "Último Uso", + "workspace.keys.copyApiKey": "Copiar chave de API", + "workspace.keys.delete": "Excluir", + + "workspace.members.title": "Membros", + "workspace.members.subtitle": "Gerencie os membros do workspace e suas permissões.", + "workspace.members.invite": "Convidar Membro", + "workspace.members.inviting": "Convidando...", + "workspace.members.beta.beforeLink": "Workspaces são gratuitos para equipes durante o beta.", + "workspace.members.form.invitee": "Convidado", + "workspace.members.form.emailPlaceholder": "Digite o e-mail", + "workspace.members.form.role": "Função", + "workspace.members.form.monthlyLimit": "Limite de gastos mensais", + "workspace.members.noLimit": "Sem limite", + "workspace.members.noLimitLowercase": "sem limite", + "workspace.members.invited": "convidado", + "workspace.members.edit": "Editar", + "workspace.members.delete": "Excluir", + "workspace.members.saving": "Salvando...", + "workspace.members.save": "Salvar", + "workspace.members.table.email": "E-mail", + "workspace.members.table.role": "Função", + "workspace.members.table.monthLimit": "Limite mensal", + "workspace.members.role.admin": "Admin", + "workspace.members.role.adminDescription": "Pode gerenciar modelos, membros e faturamento", + "workspace.members.role.member": "Membro", + "workspace.members.role.memberDescription": "Só pode gerar chaves de API para si mesmo", + + "workspace.settings.title": "Configurações", + "workspace.settings.subtitle": "Atualize o nome e as preferências do seu workspace.", + "workspace.settings.workspaceName": "Nome do workspace", + "workspace.settings.defaultName": "Padrão", + "workspace.settings.updating": "Atualizando...", + "workspace.settings.save": "Salvar", + "workspace.settings.edit": "Editar", + + "workspace.billing.title": "Faturamento", + "workspace.billing.subtitle.beforeLink": "Gerenciar formas de pagamento.", + "workspace.billing.contactUs": "Contate-nos", + "workspace.billing.subtitle.afterLink": "se você tiver alguma dúvida.", + "workspace.billing.currentBalance": "Saldo Atual", + "workspace.billing.add": "Adicionar $", + "workspace.billing.enterAmount": "Digite o valor", + "workspace.billing.loading": "Carregando...", + "workspace.billing.addAction": "Adicionar", + "workspace.billing.addBalance": "Adicionar Saldo", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Vinculado ao Stripe", + "workspace.billing.manage": "Gerenciar", + "workspace.billing.enable": "Ativar Faturamento", + + "workspace.monthlyLimit.title": "Limite Mensal", + "workspace.monthlyLimit.subtitle": "Defina um limite de uso mensal para sua conta.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Definindo...", + "workspace.monthlyLimit.set": "Definir", + "workspace.monthlyLimit.edit": "Editar Limite", + "workspace.monthlyLimit.noLimit": "Nenhum limite de uso definido.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Uso atual para", + "workspace.monthlyLimit.currentUsage.beforeAmount": "é $", + + "workspace.redeem.title": "Resgatar Cupom", + "workspace.redeem.subtitle": "Resgate um código de cupom para receber créditos ou vantagens.", + "workspace.redeem.placeholder": "Digite o código do cupom", + "workspace.redeem.redeem": "Resgatar", + "workspace.redeem.redeeming": "Resgatando...", + "workspace.redeem.success": "Cupom resgatado com sucesso.", + + "workspace.reload.title": "Recarga Automática", + "workspace.reload.disabled.before": "A recarga automática está", + "workspace.reload.disabled.state": "desativada", + "workspace.reload.disabled.after": "Ative para recarregar automaticamente quando o saldo estiver baixo.", + "workspace.reload.enabled.before": "A recarga automática está", + "workspace.reload.enabled.state": "ativada", + "workspace.reload.enabled.middle": "Recarregaremos", + "workspace.reload.processingFee": "taxa de processamento", + "workspace.reload.enabled.after": "quando o saldo atingir", + "workspace.reload.edit": "Editar", + "workspace.reload.enable": "Ativar", + "workspace.reload.enableAutoReload": "Ativar Recarga Automática", + "workspace.reload.reloadAmount": "Recarregar $", + "workspace.reload.whenBalanceReaches": "Quando o saldo atingir $", + "workspace.reload.saving": "Salvando...", + "workspace.reload.save": "Salvar", + "workspace.reload.failedAt": "Recarga falhou em", + "workspace.reload.reason": "Motivo:", + "workspace.reload.updatePaymentMethod": "Por favor, atualize sua forma de pagamento e tente novamente.", + "workspace.reload.retrying": "Tentando novamente...", + "workspace.reload.retry": "Tentar novamente", + "workspace.reload.error.paymentFailed": "Pagamento falhou.", + + "workspace.payments.title": "Histórico de Pagamentos", + "workspace.payments.subtitle": "Transações de pagamento recentes.", + "workspace.payments.table.date": "Data", + "workspace.payments.table.paymentId": "ID do Pagamento", + "workspace.payments.table.amount": "Valor", + "workspace.payments.table.receipt": "Recibo", + "workspace.payments.type.credit": "crédito", + "workspace.payments.type.subscription": "assinatura", + "workspace.payments.view": "Ver", + + "workspace.black.loading": "Carregando...", + "workspace.black.time.day": "dia", + "workspace.black.time.days": "dias", + "workspace.black.time.hour": "hora", + "workspace.black.time.hours": "horas", + "workspace.black.time.minute": "minuto", + "workspace.black.time.minutes": "minutos", + "workspace.black.time.fewSeconds": "alguns segundos", + "workspace.black.subscription.title": "Assinatura", + "workspace.black.subscription.message": "Você assina o OpenCode Black por ${{plan}} por mês.", + "workspace.black.subscription.manage": "Gerenciar Assinatura", + "workspace.black.subscription.rollingUsage": "Uso de 5 horas", + "workspace.black.subscription.weeklyUsage": "Uso Semanal", + "workspace.black.subscription.resetsIn": "Reinicia em", + "workspace.black.subscription.useBalance": "Use seu saldo disponível após atingir os limites de uso", + "workspace.black.waitlist.title": "Lista de Espera", + "workspace.black.waitlist.joined": "Você está na lista de espera para o plano OpenCode Black de ${{plan}} por mês.", + "workspace.black.waitlist.ready": "Estamos prontos para inscrever você no plano OpenCode Black de ${{plan}} por mês.", + "workspace.black.waitlist.leave": "Sair da Lista de Espera", + "workspace.black.waitlist.leaving": "Saindo...", + "workspace.black.waitlist.left": "Saiu", + "workspace.black.waitlist.enroll": "Inscrever-se", + "workspace.black.waitlist.enrolling": "Inscrevendo-se...", + "workspace.black.waitlist.enrolled": "Inscrito", + "workspace.black.waitlist.enrollNote": + "Ao clicar em Inscrever-se, sua assinatura começará imediatamente e seu cartão será cobrado.", + + "workspace.lite.loading": "Carregando...", + "workspace.lite.time.day": "dia", + "workspace.lite.time.days": "dias", + "workspace.lite.time.hour": "hora", + "workspace.lite.time.hours": "horas", + "workspace.lite.time.minute": "minuto", + "workspace.lite.time.minutes": "minutos", + "workspace.lite.time.fewSeconds": "alguns segundos", + "workspace.lite.subscription.message": "Você assina o OpenCode Go.", + "workspace.lite.subscription.manage": "Gerenciar Assinatura", + "workspace.lite.subscription.rollingUsage": "Uso de 5 horas", + "workspace.lite.subscription.rollingQuota": "Cota de 5 horas", + "workspace.lite.subscription.weeklyUsage": "Uso Semanal", + "workspace.lite.subscription.weeklyQuota": "Cota Semanal", + "workspace.lite.subscription.monthlyUsage": "Uso Mensal", + "workspace.lite.subscription.monthlyQuota": "Cota Mensal", + "workspace.lite.subscription.resetsIn": "Reinicia em", + "workspace.lite.subscription.showDetails": "Mostrar detalhes", + "workspace.lite.subscription.hideDetails": "Ocultar detalhes", + "workspace.lite.subscription.model": "Modelo", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Total", + "workspace.lite.subscription.useBalance": "Use seu saldo disponível após atingir os limites de uso", + "workspace.lite.subscription.selectProvider": + 'Selecione "OpenCode Go" como provedor na sua configuração do opencode para usar os modelos Go.', + "workspace.lite.providers.title": "Provedores", + "workspace.lite.providers.description": "Controle quais provedores são usados para roteamento.", + "workspace.lite.providers.allowTraining": "Permitir modelos que usam dados de solicitações para treinamento", + "workspace.lite.providers.useChina": "Ativar modelos hospedados na China", + "workspace.lite.black.message": + "Você está atualmente inscrito no OpenCode Black ou na lista de espera. Por favor, cancele a assinatura primeiro se desejar mudar para o Go.", + "workspace.lite.other.message": + "Outro membro neste workspace já assina o OpenCode Go. Apenas um membro por workspace pode assinar.", + "workspace.lite.promo.description": + "O OpenCode Go custa {{price}} e oferece acesso confiável a modelos de codificação abertos populares com limites de uso generosos.", + "workspace.lite.promo.price": "$10/mês", + "workspace.lite.promo.modelsTitle": "O que está incluído", + "workspace.lite.promo.footer": + "O plano foi desenvolvido principalmente para usuários internacionais e oferece acesso global estável. Os preços e limites de uso podem mudar à medida que aprendemos com o uso inicial e o feedback recebido.", + "workspace.lite.promo.subscribe": "Assinar Go", + "workspace.lite.promo.subscribing": "Redirecionando...", + "workspace.lite.promo.otherMethods": "Outros métodos de pagamento", + "workspace.lite.promo.selectMethod": "Selecionar método de pagamento", + + "workspace.referral.copyLink": "Copiar link", + "workspace.referral.copied": "Copiado", + "workspace.referral.overview.title": "Convide amigos", + "workspace.referral.overview.subtitle": "Ganhe $5 quando um amigo assinar. Ele também ganha $5.", + "workspace.referral.instructions.share": "Compartilhe seu link de indicação", + "workspace.referral.instructions.subscribe": "Seu amigo entra e assina o Go", + "workspace.referral.instructions.claim": + "Vocês dois ganham um crédito de uso de $5 para aplicar aos seus limites de uso do Go", + "workspace.referral.rewards.title": "Recompensas de indicação", + "workspace.referral.rewards.description": "Aplique os créditos de indicação disponíveis no seu uso do Go.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} recompensas aplicadas.", + "workspace.referral.rewards.empty": "Ainda não há recompensas de indicação.", + "workspace.referral.table.reward": "Recompensa", + "workspace.referral.table.referral": "Descrição", + "workspace.referral.table.date": "Data", + "workspace.referral.reward.description.inviter": "Convidou {{email}}", + "workspace.referral.reward.description.invitee": "Convidado por {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Assine para desbloquear", + "workspace.referral.reward.action.view": "Ver recompensa", + "workspace.referral.reward.action.applied": "Recompensa aplicada", + "workspace.referral.reward.source.pendingInviter": "Aguardando ele assinar", + "workspace.referral.reward.source.pendingInvitee": "Assine para desbloquear a recompensa", + "workspace.referral.reward.source.available": "Recompensa pronta para usar", + "workspace.referral.reward.source.applied": "Recompensa aplicada", + "workspace.referral.reward.status.applied": "Recompensa aplicada", + "workspace.referral.reward.status.pendingInviter": "Assine para desbloquear", + "workspace.referral.reward.status.pendingInvitee": "Assine para desbloquear", + "workspace.referral.apply.noGo": "Assine para desbloquear", + "workspace.referral.apply.preview": "Ver recompensa", + "workspace.referral.apply.action": "Aplicar", + "workspace.referral.apply.confirmTitle": "Aplicar recompensa", + "workspace.referral.apply.confirmBody": "Aplique {{amount}} para reduzir o uso atual deste workspace.", + "workspace.referral.apply.confirmAction": "Aplicar", + + "download.title": "OpenCode | Baixar", + "download.meta.description": "Baixe o OpenCode para macOS, Windows e Linux", + "download.hero.title": "Baixar OpenCode Desktop", + "download.hero.subtitle": "Disponível em Beta para macOS, Windows e Linux", + "download.hero.button": "Baixar para {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "Extensões OpenCode", + "download.section.integrations": "Integrações OpenCode", + "download.action.download": "Baixar", + "download.action.install": "Instalar", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Não necessariamente, mas provavelmente. Você precisará de uma assinatura de IA se quiser conectar o OpenCode a um provedor pago, embora você possa trabalhar com", + "download.faq.a3.localLink": "modelos locais", + "download.faq.a3.afterLocal.beforeZen": "de graça. Embora incentivemos os usuários a usar o", + "download.faq.a3.afterZen": + ", o OpenCode funciona com todos os provedores populares, como OpenAI, Anthropic, xAI etc.", + + "download.faq.a5.p1": "O OpenCode é 100% gratuito para usar.", + "download.faq.a5.p2.beforeZen": + "Quaisquer custos adicionais virão da sua assinatura de um provedor de modelo. Embora o OpenCode funcione com qualquer provedor de modelo, recomendamos o uso do", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": + "Seus dados e informações só são armazenados quando você cria links compartilháveis no OpenCode.", + "download.faq.a6.p2.beforeShare": "Saiba mais sobre", + "download.faq.a6.shareLink": "páginas de compartilhamento", + + "enterprise.title": "OpenCode | Soluções empresariais para sua organização", + "enterprise.meta.description": "Contate a OpenCode para soluções empresariais", + "enterprise.hero.title": "Seu código é seu", + "enterprise.hero.body1": + "O OpenCode opera com segurança dentro da sua organização, sem dados ou contexto armazenados e sem restrições de licenciamento ou reivindicações de propriedade. Inicie um teste com sua equipe e, em seguida, implante em toda a organização integrando-o ao seu SSO e gateway de IA interno.", + "enterprise.hero.body2": "Deixe-nos saber como podemos ajudar.", + "enterprise.form.name.label": "Nome completo", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Cargo", + "enterprise.form.role.placeholder": "Presidente Executivo", + "enterprise.form.company.label": "Empresa", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "E-mail corporativo", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Telefone", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Qual problema você está tentando resolver?", + "enterprise.form.message.placeholder": "Precisamos de ajuda com...", + "enterprise.form.send": "Enviar", + "enterprise.form.sending": "Enviando...", + "enterprise.form.success": "Mensagem enviada, entraremos em contato em breve.", + "enterprise.form.success.submitted": "Formulário enviado com sucesso.", + "enterprise.form.error.allFieldsRequired": "Todos os campos são obrigatórios.", + "enterprise.form.error.invalidEmailFormat": "Formato de e-mail inválido.", + "enterprise.form.error.internalServer": "Erro interno do servidor.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "O que é OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise é para organizações que desejam garantir que seu código e dados nunca saiam de sua infraestrutura. Isso pode ser feito usando uma configuração centralizada que se integra ao seu SSO e gateway de IA interno.", + "enterprise.faq.q2": "Como faço para começar com o OpenCode Enterprise?", + "enterprise.faq.a2": + "Basta começar com um teste interno com sua equipe. O OpenCode por padrão não armazena seu código ou dados de contexto, facilitando o início. Em seguida, entre em contato conosco para discutir opções de preços e implementação.", + "enterprise.faq.q3": "Como funciona o preço empresarial?", + "enterprise.faq.a3": + "Oferecemos preços empresariais por assento. Se você tiver seu próprio gateway de LLM, não cobramos pelos tokens usados. Para mais detalhes, entre em contato conosco para um orçamento personalizado com base nas necessidades da sua organização.", + "enterprise.faq.q4": "Meus dados estão seguros com o OpenCode Enterprise?", + "enterprise.faq.a4": + "Sim. O OpenCode não armazena seu código ou dados de contexto. Todo o processamento acontece localmente ou por meio de chamadas de API diretas para seu provedor de IA. Com configuração centralizada e integração de SSO, seus dados permanecem seguros dentro da infraestrutura de sua organização.", + + "brand.title": "OpenCode | Marca", + "brand.meta.description": "Diretrizes da marca OpenCode", + "brand.heading": "Diretrizes da marca", + "brand.subtitle": "Recursos e ativos para ajudá-lo a trabalhar com a marca OpenCode.", + "brand.downloadAll": "Baixar todos os recursos", + + "changelog.title": "OpenCode | Changelog", + "changelog.meta.description": "Notas de versão e changelog do OpenCode", + "changelog.hero.title": "Changelog", + "changelog.hero.subtitle": "Novas atualizações e melhorias no OpenCode", + "changelog.empty": "Nenhuma entrada de changelog encontrada.", + "changelog.viewJson": "Ver JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarks", + "bench.list.table.agent": "Agente", + "bench.list.table.model": "Modelo", + "bench.list.table.score": "Pontuação", + "bench.submission.error.allFieldsRequired": "Todos os campos são obrigatórios.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Tarefa não encontrada", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "Agente", + "bench.detail.labels.model": "Modelo", + "bench.detail.labels.task": "Tarefa", + "bench.detail.labels.repo": "Repositório", + "bench.detail.labels.from": "De", + "bench.detail.labels.to": "Para", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Duração Média", + "bench.detail.labels.averageScore": "Pontuação Média", + "bench.detail.labels.averageCost": "Custo Médio", + "bench.detail.labels.summary": "Resumo", + "bench.detail.labels.runs": "Execuções", + "bench.detail.labels.score": "Pontuação", + "bench.detail.labels.base": "Base", + "bench.detail.labels.penalty": "Penalidade", + "bench.detail.labels.weight": "peso", + "bench.detail.table.run": "Execução", + "bench.detail.table.score": "Pontuação (Base - Penalidade)", + "bench.detail.table.cost": "Custo", + "bench.detail.table.duration": "Duração", + "bench.detail.run.title": "Execução {{n}}", + "bench.detail.rawJson": "JSON Bruto", +} satisfies Dict diff --git a/packages/console/app/src/i18n/da.ts b/packages/console/app/src/i18n/da.ts new file mode 100644 index 0000000000000000000000000000000000000000..d2787bb611eb43f4d3cdd008f6893e0a7988b9c1 --- /dev/null +++ b/packages/console/app/src/i18n/da.ts @@ -0,0 +1,873 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash får firedoblet brugsgrænse i en begrænset periode", + "go.graph.bonus": "{{count}}× forbrug", + "nav.github": "GitHub", + "nav.docs": "Dokumentation", + "nav.changelog": "Changelog", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Log ind", + "nav.free": "Download", + "nav.home": "Hjem", + "nav.openMenu": "Åbn menu", + "nav.getStartedFree": "Kom i gang gratis", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Kopier logo som SVG", + "nav.context.copyWordmark": "Kopier wordmark som SVG", + "nav.context.brandAssets": "Brand-assets", + + "footer.github": "GitHub", + "footer.docs": "Dokumentation", + "footer.changelog": "Changelog", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Brand", + "legal.privacy": "Privatliv", + "legal.terms": "Vilkår", + + "email.title": "Få besked først, når vi lancerer nye produkter", + "email.subtitle": "Tilmeld dig ventelisten for tidlig adgang.", + "email.placeholder": "E-mailadresse", + "email.subscribe": "Tilmeld", + "email.success": "Næsten færdig - tjek din indbakke og bekræft din e-mailadresse", + + "notFound.title": "Ikke fundet | opencode", + "notFound.heading": "404 - Siden blev ikke fundet", + "notFound.home": "Hjem", + "notFound.docs": "Dokumentation", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode logo light", + "notFound.logoDarkAlt": "opencode logo dark", + + "user.logout": "Log ud", + + "auth.callback.error.codeMissing": "Ingen autorisationskode fundet.", + + "workspace.select": "Vælg workspace", + "workspace.createNew": "+ Opret nyt workspace", + "workspace.modal.title": "Opret nyt workspace", + "workspace.modal.placeholder": "Indtast workspace-navn", + + "common.cancel": "Annuller", + "common.creating": "Opretter...", + "common.create": "Opret", + "common.contactUs": "Kontakt os", + + "common.videoUnsupported": "Din browser understøtter ikke video-tagget.", + "common.figure": "Fig {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Læs mere", + + "error.invalidPlan": "Ugyldig plan", + "error.workspaceRequired": "Workspace-ID er påkrævet", + "error.alreadySubscribed": "Dette workspace har allerede et abonnement", + "error.limitRequired": "Grænse er påkrævet.", + "error.monthlyLimitInvalid": "Angiv en gyldig månedlig grænse.", + "error.workspaceNameRequired": "Workspace-navn er påkrævet.", + "error.nameTooLong": "Navnet må højst være på 255 tegn.", + "error.emailRequired": "E-mail er påkrævet", + "error.roleRequired": "Rolle er påkrævet", + "error.idRequired": "ID er påkrævet", + "error.nameRequired": "Navn er påkrævet", + "error.providerRequired": "Udbyder er påkrævet", + "error.apiKeyRequired": "API-nøgle er påkrævet", + "error.modelRequired": "Model er påkrævet", + "error.reloadAmountMin": "Genopfyldningsbeløb skal være mindst ${{amount}}", + "error.reloadTriggerMin": "Saldogrænse skal være mindst ${{amount}}", + + "app.meta.description": "OpenCode - Den open source kodningsagent.", + + "home.title": "OpenCode | Den open source AI-kodningsagent", + + "temp.title": "opencode | AI-kodningsagent bygget til terminalen", + "temp.hero.title": "AI-kodningsagenten bygget til terminalen", + "temp.zen": "opencode zen", + "temp.getStarted": "Kom i gang", + "temp.feature.native.title": "Native TUI", + "temp.feature.native.body": "En responsiv, native, tema-bar terminal-UI", + "temp.feature.zen.beforeLink": "En", + "temp.feature.zen.link": "kurateret liste over modeller", + "temp.feature.zen.afterLink": "leveret af opencode", + "temp.feature.models.beforeLink": "Understøtter 75+ LLM-udbydere gennem", + "temp.feature.models.afterLink": ", inklusive lokale modeller", + "temp.screenshot.caption": "opencode TUI med tokyonight-temaet", + "temp.screenshot.alt": "opencode TUI med tokyonight-temaet", + "temp.logoLightAlt": "opencode logo light", + "temp.logoDarkAlt": "opencode logo dark", + + "home.banner.badge": "Ny", + "home.banner.text": "Introduktion af Tabs til Desktop.", + "home.banner.platforms": "Tilgængelig på macOS, Windows og Linux", + "home.banner.downloadNow": "Download nu", + "home.banner.downloadBetaNow": "Download desktop-betaen nu", + "home.promo.title": "Introduktion af Tabs til Desktop", + "home.promo.body": "Organiser dit arbejde og aktive sessioner med faner.", + "home.promo.cta": "Download den nyeste version for at komme i gang.", + "home.promo.close": "Luk meddelelsen om Desktop-appen", + + "home.hero.title": "Den open source AI-kodningsagent", + "home.hero.subtitle.a": "Gratis modeller inkluderet, eller forbind enhver model fra enhver udbyder,", + "home.hero.subtitle.b": "inklusive Claude, GPT, Gemini og mere.", + + "home.install.ariaLabel": "Installationsmuligheder", + + "home.what.title": "Hvad er OpenCode?", + "home.what.body": + "OpenCode er en open source agent, der hjælper dig med at skrive kode i din terminal, IDE eller desktop.", + "home.what.lsp.title": "LSP aktiveret", + "home.what.lsp.body": "Indlæser automatisk de rigtige LSP'er til LLM'en", + "home.what.multiSession.title": "Multi-session", + "home.what.multiSession.body": "Start flere agenter parallelt på det samme projekt", + "home.what.shareLinks.title": "Del links", + "home.what.shareLinks.body": "Del et link til enhver session til reference eller debugging", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Log ind med GitHub for at bruge din Copilot-konto", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Log ind med OpenAI for at bruge din ChatGPT Plus- eller Pro-konto", + "home.what.anyModel.title": "Enhver model", + "home.what.anyModel.body": "75+ LLM-udbydere via Models.dev, inklusive lokale modeller", + "home.what.anyEditor.title": "Enhver editor", + "home.what.anyEditor.body": "Tilgængelig som terminal-interface, desktop-app og IDE-udvidelse", + "home.what.readDocs": "Læs docs", + + "home.growth.title": "Den open source AI-kodningsagent", + "home.growth.body": + "Med over {{stars}} GitHub-stjerner, {{contributors}} bidragsydere og over {{commits}} commits bruges OpenCode af over {{monthlyUsers}} udviklere hver måned.", + "home.growth.githubStars": "GitHub-stjerner", + "home.growth.contributors": "Bidragsydere", + "home.growth.monthlyDevs": "Månedlige udviklere", + + "home.privacy.title": "Bygget med privatliv først", + "home.privacy.body": + "OpenCode gemmer ikke din kode eller kontekstdata, så den kan bruges i privatlivsfølsomme miljøer.", + "home.privacy.learnMore": "Læs mere om", + "home.privacy.link": "privatliv", + + "home.faq.q1": "Hvad er OpenCode?", + "home.faq.a1": + "OpenCode er en open source agent, der hjælper dig med at skrive og køre kode med enhver AI-model. Den er tilgængelig som terminal-interface, desktop-app eller IDE-udvidelse.", + "home.faq.q2": "Hvordan bruger jeg OpenCode?", + "home.faq.a2.before": "Den nemmeste måde at komme i gang på er at læse", + "home.faq.a2.link": "introen", + "home.faq.q3": "Skal jeg have ekstra AI-abonnementer for at bruge OpenCode?", + "home.faq.a3.p1": + "Ikke nødvendigvis. OpenCode kommer med gratis modeller, som du kan bruge uden at oprette en konto.", + "home.faq.a3.p2.beforeZen": "Derudover kan du bruge populære kodningsmodeller ved at oprette en", + "home.faq.a3.p2.afterZen": " konto.", + "home.faq.a3.p3": + "Vi opfordrer til at bruge Zen, men OpenCode virker også med populære udbydere som OpenAI, Anthropic, xAI osv.", + "home.faq.a3.p4.beforeLocal": "Du kan endda forbinde dine", + "home.faq.a3.p4.localLink": "lokale modeller", + "home.faq.q4": "Kan jeg bruge mine eksisterende AI-abonnementer med OpenCode?", + "home.faq.a4.p1": + "Ja. OpenCode understøtter abonnementer fra alle store udbydere. Du kan bruge Claude Pro/Max, ChatGPT Plus/Pro eller GitHub Copilot.", + "home.faq.q5": "Kan jeg kun bruge OpenCode i terminalen?", + "home.faq.a5.beforeDesktop": "Ikke længere! OpenCode er nu tilgængelig som en app til", + "home.faq.a5.desktop": "desktop", + "home.faq.a5.and": "og", + "home.faq.a5.web": "web", + "home.faq.q6": "Hvad koster OpenCode?", + "home.faq.a6": + "OpenCode er 100% gratis at bruge. Det kommer også med et sæt gratis modeller. Der kan være ekstra omkostninger, hvis du forbinder en anden udbyder.", + "home.faq.q7": "Hvad med data og privatliv?", + "home.faq.a7.p1": "Dine data gemmes kun, når du bruger vores gratis modeller eller opretter delbare links.", + "home.faq.a7.p2.beforeModels": "Læs mere om", + "home.faq.a7.p2.modelsLink": "vores modeller", + "home.faq.a7.p2.and": "og", + "home.faq.a7.p2.shareLink": "delingssider", + "home.faq.q8": "Er OpenCode open source?", + "home.faq.a8.p1": "Ja, OpenCode er fuldt open source. Kildekoden er offentlig på", + "home.faq.a8.p2": "under", + "home.faq.a8.mitLicense": "MIT-licensen", + "home.faq.a8.p3": + ", hvilket betyder at alle kan bruge, ændre eller bidrage til udviklingen. Alle i communityet kan oprette issues, indsende pull requests og udvide funktionalitet.", + + "home.zenCta.title": "Få adgang til pålidelige, optimerede modeller til kodningsagenter", + "home.zenCta.body": + "Zen giver dig adgang til et håndplukket sæt AI-modeller, som OpenCode har testet og benchmarked specifikt til kodningsagenter. Du behøver ikke bekymre dig om svingende performance og kvalitet på tværs af udbydere: brug validerede modeller, der virker.", + "home.zenCta.link": "Læs om Zen", + + "zen.title": "OpenCode Zen | Et kurateret sæt af pålidelige, optimerede modeller til kodningsagenter", + "zen.hero.title": "Pålidelige optimerede modeller til kodningsagenter", + "zen.hero.body": + "Zen giver dig adgang til et kurateret sæt AI-modeller, som OpenCode har testet og benchmarked specifikt til kodningsagenter. Du behøver ikke bekymre dig om svingende performance og kvalitet: brug validerede modeller, der virker.", + + "zen.faq.q1": "Hvad er OpenCode Zen?", + "zen.faq.a1": + "Zen er et kurateret sæt AI-modeller testet og benchmarked til kodningsagenter, skabt af teamet bag OpenCode.", + "zen.faq.q2": "Hvad gør Zen mere præcis?", + "zen.faq.a2": + "Zen tilbyder kun modeller, der er testet og benchmarked specifikt til kodningsagenter. Du ville ikke bruge en smørkniv til at skære steak; brug ikke dårlige modeller til kodning.", + "zen.faq.q3": "Er Zen billigere?", + "zen.faq.a3": + "Zen er ikke for profit. Zen videregiver omkostningerne fra modeludbyderne til dig. Jo mere Zen bruges, desto mere kan OpenCode forhandle bedre priser og give dem videre til dig.", + "zen.faq.q4": "Hvad koster Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "opkræver per request", + "zen.faq.a4.p1.afterPricing": "uden markups, så du betaler præcis det, som modeludbyderen opkræver.", + "zen.faq.a4.p2.beforeAccount": "Din samlede pris afhænger af brug, og du kan sætte månedlige udgiftsgrænser i din", + "zen.faq.a4.p2.accountLink": "konto", + "zen.faq.a4.p3": + "For at dække omkostninger tilføjer OpenCode kun et lille betalingsgebyr på $1.23 per $20 saldo-opfyldning.", + "zen.faq.q5": "Hvad med data og privatliv?", + "zen.faq.a5.beforeExceptions": + "Alle Zen-modeller hostes i USA. Udbydere følger en zero-retention-policy og bruger ikke dine data til modeltræning, med de", + "zen.faq.a5.exceptionsLink": "følgende undtagelser", + "zen.faq.q6": "Kan jeg sætte udgiftsgrænser?", + "zen.faq.a6": "Ja, du kan sætte månedlige udgiftsgrænser i din konto.", + "zen.faq.q7": "Kan jeg afmelde?", + "zen.faq.a7": "Ja, du kan deaktivere betaling når som helst og bruge din resterende saldo.", + "zen.faq.q8": "Kan jeg bruge Zen med andre kodningsagenter?", + "zen.faq.a8": + "Selvom Zen fungerer godt med OpenCode, kan du bruge Zen med enhver agent. Følg opsætningsinstruktionerne i din foretrukne kodningsagent.", + "zen.faq.q9": "Kan jeg få en refusion?", + "zen.faq.a9": + "Du kan muligvis få en refusion, hvis opkrævningen blev foretaget inden for de seneste 14 dage, og du ikke har brugt kreditten fra dette køb. {{contact}} for at anmode om en refusion.", + + "zen.cta.start": "Kom godt i gang med Zen", + "zen.pricing.title": "Tilføj $20 Pay as you go-saldo", + "zen.pricing.fee": "(+$1.23 kortbehandlingsgebyr)", + "zen.pricing.body": "Brug med enhver agent. Indstil månedlige forbrugsgrænser. Annuller til enhver tid.", + "zen.problem.title": "Hvilket problem løser Zen?", + "zen.problem.body": + "Der er så mange modeller tilgængelige, men kun få fungerer godt med kodningsagenter. De fleste udbydere konfigurerer dem anderledes med forskellige resultater.", + "zen.problem.subtitle": "Vi løser dette for alle, ikke kun OpenCode-brugere.", + "zen.problem.item1": "Test af udvalgte modeller og høring af deres teams", + "zen.problem.item2": "Samarbejde med udbydere for at sikre, at de bliver leveret korrekt", + "zen.problem.item3": "Benchmarking af alle model-udbyder kombinationer, vi anbefaler", + "zen.how.title": "Hvordan Zen virker", + "zen.how.body": "Selvom vi foreslår, at du bruger Zen med OpenCode, kan du bruge Zen med enhver agent.", + "zen.how.step1.title": "Tilmeld dig og tilføj saldo på $20", + "zen.how.step1.beforeLink": "følg", + "zen.how.step1.link": "opsætningsinstruktioner", + "zen.how.step2.title": "Brug Zen med gennemsigtige priser", + "zen.how.step2.link": "betal per request", + "zen.how.step2.afterLink": "med nul markups", + "zen.how.step3.title": "Auto-top op", + "zen.how.step3.body": "når din saldo når $5, tilføjer vi automatisk $20", + "zen.privacy.title": "Dit privatliv er vigtigt for os", + "zen.privacy.beforeExceptions": + "Alle Zen-modeller er hostet i USA. Udbydere følger en nulopbevaringspolitik og bruger ikke dine data til modeltræning med", + "zen.privacy.exceptionsLink": "følgende undtagelser", + + "go.title": "OpenCode Go | Kodningsmodeller til lav pris for alle", + "go.meta.description": + "Go koster $10/måned, med generøse brugsgrænser og pålidelig adgang til førende kodningsmodeller.", + "go.hero.title": "Kodningsmodeller til lav pris for alle", + "go.hero.body": + "Go bringer agentisk kodning til programmører over hele verden. Med generøse grænser og pålidelig adgang til de mest kapable open source-modeller, så du kan bygge med kraftfulde agenter uden at bekymre dig om omkostninger eller tilgængelighed.", + + "go.cta.start": "Abonner på Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Abonner på Go", + "go.cta.price": "$10/måned", + "go.pricing.body": "Brug med enhver agent. $10/måned. Tank op med kredit efter behov. Afmeld når som helst.", + "go.graph.free": "Gratis", + "go.graph.freePill": "Big Pickle og gratis modeller", + "go.graph.go": "Go", + "go.graph.label": "Forespørgsler pr. 5 timer", + "go.graph.period": "Forbrug", + "go.graph.model": "Model", + "go.graph.requests": "Estimerede anmodninger / 5 timer", + "go.graph.allowance": "Månedligt forbrug", + "go.graph.new": "Ny", + "go.graph.scale": "Ikke-lineær skala for anmodninger", + "go.graph.showAll": "Vis alle {{count}} modeller", + "go.graph.showLess": "Vis færre modeller", + "go.graph.limitedRegions": "begrænsede regioner", + "go.graph.limitedTime": "begrænset periode", + "go.graph.usageLimits": "Forbrugsgrænser", + "go.graph.aria": "Forespørgsler pr. 5t: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "har været livsændrende, det er virkelig en no-brainer.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Founder, SEED, PM, Melt, Pop, Dapt, Cadmus, og ViewPoint", + "go.testimonials.jay.quoteBefore": "4 ud af 5 personer på vores team elsker at bruge", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "Jeg kan ikke anbefale", + "go.testimonials.adam.quoteAfter": "nok. Seriøst, det er virkelig godt.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "Med", + "go.testimonials.david.quoteAfter": "ved jeg, at alle modellerne er testede og perfekte til kodningsagenter.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Intern, Nvidia (4 gange)", + "go.testimonials.frank.quote": "Jeg ville ønske, jeg stadig var hos Nvidia.", + "go.problem.title": "Hvilket problem løser Go?", + "go.problem.body": + "Vi fokuserer på at bringe OpenCode-oplevelsen ud til så mange som muligt. OpenCode Go er et lavprisabonnement til $10/måned. Det giver generøse grænser og pålidelig adgang til de mest kapable open source-modeller.", + "go.problem.subtitle": " ", + "go.problem.item1": "Lavpris abonnementspriser", + "go.problem.item2": "Generøse grænser og pålidelig adgang", + "go.problem.item3": "Bygget til så mange programmører som muligt", + "go.problem.item4": "Et kurateret modeludvalg testet til agentisk kodning", + "go.how.title": "Hvordan Go virker", + "go.how.body": "Go koster $10/måned. Du kan bruge det med OpenCode eller enhver agent.", + "go.how.step1.title": "Opret en konto", + "go.how.step1.beforeLink": "følg", + "go.how.step1.link": "opsætningsinstruktionerne", + "go.how.step2.title": "Abonner på Go", + "go.how.step2.link": "$10/måned", + "go.how.step2.afterLink": "med generøse grænser", + "go.how.step3.title": "Start kodning", + "go.how.step3.body": "med pålidelig adgang til open source-modeller", + "go.privacy.title": "Dit privatliv er vigtigt for os", + "go.privacy.body": + "Planen er primært designet til internationale brugere, med modeller hostet i USA, EU og Singapore for stabil global adgang.", + "go.privacy.contactAfter": "hvis du har spørgsmål.", + "go.privacy.beforeExceptions": + "Go-modeller hostes i USA. Udbydere følger en nulopbevaringspolitik og bruger ikke dine data til modeltræning, med de", + "go.privacy.exceptionsLink": "følgende undtagelser", + "go.faq.q1": "Hvad er OpenCode Go?", + "go.faq.a1": + "Go er et lavprisabonnement, der giver dig pålidelig adgang til kapable open source-modeller til agentisk kodning.", + "go.faq.q2": "Hvilke modeller inkluderer Go?", + "go.faq.a2": "Go inkluderer modellerne nedenfor med generøse grænser og pålidelig adgang.", + "go.faq.q3": "Er Go det samme som Zen?", + "go.faq.a3": + "Nej. Zen er pay-as-you-go, mens Go koster $10/måned, med generøse grænser og pålidelig adgang til et kurateret modeludvalg.", + "go.faq.q4": "Hvad koster Go?", + "go.faq.a4.p1.beforePricing": "Go koster", + "go.faq.a4.p1.pricingLink": "$10/måned", + "go.faq.a4.p1.afterPricing": "med generøse grænser.", + "go.faq.a4.p2.beforeAccount": "Du kan administrere dit abonnement i din", + "go.faq.a4.p2.accountLink": "konto", + "go.faq.a4.p3": "Annuller til enhver tid.", + "go.faq.q5": "Hvad med data og privatliv?", + "go.faq.a5.model": "Model", + "go.faq.a5.training": "Modeltræning", + "go.faq.a5.retention": "Dataopbevaring", + "go.faq.a5.retention30": "30 dage", + "go.faq.a5.retention0": "0 dage", + "go.faq.a5.used": "Brugt", + "go.faq.a5.notUsed": "Ikke brugt", + "go.faq.a5.noAgreement": "Ingen aftale", + "go.faq.a5.notZdr": "Ikke ZDR", + "go.faq.a5.grokRetention": + "ZDR deaktiverer vigtige API-funktioner, der afhænger af lagrede data, herunder den tilstandsbevarende Responses API, Files and Collections og Batch API.", + "go.faq.a5.gptRetention": + "Logfiler til overvågning af misbrug genereres ved al brug af API-funktioner og opbevares i op til 30 dage.", + "go.faq.a5.museRetention": + "Kraftigt nedsatte tokenpriser til gengæld for tilladelse til at bruge dine prompts og modelsvar til at træne fremtidige Meta-modeller.", + "go.faq.a5.learnMore": "Læs mere", + "go.faq.a5.deepseekRetention": + "ZDR-aftalen fornyes månedligt. Den nuværende aftale er gyldig til og med 30. september 2026.", + + "go.faq.a5.beforeExceptions": + "Go-modeller hostes i USA. Udbydere følger en nulopbevaringspolitik og bruger ikke dine data til modeltræning, med de", + "go.faq.a5.exceptionsLink": "følgende undtagelser", + "go.faq.q6": "Kan jeg tanke kredit op?", + "go.faq.a6": "Hvis du har brug for mere forbrug, kan du tanke kredit op på din konto.", + "go.faq.q7": "Kan jeg annullere?", + "go.faq.a7": "Ja, du kan annullere til enhver tid.", + "go.faq.q8": "Kan jeg bruge Go med andre kodningsagenter?", + "go.faq.a8": "Ja, du kan bruge Go med enhver agent. Følg opsætningsinstruktionerne i din foretrukne kodningsagent.", + + "go.faq.q9": "Hvad er forskellen på gratis modeller og Go?", + "go.faq.a9": + "Gratis modeller inkluderer Big Pickle plus kampagnemodeller, der er tilgængelige på det pågældende tidspunkt, med en kvote på 200 forespørgsler/dag. Go tilbyder et kurateret modeludvalg med højere forespørgselskvoter håndhævet over rullende perioder (5 timer, ugentligt og månedligt), omtrent svarende til basiskvoter på $12 pr. 5 timer, $30 pr. uge og $60 pr. måned; modelspecifikke kvoter kan variere (det faktiske antal forespørgsler varierer efter model og brug).", + "go.faq.q10": "Kan jeg få en refusion?", + "go.faq.a10": + "Du kan muligvis få en refusion, hvis opkrævningen blev foretaget inden for de seneste 14 dage, og du ikke har brugt din Go-kvote i den pågældende faktureringsperiode. {{contact}} for at anmode om en refusion.", + + "zen.api.error.rateLimitExceeded": "Hastighedsgrænse overskredet. Prøv venligst igen senere.", + "zen.api.error.modelNotSupported": "Model {{model}} understøttes ikke", + "zen.api.error.modelFormatNotSupported": "Model {{model}} understøttes ikke for format {{format}}", + "zen.api.error.noProviderAvailable": "Ingen udbyder tilgængelig", + "zen.api.error.providerNotSupported": "Udbyder {{provider}} understøttes ikke", + "zen.api.error.missingApiKey": "Manglende API-nøgle.", + "zen.api.error.invalidApiKey": "Ugyldig API-nøgle.", + "zen.api.error.requestBlockedByUpstreamProvider": "Anmodningen blev blokeret af upstream-udbyderen.", + "zen.api.error.subscriptionQuotaExceeded": "Abonnementskvote overskredet. Prøv igen om {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "Forbrugsgrænsen for 5 timer er nået. Nulstilles om {{retryIn}}. For at fortsætte med at bruge denne model nu, aktivér forbrug fra din tilgængelige saldo: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Ugentlig forbrugsgrænse er nået. Nulstilles om {{retryIn}}. For at fortsætte med at bruge denne model nu, aktivér forbrug fra din tilgængelige saldo: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Månedlig forbrugsgrænse er nået. Nulstilles om {{retryIn}}. For at fortsætte med at bruge denne model nu, aktivér forbrug fra din tilgængelige saldo: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Ingen betalingsmetode. Tilføj en betalingsmetode her: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Utilstrækkelig saldo. Administrer din fakturering her: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Dit workspace har nået sin månedlige forbrugsgrænse på ${{amount}}. Administrer dine grænser her: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Du har nået din månedlige forbrugsgrænse på ${{amount}}. Administrer dine grænser her: {{membersUrl}}", + "zen.api.error.modelDisabled": "Modellen er deaktiveret", + "zen.api.error.regionNotAllowed": + "Den nyeste version af denne model er kun tilgængelig som hostet i Kina og kræver, at du aktivt tilvælger den: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Denne model er ikke tilgængelig i dit land.", + "zen.api.error.trainingNotAllowed": + "Denne model indsamler data, der bruges til at forbedre dens kvalitet, og kræver, at du aktivt tilvælger den: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "Den gratis kampagne for {{model}} er afsluttet. Du kan fortsætte med at bruge modellen ved at abonnere på OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Få adgang til verdens bedste kodningsmodeller", + "black.meta.description": "Få adgang til Claude, GPT, Gemini og mere med OpenCode Black-abonnementer.", + "black.hero.title": "Få adgang til verdens bedste kodningsmodeller", + "black.hero.subtitle": "Inklusive Claude, GPT, Gemini og mere", + "black.title": "OpenCode Black | Priser", + "black.paused": "Black-plantilmelding er midlertidigt sat på pause.", + "black.plan.icon20": "Black 20-plan", + "black.plan.icon100": "Black 100-plan", + "black.plan.icon200": "Black 200-plan", + "black.plan.multiplier100": "5x mere brug end Black 20", + "black.plan.multiplier200": "20x mere brug end Black 20", + "black.price.perMonth": "pr. måned", + "black.price.perPersonBilledMonthly": "pr. person faktureret månedligt", + "black.terms.1": "Dit abonnement starter ikke med det samme", + "black.terms.2": "Du bliver sat på ventelisten og aktiveret snart", + "black.terms.3": "Dit kort debiteres først, når dit abonnement er aktiveret", + "black.terms.4": "Forbrugsgrænser gælder, tung automatiseret brug kan nå grænserne hurtigere", + "black.terms.5": "Abonnementer er for enkeltpersoner, kontakt Enterprise for teams", + "black.terms.6": "Grænser kan justeres, og planer kan blive udfaset i fremtiden", + "black.terms.7": "Opsig dit abonnement når som helst", + "black.action.continue": "Fortsæt", + "black.finePrint.beforeTerms": "Viste priser inkluderer ikke gældende skat", + "black.finePrint.terms": "Servicevilkår", + "black.workspace.title": "OpenCode Black | Vælg workspace", + "black.workspace.selectPlan": "Vælg et workspace til denne plan", + "black.workspace.name": "Workspace {{n}}", + "black.subscribe.title": "Abonner på OpenCode Black", + "black.subscribe.paymentMethod": "Betalingsmetode", + "black.subscribe.loadingPaymentForm": "Indlæser betalingsformular...", + "black.subscribe.selectWorkspaceToContinue": "Vælg et workspace for at fortsætte", + "black.subscribe.failurePrefix": "Åh nej!", + "black.subscribe.error.generic": "Der opstod en fejl", + "black.subscribe.error.invalidPlan": "Ugyldig plan", + "black.subscribe.error.workspaceRequired": "Workspace-ID er påkrævet", + "black.subscribe.error.alreadySubscribed": "Dette workspace har allerede et abonnement", + "black.subscribe.processing": "Behandler...", + "black.subscribe.submit": "Abonner ${{plan}}", + "black.subscribe.form.chargeNotice": "Du bliver først debiteret, når dit abonnement er aktiveret", + "black.subscribe.success.title": "Du er på OpenCode Black-ventelisten", + "black.subscribe.success.subscriptionPlan": "Abonnementsplan", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Beløb", + "black.subscribe.success.amountValue": "${{plan}} pr. måned", + "black.subscribe.success.paymentMethod": "Betalingsmetode", + "black.subscribe.success.dateJoined": "Dato tilmeldt", + "black.subscribe.success.chargeNotice": "Dit kort vil blive debiteret, når dit abonnement er aktiveret", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Brug", + "workspace.nav.apiKeys": "API-nøgler", + "workspace.nav.members": "Medlemmer", + "workspace.nav.billing": "Fakturering", + "workspace.nav.settings": "Indstillinger", + + "workspace.home.banner.beforeLink": "Pålidelige optimerede modeller til kodningsagenter.", + "workspace.lite.banner.beforeLink": "Lavpris kodemodeller for alle.", + "workspace.home.billing.loading": "Indlæser...", + "workspace.home.billing.enable": "Aktiver fakturering", + "workspace.home.billing.currentBalance": "Nuværende saldo", + + "workspace.newUser.feature.tested.title": "Testede og verificerede modeller", + "workspace.newUser.feature.tested.body": + "Vi har benchmarket og testet modeller specifikt til kodningsagenter for at sikre den bedste ydeevne.", + "workspace.newUser.feature.quality.title": "Højeste kvalitet", + "workspace.newUser.feature.quality.body": + "Få adgang til modeller konfigureret til optimal ydeevne - ingen nedgraderinger eller routing til billigere udbydere.", + "workspace.newUser.feature.lockin.title": "Ingen indlåsning", + "workspace.newUser.feature.lockin.body": + "Brug Zen med en hvilken som helst kodningsagent, og fortsæt med at bruge andre udbydere med opencode, når du vil.", + "workspace.newUser.copyApiKey": "Kopiér API-nøgle", + "workspace.newUser.copyKey": "Kopier nøgle", + "workspace.newUser.copied": "Kopieret!", + "workspace.newUser.step.enableBilling": "Aktiver fakturering", + "workspace.newUser.step.login.before": "Kør", + "workspace.newUser.step.login.after": "og vælg opencode", + "workspace.newUser.step.pasteKey": "Indsæt din API-nøgle", + "workspace.newUser.step.models.before": "Start opencode og kør", + "workspace.newUser.step.models.after": "for at vælge en model", + + "workspace.models.title": "Modeller", + "workspace.models.subtitle.beforeLink": "Administrer, hvilke modeller workspace-medlemmer kan få adgang til.", + "workspace.models.table.model": "Model", + "workspace.models.table.enabled": "Aktiveret", + + "workspace.providers.title": "Medbring din egen nøgle", + "workspace.providers.subtitle": "Konfigurer dine egne API-nøgler fra AI-udbydere.", + "workspace.providers.placeholder": "Indtast {{provider}} API-nøgle ({{prefix}}...)", + "workspace.providers.configure": "Konfigurer", + "workspace.providers.edit": "Rediger", + "workspace.providers.delete": "Slet", + "workspace.providers.saving": "Gemmer...", + "workspace.providers.save": "Gem", + "workspace.providers.table.provider": "Udbyder", + "workspace.providers.table.apiKey": "API-nøgle", + + "workspace.usage.title": "Brugshistorik", + "workspace.usage.subtitle": "Seneste API-brug og omkostninger.", + "workspace.usage.empty": "Foretag dit første API-opkald for at komme i gang.", + "workspace.usage.table.date": "Dato", + "workspace.usage.table.model": "Model", + "workspace.usage.table.input": "Input", + "workspace.usage.table.output": "Output", + "workspace.usage.table.cost": "Omkostning", + "workspace.usage.table.session": "Session", + "workspace.usage.breakdown.input": "Input", + "workspace.usage.breakdown.cacheRead": "Cache læst", + "workspace.usage.breakdown.cacheWrite": "Cache skriv", + "workspace.usage.breakdown.output": "Output", + "workspace.usage.breakdown.reasoning": "Ræsonnement", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Omkostninger", + "workspace.cost.subtitle": "Brugsomkostninger opdelt efter model.", + "workspace.cost.allModels": "Alle modeller", + "workspace.cost.allKeys": "Alle nøgler", + "workspace.cost.deletedSuffix": "(slettet)", + "workspace.cost.empty": "Ingen brugsdata tilgængelige for den valgte periode.", + "workspace.cost.subscriptionShort": "sub", + + "workspace.keys.title": "API-nøgler", + "workspace.keys.subtitle": "Administrer dine API-nøgler for at få adgang til opencode-tjenester.", + "workspace.keys.create": "Opret API-nøgle", + "workspace.keys.placeholder": "Indtast nøglenavn", + "workspace.keys.empty": "Opret en opencode Gateway API-nøgle", + "workspace.keys.table.name": "Navn", + "workspace.keys.table.key": "Nøgle", + "workspace.keys.table.createdBy": "Oprettet af", + "workspace.keys.table.lastUsed": "Sidst brugt", + "workspace.keys.copyApiKey": "Kopiér API-nøgle", + "workspace.keys.delete": "Slet", + + "workspace.members.title": "Medlemmer", + "workspace.members.subtitle": "Administrer workspace-medlemmer og deres tilladelser.", + "workspace.members.invite": "Inviter medlem", + "workspace.members.inviting": "Inviterer...", + "workspace.members.beta.beforeLink": "Workspaces er gratis for teams under betaversionen.", + "workspace.members.form.invitee": "Inviteret", + "workspace.members.form.emailPlaceholder": "Indtast e-mail", + "workspace.members.form.role": "Rolle", + "workspace.members.form.monthlyLimit": "Månedlig forbrugsgrænse", + "workspace.members.noLimit": "Ingen grænse", + "workspace.members.noLimitLowercase": "ingen grænse", + "workspace.members.invited": "inviteret", + "workspace.members.edit": "Rediger", + "workspace.members.delete": "Slet", + "workspace.members.saving": "Gemmer...", + "workspace.members.save": "Gem", + "workspace.members.table.email": "E-mail", + "workspace.members.table.role": "Rolle", + "workspace.members.table.monthLimit": "Månedsgrænse", + "workspace.members.role.admin": "Admin", + "workspace.members.role.adminDescription": "Kan administrere modeller, medlemmer og fakturering", + "workspace.members.role.member": "Medlem", + "workspace.members.role.memberDescription": "Kan kun generere API-nøgler til sig selv", + + "workspace.settings.title": "Indstillinger", + "workspace.settings.subtitle": "Opdater dit workspace-navn og præferencer.", + "workspace.settings.workspaceName": "Workspace-navn", + "workspace.settings.defaultName": "Standard", + "workspace.settings.updating": "Opdaterer...", + "workspace.settings.save": "Gem", + "workspace.settings.edit": "Rediger", + + "workspace.billing.title": "Fakturering", + "workspace.billing.subtitle.beforeLink": "Administrer betalingsmetoder.", + "workspace.billing.contactUs": "Kontakt os", + "workspace.billing.subtitle.afterLink": "hvis du har spørgsmål.", + "workspace.billing.currentBalance": "Nuværende saldo", + "workspace.billing.add": "Tilføj $", + "workspace.billing.enterAmount": "Indtast beløb", + "workspace.billing.loading": "Indlæser...", + "workspace.billing.addAction": "Tilføj", + "workspace.billing.addBalance": "Tilføj saldo", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Forbundet til Stripe", + "workspace.billing.manage": "Administrer", + "workspace.billing.enable": "Aktiver fakturering", + + "workspace.monthlyLimit.title": "Månedlig grænse", + "workspace.monthlyLimit.subtitle": "Indstil en månedlig forbrugsgrænse for din konto.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Indstiller...", + "workspace.monthlyLimit.set": "Sæt", + "workspace.monthlyLimit.edit": "Rediger grænse", + "workspace.monthlyLimit.noLimit": "Ingen forbrugsgrænse angivet.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Nuværende brug for", + "workspace.monthlyLimit.currentUsage.beforeAmount": "er $", + + "workspace.redeem.title": "Indløs kupon", + "workspace.redeem.subtitle": "Indløs en kuponkode for at få kreditter eller fordele.", + "workspace.redeem.placeholder": "Indtast kuponkode", + "workspace.redeem.redeem": "Indløs", + "workspace.redeem.redeeming": "Indløser...", + "workspace.redeem.success": "Kuponen blev indløst.", + + "workspace.reload.title": "Automatisk genopfyldning", + "workspace.reload.disabled.before": "Automatisk genopfyldning er", + "workspace.reload.disabled.state": "deaktiveret", + "workspace.reload.disabled.after": "Aktiver for automatisk at genopfylde, når saldoen er lav.", + "workspace.reload.enabled.before": "Automatisk genopfyldning er", + "workspace.reload.enabled.state": "aktiveret", + "workspace.reload.enabled.middle": "Vi genopfylder", + "workspace.reload.processingFee": "ekspeditionsgebyr", + "workspace.reload.enabled.after": "når saldoen når", + "workspace.reload.edit": "Rediger", + "workspace.reload.enable": "Aktiver", + "workspace.reload.enableAutoReload": "Aktiver automatisk genopfyldning", + "workspace.reload.reloadAmount": "Genopfyld $", + "workspace.reload.whenBalanceReaches": "Når saldoen når $", + "workspace.reload.saving": "Gemmer...", + "workspace.reload.save": "Gem", + "workspace.reload.failedAt": "Genopfyldning mislykkedes kl", + "workspace.reload.reason": "Årsag:", + "workspace.reload.updatePaymentMethod": "Opdater din betalingsmetode, og prøv igen.", + "workspace.reload.retrying": "Prøver igen...", + "workspace.reload.retry": "Prøv igen", + "workspace.reload.error.paymentFailed": "Betaling mislykkedes.", + + "workspace.payments.title": "Betalingshistorik", + "workspace.payments.subtitle": "Seneste betalingstransaktioner.", + "workspace.payments.table.date": "Dato", + "workspace.payments.table.paymentId": "Betalings-ID", + "workspace.payments.table.amount": "Beløb", + "workspace.payments.table.receipt": "Kvittering", + "workspace.payments.type.credit": "kredit", + "workspace.payments.type.subscription": "abonnement", + "workspace.payments.view": "Vis", + + "workspace.black.loading": "Indlæser...", + "workspace.black.time.day": "dag", + "workspace.black.time.days": "dage", + "workspace.black.time.hour": "time", + "workspace.black.time.hours": "timer", + "workspace.black.time.minute": "minut", + "workspace.black.time.minutes": "minutter", + "workspace.black.time.fewSeconds": "et par sekunder", + "workspace.black.subscription.title": "Abonnement", + "workspace.black.subscription.message": "Du abonnerer på OpenCode Black for ${{plan}} om måneden.", + "workspace.black.subscription.manage": "Administrer abonnement", + "workspace.black.subscription.rollingUsage": "5-timers brug", + "workspace.black.subscription.weeklyUsage": "Ugentlig brug", + "workspace.black.subscription.resetsIn": "Nulstiller i", + "workspace.black.subscription.useBalance": "Brug din tilgængelige saldo, når du har nået forbrugsgrænserne", + "workspace.black.waitlist.title": "Venteliste", + "workspace.black.waitlist.joined": "Du er på ventelisten for ${{plan}} per måned OpenCode Black plan.", + "workspace.black.waitlist.ready": "Vi er klar til at tilmelde dig ${{plan}} per måned OpenCode Black plan.", + "workspace.black.waitlist.leave": "Forlad venteliste", + "workspace.black.waitlist.leaving": "Forlader...", + "workspace.black.waitlist.left": "Forladt", + "workspace.black.waitlist.enroll": "Tilmeld", + "workspace.black.waitlist.enrolling": "Tilmelder...", + "workspace.black.waitlist.enrolled": "Tilmeldt", + "workspace.black.waitlist.enrollNote": + "Når du klikker på Tilmeld, starter dit abonnement med det samme, og dit kort vil blive debiteret.", + + "workspace.lite.loading": "Indlæser...", + "workspace.lite.time.day": "dag", + "workspace.lite.time.days": "dage", + "workspace.lite.time.hour": "time", + "workspace.lite.time.hours": "timer", + "workspace.lite.time.minute": "minut", + "workspace.lite.time.minutes": "minutter", + "workspace.lite.time.fewSeconds": "et par sekunder", + "workspace.lite.subscription.message": "Du abonnerer på OpenCode Go.", + "workspace.lite.subscription.manage": "Administrer abonnement", + "workspace.lite.subscription.rollingUsage": "5-timers forbrug", + "workspace.lite.subscription.rollingQuota": "5-timers kvote", + "workspace.lite.subscription.weeklyUsage": "Ugentligt forbrug", + "workspace.lite.subscription.weeklyQuota": "Ugentlig kvote", + "workspace.lite.subscription.monthlyUsage": "Månedligt forbrug", + "workspace.lite.subscription.monthlyQuota": "Månedlig kvote", + "workspace.lite.subscription.resetsIn": "Nulstiller i", + "workspace.lite.subscription.showDetails": "Vis detaljer", + "workspace.lite.subscription.hideDetails": "Skjul detaljer", + "workspace.lite.subscription.model": "Model", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "I alt", + "workspace.lite.subscription.useBalance": "Brug din tilgængelige saldo, når du har nået forbrugsgrænserne", + "workspace.lite.subscription.selectProvider": + 'Vælg "OpenCode Go" som udbyder i din opencode-konfiguration for at bruge Go-modeller.', + "workspace.lite.providers.title": "Udbydere", + "workspace.lite.providers.description": "Styr, hvilke udbydere der bruges til routing.", + "workspace.lite.providers.allowTraining": "Tillad modeller, der træner på anmodningsdata", + "workspace.lite.providers.useChina": "Aktivér modeller hostet i Kina", + "workspace.lite.black.message": + "Du abonnerer i øjeblikket på OpenCode Black eller er på venteliste. Afmeld venligst først, hvis du vil skifte til Go.", + "workspace.lite.other.message": + "Et andet medlem i dette workspace abonnerer allerede på OpenCode Go. Kun ét medlem pr. workspace kan abonnere.", + "workspace.lite.promo.description": + "OpenCode Go koster {{price}} og giver pålidelig adgang til populære åbne kodningsmodeller med generøse brugsgrænser.", + "workspace.lite.promo.price": "$10/måned", + "workspace.lite.promo.modelsTitle": "Hvad er inkluderet", + "workspace.lite.promo.footer": + "Planen er primært udviklet til internationale brugere og giver stabil adgang i hele verden. Priser og forbrugsgrænser kan ændre sig, efterhånden som vi lærer af de første brugserfaringer og tilbagemeldinger.", + "workspace.lite.promo.subscribe": "Abonner på Go", + "workspace.lite.promo.subscribing": "Omdirigerer...", + "workspace.lite.promo.otherMethods": "Andre betalingsmetoder", + "workspace.lite.promo.selectMethod": "Vælg betalingsmetode", + + "workspace.referral.copyLink": "Kopiér link", + "workspace.referral.copied": "Kopieret", + "workspace.referral.overview.title": "Inviter venner", + "workspace.referral.overview.subtitle": "Få $5, når en ven abonnerer. De får også $5.", + "workspace.referral.instructions.share": "Del dit henvisningslink", + "workspace.referral.instructions.subscribe": "Din ven tilmelder sig og abonnerer på Go", + "workspace.referral.instructions.claim": "I får begge $5 i forbrugskredit til at bruge på jeres Go-forbrugsgrænser", + "workspace.referral.rewards.title": "Henvisningsbelønninger", + "workspace.referral.rewards.description": "Brug tilgængelige henvisningskreditter på dit Go-forbrug.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} belønninger brugt.", + "workspace.referral.rewards.empty": "Ingen henvisningsbelønninger endnu.", + "workspace.referral.table.reward": "Belønning", + "workspace.referral.table.referral": "Beskrivelse", + "workspace.referral.table.date": "Dato", + "workspace.referral.reward.description.inviter": "Inviterede {{email}}", + "workspace.referral.reward.description.invitee": "Inviteret af {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Abonner for at låse op", + "workspace.referral.reward.action.view": "Vis belønning", + "workspace.referral.reward.action.applied": "Belønning brugt", + "workspace.referral.reward.source.pendingInviter": "Venter på, at de abonnerer", + "workspace.referral.reward.source.pendingInvitee": "Abonner for at låse belønningen op", + "workspace.referral.reward.source.available": "Belønning klar til brug", + "workspace.referral.reward.source.applied": "Belønning brugt", + "workspace.referral.reward.status.applied": "Belønning brugt", + "workspace.referral.reward.status.pendingInviter": "Abonner for at låse op", + "workspace.referral.reward.status.pendingInvitee": "Abonner for at låse op", + "workspace.referral.apply.noGo": "Abonner for at låse op", + "workspace.referral.apply.preview": "Vis belønning", + "workspace.referral.apply.action": "Brug", + "workspace.referral.apply.confirmTitle": "Brug belønning", + "workspace.referral.apply.confirmBody": "Brug {{amount}} til at reducere dette workspaces nuværende forbrug.", + "workspace.referral.apply.confirmAction": "Brug", + + "download.title": "OpenCode | Download", + "download.meta.description": "Download OpenCode til macOS, Windows og Linux", + "download.hero.title": "Download OpenCode Desktop", + "download.hero.subtitle": "Tilgængelig i beta til macOS, Windows og Linux", + "download.hero.button": "Download til {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "OpenCode Extensions", + "download.section.integrations": "OpenCode Integrations", + "download.action.download": "Download", + "download.action.install": "Installer", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Ikke nødvendigvis, men sandsynligvis. Du skal bruge et AI-abonnement hvis du vil forbinde OpenCode til en betalt udbyder, men du kan arbejde med", + "download.faq.a3.localLink": "lokale modeller", + "download.faq.a3.afterLocal.beforeZen": "gratis. Selvom vi opfordrer brugere til at bruge", + "download.faq.a3.afterZen": ", fungerer OpenCode med alle populære udbydere som OpenAI, Anthropic, xAI osv.", + + "download.faq.a5.p1": "OpenCode er 100% gratis at bruge.", + "download.faq.a5.p2.beforeZen": + "Eventuelle ekstra omkostninger kommer fra dit abonnement hos en modeludbyder. Selvom OpenCode fungerer med enhver modeludbyder, anbefaler vi at bruge", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": "Dine data og oplysninger gemmes kun når du opretter delbare links i OpenCode.", + "download.faq.a6.p2.beforeShare": "Læs mere om", + "download.faq.a6.shareLink": "delingssider", + + "enterprise.title": "OpenCode | Enterprise-løsninger til din organisation", + "enterprise.meta.description": "Kontakt OpenCode for enterprise-løsninger", + "enterprise.hero.title": "Din kode er din egen", + "enterprise.hero.body1": + "OpenCode fungerer sikkert inde i din organisation uden at lagre data eller kontekst og uden licensbegrænsninger eller ejerskabskrav. Start en prøveperiode med dit team, og udrul det derefter i hele din organisation ved at integrere det med dit SSO og din interne AI-gateway.", + "enterprise.hero.body2": "Fortæl os, hvordan vi kan hjælpe.", + "enterprise.form.name.label": "Fulde navn", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Rolle", + "enterprise.form.role.placeholder": "Bestyrelsesformand", + "enterprise.form.company.label": "Virksomhed", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Firma-e-mail", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Telefonnummer", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Hvilket problem prøver du at løse?", + "enterprise.form.message.placeholder": "Vi har brug for hjælp med...", + "enterprise.form.send": "Send", + "enterprise.form.sending": "Sender...", + "enterprise.form.success": "Besked sendt, vi vender tilbage snart.", + "enterprise.form.success.submitted": "Formular indsendt med succes.", + "enterprise.form.error.allFieldsRequired": "Alle felter er påkrævet.", + "enterprise.form.error.invalidEmailFormat": "Ugyldigt e-mailformat.", + "enterprise.form.error.internalServer": "Intern serverfejl.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "Hvad er OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise er til organisationer, der vil sikre, at deres kode og data aldrig forlader deres infrastruktur. Det kan gøres med en central konfiguration, der integrerer med dit SSO og din interne AI-gateway.", + "enterprise.faq.q2": "Hvordan kommer jeg i gang med OpenCode Enterprise?", + "enterprise.faq.a2": + "Start blot med en intern prøveperiode med dit team. OpenCode gemmer som standard ikke din kode eller kontekstdata, hvilket gør det nemt at komme i gang. Kontakt os derefter for at tale om priser og implementeringsmuligheder.", + "enterprise.faq.q3": "Hvordan fungerer enterprise-priser?", + "enterprise.faq.a3": + "Vi tilbyder enterprise-priser pr. bruger. Hvis du har din egen LLM-gateway, opkræver vi ikke for brugte tokens. Kontakt os for flere detaljer og et tilbud tilpasset din organisations behov.", + "enterprise.faq.q4": "Er mine data sikre med OpenCode Enterprise?", + "enterprise.faq.a4": + "Ja. OpenCode gemmer ikke din kode eller kontekstdata. Al behandling sker lokalt eller via direkte API-kald til din AI-udbyder. Med central konfiguration og SSO-integration forbliver dine data sikre inden for din organisations infrastruktur.", + + "brand.title": "OpenCode | Brand", + "brand.meta.description": "OpenCode brandretningslinjer", + "brand.heading": "Brandretningslinjer", + "brand.subtitle": "Ressourcer og assets, der hjælper dig med at arbejde med OpenCode-brandet.", + "brand.downloadAll": "Download alle assets", + + "changelog.title": "OpenCode | Changelog", + "changelog.meta.description": "OpenCode versionsnoter og changelog", + "changelog.hero.title": "Changelog", + "changelog.hero.subtitle": "Nye opdateringer og forbedringer til OpenCode", + "changelog.empty": "Ingen changelog-indlæg fundet.", + "changelog.viewJson": "Se JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarks", + "bench.list.table.agent": "Agent", + "bench.list.table.model": "Model", + "bench.list.table.score": "Score", + "bench.submission.error.allFieldsRequired": "Alle felter er påkrævet.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Opgave ikke fundet", + "bench.detail.na": "Ikke tilgængelig", + "bench.detail.labels.agent": "Agent", + "bench.detail.labels.model": "Model", + "bench.detail.labels.task": "Opgave", + "bench.detail.labels.repo": "Repo", + "bench.detail.labels.from": "Fra", + "bench.detail.labels.to": "Til", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Gennemsnitlig varighed", + "bench.detail.labels.averageScore": "Gennemsnitlig score", + "bench.detail.labels.averageCost": "Gennemsnitlig omkostning", + "bench.detail.labels.summary": "Resumé", + "bench.detail.labels.runs": "Kørsler", + "bench.detail.labels.score": "Score", + "bench.detail.labels.base": "Basis", + "bench.detail.labels.penalty": "Straf", + "bench.detail.labels.weight": "vægt", + "bench.detail.table.run": "Kørsel", + "bench.detail.table.score": "Score (Basis - Straf)", + "bench.detail.table.cost": "Omkostning", + "bench.detail.table.duration": "Varighed", + "bench.detail.run.title": "Kørsel {{n}}", + "bench.detail.rawJson": "Rå JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/de.ts b/packages/console/app/src/i18n/de.ts new file mode 100644 index 0000000000000000000000000000000000000000..8fb78e76e611ed533082cf0e14c6b04048bce23b --- /dev/null +++ b/packages/console/app/src/i18n/de.ts @@ -0,0 +1,879 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash erhält für begrenzte Zeit 4x Nutzungslimits", + "go.graph.bonus": "{{count}}× Nutzung", + "nav.github": "GitHub", + "nav.docs": "Dokumentation", + "nav.changelog": "Changelog", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Anmelden", + "nav.free": "Download", + "nav.home": "Startseite", + "nav.openMenu": "Menü öffnen", + "nav.getStartedFree": "Kostenlos starten", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Logo als SVG kopieren", + "nav.context.copyWordmark": "Wortmarke als SVG kopieren", + "nav.context.brandAssets": "Marken-Assets", + + "footer.github": "GitHub", + "footer.docs": "Dokumentation", + "footer.changelog": "Changelog", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Marke", + "legal.privacy": "Datenschutz", + "legal.terms": "AGB", + + "email.title": "Erfahre als Erste:r, wenn wir neue Produkte veröffentlichen", + "email.subtitle": "Trage dich in die Warteliste für frühen Zugang ein.", + "email.placeholder": "E-Mail-Adresse", + "email.subscribe": "Anmelden", + "email.success": "Fast geschafft, überprüfe deinen Posteingang und bestätige deine E-Mail-Adresse", + + "notFound.title": "Nicht gefunden | OpenCode", + "notFound.heading": "404 - Seite nicht gefunden", + "notFound.home": "Startseite", + "notFound.docs": "Dokumentation", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "OpenCode Logo hell", + "notFound.logoDarkAlt": "OpenCode Logo dunkel", + + "user.logout": "Abmelden", + + "auth.callback.error.codeMissing": "Kein Autorisierungscode gefunden.", + + "workspace.select": "Workspace auswählen", + "workspace.createNew": "+ Neuen Workspace erstellen", + "workspace.modal.title": "Neuen Workspace erstellen", + "workspace.modal.placeholder": "Workspace-Namen eingeben", + + "common.cancel": "Abbrechen", + "common.creating": "Erstelle...", + "common.create": "Erstellen", + "common.contactUs": "Kontaktiere uns", + + "common.videoUnsupported": "Dein Browser unterstützt das Video-Tag nicht.", + "common.figure": "Abb. {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Mehr erfahren", + + "error.invalidPlan": "Ungültiger Plan", + "error.workspaceRequired": "Workspace-ID ist erforderlich", + "error.alreadySubscribed": "Dieser Workspace hat bereits ein Abonnement", + "error.limitRequired": "Limit ist erforderlich.", + "error.monthlyLimitInvalid": "Bitte gib ein gültiges monatliches Limit ein.", + "error.workspaceNameRequired": "Workspace-Name ist erforderlich.", + "error.nameTooLong": "Der Name darf höchstens 255 Zeichen lang sein.", + "error.emailRequired": "E-Mail ist erforderlich", + "error.roleRequired": "Rolle ist erforderlich", + "error.idRequired": "ID ist erforderlich", + "error.nameRequired": "Name ist erforderlich", + "error.providerRequired": "Anbieter ist erforderlich", + "error.apiKeyRequired": "API-Key ist erforderlich", + "error.modelRequired": "Modell ist erforderlich", + "error.reloadAmountMin": "Aufladebetrag muss mindestens ${{amount}} betragen", + "error.reloadTriggerMin": "Guthaben-Auslöser muss mindestens ${{amount}} betragen", + + "app.meta.description": "OpenCode - Der Open-Source Coding-Agent.", + + "home.title": "OpenCode | Der Open-Source AI-Coding-Agent", + + "temp.title": "OpenCode | Für das Terminal gebauter AI-Coding-Agent", + "temp.hero.title": "Der für das Terminal gebaute AI-Coding-Agent", + "temp.zen": "OpenCode Zen", + "temp.getStarted": "Loslegen", + "temp.feature.native.title": "Native TUI", + "temp.feature.native.body": "Eine reaktionsschnelle, native, thematisierbare Terminal-UI", + "temp.feature.zen.beforeLink": "Eine", + "temp.feature.zen.link": "kuratierte Liste von Modellen", + "temp.feature.zen.afterLink": "bereitgestellt von OpenCode", + "temp.feature.models.beforeLink": "Unterstützt 75+ LLM-Anbieter durch", + "temp.feature.models.afterLink": ", einschließlich lokaler Modelle", + "temp.screenshot.caption": "OpenCode TUI mit dem Tokyonight-Theme", + "temp.screenshot.alt": "OpenCode TUI mit Tokyonight-Theme", + "temp.logoLightAlt": "OpenCode Logo hell", + "temp.logoDarkAlt": "OpenCode Logo dunkel", + + "home.banner.badge": "Neu", + "home.banner.text": "Neu: Tabs für Desktop.", + "home.banner.platforms": "Verfügbar für macOS, Windows und Linux", + "home.banner.downloadNow": "Jetzt herunterladen", + "home.banner.downloadBetaNow": "Desktop-Beta jetzt herunterladen", + "home.promo.title": "Neu: Tabs für Desktop", + "home.promo.body": "Organisiere deine Arbeit und aktiven Sitzungen mit Tabs.", + "home.promo.cta": "Lade die neueste Version herunter, um loszulegen.", + "home.promo.close": "Ankündigung zur Desktop-App schließen", + + "home.hero.title": "Der Open-Source AI-Coding-Agent", + "home.hero.subtitle.a": "Kostenlose Modelle inklusive oder verbinde jedes Modell eines beliebigen Anbieters,", + "home.hero.subtitle.b": "einschließlich Claude, GPT, Gemini und mehr.", + + "home.install.ariaLabel": "Installationsoptionen", + + "home.what.title": "Was ist OpenCode?", + "home.what.body": + "OpenCode ist ein Open-Source-Agent, der dir hilft, Code in deinem Terminal, deiner IDE oder auf dem Desktop zu schreiben.", + "home.what.lsp.title": "LSP-fähig", + "home.what.lsp.body": "Lädt automatisch die richtigen LSPs für das LLM", + "home.what.multiSession.title": "Multi-Session", + "home.what.multiSession.body": "Starte mehrere Agenten parallel im selben Projekt", + "home.what.shareLinks.title": "Links teilen", + "home.what.shareLinks.body": "Teile einen Link zu jeder Sitzung als Referenz oder zum Debuggen", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Melde dich mit GitHub an, um deinen Copilot-Account zu nutzen", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Melde dich mit OpenAI an, um deinen ChatGPT Plus- oder Pro-Account zu nutzen", + "home.what.anyModel.title": "Jedes Modell", + "home.what.anyModel.body": "75+ LLM-Anbieter durch Models.dev, einschließlich lokaler Modelle", + "home.what.anyEditor.title": "Jeder Editor", + "home.what.anyEditor.body": "Verfügbar als Terminal-Interface, Desktop-App und IDE-Extension", + "home.what.readDocs": "Doku lesen", + + "home.growth.title": "Der Open-Source AI-Coding-Agent", + "home.growth.body": + "Mit über {{stars}} GitHub-Stars, {{contributors}} Contributors und über {{commits}} Commits wird OpenCode von über {{monthlyUsers}} Entwickler:innen jeden Monat genutzt und geschätzt.", + "home.growth.githubStars": "GitHub Stars", + "home.growth.contributors": "Contributors", + "home.growth.monthlyDevs": "Monatliche Devs", + + "home.privacy.title": "Built for privacy first", + "home.privacy.body": + "OpenCode speichert keinen deiner Codes oder Kontextdaten, sodass es in datenschutzsensiblen Umgebungen arbeiten kann.", + "home.privacy.learnMore": "Erfahre mehr über", + "home.privacy.link": "Datenschutz", + + "home.faq.q1": "Was ist OpenCode?", + "home.faq.a1": + "OpenCode ist ein Open-Source-Agent, der dir hilft, Code mit jedem KI-Modell zu schreiben und auszuführen. Er ist als Terminal-Interface, Desktop-App oder IDE-Erweiterung verfügbar.", + "home.faq.q2": "Wie nutze ich OpenCode?", + "home.faq.a2.before": "Der einfachste Weg zu starten ist, die", + "home.faq.a2.link": "Einführung zu lesen", + "home.faq.q3": "Brauche ich zusätzliche AI-Abos, um OpenCode zu nutzen?", + "home.faq.a3.p1": + "Nicht unbedingt, OpenCode kommt mit einer Reihe kostenloser Modelle, die du ohne Account nutzen kannst.", + "home.faq.a3.p2.beforeZen": "Abgesehen davon kannst du jedes beliebige Coding-Modell nutzen, indem du einen", + "home.faq.a3.p2.afterZen": " Account erstellst.", + "home.faq.a3.p3": + "Während wir dazu raten, Zen zu nutzen, funktioniert OpenCode auch mit allen beliebten Anbietern wie OpenAI, Anthropic, xAI etc.", + "home.faq.a3.p4.beforeLocal": "Du kannst sogar deine", + "home.faq.a3.p4.localLink": "lokalen Modelle verbinden", + "home.faq.q4": "Kann ich meine bestehenden AI-Abos mit OpenCode nutzen?", + "home.faq.a4.p1": + "Ja, OpenCode unterstützt Abos von allen großen Anbietern. Du kannst deine Claude Pro/Max, ChatGPT Plus/Pro oder GitHub Copilot Abos nutzen.", + "home.faq.q5": "Kann ich OpenCode nur im Terminal nutzen?", + "home.faq.a5.beforeDesktop": "Nicht mehr! OpenCode ist jetzt als App für", + "home.faq.a5.desktop": "Desktop", + "home.faq.a5.and": "und", + "home.faq.a5.web": "Web verfügbar", + "home.faq.q6": "Wie viel kostet OpenCode?", + "home.faq.a6": + "OpenCode ist zu 100% kostenlos. Es enthält auch eine Reihe kostenloser Modelle. Zusätzliche Kosten können entstehen, wenn du andere Anbieter verbindest.", + "home.faq.q7": "Was ist mit Daten und Privatsphäre?", + "home.faq.a7.p1": + "Deine Daten und Informationen werden nur gespeichert, wenn du unsere kostenlosen Modelle nutzt oder teilbare Links erstellst.", + "home.faq.a7.p2.beforeModels": "Erfahre mehr über", + "home.faq.a7.p2.modelsLink": "unsere Modelle", + "home.faq.a7.p2.and": "und", + "home.faq.a7.p2.shareLink": "Share-Pages", + "home.faq.q8": "Ist OpenCode Open Source?", + "home.faq.a8.p1": "Ja, OpenCode ist vollständig Open Source. Der Quellcode ist öffentlich auf", + "home.faq.a8.p2": "unter der", + "home.faq.a8.mitLicense": "MIT Lizenz", + "home.faq.a8.p3": + ", was bedeutet, dass jeder ihn nutzen, modifizieren oder zu seiner Entwicklung beitragen kann. Jeder aus der Community kann Issues melden, Pull Requests einreichen und die Funktionalität erweitern.", + + "home.zenCta.title": "Zugriff auf zuverlässige, optimierte Modelle für Coding-Agents", + "home.zenCta.body": + "Zen gibt dir Zugriff auf ein handverlesenes Set an AI-Modellen, die OpenCode speziell für Coding-Agents getestet und bewertet hat. Keine Sorge wegen inkonsistenter Leistung und Qualität bei verschiedenen Anbietern – nutze validierte Modelle, die funktionieren.", + "home.zenCta.link": "Erfahre mehr über Zen", + + "zen.title": "OpenCode Zen | Ein kuratiertes Set zuverlässiger, optimierter Modelle für Coding-Agents", + "zen.hero.title": "Zuverlässige, optimierte Modelle für Coding-Agents", + "zen.hero.body": + "Zen gibt dir Zugriff auf ein kuratiertes Set an AI-Modellen, die OpenCode speziell für Coding-Agents getestet und bewertet hat. Keine Sorge wegen inkonsistenter Leistung und Qualität – nutze validierte Modelle, die funktionieren.", + + "zen.faq.q1": "Was ist OpenCode Zen?", + "zen.faq.a1": + "Zen ist ein kuratiertes Set an AI-Modellen, getestet und bewertet für Coding-Agents, erstellt vom Team hinter OpenCode.", + "zen.faq.q2": "Was macht Zen genauer?", + "zen.faq.a2": + "Zen bietet nur Modelle, die speziell für Coding-Agents getestet und bewertet wurden. Du würdest kein Buttermesser nehmen, um ein Steak zu schneiden – nutze keine schlechten Modelle zum Coden.", + "zen.faq.q3": "Ist Zen günstiger?", + "zen.faq.a3": + "Zen ist nicht gewinnorientiert. Zen gibt die Kosten der Modellanbieter an dich weiter. Je höher die Nutzung von Zen, desto besser kann OpenCode Preise verhandeln und diese an dich weitergeben.", + "zen.faq.q4": "Wie viel kostet Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "berechnet pro Anfrage", + "zen.faq.a4.p1.afterPricing": "ohne Aufschläge, also zahlst du genau das, was der Modellanbieter berechnet.", + "zen.faq.a4.p2.beforeAccount": + "Deine Gesamtkosten hängen von der Nutzung ab, und du kannst monatliche Ausgabenlimits in deinem", + "zen.faq.a4.p2.accountLink": "Account festlegen", + "zen.faq.a4.p3": + "Um die Kosten zu decken, fügt OpenCode nur eine kleine Bearbeitungsgebühr von $1.23 pro $20 Guthabenaufladung hinzu.", + "zen.faq.q5": "Was ist mit Daten und Privatsphäre?", + "zen.faq.a5.beforeExceptions": + "Alle Zen-Modelle werden in den USA gehostet. Anbieter folgen einer Zero-Retention-Policy und nutzen deine Daten nicht zum Trainieren von Modellen, mit den", + "zen.faq.a5.exceptionsLink": "folgenden Ausnahmen", + "zen.faq.q6": "Kann ich Ausgabenlimits setzen?", + "zen.faq.a6": "Ja, du kannst monatliche Ausgabenlimits in deinem Account setzen.", + "zen.faq.q7": "Kann ich kündigen?", + "zen.faq.a7": "Ja, du kannst die Abrechnung jederzeit deaktivieren und dein verbleibendes Guthaben nutzen.", + "zen.faq.q8": "Kann ich Zen mit anderen Coding-Agents nutzen?", + "zen.faq.a8": + "Während Zen großartig mit OpenCode funktioniert, kannst du Zen mit jedem Agent nutzen. Folge den Einrichtungsanweisungen in deinem bevorzugten Coding-Agent.", + "zen.faq.q9": "Kann ich eine Rückerstattung erhalten?", + "zen.faq.a9": + "Du hast möglicherweise Anspruch auf eine Rückerstattung, wenn die Zahlung innerhalb der letzten 14 Tage erfolgt ist und du das Guthaben aus diesem Kauf nicht verwendet hast. {{contact}}, um eine Rückerstattung anzufordern.", + + "zen.cta.start": "Starte mit Zen", + "zen.pricing.title": "Füge $20 Pay-as-you-go Guthaben hinzu", + "zen.pricing.fee": "(+$1.23 Bearbeitungsgebühr)", + "zen.pricing.body": "Nutze es mit jedem Agent. Setze monatliche Ausgabenlimits. Jederzeit kündbar.", + "zen.problem.title": "Welches Problem löst Zen?", + "zen.problem.body": + "Es gibt so viele Modelle, aber nur wenige funktionieren gut mit Coding-Agents. Die meisten Anbieter konfigurieren sie unterschiedlich, was zu variierenden Ergebnissen führt.", + "zen.problem.subtitle": "Wir beheben das für alle, nicht nur für OpenCode-Nutzer.", + "zen.problem.item1": "Testen ausgewählter Modelle und Beratung mit deren Teams", + "zen.problem.item2": "Zusammenarbeit mit Anbietern, um korrekte Bereitstellung zu sichern", + "zen.problem.item3": "Benchmarking aller Modell-Anbieter-Kombinationen, die wir empfehlen", + "zen.how.title": "Wie Zen funktioniert", + "zen.how.body": "Während wir dir raten, Zen mit OpenCode zu nutzen, kannst du Zen mit jedem Agent nutzen.", + "zen.how.step1.title": "Melde dich an und füge $20 Guthaben hinzu", + "zen.how.step1.beforeLink": "folge den", + "zen.how.step1.link": "Einrichtungsanweisungen", + "zen.how.step2.title": "Nutze Zen mit transparenter Preisgestaltung", + "zen.how.step2.link": "zahle pro Anfrage", + "zen.how.step2.afterLink": "ohne Aufschläge", + "zen.how.step3.title": "Auto-Top-up", + "zen.how.step3.body": "wenn dein Guthaben $5 erreicht, fügen wir automatisch $20 hinzu", + "zen.privacy.title": "Deine Privatsphäre ist uns wichtig", + "zen.privacy.beforeExceptions": + "Alle Zen-Modelle werden in den USA gehostet. Anbieter folgen einer Zero-Retention-Policy und nutzen deine Daten nicht für Modelltraining, mit den", + "zen.privacy.exceptionsLink": "folgenden Ausnahmen", + + "go.title": "OpenCode Go | Kostengünstige Coding-Modelle für alle", + "go.meta.description": + "Go kostet $10/Monat, mit großzügigen Nutzungslimits und zuverlässigem Zugang zu führenden Coding-Modellen.", + "go.hero.title": "Kostengünstige Coding-Modelle für alle", + "go.hero.body": + "Go bringt Agentic Coding zu Programmierern auf der ganzen Welt. Mit großzügigen Limits und zuverlässigem Zugang zu den leistungsfähigsten Open-Source-Modellen, damit du mit leistungsstarken Agenten entwickeln kannst, ohne dir Gedanken über Kosten oder Verfügbarkeit zu machen.", + + "go.cta.start": "Go abonnieren", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Go abonnieren", + "go.cta.price": "$10/Monat", + "go.pricing.body": "Mit jedem Agenten nutzbar. $10/Monat. Guthaben bei Bedarf aufladen. Jederzeit kündbar.", + "go.graph.free": "Kostenlos", + "go.graph.freePill": "Big Pickle und kostenlose Modelle", + "go.graph.go": "Go", + "go.graph.label": "Anfragen pro 5 Stunden", + "go.graph.period": "Nutzung", + "go.graph.model": "Modell", + "go.graph.requests": "Geschätzte Anfragen / 5 Std.", + "go.graph.allowance": "Monatliche Nutzung", + "go.graph.new": "Neu", + "go.graph.scale": "Nichtlineare Skala für Anfragen", + "go.graph.showAll": "Alle {{count}} Modelle anzeigen", + "go.graph.showLess": "Weniger Modelle anzeigen", + "go.graph.limitedRegions": "begrenzte Regionen", + "go.graph.limitedTime": "begrenzte Zeit", + "go.graph.usageLimits": "Nutzungslimits", + "go.graph.aria": "Anfragen pro 5h: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "hat mein Leben verändert, es ist wirklich ein No-Brainer.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Gründer, SEED, PM, Melt, Pop, Dapt, Cadmus und ViewPoint", + "go.testimonials.jay.quoteBefore": "4 von 5 Leuten in unserem Team lieben die Nutzung von", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "Ich kann", + "go.testimonials.adam.quoteAfter": "nicht genug empfehlen. Ernsthaft, es ist wirklich gut.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "Mit", + "go.testimonials.david.quoteAfter": "weiß ich, dass alle Modelle getestet und perfekt für Coding-Agenten sind.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Praktikant, Nvidia (4 mal)", + "go.testimonials.frank.quote": "Ich wünschte, ich wäre noch bei Nvidia.", + "go.problem.title": "Welches Problem löst Go?", + "go.problem.body": + "Wir konzentrieren uns darauf, die OpenCode-Erfahrung so vielen Menschen wie möglich zugänglich zu machen. OpenCode Go ist ein kostengünstiges Abonnement für $10/Monat. Es bietet großzügige Limits und zuverlässigen Zugang zu den leistungsfähigsten Open-Source-Modellen.", + "go.problem.subtitle": " ", + "go.problem.item1": "Kostengünstiges Abonnement", + "go.problem.item2": "Großzügige Limits und zuverlässiger Zugang", + "go.problem.item3": "Für so viele Programmierer wie möglich gebaut", + "go.problem.item4": "Eine kuratierte, für Agentic Coding getestete Modellauswahl", + "go.how.title": "Wie Go funktioniert", + "go.how.body": "Go kostet $10/Monat. Du kannst es mit OpenCode oder jedem Agenten nutzen.", + "go.how.step1.title": "Konto erstellen", + "go.how.step1.beforeLink": "folge den", + "go.how.step1.link": "Einrichtungsanweisungen", + "go.how.step2.title": "Go abonnieren", + "go.how.step2.link": "$10/Monat", + "go.how.step2.afterLink": "mit großzügigen Limits", + "go.how.step3.title": "Loslegen mit Coding", + "go.how.step3.body": "mit zuverlässigem Zugang zu Open-Source-Modellen", + "go.privacy.title": "Deine Privatsphäre ist uns wichtig", + "go.privacy.body": + "Der Plan ist primär für internationale Nutzer konzipiert, mit Modellen gehostet in den USA, der EU und Singapur für stabilen globalen Zugang.", + "go.privacy.contactAfter": "wenn du Fragen hast.", + "go.privacy.beforeExceptions": + "Go-Modelle werden in den USA gehostet. Anbieter verfolgen eine Zero-Retention-Politik und nutzen deine Daten nicht für das Training von Modellen, mit den", + "go.privacy.exceptionsLink": "folgenden Ausnahmen", + "go.faq.q1": "Was ist OpenCode Go?", + "go.faq.a1": + "Go ist ein kostengünstiges Abonnement, das dir zuverlässigen Zugang zu leistungsfähigen Open-Source-Modellen für Agentic Coding bietet.", + "go.faq.q2": "Welche Modelle beinhaltet Go?", + "go.faq.a2": "Go umfasst die unten aufgeführten Modelle mit großzügigen Limits und zuverlässigem Zugriff.", + "go.faq.q3": "Ist Go dasselbe wie Zen?", + "go.faq.a3": + "Nein. Zen ist Pay-as-you-go, während Go $10/Monat kostet, mit großzügigen Limits und zuverlässigem Zugang zu einer kuratierten Modellauswahl.", + "go.faq.q4": "Wie viel kostet Go?", + "go.faq.a4.p1.beforePricing": "Go kostet", + "go.faq.a4.p1.pricingLink": "$10/Monat", + "go.faq.a4.p1.afterPricing": "mit großzügigen Limits.", + "go.faq.a4.p2.beforeAccount": "Du kannst dein Abonnement in deinem", + "go.faq.a4.p2.accountLink": "Konto verwalten", + "go.faq.a4.p3": "Jederzeit kündbar.", + "go.faq.q5": "Was ist mit Daten und Privatsphäre?", + "go.faq.a5.model": "Modell", + "go.faq.a5.training": "Modelltraining", + "go.faq.a5.retention": "Datenaufbewahrung", + "go.faq.a5.retention30": "30 Tage", + "go.faq.a5.retention0": "0 Tage", + "go.faq.a5.used": "Verwendet", + "go.faq.a5.notUsed": "Nicht verwendet", + "go.faq.a5.noAgreement": "Keine Vereinbarung", + "go.faq.a5.notZdr": "Kein ZDR", + "go.faq.a5.grokRetention": + "ZDR deaktiviert wichtige API-Funktionen, die von gespeicherten Daten abhängen, einschließlich der zustandsbehafteten Responses API, Files and Collections und der Batch API.", + "go.faq.a5.gptRetention": + "Für die Nutzung aller API-Funktionen werden Protokolle zur Missbrauchsüberwachung erstellt und bis zu 30 Tage lang aufbewahrt.", + "go.faq.a5.museRetention": + "Stark vergünstigte Tokenpreise im Gegenzug für die Erlaubnis, deine Prompts und Vervollständigungen zum Trainieren zukünftiger Meta-Modelle zu verwenden.", + "go.faq.a5.learnMore": "Mehr erfahren", + "go.faq.a5.deepseekRetention": + "Die ZDR-Vereinbarung wird monatlich erneuert. Die aktuelle Vereinbarung gilt bis einschließlich 30. September 2026.", + "go.faq.a5.beforeExceptions": + "Go-Modelle werden in den USA gehostet. Anbieter verfolgen eine Zero-Retention-Politik und nutzen deine Daten nicht für das Training von Modellen, mit den", + "go.faq.a5.exceptionsLink": "folgenden Ausnahmen", + "go.faq.q6": "Kann ich Guthaben aufladen?", + "go.faq.a6": "Wenn du mehr Nutzung benötigst, kannst du Guthaben in deinem Konto aufladen.", + "go.faq.q7": "Kann ich kündigen?", + "go.faq.a7": "Ja, du kannst jederzeit kündigen.", + "go.faq.q8": "Kann ich Go mit anderen Coding-Agenten nutzen?", + "go.faq.a8": + "Ja, du kannst Go mit jedem Agenten nutzen. Folge den Einrichtungsanweisungen in deinem bevorzugten Coding-Agenten.", + + "go.faq.q9": "Was ist der Unterschied zwischen kostenlosen Modellen und Go?", + "go.faq.a9": + "Kostenlose Modelle beinhalten Big Pickle sowie Werbemodelle, die zum jeweiligen Zeitpunkt verfügbar sind, mit einem Kontingent von 200 Anfragen/Tag. Go bietet eine kuratierte Modellauswahl mit höheren Anfragekontingenten, die über rollierende Zeitfenster (5 Stunden, wöchentlich und monatlich) durchgesetzt werden, grob äquivalent zu Basiskontingenten von $12 pro 5 Stunden, $30 pro Woche und $60 pro Monat; modellspezifische Kontingente können abweichen (tatsächliche Anfragezahlen variieren je nach Modell und Nutzung).", + "go.faq.q10": "Kann ich eine Rückerstattung erhalten?", + "go.faq.a10": + "Du hast möglicherweise Anspruch auf eine Rückerstattung, wenn die Zahlung innerhalb der letzten 14 Tage erfolgt ist und du dein Go-Kontingent in diesem Abrechnungszeitraum nicht genutzt hast. {{contact}}, um eine Rückerstattung anzufordern.", + + "zen.api.error.rateLimitExceeded": "Ratenlimit überschritten. Bitte versuche es später erneut.", + "zen.api.error.modelNotSupported": "Modell {{model}} wird nicht unterstützt", + "zen.api.error.modelFormatNotSupported": "Modell {{model}} wird für das Format {{format}} nicht unterstützt", + "zen.api.error.noProviderAvailable": "Kein Anbieter verfügbar", + "zen.api.error.providerNotSupported": "Anbieter {{provider}} wird nicht unterstützt", + "zen.api.error.missingApiKey": "Fehlender API-Key.", + "zen.api.error.invalidApiKey": "Ungültiger API-Key.", + "zen.api.error.requestBlockedByUpstreamProvider": "Anfrage vom vorgelagerten Anbieter blockiert.", + "zen.api.error.subscriptionQuotaExceeded": "Abonnement-Quote überschritten. Erneuter Versuch in {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "5-Stunden-Nutzungslimit erreicht. Wird in {{retryIn}} zurückgesetzt. Um dieses Modell jetzt weiter zu nutzen, aktiviere die Nutzung über dein verfügbares Guthaben: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Wöchentliches Nutzungslimit erreicht. Wird in {{retryIn}} zurückgesetzt. Um dieses Modell jetzt weiter zu nutzen, aktiviere die Nutzung über dein verfügbares Guthaben: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Monatliches Nutzungslimit erreicht. Wird in {{retryIn}} zurückgesetzt. Um dieses Modell jetzt weiter zu nutzen, aktiviere die Nutzung über dein verfügbares Guthaben: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Keine Zahlungsmethode. Füge hier eine Zahlungsmethode hinzu: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Unzureichendes Guthaben. Verwalte deine Abrechnung hier: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Dein Workspace hat sein monatliches Ausgabenlimit von ${{amount}} erreicht. Verwalte deine Limits hier: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Du hast dein monatliches Ausgabenlimit von ${{amount}} erreicht. Verwalte deine Limits hier: {{membersUrl}}", + "zen.api.error.modelDisabled": "Modell ist deaktiviert", + "zen.api.error.regionNotAllowed": + "Die neueste Version dieses Modells ist nur verfügbar, wenn sie in China gehostet wird, und muss ausdrücklich aktiviert werden: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Dieses Modell ist in deinem Land nicht verfügbar.", + "zen.api.error.trainingNotAllowed": + "Dieses Modell erfasst Daten, die zur Verbesserung seiner Qualität verwendet werden, und erfordert deine ausdrückliche Zustimmung: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "Die kostenlose Aktion für {{model}} ist beendet. Du kannst das Modell weiterhin nutzen, indem du OpenCode Go abonnierst - {{link}}", + + "black.meta.title": "OpenCode Black | Zugriff auf die weltweit besten Coding-Modelle", + "black.meta.description": "Erhalte Zugriff auf Claude, GPT, Gemini und mehr mit OpenCode Black Abos.", + "black.hero.title": "Zugriff auf die weltweit besten Coding-Modelle", + "black.hero.subtitle": "Einschließlich Claude, GPT, Gemini und mehr", + "black.title": "OpenCode Black | Preise", + "black.paused": "Die Anmeldung zum Black-Plan ist vorübergehend pausiert.", + "black.plan.icon20": "Black 20 Plan", + "black.plan.icon100": "Black 100 Plan", + "black.plan.icon200": "Black 200 Plan", + "black.plan.multiplier100": "5x mehr Nutzung als Black 20", + "black.plan.multiplier200": "20x mehr Nutzung als Black 20", + "black.price.perMonth": "pro Monat", + "black.price.perPersonBilledMonthly": "pro Person, monatlich abgerechnet", + "black.terms.1": "Dein Abonnement startet nicht sofort", + "black.terms.2": "Du wirst auf die Warteliste gesetzt und bald freigeschaltet", + "black.terms.3": "Deine Karte wird erst belastet, wenn dein Abonnement aktiviert ist", + "black.terms.4": "Nutzungslimits gelten, stark automatisierte Nutzung kann Limits schneller erreichen", + "black.terms.5": "Abonnements sind für Einzelpersonen, kontaktiere Enterprise für Teams", + "black.terms.6": "Limits können angepasst werden und Pläne können in Zukunft eingestellt werden", + "black.terms.7": "Kündige dein Abonnement jederzeit", + "black.action.continue": "Weiter", + "black.finePrint.beforeTerms": "Angezeigte Preise enthalten keine anfallenden Steuern", + "black.finePrint.terms": "Nutzungsbedingungen", + "black.workspace.title": "OpenCode Black | Workspace wählen", + "black.workspace.selectPlan": "Wähle einen Workspace für diesen Plan", + "black.workspace.name": "Workspace {{n}}", + "black.subscribe.title": "OpenCode Black abonnieren", + "black.subscribe.paymentMethod": "Zahlungsmethode", + "black.subscribe.loadingPaymentForm": "Lade Zahlungsformular...", + "black.subscribe.selectWorkspaceToContinue": "Wähle einen Workspace um fortzufahren", + "black.subscribe.failurePrefix": "Oh nein!", + "black.subscribe.error.generic": "Ein Fehler ist aufgetreten", + "black.subscribe.error.invalidPlan": "Ungültiger Plan", + "black.subscribe.error.workspaceRequired": "Workspace-ID ist erforderlich", + "black.subscribe.error.alreadySubscribed": "Dieser Workspace hat bereits ein Abonnement", + "black.subscribe.processing": "Verarbeitung...", + "black.subscribe.submit": "Abonnieren ${{plan}}", + "black.subscribe.form.chargeNotice": "Du wirst erst belastet, wenn dein Abonnement aktiviert ist", + "black.subscribe.success.title": "Du bist auf der OpenCode Black Warteliste", + "black.subscribe.success.subscriptionPlan": "Abo-Plan", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Betrag", + "black.subscribe.success.amountValue": "${{plan}} pro Monat", + "black.subscribe.success.paymentMethod": "Zahlungsmethode", + "black.subscribe.success.dateJoined": "Beitrittsdatum", + "black.subscribe.success.chargeNotice": "Deine Karte wird belastet, sobald dein Abonnement aktiviert ist", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Nutzung", + "workspace.nav.apiKeys": "API Keys", + "workspace.nav.members": "Mitglieder", + "workspace.nav.billing": "Abrechnung", + "workspace.nav.settings": "Einstellungen", + + "workspace.home.banner.beforeLink": "Zuverlässige, optimierte Modelle für Coding-Agents.", + "workspace.lite.banner.beforeLink": "Kostengünstige Coding-Modelle für alle.", + "workspace.home.billing.loading": "Laden...", + "workspace.home.billing.enable": "Abrechnung aktivieren", + "workspace.home.billing.currentBalance": "Aktuelles Guthaben", + + "workspace.newUser.feature.tested.title": "Getestete & Verifizierte Modelle", + "workspace.newUser.feature.tested.body": + "Wir haben Modelle speziell für Coding-Agents getestet und bewertet, um beste Leistung zu garantieren.", + "workspace.newUser.feature.quality.title": "Höchste Qualität", + "workspace.newUser.feature.quality.body": + "Zugriff auf Modelle, die für optimale Leistung konfiguriert sind – keine Downgrades oder Routing zu billigeren Anbietern.", + "workspace.newUser.feature.lockin.title": "Kein Lock-in", + "workspace.newUser.feature.lockin.body": + "Nutze Zen mit jedem Coding-Agent und nutze weiterhin andere Anbieter mit OpenCode, wann immer du willst.", + "workspace.newUser.copyApiKey": "API Key kopieren", + "workspace.newUser.copyKey": "Key kopieren", + "workspace.newUser.copied": "Kopiert!", + "workspace.newUser.step.enableBilling": "Abrechnung aktivieren", + "workspace.newUser.step.login.before": "Führe", + "workspace.newUser.step.login.after": "aus und wähle OpenCode", + "workspace.newUser.step.pasteKey": "Füge deinen API Key ein", + "workspace.newUser.step.models.before": "Starte OpenCode und führe", + "workspace.newUser.step.models.after": "aus, um ein Modell zu wählen", + + "workspace.models.title": "Modelle", + "workspace.models.subtitle.beforeLink": "Verwalte, auf welche Modelle Workspace-Mitglieder zugreifen können.", + "workspace.models.table.model": "Modell", + "workspace.models.table.enabled": "Aktiviert", + + "workspace.providers.title": "Bring Your Own Key", + "workspace.providers.subtitle": "Konfiguriere deine eigenen API Keys von AI-Anbietern.", + "workspace.providers.placeholder": "Gib {{provider}} API Key ein ({{prefix}}...)", + "workspace.providers.configure": "Konfigurieren", + "workspace.providers.edit": "Bearbeiten", + "workspace.providers.delete": "Löschen", + "workspace.providers.saving": "Speichere...", + "workspace.providers.save": "Speichern", + "workspace.providers.table.provider": "Anbieter", + "workspace.providers.table.apiKey": "API Key", + + "workspace.usage.title": "Nutzungsverlauf", + "workspace.usage.subtitle": "Kürzliche API-Nutzung und Kosten.", + "workspace.usage.empty": "Mache deinen ersten API-Aufruf, um loszulegen.", + "workspace.usage.table.date": "Datum", + "workspace.usage.table.model": "Modell", + "workspace.usage.table.input": "Input", + "workspace.usage.table.output": "Output", + "workspace.usage.table.cost": "Kosten", + "workspace.usage.table.session": "Sitzung", + "workspace.usage.breakdown.input": "Input", + "workspace.usage.breakdown.cacheRead": "Cache Read", + "workspace.usage.breakdown.cacheWrite": "Cache Write", + "workspace.usage.breakdown.output": "Output", + "workspace.usage.breakdown.reasoning": "Reasoning", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Kosten", + "workspace.cost.subtitle": "Nutzungskosten aufgeschlüsselt nach Modell.", + "workspace.cost.allModels": "Alle Modelle", + "workspace.cost.allKeys": "Alle Keys", + "workspace.cost.deletedSuffix": "(gelöscht)", + "workspace.cost.empty": "Keine Nutzungsdaten für den gewählten Zeitraum verfügbar.", + "workspace.cost.subscriptionShort": "Abo", + + "workspace.keys.title": "API Keys", + "workspace.keys.subtitle": "Verwalte deine API Keys für den Zugriff auf OpenCode-Dienste.", + "workspace.keys.create": "API Key erstellen", + "workspace.keys.placeholder": "Key-Namen eingeben", + "workspace.keys.empty": "Erstelle einen OpenCode Gateway API Key", + "workspace.keys.table.name": "Name", + "workspace.keys.table.key": "Key", + "workspace.keys.table.createdBy": "Erstellt von", + "workspace.keys.table.lastUsed": "Zuletzt genutzt", + "workspace.keys.copyApiKey": "API Key kopieren", + "workspace.keys.delete": "Löschen", + + "workspace.members.title": "Mitglieder", + "workspace.members.subtitle": "Verwalte Workspace-Mitglieder und deren Berechtigungen.", + "workspace.members.invite": "Mitglied einladen", + "workspace.members.inviting": "Lade ein...", + "workspace.members.beta.beforeLink": "Workspaces sind für Teams während der Beta kostenlos.", + "workspace.members.form.invitee": "Eingeladene Person", + "workspace.members.form.emailPlaceholder": "E-Mail eingeben", + "workspace.members.form.role": "Rolle", + "workspace.members.form.monthlyLimit": "Monatliches Ausgabenlimit", + "workspace.members.noLimit": "Kein Limit", + "workspace.members.noLimitLowercase": "kein Limit", + "workspace.members.invited": "eingeladen", + "workspace.members.edit": "Bearbeiten", + "workspace.members.delete": "Löschen", + "workspace.members.saving": "Speichere...", + "workspace.members.save": "Speichern", + "workspace.members.table.email": "E-Mail", + "workspace.members.table.role": "Rolle", + "workspace.members.table.monthLimit": "Monatslimit", + "workspace.members.role.admin": "Admin", + "workspace.members.role.adminDescription": "Kann Modelle, Mitglieder und Abrechnung verwalten", + "workspace.members.role.member": "Mitglied", + "workspace.members.role.memberDescription": "Kann nur API Keys für sich selbst generieren", + + "workspace.settings.title": "Einstellungen", + "workspace.settings.subtitle": "Aktualisiere deinen Workspace-Namen und Präferenzen.", + "workspace.settings.workspaceName": "Workspace-Name", + "workspace.settings.defaultName": "Standard", + "workspace.settings.updating": "Aktualisiere...", + "workspace.settings.save": "Speichern", + "workspace.settings.edit": "Bearbeiten", + + "workspace.billing.title": "Abrechnung", + "workspace.billing.subtitle.beforeLink": "Zahlungsmethoden verwalten.", + "workspace.billing.contactUs": "Kontaktiere uns", + "workspace.billing.subtitle.afterLink": "wenn du Fragen hast.", + "workspace.billing.currentBalance": "Aktuelles Guthaben", + "workspace.billing.add": "$ hinzufügen", + "workspace.billing.enterAmount": "Betrag eingeben", + "workspace.billing.loading": "Lade...", + "workspace.billing.addAction": "Hinzufügen", + "workspace.billing.addBalance": "Guthaben aufladen", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Mit Stripe verbunden", + "workspace.billing.manage": "Verwalten", + "workspace.billing.enable": "Abrechnung aktivieren", + + "workspace.monthlyLimit.title": "Monatliches Limit", + "workspace.monthlyLimit.subtitle": "Setze ein monatliches Nutzungslimit für deinen Account.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Setze...", + "workspace.monthlyLimit.set": "Setzen", + "workspace.monthlyLimit.edit": "Limit bearbeiten", + "workspace.monthlyLimit.noLimit": "Kein Nutzungslimit gesetzt.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Aktuelle Nutzung für", + "workspace.monthlyLimit.currentUsage.beforeAmount": "ist $", + + "workspace.redeem.title": "Gutschein einlösen", + "workspace.redeem.subtitle": "Löse einen Gutscheincode ein, um Guthaben oder Vorteile zu erhalten.", + "workspace.redeem.placeholder": "Gutscheincode eingeben", + "workspace.redeem.redeem": "Einlösen", + "workspace.redeem.redeeming": "Wird eingelöst...", + "workspace.redeem.success": "Gutschein erfolgreich eingelöst.", + + "workspace.reload.title": "Auto-Reload", + "workspace.reload.disabled.before": "Auto-Reload ist", + "workspace.reload.disabled.state": "deaktiviert", + "workspace.reload.disabled.after": "Aktivieren, um automatisch aufzuladen, wenn das Guthaben niedrig ist.", + "workspace.reload.enabled.before": "Auto-Reload ist", + "workspace.reload.enabled.state": "aktiviert", + "workspace.reload.enabled.middle": "Wir laden auf", + "workspace.reload.processingFee": "Bearbeitungsgebühr", + "workspace.reload.enabled.after": "wenn das Guthaben erreicht:", + "workspace.reload.edit": "Bearbeiten", + "workspace.reload.enable": "Aktivieren", + "workspace.reload.enableAutoReload": "Auto-Reload aktivieren", + "workspace.reload.reloadAmount": "Aufladebetrag $", + "workspace.reload.whenBalanceReaches": "Wenn Guthaben $ erreicht", + "workspace.reload.saving": "Speichere...", + "workspace.reload.save": "Speichern", + "workspace.reload.failedAt": "Aufladung fehlgeschlagen am", + "workspace.reload.reason": "Grund:", + "workspace.reload.updatePaymentMethod": "Bitte aktualisiere deine Zahlungsmethode und versuche es erneut.", + "workspace.reload.retrying": "Versuche erneut...", + "workspace.reload.retry": "Erneut versuchen", + "workspace.reload.error.paymentFailed": "Zahlung fehlgeschlagen.", + + "workspace.payments.title": "Zahlungshistorie", + "workspace.payments.subtitle": "Kürzliche Zahlungstransaktionen.", + "workspace.payments.table.date": "Datum", + "workspace.payments.table.paymentId": "Zahlungs-ID", + "workspace.payments.table.amount": "Betrag", + "workspace.payments.table.receipt": "Beleg", + "workspace.payments.type.credit": "Guthaben", + "workspace.payments.type.subscription": "Abonnement", + "workspace.payments.view": "Ansehen", + + "workspace.black.loading": "Lade...", + "workspace.black.time.day": "Tag", + "workspace.black.time.days": "Tage", + "workspace.black.time.hour": "Stunde", + "workspace.black.time.hours": "Stunden", + "workspace.black.time.minute": "Minute", + "workspace.black.time.minutes": "Minuten", + "workspace.black.time.fewSeconds": "einige Sekunden", + "workspace.black.subscription.title": "Abonnement", + "workspace.black.subscription.message": "Du hast OpenCode Black für ${{plan}} pro Monat abonniert.", + "workspace.black.subscription.manage": "Abo verwalten", + "workspace.black.subscription.rollingUsage": "5-Stunden-Nutzung", + "workspace.black.subscription.weeklyUsage": "Wöchentliche Nutzung", + "workspace.black.subscription.resetsIn": "Setzt zurück in", + "workspace.black.subscription.useBalance": "Nutze dein verfügbares Guthaben, nachdem die Limits erreicht sind", + "workspace.black.waitlist.title": "Warteliste", + "workspace.black.waitlist.joined": "Du bist auf der Warteliste für den ${{plan}} pro Monat OpenCode Black Plan.", + "workspace.black.waitlist.ready": "Wir sind bereit, dich in den ${{plan}} pro Monat OpenCode Black Plan aufzunehmen.", + "workspace.black.waitlist.leave": "Warteliste verlassen", + "workspace.black.waitlist.leaving": "Verlasse...", + "workspace.black.waitlist.left": "Verlassen", + "workspace.black.waitlist.enroll": "Einschreiben", + "workspace.black.waitlist.enrolling": "Schreibe ein...", + "workspace.black.waitlist.enrolled": "Eingeschrieben", + "workspace.black.waitlist.enrollNote": + "Wenn du auf Einschreiben klickst, startet dein Abo sofort und deine Karte wird belastet.", + + "workspace.lite.loading": "Lade...", + "workspace.lite.time.day": "Tag", + "workspace.lite.time.days": "Tage", + "workspace.lite.time.hour": "Stunde", + "workspace.lite.time.hours": "Stunden", + "workspace.lite.time.minute": "Minute", + "workspace.lite.time.minutes": "Minuten", + "workspace.lite.time.fewSeconds": "einige Sekunden", + "workspace.lite.subscription.message": "Du hast OpenCode Go abonniert.", + "workspace.lite.subscription.manage": "Abo verwalten", + "workspace.lite.subscription.rollingUsage": "5-Stunden-Nutzung", + "workspace.lite.subscription.rollingQuota": "5-Stunden-Kontingent", + "workspace.lite.subscription.weeklyUsage": "Wöchentliche Nutzung", + "workspace.lite.subscription.weeklyQuota": "Wöchentliches Kontingent", + "workspace.lite.subscription.monthlyUsage": "Monatliche Nutzung", + "workspace.lite.subscription.monthlyQuota": "Monatliches Kontingent", + "workspace.lite.subscription.resetsIn": "Setzt zurück in", + "workspace.lite.subscription.showDetails": "Details anzeigen", + "workspace.lite.subscription.hideDetails": "Details ausblenden", + "workspace.lite.subscription.model": "Modell", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Gesamt", + "workspace.lite.subscription.useBalance": "Nutze dein verfügbares Guthaben, nachdem die Nutzungslimits erreicht sind", + "workspace.lite.subscription.selectProvider": + 'Wähle "OpenCode Go" als Anbieter in deiner opencode-Konfiguration, um Go-Modelle zu verwenden.', + "workspace.lite.providers.title": "Anbieter", + "workspace.lite.providers.description": "Steuere, welche Anbieter für das Routing verwendet werden.", + "workspace.lite.providers.allowTraining": "Modelle zulassen, die mit Anfragedaten trainieren", + "workspace.lite.providers.useChina": "In China gehostete Modelle aktivieren", + "workspace.lite.black.message": + "Du hast derzeit OpenCode Black abonniert oder stehst auf der Warteliste. Bitte kündige zuerst, wenn du zu Go wechseln möchtest.", + "workspace.lite.other.message": + "Ein anderes Mitglied in diesem Workspace hat OpenCode Go bereits abonniert. Nur ein Mitglied pro Workspace kann abonnieren.", + "workspace.lite.promo.description": + "OpenCode Go kostet {{price}} und bietet zuverlässigen Zugang zu beliebten offenen Coding-Modellen mit großzügigen Nutzungslimits.", + "workspace.lite.promo.price": "$10/Monat", + "workspace.lite.promo.modelsTitle": "Was enthalten ist", + "workspace.lite.promo.footer": + "Der Plan richtet sich in erster Linie an internationale Nutzer und bietet stabilen weltweiten Zugriff. Preise und Nutzungslimits können sich ändern, wenn wir Erkenntnisse aus der ersten Nutzung und dem Feedback gewinnen.", + "workspace.lite.promo.subscribe": "Go abonnieren", + "workspace.lite.promo.subscribing": "Leite weiter...", + "workspace.lite.promo.otherMethods": "Andere Zahlungsmethoden", + "workspace.lite.promo.selectMethod": "Zahlungsmethode auswählen", + + "workspace.referral.copyLink": "Link kopieren", + "workspace.referral.copied": "Kopiert", + "workspace.referral.overview.title": "Freunde einladen", + "workspace.referral.overview.subtitle": "Erhalte $5, wenn ein Freund abonniert. Er bekommt ebenfalls $5.", + "workspace.referral.instructions.share": "Teile deinen Empfehlungslink", + "workspace.referral.instructions.subscribe": "Dein Freund tritt bei und abonniert Go", + "workspace.referral.instructions.claim": + "Ihr erhaltet beide ein Nutzungsguthaben von $5, das ihr auf eure Go-Nutzungslimits anrechnen könnt", + "workspace.referral.rewards.title": "Empfehlungsbelohnungen", + "workspace.referral.rewards.description": "Verfügbare Empfehlungsguthaben auf deine Go-Nutzung anwenden.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} Belohnungen eingelöst.", + "workspace.referral.rewards.empty": "Noch keine Empfehlungsbelohnungen.", + "workspace.referral.table.reward": "Belohnung", + "workspace.referral.table.referral": "Beschreibung", + "workspace.referral.table.date": "Datum", + "workspace.referral.reward.description.inviter": "{{email}} eingeladen", + "workspace.referral.reward.description.invitee": "Eingeladen von {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Abonnieren zum Freischalten", + "workspace.referral.reward.action.view": "Belohnung ansehen", + "workspace.referral.reward.action.applied": "Belohnung eingelöst", + "workspace.referral.reward.source.pendingInviter": "Warten auf das Abo des Freundes", + "workspace.referral.reward.source.pendingInvitee": "Abonnieren, um Belohnung freizuschalten", + "workspace.referral.reward.source.available": "Belohnung kann eingelöst werden", + "workspace.referral.reward.source.applied": "Belohnung eingelöst", + "workspace.referral.reward.status.applied": "Belohnung eingelöst", + "workspace.referral.reward.status.pendingInviter": "Abonnieren zum Freischalten", + "workspace.referral.reward.status.pendingInvitee": "Abonnieren zum Freischalten", + "workspace.referral.apply.noGo": "Abonnieren zum Freischalten", + "workspace.referral.apply.preview": "Belohnung ansehen", + "workspace.referral.apply.action": "Einlösen", + "workspace.referral.apply.confirmTitle": "Belohnung einlösen", + "workspace.referral.apply.confirmBody": + "Löse {{amount}} ein, um die aktuelle Nutzung dieses Workspace zu reduzieren.", + "workspace.referral.apply.confirmAction": "Einlösen", + + "download.title": "OpenCode | Download", + "download.meta.description": "Lade OpenCode für macOS, Windows und Linux herunter", + "download.hero.title": "OpenCode Desktop herunterladen", + "download.hero.subtitle": "In Beta verfügbar für macOS, Windows und Linux", + "download.hero.button": "Download für {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "OpenCode Extensions", + "download.section.integrations": "OpenCode Integrationen", + "download.action.download": "Download", + "download.action.install": "Installieren", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Nicht unbedingt, aber wahrscheinlich. Du brauchst ein AI-Abo, wenn du OpenCode mit einem bezahlten Anbieter verbinden willst, obwohl du mit", + "download.faq.a3.localLink": "lokalen Modellen", + "download.faq.a3.afterLocal.beforeZen": "kostenlos arbeiten kannst. Während wir Nutzern raten,", + "download.faq.a3.afterZen": + " zu nutzen, funktioniert OpenCode mit allen populären Anbietern wie OpenAI, Anthropic, xAI etc.", + + "download.faq.a5.p1": "OpenCode ist 100% kostenlos.", + "download.faq.a5.p2.beforeZen": + "Zusätzliche Kosten entstehen durch dein Abo bei einem Modellanbieter. Während OpenCode mit jedem Modellanbieter funktioniert, empfehlen wir", + "download.faq.a5.p2.afterZen": " zu nutzen.", + + "download.faq.a6.p1": + "Deine Daten und Informationen werden nur gespeichert, wenn du teilbare Links in OpenCode erstellst.", + "download.faq.a6.p2.beforeShare": "Erfahre mehr über", + "download.faq.a6.shareLink": "Share-Pages", + + "enterprise.title": "OpenCode | Enterprise-Lösungen für Ihre Organisation", + "enterprise.meta.description": "Kontaktieren Sie OpenCode für Enterprise-Lösungen", + "enterprise.hero.title": "Ihr Code gehört Ihnen", + "enterprise.hero.body1": + "OpenCode arbeitet sicher innerhalb Ihrer Organisation, ohne dass Daten oder Kontext gespeichert werden und ohne Lizenzbeschränkungen oder Eigentumsansprüche. Starten Sie einen Testlauf mit Ihrem Team, dann rollen Sie es in Ihrer Organisation aus, indem Sie es in Ihr SSO und internes AI-Gateway integrieren.", + "enterprise.hero.body2": "Lassen Sie uns wissen, wie wir helfen können.", + "enterprise.form.name.label": "Vollständiger Name", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Rolle", + "enterprise.form.role.placeholder": "Executive Chairman", + "enterprise.form.company.label": "Unternehmen", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Firmen-E-Mail", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Telefonnummer", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Welches Problem versuchen Sie zu lösen?", + "enterprise.form.message.placeholder": "Wir brauchen Hilfe bei...", + "enterprise.form.send": "Senden", + "enterprise.form.sending": "Sende...", + "enterprise.form.success": "Nachricht gesendet, wir melden uns bald.", + "enterprise.form.success.submitted": "Formular erfolgreich gesendet.", + "enterprise.form.error.allFieldsRequired": "Alle Felder sind erforderlich.", + "enterprise.form.error.invalidEmailFormat": "Ungültiges E-Mail-Format.", + "enterprise.form.error.internalServer": "Interner Serverfehler.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "Was ist OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise ist für Organisationen, die sicherstellen wollen, dass Code und Daten niemals ihre Infrastruktur verlassen. Dies geschieht durch eine zentrale Konfiguration, die in Ihr SSO und internes AI-Gateway integriert wird.", + "enterprise.faq.q2": "Wie starte ich mit OpenCode Enterprise?", + "enterprise.faq.a2": + "Starten Sie einfach mit einem internen Testlauf mit Ihrem Team. OpenCode speichert standardmäßig weder Code noch Kontextdaten, was den Einstieg erleichtert. Kontaktieren Sie uns dann, um Preise und Implementierungsoptionen zu besprechen.", + "enterprise.faq.q3": "Wie funktioniert das Enterprise-Pricing?", + "enterprise.faq.a3": + "Wir bieten eine Preisgestaltung pro Arbeitsplatz (Seat) an. Wenn Sie Ihr eigenes LLM-Gateway haben, berechnen wir keine Gebühren für genutzte Token. Für weitere Details kontaktieren Sie uns für ein individuelles Angebot basierend auf den Anforderungen Ihrer Organisation.", + "enterprise.faq.q4": "Sind meine Daten mit OpenCode Enterprise sicher?", + "enterprise.faq.a4": + "Ja. OpenCode speichert weder Ihren Code noch Kontextdaten. Alle Verarbeitungen finden lokal oder über direkte API-Aufrufe an Ihren AI-Anbieter statt. Mit zentraler Konfiguration und SSO-Integration bleiben Ihre Daten sicher innerhalb der Infrastruktur Ihrer Organisation.", + + "brand.title": "OpenCode | Marke", + "brand.meta.description": "OpenCode Markenrichtlinien", + "brand.heading": "Markenrichtlinien", + "brand.subtitle": "Ressourcen und Assets, die dir helfen, mit der OpenCode-Marke zu arbeiten.", + "brand.downloadAll": "Alle Assets herunterladen", + + "changelog.title": "OpenCode | Changelog", + "changelog.meta.description": "OpenCode Release Notes und Changelog", + "changelog.hero.title": "Changelog", + "changelog.hero.subtitle": "Neue Updates und Verbesserungen für OpenCode", + "changelog.empty": "Keine Changelog-Einträge gefunden.", + "changelog.viewJson": "JSON ansehen", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarks", + "bench.list.table.agent": "Agent", + "bench.list.table.model": "Modell", + "bench.list.table.score": "Score", + "bench.submission.error.allFieldsRequired": "Alle Felder sind erforderlich.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Task nicht gefunden", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "Agent", + "bench.detail.labels.model": "Modell", + "bench.detail.labels.task": "Task", + "bench.detail.labels.repo": "Repo", + "bench.detail.labels.from": "Von", + "bench.detail.labels.to": "Bis", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Durchschnittliche Dauer", + "bench.detail.labels.averageScore": "Durchschnittlicher Score", + "bench.detail.labels.averageCost": "Durchschnittliche Kosten", + "bench.detail.labels.summary": "Zusammenfassung", + "bench.detail.labels.runs": "Durchläufe", + "bench.detail.labels.score": "Score", + "bench.detail.labels.base": "Basis", + "bench.detail.labels.penalty": "Strafe", + "bench.detail.labels.weight": "Gewichtung", + "bench.detail.table.run": "Durchlauf", + "bench.detail.table.score": "Score (Basis - Strafe)", + "bench.detail.table.cost": "Kosten", + "bench.detail.table.duration": "Dauer", + "bench.detail.run.title": "Durchlauf {{n}}", + "bench.detail.rawJson": "Raw JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/en.ts b/packages/console/app/src/i18n/en.ts new file mode 100644 index 0000000000000000000000000000000000000000..4469c3353c518f19a6d3df4d7d2161462b30f98f --- /dev/null +++ b/packages/console/app/src/i18n/en.ts @@ -0,0 +1,879 @@ +export const dict = { + "go.promo.deepseek": "DeepSeek V4.1 Flash gets 4× usage limits for a limited time", + "go.graph.bonus": "{{count}}× usage", + "nav.github": "GitHub", + "nav.docs": "Docs", + "nav.data": "Data", + "nav.changelog": "Changelog", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.go": "Go", + "nav.login": "Login", + "nav.free": "Download", + "nav.home": "Home", + "nav.openMenu": "Open menu", + "nav.getStartedFree": "Get started for free", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Copy logo as SVG", + "nav.context.copyWordmark": "Copy wordmark as SVG", + "nav.context.brandAssets": "Brand assets", + + "footer.github": "GitHub", + "footer.docs": "Docs", + "footer.changelog": "Changelog", + "footer.feishu": "Feishu", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Brand", + "legal.privacy": "Privacy", + "legal.terms": "Terms", + + "email.title": "Be the first to know when we release new products", + "email.subtitle": "Join the waitlist for early access.", + "email.placeholder": "Email address", + "email.subscribe": "Subscribe", + "email.success": "Almost done, check your inbox and confirm your email address", + + "notFound.title": "Not Found | opencode", + "notFound.heading": "404 - Page Not Found", + "notFound.home": "Home", + "notFound.docs": "Docs", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode logo light", + "notFound.logoDarkAlt": "opencode logo dark", + + "user.logout": "Logout", + + "auth.callback.error.codeMissing": "No authorization code found.", + + "workspace.select": "Select workspace", + "workspace.createNew": "+ Create New Workspace", + "workspace.modal.title": "Create New Workspace", + "workspace.modal.placeholder": "Enter workspace name", + + "common.cancel": "Cancel", + "common.creating": "Creating...", + "common.create": "Create", + "common.contactUs": "Contact us", + + "common.videoUnsupported": "Your browser does not support the video tag.", + "common.figure": "Fig {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Learn more", + + "error.invalidPlan": "Invalid plan", + "error.workspaceRequired": "Workspace ID is required", + "error.alreadySubscribed": "This workspace already has a subscription", + "error.limitRequired": "Limit is required.", + "error.monthlyLimitInvalid": "Set a valid monthly limit.", + "error.workspaceNameRequired": "Workspace name is required.", + "error.nameTooLong": "Name must be 255 characters or less.", + "error.emailRequired": "Email is required", + "error.roleRequired": "Role is required", + "error.idRequired": "ID is required", + "error.nameRequired": "Name is required", + "error.providerRequired": "Provider is required", + "error.apiKeyRequired": "API key is required", + "error.modelRequired": "Model is required", + "error.reloadAmountMin": "Reload amount must be at least ${{amount}}", + "error.reloadTriggerMin": "Balance trigger must be at least ${{amount}}", + + "app.meta.description": "OpenCode - The open source coding agent.", + + "home.title": "OpenCode | The open source AI coding agent", + + "temp.title": "opencode | AI coding agent built for the terminal", + "temp.hero.title": "The AI coding agent built for the terminal", + "temp.zen": "opencode zen", + "temp.getStarted": "Get Started", + "temp.feature.native.title": "Native TUI", + "temp.feature.native.body": "A responsive, native, themeable terminal UI", + "temp.feature.zen.beforeLink": "A", + "temp.feature.zen.link": "curated list of models", + "temp.feature.zen.afterLink": "provided by opencode", + "temp.feature.models.beforeLink": "Supports 75+ LLM providers through", + "temp.feature.models.afterLink": ", including local models", + "temp.screenshot.caption": "opencode TUI with the tokyonight theme", + "temp.screenshot.alt": "opencode TUI with tokyonight theme", + "temp.logoLightAlt": "opencode logo light", + "temp.logoDarkAlt": "opencode logo dark", + + "home.banner.badge": "New", + "home.banner.text": "Introducing tabs for desktop.", + "home.banner.platforms": "Available on macOS, Windows, and Linux", + "home.banner.downloadNow": "Download now", + "home.banner.downloadBetaNow": "Download the desktop beta now", + + "home.promo.title": "Introducing Tabs for Desktop", + "home.promo.body": "Organize your work and active sessions with tabs.", + "home.promo.cta": "Download the latest to get started.", + "home.promo.close": "Dismiss desktop app announcement", + + "home.hero.title": "The open source AI coding agent", + "home.hero.subtitle.a": "Free models included or connect any model from any provider,", + "home.hero.subtitle.b": "including Claude, GPT, Gemini and more.", + + "home.install.ariaLabel": "Install options", + + "home.what.title": "What is OpenCode?", + "home.what.body": "OpenCode is an open source agent that helps you write code in your terminal, IDE, or desktop.", + "home.what.lsp.title": "LSP enabled", + "home.what.lsp.body": "Automatically loads the right LSPs for the LLM", + "home.what.multiSession.title": "Multi-session", + "home.what.multiSession.body": "Start multiple agents in parallel on the same project", + "home.what.shareLinks.title": "Share links", + "home.what.shareLinks.body": "Share a link to any session for reference or to debug", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Log in with GitHub to use your Copilot account", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Log in with OpenAI to use your ChatGPT Plus or Pro account", + "home.what.anyModel.title": "Any model", + "home.what.anyModel.body": "75+ LLM providers through Models.dev, including local models", + "home.what.anyEditor.title": "Any editor", + "home.what.anyEditor.body": "Available as a terminal interface, desktop app, and IDE extension", + "home.what.readDocs": "Read docs", + + "home.growth.title": "The open source AI coding agent", + "home.growth.body": + "With over {{stars}} GitHub stars, {{contributors}} contributors, and over {{commits}} commits, OpenCode is used and trusted by over {{monthlyUsers}} developers every month.", + "home.growth.githubStars": "GitHub Stars", + "home.growth.contributors": "Contributors", + "home.growth.monthlyDevs": "Monthly Devs", + + "home.privacy.title": "Built for privacy first", + "home.privacy.body": + "OpenCode does not store any of your code or context data, so that it can operate in privacy sensitive environments.", + "home.privacy.learnMore": "Learn more about", + "home.privacy.link": "privacy", + + "home.faq.q1": "What is OpenCode?", + "home.faq.a1": + "OpenCode is an open source agent that helps you write and run code with any AI model. It's available as a terminal-based interface, desktop app, or IDE extension.", + "home.faq.q2": "How do I use OpenCode?", + "home.faq.a2.before": "The easiest way to get started is to read the", + "home.faq.a2.link": "intro", + "home.faq.q3": "Do I need extra AI subscriptions to use OpenCode?", + "home.faq.a3.p1": + "Not necessarily, OpenCode comes with a set of free models that you can use without creating an account.", + "home.faq.a3.p2.beforeZen": "Aside from these, you can use any of the popular coding models by creating a", + "home.faq.a3.p2.afterZen": " account.", + "home.faq.a3.p3": + "While we encourage users to use Zen, OpenCode also works with all popular providers such as OpenAI, Anthropic, xAI etc.", + "home.faq.a3.p4.beforeLocal": "You can even connect your", + "home.faq.a3.p4.localLink": "local models", + "home.faq.q4": "Can I use my existing AI subscriptions with OpenCode?", + "home.faq.a4.p1": + "Yes, OpenCode supports subscription plans from all major providers. You can use your Claude Pro/Max, ChatGPT Plus/Pro, or GitHub Copilot subscriptions.", + "home.faq.q5": "Can I only use OpenCode in the terminal?", + "home.faq.a5.beforeDesktop": "Not anymore! OpenCode is now available as an app for your", + "home.faq.a5.desktop": "desktop", + "home.faq.a5.and": "and", + "home.faq.a5.web": "web", + "home.faq.q6": "How much does OpenCode cost?", + "home.faq.a6": + "OpenCode is 100% free to use. It also comes with a set of free models. There might be additional costs if you connect any other provider.", + "home.faq.q7": "What about data and privacy?", + "home.faq.a7.p1": "Your data and information is only stored when you use our free models or create sharable links.", + "home.faq.a7.p2.beforeModels": "Learn more about", + "home.faq.a7.p2.modelsLink": "our models", + "home.faq.a7.p2.and": "and", + "home.faq.a7.p2.shareLink": "share pages", + "home.faq.q8": "Is OpenCode open source?", + "home.faq.a8.p1": "Yes, OpenCode is fully open source. The source code is public on", + "home.faq.a8.p2": "under the", + "home.faq.a8.mitLicense": "MIT License", + "home.faq.a8.p3": + ", meaning anyone can use, modify, or contribute to its development. Anyone from the community can file issues, submit pull requests, and extend functionality.", + + "home.zenCta.title": "Access reliable optimized models for coding agents", + "home.zenCta.body": + "Zen gives you access to a handpicked set of AI models that OpenCode has tested and benchmarked specifically for coding agents. No need to worry about inconsistent performance and quality across providers, use validated models that work.", + "home.zenCta.link": "Learn about Zen", + + "zen.title": "OpenCode Zen | A curated set of reliable optimized models for coding agents", + "zen.hero.title": "Reliable optimized models for coding agents", + "zen.hero.body": + "Zen gives you access to a curated set of AI models that OpenCode has tested and benchmarked specifically for coding agents. No need to worry about inconsistent performance and quality, use validated models that work.", + + "zen.faq.q1": "What is OpenCode Zen?", + "zen.faq.a1": + "Zen is a curated set of AI models tested and benchmarked for coding agents created by the team behind OpenCode.", + "zen.faq.q2": "What makes Zen more accurate?", + "zen.faq.a2": + "Zen only provides models that have been specifically tested and benchmarked for coding agents. You wouldn't use a butter knife to cut steak, don't use poor models for coding.", + "zen.faq.q3": "Is Zen cheaper?", + "zen.faq.a3": + "Zen is not for profit. Zen passes through the costs from the model providers to you. The higher Zen's usage the more OpenCode can negotiate better rates and pass those to you.", + "zen.faq.q4": "How much does Zen cost?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "charges per request", + "zen.faq.a4.p1.afterPricing": "with zero markups, so you pay exactly what the model provider charges.", + "zen.faq.a4.p2.beforeAccount": "Your total cost depends on usage, and you can set monthly spend limits in your", + "zen.faq.a4.p2.accountLink": "account", + "zen.faq.a4.p3": "To cover costs, OpenCode adds only a small payment processing fee of $1.23 per $20 balance top-up.", + "zen.faq.q5": "What about data and privacy?", + "zen.faq.a5.beforeExceptions": + "All Zen models are hosted in the US. Providers follow a zero-retention policy and do not use your data for model training, with the", + "zen.faq.a5.exceptionsLink": "following exceptions", + "zen.faq.q6": "Can I set spend limits?", + "zen.faq.a6": "Yes, you can set monthly spending limits in your account.", + "zen.faq.q7": "Can I cancel?", + "zen.faq.a7": "Yes, you can disable billing at any time and use your remaining balance.", + "zen.faq.q8": "Can I use Zen with other coding agents?", + "zen.faq.a8": + "While Zen works great with OpenCode, you can use Zen with any agent. Follow the setup instructions in your preferred coding agent.", + "zen.faq.q9": "Can I get a refund?", + "zen.faq.a9": + "You may qualify for a refund if the charge was made within the last 14 days and you have not used the credits from that purchase. {{contact}} to request a refund.", + + "zen.cta.start": "Get started with Zen", + "zen.pricing.title": "Add $20 Pay as you go balance", + "zen.pricing.fee": "(+$1.23 card processing fee)", + "zen.pricing.body": "Use with any agent. Set monthly spend limits. Cancel any time.", + "zen.problem.title": "What problem is Zen solving?", + "zen.problem.body": + "There are so many models available, but only a few work well with coding agents. Most providers configure them differently with varying results.", + "zen.problem.subtitle": "We're fixing this for everyone, not just OpenCode users.", + "zen.problem.item1": "Testing select models and consulting their teams", + "zen.problem.item2": "Working with providers to ensure they're delivered properly", + "zen.problem.item3": "Benchmarking all model-provider combinations we recommend", + "zen.how.title": "How Zen works", + "zen.how.body": "While we suggest you use Zen with OpenCode, you can use Zen with any agent.", + "zen.how.step1.title": "Sign up and add $20 balance", + "zen.how.step1.beforeLink": "follow the", + "zen.how.step1.link": "setup instructions", + "zen.how.step2.title": "Use Zen with transparent pricing", + "zen.how.step2.link": "pay per request", + "zen.how.step2.afterLink": "with zero markups", + "zen.how.step3.title": "Auto-top up", + "zen.how.step3.body": "when your balance reaches $5 we'll automatically add $20", + "zen.privacy.title": "Your privacy is important to us", + "zen.privacy.beforeExceptions": + "All Zen models are hosted in the US. Providers follow a zero-retention policy and do not use your data for model training, with the", + "zen.privacy.exceptionsLink": "following exceptions", + + "go.title": "OpenCode Go | Low cost coding models for everyone", + "go.meta.description": "Go costs $10/month, with generous usage limits and reliable access to leading coding models.", + "go.hero.title": "Low cost coding models for everyone", + "go.hero.body": + "Go brings agentic coding to programmers around the world. Offering generous limits and reliable access to the most capable open-source models, so you can build with powerful agents without worrying about cost or availability.", + + "go.cta.start": "Subscribe to Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Subscribe to Go", + "go.cta.price": "$10/month", + "go.pricing.body": "Use with any agent. $10/month. Top up credit if needed. Cancel any time.", + "go.graph.free": "Free", + "go.graph.freePill": "Big Pickle and free models", + "go.graph.go": "Go", + "go.graph.label": "Requests / 5 hours", + "go.graph.period": "Usage", + "go.graph.model": "Model", + "go.graph.requests": "Est. requests / 5 hr", + "go.graph.allowance": "Monthly usage", + "go.graph.new": "New", + "go.graph.scale": "Nonlinear request scale", + "go.graph.showAll": "View all {{count}} models", + "go.graph.showLess": "Show fewer models", + "go.graph.limitedRegions": "limited regions", + "go.graph.limitedTime": "limited time", + "go.graph.tick": "{{n}}x", + "go.graph.usageLimits": "Usage limits", + "go.graph.aria": "Requests per 5h: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "has been life changing, it's truly a no-brainer.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Founder, SEED, PM, Melt, Pop, Dapt, Cadmus, and ViewPoint", + "go.testimonials.jay.quoteBefore": "4 out of 5 people on our team love using", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "I can't recommend", + "go.testimonials.adam.quoteAfter": "enough. Seriously, it's really good.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "With", + "go.testimonials.david.quoteAfter": "I know all the models are tested and perfect for coding agents.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Intern, Nvidia (4 times)", + "go.testimonials.frank.quote": "I wish I was still at Nvidia.", + "go.problem.title": "What problem is Go solving?", + "go.problem.body": + "We're focused on bringing the OpenCode experience to as many people as possible. OpenCode Go is a low cost $10/month subscription. It provides generous limits and reliable access to the most capable open source models.", + "go.problem.subtitle": " ", + "go.problem.item1": "Low cost subscription pricing", + "go.problem.item2": "Generous limits and reliable access", + "go.problem.item3": "Built for as many programmers as possible", + "go.problem.item4": "A curated model lineup tested for agentic coding", + "go.how.title": "How Go works", + "go.how.body": "Go costs $10/month. You can use it with OpenCode or any agent.", + "go.how.step1.title": "Create an account", + "go.how.step1.beforeLink": "follow the", + "go.how.step1.link": "setup instructions", + "go.how.step2.title": "Subscribe to Go", + "go.how.step2.link": "$10/month", + "go.how.step2.afterLink": "with generous limits", + "go.how.step3.title": "Start coding", + "go.how.step3.body": "with reliable access to open-source models", + "go.privacy.title": "Your privacy is important to us", + "go.privacy.body": + "The plan is designed primarily for international users, with models hosted in the US, EU, and Singapore for stable global access.", + "go.privacy.contactAfter": "if you have any questions.", + "go.privacy.beforeExceptions": + "Go models are hosted in the US. Providers follow a zero-retention policy and do not use your data for model training, with the", + "go.privacy.exceptionsLink": "following exceptions", + "go.faq.q1": "What is OpenCode Go?", + "go.faq.a1": + "Go is a low-cost subscription that gives you reliable access to capable open-source models for agentic coding.", + "go.faq.q2": "What models does Go include?", + "go.faq.a2": "Go includes the models listed below, with generous limits and reliable access.", + "go.faq.q3": "Is Go the same as Zen?", + "go.faq.a3": + "No. Zen is pay-as-you-go, while Go costs $10/month, with generous limits and reliable access to a curated model lineup.", + "go.faq.q4": "How much does Go cost?", + "go.faq.a4.p1.beforePricing": "Go costs", + "go.faq.a4.p1.pricingLink": "$10/month", + "go.faq.a4.p1.afterPricing": "with generous limits.", + "go.faq.a4.p2.beforeAccount": "You can manage your subscription in your", + "go.faq.a4.p2.accountLink": "account", + "go.faq.a4.p3": "Cancel any time.", + "go.faq.q5": "What about data and privacy?", + "go.faq.a5.model": "Model", + "go.faq.a5.training": "Model training", + "go.faq.a5.retention": "Data retention", + "go.faq.a5.retention30": "30 days", + "go.faq.a5.retention0": "0 days", + "go.faq.a5.used": "Used", + "go.faq.a5.notUsed": "Not used", + "go.faq.a5.noAgreement": "No agreement", + "go.faq.a5.notZdr": "Not ZDR", + "go.faq.a5.grokRetention": + "ZDR disables important API features that depend on stored data, including the stateful Responses API, Files and Collections, and the Batch API.", + "go.faq.a5.gptRetention": + "Abuse monitoring logs are generated for all API feature usage and retained for up to 30 days.", + "go.faq.a5.museRetention": + "Heavily discounted token pricing in exchange for permission to use your prompts and completions to train future Meta models.", + "go.faq.a5.deepseekRetention": + "ZDR agreement is renewed monthly. The current agreement is valid through September 30, 2026.", + "go.faq.a5.learnMore": "Learn more", + + "go.faq.a5.beforeExceptions": + "Go models are hosted in the US. Providers follow a zero-retention policy and do not use your data for model training, with the", + "go.faq.a5.exceptionsLink": "following exceptions", + "go.faq.q6": "Can I top up credit?", + "go.faq.a6": "If you need more usage, you can top up credit in your account.", + "go.faq.q7": "Can I cancel?", + "go.faq.a7": "Yes, you can cancel any time.", + "go.faq.q8": "Can I use Go with other coding agents?", + "go.faq.a8": "Yes, you can use Go with any agent. Follow the setup instructions in your preferred coding agent.", + + "go.faq.q9": "What is the difference between free models and Go?", + "go.faq.a9": + "Free models include Big Pickle plus promotional models available at the time, with a quota of 200 requests/day. Go offers a curated model lineup with higher request quotas enforced across rolling windows (5-hour, weekly, and monthly), roughly equivalent to base allowances of $12 per 5 hours, $30 per week, and $60 per month; model-specific allowances may differ (actual request counts vary by model and usage).", + "go.faq.q10": "Can I get a refund?", + "go.faq.a10": + "You may qualify for a refund if the charge was made within the last 14 days and you have not used your Go allowance during that billing period. {{contact}} to request a refund.", + + "zen.api.error.rateLimitExceeded": "Rate limit exceeded. Please try again later.", + "zen.api.error.modelNotSupported": "Model {{model}} is not supported", + "zen.api.error.modelFormatNotSupported": "Model {{model}} is not supported for format {{format}}", + "zen.api.error.noProviderAvailable": "No provider available", + "zen.api.error.providerNotSupported": "Provider {{provider}} not supported", + "zen.api.error.missingApiKey": "Missing API key.", + "zen.api.error.invalidApiKey": "Invalid API key.", + "zen.api.error.requestBlockedByUpstreamProvider": + "This account has found to be committing fraud or is in breach of terms of services and has been blocked. If you believe this is a mistake please send an email to help@anoma.ly.", + "zen.api.error.subscriptionQuotaExceeded": "Subscription quota exceeded. Retry in {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "5-hour usage limit reached. Resets in {{retryIn}}. To continue using this model now, enable usage from your available balance: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Weekly usage limit reached. Resets in {{retryIn}}. To continue using this model now, enable usage from your available balance: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Monthly usage limit reached. Resets in {{retryIn}}. To continue using this model now, enable usage from your available balance: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "No payment method. Add a payment method here: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Insufficient balance. Manage your billing here: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Your workspace has reached its monthly spending limit of ${{amount}}. Manage your limits here: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "You have reached your monthly spending limit of ${{amount}}. Manage your limits here: {{membersUrl}}", + "zen.api.error.modelDisabled": "Model is disabled", + "zen.api.error.regionNotAllowed": + "The latest version of this model is only available hosted in China and requires explicit opt in: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "This model is not available in your country.", + "zen.api.error.trainingNotAllowed": + "This model collects data used to improve its quality and requires explicit opt in: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "Free promotion has ended for {{model}}. You can continue using the model by subscribing to OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Access all the world's best coding models", + "black.meta.description": "Get access to Claude, GPT, Gemini and more with OpenCode Black subscription plans.", + "black.hero.title": "Access all the world's best coding models", + "black.hero.subtitle": "Including Claude, GPT, Gemini and more", + "black.title": "OpenCode Black | Pricing", + "black.paused": "Black plan enrollment is temporarily paused.", + "black.plan.icon20": "Black 20 plan", + "black.plan.icon100": "Black 100 plan", + "black.plan.icon200": "Black 200 plan", + "black.plan.multiplier100": "5x more usage than Black 20", + "black.plan.multiplier200": "20x more usage than Black 20", + "black.price.perMonth": "per month", + "black.price.perPersonBilledMonthly": "per person billed monthly", + "black.terms.1": "Your subscription will not start immediately", + "black.terms.2": "You will be added to the waitlist and activated soon", + "black.terms.3": "Your card will only be charged when your subscription is activated", + "black.terms.4": "Usage limits apply, heavily automated use may reach limits sooner", + "black.terms.5": "Subscriptions are for individuals, contact Enterprise for teams", + "black.terms.6": "Limits may be adjusted and plans may be discontinued in the future", + "black.terms.7": "Cancel your subscription at any time", + "black.action.continue": "Continue", + "black.finePrint.beforeTerms": "Prices shown don't include applicable tax", + "black.finePrint.terms": "Terms of Service", + "black.workspace.title": "OpenCode Black | Select Workspace", + "black.workspace.selectPlan": "Select a workspace for this plan", + "black.workspace.name": "Workspace {{n}}", + "black.subscribe.title": "Subscribe to OpenCode Black", + "black.subscribe.paymentMethod": "Payment method", + "black.subscribe.loadingPaymentForm": "Loading payment form...", + "black.subscribe.selectWorkspaceToContinue": "Select a workspace to continue", + "black.subscribe.failurePrefix": "Uh oh!", + "black.subscribe.error.generic": "An error occurred", + "black.subscribe.error.invalidPlan": "Invalid plan", + "black.subscribe.error.workspaceRequired": "Workspace ID is required", + "black.subscribe.error.alreadySubscribed": "This workspace already has a subscription", + "black.subscribe.processing": "Processing...", + "black.subscribe.submit": "Subscribe ${{plan}}", + "black.subscribe.form.chargeNotice": "You will only be charged when your subscription is activated", + "black.subscribe.success.title": "You're on the OpenCode Black waitlist", + "black.subscribe.success.subscriptionPlan": "Subscription plan", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Amount", + "black.subscribe.success.amountValue": "${{plan}} per month", + "black.subscribe.success.paymentMethod": "Payment method", + "black.subscribe.success.dateJoined": "Date joined", + "black.subscribe.success.chargeNotice": "Your card will be charged when your subscription is activated", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Usage", + "workspace.nav.apiKeys": "API Keys", + "workspace.nav.members": "Members", + "workspace.nav.billing": "Billing", + "workspace.nav.settings": "Settings", + + "workspace.home.banner.beforeLink": "Reliable optimized models for coding agents.", + "workspace.lite.banner.beforeLink": "Low cost coding models for everyone.", + "workspace.home.billing.loading": "Loading...", + "workspace.home.billing.enable": "Enable billing", + "workspace.home.billing.currentBalance": "Current balance", + + "workspace.newUser.feature.tested.title": "Tested & Verified Models", + "workspace.newUser.feature.tested.body": + "We've benchmarked and tested models specifically for coding agents to ensure the best performance.", + "workspace.newUser.feature.quality.title": "Highest Quality", + "workspace.newUser.feature.quality.body": + "Access models configured for optimal performance - no downgrades or routing to cheaper providers.", + "workspace.newUser.feature.lockin.title": "No Lock-in", + "workspace.newUser.feature.lockin.body": + "Use Zen with any coding agent, and continue using other providers with opencode whenever you want.", + "workspace.newUser.copyApiKey": "Copy API key", + "workspace.newUser.copyKey": "Copy Key", + "workspace.newUser.copied": "Copied!", + "workspace.newUser.step.enableBilling": "Enable billing", + "workspace.newUser.step.login.before": "Run", + "workspace.newUser.step.login.after": "and select opencode", + "workspace.newUser.step.pasteKey": "Paste your API key", + "workspace.newUser.step.models.before": "Start opencode and run", + "workspace.newUser.step.models.after": "to select a model", + + "workspace.models.title": "Models", + "workspace.models.subtitle.beforeLink": "Manage which models workspace members can access.", + "workspace.models.table.model": "Model", + "workspace.models.table.enabled": "Enabled", + + "workspace.providers.title": "Bring Your Own Key", + "workspace.providers.subtitle": "Configure your own API keys from AI providers.", + "workspace.providers.placeholder": "Enter {{provider}} API key ({{prefix}}...)", + "workspace.providers.configure": "Configure", + "workspace.providers.edit": "Edit", + "workspace.providers.delete": "Delete", + "workspace.providers.saving": "Saving...", + "workspace.providers.save": "Save", + "workspace.providers.table.provider": "Provider", + "workspace.providers.table.apiKey": "API Key", + + "workspace.usage.title": "Usage History", + "workspace.usage.subtitle": "Recent API usage and costs.", + "workspace.usage.empty": "Make your first API call to get started.", + "workspace.usage.table.date": "Date", + "workspace.usage.table.model": "Model", + "workspace.usage.table.input": "Input", + "workspace.usage.table.output": "Output", + "workspace.usage.table.cost": "Cost", + "workspace.usage.table.session": "Session", + "workspace.usage.breakdown.input": "Input", + "workspace.usage.breakdown.cacheRead": "Cache Read", + "workspace.usage.breakdown.cacheWrite": "Cache Write", + "workspace.usage.breakdown.output": "Output", + "workspace.usage.breakdown.reasoning": "Reasoning", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Cost", + "workspace.cost.subtitle": "Usage costs broken down by model.", + "workspace.cost.allModels": "All Models", + "workspace.cost.allKeys": "All Keys", + "workspace.cost.deletedSuffix": "(deleted)", + "workspace.cost.empty": "No usage data available for the selected period.", + "workspace.cost.subscriptionShort": "sub", + + "workspace.keys.title": "API Keys", + "workspace.keys.subtitle": "Manage your API keys for accessing opencode services.", + "workspace.keys.create": "Create API Key", + "workspace.keys.placeholder": "Enter key name", + "workspace.keys.empty": "Create an opencode Gateway API key", + "workspace.keys.table.name": "Name", + "workspace.keys.table.key": "Key", + "workspace.keys.table.createdBy": "Created By", + "workspace.keys.table.lastUsed": "Last Used", + "workspace.keys.copyApiKey": "Copy API key", + "workspace.keys.delete": "Delete", + + "workspace.members.title": "Members", + "workspace.members.subtitle": "Manage workspace members and their permissions.", + "workspace.members.invite": "Invite Member", + "workspace.members.inviting": "Inviting...", + "workspace.members.beta.beforeLink": "Workspaces are free for teams during the beta.", + "workspace.members.form.invitee": "Invitee", + "workspace.members.form.emailPlaceholder": "Enter email", + "workspace.members.form.role": "Role", + "workspace.members.form.monthlyLimit": "Monthly spending limit", + "workspace.members.noLimit": "No limit", + "workspace.members.noLimitLowercase": "no limit", + "workspace.members.invited": "invited", + "workspace.members.edit": "Edit", + "workspace.members.delete": "Delete", + "workspace.members.saving": "Saving...", + "workspace.members.save": "Save", + "workspace.members.table.email": "Email", + "workspace.members.table.role": "Role", + "workspace.members.table.monthLimit": "Month limit", + "workspace.members.role.admin": "Admin", + "workspace.members.role.adminDescription": "Can manage models, members, and billing", + "workspace.members.role.member": "Member", + "workspace.members.role.memberDescription": "Can only generate API keys for themselves", + + "workspace.settings.title": "Settings", + "workspace.settings.subtitle": "Update your workspace name and preferences.", + "workspace.settings.workspaceName": "Workspace name", + "workspace.settings.defaultName": "Default", + "workspace.settings.updating": "Updating...", + "workspace.settings.save": "Save", + "workspace.settings.edit": "Edit", + + "workspace.billing.title": "Billing", + "workspace.billing.subtitle.beforeLink": "Manage payment methods.", + "workspace.billing.contactUs": "Contact us", + "workspace.billing.subtitle.afterLink": "if you have any questions.", + "workspace.billing.currentBalance": "Current Balance", + "workspace.billing.add": "Add $", + "workspace.billing.enterAmount": "Enter amount", + "workspace.billing.loading": "Loading...", + "workspace.billing.addAction": "Add", + "workspace.billing.addBalance": "Add Balance", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Linked to Stripe", + "workspace.billing.manage": "Manage", + "workspace.billing.enable": "Enable Billing", + + "workspace.monthlyLimit.title": "Monthly Limit", + "workspace.monthlyLimit.subtitle": "Set a monthly usage limit for your account.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Setting...", + "workspace.monthlyLimit.set": "Set", + "workspace.monthlyLimit.edit": "Edit Limit", + "workspace.monthlyLimit.noLimit": "No usage limit set.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Current usage for", + "workspace.monthlyLimit.currentUsage.beforeAmount": "is $", + + "workspace.redeem.title": "Redeem Coupon", + "workspace.redeem.subtitle": "Redeem a coupon code to claim credits or perks.", + "workspace.redeem.placeholder": "Enter coupon code", + "workspace.redeem.redeem": "Redeem", + "workspace.redeem.redeeming": "Redeeming...", + "workspace.redeem.success": "Coupon redeemed successfully.", + + "workspace.reload.title": "Auto Reload", + "workspace.reload.disabled.before": "Auto reload is", + "workspace.reload.disabled.state": "disabled", + "workspace.reload.disabled.after": "Enable to automatically reload when balance is low.", + "workspace.reload.enabled.before": "Auto reload is", + "workspace.reload.enabled.state": "enabled", + "workspace.reload.enabled.middle": "We'll reload", + "workspace.reload.processingFee": "processing fee", + "workspace.reload.enabled.after": "when balance reaches", + "workspace.reload.edit": "Edit", + "workspace.reload.enable": "Enable", + "workspace.reload.enableAutoReload": "Enable Auto Reload", + "workspace.reload.reloadAmount": "Reload $", + "workspace.reload.whenBalanceReaches": "When balance reaches $", + "workspace.reload.saving": "Saving...", + "workspace.reload.save": "Save", + "workspace.reload.failedAt": "Reload failed at", + "workspace.reload.reason": "Reason:", + "workspace.reload.updatePaymentMethod": "Please update your payment method and try again.", + "workspace.reload.retrying": "Retrying...", + "workspace.reload.retry": "Retry", + "workspace.reload.error.paymentFailed": "Payment failed.", + + "workspace.payments.title": "Payments History", + "workspace.payments.subtitle": "Recent payment transactions.", + "workspace.payments.table.date": "Date", + "workspace.payments.table.paymentId": "Payment ID", + "workspace.payments.table.amount": "Amount", + "workspace.payments.table.receipt": "Receipt", + "workspace.payments.type.credit": "credit", + "workspace.payments.type.subscription": "subscription", + "workspace.payments.view": "View", + + "workspace.black.loading": "Loading...", + "workspace.black.time.day": "day", + "workspace.black.time.days": "days", + "workspace.black.time.hour": "hour", + "workspace.black.time.hours": "hours", + "workspace.black.time.minute": "minute", + "workspace.black.time.minutes": "minutes", + "workspace.black.time.fewSeconds": "a few seconds", + "workspace.black.subscription.title": "Subscription", + "workspace.black.subscription.message": "You are subscribed to OpenCode Black for ${{plan}} per month.", + "workspace.black.subscription.manage": "Manage Subscription", + "workspace.black.subscription.rollingUsage": "5-hour Usage", + "workspace.black.subscription.weeklyUsage": "Weekly Usage", + "workspace.black.subscription.resetsIn": "Resets in", + "workspace.black.subscription.useBalance": "Use your available balance after reaching the usage limits", + "workspace.black.waitlist.title": "Waitlist", + "workspace.black.waitlist.joined": "You are on the waitlist for the ${{plan}} per month OpenCode Black plan.", + "workspace.black.waitlist.ready": "We're ready to enroll you into the ${{plan}} per month OpenCode Black plan.", + "workspace.black.waitlist.leave": "Leave Waitlist", + "workspace.black.waitlist.leaving": "Leaving...", + "workspace.black.waitlist.left": "Left", + "workspace.black.waitlist.enroll": "Enroll", + "workspace.black.waitlist.enrolling": "Enrolling...", + "workspace.black.waitlist.enrolled": "Enrolled", + "workspace.black.waitlist.enrollNote": + "When you click Enroll, your subscription starts immediately and your card will be charged.", + + "workspace.lite.loading": "Loading...", + "workspace.lite.time.day": "day", + "workspace.lite.time.days": "days", + "workspace.lite.time.hour": "hour", + "workspace.lite.time.hours": "hours", + "workspace.lite.time.minute": "minute", + "workspace.lite.time.minutes": "minutes", + "workspace.lite.time.fewSeconds": "a few seconds", + "workspace.lite.subscription.message": "You are subscribed to OpenCode Go.", + "workspace.lite.subscription.manage": "Manage Subscription", + "workspace.lite.subscription.rollingUsage": "5-hour Usage", + "workspace.lite.subscription.rollingQuota": "5-hour Quota", + "workspace.lite.subscription.weeklyUsage": "Weekly Usage", + "workspace.lite.subscription.weeklyQuota": "Weekly Quota", + "workspace.lite.subscription.monthlyUsage": "Monthly Usage", + "workspace.lite.subscription.monthlyQuota": "Monthly Quota", + "workspace.lite.subscription.resetsIn": "Resets in", + "workspace.lite.subscription.showDetails": "Show details", + "workspace.lite.subscription.hideDetails": "Hide details", + "workspace.lite.subscription.model": "Model", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Total", + "workspace.lite.subscription.useBalance": "Use your available balance after reaching the usage limits", + "workspace.lite.subscription.selectProvider": + 'Select "OpenCode Go" as the provider in your opencode configuration to use Go models.', + "workspace.lite.providers.title": "Providers", + "workspace.lite.providers.description": "Control which providers are used for routing.", + "workspace.lite.providers.allowTraining": "Allow models that train on request data", + "workspace.lite.providers.useChina": "Allow models hosted in China", + "workspace.lite.black.message": + "You're currently subscribed to OpenCode Black or on the waitlist. Please unsubscribe first if you'd like to switch to Go.", + "workspace.lite.other.message": + "Another member in this workspace is already subscribed to OpenCode Go. Only one member per workspace can subscribe.", + "workspace.lite.promo.description": + "OpenCode Go costs {{price}} and provides reliable access to popular open coding models with generous usage limits.", + "workspace.lite.promo.price": "$10/month", + "workspace.lite.promo.modelsTitle": "What's Included", + "workspace.lite.promo.footer": + "The plan is designed primarily for international users and provides stable global access. Pricing and usage limits may change as we learn from early usage and feedback.", + "workspace.lite.promo.subscribe": "Subscribe to Go", + "workspace.lite.promo.subscribing": "Redirecting...", + "workspace.lite.promo.otherMethods": "Other payment methods", + "workspace.lite.promo.selectMethod": "Select payment method", + + "workspace.referral.copyLink": "Copy Link", + "workspace.referral.copied": "Copied", + "workspace.referral.overview.title": "Invite friends", + "workspace.referral.overview.subtitle": "Earn $5 when a friend subscribes. They’ll get $5 too.", + "workspace.referral.instructions.share": "Share your referral link", + "workspace.referral.instructions.subscribe": "Your friend joins and subscribes to Go", + "workspace.referral.instructions.claim": "You both get a $5 usage credit to apply toward your Go usage limits", + "workspace.referral.rewards.title": "Referral rewards", + "workspace.referral.rewards.description": "Apply available referral credits toward your Go usage.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} rewards applied.", + "workspace.referral.rewards.empty": "No referral rewards yet.", + "workspace.referral.table.reward": "Reward", + "workspace.referral.table.referral": "Description", + "workspace.referral.table.date": "Date", + "workspace.referral.reward.description.inviter": "Invited {{email}}", + "workspace.referral.reward.description.invitee": "Invited by {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Subscribe to unlock", + "workspace.referral.reward.action.view": "View Reward", + "workspace.referral.reward.action.applied": "Reward Applied", + "workspace.referral.reward.source.pendingInviter": "Waiting for them to subscribe", + "workspace.referral.reward.source.pendingInvitee": "Subscribe to unlock reward", + "workspace.referral.reward.source.available": "Reward ready to apply", + "workspace.referral.reward.source.applied": "Reward applied", + "workspace.referral.reward.status.applied": "Reward Applied", + "workspace.referral.reward.status.pendingInviter": "Subscribe to unlock", + "workspace.referral.reward.status.pendingInvitee": "Subscribe to unlock", + "workspace.referral.apply.noGo": "Subscribe to unlock", + "workspace.referral.apply.preview": "View Reward", + "workspace.referral.apply.action": "Apply", + "workspace.referral.apply.confirmTitle": "Apply reward", + "workspace.referral.apply.confirmBody": "Apply {{amount}} to reduce this workspace's current usage.", + "workspace.referral.apply.confirmAction": "Apply", + + "download.title": "OpenCode | Download", + "download.meta.description": "Download OpenCode for macOS, Windows, and Linux", + "download.hero.title": "Download OpenCode Desktop", + "download.hero.subtitle": "Available in Beta for macOS, Windows, and Linux", + "download.hero.button": "Download for {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "OpenCode Extensions", + "download.section.integrations": "OpenCode Integrations", + "download.action.download": "Download", + "download.action.install": "Install", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Not necessarily, but probably. You'll need an AI subscription if you want to connect OpenCode to a paid provider, although you can work with", + "download.faq.a3.localLink": "local models", + "download.faq.a3.afterLocal.beforeZen": "for free. While we encourage users to use", + "download.faq.a3.afterZen": ", OpenCode works with all popular providers such as OpenAI, Anthropic, xAI etc.", + + "download.faq.a5.p1": "OpenCode is 100% free to use.", + "download.faq.a5.p2.beforeZen": + "Any additional costs will come from your subscription to a model provider. While OpenCode works with any model provider, we recommend using", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": "Your data and information is only stored when you create sharable links in OpenCode.", + "download.faq.a6.p2.beforeShare": "Learn more about", + "download.faq.a6.shareLink": "share pages", + + "enterprise.title": "OpenCode | Enterprise solutions for your organisation", + "enterprise.meta.description": "Contact OpenCode for enterprise solutions", + "enterprise.hero.title": "Your code is yours", + "enterprise.hero.body1": + "OpenCode operates securely inside your organization with no data or context stored and no licensing restrictions or ownership claims. Start a trial with your team, then deploy it across your organization by integrating it with your SSO and internal AI gateway.", + "enterprise.hero.body2": "Let us know how we can help.", + "enterprise.form.name.label": "Full name", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Role", + "enterprise.form.role.placeholder": "Executive Chairman", + "enterprise.form.company.label": "Company", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Company email", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Phone number", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "What problem are you trying to solve?", + "enterprise.form.message.placeholder": "We need help with...", + "enterprise.form.send": "Send", + "enterprise.form.sending": "Sending...", + "enterprise.form.success": "Message sent, we'll be in touch soon.", + "enterprise.form.success.submitted": "Form submitted successfully.", + "enterprise.form.error.allFieldsRequired": "All fields are required.", + "enterprise.form.error.invalidEmailFormat": "Invalid email format.", + "enterprise.form.error.internalServer": "Internal server error.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "What is OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise is for organizations that want to ensure that their code and data never leaves their infrastructure. It can do this by using a centralized config that integrates with your SSO and internal AI gateway.", + "enterprise.faq.q2": "How do I get started with OpenCode Enterprise?", + "enterprise.faq.a2": + "Simply start with an internal trial with your team. OpenCode by default does not store your code or context data, making it easy to get started. Then contact us to discuss pricing and implementation options.", + "enterprise.faq.q3": "How does enterprise pricing work?", + "enterprise.faq.a3": + "We offer per-seat enterprise pricing. If you have your own LLM gateway, we do not charge for tokens used. For further details, contact us for a custom quote based on your organization's needs.", + "enterprise.faq.q4": "Is my data secure with OpenCode Enterprise?", + "enterprise.faq.a4": + "Yes. OpenCode does not store your code or context data. All processing happens locally or through direct API calls to your AI provider. With central config and SSO integration, your data remains secure within your organization's infrastructure.", + "enterprise.faq.q5": "Where can I find your security and compliance documentation?", + "enterprise.faq.a5.before": + "Our Trust Center has everything: SOC 2 Type 2 report, security policies, subprocessor list, and answers to common security questions. Visit", + "enterprise.faq.a5.after": "to review or request documents under NDA.", + + "brand.title": "OpenCode | Brand", + "brand.meta.description": "OpenCode brand guidelines", + "brand.heading": "Brand guidelines", + "brand.subtitle": "Resources and assets to help you work with the OpenCode brand.", + "brand.downloadAll": "Download all assets", + + "changelog.title": "OpenCode | Changelog", + "changelog.meta.description": "OpenCode release notes and changelog", + "changelog.hero.title": "Changelog", + "changelog.hero.subtitle": "New updates and improvements to OpenCode", + "changelog.empty": "No changelog entries found.", + "changelog.viewJson": "View JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarks", + "bench.list.table.agent": "Agent", + "bench.list.table.model": "Model", + "bench.list.table.score": "Score", + "bench.submission.error.allFieldsRequired": "All fields are required.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Task not found", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "Agent", + "bench.detail.labels.model": "Model", + "bench.detail.labels.task": "Task", + "bench.detail.labels.repo": "Repo", + "bench.detail.labels.from": "From", + "bench.detail.labels.to": "To", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Average Duration", + "bench.detail.labels.averageScore": "Average Score", + "bench.detail.labels.averageCost": "Average Cost", + "bench.detail.labels.summary": "Summary", + "bench.detail.labels.runs": "Runs", + "bench.detail.labels.score": "Score", + "bench.detail.labels.base": "Base", + "bench.detail.labels.penalty": "Penalty", + "bench.detail.labels.weight": "weight", + "bench.detail.table.run": "Run", + "bench.detail.table.score": "Score (Base - Penalty)", + "bench.detail.table.cost": "Cost", + "bench.detail.table.duration": "Duration", + "bench.detail.run.title": "Run {{n}}", + "bench.detail.rawJson": "Raw JSON", +} as const + +export type Key = keyof typeof dict +export type Dict = Record diff --git a/packages/console/app/src/i18n/es.ts b/packages/console/app/src/i18n/es.ts new file mode 100644 index 0000000000000000000000000000000000000000..9750bc584e278d58a632f1c24c50c720aa753e4d --- /dev/null +++ b/packages/console/app/src/i18n/es.ts @@ -0,0 +1,880 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash tiene límites de uso 4x mayores por tiempo limitado", + "go.graph.bonus": "{{count}}× de uso", + "nav.github": "GitHub", + "nav.docs": "Documentación", + "nav.changelog": "Registro de cambios", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Iniciar sesión", + "nav.free": "Descargar", + "nav.home": "Inicio", + "nav.openMenu": "Abrir menú", + "nav.getStartedFree": "Empezar gratis", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Copiar logo como SVG", + "nav.context.copyWordmark": "Copiar marca como SVG", + "nav.context.brandAssets": "Activos de marca", + + "footer.github": "GitHub", + "footer.docs": "Documentación", + "footer.changelog": "Registro de cambios", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Marca", + "legal.privacy": "Privacidad", + "legal.terms": "Términos", + + "email.title": "Sé el primero en enterarte cuando lancemos nuevos productos", + "email.subtitle": "Únete a la lista de espera para acceso anticipado.", + "email.placeholder": "Dirección de correo", + "email.subscribe": "Suscribirse", + "email.success": "Casi listo, revisa tu bandeja de entrada y confirma tu correo", + + "notFound.title": "No encontrado | opencode", + "notFound.heading": "404 - Página no encontrada", + "notFound.home": "Inicio", + "notFound.docs": "Documentación", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode logo claro", + "notFound.logoDarkAlt": "opencode logo oscuro", + + "user.logout": "Cerrar sesión", + + "auth.callback.error.codeMissing": "No se encontró código de autorización.", + + "workspace.select": "Seleccionar espacio de trabajo", + "workspace.createNew": "+ Crear nuevo espacio de trabajo", + "workspace.modal.title": "Crear nuevo espacio de trabajo", + "workspace.modal.placeholder": "Introduce nombre del espacio de trabajo", + + "common.cancel": "Cancelar", + "common.creating": "Creando...", + "common.create": "Crear", + "common.contactUs": "Contáctanos", + + "common.videoUnsupported": "Tu navegador no soporta la etiqueta de video.", + "common.figure": "Fig {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Más información", + + "error.invalidPlan": "Plan inválido", + "error.workspaceRequired": "Se requiere ID del espacio de trabajo", + "error.alreadySubscribed": "Este espacio de trabajo ya tiene una suscripción", + "error.limitRequired": "El límite es obligatorio.", + "error.monthlyLimitInvalid": "Establece un límite mensual válido.", + "error.workspaceNameRequired": "El nombre del espacio de trabajo es obligatorio.", + "error.nameTooLong": "El nombre debe tener 255 caracteres o menos.", + "error.emailRequired": "El correo es obligatorio", + "error.roleRequired": "El rol es obligatorio", + "error.idRequired": "El ID es obligatorio", + "error.nameRequired": "El nombre es obligatorio", + "error.providerRequired": "El proveedor es obligatorio", + "error.apiKeyRequired": "La clave de API es obligatoria", + "error.modelRequired": "El modelo es obligatorio", + "error.reloadAmountMin": "La cantidad de recarga debe ser al menos ${{amount}}", + "error.reloadTriggerMin": "El disparador de saldo debe ser al menos ${{amount}}", + + "app.meta.description": "OpenCode - El agente de codificación de código abierto.", + + "home.title": "OpenCode | El agente de codificación IA de código abierto", + + "temp.title": "opencode | Agente de codificación IA creado para la terminal", + "temp.hero.title": "El agente de codificación IA creado para la terminal", + "temp.zen": "opencode zen", + "temp.getStarted": "Empezar", + "temp.feature.native.title": "TUI Nativa", + "temp.feature.native.body": "Una interfaz de terminal responsiva, nativa y personalizable", + "temp.feature.zen.beforeLink": "Una lista", + "temp.feature.zen.link": "seleccionada de modelos", + "temp.feature.zen.afterLink": "proporcionada por opencode", + "temp.feature.models.beforeLink": "Soporta más de 75 proveedores de LLM a través de", + "temp.feature.models.afterLink": ", incluyendo modelos locales", + "temp.screenshot.caption": "opencode TUI con el tema tokyonight", + "temp.screenshot.alt": "opencode TUI con tema tokyonight", + "temp.logoLightAlt": "logo de opencode claro", + "temp.logoDarkAlt": "logo de opencode oscuro", + + "home.banner.badge": "Nuevo", + "home.banner.text": "Presentamos Tabs para Desktop.", + "home.banner.platforms": "Disponible en macOS, Windows y Linux", + "home.banner.downloadNow": "Descargar ahora", + "home.banner.downloadBetaNow": "Descargar la beta de escritorio ahora", + "home.promo.title": "Presentamos Tabs para Desktop", + "home.promo.body": "Organiza tu trabajo y tus sesiones activas con pestañas.", + "home.promo.cta": "Descarga la última versión para empezar.", + "home.promo.close": "Cerrar el anuncio de la aplicación Desktop", + + "home.hero.title": "El agente de codificación IA de código abierto", + "home.hero.subtitle.a": "Modelos gratuitos incluidos o conecta cualquier modelo de cualquier proveedor,", + "home.hero.subtitle.b": "incluyendo Claude, GPT, Gemini y más.", + + "home.install.ariaLabel": "Opciones de instalación", + + "home.what.title": "¿Qué es OpenCode?", + "home.what.body": + "OpenCode es un agente de código abierto que te ayuda a escribir código en tu terminal, IDE o escritorio.", + "home.what.lsp.title": "LSP habilitado", + "home.what.lsp.body": "Carga automáticamente los LSPs correctos para el LLM", + "home.what.multiSession.title": "Multi-sesión", + "home.what.multiSession.body": "Inicia múltiples agentes en paralelo en el mismo proyecto", + "home.what.shareLinks.title": "Compartir enlaces", + "home.what.shareLinks.body": "Comparte un enlace a cualquier sesión para referencia o depuración", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Inicia sesión con GitHub para usar tu cuenta de Copilot", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Inicia sesión con OpenAI para usar tu cuenta de ChatGPT Plus o Pro", + "home.what.anyModel.title": "Cualquier modelo", + "home.what.anyModel.body": "Más de 75 proveedores de LLM a través de Models.dev, incluyendo modelos locales", + "home.what.anyEditor.title": "Cualquier editor", + "home.what.anyEditor.body": "Disponible como interfaz de terminal, aplicación de escritorio y extensión de IDE", + "home.what.readDocs": "Leer documentación", + + "home.growth.title": "El agente de codificación IA de código abierto", + "home.growth.body": + "Con más de {{stars}} estrellas en GitHub, {{contributors}} colaboradores y más de {{commits}} commits, OpenCode es usado y confiado por más de {{monthlyUsers}} desarrolladores cada mes.", + "home.growth.githubStars": "Estrellas en GitHub", + "home.growth.contributors": "Colaboradores", + "home.growth.monthlyDevs": "Desarrolladores Mensuales", + + "home.privacy.title": "Creado pensando en la privacidad", + "home.privacy.body": + "OpenCode no almacena tu código ni datos de contexto, para que pueda operar en entornos sensibles a la privacidad.", + "home.privacy.learnMore": "Más información sobre", + "home.privacy.link": "privacidad", + + "home.faq.q1": "¿Qué es OpenCode?", + "home.faq.a1": + "OpenCode es un agente de código abierto que te ayuda a escribir y ejecutar código con cualquier modelo de IA. Está disponible como interfaz de terminal, aplicación de escritorio o extensión de IDE.", + "home.faq.q2": "¿Cómo uso OpenCode?", + "home.faq.a2.before": "La forma más fácil de empezar es leer la", + "home.faq.a2.link": "introducción", + "home.faq.q3": "¿Necesito suscripciones extra de IA para usar OpenCode?", + "home.faq.a3.p1": + "No necesariamente, OpenCode viene con un conjunto de modelos gratuitos que puedes usar sin crear una cuenta.", + "home.faq.a3.p2.beforeZen": + "Aparte de estos, puedes usar cualquiera de los modelos de codificación populares creando una cuenta de", + "home.faq.a3.p2.afterZen": ".", + "home.faq.a3.p3": + "Aunque animamos a los usuarios a usar Zen, OpenCode también funciona con todos los proveedores populares como OpenAI, Anthropic, xAI, etc.", + "home.faq.a3.p4.beforeLocal": "Incluso puedes conectar tus", + "home.faq.a3.p4.localLink": "modelos locales", + "home.faq.q4": "¿Puedo usar mis suscripciones de IA existentes con OpenCode?", + "home.faq.a4.p1": + "Sí, OpenCode soporta planes de suscripción de los principales proveedores. Puedes usar tus suscripciones de Claude Pro/Max, ChatGPT Plus/Pro o GitHub Copilot.", + "home.faq.q5": "¿Solo puedo usar OpenCode en la terminal?", + "home.faq.a5.beforeDesktop": "¡Ya no! OpenCode ahora está disponible como una aplicación para tu", + "home.faq.a5.desktop": "escritorio", + "home.faq.a5.and": "y", + "home.faq.a5.web": "web", + "home.faq.q6": "¿Cuánto cuesta OpenCode?", + "home.faq.a6": + "OpenCode es 100% gratuito de usar. También viene con un conjunto de modelos gratuitos. Puede haber costos adicionales si conectas cualquier otro proveedor.", + "home.faq.q7": "¿Qué hay sobre datos y privacidad?", + "home.faq.a7.p1": + "Tus datos e información solo se almacenan cuando usas nuestros modelos gratuitos o creas enlaces compartibles.", + "home.faq.a7.p2.beforeModels": "Más información sobre", + "home.faq.a7.p2.modelsLink": "nuestros modelos", + "home.faq.a7.p2.and": "y", + "home.faq.a7.p2.shareLink": "páginas compartidas", + "home.faq.q8": "¿Es OpenCode de código abierto?", + "home.faq.a8.p1": "Sí, OpenCode es totalmente de código abierto. El código fuente es público en", + "home.faq.a8.p2": "bajo la", + "home.faq.a8.mitLicense": "Licencia MIT", + "home.faq.a8.p3": + ", lo que significa que cualquiera puede usar, modificar o contribuir a su desarrollo. Cualquiera de la comunidad puede abrir problemas, enviar solicitudes de extracción y extender la funcionalidad.", + + "home.zenCta.title": "Accede a modelos optimizados y confiables para agentes de codificación", + "home.zenCta.body": + "Zen te da acceso a un conjunto seleccionado de modelos de IA que OpenCode ha probado y evaluado específicamente para agentes de codificación. No necesitas preocuparte por el rendimiento y la calidad inconsistentes entre proveedores, usa modelos validados que funcionan.", + "home.zenCta.link": "Aprende sobre Zen", + + "zen.title": + "OpenCode Zen | Un conjunto seleccionado de modelos optimizados y confiables para agentes de codificación", + "zen.hero.title": "Modelos optimizados y confiables para agentes de codificación", + "zen.hero.body": + "Zen te da acceso a un conjunto seleccionado de modelos de IA que OpenCode ha probado y evaluado específicamente para agentes de codificación. No necesitas preocuparte por el rendimiento y la calidad inconsistentes, usa modelos validados que funcionan.", + + "zen.faq.q1": "¿Qué es OpenCode Zen?", + "zen.faq.a1": + "Zen es un conjunto seleccionado de modelos de IA probados y evaluados para agentes de codificación, creado por el equipo detrás de OpenCode.", + "zen.faq.q2": "¿Qué hace a Zen más preciso?", + "zen.faq.a2": + "Zen solo proporciona modelos que han sido específicamente probados y evaluados para agentes de codificación. No usarías un cuchillo de mantequilla para cortar carne, no uses modelos pobres para codificar.", + "zen.faq.q3": "¿Es Zen más barato?", + "zen.faq.a3": + "Zen no tiene fines de lucro. Zen te transfiere los costos de los proveedores de modelos. Cuanto mayor sea el uso de Zen, más podrá OpenCode negociar mejores tarifas y transferírtelas.", + "zen.faq.q4": "¿Cuánto cuesta Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "cobra por solicitud", + "zen.faq.a4.p1.afterPricing": "sin recargos, así que pagas exactamente lo que cobra el proveedor del modelo.", + "zen.faq.a4.p2.beforeAccount": "Tu costo total depende del uso, y puedes establecer límites de gasto mensuales en tu", + "zen.faq.a4.p2.accountLink": "cuenta", + "zen.faq.a4.p3": + "Para cubrir costos, OpenCode añade solo una pequeña tarifa de procesamiento de pagos de $1.23 por cada recarga de saldo de $20.", + "zen.faq.q5": "¿Qué hay sobre datos y privacidad?", + "zen.faq.a5.beforeExceptions": + "Todos los modelos Zen están alojados en EE. UU. Los proveedores siguen una política de cero retención y no usan tus datos para entrenamiento de modelos, con las", + "zen.faq.a5.exceptionsLink": "siguientes excepciones", + "zen.faq.q6": "¿Puedo establecer límites de gasto?", + "zen.faq.a6": "Sí, puedes establecer límites de gasto mensuales en tu cuenta.", + "zen.faq.q7": "¿Puedo cancelar?", + "zen.faq.a7": "Sí, puedes deshabilitar la facturación en cualquier momento y usar tu saldo restante.", + "zen.faq.q8": "¿Puedo usar Zen con otros agentes de codificación?", + "zen.faq.a8": + "Aunque Zen funciona genial con OpenCode, puedes usar Zen con cualquier agente. Sigue las instrucciones de configuración en tu agente de codificación preferido.", + "zen.faq.q9": "¿Puedo obtener un reembolso?", + "zen.faq.a9": + "Podrías tener derecho a un reembolso si el cargo se realizó en los últimos 14 días y no has utilizado el crédito de esa compra. {{contact}} para solicitar un reembolso.", + + "zen.cta.start": "Empieza con Zen", + "zen.pricing.title": "Añade $20 de saldo prepago", + "zen.pricing.fee": "(+$1.23 tarifa de procesamiento de tarjeta)", + "zen.pricing.body": "Úsalo con cualquier agente. Establece límites de gasto mensual. Cancela en cualquier momento.", + "zen.problem.title": "¿Qué problema está resolviendo Zen?", + "zen.problem.body": + "Hay muchos modelos disponibles, pero solo unos pocos funcionan bien con agentes de codificación. La mayoría de los proveedores los configuran de manera diferente con resultados variables.", + "zen.problem.subtitle": "Estamos arreglando esto para todos, no solo para usuarios de OpenCode.", + "zen.problem.item1": "Probando modelos seleccionados y consultando a sus equipos", + "zen.problem.item2": "Trabajando con proveedores para asegurar que se entreguen correctamente", + "zen.problem.item3": "Evaluando todas las combinaciones modelo-proveedor que recomendamos", + "zen.how.title": "Cómo funciona Zen", + "zen.how.body": "Aunque sugerimos usar Zen con OpenCode, puedes usar Zen con cualquier agente.", + "zen.how.step1.title": "Regístrate y añade $20 de saldo", + "zen.how.step1.beforeLink": "sigue las", + "zen.how.step1.link": "instrucciones de configuración", + "zen.how.step2.title": "Usa Zen con precios transparentes", + "zen.how.step2.link": "paga por solicitud", + "zen.how.step2.afterLink": "con cero recargos", + "zen.how.step3.title": "Auto-recarga", + "zen.how.step3.body": "cuando tu saldo alcance $5 añadiremos automáticamente $20", + "zen.privacy.title": "Tu privacidad es importante para nosotros", + "zen.privacy.beforeExceptions": + "Todos los modelos Zen están alojados en EE. UU. Los proveedores siguen una política de cero retención y no usan tus datos para entrenamiento de modelos, con las", + "zen.privacy.exceptionsLink": "siguientes excepciones", + + "go.title": "OpenCode Go | Modelos de programación de bajo coste para todos", + "go.meta.description": + "Go cuesta 10 $/mes, con límites de uso generosos y acceso fiable a modelos de programación líderes.", + "go.hero.title": "Modelos de programación de bajo coste para todos", + "go.hero.body": + "Go lleva la programación agéntica a programadores de todo el mundo. Ofrece límites generosos y acceso fiable a los modelos de código abierto más capaces, para que puedas crear con agentes potentes sin preocuparte por el coste o la disponibilidad.", + + "go.cta.start": "Suscribirse a Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Suscribirse a Go", + "go.cta.price": "10 $/mes", + "go.pricing.body": + "Úsalo con cualquier agente. 10 $/mes. Recarga crédito si es necesario. Cancela en cualquier momento.", + "go.graph.free": "Gratis", + "go.graph.freePill": "Big Pickle y modelos gratuitos", + "go.graph.go": "Go", + "go.graph.label": "Solicitudes por 5 horas", + "go.graph.period": "Uso", + "go.graph.model": "Modelo", + "go.graph.requests": "Peticiones estimadas / 5 h", + "go.graph.allowance": "Uso mensual", + "go.graph.new": "Nuevo", + "go.graph.scale": "Escala no lineal de peticiones", + "go.graph.showAll": "Ver los {{count}} modelos", + "go.graph.showLess": "Mostrar menos modelos", + "go.graph.limitedRegions": "regiones limitadas", + "go.graph.limitedTime": "tiempo limitado", + "go.graph.usageLimits": "Límites de uso", + "go.graph.aria": "Solicitudes por 5h: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "ha cambiado mi vida, es realmente una obviedad.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Founder, SEED, PM, Melt, Pop, Dapt, Cadmus, and ViewPoint", + "go.testimonials.jay.quoteBefore": "A 4 de cada 5 personas en nuestro equipo les encanta usar", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "No puedo recomendar", + "go.testimonials.adam.quoteAfter": "lo suficiente. En serio, es realmente bueno.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "Con", + "go.testimonials.david.quoteAfter": + "sé que todos los modelos están probados y son perfectos para agentes de programación.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Intern, Nvidia (4 times)", + "go.testimonials.frank.quote": "Ojalá siguiera en Nvidia.", + "go.problem.title": "¿Qué problema resuelve Go?", + "go.problem.body": + "Nos enfocamos en llevar la experiencia de OpenCode a tantas personas como sea posible. OpenCode Go es una suscripción de bajo coste de 10 $/mes. Proporciona límites generosos y acceso fiable a los modelos de código abierto más capaces.", + "go.problem.subtitle": " ", + "go.problem.item1": "Precios de suscripción de bajo coste", + "go.problem.item2": "Límites generosos y acceso fiable", + "go.problem.item3": "Creado para tantos programadores como sea posible", + "go.problem.item4": "Una selección de modelos probados para programación agéntica", + "go.how.title": "Cómo funciona Go", + "go.how.body": "Go cuesta 10 $/mes. Puedes usarlo con OpenCode o cualquier agente.", + "go.how.step1.title": "Crear una cuenta", + "go.how.step1.beforeLink": "sigue las", + "go.how.step1.link": "instrucciones de configuración", + "go.how.step2.title": "Suscribirse a Go", + "go.how.step2.link": "10 $/mes", + "go.how.step2.afterLink": "con límites generosos", + "go.how.step3.title": "Empezar a programar", + "go.how.step3.body": "con acceso fiable a modelos de código abierto", + "go.privacy.title": "Tu privacidad es importante para nosotros", + "go.privacy.body": + "El plan está diseñado principalmente para usuarios internacionales, con modelos alojados en EE. UU., UE y Singapur para un acceso global estable.", + "go.privacy.contactAfter": "si tienes alguna pregunta.", + "go.privacy.beforeExceptions": + "Los modelos de Go están alojados en EE. UU. Los proveedores siguen una política de retención cero y no utilizan tus datos para el entrenamiento de modelos, con las", + "go.privacy.exceptionsLink": "siguientes excepciones", + "go.faq.q1": "¿Qué es OpenCode Go?", + "go.faq.a1": + "Go es una suscripción de bajo coste que te da acceso fiable a modelos de código abierto capaces para programación agéntica.", + "go.faq.q2": "¿Qué modelos incluye Go?", + "go.faq.a2": "Go incluye los modelos que se indican abajo, con límites generosos y acceso confiable.", + "go.faq.q3": "¿Es Go lo mismo que Zen?", + "go.faq.a3": + "No. Zen es de pago por uso, mientras que Go cuesta 10 $/mes, con límites generosos y acceso fiable a una selección de modelos.", + "go.faq.q4": "¿Cuánto cuesta Go?", + "go.faq.a4.p1.beforePricing": "Go cuesta", + "go.faq.a4.p1.pricingLink": "10 $/mes", + "go.faq.a4.p1.afterPricing": "con límites generosos.", + "go.faq.a4.p2.beforeAccount": "Puedes gestionar tu suscripción en tu", + "go.faq.a4.p2.accountLink": "cuenta", + "go.faq.a4.p3": "Cancela en cualquier momento.", + "go.faq.q5": "¿Qué pasa con los datos y la privacidad?", + "go.faq.a5.model": "Modelo", + "go.faq.a5.training": "Entrenamiento del modelo", + "go.faq.a5.retention": "Retención de datos", + "go.faq.a5.retention30": "30 días", + "go.faq.a5.retention0": "0 días", + "go.faq.a5.used": "Utilizado", + "go.faq.a5.notUsed": "No utilizado", + "go.faq.a5.noAgreement": "Sin acuerdo", + "go.faq.a5.notZdr": "Sin ZDR", + "go.faq.a5.grokRetention": + "ZDR deshabilita funciones importantes de la API que dependen de datos almacenados, incluidas la Responses API con estado, Files and Collections y la Batch API.", + "go.faq.a5.gptRetention": + "Se generan registros de supervisión de abusos para todo el uso de funciones de la API y se conservan durante un máximo de 30 días.", + "go.faq.a5.museRetention": + "Precios de tokens muy reducidos a cambio de permitir que tus prompts y las respuestas generadas se utilicen para entrenar futuros modelos de Meta.", + "go.faq.a5.learnMore": "Más información", + "go.faq.a5.deepseekRetention": + "El acuerdo de ZDR se renueva mensualmente. El acuerdo actual es válido hasta el 30 de septiembre de 2026.", + "go.faq.a5.beforeExceptions": + "Los modelos de Go están alojados en EE. UU. Los proveedores siguen una política de retención cero y no utilizan tus datos para el entrenamiento de modelos, con las", + "go.faq.a5.exceptionsLink": "siguientes excepciones", + "go.faq.q6": "¿Puedo recargar crédito?", + "go.faq.a6": "Si necesitas más uso, puedes recargar crédito en tu cuenta.", + "go.faq.q7": "¿Puedo cancelar?", + "go.faq.a7": "Sí, puedes cancelar en cualquier momento.", + "go.faq.q8": "¿Puedo usar Go con otros agentes de programación?", + "go.faq.a8": + "Sí, puedes usar Go con cualquier agente. Sigue las instrucciones de configuración en tu agente de programación preferido.", + + "go.faq.q9": "¿Cuál es la diferencia entre los modelos gratuitos y Go?", + "go.faq.a9": + "Los modelos gratuitos incluyen Big Pickle y los modelos promocionales disponibles en ese momento, con una cuota de 200 solicitudes/día. Go ofrece una selección de modelos con cuotas de solicitudes más altas aplicadas en ventanas móviles (de 5 horas, semanales y mensuales), aproximadamente equivalentes a cuotas base de 12 $ por 5 horas, 30 $ por semana y 60 $ por mes; las cuotas específicas pueden variar según el modelo (la cantidad real de solicitudes varía según el modelo y el uso).", + "go.faq.q10": "¿Puedo obtener un reembolso?", + "go.faq.a10": + "Podrías tener derecho a un reembolso si el cargo se realizó en los últimos 14 días y no has utilizado tu cuota de Go durante ese periodo de facturación. {{contact}} para solicitar un reembolso.", + + "zen.api.error.rateLimitExceeded": "Límite de tasa excedido. Por favor, inténtalo de nuevo más tarde.", + "zen.api.error.modelNotSupported": "Modelo {{model}} no soportado", + "zen.api.error.modelFormatNotSupported": "Modelo {{model}} no soportado para el formato {{format}}", + "zen.api.error.noProviderAvailable": "Ningún proveedor disponible", + "zen.api.error.providerNotSupported": "Proveedor {{provider}} no soportado", + "zen.api.error.missingApiKey": "Falta la clave API.", + "zen.api.error.invalidApiKey": "Clave API inválida.", + "zen.api.error.requestBlockedByUpstreamProvider": "El proveedor externo bloqueó la solicitud.", + "zen.api.error.subscriptionQuotaExceeded": "Cuota de suscripción excedida. Reintenta en {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "Límite de uso de 5 horas alcanzado. Se restablece en {{retryIn}}. Para seguir usando este modelo ahora, habilita el uso desde tu saldo disponible: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Límite de uso semanal alcanzado. Se restablece en {{retryIn}}. Para seguir usando este modelo ahora, habilita el uso desde tu saldo disponible: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Límite de uso mensual alcanzado. Se restablece en {{retryIn}}. Para seguir usando este modelo ahora, habilita el uso desde tu saldo disponible: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Sin método de pago. Añade un método de pago aquí: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Saldo insuficiente. Gestiona tu facturación aquí: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Tu espacio de trabajo ha alcanzado su límite de gasto mensual de ${{amount}}. Gestiona tus límites aquí: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Has alcanzado tu límite de gasto mensual de ${{amount}}. Gestiona tus límites aquí: {{membersUrl}}", + "zen.api.error.modelDisabled": "El modelo está deshabilitado", + "zen.api.error.regionNotAllowed": + "La versión más reciente de este modelo solo está disponible alojada en China y requiere una aceptación explícita: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Este modelo no está disponible en tu país.", + "zen.api.error.trainingNotAllowed": + "Este modelo recopila datos que se utilizan para mejorar su calidad y requiere tu consentimiento explícito: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "La promoción gratuita de {{model}} ha finalizado. Puedes seguir usando el modelo suscribiéndote a OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Accede a los mejores modelos de codificación del mundo", + "black.meta.description": "Obtén acceso a Claude, GPT, Gemini y más con los planes de suscripción de OpenCode Black.", + "black.hero.title": "Accede a los mejores modelos de codificación del mundo", + "black.hero.subtitle": "Incluyendo Claude, GPT, Gemini y más", + "black.title": "OpenCode Black | Precios", + "black.paused": "La inscripción al plan Black está temporalmente pausada.", + "black.plan.icon20": "Plan Black 20", + "black.plan.icon100": "Plan Black 100", + "black.plan.icon200": "Plan Black 200", + "black.plan.multiplier100": "5x más uso que Black 20", + "black.plan.multiplier200": "20x más uso que Black 20", + "black.price.perMonth": "al mes", + "black.price.perPersonBilledMonthly": "por persona facturado mensualmente", + "black.terms.1": "Tu suscripción no comenzará inmediatamente", + "black.terms.2": "Serás añadido a la lista de espera y activado pronto", + "black.terms.3": "Tu tarjeta solo se cargará cuando tu suscripción se active", + "black.terms.4": "Aplican límites de uso, el uso fuertemente automatizado puede alcanzar los límites antes", + "black.terms.5": "Las suscripciones son para individuos, contacta a Enterprise para equipos", + "black.terms.6": "Los límites pueden ajustarse y los planes pueden discontinuarse en el futuro", + "black.terms.7": "Cancela tu suscripción en cualquier momento", + "black.action.continue": "Continuar", + "black.finePrint.beforeTerms": "Los precios mostrados no incluyen impuestos aplicables", + "black.finePrint.terms": "Términos de Servicio", + "black.workspace.title": "OpenCode Black | Seleccionar Espacio de Trabajo", + "black.workspace.selectPlan": "Selecciona un espacio de trabajo para este plan", + "black.workspace.name": "Espacio de trabajo {{n}}", + "black.subscribe.title": "Suscribirse a OpenCode Black", + "black.subscribe.paymentMethod": "Método de pago", + "black.subscribe.loadingPaymentForm": "Cargando formulario de pago...", + "black.subscribe.selectWorkspaceToContinue": "Selecciona un espacio de trabajo para continuar", + "black.subscribe.failurePrefix": "¡Oh no!", + "black.subscribe.error.generic": "Ocurrió un error", + "black.subscribe.error.invalidPlan": "Plan inválido", + "black.subscribe.error.workspaceRequired": "Se requiere ID del espacio de trabajo", + "black.subscribe.error.alreadySubscribed": "Este espacio de trabajo ya tiene una suscripción", + "black.subscribe.processing": "Procesando...", + "black.subscribe.submit": "Suscribirse ${{plan}}", + "black.subscribe.form.chargeNotice": "Solo se te cobrará cuando tu suscripción se active", + "black.subscribe.success.title": "Estás en la lista de espera de OpenCode Black", + "black.subscribe.success.subscriptionPlan": "Plan de suscripción", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Cantidad", + "black.subscribe.success.amountValue": "${{plan}} al mes", + "black.subscribe.success.paymentMethod": "Método de pago", + "black.subscribe.success.dateJoined": "Fecha de unión", + "black.subscribe.success.chargeNotice": "Tu tarjeta se cargará cuando tu suscripción se active", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Uso", + "workspace.nav.apiKeys": "Claves API", + "workspace.nav.members": "Miembros", + "workspace.nav.billing": "Facturación", + "workspace.nav.settings": "Configuración", + + "workspace.home.banner.beforeLink": "Modelos optimizados y confiables para agentes de codificación.", + "workspace.lite.banner.beforeLink": "Modelos de codificación de bajo costo para todos.", + "workspace.home.billing.loading": "Cargando...", + "workspace.home.billing.enable": "Habilitar facturación", + "workspace.home.billing.currentBalance": "Saldo actual", + + "workspace.newUser.feature.tested.title": "Modelos Probados y Verificados", + "workspace.newUser.feature.tested.body": + "Hemos evaluado y probado modelos específicamente para agentes de codificación para asegurar el mejor rendimiento.", + "workspace.newUser.feature.quality.title": "Máxima Calidad", + "workspace.newUser.feature.quality.body": + "Accede a modelos configurados para un rendimiento óptimo - sin degradaciones ni enrutamiento a proveedores más baratos.", + "workspace.newUser.feature.lockin.title": "Sin Bloqueo", + "workspace.newUser.feature.lockin.body": + "Usa Zen con cualquier agente de codificación, y continúa usando otros proveedores con opencode cuando quieras.", + "workspace.newUser.copyApiKey": "Copiar clave API", + "workspace.newUser.copyKey": "Copiar Clave", + "workspace.newUser.copied": "¡Copiada!", + "workspace.newUser.step.enableBilling": "Habilitar facturación", + "workspace.newUser.step.login.before": "Ejecuta", + "workspace.newUser.step.login.after": "y selecciona opencode", + "workspace.newUser.step.pasteKey": "Pega tu clave API", + "workspace.newUser.step.models.before": "Inicia opencode y ejecuta", + "workspace.newUser.step.models.after": "para seleccionar un modelo", + + "workspace.models.title": "Modelos", + "workspace.models.subtitle.beforeLink": "Gestiona qué modelos pueden acceder los miembros del espacio de trabajo.", + "workspace.models.table.model": "Modelo", + "workspace.models.table.enabled": "Habilitado", + + "workspace.providers.title": "Trae Tu Propia Clave", + "workspace.providers.subtitle": "Configura tus propias claves API de proveedores de IA.", + "workspace.providers.placeholder": "Introduce clave API de {{provider}} ({{prefix}}...)", + "workspace.providers.configure": "Configurar", + "workspace.providers.edit": "Editar", + "workspace.providers.delete": "Eliminar", + "workspace.providers.saving": "Guardando...", + "workspace.providers.save": "Guardar", + "workspace.providers.table.provider": "Proveedor", + "workspace.providers.table.apiKey": "Clave API", + + "workspace.usage.title": "Historial de Uso", + "workspace.usage.subtitle": "Uso reciente de API y costos.", + "workspace.usage.empty": "Haz tu primera llamada a la API para empezar.", + "workspace.usage.table.date": "Fecha", + "workspace.usage.table.model": "Modelo", + "workspace.usage.table.input": "Entrada", + "workspace.usage.table.output": "Salida", + "workspace.usage.table.cost": "Costo", + "workspace.usage.table.session": "Sesión", + "workspace.usage.breakdown.input": "Entrada", + "workspace.usage.breakdown.cacheRead": "Lectura de Caché", + "workspace.usage.breakdown.cacheWrite": "Escritura de Caché", + "workspace.usage.breakdown.output": "Salida", + "workspace.usage.breakdown.reasoning": "Razonamiento", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Costo", + "workspace.cost.subtitle": "Costos de uso desglosados por modelo.", + "workspace.cost.allModels": "Todos los Modelos", + "workspace.cost.allKeys": "Todas las Claves", + "workspace.cost.deletedSuffix": "(eliminado)", + "workspace.cost.empty": "No hay datos de uso disponibles para el periodo seleccionado.", + "workspace.cost.subscriptionShort": "sub", + + "workspace.keys.title": "Claves API", + "workspace.keys.subtitle": "Gestiona tus claves API para acceder a los servicios de opencode.", + "workspace.keys.create": "Crear Clave API", + "workspace.keys.placeholder": "Introduce nombre de la clave", + "workspace.keys.empty": "Crea una clave API de opencode Gateway", + "workspace.keys.table.name": "Nombre", + "workspace.keys.table.key": "Clave", + "workspace.keys.table.createdBy": "Creado Por", + "workspace.keys.table.lastUsed": "Último Uso", + "workspace.keys.copyApiKey": "Copiar clave API", + "workspace.keys.delete": "Eliminar", + + "workspace.members.title": "Miembros", + "workspace.members.subtitle": "Gestiona miembros del espacio de trabajo y sus permisos.", + "workspace.members.invite": "Invitar Miembro", + "workspace.members.inviting": "Invitando...", + "workspace.members.beta.beforeLink": "Los espacios de trabajo son gratuitos para equipos durante la beta.", + "workspace.members.form.invitee": "Invitado", + "workspace.members.form.emailPlaceholder": "Introduce correo", + "workspace.members.form.role": "Rol", + "workspace.members.form.monthlyLimit": "Límite de gasto mensual", + "workspace.members.noLimit": "Sin límite", + "workspace.members.noLimitLowercase": "sin límite", + "workspace.members.invited": "invitado", + "workspace.members.edit": "Editar", + "workspace.members.delete": "Eliminar", + "workspace.members.saving": "Guardando...", + "workspace.members.save": "Guardar", + "workspace.members.table.email": "Correo", + "workspace.members.table.role": "Rol", + "workspace.members.table.monthLimit": "Límite mensual", + "workspace.members.role.admin": "Administrador", + "workspace.members.role.adminDescription": "Puede gestionar modelos, miembros y facturación", + "workspace.members.role.member": "Miembro", + "workspace.members.role.memberDescription": "Solo puede generar claves API para sí mismo", + + "workspace.settings.title": "Configuración", + "workspace.settings.subtitle": "Actualiza el nombre de tu espacio de trabajo y preferencias.", + "workspace.settings.workspaceName": "Nombre del espacio de trabajo", + "workspace.settings.defaultName": "Por defecto", + "workspace.settings.updating": "Actualizando...", + "workspace.settings.save": "Guardar", + "workspace.settings.edit": "Editar", + + "workspace.billing.title": "Facturación", + "workspace.billing.subtitle.beforeLink": "Gestionar métodos de pago.", + "workspace.billing.contactUs": "Contáctanos", + "workspace.billing.subtitle.afterLink": "si tienes alguna pregunta.", + "workspace.billing.currentBalance": "Saldo Actual", + "workspace.billing.add": "Añadir $", + "workspace.billing.enterAmount": "Introduce cantidad", + "workspace.billing.loading": "Cargando...", + "workspace.billing.addAction": "Añadir", + "workspace.billing.addBalance": "Añadir Saldo", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Vinculado con Stripe", + "workspace.billing.manage": "Gestionar", + "workspace.billing.enable": "Habilitar Facturación", + + "workspace.monthlyLimit.title": "Límite Mensual", + "workspace.monthlyLimit.subtitle": "Establece un límite de uso mensual para tu cuenta.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Estableciendo...", + "workspace.monthlyLimit.set": "Establecer", + "workspace.monthlyLimit.edit": "Editar Límite", + "workspace.monthlyLimit.noLimit": "Sin límite de uso establecido.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Uso actual para", + "workspace.monthlyLimit.currentUsage.beforeAmount": "es $", + + "workspace.redeem.title": "Canjear cupón", + "workspace.redeem.subtitle": "Canjea un código de cupón para obtener crédito o beneficios.", + "workspace.redeem.placeholder": "Introduce el código del cupón", + "workspace.redeem.redeem": "Canjear", + "workspace.redeem.redeeming": "Canjeando...", + "workspace.redeem.success": "Cupón canjeado correctamente.", + + "workspace.reload.title": "Auto Recarga", + "workspace.reload.disabled.before": "La auto recarga está", + "workspace.reload.disabled.state": "deshabilitada", + "workspace.reload.disabled.after": "Habilita para recargar automáticamente cuando el saldo sea bajo.", + "workspace.reload.enabled.before": "La auto recarga está", + "workspace.reload.enabled.state": "habilitada", + "workspace.reload.enabled.middle": "Recargaremos", + "workspace.reload.processingFee": "tarifa de procesamiento", + "workspace.reload.enabled.after": "cuando el saldo alcance", + "workspace.reload.edit": "Editar", + "workspace.reload.enable": "Habilitar", + "workspace.reload.enableAutoReload": "Habilitar Auto Recarga", + "workspace.reload.reloadAmount": "Recargar $", + "workspace.reload.whenBalanceReaches": "Cuando el saldo alcance $", + "workspace.reload.saving": "Guardando...", + "workspace.reload.save": "Guardar", + "workspace.reload.failedAt": "La recarga falló en", + "workspace.reload.reason": "Razón:", + "workspace.reload.updatePaymentMethod": "Por favor actualiza tu método de pago e intenta de nuevo.", + "workspace.reload.retrying": "Reintentando...", + "workspace.reload.retry": "Reintentar", + "workspace.reload.error.paymentFailed": "El pago falló.", + + "workspace.payments.title": "Historial de Pagos", + "workspace.payments.subtitle": "Transacciones de pago recientes.", + "workspace.payments.table.date": "Fecha", + "workspace.payments.table.paymentId": "ID de Pago", + "workspace.payments.table.amount": "Cantidad", + "workspace.payments.table.receipt": "Recibo", + "workspace.payments.type.credit": "crédito", + "workspace.payments.type.subscription": "suscripción", + "workspace.payments.view": "Ver", + + "workspace.black.loading": "Cargando...", + "workspace.black.time.day": "día", + "workspace.black.time.days": "días", + "workspace.black.time.hour": "hora", + "workspace.black.time.hours": "horas", + "workspace.black.time.minute": "minuto", + "workspace.black.time.minutes": "minutos", + "workspace.black.time.fewSeconds": "unos pocos segundos", + "workspace.black.subscription.title": "Suscripción", + "workspace.black.subscription.message": "Estás suscrito a OpenCode Black por ${{plan}} al mes.", + "workspace.black.subscription.manage": "Gestionar Suscripción", + "workspace.black.subscription.rollingUsage": "Uso de 5 horas", + "workspace.black.subscription.weeklyUsage": "Uso Semanal", + "workspace.black.subscription.resetsIn": "Se reinicia en", + "workspace.black.subscription.useBalance": "Usa tu saldo disponible después de alcanzar los límites de uso", + "workspace.black.waitlist.title": "Lista de Espera", + "workspace.black.waitlist.joined": "Estás en la lista de espera para el plan OpenCode Black de ${{plan}} al mes.", + "workspace.black.waitlist.ready": "Estamos listos para inscribirte en el plan OpenCode Black de ${{plan}} al mes.", + "workspace.black.waitlist.leave": "Abandonar Lista de Espera", + "workspace.black.waitlist.leaving": "Abandonando...", + "workspace.black.waitlist.left": "Abandonada", + "workspace.black.waitlist.enroll": "Inscribirse", + "workspace.black.waitlist.enrolling": "Inscribiéndose...", + "workspace.black.waitlist.enrolled": "Inscrito", + "workspace.black.waitlist.enrollNote": + "Cuando haces clic en Inscribirse, tu suscripción comienza inmediatamente y se cargará a tu tarjeta.", + + "workspace.lite.loading": "Cargando...", + "workspace.lite.time.day": "día", + "workspace.lite.time.days": "días", + "workspace.lite.time.hour": "hora", + "workspace.lite.time.hours": "horas", + "workspace.lite.time.minute": "minuto", + "workspace.lite.time.minutes": "minutos", + "workspace.lite.time.fewSeconds": "unos pocos segundos", + "workspace.lite.subscription.message": "Estás suscrito a OpenCode Go.", + "workspace.lite.subscription.manage": "Gestionar Suscripción", + "workspace.lite.subscription.rollingUsage": "Uso de 5 horas", + "workspace.lite.subscription.rollingQuota": "Cuota de 5 horas", + "workspace.lite.subscription.weeklyUsage": "Uso Semanal", + "workspace.lite.subscription.weeklyQuota": "Cuota Semanal", + "workspace.lite.subscription.monthlyUsage": "Uso Mensual", + "workspace.lite.subscription.monthlyQuota": "Cuota Mensual", + "workspace.lite.subscription.resetsIn": "Se reinicia en", + "workspace.lite.subscription.showDetails": "Mostrar detalles", + "workspace.lite.subscription.hideDetails": "Ocultar detalles", + "workspace.lite.subscription.model": "Modelo", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Total", + "workspace.lite.subscription.useBalance": "Usa tu saldo disponible después de alcanzar los límites de uso", + "workspace.lite.subscription.selectProvider": + 'Selecciona "OpenCode Go" como proveedor en tu configuración de opencode para usar los modelos Go.', + "workspace.lite.providers.title": "Proveedores", + "workspace.lite.providers.description": "Controla qué proveedores se usan para el enrutamiento.", + "workspace.lite.providers.allowTraining": "Permitir modelos que se entrenan con los datos de las solicitudes", + "workspace.lite.providers.useChina": "Activar modelos alojados en China", + "workspace.lite.black.message": + "Actualmente estás suscrito a OpenCode Black o estás en la lista de espera. Por favor, cancela la suscripción primero si deseas cambiar a Go.", + "workspace.lite.other.message": + "Otro miembro de este espacio de trabajo ya está suscrito a OpenCode Go. Solo un miembro por espacio de trabajo puede suscribirse.", + "workspace.lite.promo.description": + "OpenCode Go cuesta {{price}} y ofrece acceso confiable a modelos de codificación abiertos populares con límites de uso generosos.", + "workspace.lite.promo.price": "$10/mes", + "workspace.lite.promo.modelsTitle": "Qué incluye", + "workspace.lite.promo.footer": + "El plan está diseñado principalmente para usuarios internacionales y ofrece un acceso global estable. Los precios y los límites de uso pueden cambiar a medida que aprendemos del uso inicial y de los comentarios recibidos.", + "workspace.lite.promo.subscribe": "Suscribirse a Go", + "workspace.lite.promo.subscribing": "Redirigiendo...", + "workspace.lite.promo.otherMethods": "Otros métodos de pago", + "workspace.lite.promo.selectMethod": "Seleccionar método de pago", + + "workspace.referral.copyLink": "Copiar enlace", + "workspace.referral.copied": "Copiado", + "workspace.referral.overview.title": "Invita amigos", + "workspace.referral.overview.subtitle": "Gana $5 cuando un amigo se suscriba. Él también recibirá $5.", + "workspace.referral.instructions.share": "Comparte tu enlace de referido", + "workspace.referral.instructions.subscribe": "Tu amigo se une y se suscribe a Go", + "workspace.referral.instructions.claim": + "Ambos reciben un crédito de uso de $5 para aplicar a sus límites de uso de Go", + "workspace.referral.rewards.title": "Recompensas por referidos", + "workspace.referral.rewards.description": "Aplica los créditos por referidos disponibles a tu uso de Go.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} recompensas aplicadas.", + "workspace.referral.rewards.empty": "Aún no hay recompensas por referidos.", + "workspace.referral.table.reward": "Recompensa", + "workspace.referral.table.referral": "Descripción", + "workspace.referral.table.date": "Fecha", + "workspace.referral.reward.description.inviter": "Invitaste a {{email}}", + "workspace.referral.reward.description.invitee": "Invitado por {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Suscríbete para desbloquear", + "workspace.referral.reward.action.view": "Ver recompensa", + "workspace.referral.reward.action.applied": "Recompensa aplicada", + "workspace.referral.reward.source.pendingInviter": "Esperando a que se suscriba", + "workspace.referral.reward.source.pendingInvitee": "Suscríbete para desbloquear la recompensa", + "workspace.referral.reward.source.available": "Recompensa lista para aplicar", + "workspace.referral.reward.source.applied": "Recompensa aplicada", + "workspace.referral.reward.status.applied": "Recompensa aplicada", + "workspace.referral.reward.status.pendingInviter": "Suscríbete para desbloquear", + "workspace.referral.reward.status.pendingInvitee": "Suscríbete para desbloquear", + "workspace.referral.apply.noGo": "Suscríbete para desbloquear", + "workspace.referral.apply.preview": "Ver recompensa", + "workspace.referral.apply.action": "Aplicar", + "workspace.referral.apply.confirmTitle": "Aplicar recompensa", + "workspace.referral.apply.confirmBody": "Aplica {{amount}} para reducir el uso actual de este workspace.", + "workspace.referral.apply.confirmAction": "Aplicar", + + "download.title": "OpenCode | Descargar", + "download.meta.description": "Descarga OpenCode para macOS, Windows y Linux", + "download.hero.title": "Descargar OpenCode Desktop", + "download.hero.subtitle": "Disponible en Beta para macOS, Windows y Linux", + "download.hero.button": "Descargar para {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "Extensiones OpenCode", + "download.section.integrations": "Integraciones OpenCode", + "download.action.download": "Descargar", + "download.action.install": "Instalar", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "No necesariamente, pero probablemente. Necesitarás una suscripción de IA si quieres conectar OpenCode a un proveedor de pago, aunque puedes trabajar con", + "download.faq.a3.localLink": "modelos locales", + "download.faq.a3.afterLocal.beforeZen": "gratis. Aunque animamos a los usuarios a usar", + "download.faq.a3.afterZen": + ", OpenCode funciona con todos los proveedores populares como OpenAI, Anthropic, xAI, etc.", + + "download.faq.a5.p1": "OpenCode es 100% gratuito de usar.", + "download.faq.a5.p2.beforeZen": + "Cualquier costo adicional vendrá de tu suscripción a un proveedor de modelos. Aunque OpenCode funciona con cualquier proveedor de modelos, recomendamos usar", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": "Tus datos e información solo se almacenan cuando creas enlaces compartibles en OpenCode.", + "download.faq.a6.p2.beforeShare": "Más información sobre", + "download.faq.a6.shareLink": "páginas compartidas", + + "enterprise.title": "OpenCode | Soluciones empresariales para tu organización", + "enterprise.meta.description": "Contacta a OpenCode para soluciones empresariales", + "enterprise.hero.title": "Tu código es tuyo", + "enterprise.hero.body1": + "OpenCode opera de forma segura dentro de tu organización sin almacenar datos ni contexto, y sin restricciones de licencia ni reclamaciones de propiedad. Inicia una prueba con tu equipo, luego despliégalo en toda tu organización integrándolo con tu SSO y pasarela de IA interna.", + "enterprise.hero.body2": "Déjanos saber cómo podemos ayudar.", + "enterprise.form.name.label": "Nombre completo", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Rol", + "enterprise.form.role.placeholder": "Presidente Ejecutivo", + "enterprise.form.company.label": "Empresa", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Correo de empresa", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Teléfono", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "¿Qué problema estás intentando resolver?", + "enterprise.form.message.placeholder": "Necesitamos ayuda con...", + "enterprise.form.send": "Enviar", + "enterprise.form.sending": "Enviando...", + "enterprise.form.success": "Mensaje enviado, estaremos en contacto pronto.", + "enterprise.form.success.submitted": "Formulario enviado con éxito.", + "enterprise.form.error.allFieldsRequired": "Todos los campos son obligatorios.", + "enterprise.form.error.invalidEmailFormat": "Formato de correo inválido.", + "enterprise.form.error.internalServer": "Error interno del servidor.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "¿Qué es OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise es para organizaciones que quieren asegurar que su código y datos nunca salgan de su infraestructura. Puede hacer esto usando una configuración centralizada que se integra con tu SSO y pasarela de IA interna.", + "enterprise.faq.q2": "¿Cómo empiezo con OpenCode Enterprise?", + "enterprise.faq.a2": + "Simplemente empieza con una prueba interna con tu equipo. OpenCode por defecto no almacena tu código ni datos de contexto, haciendo fácil empezar. Luego contáctanos para discutir precios y opciones de implementación.", + "enterprise.faq.q3": "¿Cómo funciona el precio para empresas?", + "enterprise.faq.a3": + "Ofrecemos precios empresariales por asiento. Si tienes tu propia pasarela de LLM, no cobramos por los tokens usados. Para más detalles, contáctanos para una cotización personalizada basada en las necesidades de tu organización.", + "enterprise.faq.q4": "¿Están mis datos seguros con OpenCode Enterprise?", + "enterprise.faq.a4": + "Sí. OpenCode no almacena tu código ni datos de contexto. Todo el procesamiento ocurre localmente o a través de llamadas directas a la API de tu proveedor de IA. Con configuración central y integración SSO, tus datos permanecen seguros dentro de la infraestructura de tu organización.", + + "brand.title": "OpenCode | Marca", + "brand.meta.description": "Guías de marca de OpenCode", + "brand.heading": "Guías de marca", + "brand.subtitle": "Recursos y activos para ayudarte a trabajar con la marca OpenCode.", + "brand.downloadAll": "Descargar todos los activos", + + "changelog.title": "OpenCode | Registro de cambios", + "changelog.meta.description": "Notas de versión y registro de cambios de OpenCode", + "changelog.hero.title": "Registro de cambios", + "changelog.hero.subtitle": "Nuevas actualizaciones y mejoras para OpenCode", + "changelog.empty": "No se encontraron entradas en el registro de cambios.", + "changelog.viewJson": "Ver JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarks", + "bench.list.table.agent": "Agente", + "bench.list.table.model": "Modelo", + "bench.list.table.score": "Puntuación", + "bench.submission.error.allFieldsRequired": "Todos los campos son obligatorios.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Tarea no encontrada", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "Agente", + "bench.detail.labels.model": "Modelo", + "bench.detail.labels.task": "Tarea", + "bench.detail.labels.repo": "Repo", + "bench.detail.labels.from": "De", + "bench.detail.labels.to": "A", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Duración Promedio", + "bench.detail.labels.averageScore": "Puntuación Promedio", + "bench.detail.labels.averageCost": "Costo Promedio", + "bench.detail.labels.summary": "Resumen", + "bench.detail.labels.runs": "Ejecuciones", + "bench.detail.labels.score": "Puntuación", + "bench.detail.labels.base": "Base", + "bench.detail.labels.penalty": "Penalización", + "bench.detail.labels.weight": "peso", + "bench.detail.table.run": "Ejecución", + "bench.detail.table.score": "Puntuación (Base - Penalización)", + "bench.detail.table.cost": "Costo", + "bench.detail.table.duration": "Duración", + "bench.detail.run.title": "Ejecución {{n}}", + "bench.detail.rawJson": "JSON Crudo", +} as const satisfies Dict diff --git a/packages/console/app/src/i18n/fr.ts b/packages/console/app/src/i18n/fr.ts new file mode 100644 index 0000000000000000000000000000000000000000..5281b6b3e54fe574c178569e39f660c99cdd4266 --- /dev/null +++ b/packages/console/app/src/i18n/fr.ts @@ -0,0 +1,888 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash bénéficie de limites d’utilisation 4x supérieures pour une durée limitée", + "go.graph.bonus": "{{count}}× d’utilisation", + "app.meta.description": "OpenCode - L'agent de code open source.", + "nav.github": "GitHub", + "nav.docs": "Documentation", + "nav.changelog": "Changelog", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Entreprise", + "nav.zen": "Zen", + "nav.login": "Se connecter", + "nav.free": "Télécharger", + "nav.home": "Accueil", + "nav.openMenu": "Ouvrir le menu", + "nav.getStartedFree": "Commencer gratuitement", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Copier le logo en SVG", + "nav.context.copyWordmark": "Copier le logotype en SVG", + "nav.context.brandAssets": "Ressources de marque", + + "footer.github": "GitHub", + "footer.docs": "Documentation", + "footer.changelog": "Changelog", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Marque", + "legal.privacy": "Confidentialité", + "legal.terms": "Conditions", + + "email.title": "Soyez le premier à être informé de nos nouveaux produits", + "email.subtitle": "Inscrivez-vous à la liste d'attente pour un accès anticipé.", + "email.placeholder": "Adresse e-mail", + "email.subscribe": "S'abonner", + "email.success": "Presque terminé - vérifiez votre boîte de réception et confirmez votre adresse e-mail", + + "notFound.title": "Introuvable | OpenCode", + "notFound.heading": "404 - Page introuvable", + "notFound.home": "Accueil", + "notFound.docs": "Documentation", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode logo light", + "notFound.logoDarkAlt": "opencode logo dark", + + "user.logout": "Se déconnecter", + + "workspace.select": "Sélectionner un espace de travail", + "workspace.createNew": "+ Créer un nouvel espace", + "workspace.modal.title": "Créer un nouvel espace", + "workspace.modal.placeholder": "Saisir le nom de l'espace", + + "common.cancel": "Annuler", + "common.creating": "Création...", + "common.create": "Créer", + "common.contactUs": "Contactez-nous", + + "common.videoUnsupported": "Votre navigateur ne prend pas en charge la balise vidéo.", + "common.figure": "Fig {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "En savoir plus", + + "error.invalidPlan": "Forfait invalide", + "error.workspaceRequired": "L'ID de l'espace de travail est requis", + "error.alreadySubscribed": "Cet espace de travail a déjà un abonnement", + "error.limitRequired": "La limite est requise.", + "error.monthlyLimitInvalid": "Définissez une limite mensuelle valide.", + "error.workspaceNameRequired": "Le nom de l'espace de travail est requis.", + "error.nameTooLong": "Le nom doit comporter 255 caractères ou moins.", + "error.emailRequired": "L'e-mail est requis", + "error.roleRequired": "Le rôle est requis", + "error.idRequired": "L'ID est requis", + "error.nameRequired": "Le nom est requis", + "error.providerRequired": "Le fournisseur est requis", + "error.apiKeyRequired": "La clé API est requise", + "error.modelRequired": "Le modèle est requis", + "error.reloadAmountMin": "Le montant de recharge doit être d'au moins {{amount}} $", + "error.reloadTriggerMin": "Le seuil de déclenchement doit être d'au moins {{amount}} $", + "auth.callback.error.codeMissing": "Aucun code d'autorisation trouvé.", + + "home.title": "OpenCode | L'agent de code IA open source", + + "temp.title": "OpenCode | Agent de code IA conçu pour le terminal", + "temp.hero.title": "L'agent de code IA conçu pour le terminal", + "temp.zen": "OpenCode Zen", + "temp.getStarted": "Commencer", + "temp.feature.native.title": "TUI Native", + "temp.feature.native.body": "Une interface terminal native, réactive et thémable", + "temp.feature.zen.beforeLink": "Une", + "temp.feature.zen.link": "liste organisée de modèles", + "temp.feature.zen.afterLink": "fournie par OpenCode", + "temp.feature.models.beforeLink": "Prend en charge plus de 75 fournisseurs LLM via", + "temp.feature.models.afterLink": ", y compris les modèles locaux", + "temp.screenshot.caption": "OpenCode TUI avec le thème tokyonight", + "temp.screenshot.alt": "OpenCode TUI avec le thème tokyonight", + "temp.logoLightAlt": "opencode logo light", + "temp.logoDarkAlt": "opencode logo dark", + + "home.banner.badge": "Nouveau", + "home.banner.text": "Découvrez Tabs pour Desktop.", + "home.banner.platforms": "Disponible sur macOS, Windows et Linux", + "home.banner.downloadNow": "Télécharger maintenant", + "home.banner.downloadBetaNow": "Télécharger la bêta desktop maintenant", + "home.promo.title": "Découvrez Tabs pour Desktop", + "home.promo.body": "Organisez votre travail et vos sessions actives avec des onglets.", + "home.promo.cta": "Téléchargez la dernière version pour commencer.", + "home.promo.close": "Fermer l’annonce de l’application Desktop", + + "home.hero.title": "L'agent de code IA open source", + "home.hero.subtitle.a": + "Modèles gratuits inclus ou connectez n'importe quel modèle depuis n'importe quel fournisseur,", + "home.hero.subtitle.b": "dont Claude, GPT, Gemini et plus.", + + "home.install.ariaLabel": "Options d'installation", + + "home.what.title": "Qu'est-ce que OpenCode ?", + "home.what.body": + "OpenCode est un agent open source qui vous aide à écrire du code dans votre terminal, IDE ou desktop.", + "home.what.lsp.title": "LSP activé", + "home.what.lsp.body": "Charge automatiquement les bons LSP pour le LLM", + "home.what.multiSession.title": "Multi-session", + "home.what.multiSession.body": "Lancez plusieurs agents en parallèle sur le même projet", + "home.what.shareLinks.title": "Liens de partage", + "home.what.shareLinks.body": "Partagez un lien vers n'importe quelle session pour référence ou debug", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Connectez-vous avec GitHub pour utiliser votre compte Copilot", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Connectez-vous avec OpenAI pour utiliser votre compte ChatGPT Plus ou Pro", + "home.what.anyModel.title": "N'importe quel modèle", + "home.what.anyModel.body": "75+ fournisseurs de LLM via Models.dev, y compris des modèles locaux", + "home.what.anyEditor.title": "N'importe quel éditeur", + "home.what.anyEditor.body": "Disponible en interface terminal, application desktop et extension IDE", + "home.what.readDocs": "Lire la doc", + + "home.growth.title": "L'agent de code IA open source", + "home.growth.body": + "Avec plus de {{stars}} étoiles sur GitHub, {{contributors}} contributeurs et plus de {{commits}} commits, OpenCode est utilisé et approuvé par plus de {{monthlyUsers}} développeurs chaque mois.", + "home.growth.githubStars": "Étoiles GitHub", + "home.growth.contributors": "Contributeurs", + "home.growth.monthlyDevs": "Devs mensuels", + + "home.privacy.title": "Conçu pour la confidentialité", + "home.privacy.body": + "OpenCode ne stocke ni votre code ni vos données de contexte, afin de pouvoir fonctionner dans des environnements sensibles à la confidentialité.", + "home.privacy.learnMore": "En savoir plus sur", + "home.privacy.link": "la confidentialité", + + "home.faq.q1": "Qu'est-ce que OpenCode ?", + "home.faq.a1": + "OpenCode est un agent open source qui vous aide à écrire et exécuter du code avec n'importe quel modèle d'IA. Il est disponible en interface terminal, application desktop ou extension IDE.", + "home.faq.q2": "Comment utiliser OpenCode ?", + "home.faq.a2.before": "Le moyen le plus simple de commencer est de lire l'", + "home.faq.a2.link": "intro", + "home.faq.q3": "Ai-je besoin d'abonnements IA supplémentaires pour utiliser OpenCode ?", + "home.faq.a3.p1": + "Pas forcément : OpenCode propose des modèles gratuits que vous pouvez utiliser sans créer de compte.", + "home.faq.a3.p2.beforeZen": "En plus, vous pouvez utiliser des modèles populaires pour le code en créant un compte", + "home.faq.a3.p2.afterZen": ".", + "home.faq.a3.p3": + "Nous encourageons l'utilisation de Zen, mais OpenCode fonctionne aussi avec les fournisseurs populaires comme OpenAI, Anthropic, xAI, etc.", + "home.faq.a3.p4.beforeLocal": "Vous pouvez même connecter vos", + "home.faq.a3.p4.localLink": "modèles locaux", + "home.faq.q4": "Puis-je utiliser mes abonnements IA existants avec OpenCode ?", + "home.faq.a4.p1": + "Oui, OpenCode prend en charge les abonnements des principaux fournisseurs. Vous pouvez utiliser Claude Pro/Max, ChatGPT Plus/Pro ou GitHub Copilot.", + "home.faq.q5": "Puis-je utiliser OpenCode uniquement dans le terminal ?", + "home.faq.a5.beforeDesktop": "Plus maintenant ! OpenCode est désormais disponible en application pour", + "home.faq.a5.desktop": "desktop", + "home.faq.a5.and": "et", + "home.faq.a5.web": "web", + "home.faq.q6": "Combien coûte OpenCode ?", + "home.faq.a6": + "OpenCode est 100% gratuit. Il inclut aussi des modèles gratuits. Des coûts supplémentaires peuvent s'appliquer si vous connectez un autre fournisseur.", + "home.faq.q7": "Qu'en est-il des données et de la confidentialité ?", + "home.faq.a7.p1": + "Vos données ne sont stockées que lorsque vous utilisez nos modèles gratuits ou créez des liens partageables.", + "home.faq.a7.p2.beforeModels": "En savoir plus sur", + "home.faq.a7.p2.modelsLink": "nos modèles", + "home.faq.a7.p2.and": "et", + "home.faq.a7.p2.shareLink": "les pages de partage", + "home.faq.q8": "OpenCode est-il open source ?", + "home.faq.a8.p1": "Oui, OpenCode est entièrement open source. Le code source est public sur", + "home.faq.a8.p2": "sous la", + "home.faq.a8.mitLicense": "Licence MIT", + "home.faq.a8.p3": + ", ce qui signifie que tout le monde peut l'utiliser, le modifier ou contribuer à son développement. Toute personne de la communauté peut ouvrir des tickets, soumettre des pull requests et étendre les fonctionnalités.", + + "home.zenCta.title": "Accédez à des modèles fiables et optimisés pour les agents de code", + "home.zenCta.body": + "Zen vous donne accès à un ensemble sélectionné de modèles d'IA que OpenCode a testés et benchmarkés spécifiquement pour les agents de code. Plus besoin de vous soucier des variations de performance et de qualité selon les fournisseurs : utilisez des modèles validés qui fonctionnent.", + "home.zenCta.link": "En savoir plus sur Zen", + + "zen.title": "OpenCode Zen | Un ensemble sélectionné de modèles fiables et optimisés pour les agents de code", + "zen.hero.title": "Modèles fiables et optimisés pour les agents de code", + "zen.hero.body": + "Zen vous donne accès à un ensemble sélectionné de modèles d'IA que OpenCode a testés et benchmarkés spécifiquement pour les agents de code. Plus besoin de vous soucier des variations de performance et de qualité selon les fournisseurs : utilisez des modèles validés qui fonctionnent.", + + "zen.faq.q1": "Qu'est-ce que OpenCode Zen ?", + "zen.faq.a1": + "Zen est un ensemble sélectionné de modèles d'IA testés et benchmarkés pour les agents de code, créé par l'équipe derrière OpenCode.", + "zen.faq.q2": "Qu'est-ce qui rend Zen plus précis ?", + "zen.faq.a2": + "Zen ne propose que des modèles testés et benchmarkés spécifiquement pour les agents de code. Vous n'utiliseriez pas un couteau à beurre pour couper un steak ; n'utilisez pas de mauvais modèles pour coder.", + "zen.faq.q3": "Zen est-il moins cher ?", + "zen.faq.a3": + "Zen n'est pas à but lucratif. Zen vous facture au prix coûtant des fournisseurs de modèles. Plus Zen est utilisé, plus OpenCode peut négocier de meilleurs tarifs et vous les répercuter.", + "zen.faq.q4": "Combien coûte Zen ?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "facture par requête", + "zen.faq.a4.p1.afterPricing": "sans marge, vous payez donc exactement ce que facture le fournisseur du modèle.", + "zen.faq.a4.p2.beforeAccount": + "Votre coût total dépend de l'usage, et vous pouvez définir des limites de dépense mensuelles dans votre", + "zen.faq.a4.p2.accountLink": "compte", + "zen.faq.a4.p3": + "Pour couvrir les coûts, OpenCode ajoute uniquement de petits frais de traitement de paiement de 1,23 $ par recharge de 20 $.", + "zen.faq.q5": "Et pour les données et la confidentialité ?", + "zen.faq.a5.beforeExceptions": + "Tous les modèles Zen sont hébergés aux États-Unis. Les fournisseurs appliquent une politique de rétention zéro et n'utilisent pas vos données pour l'entraînement des modèles, avec les", + "zen.faq.a5.exceptionsLink": "exceptions suivantes", + "zen.faq.q6": "Puis-je définir des limites de dépense ?", + "zen.faq.a6": "Oui, vous pouvez définir des limites de dépense mensuelles dans votre compte.", + "zen.faq.q7": "Puis-je annuler ?", + "zen.faq.a7": "Oui, vous pouvez désactiver la facturation à tout moment et utiliser votre solde restant.", + "zen.faq.q8": "Puis-je utiliser Zen avec d'autres agents de code ?", + "zen.faq.a8": + "Zen fonctionne très bien avec OpenCode, mais vous pouvez utiliser Zen avec n'importe quel agent. Suivez les instructions de configuration dans votre agent préféré.", + "zen.faq.q9": "Puis-je obtenir un remboursement ?", + "zen.faq.a9": + "Vous pourriez avoir droit à un remboursement si le paiement a été effectué au cours des 14 derniers jours et que vous n’avez pas utilisé le crédit de cet achat. {{contact}} pour demander un remboursement.", + + "zen.cta.start": "Commencez avec Zen", + "zen.pricing.title": "Ajoutez 20 $ de solde Pay as you go", + "zen.pricing.fee": "(+1,23 $ de frais de traitement de carte)", + "zen.pricing.body": + "Utilisez avec n'importe quel agent. Fixez des limites de dépenses mensuelles. Annulez à tout moment.", + "zen.problem.title": "Quel problème Zen résout-il ?", + "zen.problem.body": + "Il existe de nombreux modèles disponibles, mais seuls quelques-uns fonctionnent bien avec les agents de code. La plupart des fournisseurs les configurent différemment avec des résultats variables.", + "zen.problem.subtitle": + "Nous résolvons ce problème pour tout le monde, pas seulement pour les utilisateurs de OpenCode.", + "zen.problem.item1": "Test des modèles sélectionnés et consultation de leurs équipes", + "zen.problem.item2": "Collaboration avec les fournisseurs pour garantir une livraison correcte", + "zen.problem.item3": "Benchmark de toutes les combinaisons modèle-fournisseur que nous recommandons", + "zen.how.title": "Comment fonctionne Zen", + "zen.how.body": + "Bien que nous vous suggérions d'utiliser Zen avec OpenCode, vous pouvez utiliser Zen avec n'importe quel agent.", + "zen.how.step1.title": "Inscrivez-vous et ajoutez un solde de 20 $", + "zen.how.step1.beforeLink": "suivez les", + "zen.how.step1.link": "instructions de configuration", + "zen.how.step2.title": "Utilisez Zen avec une tarification transparente", + "zen.how.step2.link": "payez par requête", + "zen.how.step2.afterLink": "sans marge", + "zen.how.step3.title": "Recharge automatique", + "zen.how.step3.body": "lorsque votre solde atteint 5 $, nous ajouterons automatiquement 20 $", + "zen.privacy.title": "Votre vie privée est importante pour nous", + "zen.privacy.beforeExceptions": + "Tous les modèles Zen sont hébergés aux États-Unis. Les fournisseurs suivent une politique de rétention zéro et n'utilisent pas vos données pour l'entraînement des modèles, avec les", + "zen.privacy.exceptionsLink": "exceptions suivantes", + + "go.title": "OpenCode Go | Modèles de code à faible coût pour tous", + "go.meta.description": + "Go coûte 10 $/mois, avec des limites d'utilisation généreuses et un accès fiable aux principaux modèles de codage.", + "go.hero.title": "Modèles de code à faible coût pour tous", + "go.hero.body": + "Go apporte le codage agentique aux programmeurs du monde entier. Offrant des limites généreuses et un accès fiable aux modèles open source les plus capables, pour que vous puissiez construire avec des agents puissants sans vous soucier du coût ou de la disponibilité.", + + "go.cta.start": "S'abonner à Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "S'abonner à Go", + "go.cta.price": "10 $/mois", + "go.pricing.body": + "Utilisez-le avec n'importe quel agent. 10 $/mois. Rechargez du crédit si nécessaire. Annulez à tout moment.", + "go.graph.free": "Gratuit", + "go.graph.freePill": "Big Pickle et modèles gratuits", + "go.graph.go": "Go", + "go.graph.label": "Requêtes par tranche de 5 heures", + "go.graph.period": "Utilisation", + "go.graph.model": "Modèle", + "go.graph.requests": "Requêtes estimées / 5 h", + "go.graph.allowance": "Utilisation mensuelle", + "go.graph.new": "Nouveau", + "go.graph.scale": "Échelle non linéaire des requêtes", + "go.graph.showAll": "Voir les {{count}} modèles", + "go.graph.showLess": "Afficher moins de modèles", + "go.graph.limitedRegions": "régions limitées", + "go.graph.limitedTime": "durée limitée", + "go.graph.usageLimits": "Limites d’utilisation", + "go.graph.aria": "Requêtes par 5h : {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-PDG, Terminal Products", + "go.testimonials.dax.quoteAfter": "a changé ma vie, c'est vraiment une évidence.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Fondateur, SEED, PM, Melt, Pop, Dapt, Cadmus, et ViewPoint", + "go.testimonials.jay.quoteBefore": "4 personnes sur 5 dans notre équipe adorent utiliser", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "Je ne peux pas recommander", + "go.testimonials.adam.quoteAfter": "assez. Sérieusement, c'est vraiment bien.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Directeur du Design, Laravel", + "go.testimonials.david.quoteBefore": "Avec", + "go.testimonials.david.quoteAfter": "je sais que tous les modèles sont testés et parfaits pour les agents de code.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Stagiaire, Nvidia (4 fois)", + "go.testimonials.frank.quote": "J'aimerais être encore chez Nvidia.", + "go.problem.title": "Quel problème Go résout-il ?", + "go.problem.body": + "Nous nous efforçons d'apporter l'expérience OpenCode au plus grand nombre. OpenCode Go est un abonnement à faible coût de 10 $/mois. Il offre des limites généreuses et un accès fiable aux modèles open source les plus performants.", + "go.problem.subtitle": " ", + "go.problem.item1": "Prix d'abonnement bas", + "go.problem.item2": "Limites généreuses et accès fiable", + "go.problem.item3": "Conçu pour autant de programmeurs que possible", + "go.problem.item4": "Une sélection de modèles testés pour le codage agentique", + "go.how.title": "Comment fonctionne Go", + "go.how.body": "Go coûte 10 $/mois. Vous pouvez l'utiliser avec OpenCode ou n'importe quel agent.", + "go.how.step1.title": "Créez un compte", + "go.how.step1.beforeLink": "suivez les", + "go.how.step1.link": "instructions de configuration", + "go.how.step2.title": "Abonnez-vous à Go", + "go.how.step2.link": "10 $/mois", + "go.how.step2.afterLink": "avec des limites généreuses", + "go.how.step3.title": "Commencez à coder", + "go.how.step3.body": "avec un accès fiable aux modèles open source", + "go.privacy.title": "Votre vie privée est importante pour nous", + "go.privacy.body": + "Le plan est conçu principalement pour les utilisateurs internationaux, avec des modèles hébergés aux États-Unis, dans l'UE et à Singapour pour un accès mondial stable.", + "go.privacy.contactAfter": "si vous avez des questions.", + "go.privacy.beforeExceptions": + "Les modèles Go sont hébergés aux États-Unis. Les fournisseurs suivent une politique de rétention zéro et n'utilisent pas vos données pour l'entraînement des modèles, avec les", + "go.privacy.exceptionsLink": "exceptions suivantes", + "go.faq.q1": "Qu'est-ce que OpenCode Go ?", + "go.faq.a1": + "Go est un abonnement à faible coût qui vous donne un accès fiable à des modèles open source performants pour le codage agentique.", + "go.faq.q2": "Quels modèles Go inclut-il ?", + "go.faq.a2": "Go inclut les modèles ci-dessous, avec des limites généreuses et un accès fiable.", + "go.faq.q3": "Est-ce que Go est la même chose que Zen ?", + "go.faq.a3": + "Non. Zen est un paiement à l'utilisation, tandis que Go coûte 10 $/mois, avec des limites généreuses et un accès fiable à une sélection de modèles.", + "go.faq.q4": "Combien coûte Go ?", + "go.faq.a4.p1.beforePricing": "Go coûte", + "go.faq.a4.p1.pricingLink": "10 $/mois", + "go.faq.a4.p1.afterPricing": "avec des limites généreuses.", + "go.faq.a4.p2.beforeAccount": "Vous pouvez gérer votre abonnement dans votre", + "go.faq.a4.p2.accountLink": "compte", + "go.faq.a4.p3": "Annulez à tout moment.", + "go.faq.q5": "Et pour les données et la confidentialité ?", + "go.faq.a5.model": "Modèle", + "go.faq.a5.training": "Entraînement des modèles", + "go.faq.a5.retention": "Conservation des données", + "go.faq.a5.retention30": "30 jours", + "go.faq.a5.retention0": "0 jour", + "go.faq.a5.used": "Utilisé", + "go.faq.a5.notUsed": "Non utilisé", + "go.faq.a5.noAgreement": "Aucun accord", + "go.faq.a5.notZdr": "Pas de ZDR", + "go.faq.a5.grokRetention": + "Le ZDR désactive d'importantes fonctionnalités API qui dépendent des données stockées, notamment Responses API avec état, Files and Collections et Batch API.", + "go.faq.a5.gptRetention": + "Des journaux de surveillance des abus sont générés pour toute utilisation des fonctionnalités API et conservés pendant un maximum de 30 jours.", + "go.faq.a5.museRetention": + "Des tarifs de tokens fortement réduits en échange de l’autorisation d’utiliser vos prompts et vos complétions pour entraîner de futurs modèles Meta.", + "go.faq.a5.learnMore": "En savoir plus", + "go.faq.a5.deepseekRetention": + "L’accord ZDR est renouvelé chaque mois. L’accord actuel est valable jusqu’au 30 septembre 2026.", + + "go.faq.a5.beforeExceptions": + "Les modèles Go sont hébergés aux États-Unis. Les fournisseurs suivent une politique de rétention zéro et n'utilisent pas vos données pour l'entraînement des modèles, avec les", + "go.faq.a5.exceptionsLink": "exceptions suivantes", + "go.faq.q6": "Puis-je recharger mon crédit ?", + "go.faq.a6": "Si vous avez besoin de plus d'utilisation, vous pouvez recharger du crédit dans votre compte.", + "go.faq.q7": "Puis-je annuler ?", + "go.faq.a7": "Oui, vous pouvez annuler à tout moment.", + "go.faq.q8": "Puis-je utiliser Go avec d'autres agents de code ?", + "go.faq.a8": + "Oui, vous pouvez utiliser Go avec n'importe quel agent. Suivez les instructions de configuration dans votre agent de code préféré.", + "go.faq.q9": "Quelle est la différence entre les modèles gratuits et Go ?", + "go.faq.a9": + "Les modèles gratuits incluent Big Pickle ainsi que les modèles promotionnels disponibles à ce moment-là, avec un quota de 200 requêtes/jour. Go propose une sélection de modèles avec des quotas de requêtes plus élevés appliqués sur des fenêtres glissantes (5 heures, hebdomadaire et mensuelle), à peu près équivalents à des quotas de base de 12 $ par 5 heures, 30 $ par semaine et 60 $ par mois ; les quotas propres à chaque modèle peuvent varier (le nombre réel de requêtes varie selon le modèle et l'utilisation).", + "go.faq.q10": "Puis-je obtenir un remboursement ?", + "go.faq.a10": + "Vous pourriez avoir droit à un remboursement si le paiement a été effectué au cours des 14 derniers jours et que vous n’avez pas utilisé votre quota Go pendant cette période de facturation. {{contact}} pour demander un remboursement.", + + "zen.api.error.rateLimitExceeded": "Limite de débit dépassée. Veuillez réessayer plus tard.", + "zen.api.error.modelNotSupported": "Modèle {{model}} non pris en charge", + "zen.api.error.modelFormatNotSupported": "Modèle {{model}} non pris en charge pour le format {{format}}", + "zen.api.error.noProviderAvailable": "Aucun fournisseur disponible", + "zen.api.error.providerNotSupported": "Fournisseur {{provider}} non pris en charge", + "zen.api.error.missingApiKey": "Clé API manquante.", + "zen.api.error.invalidApiKey": "Clé API invalide.", + "zen.api.error.requestBlockedByUpstreamProvider": "Requête bloquée par le fournisseur en amont.", + "zen.api.error.subscriptionQuotaExceeded": "Quota d'abonnement dépassé. Réessayez dans {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "Limite d'utilisation sur 5 heures atteinte. Réinitialisation dans {{retryIn}}. Pour continuer à utiliser ce modèle dès maintenant, activez l'utilisation depuis votre solde disponible : {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Limite d'utilisation hebdomadaire atteinte. Réinitialisation dans {{retryIn}}. Pour continuer à utiliser ce modèle dès maintenant, activez l'utilisation depuis votre solde disponible : {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Limite d'utilisation mensuelle atteinte. Réinitialisation dans {{retryIn}}. Pour continuer à utiliser ce modèle dès maintenant, activez l'utilisation depuis votre solde disponible : {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Aucune méthode de paiement. Ajoutez une méthode de paiement ici : {{billingUrl}}", + "zen.api.error.insufficientBalance": "Solde insuffisant. Gérez votre facturation ici : {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Votre espace de travail a atteint sa limite de dépense mensuelle de {{amount}} $. Gérez vos limites ici : {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Vous avez atteint votre limite de dépense mensuelle de {{amount}} $. Gérez vos limites ici : {{membersUrl}}", + "zen.api.error.modelDisabled": "Le modèle est désactivé", + "zen.api.error.regionNotAllowed": + "La dernière version de ce modèle est uniquement disponible avec un hébergement en Chine et nécessite votre consentement explicite : {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Ce modèle n’est pas disponible dans votre pays.", + "zen.api.error.trainingNotAllowed": + "Ce modèle collecte des données utilisées pour améliorer sa qualité et nécessite votre consentement explicite : {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "La promotion gratuite de {{model}} est terminée. Vous pouvez continuer à utiliser le modèle en vous abonnant à OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Accédez aux meilleurs modèles de code au monde", + "black.meta.description": "Accédez à Claude, GPT, Gemini et plus avec les forfaits d'abonnement OpenCode Black.", + "black.hero.title": "Accédez aux meilleurs modèles de code au monde", + "black.hero.subtitle": "Y compris Claude, GPT, Gemini et plus", + "black.title": "OpenCode Black | Tarification", + "black.paused": "L'inscription au plan Black est temporairement suspendue.", + "black.plan.icon20": "Forfait Black 20", + "black.plan.icon100": "Forfait Black 100", + "black.plan.icon200": "Forfait Black 200", + "black.plan.multiplier100": "5x plus d'utilisation que Black 20", + "black.plan.multiplier200": "20x plus d'utilisation que Black 20", + "black.price.perMonth": "par mois", + "black.price.perPersonBilledMonthly": "par personne facturé mensuellement", + "black.terms.1": "Votre abonnement ne commencera pas immédiatement", + "black.terms.2": "Vous serez ajouté à la liste d'attente et activé bientôt", + "black.terms.3": "Votre carte ne sera débitée que lorsque votre abonnement sera activé", + "black.terms.4": + "Des limites d'utilisation s'appliquent, une utilisation fortement automatisée peut atteindre les limites plus tôt", + "black.terms.5": "Les abonnements sont pour les individus, contactez Enterprise pour les équipes", + "black.terms.6": "Les limites peuvent être ajustées et les forfaits peuvent être interrompus à l'avenir", + "black.terms.7": "Annulez votre abonnement à tout moment", + "black.action.continue": "Continuer", + "black.finePrint.beforeTerms": "Les prix affichés n'incluent pas les taxes applicables", + "black.finePrint.terms": "Conditions d'utilisation", + "black.workspace.title": "OpenCode Black | Sélectionner un espace de travail", + "black.workspace.selectPlan": "Sélectionnez un espace de travail pour ce forfait", + "black.workspace.name": "Espace de travail {{n}}", + "black.subscribe.title": "S'abonner à OpenCode Black", + "black.subscribe.paymentMethod": "Méthode de paiement", + "black.subscribe.loadingPaymentForm": "Chargement du formulaire de paiement...", + "black.subscribe.selectWorkspaceToContinue": "Sélectionnez un espace de travail pour continuer", + "black.subscribe.failurePrefix": "Oh oh !", + "black.subscribe.error.generic": "Une erreur est survenue", + "black.subscribe.error.invalidPlan": "Forfait invalide", + "black.subscribe.error.workspaceRequired": "L'ID de l'espace de travail est requis", + "black.subscribe.error.alreadySubscribed": "Cet espace de travail a déjà un abonnement", + "black.subscribe.processing": "Traitement...", + "black.subscribe.submit": "S'abonner ${{plan}}", + "black.subscribe.form.chargeNotice": "Vous ne serez débité que lorsque votre abonnement sera activé", + "black.subscribe.success.title": "Vous êtes sur la liste d'attente OpenCode Black", + "black.subscribe.success.subscriptionPlan": "Forfait d'abonnement", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Montant", + "black.subscribe.success.amountValue": "{{plan}} $ par mois", + "black.subscribe.success.paymentMethod": "Méthode de paiement", + "black.subscribe.success.dateJoined": "Date d'inscription", + "black.subscribe.success.chargeNotice": "Votre carte sera débitée lorsque votre abonnement sera activé", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Utilisation", + "workspace.nav.apiKeys": "Clés API", + "workspace.nav.members": "Membres", + "workspace.nav.billing": "Facturation", + "workspace.nav.settings": "Paramètres", + + "workspace.home.banner.beforeLink": "Modèles optimisés fiables pour les agents de code.", + "workspace.lite.banner.beforeLink": "Modèles de code à faible coût pour tous.", + "workspace.home.billing.loading": "Chargement...", + "workspace.home.billing.enable": "Activer la facturation", + "workspace.home.billing.currentBalance": "Solde actuel", + + "workspace.newUser.feature.tested.title": "Modèles testés et vérifiés", + "workspace.newUser.feature.tested.body": + "Nous avons benchmarké et testé des modèles spécifiquement pour les agents de code afin de garantir les meilleures performances.", + "workspace.newUser.feature.quality.title": "La plus haute qualité", + "workspace.newUser.feature.quality.body": + "Accédez à des modèles configurés pour des performances optimales - pas de rétrogradation ni de routage vers des fournisseurs moins chers.", + "workspace.newUser.feature.lockin.title": "Pas de verrouillage", + "workspace.newUser.feature.lockin.body": + "Utilisez Zen avec n'importe quel agent de code et continuez à utiliser d'autres fournisseurs avec OpenCode quand vous le souhaitez.", + "workspace.newUser.copyApiKey": "Copier la clé API", + "workspace.newUser.copyKey": "Copier la clé", + "workspace.newUser.copied": "Copié !", + "workspace.newUser.step.enableBilling": "Activer la facturation", + "workspace.newUser.step.login.before": "Exécuter", + "workspace.newUser.step.login.after": "et sélectionnez OpenCode", + "workspace.newUser.step.pasteKey": "Collez votre clé API", + "workspace.newUser.step.models.before": "Démarrez OpenCode et exécutez", + "workspace.newUser.step.models.after": "pour sélectionner un modèle", + + "workspace.models.title": "Modèles", + "workspace.models.subtitle.beforeLink": + "Gérez les modèles auxquels les membres de l'espace de travail peuvent accéder.", + "workspace.models.table.model": "Modèle", + "workspace.models.table.enabled": "Activé", + + "workspace.providers.title": "Apportez votre propre clé", + "workspace.providers.subtitle": "Configurez vos propres clés API auprès des fournisseurs d'IA.", + "workspace.providers.placeholder": "Entrez la clé API {{provider}} ({{prefix}}...)", + "workspace.providers.configure": "Configurer", + "workspace.providers.edit": "Modifier", + "workspace.providers.delete": "Supprimer", + "workspace.providers.saving": "Enregistrement...", + "workspace.providers.save": "Enregistrer", + "workspace.providers.table.provider": "Fournisseur", + "workspace.providers.table.apiKey": "Clé API", + + "workspace.usage.title": "Historique d'utilisation", + "workspace.usage.subtitle": "Utilisation récente de l'API et coûts.", + "workspace.usage.empty": "Faites votre premier appel API pour commencer.", + "workspace.usage.table.date": "Date", + "workspace.usage.table.model": "Modèle", + "workspace.usage.table.input": "Entrée", + "workspace.usage.table.output": "Sortie", + "workspace.usage.table.cost": "Coût", + "workspace.usage.table.session": "Session", + "workspace.usage.breakdown.input": "Entrée", + "workspace.usage.breakdown.cacheRead": "Lecture cache", + "workspace.usage.breakdown.cacheWrite": "Écriture cache", + "workspace.usage.breakdown.output": "Sortie", + "workspace.usage.breakdown.reasoning": "Raisonnement", + "workspace.usage.subscription": "Black ({{amount}} $)", + "workspace.usage.lite": "Go ({{amount}} $)", + "workspace.usage.byok": "BYOK ({{amount}} $)", + + "workspace.cost.title": "Coût", + "workspace.cost.subtitle": "Coûts d'utilisation répartis par modèle.", + "workspace.cost.allModels": "Tous les modèles", + "workspace.cost.allKeys": "Toutes les clés", + "workspace.cost.deletedSuffix": "(supprimé)", + "workspace.cost.empty": "Aucune donnée d'utilisation disponible pour la période sélectionnée.", + "workspace.cost.subscriptionShort": "abo", + + "workspace.keys.title": "Clés API", + "workspace.keys.subtitle": "Gérez vos clés API pour accéder aux services OpenCode.", + "workspace.keys.create": "Créer une clé API", + "workspace.keys.placeholder": "Entrez le nom de la clé", + "workspace.keys.empty": "Créer une clé API OpenCode Gateway", + "workspace.keys.table.name": "Nom", + "workspace.keys.table.key": "Clé", + "workspace.keys.table.createdBy": "Créé par", + "workspace.keys.table.lastUsed": "Dernière utilisation", + "workspace.keys.copyApiKey": "Copier la clé API", + "workspace.keys.delete": "Supprimer", + + "workspace.members.title": "Membres", + "workspace.members.subtitle": "Gérez les membres de l'espace de travail et leurs autorisations.", + "workspace.members.invite": "Inviter un membre", + "workspace.members.inviting": "Invitation en cours...", + "workspace.members.beta.beforeLink": "Les espaces de travail sont gratuits pour les équipes pendant la version bêta.", + "workspace.members.form.invitee": "Invité", + "workspace.members.form.emailPlaceholder": "Entrez l'e-mail", + "workspace.members.form.role": "Rôle", + "workspace.members.form.monthlyLimit": "Limite de dépense mensuelle", + "workspace.members.noLimit": "Aucune limite", + "workspace.members.noLimitLowercase": "pas de limite", + "workspace.members.invited": "invité", + "workspace.members.edit": "Modifier", + "workspace.members.delete": "Supprimer", + "workspace.members.saving": "Enregistrement...", + "workspace.members.save": "Enregistrer", + "workspace.members.table.email": "E-mail", + "workspace.members.table.role": "Rôle", + "workspace.members.table.monthLimit": "Limite mensuelle", + "workspace.members.role.admin": "Administrateur", + "workspace.members.role.adminDescription": "Peut gérer les modèles, les membres et la facturation", + "workspace.members.role.member": "Membre", + "workspace.members.role.memberDescription": "Ne peut générer que des clés API pour lui-même", + + "workspace.settings.title": "Paramètres", + "workspace.settings.subtitle": "Mettez à jour le nom et les préférences de votre espace de travail.", + "workspace.settings.workspaceName": "Nom de l'espace de travail", + "workspace.settings.defaultName": "Défaut", + "workspace.settings.updating": "Mise à jour...", + "workspace.settings.save": "Enregistrer", + "workspace.settings.edit": "Modifier", + + "workspace.billing.title": "Facturation", + "workspace.billing.subtitle.beforeLink": "Gérer les méthodes de paiement.", + "workspace.billing.contactUs": "Contactez-nous", + "workspace.billing.subtitle.afterLink": "si vous avez des questions.", + "workspace.billing.currentBalance": "Solde actuel", + "workspace.billing.add": "Ajouter $", + "workspace.billing.enterAmount": "Saisir le montant", + "workspace.billing.loading": "Chargement...", + "workspace.billing.addAction": "Ajouter", + "workspace.billing.addBalance": "Ajouter un solde", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Lié à Stripe", + "workspace.billing.manage": "Gérer", + "workspace.billing.enable": "Activer la facturation", + + "workspace.monthlyLimit.title": "Limite mensuelle", + "workspace.monthlyLimit.subtitle": "Définissez une limite d'utilisation mensuelle pour votre compte.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Définition...", + "workspace.monthlyLimit.set": "Défini", + "workspace.monthlyLimit.edit": "Modifier la limite", + "workspace.monthlyLimit.noLimit": "Aucune limite d'utilisation définie.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "L'utilisation actuelle pour", + "workspace.monthlyLimit.currentUsage.beforeAmount": "est de", + + "workspace.redeem.title": "Utiliser un coupon", + "workspace.redeem.subtitle": "Utilisez un code promo pour obtenir du crédit ou des avantages.", + "workspace.redeem.placeholder": "Saisissez le code promo", + "workspace.redeem.redeem": "Utiliser", + "workspace.redeem.redeeming": "Utilisation...", + "workspace.redeem.success": "Coupon utilisé avec succès.", + + "workspace.reload.title": "Rechargement automatique", + "workspace.reload.disabled.before": "Le rechargement automatique est", + "workspace.reload.disabled.state": "désactivé", + "workspace.reload.disabled.after": "Activer le rechargement automatique lorsque le solde est faible.", + "workspace.reload.enabled.before": "Le rechargement automatique est", + "workspace.reload.enabled.state": "activé", + "workspace.reload.enabled.middle": "Nous rechargerons", + "workspace.reload.processingFee": "frais de traitement", + "workspace.reload.enabled.after": "quand le solde atteint", + "workspace.reload.edit": "Modifier", + "workspace.reload.enable": "Activer", + "workspace.reload.enableAutoReload": "Activer le rechargement automatique", + "workspace.reload.reloadAmount": "Recharger $", + "workspace.reload.whenBalanceReaches": "Lorsque le solde atteint $", + "workspace.reload.saving": "Enregistrement...", + "workspace.reload.save": "Enregistrer", + "workspace.reload.failedAt": "Le rechargement a échoué à", + "workspace.reload.reason": "Raison :", + "workspace.reload.updatePaymentMethod": "Veuillez mettre à jour votre méthode de paiement et réessayer.", + "workspace.reload.retrying": "Nouvelle tentative...", + "workspace.reload.retry": "Réessayer", + "workspace.reload.error.paymentFailed": "Échec du paiement.", + + "workspace.payments.title": "Historique des paiements", + "workspace.payments.subtitle": "Transactions de paiement récentes.", + "workspace.payments.table.date": "Date", + "workspace.payments.table.paymentId": "ID de paiement", + "workspace.payments.table.amount": "Montant", + "workspace.payments.table.receipt": "Reçu", + "workspace.payments.type.credit": "crédit", + "workspace.payments.type.subscription": "abonnement", + "workspace.payments.view": "Voir", + + "workspace.black.loading": "Chargement...", + "workspace.black.time.day": "jour", + "workspace.black.time.days": "jours", + "workspace.black.time.hour": "heure", + "workspace.black.time.hours": "heures", + "workspace.black.time.minute": "minute", + "workspace.black.time.minutes": "minutes", + "workspace.black.time.fewSeconds": "quelques secondes", + "workspace.black.subscription.title": "Abonnement", + "workspace.black.subscription.message": "Vous êtes abonné à OpenCode Black pour {{plan}} $ par mois.", + "workspace.black.subscription.manage": "Gérer l'abonnement", + "workspace.black.subscription.rollingUsage": "Utilisation 5 heures", + "workspace.black.subscription.weeklyUsage": "Utilisation hebdomadaire", + "workspace.black.subscription.resetsIn": "Réinitialisation dans", + "workspace.black.subscription.useBalance": + "Utilisez votre solde disponible après avoir atteint les limites d'utilisation", + "workspace.black.waitlist.title": "Liste d'attente", + "workspace.black.waitlist.joined": + "Vous êtes sur la liste d'attente pour le forfait OpenCode Black à {{plan}} $ par mois.", + "workspace.black.waitlist.ready": + "Nous sommes prêts à vous inscrire au forfait OpenCode Black à {{plan}} $ par mois.", + "workspace.black.waitlist.leave": "Quitter la liste d'attente", + "workspace.black.waitlist.leaving": "Sortie...", + "workspace.black.waitlist.left": "Quitté", + "workspace.black.waitlist.enroll": "S'inscrire", + "workspace.black.waitlist.enrolling": "Inscription...", + "workspace.black.waitlist.enrolled": "Inscrit", + "workspace.black.waitlist.enrollNote": + "Lorsque vous cliquez sur S'inscrire, votre abonnement démarre immédiatement et votre carte sera débitée.", + + "workspace.lite.loading": "Chargement...", + "workspace.lite.time.day": "jour", + "workspace.lite.time.days": "jours", + "workspace.lite.time.hour": "heure", + "workspace.lite.time.hours": "heures", + "workspace.lite.time.minute": "minute", + "workspace.lite.time.minutes": "minutes", + "workspace.lite.time.fewSeconds": "quelques secondes", + "workspace.lite.subscription.message": "Vous êtes abonné à OpenCode Go.", + "workspace.lite.subscription.manage": "Gérer l'abonnement", + "workspace.lite.subscription.rollingUsage": "Utilisation sur 5 heures", + "workspace.lite.subscription.rollingQuota": "Quota sur 5 heures", + "workspace.lite.subscription.weeklyUsage": "Utilisation hebdomadaire", + "workspace.lite.subscription.weeklyQuota": "Quota hebdomadaire", + "workspace.lite.subscription.monthlyUsage": "Utilisation mensuelle", + "workspace.lite.subscription.monthlyQuota": "Quota mensuel", + "workspace.lite.subscription.resetsIn": "Réinitialisation dans", + "workspace.lite.subscription.showDetails": "Afficher les détails", + "workspace.lite.subscription.hideDetails": "Masquer les détails", + "workspace.lite.subscription.model": "Modèle", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Total", + "workspace.lite.subscription.useBalance": + "Utilisez votre solde disponible après avoir atteint les limites d'utilisation", + "workspace.lite.subscription.selectProvider": + 'Sélectionnez "OpenCode Go" comme fournisseur dans votre configuration opencode pour utiliser les modèles Go.', + "workspace.lite.providers.title": "Fournisseurs", + "workspace.lite.providers.description": "Contrôlez les fournisseurs utilisés pour le routage.", + "workspace.lite.providers.allowTraining": "Autoriser les modèles qui s’entraînent sur les données des requêtes", + "workspace.lite.providers.useChina": "Activer les modèles hébergés en Chine", + "workspace.lite.black.message": + "Vous êtes actuellement abonné à OpenCode Black ou sur liste d'attente. Veuillez d'abord vous désabonner si vous souhaitez passer à Go.", + "workspace.lite.other.message": + "Un autre membre de cet espace de travail est déjà abonné à OpenCode Go. Un seul membre par espace de travail peut s'abonner.", + "workspace.lite.promo.description": + "OpenCode Go coûte {{price}} et offre un accès fiable aux modèles de code ouverts populaires avec des limites d'utilisation généreuses.", + "workspace.lite.promo.price": "10 $/mois", + "workspace.lite.promo.modelsTitle": "Ce qui est inclus", + "workspace.lite.promo.footer": + "Ce forfait est principalement conçu pour les utilisateurs internationaux et offre un accès mondial stable. Les tarifs et les limites d'utilisation peuvent évoluer à mesure que nous tirons les enseignements des premières utilisations et des retours reçus.", + "workspace.lite.promo.subscribe": "S'abonner à Go", + "workspace.lite.promo.subscribing": "Redirection...", + "workspace.lite.promo.otherMethods": "Autres méthodes de paiement", + "workspace.lite.promo.selectMethod": "Sélectionner la méthode de paiement", + + "workspace.referral.copyLink": "Copier le lien", + "workspace.referral.copied": "Copié", + "workspace.referral.overview.title": "Inviter des amis", + "workspace.referral.overview.subtitle": "Gagnez $5 lorsqu'un ami s'abonne. Il recevra également $5.", + "workspace.referral.instructions.share": "Partagez votre lien de parrainage", + "workspace.referral.instructions.subscribe": "Votre ami rejoint et s'abonne à Go", + "workspace.referral.instructions.claim": + "Vous recevez tous les deux un crédit d'utilisation de $5 à appliquer à vos limites d'utilisation Go", + "workspace.referral.rewards.title": "Récompenses de parrainage", + "workspace.referral.rewards.description": + "Utilisez les crédits de parrainage disponibles pour votre utilisation de Go.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} récompenses utilisées.", + "workspace.referral.rewards.empty": "Aucune récompense de parrainage pour l'instant.", + "workspace.referral.table.reward": "Récompense", + "workspace.referral.table.referral": "Description", + "workspace.referral.table.date": "Date", + "workspace.referral.reward.description.inviter": "Vous avez invité {{email}}", + "workspace.referral.reward.description.invitee": "Invité par {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Abonnez-vous pour débloquer", + "workspace.referral.reward.action.view": "Voir la récompense", + "workspace.referral.reward.action.applied": "Récompense utilisée", + "workspace.referral.reward.source.pendingInviter": "En attente de son abonnement", + "workspace.referral.reward.source.pendingInvitee": "Abonnez-vous pour débloquer la récompense", + "workspace.referral.reward.source.available": "Récompense prête à utiliser", + "workspace.referral.reward.source.applied": "Récompense utilisée", + "workspace.referral.reward.status.applied": "Récompense utilisée", + "workspace.referral.reward.status.pendingInviter": "Abonnez-vous pour débloquer", + "workspace.referral.reward.status.pendingInvitee": "Abonnez-vous pour débloquer", + "workspace.referral.apply.noGo": "Abonnez-vous pour débloquer", + "workspace.referral.apply.preview": "Voir la récompense", + "workspace.referral.apply.action": "Utiliser", + "workspace.referral.apply.confirmTitle": "Utiliser la récompense", + "workspace.referral.apply.confirmBody": "Utilisez {{amount}} pour réduire l'utilisation actuelle de ce workspace.", + "workspace.referral.apply.confirmAction": "Utiliser", + + "download.title": "OpenCode | Téléchargement", + "download.meta.description": "Téléchargez OpenCode pour macOS, Windows et Linux", + "download.hero.title": "Télécharger OpenCode Desktop", + "download.hero.subtitle": "Disponible en bêta pour macOS, Windows et Linux", + "download.hero.button": "Télécharger pour {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "Extensions OpenCode", + "download.section.integrations": "Intégrations OpenCode", + "download.action.download": "Télécharger", + "download.action.install": "Installer", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Pas forcément, mais probablement. Vous aurez besoin d'un abonnement IA si vous voulez connecter OpenCode à un fournisseur payant, mais vous pouvez travailler avec des", + "download.faq.a3.localLink": "modèles locaux", + "download.faq.a3.afterLocal.beforeZen": "gratuitement. Même si nous encourageons les utilisateurs à utiliser", + "download.faq.a3.afterZen": + ", OpenCode fonctionne avec tous les fournisseurs populaires comme OpenAI, Anthropic, xAI, etc.", + + "download.faq.a5.p1": "OpenCode est 100% gratuit à utiliser.", + "download.faq.a5.p2.beforeZen": + "Les coûts supplémentaires viendront de votre abonnement à un fournisseur de modèle. Même si OpenCode fonctionne avec n'importe quel fournisseur, nous recommandons d'utiliser", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": + "Vos données et informations ne sont stockées que lorsque vous créez des liens partageables dans OpenCode.", + "download.faq.a6.p2.beforeShare": "En savoir plus sur", + "download.faq.a6.shareLink": "les pages de partage", + + "enterprise.title": "OpenCode | Solutions entreprise pour votre organisation", + "enterprise.meta.description": "Contactez OpenCode pour des solutions entreprise", + "enterprise.hero.title": "Votre code vous appartient", + "enterprise.hero.body1": + "OpenCode fonctionne de manière sécurisée au sein de votre organisation, sans stocker de données ni de contexte, et sans restrictions de licence ni revendications de propriété. Démarrez un essai avec votre équipe, puis déployez-le dans votre organisation en l'intégrant à votre SSO et à votre passerelle IA interne.", + "enterprise.hero.body2": "Dites-nous comment nous pouvons vous aider.", + "enterprise.form.name.label": "Nom complet", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Poste", + "enterprise.form.role.placeholder": "Président exécutif", + "enterprise.form.company.label": "Entreprise", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "E-mail professionnel", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Téléphone", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Quel problème essayez-vous de résoudre ?", + "enterprise.form.message.placeholder": "Nous avons besoin d'aide pour...", + "enterprise.form.send": "Envoyer", + "enterprise.form.sending": "Envoi...", + "enterprise.form.success": "Message envoyé, nous vous contacterons bientôt.", + "enterprise.form.success.submitted": "Formulaire soumis avec succès.", + "enterprise.form.error.allFieldsRequired": "Tous les champs sont requis.", + "enterprise.form.error.invalidEmailFormat": "Format d'e-mail invalide.", + "enterprise.form.error.internalServer": "Erreur interne du serveur.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "Qu'est-ce que OpenCode Enterprise ?", + "enterprise.faq.a1": + "OpenCode Enterprise s'adresse aux organisations qui veulent s'assurer que leur code et leurs données ne quittent jamais leur infrastructure. Cela est possible grâce à une configuration centralisée qui s'intègre à votre SSO et à votre passerelle IA interne.", + "enterprise.faq.q2": "Comment démarrer avec OpenCode Enterprise ?", + "enterprise.faq.a2": + "Commencez simplement par un essai interne avec votre équipe. Par défaut, OpenCode ne stocke pas votre code ni vos données de contexte, ce qui facilite la prise en main. Ensuite, contactez-nous pour discuter des tarifs et des options de mise en œuvre.", + "enterprise.faq.q3": "Comment fonctionne la tarification entreprise ?", + "enterprise.faq.a3": + "Nous proposons une tarification entreprise par siège. Si vous avez votre propre passerelle LLM, nous ne facturons pas les tokens utilisés. Pour plus de détails, contactez-nous pour un devis sur mesure en fonction des besoins de votre organisation.", + "enterprise.faq.q4": "Mes données sont-elles sécurisées avec OpenCode Enterprise ?", + "enterprise.faq.a4": + "Oui. OpenCode ne stocke pas votre code ni vos données de contexte. Tout le traitement se fait localement ou via des appels API directs vers votre fournisseur d'IA. Avec une configuration centralisée et une intégration SSO, vos données restent sécurisées au sein de l'infrastructure de votre organisation.", + + "brand.title": "OpenCode | Marque", + "brand.meta.description": "Guide de marque OpenCode", + "brand.heading": "Guide de marque", + "brand.subtitle": "Ressources et éléments pour vous aider à travailler avec la marque OpenCode.", + "brand.downloadAll": "Télécharger tous les assets", + + "changelog.title": "OpenCode | Changelog", + "changelog.meta.description": "Notes de version et changelog d'OpenCode", + "changelog.hero.title": "Changelog", + "changelog.hero.subtitle": "Nouvelles mises à jour et améliorations pour OpenCode", + "changelog.empty": "Aucune entrée de changelog trouvée.", + "changelog.viewJson": "Voir le JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarks", + "bench.list.table.agent": "Agent", + "bench.list.table.model": "Modèle", + "bench.list.table.score": "Score", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Tâche introuvable", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "Agent", + "bench.detail.labels.model": "Modèle", + "bench.detail.labels.task": "Tâche", + "bench.detail.labels.repo": "Dépôt", + "bench.detail.labels.from": "De", + "bench.detail.labels.to": "À", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Durée moyenne", + "bench.detail.labels.averageScore": "Score moyen", + "bench.detail.labels.averageCost": "Coût moyen", + "bench.detail.labels.summary": "Résumé", + "bench.detail.labels.runs": "Exécutions", + "bench.detail.labels.score": "Score", + "bench.detail.labels.base": "Base", + "bench.detail.labels.penalty": "Pénalité", + "bench.detail.labels.weight": "poids", + "bench.detail.table.run": "Exécution", + "bench.detail.table.score": "Score (Base - Pénalité)", + "bench.detail.table.cost": "Coût", + "bench.detail.table.duration": "Durée", + "bench.detail.run.title": "Exécution {{n}}", + "bench.detail.rawJson": "JSON brut", + "bench.submission.error.allFieldsRequired": "Tous les champs sont requis.", +} satisfies Dict diff --git a/packages/console/app/src/i18n/index.ts b/packages/console/app/src/i18n/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..a855ccfa3efee36cb40de255e73f0d2f081dd098 --- /dev/null +++ b/packages/console/app/src/i18n/index.ts @@ -0,0 +1,45 @@ +import type { Locale } from "~/lib/language" +import { dict as en } from "~/i18n/en" +import { dict as zh } from "~/i18n/zh" +import { dict as zht } from "~/i18n/zht" +import { dict as ko } from "~/i18n/ko" +import { dict as de } from "~/i18n/de" +import { dict as es } from "~/i18n/es" +import { dict as fr } from "~/i18n/fr" +import { dict as it } from "~/i18n/it" +import { dict as da } from "~/i18n/da" +import { dict as ja } from "~/i18n/ja" +import { dict as pl } from "~/i18n/pl" +import { dict as ru } from "~/i18n/ru" +import { dict as uk } from "~/i18n/uk" +import { dict as ar } from "~/i18n/ar" +import { dict as no } from "~/i18n/no" +import { dict as br } from "~/i18n/br" +import { dict as th } from "~/i18n/th" +import { dict as tr } from "~/i18n/tr" + +export type Key = keyof typeof en +export type Dict = Record + +const base = en satisfies Dict + +export function i18n(locale: Locale): Dict { + if (locale === "en") return base + if (locale === "zh") return { ...base, ...zh } + if (locale === "zht") return { ...base, ...zht } + if (locale === "ko") return { ...base, ...ko } + if (locale === "de") return { ...base, ...de } + if (locale === "es") return { ...base, ...es } + if (locale === "fr") return { ...base, ...fr } + if (locale === "it") return { ...base, ...it } + if (locale === "da") return { ...base, ...da } + if (locale === "ja") return { ...base, ...ja } + if (locale === "pl") return { ...base, ...pl } + if (locale === "ru") return { ...base, ...ru } + if (locale === "uk") return { ...base, ...uk } + if (locale === "ar") return { ...base, ...ar } + if (locale === "no") return { ...base, ...no } + if (locale === "br") return { ...base, ...br } + if (locale === "th") return { ...base, ...th } + return { ...base, ...tr } +} diff --git a/packages/console/app/src/i18n/it.ts b/packages/console/app/src/i18n/it.ts new file mode 100644 index 0000000000000000000000000000000000000000..cb2f3d7d7a83ab732b8557892f27915131856212 --- /dev/null +++ b/packages/console/app/src/i18n/it.ts @@ -0,0 +1,877 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash offre limiti di utilizzo 4x superiori per un periodo limitato", + "go.graph.bonus": "Utilizzo {{count}}×", + "nav.github": "GitHub", + "nav.docs": "Documentazione", + "nav.changelog": "Changelog", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Accedi", + "nav.free": "Scarica", + "nav.home": "Home", + "nav.openMenu": "Apri menu", + "nav.getStartedFree": "Inizia gratis", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Copia il logo come SVG", + "nav.context.copyWordmark": "Copia il wordmark come SVG", + "nav.context.brandAssets": "Asset del brand", + + "footer.github": "GitHub", + "footer.docs": "Documentazione", + "footer.changelog": "Changelog", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Brand", + "legal.privacy": "Privacy", + "legal.terms": "Termini", + + "email.title": "Sii il primo a sapere quando rilasciamo nuovi prodotti", + "email.subtitle": "Iscriviti alla waitlist per l'accesso anticipato.", + "email.placeholder": "Indirizzo email", + "email.subscribe": "Iscriviti", + "email.success": "Quasi fatto, controlla la posta in arrivo e conferma il tuo indirizzo email", + + "notFound.title": "Non trovato | opencode", + "notFound.heading": "404 - Pagina non trovata", + "notFound.home": "Home", + "notFound.docs": "Documentazione", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "logo chiaro di opencode", + "notFound.logoDarkAlt": "logo scuro di opencode", + + "user.logout": "Esci", + + "auth.callback.error.codeMissing": "Nessun codice di autorizzazione trovato.", + + "workspace.select": "Seleziona workspace", + "workspace.createNew": "+ Crea nuovo workspace", + "workspace.modal.title": "Crea nuovo workspace", + "workspace.modal.placeholder": "Inserisci il nome del workspace", + + "common.cancel": "Annulla", + "common.creating": "Creazione...", + "common.create": "Crea", + "common.contactUs": "Contattaci", + + "common.videoUnsupported": "Il tuo browser non supporta il tag video.", + "common.figure": "Fig {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Scopri di più", + + "error.invalidPlan": "Piano non valido", + "error.workspaceRequired": "ID Workspace richiesto", + "error.alreadySubscribed": "Questo workspace ha già un abbonamento", + "error.limitRequired": "Il limite è richiesto.", + "error.monthlyLimitInvalid": "Imposta un limite mensile valido.", + "error.workspaceNameRequired": "Il nome del workspace è richiesto.", + "error.nameTooLong": "Il nome deve essere di 255 caratteri o meno.", + "error.emailRequired": "L'email è richiesta", + "error.roleRequired": "Il ruolo è richiesto", + "error.idRequired": "L'ID è richiesto", + "error.nameRequired": "Il nome è richiesto", + "error.providerRequired": "Il provider è richiesto", + "error.apiKeyRequired": "La chiave API è richiesta", + "error.modelRequired": "Il modello è richiesto", + "error.reloadAmountMin": "L'importo della ricarica deve essere almeno ${{amount}}", + "error.reloadTriggerMin": "La soglia del saldo deve essere almeno ${{amount}}", + + "app.meta.description": "OpenCode - L'agente di programmazione open source.", + + "home.title": "OpenCode | L'agente di coding IA open source", + + "temp.title": "opencode | Agente di coding IA costruito per il terminale", + "temp.hero.title": "L'agente di coding IA costruito per il terminale", + "temp.zen": "opencode zen", + "temp.getStarted": "Inizia", + "temp.feature.native.title": "TUI Nativa", + "temp.feature.native.body": "Un'interfaccia terminale reattiva, nativa e personalizzabile", + "temp.feature.zen.beforeLink": "Una", + "temp.feature.zen.link": "lista curata di modelli", + "temp.feature.zen.afterLink": "fornita da opencode", + "temp.feature.models.beforeLink": "Supporta 75+ provider LLM tramite", + "temp.feature.models.afterLink": ", inclusi modelli locali", + "temp.screenshot.caption": "OpenCode TUI con il tema tokyonight", + "temp.screenshot.alt": "OpenCode TUI con tema tokyonight", + "temp.logoLightAlt": "logo chiaro di opencode", + "temp.logoDarkAlt": "logo scuro di opencode", + + "home.banner.badge": "Nuovo", + "home.banner.text": "Scopri Tabs per Desktop.", + "home.banner.platforms": "Disponibile su macOS, Windows e Linux", + "home.banner.downloadNow": "Scarica ora", + "home.banner.downloadBetaNow": "Scarica ora la beta desktop", + "home.promo.title": "Scopri Tabs per Desktop", + "home.promo.body": "Organizza il tuo lavoro e le sessioni attive con le schede.", + "home.promo.cta": "Scarica l’ultima versione per iniziare.", + "home.promo.close": "Chiudi l’annuncio dell’app Desktop", + + "home.hero.title": "L'agente di coding IA open source", + "home.hero.subtitle.a": "Modelli gratuiti inclusi o collega qualsiasi modello da qualsiasi provider,", + "home.hero.subtitle.b": "inclusi Claude, GPT, Gemini e altri.", + + "home.install.ariaLabel": "Opzioni di installazione", + + "home.what.title": "Che cos'è OpenCode?", + "home.what.body": "OpenCode è un agente open source che ti aiuta a scrivere codice nel terminale, IDE o desktop.", + "home.what.lsp.title": "LSP abilitato", + "home.what.lsp.body": "Carica automaticamente gli LSP giusti per il LLM", + "home.what.multiSession.title": "Multi-session", + "home.what.multiSession.body": "Avvia più agenti in parallelo sullo stesso progetto", + "home.what.shareLinks.title": "Link condivisi", + "home.what.shareLinks.body": "Condividi un link a qualsiasi sessione per riferimento o debug", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Accedi con GitHub per usare il tuo account Copilot", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Accedi con OpenAI per usare il tuo account ChatGPT Plus o Pro", + "home.what.anyModel.title": "Qualsiasi modello", + "home.what.anyModel.body": "75+ provider LLM tramite Models.dev, inclusi modelli locali", + "home.what.anyEditor.title": "Qualsiasi editor", + "home.what.anyEditor.body": "Disponibile come interfaccia terminale, app desktop ed estensione IDE", + "home.what.readDocs": "Leggi la doc", + + "home.growth.title": "L'agente di coding IA open source", + "home.growth.body": + "Con oltre {{stars}} stelle su GitHub, {{contributors}} contributori e oltre {{commits}} commit, OpenCode è usato e apprezzato da oltre {{monthlyUsers}} sviluppatori ogni mese.", + "home.growth.githubStars": "Stelle GitHub", + "home.growth.contributors": "Contributori", + "home.growth.monthlyDevs": "Devs mensili", + + "home.privacy.title": "Progettato per la privacy", + "home.privacy.body": + "OpenCode non archivia il tuo codice né i dati di contesto, così può operare in ambienti sensibili alla privacy.", + "home.privacy.learnMore": "Scopri di più su", + "home.privacy.link": "privacy", + + "home.faq.q1": "Che cos'è OpenCode?", + "home.faq.a1": + "OpenCode è un agente open source che ti aiuta a scrivere ed eseguire codice con qualsiasi modello di IA. È disponibile come interfaccia terminale, app desktop o estensione IDE.", + "home.faq.q2": "Come uso OpenCode?", + "home.faq.a2.before": "Il modo più semplice per iniziare è leggere l'", + "home.faq.a2.link": "introduzione", + "home.faq.q3": "Mi servono abbonamenti IA extra per usare OpenCode?", + "home.faq.a3.p1": + "Non necessariamente: OpenCode include un set di modelli gratuiti che puoi usare senza creare un account.", + "home.faq.a3.p2.beforeZen": "Inoltre, puoi usare modelli popolari per il coding creando un account", + "home.faq.a3.p2.afterZen": ".", + "home.faq.a3.p3": + "Anche se incoraggiamo gli utenti a usare Zen, OpenCode funziona anche con i provider più diffusi come OpenAI, Anthropic, xAI, ecc.", + "home.faq.a3.p4.beforeLocal": "Puoi anche collegare i tuoi", + "home.faq.a3.p4.localLink": "modelli locali", + "home.faq.q4": "Posso usare i miei abbonamenti IA esistenti con OpenCode?", + "home.faq.a4.p1": + "Sì, OpenCode supporta gli abbonamenti dei principali provider. Puoi usare Claude Pro/Max, ChatGPT Plus/Pro o GitHub Copilot.", + "home.faq.q5": "Posso usare OpenCode solo nel terminale?", + "home.faq.a5.beforeDesktop": "Non più! OpenCode ora è disponibile come app per", + "home.faq.a5.desktop": "desktop", + "home.faq.a5.and": "e", + "home.faq.a5.web": "web", + "home.faq.q6": "Quanto costa OpenCode?", + "home.faq.a6": + "OpenCode è gratuito al 100%. Include anche un set di modelli gratuiti. Potrebbero esserci costi aggiuntivi se colleghi altri provider.", + "home.faq.q7": "E per quanto riguarda dati e privacy?", + "home.faq.a7.p1": + "I tuoi dati vengono archiviati solo quando usi i nostri modelli gratuiti o crei link condivisibili.", + "home.faq.a7.p2.beforeModels": "Scopri di più su", + "home.faq.a7.p2.modelsLink": "i nostri modelli", + "home.faq.a7.p2.and": "e", + "home.faq.a7.p2.shareLink": "le pagine di condivisione", + "home.faq.q8": "OpenCode è open source?", + "home.faq.a8.p1": "Sì, OpenCode è completamente open source. Il codice sorgente è pubblico su", + "home.faq.a8.p2": "sotto la", + "home.faq.a8.mitLicense": "Licenza MIT", + "home.faq.a8.p3": + ", il che significa che chiunque può usarlo, modificarlo o contribuire al suo sviluppo. Chiunque nella comunità può aprire issue, inviare pull request ed estendere le funzionalità.", + + "home.zenCta.title": "Accedi a modelli affidabili e ottimizzati per agenti di coding", + "home.zenCta.body": + "Zen ti dà accesso a una selezione di modelli di IA che OpenCode ha testato e benchmarkato specificamente per agenti di coding. Niente più preoccupazioni per prestazioni e qualità incoerenti tra provider: usa modelli validati che funzionano.", + "home.zenCta.link": "Scopri Zen", + + "zen.title": "OpenCode Zen | Una selezione curata di modelli affidabili e ottimizzati per agenti di coding", + "zen.hero.title": "Accedi a modelli affidabili e ottimizzati per agenti di coding", + "zen.hero.body": + "Zen ti dà accesso a una selezione di modelli di IA che OpenCode ha testato e benchmarkato specificamente per agenti di coding. Niente più preoccupazioni per prestazioni e qualità incoerenti tra provider: usa modelli validati che funzionano.", + + "zen.faq.q1": "Cos'è OpenCode Zen?", + "zen.faq.a1": + "Zen è un set curato di modelli di IA testati e benchmarkati per agenti di coding, creato dal team dietro OpenCode.", + "zen.faq.q2": "Cosa rende Zen più accurato?", + "zen.faq.a2": + "Zen offre solo modelli testati e benchmarkati specificamente per agenti di coding. Non useresti un coltello da burro per tagliare una bistecca; non usare modelli scarsi per programmare.", + "zen.faq.q3": "Zen è più economico?", + "zen.faq.a3": + "Zen non è a scopo di lucro. Zen ribalta i costi dei provider di modelli direttamente su di te. Più Zen viene usato, più OpenCode può negoziare tariffe migliori e passarle a te.", + "zen.faq.q4": "Quanto costa Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "addebita per richiesta", + "zen.faq.a4.p1.afterPricing": "senza ricarichi, quindi paghi esattamente ciò che addebita il provider del modello.", + "zen.faq.a4.p2.beforeAccount": "Il costo totale dipende dall'uso e puoi impostare limiti di spesa mensili nel tuo", + "zen.faq.a4.p2.accountLink": "account", + "zen.faq.a4.p3": + "Per coprire i costi, OpenCode aggiunge solo una piccola commissione di elaborazione del pagamento di $1.23 per ogni ricarica di saldo da $20.", + "zen.faq.q5": "E per quanto riguarda dati e privacy?", + "zen.faq.a5.beforeExceptions": + "Tutti i modelli Zen sono ospitati negli Stati Uniti. I provider seguono una policy di zero-retention e non usano i tuoi dati per l'addestramento dei modelli, con le", + "zen.faq.a5.exceptionsLink": "seguenti eccezioni", + "zen.faq.q6": "Posso impostare limiti di spesa?", + "zen.faq.a6": "Sì, puoi impostare limiti di spesa mensuali nel tuo account.", + "zen.faq.q7": "Posso annullare?", + "zen.faq.a7": "Sì, puoi disattivare la fatturazione in qualsiasi momento e usare il saldo rimanente.", + "zen.faq.q8": "Posso usare Zen con altri agenti di coding?", + "zen.faq.a8": + "Anche se Zen funziona alla grande con OpenCode, puoi usare Zen con qualsiasi agente. Segui le istruzioni di configurazione nel tuo agente di coding preferito.", + "zen.faq.q9": "Posso ottenere un rimborso?", + "zen.faq.a9": + "Potresti avere diritto a un rimborso se l'addebito è stato effettuato negli ultimi 14 giorni e non hai utilizzato il credito di quell'acquisto. {{contact}} per richiedere un rimborso.", + + "zen.cta.start": "Inizia con Zen", + "zen.pricing.title": "Aggiungi $20 di saldo a consumo", + "zen.pricing.fee": "(+$1.23 commissione di elaborazione carta)", + "zen.pricing.body": "Usa con qualsiasi agente. Imposta limiti di spesa mensili. Annulla in qualsiasi momento.", + "zen.problem.title": "Quale problema risolve Zen?", + "zen.problem.body": + "Sono disponibili numerosi modelli, ma solo pochi funzionano bene con gli agenti di coding. La maggior parte dei provider li configura in modo diverso con risultati variabili.", + "zen.problem.subtitle": "Stiamo risolvendo questo problema per tutti, non solo per gli utenti OpenCode.", + "zen.problem.item1": "Testare modelli selezionati e consultare i loro team", + "zen.problem.item2": "Collaborare con i provider per garantire che vengano consegnati correttamente", + "zen.problem.item3": "Benchmark di tutte le combinazioni modello-provider che raccomandiamo", + "zen.how.title": "Come funziona Zen", + "zen.how.body": "Anche se ti consigliamo di utilizzare Zen con OpenCode, puoi utilizzare Zen con qualsiasi agente.", + "zen.how.step1.title": "Iscriviti e aggiungi un saldo di $20", + "zen.how.step1.beforeLink": "segui le", + "zen.how.step1.link": "istruzioni di configurazione", + "zen.how.step2.title": "Usa Zen con prezzi trasparenti", + "zen.how.step2.link": "paga per richiesta", + "zen.how.step2.afterLink": "senza ricarichi", + "zen.how.step3.title": "Ricarica automatica", + "zen.how.step3.body": "quando il tuo saldo raggiunge $5, aggiungeremo automaticamente $20", + "zen.privacy.title": "La tua privacy è importante per noi", + "zen.privacy.beforeExceptions": + "Tutti i modelli Zen sono ospitati negli Stati Uniti. I provider seguono una policy di zero-retention e non usano i tuoi dati per l'addestramento dei modelli, con le", + "zen.privacy.exceptionsLink": "seguenti eccezioni", + + "go.title": "OpenCode Go | Modelli di coding a basso costo per tutti", + "go.meta.description": + "Go costa $10/mese, con limiti di utilizzo generosi e un accesso affidabile ai principali modelli di coding.", + "go.hero.title": "Modelli di coding a basso costo per tutti", + "go.hero.body": + "Go porta il coding agentico ai programmatori di tutto il mondo. Offrendo limiti generosi e un accesso affidabile ai modelli open source più capaci, in modo da poter costruire con agenti potenti senza preoccuparsi dei costi o della disponibilità.", + + "go.cta.start": "Abbonati a Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Abbonati a Go", + "go.cta.price": "$10/mese", + "go.pricing.body": + "Usalo con qualsiasi agente. $10/mese. Ricarica il credito se necessario. Annulla in qualsiasi momento.", + "go.graph.free": "Gratis", + "go.graph.freePill": "Big Pickle e modelli gratuiti", + "go.graph.go": "Go", + "go.graph.label": "Richieste ogni 5 ore", + "go.graph.period": "Utilizzo", + "go.graph.model": "Modello", + "go.graph.requests": "Richieste stimate / 5 ore", + "go.graph.allowance": "Utilizzo mensile", + "go.graph.new": "Nuovo", + "go.graph.scale": "Scala non lineare delle richieste", + "go.graph.showAll": "Mostra tutti i {{count}} modelli", + "go.graph.showLess": "Mostra meno modelli", + "go.graph.limitedRegions": "regioni limitate", + "go.graph.limitedTime": "periodo limitato", + "go.graph.usageLimits": "Limiti di utilizzo", + "go.graph.aria": "Richieste ogni 5h: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "ha cambiato la vita, è davvero una scelta ovvia.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Founder, SEED, PM, Melt, Pop, Dapt, Cadmus, e ViewPoint", + "go.testimonials.jay.quoteBefore": "4 persone su 5 nel nostro team amano usare", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "Non posso raccomandare", + "go.testimonials.adam.quoteAfter": "abbastanza. Seriamente, è davvero buono.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "Con", + "go.testimonials.david.quoteAfter": "so che tutti i modelli sono testati e perfetti per gli agenti di coding.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Intern, Nvidia (4 volte)", + "go.testimonials.frank.quote": "Vorrei essere ancora a Nvidia.", + "go.problem.title": "Quale problema risolve Go?", + "go.problem.body": + "Ci concentriamo nel portare l'esperienza OpenCode a quante più persone possibile. OpenCode Go è un abbonamento a basso costo da $10/mese. Offre limiti generosi e accesso affidabile ai modelli open source più capaci.", + "go.problem.subtitle": " ", + "go.problem.item1": "Prezzo di abbonamento a basso costo", + "go.problem.item2": "Limiti generosi e accesso affidabile", + "go.problem.item3": "Costruito per il maggior numero possibile di programmatori", + "go.problem.item4": "Una selezione curata di modelli testati per il coding agentico", + "go.how.title": "Come funziona Go", + "go.how.body": "Go costa $10/mese. Puoi usarlo con OpenCode o qualsiasi agente.", + "go.how.step1.title": "Crea un account", + "go.how.step1.beforeLink": "segui le", + "go.how.step1.link": "istruzioni di configurazione", + "go.how.step2.title": "Abbonati a Go", + "go.how.step2.link": "$10/mese", + "go.how.step2.afterLink": "con limiti generosi", + "go.how.step3.title": "Inizia a programmare", + "go.how.step3.body": "con accesso affidabile ai modelli open source", + "go.privacy.title": "La tua privacy è importante per noi", + "go.privacy.body": + "Il piano è progettato principalmente per gli utenti internazionali, con modelli ospitati negli Stati Uniti, UE e Singapore per un accesso globale stabile.", + "go.privacy.contactAfter": "se hai domande.", + "go.privacy.beforeExceptions": + "I modelli Go sono ospitati negli Stati Uniti. I provider seguono una policy di zero-retention e non usano i tuoi dati per l'addestramento dei modelli, con le", + "go.privacy.exceptionsLink": "seguenti eccezioni", + "go.faq.q1": "Che cos'è OpenCode Go?", + "go.faq.a1": + "Go è un abbonamento a basso costo che ti dà un accesso affidabile a modelli open source capaci per il coding agentico.", + "go.faq.q2": "Quali modelli include Go?", + "go.faq.a2": "Go include i modelli elencati di seguito, con limiti generosi e accesso affidabile.", + "go.faq.q3": "Go è lo stesso di Zen?", + "go.faq.a3": + "No. Zen è a consumo, mentre Go costa $10/mese, con limiti generosi e un accesso affidabile a una selezione curata di modelli.", + "go.faq.q4": "Quanto costa Go?", + "go.faq.a4.p1.beforePricing": "Go costa", + "go.faq.a4.p1.pricingLink": "$10/mese", + "go.faq.a4.p1.afterPricing": "con limiti generosi.", + "go.faq.a4.p2.beforeAccount": "Puoi gestire il tuo abbonamento nel tuo", + "go.faq.a4.p2.accountLink": "account", + "go.faq.a4.p3": "Annulla in qualsiasi momento.", + "go.faq.q5": "E per quanto riguarda dati e privacy?", + "go.faq.a5.model": "Modello", + "go.faq.a5.training": "Addestramento del modello", + "go.faq.a5.retention": "Conservazione dei dati", + "go.faq.a5.retention30": "30 giorni", + "go.faq.a5.retention0": "0 giorni", + "go.faq.a5.used": "Utilizzato", + "go.faq.a5.notUsed": "Non utilizzato", + "go.faq.a5.noAgreement": "Nessun accordo", + "go.faq.a5.notZdr": "Non ZDR", + "go.faq.a5.grokRetention": + "ZDR disabilita importanti funzionalità API che dipendono dai dati archiviati, tra cui la Responses API con stato, Files and Collections e Batch API.", + "go.faq.a5.gptRetention": + "I log di monitoraggio degli abusi vengono generati per l'utilizzo di tutte le funzionalità API e conservati per un massimo di 30 giorni.", + "go.faq.a5.learnMore": "Scopri di più", + "go.faq.a5.deepseekRetention": + "L'accordo ZDR viene rinnovato mensilmente. L'accordo attuale è valido fino al 30 settembre 2026.", + "go.faq.a5.museRetention": + "Prezzi dei token fortemente scontati in cambio dell'autorizzazione a utilizzare i tuoi prompt e completamenti per addestrare futuri modelli Meta.", + "go.faq.a5.beforeExceptions": + "I modelli Go sono ospitati negli Stati Uniti. I provider seguono una policy di zero-retention e non usano i tuoi dati per l'addestramento dei modelli, con le", + "go.faq.a5.exceptionsLink": "seguenti eccezioni", + "go.faq.q6": "Posso ricaricare il credito?", + "go.faq.a6": "Se hai bisogno di più utilizzo, puoi ricaricare il credito nel tuo account.", + "go.faq.q7": "Posso annullare?", + "go.faq.a7": "Sì, puoi annullare in qualsiasi momento.", + "go.faq.q8": "Posso usare Go con altri agenti di coding?", + "go.faq.a8": + "Sì, puoi usare Go con qualsiasi agente. Segui le istruzioni di configurazione nel tuo agente di coding preferito.", + + "go.faq.q9": "Qual è la differenza tra i modelli gratuiti e Go?", + "go.faq.a9": + "I modelli gratuiti includono Big Pickle più i modelli promozionali disponibili al momento, con una quota di 200 richieste/giorno. Go offre una selezione curata di modelli con quote di richiesta più elevate applicate su finestre mobili (5 ore, settimanale e mensile), approssimativamente equivalenti a quote base di $12 ogni 5 ore, $30 a settimana e $60 al mese; le quote specifiche possono variare in base al modello (il conteggio effettivo delle richieste varia in base al modello e all'utilizzo).", + "go.faq.q10": "Posso ottenere un rimborso?", + "go.faq.a10": + "Potresti avere diritto a un rimborso se l'addebito è stato effettuato negli ultimi 14 giorni e non hai utilizzato la tua quota Go durante quel periodo di fatturazione. {{contact}} per richiedere un rimborso.", + + "zen.api.error.rateLimitExceeded": "Limite di richieste superato. Riprova più tardi.", + "zen.api.error.modelNotSupported": "Modello {{model}} non supportato", + "zen.api.error.modelFormatNotSupported": "Modello {{model}} non supportato per il formato {{format}}", + "zen.api.error.noProviderAvailable": "Nessun provider disponibile", + "zen.api.error.providerNotSupported": "Provider {{provider}} non supportato", + "zen.api.error.missingApiKey": "Chiave API mancante.", + "zen.api.error.invalidApiKey": "Chiave API non valida.", + "zen.api.error.requestBlockedByUpstreamProvider": "Richiesta bloccata dal provider upstream.", + "zen.api.error.subscriptionQuotaExceeded": "Quota dell'abbonamento superata. Riprova tra {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "Limite di utilizzo di 5 ore raggiunto. Si reimposta tra {{retryIn}}. Per continuare a usare questo modello ora, abilita l'utilizzo dal tuo saldo disponibile: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Limite di utilizzo settimanale raggiunto. Si reimposta tra {{retryIn}}. Per continuare a usare questo modello ora, abilita l'utilizzo dal tuo saldo disponibile: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Limite di utilizzo mensile raggiunto. Si reimposta tra {{retryIn}}. Per continuare a usare questo modello ora, abilita l'utilizzo dal tuo saldo disponibile: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Nessun metodo di pagamento. Aggiungi un metodo di pagamento qui: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Saldo insufficiente. Gestisci la tua fatturazione qui: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "La tua area di lavoro ha raggiunto il limite di spesa mensile di ${{amount}}. Gestisci i tuoi limiti qui: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Hai raggiunto il tuo limite di spesa mensile di ${{amount}}. Gestisci i tuoi limiti qui: {{membersUrl}}", + "zen.api.error.modelDisabled": "Il modello è disabilitato", + "zen.api.error.regionNotAllowed": + "La versione più recente di questo modello è disponibile solo con hosting in Cina e richiede un consenso esplicito: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Questo modello non è disponibile nel tuo paese.", + "zen.api.error.trainingNotAllowed": + "Questo modello raccoglie dati utilizzati per migliorarne la qualità e richiede il tuo consenso esplicito: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "La promozione gratuita di {{model}} è terminata. Puoi continuare a usare il modello abbonandoti a OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Accedi ai migliori modelli di coding al mondo", + "black.meta.description": + "Ottieni l'accesso a Claude, GPT, Gemini e altri con i piani di abbonamento OpenCode Black.", + "black.hero.title": "Accedi ai migliori modelli di coding al mondo", + "black.hero.subtitle": "Inclusi Claude, GPT, Gemini e altri", + "black.title": "OpenCode Black | Prezzi", + "black.paused": "L'iscrizione al piano Black è temporaneamente sospesa.", + "black.plan.icon20": "Piano Black 20", + "black.plan.icon100": "Piano Black 100", + "black.plan.icon200": "Piano Black 200", + "black.plan.multiplier100": "5x più utilizzo rispetto a Black 20", + "black.plan.multiplier200": "20x più utilizzo rispetto a Black 20", + "black.price.perMonth": "al mese", + "black.price.perPersonBilledMonthly": "per persona fatturato mensilmente", + "black.terms.1": "Il tuo abbonamento non inizierà immediatamente", + "black.terms.2": "Verrai aggiunto alla lista d'attesa e attivato presto", + "black.terms.3": "La tua carta verrà addebitata solo quando il tuo abbonamento sarà attivato", + "black.terms.4": + "Si applicano limiti di utilizzo, un uso fortemente automatizzato potrebbe raggiungere i limiti prima", + "black.terms.5": "Gli abbonamenti sono per individui, contatta Enterprise per i team", + "black.terms.6": "I limiti potrebbero essere modificati e i piani potrebbero essere interrotti in futuro", + "black.terms.7": "Annulla il tuo abbonamento in qualsiasi momento", + "black.action.continue": "Continua", + "black.finePrint.beforeTerms": "I prezzi mostrati non includono le tasse applicabili", + "black.finePrint.terms": "Termini di servizio", + "black.workspace.title": "OpenCode Black | Seleziona Workspace", + "black.workspace.selectPlan": "Seleziona un workspace per questo piano", + "black.workspace.name": "Workspace {{n}}", + "black.subscribe.title": "Abbonati a OpenCode Black", + "black.subscribe.paymentMethod": "Metodo di pagamento", + "black.subscribe.loadingPaymentForm": "Caricamento modulo di pagamento...", + "black.subscribe.selectWorkspaceToContinue": "Seleziona un workspace per continuare", + "black.subscribe.failurePrefix": "Oh no!", + "black.subscribe.error.generic": "Si è verificato un errore", + "black.subscribe.error.invalidPlan": "Piano non valido", + "black.subscribe.error.workspaceRequired": "ID Workspace richiesto", + "black.subscribe.error.alreadySubscribed": "Questo workspace ha già un abbonamento", + "black.subscribe.processing": "Elaborazione...", + "black.subscribe.submit": "Abbonati ${{plan}}", + "black.subscribe.form.chargeNotice": "Ti verrà addebitato solo quando il tuo abbonamento sarà attivato", + "black.subscribe.success.title": "Sei nella lista d'attesa di OpenCode Black", + "black.subscribe.success.subscriptionPlan": "Piano di abbonamento", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Importo", + "black.subscribe.success.amountValue": "${{plan}} al mese", + "black.subscribe.success.paymentMethod": "Metodo di pagamento", + "black.subscribe.success.dateJoined": "Data di adesione", + "black.subscribe.success.chargeNotice": "La tua carta verrà addebitata quando il tuo abbonamento sarà attivato", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Utilizzo", + "workspace.nav.apiKeys": "Chiavi API", + "workspace.nav.members": "Membri", + "workspace.nav.billing": "Fatturazione", + "workspace.nav.settings": "Impostazioni", + + "workspace.home.banner.beforeLink": "Modelli ottimizzati e affidabili per agenti di coding.", + "workspace.lite.banner.beforeLink": "Modelli di coding a basso costo per tutti.", + "workspace.home.billing.loading": "Caricamento...", + "workspace.home.billing.enable": "Abilita fatturazione", + "workspace.home.billing.currentBalance": "Saldo attuale", + + "workspace.newUser.feature.tested.title": "Modelli testati e verificati", + "workspace.newUser.feature.tested.body": + "Abbiamo benchmarkato e testato modelli specificamente per agenti di coding per garantire le migliori prestazioni.", + "workspace.newUser.feature.quality.title": "Massima qualità", + "workspace.newUser.feature.quality.body": + "Accedi a modelli configurati per prestazioni ottimali - nessun downgrade o instradamento verso provider più economici.", + "workspace.newUser.feature.lockin.title": "Nessun lock-in", + "workspace.newUser.feature.lockin.body": + "Usa Zen con qualsiasi agente di coding, e continua a usare altri provider con opencode quando vuoi.", + "workspace.newUser.copyApiKey": "Copia chiave API", + "workspace.newUser.copyKey": "Copia Chiave", + "workspace.newUser.copied": "Copiato!", + "workspace.newUser.step.enableBilling": "Abilita fatturazione", + "workspace.newUser.step.login.before": "Esegui", + "workspace.newUser.step.login.after": "e seleziona opencode", + "workspace.newUser.step.pasteKey": "Incolla la tua chiave API", + "workspace.newUser.step.models.before": "Avvia opencode ed esegui", + "workspace.newUser.step.models.after": "per selezionare un modello", + + "workspace.models.title": "Modelli", + "workspace.models.subtitle.beforeLink": "Gestisci i modelli a cui possono accedere i membri del workspace.", + "workspace.models.table.model": "Modello", + "workspace.models.table.enabled": "Abilitato", + + "workspace.providers.title": "Bring Your Own Key", + "workspace.providers.subtitle": "Configura le tue chiavi API dai provider di IA.", + "workspace.providers.placeholder": "Inserisci chiave API {{provider}} ({{prefix}}...)", + "workspace.providers.configure": "Configura", + "workspace.providers.edit": "Modifica", + "workspace.providers.delete": "Elimina", + "workspace.providers.saving": "Salvataggio...", + "workspace.providers.save": "Salva", + "workspace.providers.table.provider": "Provider", + "workspace.providers.table.apiKey": "Chiave API", + + "workspace.usage.title": "Cronologia Utilizzo", + "workspace.usage.subtitle": "Utilizzo API recente e costi.", + "workspace.usage.empty": "Effettua la tua prima chiamata API per iniziare.", + "workspace.usage.table.date": "Data", + "workspace.usage.table.model": "Modello", + "workspace.usage.table.input": "Input", + "workspace.usage.table.output": "Output", + "workspace.usage.table.cost": "Costo", + "workspace.usage.table.session": "Sessione", + "workspace.usage.breakdown.input": "Input", + "workspace.usage.breakdown.cacheRead": "Lettura Cache", + "workspace.usage.breakdown.cacheWrite": "Scrittura Cache", + "workspace.usage.breakdown.output": "Output", + "workspace.usage.breakdown.reasoning": "Reasoning", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Costo", + "workspace.cost.subtitle": "Costi di utilizzo suddivisi per modello.", + "workspace.cost.allModels": "Tutti i Modelli", + "workspace.cost.allKeys": "Tutte le Chiavi", + "workspace.cost.deletedSuffix": "(eliminato)", + "workspace.cost.empty": "Nessun dato di utilizzo disponibile per il periodo selezionato.", + "workspace.cost.subscriptionShort": "sub", + + "workspace.keys.title": "Chiavi API", + "workspace.keys.subtitle": "Gestisci le tue chiavi API per accedere ai servizi opencode.", + "workspace.keys.create": "Crea Chiave API", + "workspace.keys.placeholder": "Inserisci nome chiave", + "workspace.keys.empty": "Crea una chiave API opencode Gateway", + "workspace.keys.table.name": "Nome", + "workspace.keys.table.key": "Chiave", + "workspace.keys.table.createdBy": "Creato da", + "workspace.keys.table.lastUsed": "Ultimo Utilizzo", + "workspace.keys.copyApiKey": "Copia chiave API", + "workspace.keys.delete": "Elimina", + + "workspace.members.title": "Membri", + "workspace.members.subtitle": "Gestisci i membri del workspace e le loro autorizzazioni.", + "workspace.members.invite": "Invita Membro", + "workspace.members.inviting": "Invito in corso...", + "workspace.members.beta.beforeLink": "I workspace sono gratuiti per i team durante la beta.", + "workspace.members.form.invitee": "Invitato", + "workspace.members.form.emailPlaceholder": "Inserisci email", + "workspace.members.form.role": "Ruolo", + "workspace.members.form.monthlyLimit": "Limite di spesa mensile", + "workspace.members.noLimit": "Nessun limite", + "workspace.members.noLimitLowercase": "nessun limite", + "workspace.members.invited": "invitato", + "workspace.members.edit": "Modifica", + "workspace.members.delete": "Elimina", + "workspace.members.saving": "Salvataggio...", + "workspace.members.save": "Salva", + "workspace.members.table.email": "Email", + "workspace.members.table.role": "Ruolo", + "workspace.members.table.monthLimit": "Limite mensile", + "workspace.members.role.admin": "Admin", + "workspace.members.role.adminDescription": "Può gestire modelli, membri e fatturazione", + "workspace.members.role.member": "Membro", + "workspace.members.role.memberDescription": "Può generare chiavi API solo per sé", + + "workspace.settings.title": "Impostazioni", + "workspace.settings.subtitle": "Aggiorna il nome e le preferenze del workspace.", + "workspace.settings.workspaceName": "Nome Workspace", + "workspace.settings.defaultName": "Predefinito", + "workspace.settings.updating": "Aggiornamento...", + "workspace.settings.save": "Salva", + "workspace.settings.edit": "Modifica", + + "workspace.billing.title": "Fatturazione", + "workspace.billing.subtitle.beforeLink": "Gestisci i metodi di pagamento.", + "workspace.billing.contactUs": "Contattaci", + "workspace.billing.subtitle.afterLink": "se hai domande.", + "workspace.billing.currentBalance": "Saldo Attuale", + "workspace.billing.add": "Aggiungi $", + "workspace.billing.enterAmount": "Inserisci importo", + "workspace.billing.loading": "Caricamento...", + "workspace.billing.addAction": "Aggiungi", + "workspace.billing.addBalance": "Aggiungi Saldo", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Collegato a Stripe", + "workspace.billing.manage": "Gestisci", + "workspace.billing.enable": "Abilita Fatturazione", + + "workspace.monthlyLimit.title": "Limite Mensile", + "workspace.monthlyLimit.subtitle": "Imposta un limite di utilizzo mensile per il tuo account.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Impostazione...", + "workspace.monthlyLimit.set": "Impostato", + "workspace.monthlyLimit.edit": "Modifica Limite", + "workspace.monthlyLimit.noLimit": "Nessun limite di utilizzo impostato.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Utilizzo attuale per", + "workspace.monthlyLimit.currentUsage.beforeAmount": "è $", + + "workspace.redeem.title": "Riscatta Coupon", + "workspace.redeem.subtitle": "Riscatta un codice coupon per ottenere credito o vantaggi.", + "workspace.redeem.placeholder": "Inserisci il codice coupon", + "workspace.redeem.redeem": "Riscatta", + "workspace.redeem.redeeming": "Riscatto in corso...", + "workspace.redeem.success": "Coupon riscattato con successo.", + + "workspace.reload.title": "Ricarica Auto", + "workspace.reload.disabled.before": "La ricarica auto è", + "workspace.reload.disabled.state": "disabilitata", + "workspace.reload.disabled.after": "Abilita per ricaricare automaticamente quando il saldo è basso.", + "workspace.reload.enabled.before": "La ricarica auto è", + "workspace.reload.enabled.state": "abilitata", + "workspace.reload.enabled.middle": "Ricaricheremo", + "workspace.reload.processingFee": "commissione", + "workspace.reload.enabled.after": "quando il saldo raggiunge", + "workspace.reload.edit": "Modifica", + "workspace.reload.enable": "Abilita", + "workspace.reload.enableAutoReload": "Abilita Ricarica Auto", + "workspace.reload.reloadAmount": "Ricarica $", + "workspace.reload.whenBalanceReaches": "Quando il saldo raggiunge $", + "workspace.reload.saving": "Salvataggio...", + "workspace.reload.save": "Salva", + "workspace.reload.failedAt": "Ricarica fallita il", + "workspace.reload.reason": "Motivo:", + "workspace.reload.updatePaymentMethod": "Aggiorna il tuo metodo di pagamento e riprova.", + "workspace.reload.retrying": "Riprovo...", + "workspace.reload.retry": "Riprova", + "workspace.reload.error.paymentFailed": "Pagamento fallito.", + + "workspace.payments.title": "Cronologia Pagamenti", + "workspace.payments.subtitle": "Transazioni di pagamento recenti.", + "workspace.payments.table.date": "Data", + "workspace.payments.table.paymentId": "ID Pagamento", + "workspace.payments.table.amount": "Importo", + "workspace.payments.table.receipt": "Ricevuta", + "workspace.payments.type.credit": "credito", + "workspace.payments.type.subscription": "abbonamento", + "workspace.payments.view": "Visualizza", + + "workspace.black.loading": "Caricamento...", + "workspace.black.time.day": "giorno", + "workspace.black.time.days": "giorni", + "workspace.black.time.hour": "ora", + "workspace.black.time.hours": "ore", + "workspace.black.time.minute": "minuto", + "workspace.black.time.minutes": "minuti", + "workspace.black.time.fewSeconds": "pochi secondi", + "workspace.black.subscription.title": "Abbonamento", + "workspace.black.subscription.message": "Sei abbonato a OpenCode Black per ${{plan}} al mese.", + "workspace.black.subscription.manage": "Gestisci Abbonamento", + "workspace.black.subscription.rollingUsage": "Utilizzo 5-ore", + "workspace.black.subscription.weeklyUsage": "Utilizzo Settimanale", + "workspace.black.subscription.resetsIn": "Si resetta tra", + "workspace.black.subscription.useBalance": "Usa il tuo saldo disponibile dopo aver raggiunto i limiti di utilizzo", + "workspace.black.waitlist.title": "Waitlist", + "workspace.black.waitlist.joined": "Sei nella waitlist per il piano OpenCode Black da ${{plan}} al mese.", + "workspace.black.waitlist.ready": "Siamo pronti per iscriverti al piano OpenCode Black da ${{plan}} al mese.", + "workspace.black.waitlist.leave": "Lascia Waitlist", + "workspace.black.waitlist.leaving": "Uscita...", + "workspace.black.waitlist.left": "Uscito", + "workspace.black.waitlist.enroll": "Iscriviti", + "workspace.black.waitlist.enrolling": "Iscrizione...", + "workspace.black.waitlist.enrolled": "Iscritto", + "workspace.black.waitlist.enrollNote": + "Quando clicchi su Iscriviti, il tuo abbonamento inizia immediatamente e la tua carta verrà addebitata.", + + "workspace.lite.loading": "Caricamento...", + "workspace.lite.time.day": "giorno", + "workspace.lite.time.days": "giorni", + "workspace.lite.time.hour": "ora", + "workspace.lite.time.hours": "ore", + "workspace.lite.time.minute": "minuto", + "workspace.lite.time.minutes": "minuti", + "workspace.lite.time.fewSeconds": "pochi secondi", + "workspace.lite.subscription.message": "Sei abbonato a OpenCode Go.", + "workspace.lite.subscription.manage": "Gestisci Abbonamento", + "workspace.lite.subscription.rollingUsage": "Utilizzo su 5 ore", + "workspace.lite.subscription.rollingQuota": "Quota su 5 ore", + "workspace.lite.subscription.weeklyUsage": "Utilizzo Settimanale", + "workspace.lite.subscription.weeklyQuota": "Quota Settimanale", + "workspace.lite.subscription.monthlyUsage": "Utilizzo Mensile", + "workspace.lite.subscription.monthlyQuota": "Quota Mensile", + "workspace.lite.subscription.resetsIn": "Si resetta tra", + "workspace.lite.subscription.showDetails": "Mostra dettagli", + "workspace.lite.subscription.hideDetails": "Nascondi dettagli", + "workspace.lite.subscription.model": "Modello", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Totale", + "workspace.lite.subscription.useBalance": "Usa il tuo saldo disponibile dopo aver raggiunto i limiti di utilizzo", + "workspace.lite.subscription.selectProvider": + 'Seleziona "OpenCode Go" come provider nella tua configurazione opencode per utilizzare i modelli Go.', + "workspace.lite.providers.title": "Provider", + "workspace.lite.providers.description": "Controlla quali provider vengono usati per il routing.", + "workspace.lite.providers.allowTraining": "Consenti i modelli che si addestrano sui dati delle richieste", + "workspace.lite.providers.useChina": "Abilita modelli ospitati in Cina", + "workspace.lite.black.message": + "Attualmente sei abbonato a OpenCode Black o sei in lista d'attesa. Annulla l'iscrizione prima se desideri passare a Go.", + "workspace.lite.other.message": + "Un altro membro in questo workspace è già abbonato a OpenCode Go. Solo un membro per workspace può abbonarsi.", + "workspace.lite.promo.description": + "OpenCode Go costa {{price}} e offre un accesso affidabile a popolari modelli di coding aperti con generosi limiti di utilizzo.", + "workspace.lite.promo.price": "$10/mese", + "workspace.lite.promo.modelsTitle": "Cosa è incluso", + "workspace.lite.promo.footer": + "Il piano è pensato principalmente per gli utenti internazionali e offre un accesso globale stabile. I prezzi e i limiti di utilizzo potrebbero cambiare in base a quanto apprenderemo dall'utilizzo iniziale e dai feedback.", + "workspace.lite.promo.subscribe": "Abbonati a Go", + "workspace.lite.promo.subscribing": "Reindirizzamento...", + "workspace.lite.promo.otherMethods": "Altri metodi di pagamento", + "workspace.lite.promo.selectMethod": "Seleziona metodo di pagamento", + + "workspace.referral.copyLink": "Copia link", + "workspace.referral.copied": "Copiato", + "workspace.referral.overview.title": "Invita amici", + "workspace.referral.overview.subtitle": "Guadagna $5 quando un amico si abbona. Anche lui riceverà $5.", + "workspace.referral.instructions.share": "Condividi il tuo link di referral", + "workspace.referral.instructions.subscribe": "Il tuo amico si iscrive e si abbona a Go", + "workspace.referral.instructions.claim": + "Entrambi ricevete un credito di utilizzo di $5 da applicare ai vostri limiti di utilizzo Go", + "workspace.referral.rewards.title": "Premi referral", + "workspace.referral.rewards.description": "Applica i crediti referral disponibili al tuo utilizzo di Go.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} premi utilizzati.", + "workspace.referral.rewards.empty": "Nessun premio referral ancora.", + "workspace.referral.table.reward": "Premio", + "workspace.referral.table.referral": "Descrizione", + "workspace.referral.table.date": "Data", + "workspace.referral.reward.description.inviter": "Hai invitato {{email}}", + "workspace.referral.reward.description.invitee": "Invitato da {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Abbonati per sbloccare", + "workspace.referral.reward.action.view": "Vedi premio", + "workspace.referral.reward.action.applied": "Premio utilizzato", + "workspace.referral.reward.source.pendingInviter": "In attesa che si abboni", + "workspace.referral.reward.source.pendingInvitee": "Abbonati per sbloccare il premio", + "workspace.referral.reward.source.available": "Premio pronto da utilizzare", + "workspace.referral.reward.source.applied": "Premio utilizzato", + "workspace.referral.reward.status.applied": "Premio utilizzato", + "workspace.referral.reward.status.pendingInviter": "Abbonati per sbloccare", + "workspace.referral.reward.status.pendingInvitee": "Abbonati per sbloccare", + "workspace.referral.apply.noGo": "Abbonati per sbloccare", + "workspace.referral.apply.preview": "Vedi premio", + "workspace.referral.apply.action": "Utilizza", + "workspace.referral.apply.confirmTitle": "Utilizza premio", + "workspace.referral.apply.confirmBody": "Utilizza {{amount}} per ridurre l'utilizzo attuale di questo workspace.", + "workspace.referral.apply.confirmAction": "Utilizza", + + "download.title": "OpenCode | Download", + "download.meta.description": "Scarica OpenCode per macOS, Windows e Linux", + "download.hero.title": "Scarica OpenCode Desktop", + "download.hero.subtitle": "Disponibile in Beta per macOS, Windows e Linux", + "download.hero.button": "Scarica per {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "OpenCode Extensions", + "download.section.integrations": "OpenCode Integrations", + "download.action.download": "Scarica", + "download.action.install": "Installa", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Non necessariamente, ma probabilmente. Avrai bisogno di un abbonamento IA se vuoi collegare OpenCode a un provider a pagamento, sebbene tu possa lavorare con", + "download.faq.a3.localLink": "modelli locali", + "download.faq.a3.afterLocal.beforeZen": "gratuitamente. Mentre incoraggiamo gli utenti a usare", + "download.faq.a3.afterZen": ", OpenCode funziona con tutti i provider popolari come OpenAI, Anthropic, xAI ecc.", + + "download.faq.a5.p1": "OpenCode è gratuito al 100%.", + "download.faq.a5.p2.beforeZen": + "Eventuali costi aggiuntivi proverranno dal tuo abbonamento a un provider di modelli. Mentre OpenCode funziona con qualsiasi provider di modelli, raccomandiamo di usare", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": "I tuoi dati e informazioni sono archiviati solo quando crei link condivisibili in OpenCode.", + "download.faq.a6.p2.beforeShare": "Scopri di più sulle", + "download.faq.a6.shareLink": "pagine condivise", + + "enterprise.title": "OpenCode | Soluzioni Enterprise per la tua organizzazione", + "enterprise.meta.description": "Contatta OpenCode per soluzioni enterprise", + "enterprise.hero.title": "Il tuo codice è tuo", + "enterprise.hero.body1": + "OpenCode opera in modo sicuro all'interno della tua organizzazione senza dati o contesto archiviati e senza restrizioni di licenza o rivendicazioni di proprietà. Inizia una prova con il tuo team, poi distribuisci attraverso la tua organizzazione integrandolo con il tuo SSO e gateway IA interno.", + "enterprise.hero.body2": "Facci sapere come possiamo aiutare.", + "enterprise.form.name.label": "Nome completo", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Ruolo", + "enterprise.form.role.placeholder": "Presidente Esecutivo", + "enterprise.form.company.label": "Azienda", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Email aziendale", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Numero di telefono", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Quale problema stai cercando di risolvere?", + "enterprise.form.message.placeholder": "Abbiamo bisogno di aiuto con...", + "enterprise.form.send": "Invia", + "enterprise.form.sending": "Invio...", + "enterprise.form.success": "Messaggio inviato, ti contatteremo presto.", + "enterprise.form.success.submitted": "Modulo inviato con successo.", + "enterprise.form.error.allFieldsRequired": "Tutti i campi sono obbligatori.", + "enterprise.form.error.invalidEmailFormat": "Formato email non valido.", + "enterprise.form.error.internalServer": "Errore interno del server.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "Cos'è OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise è per le organizzazioni che vogliono garantire che il loro codice e dati non lascino mai la loro infrastruttura. Può farlo usando una configurazione centralizzata che si integra con il tuo SSO e gateway IA interno.", + "enterprise.faq.q2": "Come inizio con OpenCode Enterprise?", + "enterprise.faq.a2": + "Inizia semplicemente con una prova interna con il tuo team. OpenCode per impostazione predefinita non archivia il tuo codice o dati di contesto, rendendo facile iniziare. Poi contattaci per discutere prezzi e opzioni di implementazione.", + "enterprise.faq.q3": "Come funziona il prezzo enterprise?", + "enterprise.faq.a3": + "Offriamo prezzi enterprise per postazione. Se hai il tuo gateway LLM, non addebitiamo per i token usati. Per ulteriori dettagli, contattaci per un preventivo personalizzato basato sulle esigenze della tua organizzazione.", + "enterprise.faq.q4": "I miei dati sono sicuri con OpenCode Enterprise?", + "enterprise.faq.a4": + "Sì. OpenCode non archivia il tuo codice o dati di contesto. Tutto il trattamento avviene localmente o attraverso chiamate API dirette al tuo provider IA. Con configurazione centrale e integrazione SSO, i tuoi dati rimangono sicuri all'interno dell'infrastruttura della tua organizzazione.", + + "brand.title": "OpenCode | Brand", + "brand.meta.description": "Linee guida del brand OpenCode", + "brand.heading": "Linee guida del brand", + "brand.subtitle": "Risorse e asset per aiutarti a lavorare con il brand OpenCode.", + "brand.downloadAll": "Scarica tutti gli asset", + + "changelog.title": "OpenCode | Changelog", + "changelog.meta.description": "Note di rilascio e changelog OpenCode", + "changelog.hero.title": "Changelog", + "changelog.hero.subtitle": "Nuovi aggiornamenti e miglioramenti a OpenCode", + "changelog.empty": "Nessuna voce del changelog trovata.", + "changelog.viewJson": "Vedi JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmark", + "bench.list.table.agent": "Agente", + "bench.list.table.model": "Modello", + "bench.list.table.score": "Punteggio", + "bench.submission.error.allFieldsRequired": "Tutti i campi sono obbligatori.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Task non trovato", + "bench.detail.na": "N/D", + "bench.detail.labels.agent": "Agente", + "bench.detail.labels.model": "Modello", + "bench.detail.labels.task": "Task", + "bench.detail.labels.repo": "Repo", + "bench.detail.labels.from": "Da", + "bench.detail.labels.to": "A", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Durata Media", + "bench.detail.labels.averageScore": "Punteggio Medio", + "bench.detail.labels.averageCost": "Costo Medio", + "bench.detail.labels.summary": "Riepilogo", + "bench.detail.labels.runs": "Esecuzioni", + "bench.detail.labels.score": "Punteggio", + "bench.detail.labels.base": "Base", + "bench.detail.labels.penalty": "Penalità", + "bench.detail.labels.weight": "peso", + "bench.detail.table.run": "Esecuzione", + "bench.detail.table.score": "Punteggio (Base - Penalità)", + "bench.detail.table.cost": "Costo", + "bench.detail.table.duration": "Durata", + "bench.detail.run.title": "Esecuzione {{n}}", + "bench.detail.rawJson": "Raw JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/ja.ts b/packages/console/app/src/i18n/ja.ts new file mode 100644 index 0000000000000000000000000000000000000000..2ae754c47d90bcfdfb9cd60046b4d1016d155402 --- /dev/null +++ b/packages/console/app/src/i18n/ja.ts @@ -0,0 +1,875 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flashの利用上限が期間限定で4倍に", + "go.graph.bonus": "利用枠{{count}}倍", + "nav.github": "GitHub", + "nav.docs": "ドキュメント", + "nav.changelog": "変更履歴", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "エンタープライズ", + "nav.zen": "Zen", + "nav.login": "ログイン", + "nav.free": "ダウンロード", + "nav.home": "ホーム", + "nav.openMenu": "メニューを開く", + "nav.getStartedFree": "無料ではじめる", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "ロゴをSVGでコピー", + "nav.context.copyWordmark": "ワードマークをSVGでコピー", + "nav.context.brandAssets": "ブランド素材", + + "footer.github": "GitHub", + "footer.docs": "ドキュメント", + "footer.changelog": "変更履歴", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "ブランド", + "legal.privacy": "プライバシー", + "legal.terms": "利用規約", + + "email.title": "新製品リリースの情報をいち早く受け取る", + "email.subtitle": "早期アクセスのためにウェイトリストに登録してください。", + "email.placeholder": "メールアドレス", + "email.subscribe": "登録", + "email.success": "ほぼ完了です。受信トレイを確認してメールアドレスを認証してください", + + "notFound.title": "見つかりません | OpenCode", + "notFound.heading": "404 - ページが見つかりません", + "notFound.home": "ホーム", + "notFound.docs": "ドキュメント", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencodeのロゴ(ライト)", + "notFound.logoDarkAlt": "opencodeのロゴ(ダーク)", + + "user.logout": "ログアウト", + + "auth.callback.error.codeMissing": "認証コードが見つかりません。", + + "workspace.select": "ワークスペースを選択", + "workspace.createNew": "+ 新しいワークスペースを作成", + "workspace.modal.title": "新しいワークスペースを作成", + "workspace.modal.placeholder": "ワークスペース名を入力", + + "common.cancel": "キャンセル", + "common.creating": "作成中...", + "common.create": "作成", + "common.contactUs": "お問い合わせ", + + "common.videoUnsupported": "お使いのブラウザは video タグをサポートしていません。", + "common.figure": "図 {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "詳しく見る", + + "error.invalidPlan": "無効なプラン", + "error.workspaceRequired": "ワークスペースIDが必要です", + "error.alreadySubscribed": "このワークスペースは既にサブスクリプションを持っています", + "error.limitRequired": "制限値が必要です。", + "error.monthlyLimitInvalid": "有効な月間制限を設定してください。", + "error.workspaceNameRequired": "ワークスペース名が必要です。", + "error.nameTooLong": "名前は255文字以下である必要があります。", + "error.emailRequired": "メールアドレスが必要です", + "error.roleRequired": "ロールが必要です", + "error.idRequired": "IDが必要です", + "error.nameRequired": "名前が必要です", + "error.providerRequired": "プロバイダーが必要です", + "error.apiKeyRequired": "APIキーが必要です", + "error.modelRequired": "モデルが必要です", + "error.reloadAmountMin": "リロード額は少なくとも ${{amount}} である必要があります", + "error.reloadTriggerMin": "残高トリガーは少なくとも ${{amount}} である必要があります", + + "app.meta.description": "OpenCode - オープンソースのコーディングエージェント。", + + "home.title": "OpenCode | オープンソースのAIコーディングエージェント", + + "temp.title": "OpenCode | ターミナル向けに構築されたAIコーディングエージェント", + "temp.hero.title": "ターミナル向けに構築されたAIコーディングエージェント", + "temp.zen": "OpenCode Zen", + "temp.getStarted": "はじめる", + "temp.feature.native.title": "ネイティブ TUI", + "temp.feature.native.body": "レスポンシブでネイティブ、テーマ変更可能なターミナルUI", + "temp.feature.zen.beforeLink": "OpenCodeが提供する", + "temp.feature.zen.link": "厳選されたモデルリスト", + "temp.feature.zen.afterLink": "", + "temp.feature.models.beforeLink": "ローカルモデルを含む、", + "temp.feature.models.afterLink": "を通じて75以上のLLMプロバイダーをサポート", + "temp.screenshot.caption": "tokyonight テーマを使用した OpenCode TUI", + "temp.screenshot.alt": "tokyonight テーマの OpenCode TUI", + "temp.logoLightAlt": "opencodeのロゴ(ライト)", + "temp.logoDarkAlt": "opencodeのロゴ(ダーク)", + + "home.banner.badge": "新着", + "home.banner.text": "デスクトップ版にタブが登場。", + "home.banner.platforms": "macOS、Windows、Linux で利用できます", + "home.banner.downloadNow": "今すぐダウンロード", + "home.banner.downloadBetaNow": "デスクトップベータ版を今すぐダウンロード", + "home.promo.title": "デスクトップ版にタブが登場", + "home.promo.body": "タブで作業とアクティブなセッションを整理できます。", + "home.promo.cta": "始めるには最新版をダウンロードしてください。", + "home.promo.close": "デスクトップアプリのお知らせを閉じる", + + "home.hero.title": "オープンソースのAIコーディングエージェント", + "home.hero.subtitle.a": "無料モデルが含まれています。また、任意のプロバイダーの任意のモデルに接続でき、", + "home.hero.subtitle.b": "Claude、GPT、Gemini などにも対応します。", + + "home.install.ariaLabel": "インストールオプション", + + "home.what.title": "OpenCodeとは?", + "home.what.body": + "OpenCodeは、ターミナル、IDE、またはデスクトップでのコード作成を支援するオープンソースのエージェントです。", + "home.what.lsp.title": "LSP対応", + "home.what.lsp.body": "LLMに適したLSPを自動的に読み込みます", + "home.what.multiSession.title": "マルチセッション", + "home.what.multiSession.body": "同じプロジェクトで複数のエージェントを並行実行できます", + "home.what.shareLinks.title": "共有リンク", + "home.what.shareLinks.body": "参照やデバッグのために、任意のセッションへのリンクを共有できます", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "GitHubでログインしてCopilotアカウントを利用できます", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "OpenAIでログインしてChatGPT PlusまたはProアカウントを利用できます", + "home.what.anyModel.title": "あらゆるモデル", + "home.what.anyModel.body": "Models.dev経由で75以上のLLMプロバイダーに対応(ローカルモデル含む)", + "home.what.anyEditor.title": "あらゆるエディタ", + "home.what.anyEditor.body": "ターミナルインターフェース、デスクトップアプリ、IDE拡張機能として利用できます", + "home.what.readDocs": "ドキュメントを読む", + + "home.growth.title": "オープンソースのAIコーディングエージェント", + "home.growth.body": + "GitHubスター{{stars}}以上、コントリビューター{{contributors}}人、コミット{{commits}}件以上。毎月{{monthlyUsers}}人以上の開発者に利用・信頼されています。", + "home.growth.githubStars": "GitHubスター", + "home.growth.contributors": "コントリビューター", + "home.growth.monthlyDevs": "月間開発者数", + + "home.privacy.title": "プライバシーを最優先に設計", + "home.privacy.body": + "OpenCodeはコードやコンテキストデータを一切保存しないため、プライバシーが重視される環境でも利用できます。", + "home.privacy.learnMore": "詳しくは", + "home.privacy.link": "プライバシー", + + "home.faq.q1": "OpenCodeとは?", + "home.faq.a1": + "OpenCodeは、任意のAIモデルでコードの作成・実行を支援するオープンソースのエージェントです。ターミナルベースのインターフェース、デスクトップアプリ、IDE拡張として利用できます。", + "home.faq.q2": "OpenCodeの使い方は?", + "home.faq.a2.before": "最も簡単な始め方は", + "home.faq.a2.link": "イントロを読む", + "home.faq.q3": "OpenCodeには追加のAIサブスクリプションが必要ですか?", + "home.faq.a3.p1": "必ずしも必要ではありません。OpenCodeには、アカウント不要で使える無料モデルが含まれています。", + "home.faq.a3.p2.beforeZen": "これらに加えて、", + "home.faq.a3.p2.afterZen": " アカウントを作成することで、人気のコーディングモデルを利用できます。", + "home.faq.a3.p3": + "Zenの利用を推奨していますが、OpenCodeはOpenAI、Anthropic、xAIなどの主要プロバイダーにも対応しています。", + "home.faq.a3.p4.beforeLocal": "さらに、", + "home.faq.a3.p4.localLink": "ローカルモデル", + "home.faq.q4": "既存のAIサブスクリプションをOpenCodeで使えますか?", + "home.faq.a4.p1": + "はい、OpenCodeは主要プロバイダーのサブスクリプションプランに対応しています。Claude Pro/Max、ChatGPT Plus/Pro、GitHub Copilotのサブスクリプションを利用できます。", + "home.faq.q5": "ターミナルだけで使えますか?", + "home.faq.a5.beforeDesktop": "もう違います!OpenCodeは今は", + "home.faq.a5.desktop": "デスクトップ", + "home.faq.a5.and": "と", + "home.faq.a5.web": "ウェブ", + "home.faq.q6": "OpenCodeの価格は?", + "home.faq.a6": + "OpenCodeは100%無料で使えます。無料モデルも含まれています。他のプロバイダーに接続する場合は追加費用が発生することがあります。", + "home.faq.q7": "データとプライバシーは?", + "home.faq.a7.p1": "無料モデルを使う場合や共有リンクを作成する場合にのみ、データが保存されます。", + "home.faq.a7.p2.beforeModels": "詳しくは", + "home.faq.a7.p2.modelsLink": "モデルのプライバシー", + "home.faq.a7.p2.and": "と", + "home.faq.a7.p2.shareLink": "共有ページのプライバシー", + "home.faq.q8": "OpenCodeはオープンソースですか?", + "home.faq.a8.p1": "はい、OpenCodeは完全にオープンソースです。ソースコードは", + "home.faq.a8.p2": "の", + "home.faq.a8.mitLicense": "MITライセンス", + "home.faq.a8.p3": + "のもとで公開されており、誰でも使用、変更、開発への参加ができます。コミュニティの誰でもissueを起こしたり、pull requestを送ったり、機能を拡張できます。", + + "home.zenCta.title": "コーディングエージェント向けの信頼できる最適化モデル", + "home.zenCta.body": + "Zenは、OpenCodeがコーディングエージェント向けにテスト・ベンチマーク済みのAIモデルを厳選して提供します。プロバイダー間の性能・品質のブレを気にせず、検証済みのモデルを利用できます。", + "home.zenCta.link": "Zenについて知る", + + "zen.title": "OpenCode Zen | コーディングエージェント向けの信頼できる最適化モデル", + "zen.hero.title": "コーディングエージェント向けの信頼できる最適化モデル", + "zen.hero.body": + "Zenは、OpenCodeがコーディングエージェント向けにテスト・ベンチマーク済みのAIモデルを厳選して提供します。プロバイダー間の性能・品質のブレを気にせず、検証済みのモデルを利用できます。", + + "zen.faq.q1": "OpenCode Zenとは?", + "zen.faq.a1": + "Zenは、OpenCodeのチームが作成した、コーディングエージェント向けにテスト・ベンチマークされたAIモデルの厳選セットです。", + "zen.faq.q2": "Zenはなぜ精度が高いのですか?", + "zen.faq.a2": + "Zenはコーディングエージェント向けにテスト・ベンチマークされたモデルだけを提供します。ステーキを切るのにバターナイフを使わないように、コーディングには品質の低いモデルを使わないでください。", + "zen.faq.q3": "Zenは安いですか?", + "zen.faq.a3": + "Zenは営利目的ではありません。Zenはモデル提供元のコストをそのままあなたに渡します。Zenの利用が増えるほど、OpenCodeはより良いレートを交渉し、その分をあなたに還元できます。", + "zen.faq.q4": "Zenの料金は?", + "zen.faq.a4.p1.beforePricing": "Zenは", + "zen.faq.a4.p1.pricingLink": "リクエスト単位で課金", + "zen.faq.a4.p1.afterPricing": "し、マークアップはありません。つまり、モデル提供元の請求額をそのまま支払います。", + "zen.faq.a4.p2.beforeAccount": "総コストは利用量に依存し、月次の支出上限を", + "zen.faq.a4.p2.accountLink": "アカウント", + "zen.faq.a4.p3": "コストを賄うために、OpenCodeは$20の残高チャージあたり$1.23の小さな決済手数料のみを追加します。", + "zen.faq.q5": "データとプライバシーは?", + "zen.faq.a5.beforeExceptions": + "Zenのモデルはすべて米国でホストされています。プロバイダーはゼロ保持ポリシーを守り、データをモデル学習に使用しません(", + "zen.faq.a5.exceptionsLink": "以下の例外", + "zen.faq.q6": "支出上限を設定できますか?", + "zen.faq.a6": "はい、アカウントで月次の支出上限を設定できます。", + "zen.faq.q7": "キャンセルできますか?", + "zen.faq.a7": "はい、いつでも請求を無効化し、残りの残高を利用できます。", + "zen.faq.q8": "他のコーディングエージェントでもZenを使えますか?", + "zen.faq.a8": + "ZenはOpenCodeとの相性が良いですが、どのエージェントでもZenを利用できます。お使いのコーディングエージェントのセットアップ手順に従ってください。", + "zen.faq.q9": "返金を受けられますか?", + "zen.faq.a9": + "請求から14日以内で、その購入分のクレジットを一切使用していない場合、返金の対象となる可能性があります。返金を希望する場合は、{{contact}}ください。", + + "zen.cta.start": "Zenをはじめる", + "zen.pricing.title": "$20の従量課金制残高を追加", + "zen.pricing.fee": "(+$1.23 カード処理手数料)", + "zen.pricing.body": + "任意のエージェントと一緒に使用できます。毎月の支出制限を設定できます。いつでもキャンセルできます。", + "zen.problem.title": "Zenはどのような問題を解決していますか?", + "zen.problem.body": + "利用可能なモデルは非常に多くありますが、コーディングエージェントで適切に機能するモデルはほんのわずかです。ほとんどのプロバイダーは、それらを異なる設定で提供し、結果も異なります。", + "zen.problem.subtitle": "OpenCodeユーザーだけでなく、すべての人を対象にこの問題を修正しています。", + "zen.problem.item1": "選択したモデルをテストし、チームに相談する", + "zen.problem.item2": "プロバイダーと連携して適切に提供されるようにする", + "zen.problem.item3": "私たちが推奨するすべてのモデルとプロバイダーの組み合わせをベンチマークする", + "zen.how.title": "Zenの仕組み", + "zen.how.body": "ZenをOpenCodeとともに使用することをお勧めしますが、Zenはどのエージェントでも使用できます。", + "zen.how.step1.title": "サインアップして$20の残高を追加", + "zen.how.step1.beforeLink": "", + "zen.how.step1.link": "セットアップ手順", + "zen.how.step2.title": "透明性のある価格設定でZenを使用する", + "zen.how.step2.link": "リクエストごとに支払う", + "zen.how.step2.afterLink": "(マークアップなし)", + "zen.how.step3.title": "自動チャージ", + "zen.how.step3.body": "残高が$5に達すると、自動的に$20が追加されます", + "zen.privacy.title": "あなたのプライバシーは私たちにとって重要です", + "zen.privacy.beforeExceptions": + "すべてのZenモデルは米国でホストされています。プロバイダーはゼロ保持ポリシーに従い、モデルのトレーニングにデータを使用しません(", + "zen.privacy.exceptionsLink": "以下の例外", + + "go.title": "OpenCode Go | すべての人のための低価格なコーディングモデル", + "go.meta.description": + "Goは月額$10で、主要なコーディングモデルへのゆとりある利用上限と安定したアクセスを提供します。", + "go.hero.title": "すべての人のための低価格なコーディングモデル", + "go.hero.body": + "Goは、世界中のプログラマーにエージェント型コーディングをもたらします。最も高性能なオープンソースモデルへの十分な制限と安定したアクセスを提供し、コストや可用性を気にすることなく強力なエージェントで構築できます。", + + "go.cta.start": "Goを購読する", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Goを購読する", + "go.cta.price": "$10/月", + "go.pricing.body": + "どのエージェントでも使えます。月額$10。必要に応じてクレジットを追加。いつでもキャンセルできます。", + "go.graph.free": "無料", + "go.graph.freePill": "Big Pickleと無料モデル", + "go.graph.go": "Go", + "go.graph.label": "5時間あたりのリクエスト数", + "go.graph.period": "利用枠", + "go.graph.model": "モデル", + "go.graph.requests": "推定リクエスト数 / 5時間", + "go.graph.allowance": "月間利用枠", + "go.graph.new": "新着", + "go.graph.scale": "リクエスト数は非線形目盛りで表示", + "go.graph.showAll": "全{{count}}モデルを表示", + "go.graph.showLess": "折りたたむ", + "go.graph.limitedRegions": "一部の地域に限定", + "go.graph.limitedTime": "期間限定", + "go.graph.usageLimits": "利用制限", + "go.graph.aria": "5時間あたりのリクエスト数: {{free}} 対 {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "元CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "は人生を変えるものでした。本当に迷う必要はありません。", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "元創業者, SEED, PM, Melt, Pop, Dapt, Cadmus, ViewPoint", + "go.testimonials.jay.quoteBefore": "チームの5人中4人が", + "go.testimonials.jay.quoteAfter": "の使用を気に入っています。", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "元Hero, AWS", + "go.testimonials.adam.quoteBefore": "私は", + "go.testimonials.adam.quoteAfter": "をどれだけ推薦してもしきれません。真剣に、本当に良いです。", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "元デザイン責任者, Laravel", + "go.testimonials.david.quoteBefore": "", + "go.testimonials.david.quoteAfter": + "を使えば、すべてのモデルがテスト済みでコーディングエージェントに最適だと確信できます。", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "元インターン, Nvidia (4回)", + "go.testimonials.frank.quote": "まだNvidiaにいられたらよかったのに。", + "go.problem.title": "Goはどのような問題を解決していますか?", + "go.problem.body": + "私たちはOpenCodeの体験をできるだけ多くの人に届けることに注力しています。OpenCode Goは月額$10の低価格なサブスクリプションです。ゆとりある上限と、最も高性能なオープンソースモデルへの信頼できるアクセスを提供します。", + "go.problem.subtitle": " ", + "go.problem.item1": "低価格なサブスクリプション料金", + "go.problem.item2": "十分な制限と安定したアクセス", + "go.problem.item3": "できるだけ多くのプログラマーのために構築", + "go.problem.item4": "エージェント型コーディング向けにテストされた厳選モデルラインナップ", + "go.how.title": "Goの仕組み", + "go.how.body": "Goは月額$10です。OpenCodeまたは任意のエージェントで使えます。", + "go.how.step1.title": "アカウントを作成", + "go.how.step1.beforeLink": "", + "go.how.step1.link": "セットアップ手順はこちら", + "go.how.step2.title": "Goを購読する", + "go.how.step2.link": "月額$10", + "go.how.step2.afterLink": "ゆとりある上限付き", + "go.how.step3.title": "コーディングを開始", + "go.how.step3.body": "オープンソースモデルへの安定したアクセスで", + "go.privacy.title": "あなたのプライバシーは私たちにとって重要です", + "go.privacy.body": + "このプランは主に海外ユーザー向けに設計されており、米国、EU、シンガポールでホストされたモデルにより安定したグローバルアクセスを提供します。", + "go.privacy.contactAfter": "ご質問がございましたら。", + "go.privacy.beforeExceptions": + "Goのモデルは米国でホストされています。プロバイダーはゼロ保持ポリシーに従い、モデルのトレーニングにデータを使用しません(", + "go.privacy.exceptionsLink": "以下の例外", + "go.faq.q1": "OpenCode Goとは?", + "go.faq.a1": + "Goは、エージェント型コーディングのための有能なオープンソースモデルへの安定したアクセスを提供する低価格なサブスクリプションです。", + "go.faq.q2": "Goにはどのモデルが含まれますか?", + "go.faq.a2": "Go には、十分な利用上限と安定したアクセスを備えた、以下のモデルが含まれます。", + "go.faq.q3": "GoはZenと同じですか?", + "go.faq.a3": + "いいえ。Zenは従量課金制ですが、Goは月額$10で、厳選されたモデルラインナップへのゆとりある上限と安定したアクセスを提供します。", + "go.faq.q4": "Goの料金は?", + "go.faq.a4.p1.beforePricing": "Goは", + "go.faq.a4.p1.pricingLink": "月額$10", + "go.faq.a4.p1.afterPricing": "ゆとりある上限付き。", + "go.faq.a4.p2.beforeAccount": "管理画面:", + "go.faq.a4.p2.accountLink": "アカウント", + "go.faq.a4.p3": "いつでもキャンセル可能です。", + "go.faq.q5": "データとプライバシーは?", + "go.faq.a5.model": "モデル", + "go.faq.a5.training": "モデルのトレーニング", + "go.faq.a5.retention": "データ保持", + "go.faq.a5.retention30": "30日", + "go.faq.a5.retention0": "0日", + "go.faq.a5.used": "使用あり", + "go.faq.a5.notUsed": "使用なし", + "go.faq.a5.noAgreement": "契約なし", + "go.faq.a5.notZdr": "ZDRではない", + "go.faq.a5.grokRetention": + "ZDRでは、保存データに依存する重要なAPI機能(ステートフルなResponses API、Files and Collections、Batch APIなど)が無効になります。", + "go.faq.a5.gptRetention": "不正使用監視ログはすべてのAPI機能の使用時に生成され、最大30日間保持されます。", + "go.faq.a5.museRetention": + "将来のMetaモデルのトレーニングにプロンプトと生成結果を使用する許可と引き換えに、トークン料金が大幅に割引されます。", + "go.faq.a5.learnMore": "詳しく見る", + "go.faq.a5.deepseekRetention": "ZDR契約は毎月更新されます。現在の契約は2026年9月30日まで有効です。", + "go.faq.a5.beforeExceptions": + "Goのモデルは米国でホストされています。プロバイダーはゼロ保持ポリシーに従い、モデルのトレーニングにデータを使用しません(", + "go.faq.a5.exceptionsLink": "以下の例外", + "go.faq.q6": "クレジットをチャージできますか?", + "go.faq.a6": "利用枠を追加したい場合は、アカウントでクレジットをチャージできます。", + "go.faq.q7": "キャンセルできますか?", + "go.faq.a7": "はい、いつでもキャンセル可能です。", + "go.faq.q8": "他のコーディングエージェントでGoを使えますか?", + "go.faq.a8": + "はい、Goは任意のエージェントで使用できます。お使いのコーディングエージェントのセットアップ手順に従ってください。", + + "go.faq.q9": "無料モデルとGoの違いは何ですか?", + "go.faq.a9": + "無料モデルにはBig Pickleと、その時点で利用可能なプロモーションモデルが含まれ、1日200リクエストの制限があります。Goでは厳選されたモデルラインナップを利用でき、ローリングウィンドウ(5時間、週間、月間)全体でより高いリクエスト制限が適用されます。基本利用枠では概算で5時間あたり$12、週間$30、月間$60相当ですが、モデル別の利用枠は異なる場合があります(実際のリクエスト数はモデルと使用状況により異なります)。", + "go.faq.q10": "返金を受けられますか?", + "go.faq.a10": + "請求から14日以内で、その請求期間中にGoの利用枠を一切使用していない場合、返金の対象となる可能性があります。返金を希望する場合は、{{contact}}ください。", + + "zen.api.error.rateLimitExceeded": "レート制限を超えました。後でもう一度お試しください。", + "zen.api.error.modelNotSupported": "モデル {{model}} はサポートされていません", + "zen.api.error.modelFormatNotSupported": "フォーマット {{format}} ではモデル {{model}} はサポートされていません", + "zen.api.error.noProviderAvailable": "利用可能なプロバイダーがありません", + "zen.api.error.providerNotSupported": "プロバイダー {{provider}} はサポートされていません", + "zen.api.error.missingApiKey": "APIキーがありません。", + "zen.api.error.invalidApiKey": "無効なAPIキーです。", + "zen.api.error.requestBlockedByUpstreamProvider": "上流プロバイダーによりリクエストがブロックされました。", + "zen.api.error.subscriptionQuotaExceeded": + "サブスクリプションの制限を超えました。{{retryIn}} 後に再試行してください。", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "5時間の利用上限に達しました。{{retryIn}} 後にリセットされます。今すぐこのモデルの利用を続けるには、利用可能な残高からの利用を有効化してください: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "週間の利用上限に達しました。{{retryIn}} 後にリセットされます。今すぐこのモデルの利用を続けるには、利用可能な残高からの利用を有効化してください: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "月間の利用上限に達しました。{{retryIn}} 後にリセットされます。今すぐこのモデルの利用を続けるには、利用可能な残高からの利用を有効化してください: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "お支払い方法がありません。こちらからお支払い方法を追加してください: {{billingUrl}}", + "zen.api.error.insufficientBalance": "残高が不足しています。こちらから請求を管理してください: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "ワークスペースが月額の利用上限 ${{amount}} に達しました。こちらから上限を管理してください: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "月額の利用上限 ${{amount}} に達しました。こちらから上限を管理してください: {{membersUrl}}", + "zen.api.error.modelDisabled": "モデルが無効です", + "zen.api.error.regionNotAllowed": + "このモデルの最新バージョンは中国でのみホスト提供されており、利用するには明示的なオプトインが必要です: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "このモデルはお住まいの国では利用できません。", + "zen.api.error.trainingNotAllowed": + "このモデルは品質向上のためのデータを収集します。利用するには明示的な同意が必要です: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "{{model}} の無料プロモーションは終了しました。OpenCode Go を購読するとモデルを引き続き使用できます - {{link}}", + + "black.meta.title": "OpenCode Black | 世界最高峰のコーディングモデルすべてにアクセス", + "black.meta.description": "OpenCode Black サブスクリプションプランで、Claude、GPT、Gemini などにアクセス。", + "black.hero.title": "世界最高峰のコーディングモデルすべてにアクセス", + "black.hero.subtitle": "Claude、GPT、Gemini などを含む", + "black.title": "OpenCode Black | 料金", + "black.paused": "Blackプランの登録は一時的に停止しています。", + "black.plan.icon20": "Black 20 プラン", + "black.plan.icon100": "Black 100 プラン", + "black.plan.icon200": "Black 200 プラン", + "black.plan.multiplier100": "Black 20 の5倍の利用量", + "black.plan.multiplier200": "Black 20 の20倍の利用量", + "black.price.perMonth": "/月", + "black.price.perPersonBilledMonthly": "1人あたり / 月額請求", + "black.terms.1": "サブスクリプションはすぐには開始されません", + "black.terms.2": "ウェイトリストに追加され、まもなく有効化されます", + "black.terms.3": "サブスクリプションが有効化された時点でのみカードに請求されます", + "black.terms.4": "利用制限が適用されます。過度な自動化利用は早く制限に達する可能性があります", + "black.terms.5": "サブスクリプションは個人向けです。チーム利用はエンタープライズにお問い合わせください", + "black.terms.6": "将来的に制限が調整されたり、プランが廃止される可能性があります", + "black.terms.7": "サブスクリプションはいつでもキャンセル可能です", + "black.action.continue": "続ける", + "black.finePrint.beforeTerms": "表示価格には適用される税金は含まれていません", + "black.finePrint.terms": "利用規約", + "black.workspace.title": "OpenCode Black | ワークスペースの選択", + "black.workspace.selectPlan": "このプランのワークスペースを選択してください", + "black.workspace.name": "ワークスペース {{n}}", + "black.subscribe.title": "OpenCode Black を購読する", + "black.subscribe.paymentMethod": "支払い方法", + "black.subscribe.loadingPaymentForm": "支払いフォームを読み込み中...", + "black.subscribe.selectWorkspaceToContinue": "続けるにはワークスペースを選択してください", + "black.subscribe.failurePrefix": "おっと!", + "black.subscribe.error.generic": "エラーが発生しました", + "black.subscribe.error.invalidPlan": "無効なプランです", + "black.subscribe.error.workspaceRequired": "ワークスペースIDが必要です", + "black.subscribe.error.alreadySubscribed": "このワークスペースは既にサブスクリプションを持っています", + "black.subscribe.processing": "処理中...", + "black.subscribe.submit": "購読する ${{plan}}", + "black.subscribe.form.chargeNotice": "サブスクリプションが有効化された時点でのみ請求されます", + "black.subscribe.success.title": "OpenCode Black ウェイトリストに登録されました", + "black.subscribe.success.subscriptionPlan": "サブスクリプションプラン", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "金額", + "black.subscribe.success.amountValue": "${{plan}} / 月", + "black.subscribe.success.paymentMethod": "支払い方法", + "black.subscribe.success.dateJoined": "登録日", + "black.subscribe.success.chargeNotice": "サブスクリプションが有効化された時点でカードに請求されます", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "利用", + "workspace.nav.apiKeys": "APIキー", + "workspace.nav.members": "メンバー", + "workspace.nav.billing": "請求", + "workspace.nav.settings": "設定", + + "workspace.home.banner.beforeLink": "コーディングエージェント向けに信頼性の高い最適化されたモデル。", + "workspace.lite.banner.beforeLink": "誰でも使える低コストコーディングモデル。", + "workspace.home.billing.loading": "読み込み中...", + "workspace.home.billing.enable": "課金を有効にする", + "workspace.home.billing.currentBalance": "現在の残高", + + "workspace.newUser.feature.tested.title": "テスト・検証済みモデル", + "workspace.newUser.feature.tested.body": + "最高のパフォーマンスを保証するために、コーディングエージェントに特化したモデルのベンチマークとテストを行いました。", + "workspace.newUser.feature.quality.title": "最高品質", + "workspace.newUser.feature.quality.body": + "最適なパフォーマンスを実現するように構成されたモデルにアクセスします。ダウングレードや安価なプロバイダーへのルーティングはありません。", + "workspace.newUser.feature.lockin.title": "ロックインなし", + "workspace.newUser.feature.lockin.body": + "任意のコーディングエージェントでZenを使用でき、必要に応じていつでもOpenCodeを備えた他のプロバイダーを使用し続けることができます。", + "workspace.newUser.copyApiKey": "APIキーをコピー", + "workspace.newUser.copyKey": "キーをコピー", + "workspace.newUser.copied": "コピーしました!", + "workspace.newUser.step.enableBilling": "課金を有効にする", + "workspace.newUser.step.login.before": "実行", + "workspace.newUser.step.login.after": "してOpenCodeを選択", + "workspace.newUser.step.pasteKey": "APIキーを貼り付け", + "workspace.newUser.step.models.before": "OpenCodeを起動し実行", + "workspace.newUser.step.models.after": "してモデルを選択", + + "workspace.models.title": "モデル", + "workspace.models.subtitle.beforeLink": "ワークスペースのメンバーがアクセスできるモデルを管理します。", + "workspace.models.table.model": "モデル", + "workspace.models.table.enabled": "有効", + + "workspace.providers.title": "APIキーの設定", + "workspace.providers.subtitle": "AIプロバイダーの独自のAPIキーを設定します。", + "workspace.providers.placeholder": "{{provider}} APIキーを入力 ({{prefix}}...)", + "workspace.providers.configure": "設定", + "workspace.providers.edit": "編集", + "workspace.providers.delete": "削除", + "workspace.providers.saving": "保存中...", + "workspace.providers.save": "保存", + "workspace.providers.table.provider": "プロバイダー", + "workspace.providers.table.apiKey": "APIキー", + + "workspace.usage.title": "利用履歴", + "workspace.usage.subtitle": "最近のAPIの使用状況とコスト。", + "workspace.usage.empty": "開始するには、最初のAPI呼び出しを行ってください。", + "workspace.usage.table.date": "日付", + "workspace.usage.table.model": "モデル", + "workspace.usage.table.input": "入力", + "workspace.usage.table.output": "出力", + "workspace.usage.table.cost": "コスト", + "workspace.usage.table.session": "セッション", + "workspace.usage.breakdown.input": "入力", + "workspace.usage.breakdown.cacheRead": "キャッシュ読み取り", + "workspace.usage.breakdown.cacheWrite": "キャッシュ書き込み", + "workspace.usage.breakdown.output": "出力", + "workspace.usage.breakdown.reasoning": "推論", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "コスト", + "workspace.cost.subtitle": "モデルごとの使用料金の内訳。", + "workspace.cost.allModels": "全モデル", + "workspace.cost.allKeys": "すべてのキー", + "workspace.cost.deletedSuffix": "(削除済み)", + "workspace.cost.empty": "選択した期間の使用状況データはありません。", + "workspace.cost.subscriptionShort": "サブ", + + "workspace.keys.title": "APIキー", + "workspace.keys.subtitle": "OpenCodeサービスにアクセスするためのAPIキーを管理します。", + "workspace.keys.create": "APIキーの作成", + "workspace.keys.placeholder": "キー名を入力してください", + "workspace.keys.empty": "OpenCodeゲートウェイAPIキーを作成する", + "workspace.keys.table.name": "名前", + "workspace.keys.table.key": "キー", + "workspace.keys.table.createdBy": "作成者", + "workspace.keys.table.lastUsed": "最終利用", + "workspace.keys.copyApiKey": "APIキーをコピー", + "workspace.keys.delete": "削除", + + "workspace.members.title": "メンバー", + "workspace.members.subtitle": "ワークスペースのメンバーとその権限を管理します。", + "workspace.members.invite": "メンバーを招待", + "workspace.members.inviting": "招待中...", + "workspace.members.beta.beforeLink": "ベータ期間中、チームはワークスペースを無料で利用できます。", + "workspace.members.form.invitee": "招待する人", + "workspace.members.form.emailPlaceholder": "メールアドレスを入力", + "workspace.members.form.role": "ロール", + "workspace.members.form.monthlyLimit": "月間支出上限", + "workspace.members.noLimit": "制限なし", + "workspace.members.noLimitLowercase": "制限なし", + "workspace.members.invited": "招待済み", + "workspace.members.edit": "編集", + "workspace.members.delete": "削除", + "workspace.members.saving": "保存中...", + "workspace.members.save": "保存", + "workspace.members.table.email": "メールアドレス", + "workspace.members.table.role": "ロール", + "workspace.members.table.monthLimit": "月間上限", + "workspace.members.role.admin": "管理者", + "workspace.members.role.adminDescription": "モデル、メンバー、請求を管理できます", + "workspace.members.role.member": "メンバー", + "workspace.members.role.memberDescription": "自分自身のAPIキーのみを生成できます", + + "workspace.settings.title": "設定", + "workspace.settings.subtitle": "ワークスペース名と設定を更新します。", + "workspace.settings.workspaceName": "ワークスペース名", + "workspace.settings.defaultName": "デフォルト", + "workspace.settings.updating": "更新中...", + "workspace.settings.save": "保存", + "workspace.settings.edit": "編集", + + "workspace.billing.title": "請求", + "workspace.billing.subtitle.beforeLink": "支払い方法を管理します。", + "workspace.billing.contactUs": "お問い合わせ", + "workspace.billing.subtitle.afterLink": "ご質問がございましたら。", + "workspace.billing.currentBalance": "現在の残高", + "workspace.billing.add": "$を追加", + "workspace.billing.enterAmount": "金額を入力", + "workspace.billing.loading": "読み込み中...", + "workspace.billing.addAction": "追加", + "workspace.billing.addBalance": "残高を追加", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Stripeと連携済み", + "workspace.billing.manage": "管理", + "workspace.billing.enable": "課金を有効にする", + + "workspace.monthlyLimit.title": "月間上限", + "workspace.monthlyLimit.subtitle": "アカウントの月間使用制限を設定します。", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "設定中...", + "workspace.monthlyLimit.set": "設定", + "workspace.monthlyLimit.edit": "上限を編集", + "workspace.monthlyLimit.noLimit": "使用制限は設定されていません。", + "workspace.monthlyLimit.currentUsage.beforeMonth": "現在の使用状況(", + "workspace.monthlyLimit.currentUsage.beforeAmount": ")は $", + + "workspace.redeem.title": "クーポンを利用", + "workspace.redeem.subtitle": "クーポンコードを利用して、クレジットや特典を受け取ります。", + "workspace.redeem.placeholder": "クーポンコードを入力", + "workspace.redeem.redeem": "利用する", + "workspace.redeem.redeeming": "利用中...", + "workspace.redeem.success": "クーポンを利用しました。", + + "workspace.reload.title": "自動チャージ", + "workspace.reload.disabled.before": "自動チャージは", + "workspace.reload.disabled.state": "無効", + "workspace.reload.disabled.after": "です。残高が少なくなったときに自動的にチャージするには有効にしてください。", + "workspace.reload.enabled.before": "自動チャージは", + "workspace.reload.enabled.state": "有効", + "workspace.reload.enabled.middle": "チャージします(", + "workspace.reload.processingFee": "手数料", + "workspace.reload.enabled.after": ")。残高が以下に達したとき:", + "workspace.reload.edit": "編集", + "workspace.reload.enable": "有効にする", + "workspace.reload.enableAutoReload": "自動チャージを有効にする", + "workspace.reload.reloadAmount": "チャージ額 $", + "workspace.reload.whenBalanceReaches": "残高が $ に達したとき", + "workspace.reload.saving": "保存中...", + "workspace.reload.save": "保存", + "workspace.reload.failedAt": "チャージ失敗:", + "workspace.reload.reason": "理由:", + "workspace.reload.updatePaymentMethod": "支払い方法を更新して、もう一度お試しください。", + "workspace.reload.retrying": "再試行中...", + "workspace.reload.retry": "再試行", + "workspace.reload.error.paymentFailed": "支払いに失敗しました。", + + "workspace.payments.title": "支払い履歴", + "workspace.payments.subtitle": "最近の支払い取引。", + "workspace.payments.table.date": "日付", + "workspace.payments.table.paymentId": "支払いID", + "workspace.payments.table.amount": "金額", + "workspace.payments.table.receipt": "領収書", + "workspace.payments.type.credit": "クレジット", + "workspace.payments.type.subscription": "サブスクリプション", + "workspace.payments.view": "表示", + + "workspace.black.loading": "読み込み中...", + "workspace.black.time.day": "日", + "workspace.black.time.days": "日", + "workspace.black.time.hour": "時間", + "workspace.black.time.hours": "時間", + "workspace.black.time.minute": "分", + "workspace.black.time.minutes": "分", + "workspace.black.time.fewSeconds": "数秒", + "workspace.black.subscription.title": "サブスクリプション", + "workspace.black.subscription.message": "あなたは OpenCode Black を月額 ${{plan}} で購読しています。", + "workspace.black.subscription.manage": "サブスクリプションの管理", + "workspace.black.subscription.rollingUsage": "5時間利用", + "workspace.black.subscription.weeklyUsage": "週間利用量", + "workspace.black.subscription.resetsIn": "リセットまで", + "workspace.black.subscription.useBalance": "利用限度額に達したら利用可能な残高を使用する", + "workspace.black.waitlist.title": "ウェイトリスト", + "workspace.black.waitlist.joined": + "あなたは月額 ${{plan}} の OpenCode Black プランのウェイトリストに登録されています。", + "workspace.black.waitlist.ready": "月額 ${{plan}} の OpenCode Black プランに登録する準備ができました。", + "workspace.black.waitlist.leave": "ウェイトリストから抜ける", + "workspace.black.waitlist.leaving": "処理中...", + "workspace.black.waitlist.left": "退会済み", + "workspace.black.waitlist.enroll": "登録する", + "workspace.black.waitlist.enrolling": "登録中...", + "workspace.black.waitlist.enrolled": "登録済み", + "workspace.black.waitlist.enrollNote": + "「登録する」をクリックすると、サブスクリプションがすぐに開始され、カードに請求されます。", + + "workspace.lite.loading": "読み込み中...", + "workspace.lite.time.day": "日", + "workspace.lite.time.days": "日", + "workspace.lite.time.hour": "時間", + "workspace.lite.time.hours": "時間", + "workspace.lite.time.minute": "分", + "workspace.lite.time.minutes": "分", + "workspace.lite.time.fewSeconds": "数秒", + "workspace.lite.subscription.message": "あなたは OpenCode Go を購読しています。", + "workspace.lite.subscription.manage": "サブスクリプションの管理", + "workspace.lite.subscription.rollingUsage": "5時間利用量", + "workspace.lite.subscription.rollingQuota": "5時間上限", + "workspace.lite.subscription.weeklyUsage": "週間利用量", + "workspace.lite.subscription.weeklyQuota": "週間上限", + "workspace.lite.subscription.monthlyUsage": "月間利用量", + "workspace.lite.subscription.monthlyQuota": "月間上限", + "workspace.lite.subscription.resetsIn": "リセットまで", + "workspace.lite.subscription.showDetails": "詳細を表示", + "workspace.lite.subscription.hideDetails": "詳細を非表示", + "workspace.lite.subscription.model": "モデル", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "合計", + "workspace.lite.subscription.useBalance": "利用限度額に達したら利用可能な残高を使用する", + "workspace.lite.subscription.selectProvider": + "Go モデルを使用するには、opencode の設定で「OpenCode Go」をプロバイダーとして選択してください。", + "workspace.lite.providers.title": "プロバイダー", + "workspace.lite.providers.description": "ルーティングに使用するプロバイダーを管理します。", + "workspace.lite.providers.allowTraining": "リクエストデータを学習に使用するモデルを許可", + "workspace.lite.providers.useChina": "中国でホストされているモデルを有効にする", + "workspace.lite.black.message": + "現在 OpenCode Black を購読中、またはウェイティングリストに登録されています。Go に切り替える場合は、先に登録を解除してください。", + "workspace.lite.other.message": + "このワークスペースの別のメンバーが既に OpenCode Go を購読しています。ワークスペースにつき1人のメンバーのみが購読できます。", + "workspace.lite.promo.description": + "OpenCode Goは{{price}}で、人気の高いオープンコーディングモデルへの安定したアクセスと余裕のある利用枠を提供します。", + "workspace.lite.promo.price": "$10/月", + "workspace.lite.promo.modelsTitle": "含まれるもの", + "workspace.lite.promo.footer": + "このプランは主に海外のユーザー向けに設計されており、世界中から安定してご利用いただけます。料金と利用上限は、初期の利用状況やフィードバックを踏まえて変更される場合があります。", + "workspace.lite.promo.subscribe": "Goを購読する", + "workspace.lite.promo.subscribing": "リダイレクト中...", + "workspace.lite.promo.otherMethods": "その他の支払い方法", + "workspace.lite.promo.selectMethod": "支払い方法を選択", + + "workspace.referral.copyLink": "リンクをコピー", + "workspace.referral.copied": "コピーしました", + "workspace.referral.overview.title": "友達を招待", + "workspace.referral.overview.subtitle": "友達がサブスクライブすると $5 を獲得。友達にも $5 が付与されます。", + "workspace.referral.instructions.share": "リファラルリンクをシェア", + "workspace.referral.instructions.subscribe": "友達が参加して Go にサブスクライブ", + "workspace.referral.instructions.claim": "二人とも $5 の利用クレジットを獲得し、Go の利用上限に充当できます", + "workspace.referral.rewards.title": "リファラル特典", + "workspace.referral.rewards.description": "利用可能なリファラルクレジットを Go の利用に適用します。", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} 件の特典を適用済み。", + "workspace.referral.rewards.empty": "リファラル特典はまだありません。", + "workspace.referral.table.reward": "特典", + "workspace.referral.table.referral": "説明", + "workspace.referral.table.date": "日付", + "workspace.referral.reward.description.inviter": "{{email}} を招待しました", + "workspace.referral.reward.description.invitee": "{{email}} に招待されました", + "workspace.referral.reward.action.subscribeUnlock": "サブスクライブしてアンロック", + "workspace.referral.reward.action.view": "特典を表示", + "workspace.referral.reward.action.applied": "特典を適用済み", + "workspace.referral.reward.source.pendingInviter": "友達のサブスクライブ待ち", + "workspace.referral.reward.source.pendingInvitee": "サブスクライブして特典をアンロック", + "workspace.referral.reward.source.available": "特典は適用可能です", + "workspace.referral.reward.source.applied": "特典を適用済み", + "workspace.referral.reward.status.applied": "特典を適用済み", + "workspace.referral.reward.status.pendingInviter": "サブスクライブしてアンロック", + "workspace.referral.reward.status.pendingInvitee": "サブスクライブしてアンロック", + "workspace.referral.apply.noGo": "サブスクライブしてアンロック", + "workspace.referral.apply.preview": "特典を表示", + "workspace.referral.apply.action": "適用", + "workspace.referral.apply.confirmTitle": "特典を適用", + "workspace.referral.apply.confirmBody": "{{amount}} を適用して、このワークスペースの現在の使用量を減らします。", + "workspace.referral.apply.confirmAction": "適用", + + "download.title": "OpenCode | ダウンロード", + "download.meta.description": "OpenCode を macOS、Windows、Linux 向けにダウンロード", + "download.hero.title": "OpenCode デスクトップ版をダウンロード", + "download.hero.subtitle": "macOS、Windows、Linux 向けベータ版を利用可能", + "download.hero.button": "{{os}} 向けダウンロード", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "OpenCode Extensions", + "download.section.integrations": "OpenCode Integrations", + "download.action.download": "ダウンロード", + "download.action.install": "インストール", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "必ずしもそうではありませんが、おそらく必要です。OpenCodeを有料プロバイダーに接続したい場合はAIサブスクリプションが必要ですが、", + "download.faq.a3.localLink": "ローカルモデル", + "download.faq.a3.afterLocal.beforeZen": "であれば無料で利用できます。ユーザーには", + "download.faq.a3.afterZen": + "の利用をお勧めしていますが、OpenCodeはOpenAI、Anthropic、xAIなどの主要なプロバイダーに対応しています。", + + "download.faq.a5.p1": "OpenCodeは100%無料で利用できます。", + "download.faq.a5.p2.beforeZen": + "追加コストはモデルプロバイダーのサブスクリプションから発生します。OpenCodeはどのモデルプロバイダーでも利用できますが、", + "download.faq.a5.p2.afterZen": "の利用をおすすめします。", + + "download.faq.a6.p1": "あなたのデータと情報は、OpenCodeで共有リンクを作成したときにのみ保存されます。", + "download.faq.a6.p2.beforeShare": "詳しくは", + "download.faq.a6.shareLink": "共有ページ", + + "enterprise.title": "OpenCode | 組織向けエンタープライズソリューション", + "enterprise.meta.description": "エンタープライズソリューションについてOpenCodeに問い合わせる", + "enterprise.hero.title": "あなたのコードはあなたのもの", + "enterprise.hero.body1": + "OpenCodeは、データやコンテキストを一切保存せず、ライセンス制限や所有権の主張もなく、組織内で安全に動作します。チームでのトライアルから始め、SSOや社内AIゲートウェイと統合して組織全体に展開できます。", + "enterprise.hero.body2": "どのような支援ができるか、お聞かせください。", + "enterprise.form.name.label": "氏名", + "enterprise.form.name.placeholder": "ジェフ・ベゾス", + "enterprise.form.role.label": "役職", + "enterprise.form.role.placeholder": "会長", + "enterprise.form.company.label": "会社名", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "会社メールアドレス", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "電話番号", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "どのような課題を解決したいですか?", + "enterprise.form.message.placeholder": "これについて支援が必要です...", + "enterprise.form.send": "送信", + "enterprise.form.sending": "送信中...", + "enterprise.form.success": "送信しました。まもなくご連絡いたします。", + "enterprise.form.success.submitted": "フォームが正常に送信されました。", + "enterprise.form.error.allFieldsRequired": "すべての項目は必須です。", + "enterprise.form.error.invalidEmailFormat": "無効なメール形式です。", + "enterprise.form.error.internalServer": "内部サーバーエラー。", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "OpenCode Enterpriseとは?", + "enterprise.faq.a1": + "OpenCode Enterpriseは、コードとデータが決してインフラの外に出ないことを保証したい組織向けです。SSOや社内AIゲートウェイと統合する集中設定を使用することでこれを実現します。", + "enterprise.faq.q2": "OpenCode Enterpriseを始めるには?", + "enterprise.faq.a2": + "まずはチームでの社内トライアルから始めてください。OpenCodeはデフォルトでコードやコンテキストデータを保存しないため、簡単に始められます。その後、価格や導入オプションについてお問い合わせください。", + "enterprise.faq.q3": "エンタープライズ価格の仕組みは?", + "enterprise.faq.a3": + "シート単位(ユーザー数)でのエンタープライズ価格を提供します。独自のLLMゲートウェイをお持ちの場合、使用トークンに対する課金はありません。詳細は、組織の要件に基づいた見積もりのためにお問い合わせください。", + "enterprise.faq.q4": "OpenCode Enterpriseでデータは安全ですか?", + "enterprise.faq.a4": + "はい。OpenCodeはコードやコンテキストデータを保存しません。すべての処理はローカル、またはAIプロバイダーへの直接API呼び出しを通じて行われます。集中設定とSSO統合により、データは組織のインフラ内で安全に保たれます。", + + "brand.title": "OpenCode | ブランド", + "brand.meta.description": "OpenCode ブランドガイドライン", + "brand.heading": "ブランドガイドライン", + "brand.subtitle": "OpenCodeブランドを扱うためのリソースと素材です。", + "brand.downloadAll": "すべての素材をダウンロード", + + "changelog.title": "OpenCode | 変更履歴", + "changelog.meta.description": "OpenCode リリースノートと変更履歴", + "changelog.hero.title": "変更履歴", + "changelog.hero.subtitle": "OpenCodeの新しいアップデートと改善", + "changelog.empty": "変更履歴が見つかりませんでした。", + "changelog.viewJson": "JSONを表示", + + "bench.list.title": "ベンチマーク", + "bench.list.heading": "ベンチマーク", + "bench.list.table.agent": "エージェント", + "bench.list.table.model": "モデル", + "bench.list.table.score": "スコア", + "bench.submission.error.allFieldsRequired": "すべての項目は必須です。", + + "bench.detail.title": "ベンチマーク - {{task}}", + "bench.detail.notFound": "タスクが見つかりません", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "エージェント", + "bench.detail.labels.model": "モデル", + "bench.detail.labels.task": "タスク", + "bench.detail.labels.repo": "リポジトリ", + "bench.detail.labels.from": "From", + "bench.detail.labels.to": "To", + "bench.detail.labels.prompt": "プロンプト", + "bench.detail.labels.commit": "コミット", + "bench.detail.labels.averageDuration": "平均所要時間", + "bench.detail.labels.averageScore": "平均スコア", + "bench.detail.labels.averageCost": "平均コスト", + "bench.detail.labels.summary": "概要", + "bench.detail.labels.runs": "実行回数", + "bench.detail.labels.score": "スコア", + "bench.detail.labels.base": "ベース", + "bench.detail.labels.penalty": "ペナルティ", + "bench.detail.labels.weight": "重み", + "bench.detail.table.run": "実行", + "bench.detail.table.score": "スコア (ベース - ペナルティ)", + "bench.detail.table.cost": "コスト", + "bench.detail.table.duration": "所要時間", + "bench.detail.run.title": "実行 {{n}}", + "bench.detail.rawJson": "Raw JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/ko.ts b/packages/console/app/src/i18n/ko.ts new file mode 100644 index 0000000000000000000000000000000000000000..e9b5c92071c4801b2af65487a0a2b25ecc5fdac9 --- /dev/null +++ b/packages/console/app/src/i18n/ko.ts @@ -0,0 +1,865 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash 사용 한도가 한시적으로 4배 확대됩니다", + "go.graph.bonus": "사용량 {{count}}배", + "nav.github": "GitHub", + "nav.docs": "문서", + "nav.changelog": "변경 내역", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "엔터프라이즈", + "nav.zen": "Zen", + "nav.login": "로그인", + "nav.free": "다운로드", + "nav.home": "홈", + "nav.openMenu": "메뉴 열기", + "nav.getStartedFree": "무료로 시작하기", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "로고를 SVG로 복사", + "nav.context.copyWordmark": "워드마크를 SVG로 복사", + "nav.context.brandAssets": "브랜드 자산", + + "footer.github": "GitHub", + "footer.docs": "문서", + "footer.changelog": "변경 내역", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "브랜드", + "legal.privacy": "개인정보처리방침", + "legal.terms": "이용약관", + + "email.title": "새로운 제품 출시 소식을 가장 먼저 받아보세요", + "email.subtitle": "대기 명단에 등록하여 조기 이용 권한을 받으세요.", + "email.placeholder": "이메일 주소", + "email.subscribe": "구독", + "email.success": "거의 완료되었습니다. 이메일 수신함을 확인하고 주소를 인증해주세요.", + + "notFound.title": "페이지를 찾을 수 없음 | OpenCode", + "notFound.heading": "404 - 페이지를 찾을 수 없음", + "notFound.home": "홈", + "notFound.docs": "문서", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode 밝은 로고", + "notFound.logoDarkAlt": "opencode 어두운 로고", + + "user.logout": "로그아웃", + + "auth.callback.error.codeMissing": "인증 코드를 찾을 수 없습니다.", + + "workspace.select": "워크스페이스 선택", + "workspace.createNew": "+ 새 워크스페이스 만들기", + "workspace.modal.title": "새 워크스페이스 만들기", + "workspace.modal.placeholder": "워크스페이스 이름 입력", + + "common.cancel": "취소", + "common.creating": "생성 중...", + "common.create": "만들기", + "common.contactUs": "문의하기", + + "common.videoUnsupported": "브라우저가 비디오 태그를 지원하지 않습니다.", + "common.figure": "그림 {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "더 알아보기", + + "error.invalidPlan": "유효하지 않은 플랜", + "error.workspaceRequired": "워크스페이스 ID가 필요합니다", + "error.alreadySubscribed": "이 워크스페이스는 이미 구독 중입니다", + "error.limitRequired": "한도가 필요합니다.", + "error.monthlyLimitInvalid": "유효한 월 한도를 설정하세요.", + "error.workspaceNameRequired": "워크스페이스 이름이 필요합니다.", + "error.nameTooLong": "이름은 255자 이하여야 합니다.", + "error.emailRequired": "이메일이 필요합니다", + "error.roleRequired": "역할이 필요합니다", + "error.idRequired": "ID가 필요합니다", + "error.nameRequired": "이름이 필요합니다", + "error.providerRequired": "제공자가 필요합니다", + "error.apiKeyRequired": "API 키가 필요합니다", + "error.modelRequired": "모델이 필요합니다", + "error.reloadAmountMin": "충전 금액은 최소 ${{amount}}이어야 합니다", + "error.reloadTriggerMin": "잔액 트리거는 최소 ${{amount}}이어야 합니다", + + "app.meta.description": "OpenCode - 오픈 소스 코딩 에이전트.", + + "home.title": "OpenCode | 오픈 소스 AI 코딩 에이전트", + + "temp.title": "OpenCode | 터미널을 위해 만들어진 AI 코딩 에이전트", + "temp.hero.title": "터미널을 위해 만들어진 AI 코딩 에이전트", + "temp.zen": "OpenCode Zen", + "temp.getStarted": "시작하기", + "temp.feature.native.title": "네이티브 TUI", + "temp.feature.native.body": "반응형, 네이티브, 테마 적용 가능한 터미널 UI", + "temp.feature.zen.beforeLink": "OpenCode가 제공하는", + "temp.feature.zen.link": "엄선된 모델 목록", + "temp.feature.zen.afterLink": "", + "temp.feature.models.beforeLink": "로컬 모델을 포함하여", + "temp.feature.models.afterLink": "를 통해 75개 이상의 LLM 제공자 지원", + "temp.screenshot.caption": "tokyonight 테마가 적용된 OpenCode TUI", + "temp.screenshot.alt": "tokyonight 테마가 적용된 OpenCode TUI", + "temp.logoLightAlt": "opencode 밝은 로고", + "temp.logoDarkAlt": "opencode 어두운 로고", + + "home.banner.badge": "신규", + "home.banner.text": "데스크톱 탭을 소개합니다.", + "home.banner.platforms": "macOS, Windows, Linux에서 사용할 수 있습니다", + "home.banner.downloadNow": "지금 다운로드", + "home.banner.downloadBetaNow": "데스크톱 베타 다운로드", + "home.promo.title": "데스크톱 탭을 소개합니다", + "home.promo.body": "탭으로 작업과 활성 세션을 정리하세요.", + "home.promo.cta": "최신 버전을 다운로드하여 시작하세요.", + "home.promo.close": "데스크톱 앱 안내 닫기", + + "home.hero.title": "오픈 소스 AI 코딩 에이전트", + "home.hero.subtitle.a": "무료 모델이 포함되어 있으며, 어떤 제공자의 모델이든 연결 가능합니다.", + "home.hero.subtitle.b": "Claude, GPT, Gemini 등을 포함합니다.", + + "home.install.ariaLabel": "설치 옵션", + + "home.what.title": "OpenCode란 무엇인가요?", + "home.what.body": + "OpenCode는 터미널, IDE, 또는 데스크톱에서 코드를 작성할 수 있도록 도와주는 오픈 소스 에이전트입니다.", + "home.what.lsp.title": "LSP 지원", + "home.what.lsp.body": "LLM에 적합한 LSP를 자동으로 로드합니다", + "home.what.multiSession.title": "멀티 세션", + "home.what.multiSession.body": "동일한 프로젝트에서 여러 에이전트를 병렬로 실행하세요", + "home.what.shareLinks.title": "링크 공유", + "home.what.shareLinks.body": "참조나 디버깅을 위해 세션 링크를 공유하세요", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "GitHub로 로그인하여 Copilot 계정을 사용하세요", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "OpenAI로 로그인하여 ChatGPT Plus 또는 Pro 계정을 사용하세요", + "home.what.anyModel.title": "모든 모델", + "home.what.anyModel.body": "Models.dev를 통해 로컬 모델 포함 75개 이상의 LLM 제공자 지원", + "home.what.anyEditor.title": "모든 에디터", + "home.what.anyEditor.body": "터미널 인터페이스, 데스크톱 앱, IDE 확장 프로그램으로 사용 가능", + "home.what.readDocs": "문서 읽기", + + "home.growth.title": "오픈 소스 AI 코딩 에이전트", + "home.growth.body": + "{{stars}}개 이상의 GitHub 스타, {{contributors}}명의 기여자, {{commits}}개 이상의 커밋과 함께, OpenCode는 매달 {{monthlyUsers}}명 이상의 개발자가 사용하고 신뢰합니다.", + "home.growth.githubStars": "GitHub 스타", + "home.growth.contributors": "기여자", + "home.growth.monthlyDevs": "월간 사용자", + + "home.privacy.title": "프라이버시를 최우선으로 설계", + "home.privacy.body": + "OpenCode는 코드나 컨텍스트 데이터를 저장하지 않으므로, 프라이버시에 민감한 환경에서도 안전하게 작동합니다.", + "home.privacy.learnMore": "더 알아보기:", + "home.privacy.link": "프라이버시", + + "home.faq.q1": "OpenCode란 무엇인가요?", + "home.faq.a1": + "OpenCode는 어떤 AI 모델로든 코드를 작성하고 실행할 수 있도록 도와주는 오픈 소스 에이전트입니다. 터미널 기반 인터페이스, 데스크톱 앱, 또는 IDE 확장 프로그램으로 사용할 수 있습니다.", + "home.faq.q2": "OpenCode는 어떻게 사용하나요?", + "home.faq.a2.before": "가장 쉬운 시작 방법은", + "home.faq.a2.link": "소개", + "home.faq.q3": "OpenCode를 사용하려면 별도의 AI 구독이 필요한가요?", + "home.faq.a3.p1": "꼭 그렇지는 않습니다. OpenCode에는 계정 없이도 사용할 수 있는 무료 모델 세트가 포함되어 있습니다.", + "home.faq.a3.p2.beforeZen": "이 외에도,", + "home.faq.a3.p2.afterZen": " 계정을 생성하여 인기 있는 코딩 모델들을 사용할 수 있습니다.", + "home.faq.a3.p3": "Zen 사용을 권장하지만, OpenCode는 OpenAI, Anthropic, xAI 등 모든 인기 제공자와도 작동합니다.", + "home.faq.a3.p4.beforeLocal": "또한", + "home.faq.a3.p4.localLink": "로컬 모델", + "home.faq.q4": "기존 AI 구독을 OpenCode에서 사용할 수 있나요?", + "home.faq.a4.p1": + "네, OpenCode는 모든 주요 제공자의 구독 플랜을 지원합니다. Claude Pro/Max, ChatGPT Plus/Pro, 또는 GitHub Copilot 구독을 사용할 수 있습니다.", + "home.faq.q5": "OpenCode는 터미널에서만 사용할 수 있나요?", + "home.faq.a5.beforeDesktop": "이제 아닙니다! OpenCode는 이제", + "home.faq.a5.desktop": "데스크톱", + "home.faq.a5.and": "및", + "home.faq.a5.web": "웹", + "home.faq.q6": "OpenCode 비용은 얼마인가요?", + "home.faq.a6": + "OpenCode는 100% 무료로 사용할 수 있습니다. 무료 모델 세트도 포함되어 있습니다. 다른 제공자를 연결할 경우 추가 비용이 발생할 수 있습니다.", + "home.faq.q7": "데이터와 프라이버시는 어떤가요?", + "home.faq.a7.p1": "데이터와 정보는 무료 모델을 사용하거나 공유 링크를 생성할 때만 저장됩니다.", + "home.faq.a7.p2.beforeModels": "더 알아보기:", + "home.faq.a7.p2.modelsLink": "모델", + "home.faq.a7.p2.and": "및", + "home.faq.a7.p2.shareLink": "공유 페이지", + "home.faq.q8": "OpenCode는 오픈 소스인가요?", + "home.faq.a8.p1": "네, OpenCode는 완전히 오픈 소스입니다. 소스 코드는", + "home.faq.a8.p2": "에 공개되어 있으며,", + "home.faq.a8.mitLicense": "MIT 라이선스", + "home.faq.a8.p3": + "를 따릅니다. 즉, 누구나 사용, 수정 또는 개발에 기여할 수 있습니다. 커뮤니티의 누구든지 이슈를 등록하고, 풀 리퀘스트를 제출하고, 기능을 확장할 수 있습니다.", + + "home.zenCta.title": "코딩 에이전트를 위한 신뢰할 수 있고 최적화된 모델", + "home.zenCta.body": + "Zen은 OpenCode가 코딩 에이전트를 위해 특별히 테스트하고 벤치마킹한 엄선된 AI 모델 세트에 대한 액세스를 제공합니다. 제공자 간의 일관되지 않은 성능과 품질에 대해 걱정할 필요 없이, 검증된 모델을 사용하세요.", + "home.zenCta.link": "Zen 알아보기", + + "zen.title": "OpenCode Zen | 코딩 에이전트를 위한 신뢰할 수 있고 최적화된 모델 세트", + "zen.hero.title": "코딩 에이전트를 위한 신뢰할 수 있고 최적화된 모델", + "zen.hero.body": + "Zen은 OpenCode가 코딩 에이전트를 위해 특별히 테스트하고 벤치마킹한 엄선된 AI 모델 세트에 대한 액세스를 제공합니다. 일관되지 않은 성능과 품질에 대해 걱정할 필요 없이, 검증된 모델을 사용하세요.", + + "zen.faq.q1": "OpenCode Zen이란 무엇인가요?", + "zen.faq.a1": "Zen은 OpenCode 팀이 코딩 에이전트를 위해 테스트하고 벤치마킹한 엄선된 AI 모델 세트입니다.", + "zen.faq.q2": "Zen은 왜 더 정확한가요?", + "zen.faq.a2": + "Zen은 코딩 에이전트를 위해 특별히 테스트되고 벤치마킹된 모델만 제공합니다. 스테이크를 버터 나이프로 자르지 않듯이, 코딩에 품질이 낮은 모델을 사용하지 마세요.", + "zen.faq.q3": "Zen이 더 저렴한가요?", + "zen.faq.a3": + "Zen은 영리를 목적으로 하지 않습니다. Zen은 모델 제공자의 비용을 사용자에게 그대로 전달합니다. Zen 사용량이 늘어날수록 OpenCode는 더 좋은 요율을 협상하여 그 혜택을 사용자에게 돌려드릴 수 있습니다.", + "zen.faq.q4": "Zen 비용은 얼마인가요?", + "zen.faq.a4.p1.beforePricing": "Zen은", + "zen.faq.a4.p1.pricingLink": "요청당 비용을 청구하며", + "zen.faq.a4.p1.afterPricing": ", 마크업이 0이므로 모델 제공자가 청구하는 금액 그대로 지불하게 됩니다.", + "zen.faq.a4.p2.beforeAccount": "총 비용은 사용량에 따라 달라지며, 월간 지출 한도를", + "zen.faq.a4.p2.accountLink": "계정", + "zen.faq.a4.p3": "비용을 충당하기 위해 OpenCode는 $20 잔액 충전 시 $1.23의 소액 결제 처리 수수료만 추가합니다.", + "zen.faq.q5": "데이터와 프라이버시는 어떤가요?", + "zen.faq.a5.beforeExceptions": + "모든 Zen 모델은 미국에서 호스팅됩니다. 제공자들은 데이터 보존 금지(zero-retention) 정책을 따르며, 모델 학습에 귀하의 데이터를 사용하지 않습니다. 단,", + "zen.faq.a5.exceptionsLink": "다음 예외", + "zen.faq.q6": "지출 한도를 설정할 수 있나요?", + "zen.faq.a6": "네, 계정에서 월간 지출 한도를 설정할 수 있습니다.", + "zen.faq.q7": "취소할 수 있나요?", + "zen.faq.a7": "네, 언제든지 결제를 비활성화하고 남은 잔액을 사용할 수 있습니다.", + "zen.faq.q8": "다른 코딩 에이전트와 Zen을 사용할 수 있나요?", + "zen.faq.a8": + "Zen은 OpenCode와 훌륭하게 작동하지만, 어떤 에이전트와도 Zen을 사용할 수 있습니다. 선호하는 코딩 에이전트의 설정 지침을 따르세요.", + "zen.faq.q9": "환불받을 수 있나요?", + "zen.faq.a9": + "결제일로부터 14일 이내이며 해당 구매로 받은 크레딧을 전혀 사용하지 않은 경우 환불 대상이 될 수 있습니다. 환불을 요청하려면 {{contact}}를 선택해 주세요.", + + "zen.cta.start": "Zen 시작하기", + "zen.pricing.title": "$20 선불 잔액 추가", + "zen.pricing.fee": "(+$1.23 카드 처리 수수료)", + "zen.pricing.body": "모든 에이전트와 함께 사용하세요. 월간 지출 한도 설정 가능. 언제든지 취소 가능.", + "zen.problem.title": "Zen은 어떤 문제를 해결하나요?", + "zen.problem.body": + "사용 가능한 모델은 매우 많지만, 코딩 에이전트와 잘 작동하는 모델은 소수에 불과합니다. 대부분의 제공자들은 모델을 다르게 구성하여 결과가 제각각입니다.", + "zen.problem.subtitle": "우리는 OpenCode 사용자뿐만 아니라 모든 분들을 위해 이 문제를 해결하고 있습니다.", + "zen.problem.item1": "선별된 모델 테스트 및 팀 자문", + "zen.problem.item2": "제공자와 협력하여 올바른 모델 전달 보장", + "zen.problem.item3": "권장하는 모든 모델-제공자 조합 벤치마킹", + "zen.how.title": "Zen 작동 방식", + "zen.how.body": "OpenCode와 함께 사용하는 것을 권장하지만, Zen은 어떤 에이전트와도 사용할 수 있습니다.", + "zen.how.step1.title": "가입 및 $20 잔액 추가", + "zen.how.step1.beforeLink": "", + "zen.how.step1.link": "설정 지침", + "zen.how.step2.title": "투명한 가격으로 Zen 사용", + "zen.how.step2.link": "요청당 지불", + "zen.how.step2.afterLink": "(마크업 0)", + "zen.how.step3.title": "자동 충전", + "zen.how.step3.body": "잔액이 $5에 도달하면 자동으로 $20가 충전됩니다", + "zen.privacy.title": "귀하의 프라이버시는 우리에게 중요합니다", + "zen.privacy.beforeExceptions": + "모든 Zen 모델은 미국에서 호스팅됩니다. 제공자들은 데이터 보존 금지 정책을 따르며 모델 학습에 데이터를 사용하지 않습니다. 단,", + "zen.privacy.exceptionsLink": "다음 예외", + + "go.title": "OpenCode Go | 모두를 위한 저비용 코딩 모델", + "go.meta.description": "Go는 월 $10이며, 넉넉한 사용 한도와 주요 코딩 모델에 대한 안정적인 액세스를 제공합니다.", + "go.hero.title": "모두를 위한 저비용 코딩 모델", + "go.hero.body": + "Go는 전 세계 프로그래머들에게 에이전트 코딩을 제공합니다. 가장 유능한 오픈 소스 모델에 대한 넉넉한 한도와 안정적인 액세스를 제공하므로, 비용이나 가용성 걱정 없이 강력한 에이전트로 빌드할 수 있습니다.", + + "go.cta.start": "Go 구독하기", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Go 구독하기", + "go.cta.price": "$10/월", + "go.pricing.body": + "어떤 에이전트와도 사용할 수 있습니다. 월 $10. 필요하면 크레딧을 충전하세요. 언제든지 취소할 수 있습니다.", + "go.graph.free": "무료", + "go.graph.freePill": "Big Pickle 및 무료 모델", + "go.graph.go": "Go", + "go.graph.label": "5시간당 요청 수", + "go.graph.period": "사용량", + "go.graph.model": "모델", + "go.graph.requests": "예상 요청 횟수 / 5시간", + "go.graph.allowance": "월간 사용량", + "go.graph.new": "신규", + "go.graph.scale": "요청 수는 비선형 눈금으로 표시됩니다", + "go.graph.showAll": "전체 {{count}}개 모델 보기", + "go.graph.showLess": "접기", + "go.graph.limitedRegions": "일부 지역에서만 제공", + "go.graph.limitedTime": "한정된 기간", + "go.graph.usageLimits": "사용 한도", + "go.graph.aria": "5시간당 요청 수: {{free}} 대 {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "전 Terminal Products CEO", + "go.testimonials.dax.quoteAfter": "(은)는 삶을 변화시켰습니다. 정말 당연한 선택입니다.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "전 Founder, SEED, PM, Melt, Pop, Dapt, Cadmus, ViewPoint", + "go.testimonials.jay.quoteBefore": "우리 팀 5명 중 4명이", + "go.testimonials.jay.quoteAfter": " 사용을 정말 좋아합니다.", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "전 AWS Hero", + "go.testimonials.adam.quoteBefore": "저는", + "go.testimonials.adam.quoteAfter": "를(을) 아무리 추천해도 부족합니다. 진심으로 정말 좋습니다.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "전 Laravel 디자인 총괄", + "go.testimonials.david.quoteBefore": "", + "go.testimonials.david.quoteAfter": + "와(과) 함께라면 모든 모델이 테스트를 거쳤고 코딩 에이전트에 완벽하다는 것을 알 수 있습니다.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "전 Nvidia 인턴 (4회)", + "go.testimonials.frank.quote": "아직 Nvidia에 있었으면 좋았을 텐데요.", + "go.problem.title": "Go는 어떤 문제를 해결하나요?", + "go.problem.body": + "우리는 가능한 많은 사람들에게 OpenCode 경험을 제공하는 데 집중하고 있습니다. OpenCode Go는 월 $10의 저렴한 구독 서비스입니다. 넉넉한 한도와 가장 뛰어난 오픈 소스 모델에 대한 안정적인 액세스를 제공합니다.", + "go.problem.subtitle": " ", + "go.problem.item1": "저렴한 구독 가격", + "go.problem.item2": "넉넉한 한도와 안정적인 액세스", + "go.problem.item3": "가능한 한 많은 프로그래머를 위해 제작됨", + "go.problem.item4": "에이전트 코딩용으로 테스트된 엄선된 모델 라인업", + "go.how.title": "Go 작동 방식", + "go.how.body": "Go는 월 $10입니다. OpenCode 또는 어떤 에이전트와도 함께 사용할 수 있습니다.", + "go.how.step1.title": "계정 생성", + "go.how.step1.beforeLink": "", + "go.how.step1.link": "설정 지침을 따르세요", + "go.how.step2.title": "Go 구독", + "go.how.step2.link": "월 $10", + "go.how.step2.afterLink": "넉넉한 한도 포함", + "go.how.step3.title": "코딩 시작", + "go.how.step3.body": "오픈 소스 모델에 대한 안정적인 액세스와 함께", + "go.privacy.title": "귀하의 프라이버시는 우리에게 중요합니다", + "go.privacy.body": + "이 플랜은 주로 글로벌 사용자를 위해 설계되었으며, 안정적인 글로벌 액세스를 위해 미국, EU, 싱가포르에 모델이 호스팅되어 있습니다.", + "go.privacy.contactAfter": "질문이 있으시면 언제든지 문의해 주세요.", + "go.privacy.beforeExceptions": + "Go 모델은 미국에서 호스팅됩니다. 제공자들은 데이터 보존 금지 정책을 따르며 모델 학습에 데이터를 사용하지 않습니다. 단,", + "go.privacy.exceptionsLink": "다음 예외", + "go.faq.q1": "OpenCode Go란 무엇인가요?", + "go.faq.a1": "Go는 에이전트 코딩을 위한 유능한 오픈 소스 모델에 대해 안정적인 액세스를 제공하는 저비용 구독입니다.", + "go.faq.q2": "Go에는 어떤 모델이 포함되나요?", + "go.faq.a2": "Go에는 넉넉한 한도와 안정적인 액세스를 제공하는 아래 모델이 포함됩니다.", + "go.faq.q3": "Go는 Zen과 같은가요?", + "go.faq.a3": + "아니요. Zen은 종량제인 반면, Go는 월 $10이며, 엄선된 모델 라인업에 대한 넉넉한 한도와 안정적인 액세스를 제공합니다.", + "go.faq.q4": "Go 비용은 얼마인가요?", + "go.faq.a4.p1.beforePricing": "Go 비용은", + "go.faq.a4.p1.pricingLink": "월 $10", + "go.faq.a4.p1.afterPricing": "넉넉한 한도 포함.", + "go.faq.a4.p2.beforeAccount": "구독 관리는 다음에서 가능합니다:", + "go.faq.a4.p2.accountLink": "계정", + "go.faq.a4.p3": "언제든지 취소할 수 있습니다.", + "go.faq.q5": "데이터와 프라이버시는 어떤가요?", + "go.faq.a5.model": "모델", + "go.faq.a5.training": "모델 학습", + "go.faq.a5.retention": "데이터 보존", + "go.faq.a5.retention30": "30일", + "go.faq.a5.retention0": "0일", + "go.faq.a5.used": "사용됨", + "go.faq.a5.notUsed": "사용되지 않음", + "go.faq.a5.noAgreement": "합의 없음", + "go.faq.a5.notZdr": "ZDR 아님", + "go.faq.a5.grokRetention": + "ZDR은 저장된 데이터에 의존하는 중요한 API 기능(상태 저장형 Responses API, Files and Collections, Batch API 포함)을 비활성화합니다.", + "go.faq.a5.gptRetention": "모든 API 기능 사용에 대해 악용 모니터링 로그가 생성되며 최대 30일 동안 보존됩니다.", + "go.faq.a5.museRetention": + "향후 Meta 모델 학습에 사용자의 프롬프트와 생성 결과를 사용할 수 있도록 허용하는 대신 토큰 가격이 대폭 할인됩니다.", + "go.faq.a5.learnMore": "자세히 알아보기", + "go.faq.a5.deepseekRetention": "ZDR 계약은 매월 갱신됩니다. 현재 계약은 2026년 9월 30일까지 유효합니다.", + "go.faq.a5.beforeExceptions": + "Go 모델은 미국에서 호스팅됩니다. 제공자들은 데이터 보존 금지 정책을 따르며 모델 학습에 데이터를 사용하지 않습니다. 단,", + "go.faq.a5.exceptionsLink": "다음 예외", + "go.faq.q6": "크레딧을 충전할 수 있나요?", + "go.faq.a6": "사용량이 더 필요한 경우 계정에서 크레딧을 충전할 수 있습니다.", + "go.faq.q7": "취소할 수 있나요?", + "go.faq.a7": "네, 언제든지 취소할 수 있습니다.", + "go.faq.q8": "다른 코딩 에이전트와 Go를 사용할 수 있나요?", + "go.faq.a8": "네, Go는 어떤 에이전트와도 사용할 수 있습니다. 선호하는 코딩 에이전트의 설정 지침을 따르세요.", + + "go.faq.q9": "무료 모델과 Go의 차이점은 무엇인가요?", + "go.faq.a9": + "무료 모델에는 Big Pickle과 당시 사용 가능한 프로모션 모델이 포함되며, 하루 200회 요청 할당량이 적용됩니다. Go는 엄선된 모델 라인업을 제공하며, 롤링 윈도우(5시간, 주간, 월간)에 걸쳐 더 높은 요청 할당량을 적용합니다. 기본 할당량은 대략 5시간당 $12, 주당 $30, 월 $60에 해당하며 모델별 할당량은 다를 수 있습니다(실제 요청 수는 모델 및 사용량에 따라 다름).", + "go.faq.q10": "환불받을 수 있나요?", + "go.faq.a10": + "결제일로부터 14일 이내이며 해당 결제 기간에 Go 사용 한도를 전혀 사용하지 않은 경우 환불 대상이 될 수 있습니다. 환불을 요청하려면 {{contact}}를 선택해 주세요.", + + "zen.api.error.rateLimitExceeded": "속도 제한을 초과했습니다. 나중에 다시 시도해 주세요.", + "zen.api.error.modelNotSupported": "{{model}} 모델은 지원되지 않습니다", + "zen.api.error.modelFormatNotSupported": "{{model}} 모델은 {{format}} 형식에 대해 지원되지 않습니다", + "zen.api.error.noProviderAvailable": "사용 가능한 제공자가 없습니다", + "zen.api.error.providerNotSupported": "{{provider}} 제공자는 지원되지 않습니다", + "zen.api.error.missingApiKey": "API 키가 누락되었습니다.", + "zen.api.error.invalidApiKey": "유효하지 않은 API 키입니다.", + "zen.api.error.requestBlockedByUpstreamProvider": "상위 제공자가 요청을 차단했습니다.", + "zen.api.error.subscriptionQuotaExceeded": "구독 할당량을 초과했습니다. {{retryIn}} 후 다시 시도해 주세요.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "5시간 사용 한도에 도달했습니다. {{retryIn}} 후 초기화됩니다. 이 모델을 지금 계속 사용하려면 사용 가능한 잔액에서 사용을 활성화하세요: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "주간 사용 한도에 도달했습니다. {{retryIn}} 후 초기화됩니다. 이 모델을 지금 계속 사용하려면 사용 가능한 잔액에서 사용을 활성화하세요: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "월간 사용 한도에 도달했습니다. {{retryIn}} 후 초기화됩니다. 이 모델을 지금 계속 사용하려면 사용 가능한 잔액에서 사용을 활성화하세요: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "결제 수단이 없습니다. 결제 수단을 추가하세요: {{billingUrl}}", + "zen.api.error.insufficientBalance": "잔액이 부족합니다. 결제 관리를 여기서 하세요: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "워크스페이스의 월간 지출 한도인 ${{amount}}에 도달했습니다. 한도 관리를 여기서 하세요: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "월간 지출 한도인 ${{amount}}에 도달했습니다. 한도 관리를 여기서 하세요: {{membersUrl}}", + "zen.api.error.modelDisabled": "모델이 비활성화되었습니다", + "zen.api.error.regionNotAllowed": + "이 모델의 최신 버전은 중국에서 호스팅되는 경우에만 사용할 수 있으며, 명시적으로 사용에 동의해야 합니다: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "이 모델은 거주 국가에서 사용할 수 없습니다.", + "zen.api.error.trainingNotAllowed": + "이 모델은 품질 개선에 사용되는 데이터를 수집하며, 사용하려면 명시적으로 동의해야 합니다: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "{{model}}의 무료 프로모션이 종료되었습니다. OpenCode Go를 구독하면 모델을 계속 사용할 수 있습니다 - {{link}}", + + "black.meta.title": "OpenCode Black | 세계 최고의 코딩 모델에 액세스하세요", + "black.meta.description": "OpenCode Black 구독 플랜으로 Claude, GPT, Gemini 등에 액세스하세요.", + "black.hero.title": "세계 최고의 코딩 모델에 액세스하세요", + "black.hero.subtitle": "Claude, GPT, Gemini 등 포함", + "black.title": "OpenCode Black | 가격", + "black.paused": "Black 플랜 등록이 일시적으로 중단되었습니다.", + "black.plan.icon20": "Black 20 플랜", + "black.plan.icon100": "Black 100 플랜", + "black.plan.icon200": "Black 200 플랜", + "black.plan.multiplier100": "Black 20보다 5배 더 많은 사용량", + "black.plan.multiplier200": "Black 20보다 20배 더 많은 사용량", + "black.price.perMonth": "월", + "black.price.perPersonBilledMonthly": "인당 / 월 청구", + "black.terms.1": "구독이 즉시 시작되지 않습니다", + "black.terms.2": "대기 명단에 추가되며 곧 활성화됩니다", + "black.terms.3": "구독이 활성화될 때만 카드가 청구됩니다", + "black.terms.4": "사용량 제한이 적용되며, 과도한 자동화 사용 시 제한에 더 빨리 도달할 수 있습니다", + "black.terms.5": "구독은 개인용이며, 팀용은 엔터프라이즈에 문의하세요", + "black.terms.6": "향후 제한이 조정되거나 플랜이 중단될 수 있습니다", + "black.terms.7": "언제든지 구독을 취소할 수 있습니다", + "black.action.continue": "계속", + "black.finePrint.beforeTerms": "표시된 가격에는 해당 세금이 포함되어 있지 않습니다", + "black.finePrint.terms": "서비스 약관", + "black.workspace.title": "OpenCode Black | 워크스페이스 선택", + "black.workspace.selectPlan": "이 플랜을 사용할 워크스페이스를 선택하세요", + "black.workspace.name": "워크스페이스 {{n}}", + "black.subscribe.title": "OpenCode Black 구독하기", + "black.subscribe.paymentMethod": "결제 수단", + "black.subscribe.loadingPaymentForm": "결제 양식 로드 중...", + "black.subscribe.selectWorkspaceToContinue": "계속하려면 워크스페이스를 선택하세요", + "black.subscribe.failurePrefix": "이런!", + "black.subscribe.error.generic": "오류가 발생했습니다", + "black.subscribe.error.invalidPlan": "유효하지 않은 플랜", + "black.subscribe.error.workspaceRequired": "워크스페이스 ID가 필요합니다", + "black.subscribe.error.alreadySubscribed": "이 워크스페이스는 이미 구독 중입니다", + "black.subscribe.processing": "처리 중...", + "black.subscribe.submit": "${{plan}} 구독하기", + "black.subscribe.form.chargeNotice": "구독이 활성화될 때만 청구됩니다", + "black.subscribe.success.title": "OpenCode Black 대기 명단에 등록되었습니다", + "black.subscribe.success.subscriptionPlan": "구독 플랜", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "금액", + "black.subscribe.success.amountValue": "월 ${{plan}}", + "black.subscribe.success.paymentMethod": "결제 수단", + "black.subscribe.success.dateJoined": "가입일", + "black.subscribe.success.chargeNotice": "구독이 활성화되면 카드에 청구됩니다", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "사용량", + "workspace.nav.apiKeys": "API 키", + "workspace.nav.members": "멤버", + "workspace.nav.billing": "결제", + "workspace.nav.settings": "설정", + + "workspace.home.banner.beforeLink": "코딩 에이전트를 위한 신뢰할 수 있고 최적화된 모델.", + "workspace.lite.banner.beforeLink": "모두를 위한 저비용 코딩 모델.", + "workspace.home.billing.loading": "로드 중...", + "workspace.home.billing.enable": "결제 활성화", + "workspace.home.billing.currentBalance": "현재 잔액", + + "workspace.newUser.feature.tested.title": "테스트 및 검증된 모델", + "workspace.newUser.feature.tested.body": + "최고의 성능을 보장하기 위해 코딩 에이전트용 모델을 구체적으로 벤치마킹하고 테스트했습니다.", + "workspace.newUser.feature.quality.title": "최고 품질", + "workspace.newUser.feature.quality.body": + "최적의 성능을 위해 구성된 모델에 액세스하세요 - 다운그레이드나 저렴한 제공자로 라우팅되지 않습니다.", + "workspace.newUser.feature.lockin.title": "락인(Lock-in) 없음", + "workspace.newUser.feature.lockin.body": + "Zen을 어떤 코딩 에이전트와도 함께 사용할 수 있으며, 원할 때 언제든지 OpenCode와 함께 다른 제공자를 계속 사용할 수 있습니다.", + "workspace.newUser.copyApiKey": "API 키 복사", + "workspace.newUser.copyKey": "키 복사", + "workspace.newUser.copied": "복사됨!", + "workspace.newUser.step.enableBilling": "결제 활성화", + "workspace.newUser.step.login.before": "실행", + "workspace.newUser.step.login.after": "후 OpenCode 선택", + "workspace.newUser.step.pasteKey": "API 키 붙여넣기", + "workspace.newUser.step.models.before": "OpenCode를 시작하고 실행", + "workspace.newUser.step.models.after": "하여 모델 선택", + + "workspace.models.title": "모델", + "workspace.models.subtitle.beforeLink": "워크스페이스 멤버가 액세스할 수 있는 모델을 관리합니다.", + "workspace.models.table.model": "모델", + "workspace.models.table.enabled": "활성화됨", + + "workspace.providers.title": "나만의 키 가져오기 (BYOK)", + "workspace.providers.subtitle": "AI 제공자의 자체 API 키를 구성하세요.", + "workspace.providers.placeholder": "{{provider}} API 키 입력 ({{prefix}}...)", + "workspace.providers.configure": "구성", + "workspace.providers.edit": "편집", + "workspace.providers.delete": "삭제", + "workspace.providers.saving": "저장 중...", + "workspace.providers.save": "저장", + "workspace.providers.table.provider": "제공자", + "workspace.providers.table.apiKey": "API 키", + + "workspace.usage.title": "사용 내역", + "workspace.usage.subtitle": "최근 API 사용량 및 비용.", + "workspace.usage.empty": "시작하려면 첫 API 호출을 해보세요.", + "workspace.usage.table.date": "날짜", + "workspace.usage.table.model": "모델", + "workspace.usage.table.input": "입력", + "workspace.usage.table.output": "출력", + "workspace.usage.table.cost": "비용", + "workspace.usage.table.session": "세션", + "workspace.usage.breakdown.input": "입력", + "workspace.usage.breakdown.cacheRead": "캐시 읽기", + "workspace.usage.breakdown.cacheWrite": "캐시 쓰기", + "workspace.usage.breakdown.output": "출력", + "workspace.usage.breakdown.reasoning": "추론", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "비용", + "workspace.cost.subtitle": "모델별 사용 비용 내역.", + "workspace.cost.allModels": "모든 모델", + "workspace.cost.allKeys": "모든 키", + "workspace.cost.deletedSuffix": "(삭제됨)", + "workspace.cost.empty": "선택한 기간에 사용 데이터가 없습니다.", + "workspace.cost.subscriptionShort": "구독", + + "workspace.keys.title": "API 키", + "workspace.keys.subtitle": "OpenCode 서비스 액세스를 위한 API 키를 관리하세요.", + "workspace.keys.create": "API 키 생성", + "workspace.keys.placeholder": "키 이름 입력", + "workspace.keys.empty": "OpenCode 게이트웨이 API 키 생성", + "workspace.keys.table.name": "이름", + "workspace.keys.table.key": "키", + "workspace.keys.table.createdBy": "생성자", + "workspace.keys.table.lastUsed": "마지막 사용", + "workspace.keys.copyApiKey": "API 키 복사", + "workspace.keys.delete": "삭제", + + "workspace.members.title": "멤버", + "workspace.members.subtitle": "워크스페이스 멤버 및 권한을 관리합니다.", + "workspace.members.invite": "멤버 초대", + "workspace.members.inviting": "초대 중...", + "workspace.members.beta.beforeLink": "베타 기간 동안 팀 워크스페이스는 무료입니다.", + "workspace.members.form.invitee": "초대받는 사람", + "workspace.members.form.emailPlaceholder": "이메일 입력", + "workspace.members.form.role": "역할", + "workspace.members.form.monthlyLimit": "월간 지출 한도", + "workspace.members.noLimit": "제한 없음", + "workspace.members.noLimitLowercase": "제한 없음", + "workspace.members.invited": "초대됨", + "workspace.members.edit": "편집", + "workspace.members.delete": "삭제", + "workspace.members.saving": "저장 중...", + "workspace.members.save": "저장", + "workspace.members.table.email": "이메일", + "workspace.members.table.role": "역할", + "workspace.members.table.monthLimit": "월 한도", + "workspace.members.role.admin": "관리자", + "workspace.members.role.adminDescription": "모델, 멤버, 결제 관리 가능", + "workspace.members.role.member": "멤버", + "workspace.members.role.memberDescription": "자신의 API 키만 생성 가능", + + "workspace.settings.title": "설정", + "workspace.settings.subtitle": "워크스페이스 이름과 환경설정을 업데이트하세요.", + "workspace.settings.workspaceName": "워크스페이스 이름", + "workspace.settings.defaultName": "기본", + "workspace.settings.updating": "업데이트 중...", + "workspace.settings.save": "저장", + "workspace.settings.edit": "편집", + + "workspace.billing.title": "결제", + "workspace.billing.subtitle.beforeLink": "결제 수단을 관리하세요.", + "workspace.billing.contactUs": "문의하기", + "workspace.billing.subtitle.afterLink": "질문이 있으시면 언제든 연락주세요.", + "workspace.billing.currentBalance": "현재 잔액", + "workspace.billing.add": "추가 $", + "workspace.billing.enterAmount": "금액 입력", + "workspace.billing.loading": "로드 중...", + "workspace.billing.addAction": "추가", + "workspace.billing.addBalance": "잔액 추가", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Stripe에 연결됨", + "workspace.billing.manage": "관리", + "workspace.billing.enable": "결제 활성화", + + "workspace.monthlyLimit.title": "월 한도", + "workspace.monthlyLimit.subtitle": "계정의 월간 사용 한도를 설정하세요.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "설정 중...", + "workspace.monthlyLimit.set": "설정", + "workspace.monthlyLimit.edit": "한도 편집", + "workspace.monthlyLimit.noLimit": "사용 한도가 설정되지 않았습니다.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "현재", + "workspace.monthlyLimit.currentUsage.beforeAmount": "사용량: $", + + "workspace.redeem.title": "쿠폰 사용", + "workspace.redeem.subtitle": "쿠폰 코드를 사용해 크레딧이나 혜택을 받으세요.", + "workspace.redeem.placeholder": "쿠폰 코드를 입력하세요", + "workspace.redeem.redeem": "사용", + "workspace.redeem.redeeming": "사용 중...", + "workspace.redeem.success": "쿠폰을 성공적으로 사용했습니다.", + + "workspace.reload.title": "자동 충전", + "workspace.reload.disabled.before": "자동 충전이", + "workspace.reload.disabled.state": "비활성화", + "workspace.reload.disabled.after": "되었습니다. 잔액이 부족할 때 자동으로 충전하려면 활성화하세요.", + "workspace.reload.enabled.before": "자동 충전이", + "workspace.reload.enabled.state": "활성화", + "workspace.reload.enabled.middle": "되었습니다. 잔액이", + "workspace.reload.processingFee": "처리 수수료", + "workspace.reload.enabled.after": "에 도달하면 충전합니다.", + "workspace.reload.edit": "편집", + "workspace.reload.enable": "활성화", + "workspace.reload.enableAutoReload": "자동 충전 활성화", + "workspace.reload.reloadAmount": "충전 금액 $", + "workspace.reload.whenBalanceReaches": "잔액이 다음 금액에 도달할 때 $", + "workspace.reload.saving": "저장 중...", + "workspace.reload.save": "저장", + "workspace.reload.failedAt": "충전 실패 시간:", + "workspace.reload.reason": "사유:", + "workspace.reload.updatePaymentMethod": "결제 수단을 업데이트하고 다시 시도해 주세요.", + "workspace.reload.retrying": "재시도 중...", + "workspace.reload.retry": "재시도", + "workspace.reload.error.paymentFailed": "결제에 실패했습니다.", + + "workspace.payments.title": "결제 내역", + "workspace.payments.subtitle": "최근 결제 거래 내역입니다.", + "workspace.payments.table.date": "날짜", + "workspace.payments.table.paymentId": "결제 ID", + "workspace.payments.table.amount": "금액", + "workspace.payments.table.receipt": "영수증", + "workspace.payments.type.credit": "크레딧", + "workspace.payments.type.subscription": "구독", + "workspace.payments.view": "보기", + + "workspace.black.loading": "로드 중...", + "workspace.black.time.day": "일", + "workspace.black.time.days": "일", + "workspace.black.time.hour": "시간", + "workspace.black.time.hours": "시간", + "workspace.black.time.minute": "분", + "workspace.black.time.minutes": "분", + "workspace.black.time.fewSeconds": "몇 초", + "workspace.black.subscription.title": "구독", + "workspace.black.subscription.message": "현재 월 ${{plan}} OpenCode Black 플랜을 구독 중입니다.", + "workspace.black.subscription.manage": "구독 관리", + "workspace.black.subscription.rollingUsage": "5시간 사용량", + "workspace.black.subscription.weeklyUsage": "주간 사용량", + "workspace.black.subscription.resetsIn": "초기화까지 남은 시간:", + "workspace.black.subscription.useBalance": "사용 한도 도달 후에는 보유 잔액 사용", + "workspace.black.waitlist.title": "대기 명단", + "workspace.black.waitlist.joined": "월 ${{plan}} OpenCode Black 플랜 대기 명단에 등록되었습니다.", + "workspace.black.waitlist.ready": "월 ${{plan}} OpenCode Black 플랜에 등록할 준비가 되었습니다.", + "workspace.black.waitlist.leave": "대기 명단에서 나가기", + "workspace.black.waitlist.leaving": "나가는 중...", + "workspace.black.waitlist.left": "나감", + "workspace.black.waitlist.enroll": "등록", + "workspace.black.waitlist.enrolling": "등록 중...", + "workspace.black.waitlist.enrolled": "등록됨", + "workspace.black.waitlist.enrollNote": "등록을 클릭하면 구독이 즉시 시작되며 카드에 요금이 청구됩니다.", + + "workspace.lite.loading": "로드 중...", + "workspace.lite.time.day": "일", + "workspace.lite.time.days": "일", + "workspace.lite.time.hour": "시간", + "workspace.lite.time.hours": "시간", + "workspace.lite.time.minute": "분", + "workspace.lite.time.minutes": "분", + "workspace.lite.time.fewSeconds": "몇 초", + "workspace.lite.subscription.message": "현재 OpenCode Go를 구독 중입니다.", + "workspace.lite.subscription.manage": "구독 관리", + "workspace.lite.subscription.rollingUsage": "5시간 사용량", + "workspace.lite.subscription.rollingQuota": "5시간 할당량", + "workspace.lite.subscription.weeklyUsage": "주간 사용량", + "workspace.lite.subscription.weeklyQuota": "주간 할당량", + "workspace.lite.subscription.monthlyUsage": "월간 사용량", + "workspace.lite.subscription.monthlyQuota": "월간 할당량", + "workspace.lite.subscription.resetsIn": "초기화까지 남은 시간:", + "workspace.lite.subscription.showDetails": "상세 정보 보기", + "workspace.lite.subscription.hideDetails": "상세 정보 숨기기", + "workspace.lite.subscription.model": "모델", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "합계", + "workspace.lite.subscription.useBalance": "사용 한도 도달 후에는 보유 잔액 사용", + "workspace.lite.subscription.selectProvider": + 'Go 모델을 사용하려면 opencode 설정에서 "OpenCode Go"를 공급자로 선택하세요.', + "workspace.lite.providers.title": "공급자", + "workspace.lite.providers.description": "라우팅에 사용할 공급자를 제어합니다.", + "workspace.lite.providers.allowTraining": "요청 데이터를 학습에 사용하는 모델 허용", + "workspace.lite.providers.useChina": "중국에서 호스팅되는 모델 활성화", + "workspace.lite.black.message": + "현재 OpenCode Black을 구독 중이거나 대기 명단에 등록되어 있습니다. Go로 전환하려면 먼저 구독을 취소해 주세요.", + "workspace.lite.other.message": + "이 워크스페이스의 다른 멤버가 이미 OpenCode Go를 구독 중입니다. 워크스페이스당 한 명의 멤버만 구독할 수 있습니다.", + "workspace.lite.promo.description": + "OpenCode Go는 {{price}}로 넉넉한 사용량 한도와 함께 인기 있는 오픈 코딩 모델에 대한 안정적인 액세스를 제공합니다.", + "workspace.lite.promo.price": "$10/월", + "workspace.lite.promo.modelsTitle": "포함 내역", + "workspace.lite.promo.footer": + "이 플랜은 주로 해외 사용자를 위해 설계되었으며, 전 세계에서 안정적으로 이용할 수 있습니다. 초기 이용 현황과 피드백을 반영하는 과정에서 가격과 사용 한도가 변경될 수 있습니다.", + "workspace.lite.promo.subscribe": "Go 구독하기", + "workspace.lite.promo.subscribing": "리디렉션 중...", + "workspace.lite.promo.otherMethods": "기타 결제 수단", + "workspace.lite.promo.selectMethod": "결제 수단 선택", + + "workspace.referral.copyLink": "링크 복사", + "workspace.referral.copied": "복사됨", + "workspace.referral.overview.title": "친구 초대", + "workspace.referral.overview.subtitle": "친구가 구독하면 $5를 받으세요. 친구도 $5를 받습니다.", + "workspace.referral.instructions.share": "추천 링크 공유", + "workspace.referral.instructions.subscribe": "친구가 가입하고 Go를 구독", + "workspace.referral.instructions.claim": "두 분 모두 $5 사용 크레딧을 받아 Go 사용 한도에 적용할 수 있습니다", + "workspace.referral.rewards.title": "추천 보상", + "workspace.referral.rewards.description": "사용 가능한 추천 크레딧을 Go 사용량에 적용합니다.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}}개 보상 사용됨.", + "workspace.referral.rewards.empty": "아직 추천 보상이 없습니다.", + "workspace.referral.table.reward": "보상", + "workspace.referral.table.referral": "설명", + "workspace.referral.table.date": "날짜", + "workspace.referral.reward.description.inviter": "{{email}} 초대됨", + "workspace.referral.reward.description.invitee": "{{email}}님이 초대", + "workspace.referral.reward.action.subscribeUnlock": "구독하여 잠금 해제", + "workspace.referral.reward.action.view": "보상 보기", + "workspace.referral.reward.action.applied": "보상 사용됨", + "workspace.referral.reward.source.pendingInviter": "친구의 구독을 기다리는 중", + "workspace.referral.reward.source.pendingInvitee": "구독하여 보상 잠금 해제", + "workspace.referral.reward.source.available": "보상 사용 가능", + "workspace.referral.reward.source.applied": "보상 사용됨", + "workspace.referral.reward.status.applied": "보상 사용됨", + "workspace.referral.reward.status.pendingInviter": "구독하여 잠금 해제", + "workspace.referral.reward.status.pendingInvitee": "구독하여 잠금 해제", + "workspace.referral.apply.noGo": "구독하여 잠금 해제", + "workspace.referral.apply.preview": "보상 보기", + "workspace.referral.apply.action": "사용", + "workspace.referral.apply.confirmTitle": "보상 사용", + "workspace.referral.apply.confirmBody": "{{amount}}를 사용하여 이 워크스페이스의 현재 사용량을 줄입니다.", + "workspace.referral.apply.confirmAction": "사용", + + "download.title": "OpenCode | 다운로드", + "download.meta.description": "macOS, Windows, Linux용 OpenCode 다운로드", + "download.hero.title": "OpenCode 데스크톱 다운로드", + "download.hero.subtitle": "macOS, Windows, Linux용 베타 버전 사용 가능", + "download.hero.button": "{{os}}용 다운로드", + "download.section.terminal": "OpenCode 터미널", + "download.section.desktop": "OpenCode 데스크톱", + "download.section.extensions": "OpenCode 확장 프로그램", + "download.section.integrations": "OpenCode 통합", + "download.action.download": "다운로드", + "download.action.install": "설치", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "꼭 그렇지는 않지만, 아마도 필요할 것입니다. OpenCode를 유료 제공자에 연결하려면 AI 구독이 필요할 수 있습니다. 하지만", + "download.faq.a3.localLink": "로컬 모델", + "download.faq.a3.afterLocal.beforeZen": "은 무료로 사용할 수 있습니다. 우리는", + "download.faq.a3.afterZen": " 사용을 권장하지만, OpenCode는 OpenAI, Anthropic, xAI 등 모든 인기 제공자와 작동합니다.", + + "download.faq.a5.p1": "OpenCode는 100% 무료로 사용할 수 있습니다.", + "download.faq.a5.p2.beforeZen": + "추가 비용은 모델 제공자 구독에서 발생합니다. OpenCode는 모든 모델 제공자와 작동하지만, 우리는", + "download.faq.a5.p2.afterZen": " 사용을 권장합니다.", + + "download.faq.a6.p1": "데이터와 정보는 OpenCode에서 공유 링크를 생성할 때만 저장됩니다.", + "download.faq.a6.p2.beforeShare": "더 알아보기:", + "download.faq.a6.shareLink": "공유 페이지", + + "enterprise.title": "OpenCode | 조직을 위한 엔터프라이즈 솔루션", + "enterprise.meta.description": "OpenCode 엔터프라이즈 솔루션 문의", + "enterprise.hero.title": "여러분의 코드는 여러분의 것입니다", + "enterprise.hero.body1": + "OpenCode는 조직 내부에서 안전하게 작동하며, 데이터나 컨텍스트를 저장하지 않고 라이선스 제한이나 소유권 주장도 없습니다. 팀과 함께 트라이얼을 시작한 후, SSO 및 내부 AI 게이트웨이와 통합하여 조직 전체에 배포하세요.", + "enterprise.hero.body2": "어떻게 도와드릴 수 있는지 알려주세요.", + "enterprise.form.name.label": "이름", + "enterprise.form.name.placeholder": "홍길동", + "enterprise.form.role.label": "직책", + "enterprise.form.role.placeholder": "CTO / 개발 팀장", + "enterprise.form.company.label": "회사", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "회사 이메일", + "enterprise.form.email.placeholder": "name@company.com", + "enterprise.form.phone.label": "전화번호", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "어떤 문제를 해결하고 싶으신가요?", + "enterprise.form.message.placeholder": "도움이 필요한 부분은...", + "enterprise.form.send": "전송", + "enterprise.form.sending": "전송 중...", + "enterprise.form.success": "메시지가 전송되었습니다. 곧 연락드리겠습니다.", + "enterprise.form.success.submitted": "양식이 성공적으로 제출되었습니다.", + "enterprise.form.error.allFieldsRequired": "모든 필드는 필수 항목입니다.", + "enterprise.form.error.invalidEmailFormat": "유효하지 않은 이메일 형식입니다.", + "enterprise.form.error.internalServer": "내부 서버 오류입니다.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "OpenCode 엔터프라이즈란 무엇인가요?", + "enterprise.faq.a1": + "OpenCode 엔터프라이즈는 코드와 데이터가 인프라 외부로 유출되지 않도록 보장하려는 조직을 위한 솔루션입니다. SSO 및 내부 AI 게이트웨이와 통합되는 중앙 집중식 설정을 통해 이를 구현합니다.", + "enterprise.faq.q2": "OpenCode 엔터프라이즈는 어떻게 시작하나요?", + "enterprise.faq.a2": + "팀과 함께 내부 트라이얼로 간단히 시작해보세요. OpenCode는 기본적으로 코드나 컨텍스트 데이터를 저장하지 않아 시작하기 쉽습니다. 그 후 가격 및 구현 옵션에 대해 문의해주세요.", + "enterprise.faq.q3": "엔터프라이즈 가격은 어떻게 되나요?", + "enterprise.faq.a3": + "좌석(seat) 당 엔터프라이즈 가격을 제공합니다. 자체 LLM 게이트웨이를 보유한 경우, 사용된 토큰에 대해 비용을 청구하지 않습니다. 자세한 내용은 조직의 요구사항에 따른 맞춤 견적을 위해 문의해주세요.", + "enterprise.faq.q4": "OpenCode 엔터프라이즈에서 데이터는 안전한가요?", + "enterprise.faq.a4": + "네. OpenCode는 코드나 컨텍스트 데이터를 저장하지 않습니다. 모든 처리는 로컬에서 이루어지거나 AI 제공자에 대한 직접 API 호출을 통해 이루어집니다. 중앙 설정 및 SSO 통합을 통해 데이터는 조직의 인프라 내에서 안전하게 유지됩니다.", + + "brand.title": "OpenCode | 브랜드", + "brand.meta.description": "OpenCode 브랜드 가이드라인", + "brand.heading": "브랜드 가이드라인", + "brand.subtitle": "OpenCode 브랜드를 활용하는 데 도움이 되는 리소스와 자산입니다.", + "brand.downloadAll": "모든 자산 다운로드", + + "changelog.title": "OpenCode | 변경 내역", + "changelog.meta.description": "OpenCode 릴리스 노트 및 변경 내역", + "changelog.hero.title": "변경 내역", + "changelog.hero.subtitle": "OpenCode의 새로운 업데이트 및 개선 사항", + "changelog.empty": "변경 내역 항목을 찾을 수 없습니다.", + "changelog.viewJson": "JSON 보기", + + "bench.list.title": "벤치마크", + "bench.list.heading": "벤치마크", + "bench.list.table.agent": "에이전트", + "bench.list.table.model": "모델", + "bench.list.table.score": "점수", + "bench.submission.error.allFieldsRequired": "모든 필드는 필수 항목입니다.", + + "bench.detail.title": "벤치마크 - {{task}}", + "bench.detail.notFound": "태스크를 찾을 수 없음", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "에이전트", + "bench.detail.labels.model": "모델", + "bench.detail.labels.task": "태스크", + "bench.detail.labels.repo": "저장소", + "bench.detail.labels.from": "From", + "bench.detail.labels.to": "To", + "bench.detail.labels.prompt": "프롬프트", + "bench.detail.labels.commit": "커밋", + "bench.detail.labels.averageDuration": "평균 소요 시간", + "bench.detail.labels.averageScore": "평균 점수", + "bench.detail.labels.averageCost": "평균 비용", + "bench.detail.labels.summary": "요약", + "bench.detail.labels.runs": "실행 횟수", + "bench.detail.labels.score": "점수", + "bench.detail.labels.base": "기본", + "bench.detail.labels.penalty": "페널티", + "bench.detail.labels.weight": "가중치", + "bench.detail.table.run": "실행", + "bench.detail.table.score": "점수 (기본 - 페널티)", + "bench.detail.table.cost": "비용", + "bench.detail.table.duration": "소요 시간", + "bench.detail.run.title": "실행 {{n}}", + "bench.detail.rawJson": "Raw JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/no.ts b/packages/console/app/src/i18n/no.ts new file mode 100644 index 0000000000000000000000000000000000000000..fc2636a30057fa51439b1326e8b2d6d9a75ddf36 --- /dev/null +++ b/packages/console/app/src/i18n/no.ts @@ -0,0 +1,874 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash får 4x bruksgrense i en begrenset periode", + "go.graph.bonus": "{{count}}× bruk", + "nav.github": "GitHub", + "nav.docs": "Dokumentasjon", + "nav.changelog": "Endringslogg", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Logg inn", + "nav.free": "Last ned", + "nav.home": "Hjem", + "nav.openMenu": "Åpne meny", + "nav.getStartedFree": "Kom i gang gratis", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Kopier logo som SVG", + "nav.context.copyWordmark": "Kopier wordmark som SVG", + "nav.context.brandAssets": "Merkevareressurser", + + "footer.github": "GitHub", + "footer.docs": "Dokumentasjon", + "footer.changelog": "Endringslogg", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Merkevare", + "legal.privacy": "Personvern", + "legal.terms": "Vilkår", + + "email.title": "Få beskjed først når vi lanserer nye produkter", + "email.subtitle": "Meld deg på ventelisten for tidlig tilgang.", + "email.placeholder": "E-postadresse", + "email.subscribe": "Abonner", + "email.success": "Nesten ferdig - sjekk innboksen din og bekreft e-postadressen", + + "notFound.title": "Ikke funnet | opencode", + "notFound.heading": "404 - Side ikke funnet", + "notFound.home": "Hjem", + "notFound.docs": "Dokumentasjon", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode logo lys", + "notFound.logoDarkAlt": "opencode logo mørk", + + "user.logout": "Logg ut", + + "auth.callback.error.codeMissing": "Ingen autorisasjonskode funnet.", + + "workspace.select": "Velg arbeidsområde", + "workspace.createNew": "+ Opprett nytt arbeidsområde", + "workspace.modal.title": "Opprett nytt arbeidsområde", + "workspace.modal.placeholder": "Skriv inn navn på arbeidsområde", + + "common.cancel": "Avbryt", + "common.creating": "Oppretter...", + "common.create": "Opprett", + "common.contactUs": "Kontakt oss", + + "common.videoUnsupported": "Nettleseren din støtter ikke video-taggen.", + "common.figure": "Fig {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Les mer", + + "error.invalidPlan": "Ugyldig plan", + "error.workspaceRequired": "Arbeidsområde-ID er påkrevd", + "error.alreadySubscribed": "Dette arbeidsområdet har allerede et abonnement", + "error.limitRequired": "Grense er påkrevd.", + "error.monthlyLimitInvalid": "Angi en gyldig månedlig grense.", + "error.workspaceNameRequired": "Navn på arbeidsområde er påkrevd.", + "error.nameTooLong": "Navnet må være 255 tegn eller mindre.", + "error.emailRequired": "E-post er påkrevd", + "error.roleRequired": "Rolle er påkrevd", + "error.idRequired": "ID er påkrevd", + "error.nameRequired": "Navn er påkrevd", + "error.providerRequired": "Leverandør er påkrevd", + "error.apiKeyRequired": "API-nøkkel er påkrevd", + "error.modelRequired": "Modell er påkrevd", + "error.reloadAmountMin": "Påfyllingsbeløp må være minst ${{amount}}", + "error.reloadTriggerMin": "Saldo-trigger må være minst ${{amount}}", + + "app.meta.description": "OpenCode - Den åpne kildekode kodingsagenten.", + + "home.title": "OpenCode | Den åpne kildekode AI-kodingsagenten", + + "temp.title": "opencode | AI-kodingsagent bygget for terminalen", + "temp.hero.title": "AI-kodingsagenten bygget for terminalen", + "temp.zen": "opencode zen", + "temp.getStarted": "Kom i gang", + "temp.feature.native.title": "Native TUI", + "temp.feature.native.body": "Et responsivt, native terminal-brukergrensesnitt som kan temes", + "temp.feature.zen.beforeLink": "En", + "temp.feature.zen.link": "kuratert liste over modeller", + "temp.feature.zen.afterLink": "levert av opencode", + "temp.feature.models.beforeLink": "Støtter 75+ LLM-leverandører gjennom", + "temp.feature.models.afterLink": ", inkludert lokale modeller", + "temp.screenshot.caption": "opencode TUI med tokyonight-tema", + "temp.screenshot.alt": "opencode TUI med tokyonight-tema", + "temp.logoLightAlt": "opencode logo lys", + "temp.logoDarkAlt": "opencode logo mørk", + + "home.banner.badge": "Ny", + "home.banner.text": "Vi introduserer Tabs for Desktop.", + "home.banner.platforms": "Tilgjengelig på macOS, Windows og Linux", + "home.banner.downloadNow": "Last ned nå", + "home.banner.downloadBetaNow": "Last ned desktop-betaen nå", + "home.promo.title": "Vi introduserer Tabs for Desktop", + "home.promo.body": "Organiser arbeidet ditt og aktive økter med faner.", + "home.promo.cta": "Last ned den nyeste versjonen for å komme i gang.", + "home.promo.close": "Lukk kunngjøringen om Desktop-appen", + + "home.hero.title": "Den åpne kildekode AI-kodingsagenten", + "home.hero.subtitle.a": + "Gratis modeller inkludert, eller koble til hvilken som helst modell fra hvilken som helst leverandør,", + "home.hero.subtitle.b": "inkludert Claude, GPT, Gemini og mer.", + + "home.install.ariaLabel": "Installeringsalternativer", + + "home.what.title": "Hva er OpenCode?", + "home.what.body": "OpenCode er en åpen kildekode-agent som hjelper deg å skrive kode i terminal, IDE eller desktop.", + "home.what.lsp.title": "LSP aktivert", + "home.what.lsp.body": "Laster automatisk de riktige LSP-ene for LLM-en", + "home.what.multiSession.title": "Multi-sesjon", + "home.what.multiSession.body": "Start flere agenter parallelt på samme prosjekt", + "home.what.shareLinks.title": "Del lenker", + "home.what.shareLinks.body": "Del en lenke til en sesjon for referanse eller feilsøking", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Logg inn med GitHub for å bruke Copilot-kontoen din", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Logg inn med OpenAI for å bruke ChatGPT Plus- eller Pro-kontoen din", + "home.what.anyModel.title": "Hvilken som helst modell", + "home.what.anyModel.body": "75+ LLM-leverandører via Models.dev, inkludert lokale modeller", + "home.what.anyEditor.title": "Hvilken som helst editor", + "home.what.anyEditor.body": "Tilgjengelig som terminalgrensesnitt, desktop-app og IDE-utvidelse", + "home.what.readDocs": "Les dokumentasjonen", + + "home.growth.title": "Den åpne kildekode AI-kodingsagenten", + "home.growth.body": + "Med over {{stars}} GitHub-stjerner, {{contributors}} bidragsytere og over {{commits}} commits, brukes OpenCode av over {{monthlyUsers}} utviklere hver måned.", + "home.growth.githubStars": "GitHub-stjerner", + "home.growth.contributors": "Bidragsytere", + "home.growth.monthlyDevs": "Månedlige utviklere", + + "home.privacy.title": "Bygget med personvern først", + "home.privacy.body": + "OpenCode lagrer ikke koden din eller kontekstdata, slik at den kan fungere i personvernsensitive miljøer.", + "home.privacy.learnMore": "Les mer om", + "home.privacy.link": "personvern", + + "home.faq.q1": "Hva er OpenCode?", + "home.faq.a1": + "OpenCode er en åpen kildekode-agent som hjelper deg å skrive og kjøre kode med hvilken som helst AI-modell. Den er tilgjengelig som terminalgrensesnitt, desktop-app eller IDE-utvidelse.", + "home.faq.q2": "Hvordan bruker jeg OpenCode?", + "home.faq.a2.before": "Den enkleste måten å komme i gang på er å lese", + "home.faq.a2.link": "introen", + "home.faq.q3": "Trenger jeg ekstra AI-abonnementer for å bruke OpenCode?", + "home.faq.a3.p1": + "Ikke nødvendigvis. OpenCode kommer med et sett gratis modeller du kan bruke uten å opprette en konto.", + "home.faq.a3.p2.beforeZen": "I tillegg kan du bruke populære kodemodeller ved å opprette en", + "home.faq.a3.p2.afterZen": " konto.", + "home.faq.a3.p3": + "Vi oppfordrer til å bruke Zen, men OpenCode fungerer også med populære leverandører som OpenAI, Anthropic, xAI osv.", + "home.faq.a3.p4.beforeLocal": "Du kan til og med koble til dine", + "home.faq.a3.p4.localLink": "lokale modeller", + "home.faq.q4": "Kan jeg bruke mine eksisterende AI-abonnementer med OpenCode?", + "home.faq.a4.p1": + "Ja, OpenCode støtter abonnementer fra alle store leverandører. Du kan bruke Claude Pro/Max, ChatGPT Plus/Pro eller GitHub Copilot-abonnementer.", + "home.faq.q5": "Kan jeg bare bruke OpenCode i terminalen?", + "home.faq.a5.beforeDesktop": "Ikke lenger! OpenCode er nå tilgjengelig som en app for", + "home.faq.a5.desktop": "desktop", + "home.faq.a5.and": "og", + "home.faq.a5.web": "web", + "home.faq.q6": "Hva koster OpenCode?", + "home.faq.a6": + "OpenCode er 100% gratis å bruke. Det kommer også med et sett gratis modeller. Det kan være ekstra kostnader hvis du kobler til en annen leverandør.", + "home.faq.q7": "Hva med data og personvern?", + "home.faq.a7.p1": "Dataene dine lagres kun når du bruker våre gratis modeller eller lager delbare lenker.", + "home.faq.a7.p2.beforeModels": "Les mer om", + "home.faq.a7.p2.modelsLink": "våre modeller", + "home.faq.a7.p2.and": "og", + "home.faq.a7.p2.shareLink": "delingssider", + "home.faq.q8": "Er OpenCode åpen kildekode?", + "home.faq.a8.p1": "Ja, OpenCode er fullt open source. Kildekoden er offentlig på", + "home.faq.a8.p2": "under", + "home.faq.a8.mitLicense": "MIT-lisensen", + "home.faq.a8.p3": + ", som betyr at hvem som helst kan bruke, endre eller bidra til utviklingen. Alle i communityet kan opprette issues, sende inn pull requests og utvide funksjonalitet.", + + "home.zenCta.title": "Få tilgang til pålitelige, optimaliserte modeller for kodeagenter", + "home.zenCta.body": + "Zen gir deg tilgang til et håndplukket sett med AI-modeller som OpenCode har testet og benchmarked spesielt for kodeagenter. Du slipper å bekymre deg for ujevn ytelse og kvalitet på tvers av leverandører; bruk validerte modeller som fungerer.", + "home.zenCta.link": "Les om Zen", + + "zen.title": "OpenCode Zen | Et kuratert sett med pålitelige, optimaliserte modeller for kodeagenter", + "zen.hero.title": "Pålitelige optimaliserte modeller for kodeagenter", + "zen.hero.body": + "Zen gir deg tilgang til et kuratert sett med AI-modeller som OpenCode har testet og benchmarked spesielt for kodeagenter. Du slipper å bekymre deg for ujevn ytelse og kvalitet; bruk validerte modeller som fungerer.", + + "zen.faq.q1": "Hva er OpenCode Zen?", + "zen.faq.a1": + "Zen er et kuratert sett med AI-modeller testet og benchmarked for kodeagenter, laget av teamet bak OpenCode.", + "zen.faq.q2": "Hva gjør Zen mer presis?", + "zen.faq.a2": + "Zen tilbyr bare modeller som er testet og benchmarked spesifikt for kodeagenter. Du ville ikke brukt en smørkniv til å skjære biff; ikke bruk dårlige modeller til koding.", + "zen.faq.q3": "Er Zen billigere?", + "zen.faq.a3": + "Zen er ikke for profitt. Zen videreformidler kostnadene fra modellleverandørene direkte til deg. Jo mer Zen brukes, desto bedre priser kan OpenCode forhandle og gi videre til deg.", + "zen.faq.q4": "Hva koster Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "tar betalt per forespørsel", + "zen.faq.a4.p1.afterPricing": "uten påslag, så du betaler akkurat det modellleverandøren tar betalt.", + "zen.faq.a4.p2.beforeAccount": "Totalprisen avhenger av bruk, og du kan sette månedlige utgiftsgrenser i din", + "zen.faq.a4.p2.accountLink": "konto", + "zen.faq.a4.p3": + "For å dekke kostnader legger OpenCode til bare et lite betalingsbehandlingsgebyr på $1.23 per $20 saldo-påfyll.", + "zen.faq.q5": "Hva med data og personvern?", + "zen.faq.a5.beforeExceptions": + "Alle Zen-modeller hostes i USA. Leverandører følger en policy om null oppbevaring og bruker ikke dataene dine til modelltrening, med de", + "zen.faq.a5.exceptionsLink": "følgende unntakene", + "zen.faq.q6": "Kan jeg sette utgiftsgrenser?", + "zen.faq.a6": "Ja, du kan sette månedlige utgiftsgrenser i kontoen din.", + "zen.faq.q7": "Kan jeg avslutte?", + "zen.faq.a7": "Ja, du kan deaktivere fakturering når som helst og bruke gjenværende saldo.", + "zen.faq.q8": "Kan jeg bruke Zen med andre kodeagenter?", + "zen.faq.a8": + "Selv om Zen fungerer veldig bra med OpenCode, kan du bruke Zen med hvilken som helst agent. Følg oppsettinstruksjonene i din foretrukne kodeagent.", + "zen.faq.q9": "Kan jeg få refusjon?", + "zen.faq.a9": + "Du kan ha rett på refusjon hvis belastningen ble gjort i løpet av de siste 14 dagene og du ikke har brukt noe av kreditten fra kjøpet. {{contact}} for å be om refusjon.", + + "zen.cta.start": "Kom i gang med Zen", + "zen.pricing.title": "Legg til $20 Pay as you go-saldo", + "zen.pricing.fee": "(+$1.23 kortbehandlingsgebyr)", + "zen.pricing.body": "Bruk med hvilken som helst agent. Angi månedlige forbruksgrenser. Avslutt når som helst.", + "zen.problem.title": "Hvilket problem løser Zen?", + "zen.problem.body": + "Det er så mange modeller tilgjengelig, men bare noen få fungerer bra med kodeagenter. De fleste leverandører konfigurerer dem annerledes med varierende resultater.", + "zen.problem.subtitle": "Vi fikser dette for alle, ikke bare OpenCode-brukere.", + "zen.problem.item1": "Tester utvalgte modeller og konsulterer teamene deres", + "zen.problem.item2": "Samarbeider med leverandører for å sikre at de blir levert riktig", + "zen.problem.item3": "Benchmarker alle modell-leverandør-kombinasjoner vi anbefaler", + "zen.how.title": "Hvordan Zen fungerer", + "zen.how.body": "Selv om vi foreslår at du bruker Zen med OpenCode, kan du bruke Zen med hvilken som helst agent.", + "zen.how.step1.title": "Registrer deg og legg til $20 saldo", + "zen.how.step1.beforeLink": "følg", + "zen.how.step1.link": "oppsettsinstruksjonene", + "zen.how.step2.title": "Bruk Zen med transparente priser", + "zen.how.step2.link": "betal per forespørsel", + "zen.how.step2.afterLink": "uten påslag", + "zen.how.step3.title": "Auto-påfyll", + "zen.how.step3.body": "når saldoen din når $5, fyller vi automatisk på $20", + "zen.privacy.title": "Personvernet ditt er viktig for oss", + "zen.privacy.beforeExceptions": + "Alle Zen-modeller hostes i USA. Leverandører følger en policy om null oppbevaring og bruker ikke dataene dine til modelltrening, med", + "zen.privacy.exceptionsLink": "følgende unntak", + + "go.title": "OpenCode Go | Rimelige kodemodeller for alle", + "go.meta.description": + "Go koster $10/måned, med sjenerøse bruksgrenser og pålitelig tilgang til ledende kodemodeller.", + "go.hero.title": "Rimelige kodemodeller for alle", + "go.hero.body": + "Go bringer agent-koding til programmerere over hele verden. Med rause grenser og pålitelig tilgang til de mest kapable åpen kildekode-modellene, kan du bygge med kraftige agenter uten å bekymre deg for kostnader eller tilgjengelighet.", + + "go.cta.start": "Abonner på Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Abonner på Go", + "go.cta.price": "$10/måned", + "go.pricing.body": "Bruk med hvilken som helst agent. $10/måned. Fyll på kreditt ved behov. Avslutt når som helst.", + "go.graph.free": "Gratis", + "go.graph.freePill": "Big Pickle og gratis modeller", + "go.graph.go": "Go", + "go.graph.label": "Forespørsler per 5 timer", + "go.graph.period": "Bruk", + "go.graph.model": "Modell", + "go.graph.requests": "Estimerte forespørsler / 5 timer", + "go.graph.allowance": "Månedlig bruk", + "go.graph.new": "Ny", + "go.graph.scale": "Ikke-lineær skala for forespørsler", + "go.graph.showAll": "Vis alle {{count}} modeller", + "go.graph.showLess": "Vis færre modeller", + "go.graph.limitedRegions": "begrensede regioner", + "go.graph.limitedTime": "begrenset periode", + "go.graph.usageLimits": "Bruksgrenser", + "go.graph.aria": "Forespørsler per 5t: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "tidligere CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "har endret livet mitt, det er virkelig en no-brainer.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "tidligere grunnlegger, SEED, PM, Melt, Pop, Dapt, Cadmus og ViewPoint", + "go.testimonials.jay.quoteBefore": "4 av 5 personer på teamet vårt elsker å bruke", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "tidligere Hero, AWS", + "go.testimonials.adam.quoteBefore": "Jeg kan ikke anbefale", + "go.testimonials.adam.quoteAfter": "nok. Seriøst, det er virkelig bra.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "tidligere Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "Med", + "go.testimonials.david.quoteAfter": "vet jeg at alle modellene er testet og perfekte for kodeagenter.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "tidligere intern, Nvidia (4 ganger)", + "go.testimonials.frank.quote": "Jeg skulle ønske jeg fortsatt var hos Nvidia.", + "go.problem.title": "Hvilket problem løser Go?", + "go.problem.body": + "Vi fokuserer på å bringe OpenCode-opplevelsen til så mange som mulig. OpenCode Go er et rimelig abonnement til $10/måned. Det gir sjenerøse grenser og pålitelig tilgang til de mest kapable åpen kildekode-modellene.", + "go.problem.subtitle": " ", + "go.problem.item1": "Rimelig abonnementspris", + "go.problem.item2": "Rause grenser og pålitelig tilgang", + "go.problem.item3": "Bygget for så mange programmerere som mulig", + "go.problem.item4": "Et kuratert modellutvalg testet for agent-koding", + "go.how.title": "Hvordan Go fungerer", + "go.how.body": "Go koster $10/måned. Du kan bruke det med OpenCode eller hvilken som helst agent.", + "go.how.step1.title": "Opprett en konto", + "go.how.step1.beforeLink": "følg", + "go.how.step1.link": "oppsettsinstruksjonene", + "go.how.step2.title": "Abonner på Go", + "go.how.step2.link": "$10/måned", + "go.how.step2.afterLink": "med sjenerøse grenser", + "go.how.step3.title": "Begynn å kode", + "go.how.step3.body": "med pålitelig tilgang til åpen kildekode-modeller", + "go.privacy.title": "Personvernet ditt er viktig for oss", + "go.privacy.body": + "Planen er primært designet for internasjonale brukere, med modeller driftet i USA, EU og Singapore for stabil global tilgang.", + "go.privacy.contactAfter": "hvis du har spørsmål.", + "go.privacy.beforeExceptions": + "Go-modeller hostes i USA. Leverandører følger en policy om null oppbevaring og bruker ikke dataene dine til modelltrening, med", + "go.privacy.exceptionsLink": "følgende unntak", + "go.faq.q1": "Hva er OpenCode Go?", + "go.faq.a1": + "Go er et rimelig abonnement som gir deg pålitelig tilgang til kapable åpen kildekode-modeller for agent-koding.", + "go.faq.q2": "Hvilke modeller inkluderer Go?", + "go.faq.a2": "Go inkluderer modellene nedenfor, med høye grenser og pålitelig tilgang.", + "go.faq.q3": "Er Go det samme som Zen?", + "go.faq.a3": + "Nei. Zen er betaling etter bruk, mens Go koster $10/måned, med sjenerøse grenser og pålitelig tilgang til et kuratert modellutvalg.", + "go.faq.q4": "Hva koster Go?", + "go.faq.a4.p1.beforePricing": "Go koster", + "go.faq.a4.p1.pricingLink": "$10/måned", + "go.faq.a4.p1.afterPricing": "med sjenerøse grenser.", + "go.faq.a4.p2.beforeAccount": "Du kan administrere abonnementet ditt i din", + "go.faq.a4.p2.accountLink": "konto", + "go.faq.a4.p3": "Avslutt når som helst.", + "go.faq.q5": "Hva med data og personvern?", + "go.faq.a5.model": "Modell", + "go.faq.a5.training": "Modelltrening", + "go.faq.a5.retention": "Dataoppbevaring", + "go.faq.a5.retention30": "30 dager", + "go.faq.a5.retention0": "0 dager", + "go.faq.a5.used": "Brukes", + "go.faq.a5.notUsed": "Brukes ikke", + "go.faq.a5.noAgreement": "Ingen avtale", + "go.faq.a5.notZdr": "Ikke ZDR", + "go.faq.a5.grokRetention": + "ZDR deaktiverer viktige API-funksjoner som er avhengige av lagrede data, inkludert den tilstandsbaserte Responses API, Files and Collections og Batch API.", + "go.faq.a5.gptRetention": + "Logger for overvåking av misbruk genereres for all bruk av API-funksjoner og oppbevares i opptil 30 dager.", + "go.faq.a5.learnMore": "Les mer", + "go.faq.a5.deepseekRetention": + "ZDR-avtalen fornyes månedlig. Den gjeldende avtalen er gyldig til og med 30. september 2026.", + "go.faq.a5.museRetention": + "Kraftig rabatterte tokenpriser i bytte mot tillatelse til å bruke ledetekstene og fullføringene dine til å trene fremtidige Meta-modeller.", + + "go.faq.a5.beforeExceptions": + "Go-modeller hostes i USA. Leverandører følger en policy om null oppbevaring og bruker ikke dataene dine til modelltrening, med", + "go.faq.a5.exceptionsLink": "følgende unntak", + "go.faq.q6": "Kan jeg fylle på kreditt?", + "go.faq.a6": "Hvis du trenger mer bruk, kan du fylle på kreditt i kontoen din.", + "go.faq.q7": "Kan jeg avslutte?", + "go.faq.a7": "Ja, du kan avslutte når som helst.", + "go.faq.q8": "Kan jeg bruke Go med andre kodeagenter?", + "go.faq.a8": + "Ja, du kan bruke Go med hvilken som helst agent. Følg oppsettinstruksjonene i din foretrukne kodeagent.", + + "go.faq.q9": "Hva er forskjellen mellom gratis modeller og Go?", + "go.faq.a9": + "Gratis modeller inkluderer Big Pickle pluss kampanjemodeller som er tilgjengelige på det tidspunktet, med en kvote på 200 forespørsler/dag. Go tilbyr et kuratert modellutvalg med høyere forespørselskvoter som håndheves over rullerende vinduer (5 timer, ukentlig og månedlig), omtrent tilsvarende basiskvoter på $12 per 5 timer, $30 per uke og $60 per måned; modellspesifikke kvoter kan variere (faktiske forespørselsantall varierer etter modell og bruk).", + "go.faq.q10": "Kan jeg få refusjon?", + "go.faq.a10": + "Du kan ha rett på refusjon hvis belastningen ble gjort i løpet av de siste 14 dagene og du ikke har brukt noe av Go-kvoten i den faktureringsperioden. {{contact}} for å be om refusjon.", + + "zen.api.error.rateLimitExceeded": "Rate limit overskredet. Vennligst prøv igjen senere.", + "zen.api.error.modelNotSupported": "Modell {{model}} støttes ikke", + "zen.api.error.modelFormatNotSupported": "Modell {{model}} støttes ikke for format {{format}}", + "zen.api.error.noProviderAvailable": "Ingen leverandør tilgjengelig", + "zen.api.error.providerNotSupported": "Leverandør {{provider}} støttes ikke", + "zen.api.error.missingApiKey": "Mangler API-nøkkel.", + "zen.api.error.invalidApiKey": "Ugyldig API-nøkkel.", + "zen.api.error.requestBlockedByUpstreamProvider": "Forespørselen ble blokkert av leverandøren.", + "zen.api.error.subscriptionQuotaExceeded": "Abonnementskvote overskredet. Prøv igjen om {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "5-timers bruksgrense nådd. Tilbakestilles om {{retryIn}}. For å fortsette å bruke denne modellen nå, aktiver bruk fra din tilgjengelige saldo: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Ukentlig bruksgrense nådd. Tilbakestilles om {{retryIn}}. For å fortsette å bruke denne modellen nå, aktiver bruk fra din tilgjengelige saldo: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Månedlig bruksgrense nådd. Tilbakestilles om {{retryIn}}. For å fortsette å bruke denne modellen nå, aktiver bruk fra din tilgjengelige saldo: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Ingen betalingsmetode. Legg til en betalingsmetode her: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Utilstrekkelig saldo. Administrer faktureringen din her: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Arbeidsområdet ditt har nådd sin månedlige utgiftsgrense på ${{amount}}. Administrer grensene dine her: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Du har nådd din månedlige utgiftsgrense på ${{amount}}. Administrer grensene dine her: {{membersUrl}}", + "zen.api.error.modelDisabled": "Modellen er deaktivert", + "zen.api.error.regionNotAllowed": + "Den nyeste versjonen av denne modellen er bare tilgjengelig som en tjeneste driftet i Kina og krever at du uttrykkelig samtykker: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Denne modellen er ikke tilgjengelig i landet ditt.", + "zen.api.error.trainingNotAllowed": + "Denne modellen samler inn data som brukes til å forbedre modellens kvalitet, og krever at du uttrykkelig samtykker: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "Den gratis kampanjen for {{model}} er avsluttet. Du kan fortsette å bruke modellen ved å abonnere på OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Få tilgang til verdens beste kodemodeller", + "black.meta.description": "Få tilgang til Claude, GPT, Gemini og mer med OpenCode Black-abonnementer.", + "black.hero.title": "Få tilgang til verdens beste kodemodeller", + "black.hero.subtitle": "Inkludert Claude, GPT, Gemini og mer", + "black.title": "OpenCode Black | Priser", + "black.paused": "Black-planregistrering er midlertidig satt på pause.", + "black.plan.icon20": "Black 20-plan", + "black.plan.icon100": "Black 100-plan", + "black.plan.icon200": "Black 200-plan", + "black.plan.multiplier100": "5x mer bruk enn Black 20", + "black.plan.multiplier200": "20x mer bruk enn Black 20", + "black.price.perMonth": "per måned", + "black.price.perPersonBilledMonthly": "per person fakturert månedlig", + "black.terms.1": "Abonnementet ditt starter ikke umiddelbart", + "black.terms.2": "Du blir lagt til i ventelisten og aktivert snart", + "black.terms.3": "Kortet ditt belastes kun når abonnementet aktiveres", + "black.terms.4": "Bruksgrenser gjelder, tung automatisert bruk kan nå grensene raskere", + "black.terms.5": "Abonnementer er for enkeltpersoner, kontakt Enterprise for team", + "black.terms.6": "Grenser kan justeres og planer kan avvikles i fremtiden", + "black.terms.7": "Avslutt abonnementet når som helst", + "black.action.continue": "Fortsett", + "black.finePrint.beforeTerms": "Priser vist inkluderer ikke gjeldende skatt", + "black.finePrint.terms": "Vilkår for bruk", + "black.workspace.title": "OpenCode Black | Velg arbeidsområde", + "black.workspace.selectPlan": "Velg et arbeidsområde for denne planen", + "black.workspace.name": "Arbeidsområde {{n}}", + "black.subscribe.title": "Abonner på OpenCode Black", + "black.subscribe.paymentMethod": "Betalingsmetode", + "black.subscribe.loadingPaymentForm": "Laster betalingsskjema...", + "black.subscribe.selectWorkspaceToContinue": "Velg et arbeidsområde for å fortsette", + "black.subscribe.failurePrefix": "Å nei!", + "black.subscribe.error.generic": "Det oppstod en feil", + "black.subscribe.error.invalidPlan": "Ugyldig plan", + "black.subscribe.error.workspaceRequired": "Arbeidsområde-ID er påkrevd", + "black.subscribe.error.alreadySubscribed": "Dette arbeidsområdet har allerede et abonnement", + "black.subscribe.processing": "Behandler...", + "black.subscribe.submit": "Abonner ${{plan}}", + "black.subscribe.form.chargeNotice": "Du blir kun belastet når abonnementet ditt aktiveres", + "black.subscribe.success.title": "Du er på ventelisten for OpenCode Black", + "black.subscribe.success.subscriptionPlan": "Abonnementsplan", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Beløp", + "black.subscribe.success.amountValue": "${{plan}} per måned", + "black.subscribe.success.paymentMethod": "Betalingsmetode", + "black.subscribe.success.dateJoined": "Dato meldt på", + "black.subscribe.success.chargeNotice": "Kortet ditt vil bli belastet når abonnementet aktiveres", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Bruk", + "workspace.nav.apiKeys": "API-nøkler", + "workspace.nav.members": "Medlemmer", + "workspace.nav.billing": "Fakturering", + "workspace.nav.settings": "Innstillinger", + + "workspace.home.banner.beforeLink": "Pålitelige optimaliserte modeller for kodeagenter.", + "workspace.lite.banner.beforeLink": "Lavkost kodemodeller for alle.", + "workspace.home.billing.loading": "Laster...", + "workspace.home.billing.enable": "Aktiver fakturering", + "workspace.home.billing.currentBalance": "Gjeldende saldo", + + "workspace.newUser.feature.tested.title": "Testede og verifiserte modeller", + "workspace.newUser.feature.tested.body": + "Vi har benchmarked og testet modeller spesifikt for kodeagenter for å sikre best mulig ytelse.", + "workspace.newUser.feature.quality.title": "Høyeste kvalitet", + "workspace.newUser.feature.quality.body": + "Få tilgang til modeller konfigurert for optimal ytelse – ingen nedgraderinger eller ruting til billigere leverandører.", + "workspace.newUser.feature.lockin.title": "Ingen innlåsing", + "workspace.newUser.feature.lockin.body": + "Bruk Zen med hvilken som helst kodeagent, og fortsett å bruke andre leverandører med opencode når du vil.", + "workspace.newUser.copyApiKey": "Kopier API-nøkkel", + "workspace.newUser.copyKey": "Kopier nøkkel", + "workspace.newUser.copied": "Kopiert!", + "workspace.newUser.step.enableBilling": "Aktiver fakturering", + "workspace.newUser.step.login.before": "Kjør", + "workspace.newUser.step.login.after": "og velg opencode", + "workspace.newUser.step.pasteKey": "Lim inn API-nøkkelen", + "workspace.newUser.step.models.before": "Start opencode og kjør", + "workspace.newUser.step.models.after": "for å velge en modell", + + "workspace.models.title": "Modeller", + "workspace.models.subtitle.beforeLink": "Administrer hvilke modeller medlemmene i arbeidsområdet har tilgang til.", + "workspace.models.table.model": "Modell", + "workspace.models.table.enabled": "Aktivert", + + "workspace.providers.title": "Ta med din egen nøkkel", + "workspace.providers.subtitle": "Konfigurer dine egne API-nøkler fra AI-leverandører.", + "workspace.providers.placeholder": "Skriv inn {{provider}} API-nøkkel ({{prefix}}...)", + "workspace.providers.configure": "Konfigurer", + "workspace.providers.edit": "Rediger", + "workspace.providers.delete": "Slett", + "workspace.providers.saving": "Lagrer...", + "workspace.providers.save": "Lagre", + "workspace.providers.table.provider": "Leverandør", + "workspace.providers.table.apiKey": "API-nøkkel", + + "workspace.usage.title": "Brukshistorikk", + "workspace.usage.subtitle": "Nylig API-bruk og kostnader.", + "workspace.usage.empty": "Gjør ditt første API-kall for å komme i gang.", + "workspace.usage.table.date": "Dato", + "workspace.usage.table.model": "Modell", + "workspace.usage.table.input": "Input", + "workspace.usage.table.output": "Output", + "workspace.usage.table.cost": "Kostnad", + "workspace.usage.table.session": "Økt", + "workspace.usage.breakdown.input": "Input", + "workspace.usage.breakdown.cacheRead": "Cache Lest", + "workspace.usage.breakdown.cacheWrite": "Cache Skrevet", + "workspace.usage.breakdown.output": "Output", + "workspace.usage.breakdown.reasoning": "Resonnering", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Kostnad", + "workspace.cost.subtitle": "Brukskostnader fordelt på modell.", + "workspace.cost.allModels": "Alle modeller", + "workspace.cost.allKeys": "Alle nøkler", + "workspace.cost.deletedSuffix": "(slettet)", + "workspace.cost.empty": "Ingen bruksdata tilgjengelig for den valgte perioden.", + "workspace.cost.subscriptionShort": "sub", + + "workspace.keys.title": "API-nøkler", + "workspace.keys.subtitle": "Administrer API-nøklene dine for å få tilgang til opencode-tjenester.", + "workspace.keys.create": "Opprett API-nøkkel", + "workspace.keys.placeholder": "Skriv inn navn på nøkkel", + "workspace.keys.empty": "Opprett en opencode Gateway API-nøkkel", + "workspace.keys.table.name": "Navn", + "workspace.keys.table.key": "Nøkkel", + "workspace.keys.table.createdBy": "Opprettet av", + "workspace.keys.table.lastUsed": "Sist brukt", + "workspace.keys.copyApiKey": "Kopier API-nøkkel", + "workspace.keys.delete": "Slett", + + "workspace.members.title": "Medlemmer", + "workspace.members.subtitle": "Administrer medlemmer i arbeidsområdet og deres tillatelser.", + "workspace.members.invite": "Inviter medlem", + "workspace.members.inviting": "Inviterer...", + "workspace.members.beta.beforeLink": "Arbeidsområder er gratis for team i beta-perioden.", + "workspace.members.form.invitee": "Invitert", + "workspace.members.form.emailPlaceholder": "Skriv inn e-post", + "workspace.members.form.role": "Rolle", + "workspace.members.form.monthlyLimit": "Månedlig utgiftsgrense", + "workspace.members.noLimit": "Ingen grense", + "workspace.members.noLimitLowercase": "ingen grense", + "workspace.members.invited": "invitert", + "workspace.members.edit": "Rediger", + "workspace.members.delete": "Slett", + "workspace.members.saving": "Lagrer...", + "workspace.members.save": "Lagre", + "workspace.members.table.email": "E-post", + "workspace.members.table.role": "Rolle", + "workspace.members.table.monthLimit": "Månedsgrense", + "workspace.members.role.admin": "Admin", + "workspace.members.role.adminDescription": "Kan administrere modeller, medlemmer og fakturering", + "workspace.members.role.member": "Medlem", + "workspace.members.role.memberDescription": "Kan kun generere API-nøkler for seg selv", + + "workspace.settings.title": "Innstillinger", + "workspace.settings.subtitle": "Oppdater arbeidsområdets navn og preferanser.", + "workspace.settings.workspaceName": "Navn på arbeidsområde", + "workspace.settings.defaultName": "Standard", + "workspace.settings.updating": "Oppdaterer...", + "workspace.settings.save": "Lagre", + "workspace.settings.edit": "Rediger", + + "workspace.billing.title": "Fakturering", + "workspace.billing.subtitle.beforeLink": "Administrer betalingsmetoder.", + "workspace.billing.contactUs": "Kontakt oss", + "workspace.billing.subtitle.afterLink": "hvis du har spørsmål.", + "workspace.billing.currentBalance": "Gjeldende saldo", + "workspace.billing.add": "Legg til $", + "workspace.billing.enterAmount": "Angi beløp", + "workspace.billing.loading": "Laster...", + "workspace.billing.addAction": "Legg til", + "workspace.billing.addBalance": "Legg til saldo", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Koblet til Stripe", + "workspace.billing.manage": "Administrer", + "workspace.billing.enable": "Aktiver fakturering", + + "workspace.monthlyLimit.title": "Månedlig grense", + "workspace.monthlyLimit.subtitle": "Angi en månedlig bruksgrense for kontoen din.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Angir...", + "workspace.monthlyLimit.set": "Sett", + "workspace.monthlyLimit.edit": "Rediger grense", + "workspace.monthlyLimit.noLimit": "Ingen bruksgrense satt.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Gjeldende forbruk for", + "workspace.monthlyLimit.currentUsage.beforeAmount": "er $", + + "workspace.redeem.title": "Løs inn kupong", + "workspace.redeem.subtitle": "Løs inn en kupongkode for å få kreditt eller fordeler.", + "workspace.redeem.placeholder": "Skriv inn kupongkode", + "workspace.redeem.redeem": "Løs inn", + "workspace.redeem.redeeming": "Løser inn...", + "workspace.redeem.success": "Kupongen ble løst inn.", + + "workspace.reload.title": "Auto-påfyll", + "workspace.reload.disabled.before": "Auto-påfyll er", + "workspace.reload.disabled.state": "deaktivert", + "workspace.reload.disabled.after": "Aktiver for å fylle på automatisk når saldoen er lav.", + "workspace.reload.enabled.before": "Auto-påfyll er", + "workspace.reload.enabled.state": "aktivert", + "workspace.reload.enabled.middle": "Vi fyller på", + "workspace.reload.processingFee": "behandlingsgebyr", + "workspace.reload.enabled.after": "når saldoen når", + "workspace.reload.edit": "Rediger", + "workspace.reload.enable": "Aktiver", + "workspace.reload.enableAutoReload": "Aktiver Auto-påfyll", + "workspace.reload.reloadAmount": "Fyll på $", + "workspace.reload.whenBalanceReaches": "Når saldoen når $", + "workspace.reload.saving": "Lagrer...", + "workspace.reload.save": "Lagre", + "workspace.reload.failedAt": "Påfylling mislyktes kl", + "workspace.reload.reason": "Årsak:", + "workspace.reload.updatePaymentMethod": "Vennligst oppdater betalingsmetoden din og prøv på nytt.", + "workspace.reload.retrying": "Prøver på nytt...", + "workspace.reload.retry": "Prøv på nytt", + "workspace.reload.error.paymentFailed": "Betaling mislyktes.", + + "workspace.payments.title": "Betalingshistorikk", + "workspace.payments.subtitle": "Nylige betalingstransaksjoner.", + "workspace.payments.table.date": "Dato", + "workspace.payments.table.paymentId": "Betalings-ID", + "workspace.payments.table.amount": "Beløp", + "workspace.payments.table.receipt": "Kvittering", + "workspace.payments.type.credit": "kreditt", + "workspace.payments.type.subscription": "abonnement", + "workspace.payments.view": "Vis", + + "workspace.black.loading": "Laster...", + "workspace.black.time.day": "dag", + "workspace.black.time.days": "dager", + "workspace.black.time.hour": "time", + "workspace.black.time.hours": "timer", + "workspace.black.time.minute": "minutt", + "workspace.black.time.minutes": "minutter", + "workspace.black.time.fewSeconds": "noen få sekunder", + "workspace.black.subscription.title": "Abonnement", + "workspace.black.subscription.message": "Du abonnerer på OpenCode Black for ${{plan}} per måned.", + "workspace.black.subscription.manage": "Administrer abonnement", + "workspace.black.subscription.rollingUsage": "5-timers bruk", + "workspace.black.subscription.weeklyUsage": "Ukentlig bruk", + "workspace.black.subscription.resetsIn": "Nullstilles om", + "workspace.black.subscription.useBalance": "Bruk din tilgjengelige saldo etter å ha nådd bruksgrensene", + "workspace.black.waitlist.title": "Venteliste", + "workspace.black.waitlist.joined": "Du står på venteliste for OpenCode Black-planen til ${{plan}} per måned.", + "workspace.black.waitlist.ready": "Vi er klare til å melde deg på OpenCode Black-planen til ${{plan}} per måned.", + "workspace.black.waitlist.leave": "Forlat venteliste", + "workspace.black.waitlist.leaving": "Forlater...", + "workspace.black.waitlist.left": "Forlot", + "workspace.black.waitlist.enroll": "Meld på", + "workspace.black.waitlist.enrolling": "Melder på...", + "workspace.black.waitlist.enrolled": "Påmeldt", + "workspace.black.waitlist.enrollNote": + "Når du klikker på Meld på, starter abonnementet umiddelbart og kortet ditt belastes.", + + "workspace.lite.loading": "Laster...", + "workspace.lite.time.day": "dag", + "workspace.lite.time.days": "dager", + "workspace.lite.time.hour": "time", + "workspace.lite.time.hours": "timer", + "workspace.lite.time.minute": "minutt", + "workspace.lite.time.minutes": "minutter", + "workspace.lite.time.fewSeconds": "noen få sekunder", + "workspace.lite.subscription.message": "Du abonnerer på OpenCode Go.", + "workspace.lite.subscription.manage": "Administrer abonnement", + "workspace.lite.subscription.rollingUsage": "5-timers bruk", + "workspace.lite.subscription.rollingQuota": "5-timers kvote", + "workspace.lite.subscription.weeklyUsage": "Ukentlig bruk", + "workspace.lite.subscription.weeklyQuota": "Ukentlig kvote", + "workspace.lite.subscription.monthlyUsage": "Månedlig bruk", + "workspace.lite.subscription.monthlyQuota": "Månedlig kvote", + "workspace.lite.subscription.resetsIn": "Nullstilles om", + "workspace.lite.subscription.showDetails": "Vis detaljer", + "workspace.lite.subscription.hideDetails": "Skjul detaljer", + "workspace.lite.subscription.model": "Modell", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Totalt", + "workspace.lite.subscription.useBalance": "Bruk din tilgjengelige saldo etter å ha nådd bruksgrensene", + "workspace.lite.subscription.selectProvider": + 'Velg "OpenCode Go" som leverandør i opencode-konfigurasjonen din for å bruke Go-modeller.', + "workspace.lite.providers.title": "Leverandører", + "workspace.lite.providers.description": "Kontroller hvilke leverandører som brukes til ruting.", + "workspace.lite.providers.allowTraining": "Tillat modeller som trener på forespørselsdata", + "workspace.lite.providers.useChina": "Aktiver modeller hostet i Kina", + "workspace.lite.black.message": + "Du abonnerer for øyeblikket på OpenCode Black eller står på venteliste. Vennligst avslutt abonnementet først hvis du vil bytte til Go.", + "workspace.lite.other.message": + "Et annet medlem i dette arbeidsområdet abonnerer allerede på OpenCode Go. Kun ett medlem per arbeidsområde kan abonnere.", + "workspace.lite.promo.description": + "OpenCode Go koster {{price}} og gir pålitelig tilgang til populære åpne kodingsmodeller med sjenerøse bruksgrenser.", + "workspace.lite.promo.price": "$10/måned", + "workspace.lite.promo.modelsTitle": "Hva som er inkludert", + "workspace.lite.promo.footer": + "Planen er primært utviklet for internasjonale brukere og gir stabil global tilgang. Priser og bruksgrenser kan endres etter hvert som vi lærer av tidlig bruk og tilbakemeldinger.", + "workspace.lite.promo.subscribe": "Abonner på Go", + "workspace.lite.promo.subscribing": "Omdirigerer...", + "workspace.lite.promo.otherMethods": "Andre betalingsmetoder", + "workspace.lite.promo.selectMethod": "Velg betalingsmetode", + + "workspace.referral.copyLink": "Kopier lenke", + "workspace.referral.copied": "Kopiert", + "workspace.referral.overview.title": "Inviter venner", + "workspace.referral.overview.subtitle": "Få $5 når en venn abonnerer. De får også $5.", + "workspace.referral.instructions.share": "Del henvisningslenken din", + "workspace.referral.instructions.subscribe": "Vennen din blir med og abonnerer på Go", + "workspace.referral.instructions.claim": "Dere får begge $5 i brukskreditt å bruke på Go-bruksgrensene deres", + "workspace.referral.rewards.title": "Henvisningsbelønninger", + "workspace.referral.rewards.description": "Bruk tilgjengelige henvisningskreditter på Go-bruken din.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} belønninger brukt.", + "workspace.referral.rewards.empty": "Ingen henvisningsbelønninger ennå.", + "workspace.referral.table.reward": "Belønning", + "workspace.referral.table.referral": "Beskrivelse", + "workspace.referral.table.date": "Dato", + "workspace.referral.reward.description.inviter": "Inviterte {{email}}", + "workspace.referral.reward.description.invitee": "Invitert av {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Abonner for å låse opp", + "workspace.referral.reward.action.view": "Vis belønning", + "workspace.referral.reward.action.applied": "Belønning brukt", + "workspace.referral.reward.source.pendingInviter": "Venter på at de abonnerer", + "workspace.referral.reward.source.pendingInvitee": "Abonner for å låse opp belønningen", + "workspace.referral.reward.source.available": "Belønning klar til bruk", + "workspace.referral.reward.source.applied": "Belønning brukt", + "workspace.referral.reward.status.applied": "Belønning brukt", + "workspace.referral.reward.status.pendingInviter": "Abonner for å låse opp", + "workspace.referral.reward.status.pendingInvitee": "Abonner for å låse opp", + "workspace.referral.apply.noGo": "Abonner for å låse opp", + "workspace.referral.apply.preview": "Vis belønning", + "workspace.referral.apply.action": "Bruk", + "workspace.referral.apply.confirmTitle": "Bruk belønning", + "workspace.referral.apply.confirmBody": "Bruk {{amount}} for å redusere dette workspacets nåværende forbruk.", + "workspace.referral.apply.confirmAction": "Bruk", + + "download.title": "OpenCode | Last ned", + "download.meta.description": "Last ned OpenCode for macOS, Windows og Linux", + "download.hero.title": "Last ned OpenCode Desktop", + "download.hero.subtitle": "Tilgjengelig i beta for macOS, Windows og Linux", + "download.hero.button": "Last ned for {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "OpenCode Extensions", + "download.section.integrations": "OpenCode Integrations", + "download.action.download": "Last ned", + "download.action.install": "Installer", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Ikke nødvendigvis, men sannsynligvis. Du trenger et AI-abonnement hvis du vil koble OpenCode til en betalt leverandør, selv om du kan jobbe med", + "download.faq.a3.localLink": "lokale modeller", + "download.faq.a3.afterLocal.beforeZen": "gratis. Selv om vi oppfordrer brukere til å bruke", + "download.faq.a3.afterZen": ", fungerer OpenCode med alle populære leverandører som OpenAI, Anthropic, xAI osv.", + + "download.faq.a5.p1": "OpenCode er 100% gratis å bruke.", + "download.faq.a5.p2.beforeZen": + "Eventuelle ekstra kostnader kommer fra abonnementet ditt hos en modellleverandør. Selv om OpenCode fungerer med enhver modellleverandør, anbefaler vi å bruke", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": "Dataene og informasjonen din lagres bare når du oppretter delbare lenker i OpenCode.", + "download.faq.a6.p2.beforeShare": "Les mer om", + "download.faq.a6.shareLink": "delingssider", + + "enterprise.title": "OpenCode | Enterprise-løsninger for din organisasjon", + "enterprise.meta.description": "Kontakt OpenCode for enterprise-løsninger", + "enterprise.hero.title": "Koden din er din", + "enterprise.hero.body1": + "OpenCode opererer sikkert inne i organisasjonen din uten at data eller kontekst lagres, og uten lisensbegrensninger eller eierskapskrav. Start en prøveperiode med teamet ditt, og rull den deretter ut i hele organisasjonen ved å integrere den med SSO og din interne AI-gateway.", + "enterprise.hero.body2": "Fortell oss hvordan vi kan hjelpe.", + "enterprise.form.name.label": "Fullt navn", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Rolle", + "enterprise.form.role.placeholder": "Styreleder", + "enterprise.form.company.label": "Selskap", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Bedrifts-e-post", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Telefonnummer", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Hvilket problem prøver dere å løse?", + "enterprise.form.message.placeholder": "Vi trenger hjelp med...", + "enterprise.form.send": "Send", + "enterprise.form.sending": "Sender...", + "enterprise.form.success": "Melding sendt, vi tar kontakt snart.", + "enterprise.form.success.submitted": "Skjemaet ble sendt inn.", + "enterprise.form.error.allFieldsRequired": "Alle felt er obligatoriske.", + "enterprise.form.error.invalidEmailFormat": "Ugyldig e-postformat.", + "enterprise.form.error.internalServer": "Intern serverfeil.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "Hva er OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise er for organisasjoner som vil sikre at koden og dataene deres aldri forlater infrastrukturen. Dette kan gjøres med en sentral konfigurasjon som integreres med SSO og intern AI-gateway.", + "enterprise.faq.q2": "Hvordan kommer jeg i gang med OpenCode Enterprise?", + "enterprise.faq.a2": + "Start enkelt med en intern prøveperiode med teamet ditt. OpenCode lagrer som standard ikke koden din eller kontekstdata, noe som gjør det enkelt å komme i gang. Kontakt oss deretter for å diskutere priser og implementeringsalternativer.", + "enterprise.faq.q3": "Hvordan fungerer enterprise-prising?", + "enterprise.faq.a3": + "Vi tilbyr enterprise-prising per sete. Har du din egen LLM-gateway, tar vi ikke betalt for brukte tokens. Kontakt oss for flere detaljer og et tilpasset tilbud basert på organisasjonens behov.", + "enterprise.faq.q4": "Er dataene mine sikre med OpenCode Enterprise?", + "enterprise.faq.a4": + "Ja. OpenCode lagrer ikke koden din eller kontekstdata. All behandling skjer lokalt eller gjennom direkte API-kall til AI-leverandøren din. Med sentral konfigurasjon og SSO-integrasjon forblir dataene dine sikre innenfor organisasjonens infrastruktur.", + + "brand.title": "OpenCode | Merkevare", + "brand.meta.description": "OpenCode retningslinjer for merkevare", + "brand.heading": "Retningslinjer for merkevare", + "brand.subtitle": "Ressurser og assets som hjelper deg å jobbe med OpenCode-brandet.", + "brand.downloadAll": "Last ned alle assets", + + "changelog.title": "OpenCode | Endringslogg", + "changelog.meta.description": "Utgivelsesnotater og endringslogg for OpenCode", + "changelog.hero.title": "Endringslogg", + "changelog.hero.subtitle": "Nye oppdateringer og forbedringer for OpenCode", + "changelog.empty": "Ingen endringsloggoppføringer funnet.", + "changelog.viewJson": "Vis JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarks", + "bench.list.table.agent": "Agent", + "bench.list.table.model": "Modell", + "bench.list.table.score": "Poengsum", + "bench.submission.error.allFieldsRequired": "Alle felt er obligatoriske.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Oppgave ikke funnet", + "bench.detail.na": "I/T", + "bench.detail.labels.agent": "Agent", + "bench.detail.labels.model": "Modell", + "bench.detail.labels.task": "Oppgave", + "bench.detail.labels.repo": "Repo", + "bench.detail.labels.from": "Fra", + "bench.detail.labels.to": "Til", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Gjennomsnittlig varighet", + "bench.detail.labels.averageScore": "Gjennomsnittlig poengsum", + "bench.detail.labels.averageCost": "Gjennomsnittlig kostnad", + "bench.detail.labels.summary": "Sammendrag", + "bench.detail.labels.runs": "Kjøringer", + "bench.detail.labels.score": "Poengsum", + "bench.detail.labels.base": "Basis", + "bench.detail.labels.penalty": "Straff", + "bench.detail.labels.weight": "vekt", + "bench.detail.table.run": "Kjøring", + "bench.detail.table.score": "Poengsum (Basis - Straff)", + "bench.detail.table.cost": "Kostnad", + "bench.detail.table.duration": "Varighet", + "bench.detail.run.title": "Kjøring {{n}}", + "bench.detail.rawJson": "Rå JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/pl.ts b/packages/console/app/src/i18n/pl.ts new file mode 100644 index 0000000000000000000000000000000000000000..4a4e1ba724a6f1b76eca11762521d4dca2598962 --- /dev/null +++ b/packages/console/app/src/i18n/pl.ts @@ -0,0 +1,880 @@ +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash oferuje 4x wyższe limity użycia przez ograniczony czas", + "go.graph.bonus": "{{count}}× większy limit", + "nav.github": "GitHub", + "nav.docs": "Dokumentacja", + "nav.changelog": "Dziennik zmian", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Zaloguj się", + "nav.free": "Pobierz", + "nav.home": "Strona główna", + "nav.openMenu": "Otwórz menu", + "nav.getStartedFree": "Zacznij za darmo", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Skopiuj logo jako SVG", + "nav.context.copyWordmark": "Skopiuj logotyp jako SVG", + "nav.context.brandAssets": "Zasoby marki", + + "footer.github": "GitHub", + "footer.docs": "Dokumentacja", + "footer.changelog": "Dziennik zmian", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Marka", + "legal.privacy": "Prywatność", + "legal.terms": "Warunki", + + "email.title": "Bądź pierwszym, który dowie się o nowych produktach", + "email.subtitle": "Dołącz do listy oczekujących na wczesny dostęp.", + "email.placeholder": "Adres e-mail", + "email.subscribe": "Subskrybuj", + "email.success": "Prawie gotowe, sprawdź skrzynkę i potwierdź swój adres e-mail", + + "notFound.title": "Nie znaleziono | opencode", + "notFound.heading": "404 - Nie znaleziono strony", + "notFound.home": "Strona główna", + "notFound.docs": "Dokumentacja", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "jasne logo opencode", + "notFound.logoDarkAlt": "ciemne logo opencode", + + "user.logout": "Wyloguj się", + + "auth.callback.error.codeMissing": "Nie znaleziono kodu autoryzacji.", + + "workspace.select": "Wybierz obszar roboczy", + "workspace.createNew": "+ Utwórz nowy obszar roboczy", + "workspace.modal.title": "Utwórz nowy obszar roboczy", + "workspace.modal.placeholder": "Wpisz nazwę obszaru roboczego", + + "common.cancel": "Anuluj", + "common.creating": "Tworzenie...", + "common.create": "Utwórz", + "common.contactUs": "Skontaktuj się z nami", + + "common.videoUnsupported": "Twoja przeglądarka nie obsługuje znacznika wideo.", + "common.figure": "Rys. {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Dowiedz się więcej", + + "error.invalidPlan": "Nieprawidłowy plan", + "error.workspaceRequired": "ID obszaru roboczego jest wymagane", + "error.alreadySubscribed": "Ten obszar roboczy ma już subskrypcję", + "error.limitRequired": "Limit jest wymagany.", + "error.monthlyLimitInvalid": "Ustaw prawidłowy limit miesięczny.", + "error.workspaceNameRequired": "Nazwa obszaru roboczego jest wymagana.", + "error.nameTooLong": "Nazwa musi mieć 255 znaków lub mniej.", + "error.emailRequired": "E-mail jest wymagany", + "error.roleRequired": "Rola jest wymagana", + "error.idRequired": "ID jest wymagane", + "error.nameRequired": "Nazwa jest wymagana", + "error.providerRequired": "Dostawca jest wymagany", + "error.apiKeyRequired": "Klucz API jest wymagany", + "error.modelRequired": "Model jest wymagany", + "error.reloadAmountMin": "Kwota doładowania musi wynosić co najmniej ${{amount}}", + "error.reloadTriggerMin": "Próg salda musi wynosić co najmniej ${{amount}}", + + "app.meta.description": "OpenCode - Otwartoźródłowy agent programistyczny.", + + "home.title": "OpenCode | Open source'owy agent AI do kodowania", + + "temp.title": "opencode | Agent AI do kodowania zbudowany dla terminala", + "temp.hero.title": "Agent AI do kodowania zbudowany dla terminala", + "temp.zen": "opencode zen", + "temp.getStarted": "Rozpocznij", + "temp.feature.native.title": "Natywny TUI", + "temp.feature.native.body": "Responsywny, natywny, tematyczny interfejs terminala", + "temp.feature.zen.beforeLink": "A", + "temp.feature.zen.link": "wyselekcjonowana lista modeli", + "temp.feature.zen.afterLink": "dostarczana przez opencode", + "temp.feature.models.beforeLink": "Obsługuje 75+ dostawców LLM przez", + "temp.feature.models.afterLink": ", w tym modele lokalne", + "temp.screenshot.caption": "OpenCode TUI z motywem tokyonight", + "temp.screenshot.alt": "OpenCode TUI z motywem tokyonight", + "temp.logoLightAlt": "jasne logo opencode", + "temp.logoDarkAlt": "ciemne logo opencode", + + "home.banner.badge": "Nowość", + "home.banner.text": "Przedstawiamy karty w aplikacji desktopowej.", + "home.banner.platforms": "Dostępne na macOS, Windows i Linux", + "home.banner.downloadNow": "Pobierz teraz", + "home.banner.downloadBetaNow": "Pobierz betę wersji desktopowej", + "home.promo.title": "Przedstawiamy karty w aplikacji desktopowej", + "home.promo.body": "Organizuj swoją pracę i aktywne sesje za pomocą kart.", + "home.promo.cta": "Pobierz najnowszą wersję, aby rozpocząć.", + "home.promo.close": "Zamknij ogłoszenie o aplikacji desktopowej", + + "home.hero.title": "Open source'owy agent AI do kodowania", + "home.hero.subtitle.a": "Darmowe modele w zestawie lub podłącz dowolny model od dowolnego dostawcy,", + "home.hero.subtitle.b": "w tym Claude, GPT, Gemini i inne.", + + "home.install.ariaLabel": "Opcje instalacji", + + "home.what.title": "Czym jest OpenCode?", + "home.what.body": + "OpenCode to open source'owy agent, który pomaga pisać kod w terminalu, IDE lub aplikacji desktopowej.", + "home.what.lsp.title": "LSP włączone", + "home.what.lsp.body": "Automatycznie ładuje odpowiednie LSP dla LLM", + "home.what.multiSession.title": "Wielosesyjność", + "home.what.multiSession.body": "Uruchom wiele agentów równolegle w tym samym projekcie", + "home.what.shareLinks.title": "Udostępnianie linków", + "home.what.shareLinks.body": "Udostępnij link do dowolnej sesji w celach referencyjnych lub do debugowania", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Zaloguj się przez GitHub, aby używać swojego konta Copilot", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Zaloguj się przez OpenAI, aby używać swojego konta ChatGPT Plus lub Pro", + "home.what.anyModel.title": "Dowolny model", + "home.what.anyModel.body": "75+ dostawców LLM przez Models.dev, w tym modele lokalne", + "home.what.anyEditor.title": "Dowolny edytor", + "home.what.anyEditor.body": "Dostępny jako interfejs terminalowy, aplikacja desktopowa i rozszerzenie IDE", + "home.what.readDocs": "Czytaj dokumentację", + + "home.growth.title": "Open source'owy agent AI do kodowania", + "home.growth.body": + "Z ponad {{stars}} gwiazdkami na GitHubie, {{contributors}} współtwórcami i ponad {{commits}} commitami, OpenCode jest używany i ceniony przez ponad {{monthlyUsers}} deweloperów każdego miesiąca.", + "home.growth.githubStars": "Gwiazdki GitHub", + "home.growth.contributors": "Współtwórcy", + "home.growth.monthlyDevs": "Miesięczni użytkownicy", + + "home.privacy.title": "Zbudowany z myślą o prywatności", + "home.privacy.body": + "OpenCode nie przechowuje Twojego kodu ani danych kontekstowych, dzięki czemu może działać w środowiskach wrażliwych na prywatność.", + "home.privacy.learnMore": "Dowiedz się więcej o", + "home.privacy.link": "prywatności", + + "home.faq.q1": "Czym jest OpenCode?", + "home.faq.a1": + "OpenCode to open source'owy agent, który pomaga pisać i uruchamiać kod z dowolnym modelem AI. Jest dostępny jako interfejs terminalowy, aplikacja desktopowa lub rozszerzenie IDE.", + "home.faq.q2": "Jak korzystać z OpenCode?", + "home.faq.a2.before": "Najłatwiej zacząć od przeczytania", + "home.faq.a2.link": "wprowadzenia", + "home.faq.q3": "Czy potrzebuję dodatkowych subskrypcji AI, aby używać OpenCode?", + "home.faq.a3.p1": + "Niekoniecznie. OpenCode posiada zestaw darmowych modeli, z których możesz korzystać bez zakładania konta.", + "home.faq.a3.p2.beforeZen": "Poza tym możesz używać dowolnych popularnych modeli do kodowania, tworząc konto", + "home.faq.a3.p2.afterZen": ".", + "home.faq.a3.p3": + "Chociaż zachęcamy do korzystania z Zen, OpenCode działa również ze wszystkimi popularnymi dostawcami, takimi jak OpenAI, Anthropic, xAI itp.", + "home.faq.a3.p4.beforeLocal": "Możesz nawet podłączyć swoje", + "home.faq.a3.p4.localLink": "lokalne modele", + "home.faq.q4": "Czy mogę używać moich istniejących subskrypcji AI z OpenCode?", + "home.faq.a4.p1": + "Tak, OpenCode obsługuje plany subskrypcyjne od wszystkich głównych dostawców. Możesz używać swoich subskrypcji Claude Pro/Max, ChatGPT Plus/Pro lub GitHub Copilot.", + "home.faq.q5": "Czy mogę używać OpenCode tylko w terminalu?", + "home.faq.a5.beforeDesktop": "Już nie! OpenCode jest teraz dostępny jako aplikacja na", + "home.faq.a5.desktop": "pulpit (desktop)", + "home.faq.a5.and": "i", + "home.faq.a5.web": "web", + "home.faq.q6": "Ile kosztuje OpenCode?", + "home.faq.a6": + "OpenCode jest w 100% darmowy. Zawiera również zestaw darmowych modeli. Mogą pojawić się dodatkowe koszty, jeśli podłączysz innego dostawcę.", + "home.faq.q7": "A co z danymi i prywatnością?", + "home.faq.a7.p1": + "Twoje dane i informacje są przechowywane tylko wtedy, gdy używasz naszych darmowych modeli lub tworzysz linki do udostępniania.", + "home.faq.a7.p2.beforeModels": "Dowiedz się więcej o", + "home.faq.a7.p2.modelsLink": "naszych modelach", + "home.faq.a7.p2.and": "i", + "home.faq.a7.p2.shareLink": "stronach udostępniania", + "home.faq.q8": "Czy OpenCode jest open source?", + "home.faq.a8.p1": "Tak, OpenCode jest w pełni open source. Kod źródłowy jest publicznie dostępny na", + "home.faq.a8.p2": "na licencji", + "home.faq.a8.mitLicense": "MIT License", + "home.faq.a8.p3": + ", co oznacza, że każdy może go używać, modyfikować i wspierać jego rozwój. Każdy ze społeczności może zgłaszać błędy, przesyłać pull requesty i rozszerzać funkcjonalność.", + + "home.zenCta.title": "Uzyskaj dostęp do niezawodnych, zoptymalizowanych modeli dla agentów kodujących", + "home.zenCta.body": + "Zen daje dostęp do wyselekcjonowanego zestawu modeli AI, które OpenCode przetestował i sprawdził (benchmark) specjalnie dla agentów kodujących. Nie musisz martwić się o niespójną wydajność i jakość u różnych dostawców, używaj sprawdzonych modeli, które działają.", + "home.zenCta.link": "Dowiedz się więcej o Zen", + + "zen.title": "OpenCode Zen | Wyselekcjonowany zestaw niezawodnych, zoptymalizowanych modeli dla agentów kodujących", + "zen.hero.title": "Niezawodne, zoptymalizowane modele dla agentów kodujących", + "zen.hero.body": + "Zen daje dostęp do wyselekcjonowanego zestawu modeli AI, które OpenCode przetestował i sprawdził (benchmark) specjalnie dla agentów kodujących. Nie musisz martwić się o niespójną wydajność i jakość, używaj sprawdzonych modeli, które działają.", + + "zen.faq.q1": "Czym jest OpenCode Zen?", + "zen.faq.a1": + "Zen to wyselekcjonowany zestaw modeli AI przetestowanych i sprawdzonych pod kątem agentów kodujących, stworzony przez zespół stojący za OpenCode.", + "zen.faq.q2": "Co sprawia, że Zen jest bardziej precyzyjny?", + "zen.faq.a2": + "Zen oferuje tylko modele, które zostały specjalnie przetestowane i sprawdzone dla agentów kodujących. Nie używasz noża do masła do krojenia steku, więc nie używaj słabych modeli do kodowania.", + "zen.faq.q3": "Czy Zen jest tańszy?", + "zen.faq.a3": + "Zen nie jest nastawiony na zysk. Zen przekazuje koszty od dostawców modeli bezpośrednio do Ciebie. Im większe użycie Zen, tym lepsze stawki OpenCode może wynegocjować i przekazać Tobie.", + "zen.faq.q4": "Ile kosztuje Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "pobiera opłaty za żądanie", + "zen.faq.a4.p1.afterPricing": "bez marży, więc płacisz dokładnie tyle, ile pobiera dostawca modelu.", + "zen.faq.a4.p2.beforeAccount": + "Twój całkowity koszt zależy od użycia, i możesz ustawić miesięczne limity wydatków na swoim", + "zen.faq.a4.p2.accountLink": "koncie", + "zen.faq.a4.p3": + "Aby pokryć koszty, OpenCode dolicza jedynie niewielką opłatę za przetwarzanie płatności w wysokości $1.23 przy każdym doładowaniu salda o $20.", + "zen.faq.q5": "A co z danymi i prywatnością?", + "zen.faq.a5.beforeExceptions": + "Wszystkie modele Zen są hostowane w USA. Dostawcy stosują politykę zerowej retencji i nie używają Twoich danych do trenowania modeli, z", + "zen.faq.a5.exceptionsLink": "następującymi wyjątkami", + "zen.faq.q6": "Czy mogę ustawić limity wydatków?", + "zen.faq.a6": "Tak, możesz ustawić miesięczne limity wydatków na swoim koncie.", + "zen.faq.q7": "Czy mogę anulować?", + "zen.faq.a7": "Tak, możesz wyłączyć rozliczenia w dowolnym momencie i wykorzystać pozostałe saldo.", + "zen.faq.q8": "Czy mogę używać Zen z innymi agentami kodującymi?", + "zen.faq.a8": + "Chociaż Zen świetnie działa z OpenCode, możesz używać Zen z dowolnym agentem. Postępuj zgodnie z instrukcjami konfiguracji w swoim preferowanym agencie.", + "zen.faq.q9": "Czy mogę otrzymać zwrot pieniędzy?", + "zen.faq.a9": + "Możesz kwalifikować się do zwrotu, jeśli opłata została pobrana w ciągu ostatnich 14 dni i nie wykorzystano żadnych środków z tego zakupu. {{contact}}, aby poprosić o zwrot.", + + "zen.cta.start": "Zacznij korzystać z Zen", + "zen.pricing.title": "Dodaj 20$ salda Pay as you go", + "zen.pricing.fee": "(+$1.23 opłaty za przetwarzanie karty)", + "zen.pricing.body": "Używaj z dowolnym agentem. Ustaw miesięczne limity wydatków. Anuluj w dowolnym momencie.", + "zen.problem.title": "Jaki problem rozwiązuje Zen?", + "zen.problem.body": + "Dostępnych jest wiele modeli, ale tylko nieliczne dobrze współpracują z agentami kodującymi. Większość dostawców konfiguruje je inaczej, co daje różne wyniki.", + "zen.problem.subtitle": "Naprawiamy to dla wszystkich, nie tylko dla użytkowników OpenCode.", + "zen.problem.item1": "Testowanie wybranych modeli i konsultacje z ich zespołami", + "zen.problem.item2": "Współpraca z dostawcami w celu zapewnienia ich prawidłowego dostarczania", + "zen.problem.item3": "Benchmark wszystkich rekomendowanych przez nas kombinacji modeli i dostawców", + "zen.how.title": "Jak działa Zen", + "zen.how.body": "Chociaż sugerujemy używanie Zen z OpenCode, możesz używać Zen z dowolnym agentem.", + "zen.how.step1.title": "Zarejestruj się i doładuj saldo 20$", + "zen.how.step1.beforeLink": "postępuj zgodnie z", + "zen.how.step1.link": "instrukcją konfiguracji", + "zen.how.step2.title": "Używaj Zen z przejrzystym cennikiem", + "zen.how.step2.link": "płać za żądanie", + "zen.how.step2.afterLink": "bez marży", + "zen.how.step3.title": "Automatyczne doładowanie", + "zen.how.step3.body": "gdy Twoje saldo osiągnie 5$, automatycznie dodamy 20$", + "zen.privacy.title": "Twoja prywatność jest dla nas ważna", + "zen.privacy.beforeExceptions": + "Wszystkie modele Zen są hostowane w USA. Dostawcy stosują politykę zerowej retencji i nie wykorzystują Twoich danych do trenowania modeli, z", + "zen.privacy.exceptionsLink": "następującymi wyjątkami", + + "go.title": "OpenCode Go | Niskokosztowe modele do kodowania dla każdego", + "go.meta.description": + "Go kosztuje $10/miesiąc, oferując hojne limity użycia i niezawodny dostęp do wiodących modeli do kodowania.", + "go.hero.title": "Niskokosztowe modele do kodowania dla każdego", + "go.hero.body": + "Go udostępnia programowanie z agentami programistom na całym świecie. Oferuje hojne limity i niezawodny dostęp do najzdolniejszych modeli open source, dzięki czemu możesz budować za pomocą potężnych agentów, nie martwiąc się o koszty czy dostępność.", + + "go.cta.start": "Zasubskrybuj Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Zasubskrybuj Go", + "go.cta.price": "$10/miesiąc", + "go.pricing.body": + "Używaj z dowolnym agentem. $10/miesiąc. Doładuj konto w razie potrzeby. Anuluj w dowolnym momencie.", + "go.graph.free": "Darmowe", + "go.graph.freePill": "Big Pickle i darmowe modele", + "go.graph.go": "Go", + "go.graph.label": "Żądania na 5 godzin", + "go.graph.period": "Użycie", + "go.graph.model": "Model", + "go.graph.requests": "Szac. żądania / 5 godz.", + "go.graph.allowance": "Miesięczne użycie", + "go.graph.new": "Nowość", + "go.graph.scale": "Nieliniowa skala liczby żądań", + "go.graph.showAll": "Pokaż wszystkie modele ({{count}})", + "go.graph.showLess": "Pokaż mniej modeli", + "go.graph.limitedRegions": "ograniczone regiony", + "go.graph.limitedTime": "ograniczony czas", + "go.graph.usageLimits": "Limity użycia", + "go.graph.aria": "Żądania na 5h: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "zmieniło moje życie, to naprawdę oczywisty wybór.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Founder, SEED, PM, Melt, Pop, Dapt, Cadmus, and ViewPoint", + "go.testimonials.jay.quoteBefore": "4 na 5 osób w naszym zespole uwielbia używać", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "Nie mogę wystarczająco polecić", + "go.testimonials.adam.quoteAfter": ". Poważnie, to jest naprawdę dobre.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "Dzięki", + "go.testimonials.david.quoteAfter": "wiem, że wszystkie modele są przetestowane i idealne dla agentów kodujących.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Intern, Nvidia (4 times)", + "go.testimonials.frank.quote": "Chciałbym wciąż być w Nvidia.", + "go.problem.title": "Jaki problem rozwiązuje Go?", + "go.problem.body": + "Skupiamy się na udostępnieniu doświadczenia OpenCode jak największej liczbie osób. OpenCode Go to tania subskrypcja za $10/miesiąc. Zapewnia hojne limity i niezawodny dostęp do najbardziej wydajnych modeli open source.", + "go.problem.subtitle": " ", + "go.problem.item1": "Niskokosztowa cena subskrypcji", + "go.problem.item2": "Hojne limity i niezawodny dostęp", + "go.problem.item3": "Stworzony dla jak największej liczby programistów", + "go.problem.item4": "Starannie dobrany zestaw modeli przetestowanych pod kątem kodowania z agentami", + "go.how.title": "Jak działa Go", + "go.how.body": "Go kosztuje $10/miesiąc. Możesz go używać z OpenCode lub dowolnym agentem.", + "go.how.step1.title": "Załóż konto", + "go.how.step1.beforeLink": "postępuj zgodnie z", + "go.how.step1.link": "instrukcją konfiguracji", + "go.how.step2.title": "Zasubskrybuj Go", + "go.how.step2.link": "$10/miesiąc", + "go.how.step2.afterLink": "z hojnymi limitami", + "go.how.step3.title": "Zacznij kodować", + "go.how.step3.body": "z niezawodnym dostępem do modeli open source", + "go.privacy.title": "Twoja prywatność jest dla nas ważna", + "go.privacy.body": + "Plan został zaprojektowany głównie dla użytkowników międzynarodowych, z modelami hostowanymi w USA, UE i Singapurze, aby zapewnić stabilny globalny dostęp.", + "go.privacy.contactAfter": "jeśli masz jakiekolwiek pytania.", + "go.privacy.beforeExceptions": + "Modele Go są hostowane w USA. Dostawcy stosują politykę zerowej retencji i nie używają Twoich danych do trenowania modeli, z", + "go.privacy.exceptionsLink": "następującymi wyjątkami", + "go.faq.q1": "Czym jest OpenCode Go?", + "go.faq.a1": + "Go to niskokosztowa subskrypcja, która daje niezawodny dostęp do zdolnych modeli open source dla agentów kodujących.", + "go.faq.q2": "Jakie modele zawiera Go?", + "go.faq.a2": "Go obejmuje poniższe modele z wysokimi limitami i niezawodnym dostępem.", + "go.faq.q3": "Czy Go to to samo co Zen?", + "go.faq.a3": + "Nie. Zen działa w modelu płatności za użycie, natomiast Go kosztuje $10/miesiąc, oferując hojne limity i niezawodny dostęp do starannie dobranego zestawu modeli.", + "go.faq.q4": "Ile kosztuje Go?", + "go.faq.a4.p1.beforePricing": "Go kosztuje", + "go.faq.a4.p1.pricingLink": "$10/miesiąc", + "go.faq.a4.p1.afterPricing": "z hojnymi limitami.", + "go.faq.a4.p2.beforeAccount": "Możesz zarządzać subskrypcją na swoim", + "go.faq.a4.p2.accountLink": "koncie", + "go.faq.a4.p3": "Anuluj w dowolnym momencie.", + "go.faq.q5": "A co z danymi i prywatnością?", + "go.faq.a5.model": "Model", + "go.faq.a5.training": "Trenowanie modelu", + "go.faq.a5.retention": "Retencja danych", + "go.faq.a5.retention30": "30 dni", + "go.faq.a5.retention0": "0 dni", + "go.faq.a5.used": "Wykorzystywane", + "go.faq.a5.notUsed": "Niewykorzystywane", + "go.faq.a5.noAgreement": "Brak umowy", + "go.faq.a5.notZdr": "Nie ZDR", + "go.faq.a5.grokRetention": + "ZDR wyłącza ważne funkcje API zależne od przechowywanych danych, w tym stanowy Responses API, Files and Collections oraz Batch API.", + "go.faq.a5.gptRetention": + "Dzienniki monitorowania nadużyć są generowane dla każdego użycia funkcji API i przechowywane przez maksymalnie 30 dni.", + "go.faq.a5.learnMore": "Dowiedz się więcej", + "go.faq.a5.deepseekRetention": "Umowa ZDR jest odnawiana co miesiąc. Obecna umowa obowiązuje do 30 września 2026 r.", + "go.faq.a5.museRetention": + "Znacznie obniżone ceny tokenów w zamian za zgodę na wykorzystanie Twoich promptów i odpowiedzi do trenowania przyszłych modeli Meta.", + + "go.faq.a5.beforeExceptions": + "Modele Go są hostowane w USA. Dostawcy stosują politykę zerowej retencji i nie używają Twoich danych do trenowania modeli, z", + "go.faq.a5.exceptionsLink": "następującymi wyjątkami", + "go.faq.q6": "Czy mogę doładować środki?", + "go.faq.a6": "Jeśli potrzebujesz większego użycia, możesz doładować środki na swoim koncie.", + "go.faq.q7": "Czy mogę anulować?", + "go.faq.a7": "Tak, możesz anulować w dowolnym momencie.", + "go.faq.q8": "Czy mogę używać Go z innymi agentami kodującymi?", + "go.faq.a8": + "Tak, możesz używać Go z dowolnym agentem. Postępuj zgodnie z instrukcjami konfiguracji w swoim preferowanym agencie.", + + "go.faq.q9": "Jaka jest różnica między darmowymi modelami a Go?", + "go.faq.a9": + "Darmowe modele obejmują Big Pickle oraz modele promocyjne dostępne w danym momencie, z limitem 200 zapytań/dzień. Go oferuje starannie dobrany zestaw modeli z wyższymi limitami zapytań egzekwowanymi w oknach kroczących (5-godzinnych, tygodniowych i miesięcznych), odpowiadającymi w przybliżeniu bazowym limitom $12 na 5 godzin, $30 tygodniowo i $60 miesięcznie; limity mogą się różnić zależnie od modelu (rzeczywista liczba zapytań zależy od modelu i użycia).", + "go.faq.q10": "Czy mogę otrzymać zwrot pieniędzy?", + "go.faq.a10": + "Możesz kwalifikować się do zwrotu, jeśli opłata została pobrana w ciągu ostatnich 14 dni i nie wykorzystano żadnej części limitu Go w tym okresie rozliczeniowym. {{contact}}, aby poprosić o zwrot.", + + "zen.api.error.rateLimitExceeded": "Przekroczono limit zapytań. Spróbuj ponownie później.", + "zen.api.error.modelNotSupported": "Model {{model}} nie jest obsługiwany", + "zen.api.error.modelFormatNotSupported": "Model {{model}} nie jest obsługiwany dla formatu {{format}}", + "zen.api.error.noProviderAvailable": "Brak dostępnego dostawcy", + "zen.api.error.providerNotSupported": "Dostawca {{provider}} nie jest obsługiwany", + "zen.api.error.missingApiKey": "Brak klucza API.", + "zen.api.error.invalidApiKey": "Nieprawidłowy klucz API.", + "zen.api.error.requestBlockedByUpstreamProvider": "Żądanie zablokowane przez dostawcę zewnętrznego.", + "zen.api.error.subscriptionQuotaExceeded": "Przekroczono limit subskrypcji. Spróbuj ponownie za {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "Osiągnięto 5-godzinny limit użycia. Resetuje się za {{retryIn}}. Aby nadal korzystać z tego modelu, włącz użycie z dostępnego salda: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Osiągnięto tygodniowy limit użycia. Resetuje się za {{retryIn}}. Aby nadal korzystać z tego modelu, włącz użycie z dostępnego salda: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Osiągnięto miesięczny limit użycia. Resetuje się za {{retryIn}}. Aby nadal korzystać z tego modelu, włącz użycie z dostępnego salda: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Brak metody płatności. Dodaj metodę płatności tutaj: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Niewystarczające saldo. Zarządzaj swoimi płatnościami tutaj: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Twoja przestrzeń robocza osiągnęła miesięczny limit wydatków w wysokości ${{amount}}. Zarządzaj swoimi limitami tutaj: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Osiągnąłeś swój miesięczny limit wydatków w wysokości ${{amount}}. Zarządzaj swoimi limitami tutaj: {{membersUrl}}", + "zen.api.error.modelDisabled": "Model jest wyłączony", + "zen.api.error.regionNotAllowed": + "Najnowsza wersja tego modelu jest dostępna wyłącznie jako usługa hostowana w Chinach i wymaga jawnej zgody użytkownika: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Ten model nie jest dostępny w Twoim kraju.", + "zen.api.error.trainingNotAllowed": + "Ten model zbiera dane wykorzystywane do poprawy jego jakości i wymaga wyraźnej zgody użytkownika: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "Bezpłatna promocja {{model}} dobiegła końca. Możesz dalej korzystać z modelu, subskrybując OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Dostęp do najlepszych na świecie modeli kodujących", + "black.meta.description": "Uzyskaj dostęp do Claude, GPT, Gemini i innych dzięki planom subskrypcji OpenCode Black.", + "black.hero.title": "Dostęp do najlepszych na świecie modeli kodujących", + "black.hero.subtitle": "W tym Claude, GPT, Gemini i inne", + "black.title": "OpenCode Black | Cennik", + "black.paused": "Rejestracja planu Black jest tymczasowo wstrzymana.", + "black.plan.icon20": "Plan Black 20", + "black.plan.icon100": "Plan Black 100", + "black.plan.icon200": "Plan Black 200", + "black.plan.multiplier100": "5x większe użycie niż Black 20", + "black.plan.multiplier200": "20x większe użycie niż Black 20", + "black.price.perMonth": "miesięcznie", + "black.price.perPersonBilledMonthly": "za osobę rozliczane miesięcznie", + "black.terms.1": "Twoja subskrypcja nie rozpocznie się natychmiast", + "black.terms.2": "Zostaniesz dodany do listy oczekujących i aktywowany wkrótce", + "black.terms.3": "Twoja karta zostanie obciążona dopiero po aktywacji subskrypcji", + "black.terms.4": "Obowiązują limity użycia, intensywne automatyczne użycie może wyczerpać limity szybciej", + "black.terms.5": "Subskrypcje są dla osób indywidualnych, skontaktuj się z Enterprise dla zespołów", + "black.terms.6": "Limity mogą zostać dostosowane, a plany mogą zostać wycofane w przyszłości", + "black.terms.7": "Anuluj subskrypcję w dowolnym momencie", + "black.action.continue": "Kontynuuj", + "black.finePrint.beforeTerms": "Podane ceny nie zawierają stosownego podatku", + "black.finePrint.terms": "Warunki świadczenia usług", + "black.workspace.title": "OpenCode Black | Wybierz obszar roboczy", + "black.workspace.selectPlan": "Wybierz obszar roboczy dla tego planu", + "black.workspace.name": "Obszar roboczy {{n}}", + "black.subscribe.title": "Subskrybuj OpenCode Black", + "black.subscribe.paymentMethod": "Metoda płatności", + "black.subscribe.loadingPaymentForm": "Ładowanie formularza płatności...", + "black.subscribe.selectWorkspaceToContinue": "Wybierz obszar roboczy, aby kontynuować", + "black.subscribe.failurePrefix": "O nie!", + "black.subscribe.error.generic": "Wystąpił błąd", + "black.subscribe.error.invalidPlan": "Nieprawidłowy plan", + "black.subscribe.error.workspaceRequired": "ID obszaru roboczego jest wymagane", + "black.subscribe.error.alreadySubscribed": "Ten obszar roboczy ma już subskrypcję", + "black.subscribe.processing": "Przetwarzanie...", + "black.subscribe.submit": "Subskrybuj ${{plan}}", + "black.subscribe.form.chargeNotice": "Zostaniesz obciążony dopiero po aktywacji subskrypcji", + "black.subscribe.success.title": "Jesteś na liście oczekujących OpenCode Black", + "black.subscribe.success.subscriptionPlan": "Plan subskrypcji", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Kwota", + "black.subscribe.success.amountValue": "${{plan}} miesięcznie", + "black.subscribe.success.paymentMethod": "Metoda płatności", + "black.subscribe.success.dateJoined": "Data dołączenia", + "black.subscribe.success.chargeNotice": "Twoja karta zostanie obciążona po aktywacji subskrypcji", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Użycie", + "workspace.nav.apiKeys": "Klucze API", + "workspace.nav.members": "Członkowie", + "workspace.nav.billing": "Rozliczenia", + "workspace.nav.settings": "Ustawienia", + + "workspace.home.banner.beforeLink": "Niezawodne, zoptymalizowane modele dla agentów kodujących.", + "workspace.lite.banner.beforeLink": "Niskokosztowe modele kodowania dla każdego.", + "workspace.home.billing.loading": "Ładowanie...", + "workspace.home.billing.enable": "Włącz rozliczenia", + "workspace.home.billing.currentBalance": "Aktualne saldo", + + "workspace.newUser.feature.tested.title": "Przetestowane i zweryfikowane modele", + "workspace.newUser.feature.tested.body": + "Przeprowadziliśmy testy porównawcze i przetestowaliśmy modele specjalnie dla agentów kodujących, aby zapewnić najlepszą wydajność.", + "workspace.newUser.feature.quality.title": "Najwyższa jakość", + "workspace.newUser.feature.quality.body": + "Dostęp do modeli skonfigurowanych pod kątem optymalnej wydajności - bez degradacji jakości czy przekierowywania do tańszych dostawców.", + "workspace.newUser.feature.lockin.title": "Brak blokady (Lock-in)", + "workspace.newUser.feature.lockin.body": + "Używaj Zen z dowolnym agentem kodującym i kontynuuj korzystanie z innych dostawców z OpenCode, kiedy tylko chcesz.", + "workspace.newUser.copyApiKey": "Skopiuj klucz API", + "workspace.newUser.copyKey": "Skopiuj klucz", + "workspace.newUser.copied": "Skopiowano!", + "workspace.newUser.step.enableBilling": "Włącz rozliczenia", + "workspace.newUser.step.login.before": "Uruchom", + "workspace.newUser.step.login.after": "i wybierz opencode", + "workspace.newUser.step.pasteKey": "Wklej swój klucz API", + "workspace.newUser.step.models.before": "Uruchom opencode i wpisz", + "workspace.newUser.step.models.after": "aby wybrać model", + + "workspace.models.title": "Modele", + "workspace.models.subtitle.beforeLink": "Zarządzaj dostępem członków obszaru roboczego do modeli.", + "workspace.models.table.model": "Model", + "workspace.models.table.enabled": "Włączony", + + "workspace.providers.title": "Przynieś własny klucz (BYOK)", + "workspace.providers.subtitle": "Skonfiguruj własne klucze API od dostawców AI.", + "workspace.providers.placeholder": "Wprowadź klucz API {{provider}} ({{prefix}}...)", + "workspace.providers.configure": "Konfiguruj", + "workspace.providers.edit": "Edytuj", + "workspace.providers.delete": "Usuń", + "workspace.providers.saving": "Zapisywanie...", + "workspace.providers.save": "Zapisz", + "workspace.providers.table.provider": "Dostawca", + "workspace.providers.table.apiKey": "Klucz API", + + "workspace.usage.title": "Historia użycia", + "workspace.usage.subtitle": "Ostatnie użycie API i koszty.", + "workspace.usage.empty": "Wykonaj pierwsze wywołanie API, aby rozpocząć.", + "workspace.usage.table.date": "Data", + "workspace.usage.table.model": "Model", + "workspace.usage.table.input": "Wejście", + "workspace.usage.table.output": "Wyjście", + "workspace.usage.table.cost": "Koszt", + "workspace.usage.table.session": "Sesja", + "workspace.usage.breakdown.input": "Wejście", + "workspace.usage.breakdown.cacheRead": "Odczyt Cache", + "workspace.usage.breakdown.cacheWrite": "Zapis Cache", + "workspace.usage.breakdown.output": "Wyjście", + "workspace.usage.breakdown.reasoning": "Rozumowanie", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Koszt", + "workspace.cost.subtitle": "Koszty użycia w podziale na modele.", + "workspace.cost.allModels": "Wszystkie modele", + "workspace.cost.allKeys": "Wszystkie klucze", + "workspace.cost.deletedSuffix": "(usunięte)", + "workspace.cost.empty": "Brak danych o użyciu dla wybranego okresu.", + "workspace.cost.subscriptionShort": "sub", + + "workspace.keys.title": "Klucze API", + "workspace.keys.subtitle": "Zarządzaj kluczami API do usług opencode.", + "workspace.keys.create": "Utwórz klucz API", + "workspace.keys.placeholder": "Wpisz nazwę klucza", + "workspace.keys.empty": "Utwórz klucz API bramy opencode", + "workspace.keys.table.name": "Nazwa", + "workspace.keys.table.key": "Klucz", + "workspace.keys.table.createdBy": "Utworzony przez", + "workspace.keys.table.lastUsed": "Ostatnio użyty", + "workspace.keys.copyApiKey": "Skopiuj klucz API", + "workspace.keys.delete": "Usuń", + + "workspace.members.title": "Członkowie", + "workspace.members.subtitle": "Zarządzaj członkami obszaru roboczego i ich uprawnieniami.", + "workspace.members.invite": "Zaproś członka", + "workspace.members.inviting": "Zapraszanie...", + "workspace.members.beta.beforeLink": "Obszary robocze są darmowe dla zespołów w fazie beta.", + "workspace.members.form.invitee": "Zaproszona osoba", + "workspace.members.form.emailPlaceholder": "Wpisz e-mail", + "workspace.members.form.role": "Rola", + "workspace.members.form.monthlyLimit": "Miesięczny limit wydatków", + "workspace.members.noLimit": "Bez limitu", + "workspace.members.noLimitLowercase": "bez limitu", + "workspace.members.invited": "zaproszono", + "workspace.members.edit": "Edytuj", + "workspace.members.delete": "Usuń", + "workspace.members.saving": "Zapisywanie...", + "workspace.members.save": "Zapisz", + "workspace.members.table.email": "E-mail", + "workspace.members.table.role": "Rola", + "workspace.members.table.monthLimit": "Limit miesięczny", + "workspace.members.role.admin": "Administrator", + "workspace.members.role.adminDescription": "Może zarządzać modelami, członkami i rozliczeniami", + "workspace.members.role.member": "Członek", + "workspace.members.role.memberDescription": "Może generować klucze API tylko dla siebie", + + "workspace.settings.title": "Ustawienia", + "workspace.settings.subtitle": "Zaktualizuj nazwę i preferencje obszaru roboczego.", + "workspace.settings.workspaceName": "Nazwa obszaru roboczego", + "workspace.settings.defaultName": "Domyślny", + "workspace.settings.updating": "Aktualizowanie...", + "workspace.settings.save": "Zapisz", + "workspace.settings.edit": "Edytuj", + + "workspace.billing.title": "Rozliczenia", + "workspace.billing.subtitle.beforeLink": "Zarządzaj metodami płatności.", + "workspace.billing.contactUs": "Skontaktuj się z nami", + "workspace.billing.subtitle.afterLink": "jeśli masz jakiekolwiek pytania.", + "workspace.billing.currentBalance": "Aktualne saldo", + "workspace.billing.add": "Dodaj $", + "workspace.billing.enterAmount": "Wpisz kwotę", + "workspace.billing.loading": "Ładowanie...", + "workspace.billing.addAction": "Dodaj", + "workspace.billing.addBalance": "Doładuj saldo", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Połączono ze Stripe", + "workspace.billing.manage": "Zarządzaj", + "workspace.billing.enable": "Włącz rozliczenia", + + "workspace.monthlyLimit.title": "Limit miesięczny", + "workspace.monthlyLimit.subtitle": "Ustaw miesięczny limit użycia dla swojego konta.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Ustawianie...", + "workspace.monthlyLimit.set": "Ustaw", + "workspace.monthlyLimit.edit": "Edytuj limit", + "workspace.monthlyLimit.noLimit": "Brak ustawionego limitu użycia.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Aktualne użycie za", + "workspace.monthlyLimit.currentUsage.beforeAmount": "wynosi $", + + "workspace.redeem.title": "Zrealizuj kupon", + "workspace.redeem.subtitle": "Zrealizuj kod kuponu, aby otrzymać środki lub korzyści.", + "workspace.redeem.placeholder": "Wpisz kod kuponu", + "workspace.redeem.redeem": "Zrealizuj", + "workspace.redeem.redeeming": "Realizowanie...", + "workspace.redeem.success": "Kupon został zrealizowany.", + + "workspace.reload.title": "Automatyczne doładowanie", + "workspace.reload.disabled.before": "Automatyczne doładowanie jest", + "workspace.reload.disabled.state": "wyłączone", + "workspace.reload.disabled.after": "Włącz, aby automatycznie doładować, gdy saldo jest niskie.", + "workspace.reload.enabled.before": "Automatyczne doładowanie jest", + "workspace.reload.enabled.state": "włączone", + "workspace.reload.enabled.middle": "Doładujemy", + "workspace.reload.processingFee": "opłata procesowa", + "workspace.reload.enabled.after": "gdy saldo osiągnie", + "workspace.reload.edit": "Edytuj", + "workspace.reload.enable": "Włącz", + "workspace.reload.enableAutoReload": "Włącz automatyczne doładowanie", + "workspace.reload.reloadAmount": "Doładuj kwotą $", + "workspace.reload.whenBalanceReaches": "Gdy saldo osiągnie $", + "workspace.reload.saving": "Zapisywanie...", + "workspace.reload.save": "Zapisz", + "workspace.reload.failedAt": "Doładowanie nie powiodło się o", + "workspace.reload.reason": "Powód:", + "workspace.reload.updatePaymentMethod": "Zaktualizuj metodę płatności i spróbuj ponownie.", + "workspace.reload.retrying": "Ponawianie...", + "workspace.reload.retry": "Spróbuj ponownie", + "workspace.reload.error.paymentFailed": "Płatność nie powiodła się.", + + "workspace.payments.title": "Historia płatności", + "workspace.payments.subtitle": "Ostatnie transakcje płatnicze.", + "workspace.payments.table.date": "Data", + "workspace.payments.table.paymentId": "ID płatności", + "workspace.payments.table.amount": "Kwota", + "workspace.payments.table.receipt": "Rachunek", + "workspace.payments.type.credit": "środki", + "workspace.payments.type.subscription": "subskrypcja", + "workspace.payments.view": "Zobacz", + + "workspace.black.loading": "Ładowanie...", + "workspace.black.time.day": "dzień", + "workspace.black.time.days": "dni", + "workspace.black.time.hour": "godzina", + "workspace.black.time.hours": "godzin(y)", + "workspace.black.time.minute": "minuta", + "workspace.black.time.minutes": "minut(y)", + "workspace.black.time.fewSeconds": "kilka sekund", + "workspace.black.subscription.title": "Subskrypcja", + "workspace.black.subscription.message": "Subskrybujesz OpenCode Black za ${{plan}} miesięcznie.", + "workspace.black.subscription.manage": "Zarządzaj subskrypcją", + "workspace.black.subscription.rollingUsage": "Użycie (okno 5h)", + "workspace.black.subscription.weeklyUsage": "Użycie tygodniowe", + "workspace.black.subscription.resetsIn": "Resetuje się za", + "workspace.black.subscription.useBalance": "Użyj dostępnego salda po osiągnięciu limitów użycia", + "workspace.black.waitlist.title": "Lista oczekujących", + "workspace.black.waitlist.joined": "Jesteś na liście oczekujących na plan OpenCode Black za ${{plan}} miesięcznie.", + "workspace.black.waitlist.ready": "Jesteśmy gotowi zapisać Cię do planu OpenCode Black za ${{plan}} miesięcznie.", + "workspace.black.waitlist.leave": "Opuść listę oczekujących", + "workspace.black.waitlist.leaving": "Opuszczanie...", + "workspace.black.waitlist.left": "Opuszczono", + "workspace.black.waitlist.enroll": "Zapisz się", + "workspace.black.waitlist.enrolling": "Zapisywanie...", + "workspace.black.waitlist.enrolled": "Zapisano", + "workspace.black.waitlist.enrollNote": + "Po kliknięciu Zapisz się, Twoja subskrypcja rozpocznie się natychmiast, a karta zostanie obciążona.", + + "workspace.lite.loading": "Ładowanie...", + "workspace.lite.time.day": "dzień", + "workspace.lite.time.days": "dni", + "workspace.lite.time.hour": "godzina", + "workspace.lite.time.hours": "godzin(y)", + "workspace.lite.time.minute": "minuta", + "workspace.lite.time.minutes": "minut(y)", + "workspace.lite.time.fewSeconds": "kilka sekund", + "workspace.lite.subscription.message": "Subskrybujesz OpenCode Go.", + "workspace.lite.subscription.manage": "Zarządzaj subskrypcją", + "workspace.lite.subscription.rollingUsage": "Użycie w ciągu 5 godzin", + "workspace.lite.subscription.rollingQuota": "Limit 5-godzinny", + "workspace.lite.subscription.weeklyUsage": "Użycie tygodniowe", + "workspace.lite.subscription.weeklyQuota": "Limit tygodniowy", + "workspace.lite.subscription.monthlyUsage": "Użycie miesięczne", + "workspace.lite.subscription.monthlyQuota": "Limit miesięczny", + "workspace.lite.subscription.resetsIn": "Resetuje się za", + "workspace.lite.subscription.showDetails": "Pokaż szczegóły", + "workspace.lite.subscription.hideDetails": "Ukryj szczegóły", + "workspace.lite.subscription.model": "Model", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Łącznie", + "workspace.lite.subscription.useBalance": "Użyj dostępnego salda po osiągnięciu limitów użycia", + "workspace.lite.subscription.selectProvider": + 'Wybierz "OpenCode Go" jako dostawcę w konfiguracji opencode, aby używać modeli Go.', + "workspace.lite.providers.title": "Dostawcy", + "workspace.lite.providers.description": "Kontroluj, którzy dostawcy są używani do routingu.", + "workspace.lite.providers.allowTraining": "Zezwalaj na modele wykorzystujące dane żądań do trenowania", + "workspace.lite.providers.useChina": "Włącz modele hostowane w Chinach", + "workspace.lite.black.message": + "Obecnie subskrybujesz OpenCode Black lub jesteś na liście oczekujących. Jeśli chcesz przejść na Go, najpierw anuluj subskrypcję.", + "workspace.lite.other.message": + "Inny członek tego obszaru roboczego już subskrybuje OpenCode Go. Tylko jeden członek na obszar roboczy może subskrybować.", + "workspace.lite.promo.description": + "OpenCode Go kosztuje {{price}} i zapewnia niezawodny dostęp do popularnych otwartych modeli kodowania z hojnymi limitami użycia.", + "workspace.lite.promo.price": "$10/miesiąc", + "workspace.lite.promo.modelsTitle": "Co zawiera", + "workspace.lite.promo.footer": + "Plan został opracowany przede wszystkim z myślą o użytkownikach z całego świata i zapewnia stabilny globalny dostęp. Ceny i limity użycia mogą ulec zmianie w miarę zdobywania doświadczeń na podstawie początkowego korzystania z usługi i otrzymywanych opinii.", + "workspace.lite.promo.subscribe": "Subskrybuj Go", + "workspace.lite.promo.subscribing": "Przekierowywanie...", + "workspace.lite.promo.otherMethods": "Inne metody płatności", + "workspace.lite.promo.selectMethod": "Wybierz metodę płatności", + + "workspace.referral.copyLink": "Kopiuj link", + "workspace.referral.copied": "Skopiowano", + "workspace.referral.overview.title": "Zaproś znajomych", + "workspace.referral.overview.subtitle": "Zdobądź $5, gdy znajomy się zasubskrybuje. On też dostanie $5.", + "workspace.referral.instructions.share": "Udostępnij swój link polecający", + "workspace.referral.instructions.subscribe": "Twój znajomy dołącza i subskrybuje Go", + "workspace.referral.instructions.claim": "Oboje otrzymujecie kredyt $5 do wykorzystania na limity użycia Go", + "workspace.referral.rewards.title": "Nagrody za polecenia", + "workspace.referral.rewards.description": "Wykorzystaj dostępne środki za polecenia na swoje użycie Go.", + "workspace.referral.rewards.subtitle": "Wykorzystano {{applied}} / {{total}} nagród.", + "workspace.referral.rewards.empty": "Brak nagród za polecenia.", + "workspace.referral.table.reward": "Nagroda", + "workspace.referral.table.referral": "Opis", + "workspace.referral.table.date": "Data", + "workspace.referral.reward.description.inviter": "Zaproszono {{email}}", + "workspace.referral.reward.description.invitee": "Zaproszony przez {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Subskrybuj, aby odblokować", + "workspace.referral.reward.action.view": "Zobacz nagrodę", + "workspace.referral.reward.action.applied": "Nagroda wykorzystana", + "workspace.referral.reward.source.pendingInviter": "Oczekiwanie na jego subskrypcję", + "workspace.referral.reward.source.pendingInvitee": "Subskrybuj, aby odblokować nagrodę", + "workspace.referral.reward.source.available": "Nagroda gotowa do wykorzystania", + "workspace.referral.reward.source.applied": "Nagroda wykorzystana", + "workspace.referral.reward.status.applied": "Nagroda wykorzystana", + "workspace.referral.reward.status.pendingInviter": "Subskrybuj, aby odblokować", + "workspace.referral.reward.status.pendingInvitee": "Subskrybuj, aby odblokować", + "workspace.referral.apply.noGo": "Subskrybuj, aby odblokować", + "workspace.referral.apply.preview": "Zobacz nagrodę", + "workspace.referral.apply.action": "Wykorzystaj", + "workspace.referral.apply.confirmTitle": "Wykorzystaj nagrodę", + "workspace.referral.apply.confirmBody": "Wykorzystaj {{amount}}, aby zmniejszyć aktualne użycie w tym workspace.", + "workspace.referral.apply.confirmAction": "Wykorzystaj", + + "download.title": "OpenCode | Pobierz", + "download.meta.description": "Pobierz OpenCode na macOS, Windows i Linux", + "download.hero.title": "Pobierz OpenCode Desktop", + "download.hero.subtitle": "Dostępne w wersji Beta na macOS, Windows i Linux", + "download.hero.button": "Pobierz na {{os}}", + "download.section.terminal": "Terminal OpenCode", + "download.section.desktop": "Pulpit OpenCode", + "download.section.extensions": "Rozszerzenia OpenCode", + "download.section.integrations": "Integracje OpenCode", + "download.action.download": "Pobierz", + "download.action.install": "Zainstaluj", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Niekoniecznie, ale prawdopodobnie. Będziesz potrzebować subskrypcji AI, jeśli chcesz połączyć OpenCode z płatnym dostawcą, chociaż możesz pracować z", + "download.faq.a3.localLink": "modelami lokalnymi", + "download.faq.a3.afterLocal.beforeZen": "za darmo. Chociaż zachęcamy użytkowników do korzystania z", + "download.faq.a3.afterZen": + ", OpenCode współpracuje ze wszystkimi popularnymi dostawcami, takimi jak OpenAI, Anthropic, xAI itp.", + + "download.faq.a5.p1": "OpenCode jest w 100% darmowy.", + "download.faq.a5.p2.beforeZen": + "Wszelkie dodatkowe koszty będą pochodzić z Twojej subskrypcji u dostawcy modelu. Chociaż OpenCode współpracuje z dowolnym dostawcą modeli, zalecamy korzystanie z", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": + "Twoje dane i informacje są przechowywane tylko wtedy, gdy tworzysz linki do udostępniania w OpenCode.", + "download.faq.a6.p2.beforeShare": "Dowiedz się więcej o", + "download.faq.a6.shareLink": "stronach udostępniania", + + "enterprise.title": "OpenCode | Rozwiązania Enterprise dla Twojej organizacji", + "enterprise.meta.description": "Skontaktuj się z OpenCode w sprawie rozwiązań dla przedsiębiorstw", + "enterprise.hero.title": "Twój kod jest Twój", + "enterprise.hero.body1": + "OpenCode działa bezpiecznie wewnątrz Twojej organizacji bez przechowywania danych czy kontekstu, oraz bez ograniczeń licencyjnych czy roszczeń własnościowych. Rozpocznij okres próbny ze swoim zespołem, a następnie wdróż go w całej organizacji, integrując z SSO i wewnętrzną bramą AI.", + "enterprise.hero.body2": "Daj nam znać, jak możemy pomóc.", + "enterprise.form.name.label": "Imię i nazwisko", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Rola", + "enterprise.form.role.placeholder": "Prezes Zarządu", + "enterprise.form.company.label": "Firma", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "E-mail firmowy", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Numer telefonu", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Jaki problem próbujesz rozwiązać?", + "enterprise.form.message.placeholder": "Potrzebujemy pomocy z...", + "enterprise.form.send": "Wyślij", + "enterprise.form.sending": "Wysyłanie...", + "enterprise.form.success": "Wiadomość wysłana, skontaktujemy się wkrótce.", + "enterprise.form.success.submitted": "Formularz został pomyślnie wysłany.", + "enterprise.form.error.allFieldsRequired": "Wszystkie pola są wymagane.", + "enterprise.form.error.invalidEmailFormat": "Nieprawidłowy format adresu e-mail.", + "enterprise.form.error.internalServer": "Wewnętrzny błąd serwera.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "Czym jest OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise jest dla organizacji, które chcą mieć pewność, że ich kod i dane nigdy nie opuszczą ich infrastruktury. Można to osiągnąć dzięki scentralizowanej konfiguracji, która integruje się z Twoim SSO i wewnętrzną bramą AI.", + "enterprise.faq.q2": "Jak zacząć z OpenCode Enterprise?", + "enterprise.faq.a2": + "Po prostu rozpocznij wewnętrzny okres próbny ze swoim zespołem. OpenCode domyślnie nie przechowuje Twojego kodu ani danych kontekstowych, co ułatwia start. Następnie skontaktuj się z nami, aby omówić opcje cenowe i wdrożeniowe.", + "enterprise.faq.q3": "Jak działa cennik enterprise?", + "enterprise.faq.a3": + "Oferujemy cennik enterprise za stanowisko (per-seat). Jeśli masz własną bramę LLM, nie pobieramy opłat za wykorzystane tokeny. Aby uzyskać więcej szczegółów, skontaktuj się z nami w celu uzyskania wyceny dostosowanej do potrzeb Twojej organizacji.", + "enterprise.faq.q4": "Czy moje dane są bezpieczne z OpenCode Enterprise?", + "enterprise.faq.a4": + "Tak. OpenCode nie przechowuje Twojego kodu ani danych kontekstowych. Całe przetwarzanie odbywa się lokalnie lub poprzez bezpośrednie wywołania API do Twojego dostawcy AI. Dzięki centralnej konfiguracji i integracji SSO, Twoje dane pozostają bezpieczne w infrastrukturze Twojej organizacji.", + + "brand.title": "OpenCode | Marka", + "brand.meta.description": "Wytyczne marki OpenCode", + "brand.heading": "Wytyczne marki", + "brand.subtitle": "Zasoby i aktywa, które pomogą Ci pracować z marką OpenCode.", + "brand.downloadAll": "Pobierz wszystkie zasoby", + + "changelog.title": "OpenCode | Dziennik zmian", + "changelog.meta.description": "Notatki o wydaniu i dziennik zmian OpenCode", + "changelog.hero.title": "Dziennik zmian", + "changelog.hero.subtitle": "Nowe aktualizacje i ulepszenia OpenCode", + "changelog.empty": "Nie znaleziono wpisów w dzienniku zmian.", + "changelog.viewJson": "Zobacz JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarki", + "bench.list.table.agent": "Agent", + "bench.list.table.model": "Model", + "bench.list.table.score": "Wynik", + "bench.submission.error.allFieldsRequired": "Wszystkie pola są wymagane.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Nie znaleziono zadania", + "bench.detail.na": "Brak danych", + "bench.detail.labels.agent": "Agent", + "bench.detail.labels.model": "Model", + "bench.detail.labels.task": "Zadanie", + "bench.detail.labels.repo": "Repozytorium", + "bench.detail.labels.from": "Z", + "bench.detail.labels.to": "Do", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Średni czas trwania", + "bench.detail.labels.averageScore": "Średni wynik", + "bench.detail.labels.averageCost": "Średni koszt", + "bench.detail.labels.summary": "Podsumowanie", + "bench.detail.labels.runs": "Uruchomienia", + "bench.detail.labels.score": "Wynik", + "bench.detail.labels.base": "Baza", + "bench.detail.labels.penalty": "Kara", + "bench.detail.labels.weight": "waga", + "bench.detail.table.run": "Uruchomienie", + "bench.detail.table.score": "Wynik (Baza - Kara)", + "bench.detail.table.cost": "Koszt", + "bench.detail.table.duration": "Czas trwania", + "bench.detail.run.title": "Uruchomienie {{n}}", + "bench.detail.rawJson": "Surowy JSON", +} as const + +export type Key = keyof typeof dict +export type Dict = Record diff --git a/packages/console/app/src/i18n/ru.ts b/packages/console/app/src/i18n/ru.ts new file mode 100644 index 0000000000000000000000000000000000000000..37f6e43b06d68fa7bc150d1b05eb91f891d7d9f6 --- /dev/null +++ b/packages/console/app/src/i18n/ru.ts @@ -0,0 +1,885 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash получает 4x лимиты использования на ограниченное время", + "go.graph.bonus": "Лимит ×{{count}}", + "nav.github": "GitHub", + "nav.docs": "Документация", + "nav.changelog": "Список изменений", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Войти", + "nav.free": "Скачать", + "nav.home": "Главная", + "nav.openMenu": "Открыть меню", + "nav.getStartedFree": "Начать бесплатно", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Скопировать логотип как SVG", + "nav.context.copyWordmark": "Скопировать название как SVG", + "nav.context.brandAssets": "Ресурсы бренда", + + "footer.github": "GitHub", + "footer.docs": "Документация", + "footer.changelog": "Список изменений", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Бренд", + "legal.privacy": "Конфиденциальность", + "legal.terms": "Условия", + + "email.title": "Узнайте первыми о выходе новых продуктов", + "email.subtitle": "Присоединяйтесь к списку ожидания для раннего доступа.", + "email.placeholder": "Email адрес", + "email.subscribe": "Подписаться", + "email.success": "Почти готово, проверьте почту и подтвердите ваш email", + + "notFound.title": "Не найдено | opencode", + "notFound.heading": "404 - Страница не найдена", + "notFound.home": "Главная", + "notFound.docs": "Документация", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "светлый логотип opencode", + "notFound.logoDarkAlt": "темный логотип opencode", + + "user.logout": "Выйти", + + "auth.callback.error.codeMissing": "Код авторизации не найден.", + + "workspace.select": "Выбрать рабочее пространство", + "workspace.createNew": "+ Создать рабочее пространство", + "workspace.modal.title": "Создать рабочее пространство", + "workspace.modal.placeholder": "Введите название рабочего пространства", + + "common.cancel": "Отмена", + "common.creating": "Создание...", + "common.create": "Создать", + "common.contactUs": "Свяжитесь с нами", + + "common.videoUnsupported": "Ваш браузер не поддерживает видео тег.", + "common.figure": "Рис {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Подробнее", + + "error.invalidPlan": "Неверный план", + "error.workspaceRequired": "Требуется ID рабочего пространства", + "error.alreadySubscribed": "У этого рабочего пространства уже есть подписка", + "error.limitRequired": "Требуется лимит.", + "error.monthlyLimitInvalid": "Укажите корректный ежемесячный лимит.", + "error.workspaceNameRequired": "Требуется название рабочего пространства.", + "error.nameTooLong": "Название должно быть не более 255 символов.", + "error.emailRequired": "Требуется email", + "error.roleRequired": "Требуется роль", + "error.idRequired": "Требуется ID", + "error.nameRequired": "Требуется имя", + "error.providerRequired": "Требуется провайдер", + "error.apiKeyRequired": "Требуется API ключ", + "error.modelRequired": "Требуется модель", + "error.reloadAmountMin": "Сумма пополнения должна быть не менее ${{amount}}", + "error.reloadTriggerMin": "Порог баланса должен быть не менее ${{amount}}", + + "app.meta.description": "OpenCode - AI-агент с открытым кодом для программирования.", + + "home.title": "OpenCode | AI-агент с открытым кодом для программирования", + + "temp.title": "opencode | AI-агент для программирования в терминале", + "temp.hero.title": "AI-агент для программирования в терминале", + "temp.zen": "opencode zen", + "temp.getStarted": "Начать", + "temp.feature.native.title": "Нативный TUI", + "temp.feature.native.body": "Отзывчивый, нативный, темизируемый терминальный интерфейс", + "temp.feature.zen.beforeLink": "", + "temp.feature.zen.link": "Отобранный список моделей", + "temp.feature.zen.afterLink": "от opencode", + "temp.feature.models.beforeLink": "Поддерживает 75+ провайдеров LLM через", + "temp.feature.models.afterLink": ", включая локальные модели", + "temp.screenshot.caption": "OpenCode TUI с темой tokyonight", + "temp.screenshot.alt": "OpenCode TUI с темой tokyonight", + "temp.logoLightAlt": "светлый логотип opencode", + "temp.logoDarkAlt": "темный логотип opencode", + + "home.banner.badge": "Новое", + "home.banner.text": "Представляем вкладки в десктопном приложении.", + "home.banner.platforms": "Доступно на macOS, Windows и Linux", + "home.banner.downloadNow": "Скачать", + "home.banner.downloadBetaNow": "Скачать бету для десктопа", + "home.promo.title": "Представляем вкладки в десктопном приложении", + "home.promo.body": "Организуйте работу и активные сессии с помощью вкладок.", + "home.promo.cta": "Скачайте последнюю версию, чтобы начать.", + "home.promo.close": "Закрыть объявление о десктопном приложении", + + "home.hero.title": "AI-агент с открытым кодом для программирования", + "home.hero.subtitle.a": "Бесплатные модели включены, или подключите любую модель от любого провайдера,", + "home.hero.subtitle.b": "включая Claude, GPT, Gemini и другие.", + + "home.install.ariaLabel": "Варианты установки", + + "home.what.title": "Что такое OpenCode?", + "home.what.body": + "OpenCode — это агент с открытым исходным кодом, который помогает писать код в терминале, IDE или на десктопе.", + "home.what.lsp.title": "Поддержка LSP", + "home.what.lsp.body": "Автоматически загружает нужные LSP для LLM", + "home.what.multiSession.title": "Мульти-сессии", + "home.what.multiSession.body": "Запускайте несколько агентов параллельно в одном проекте", + "home.what.shareLinks.title": "Общие ссылки", + "home.what.shareLinks.body": "Делитесь ссылкой на любую сессию для справки или отладки", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Войдите через GitHub, чтобы использовать ваш аккаунт Copilot", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Войдите через OpenAI, чтобы использовать ваш аккаунт ChatGPT Plus или Pro", + "home.what.anyModel.title": "Любая модель", + "home.what.anyModel.body": "75+ провайдеров LLM через Models.dev, включая локальные модели", + "home.what.anyEditor.title": "Любой редактор", + "home.what.anyEditor.body": "Доступно как терминальный интерфейс, десктопное приложение и расширение для IDE", + "home.what.readDocs": "Читать документацию", + + "home.growth.title": "AI-агент с открытым кодом для программирования", + "home.growth.body": + "С более чем {{stars}} звезд на GitHub, {{contributors}} контрибьюторов и {{commits}} коммитов, OpenCode доверяют более {{monthlyUsers}} разработчиков ежемесячно.", + "home.growth.githubStars": "Звезд на GitHub", + "home.growth.contributors": "Контрибьюторов", + "home.growth.monthlyDevs": "Разработчиков в месяц", + + "home.privacy.title": "Создан с заботой о приватности", + "home.privacy.body": + "OpenCode не хранит ваш код или контекстные данные, поэтому он может работать в средах, чувствительных к приватности.", + "home.privacy.learnMore": "Подробнее о", + "home.privacy.link": "приватности", + + "home.faq.q1": "Что такое OpenCode?", + "home.faq.a1": + "OpenCode — это агент с открытым исходным кодом, который помогает писать и запускать код с любой AI-моделью. Доступен как терминальный интерфейс, десктопное приложение или расширение для IDE.", + "home.faq.q2": "Как использовать OpenCode?", + "home.faq.a2.before": "Проще всего начать с чтения", + "home.faq.a2.link": "введения", + "home.faq.q3": "Нужны ли дополнительные подписки на AI для использования OpenCode?", + "home.faq.a3.p1": + "Не обязательно, OpenCode поставляется с набором бесплатных моделей, которые можно использовать без создания аккаунта.", + "home.faq.a3.p2.beforeZen": + "Помимо этого, вы можете использовать любые популярные модели для кодинга, создав аккаунт", + "home.faq.a3.p2.afterZen": ".", + "home.faq.a3.p3": + "Хотя мы рекомендуем использовать Zen, OpenCode также работает со всеми популярными провайдерами, такими как OpenAI, Anthropic, xAI и др.", + "home.faq.a3.p4.beforeLocal": "Вы даже можете подключить ваши", + "home.faq.a3.p4.localLink": "локальные модели", + "home.faq.q4": "Могу ли я использовать мои существующие AI-подписки с OpenCode?", + "home.faq.a4.p1": + "Да, OpenCode поддерживает подписки всех основных провайдеров. Вы можете использовать ваши подписки Claude Pro/Max, ChatGPT Plus/Pro или GitHub Copilot.", + "home.faq.q5": "Можно ли использовать OpenCode только в терминале?", + "home.faq.a5.beforeDesktop": "Больше нет! OpenCode теперь доступен как приложение для", + "home.faq.a5.desktop": "десктопа", + "home.faq.a5.and": "и", + "home.faq.a5.web": "веба", + "home.faq.q6": "Сколько стоит OpenCode?", + "home.faq.a6": + "OpenCode на 100% бесплатен. Он также включает набор бесплатных моделей. Дополнительные расходы могут возникнуть, если вы подключите другого провайдера.", + "home.faq.q7": "Как насчет данных и приватности?", + "home.faq.a7.p1": + "Ваши данные сохраняются только тогда, когда вы используете наши бесплатные модели или создаете ссылки для шеринга.", + "home.faq.a7.p2.beforeModels": "Подробнее о", + "home.faq.a7.p2.modelsLink": "наших моделях", + "home.faq.a7.p2.and": "и", + "home.faq.a7.p2.shareLink": "страницах шеринга", + "home.faq.q8": "OpenCode — это open source?", + "home.faq.a8.p1": "Да, OpenCode полностью open source. Исходный код доступен публично на", + "home.faq.a8.p2": "под", + "home.faq.a8.mitLicense": "лицензией MIT", + "home.faq.a8.p3": + ", что означает, что любой может использовать, изменять или вносить вклад в его развитие. Любой участник сообщества может создавать issues, отправлять pull requests и расширять функциональность.", + + "home.zenCta.title": "Доступ к надежным оптимизированным моделям для кодинг-агентов", + "home.zenCta.body": + "Zen дает доступ к отобранному набору AI-моделей, которые OpenCode протестировал и проверил специально для кодинг-агентов. Не нужно беспокоиться о нестабильной производительности и качестве разных провайдеров, используйте проверенные модели, которые работают.", + "home.zenCta.link": "Узнать о Zen", + + "zen.title": "OpenCode Zen | Набор надежных оптимизированных моделей для кодинг-агентов", + "zen.hero.title": "Надежные оптимизированные модели для кодинг-агентов", + "zen.hero.body": + "Zen дает доступ к отобранному набору AI-моделей, которые OpenCode протестировал и проверил специально для кодинг-агентов. Не нужно беспокоиться о нестабильной производительности и качестве, используйте проверенные модели, которые работают.", + + "zen.faq.q1": "Что такое OpenCode Zen?", + "zen.faq.a1": + "Zen — это отобранный набор AI-моделей, протестированных и проверенных для кодинг-агентов командой, стоящей за OpenCode.", + "zen.faq.q2": "Почему Zen точнее?", + "zen.faq.a2": + "Zen предоставляет только те модели, которые были специально протестированы и проверены для кодинг-агентов. Вы же не режете стейк ножом для масла, не используйте плохие модели для кодинга.", + "zen.faq.q3": "Zen дешевле?", + "zen.faq.a3": + "Zen — некоммерческий проект. Zen транслирует расходы от провайдеров моделей вам. Чем больше использование Zen, тем лучшие тарифы OpenCode может согласовать и передать вам.", + "zen.faq.q4": "Сколько стоит Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "взимает плату за запрос", + "zen.faq.a4.p1.afterPricing": + "с нулевой наценкой, так что вы платите ровно столько, сколько взимает провайдер модели.", + "zen.faq.a4.p2.beforeAccount": + "Общая стоимость зависит от использования, и вы можете установить ежемесячные лимиты расходов в своем", + "zen.faq.a4.p2.accountLink": "аккаунте", + "zen.faq.a4.p3": + "Для покрытия расходов OpenCode добавляет лишь небольшую комиссию за обработку платежа в размере $1.23 при пополнении баланса на $20.", + "zen.faq.q5": "Как насчет данных и приватности?", + "zen.faq.a5.beforeExceptions": + "Все модели Zen размещены в США. Провайдеры следуют политике нулевого хранения и не используют ваши данные для обучения моделей, за", + "zen.faq.a5.exceptionsLink": "следующими исключениями", + "zen.faq.q6": "Могу ли я установить лимиты расходов?", + "zen.faq.a6": "Да, вы можете установить ежемесячные лимиты расходов в своем аккаунте.", + "zen.faq.q7": "Могу ли я отменить?", + "zen.faq.a7": "Да, вы можете отключить оплату в любое время и использовать оставшийся баланс.", + "zen.faq.q8": "Могу ли я использовать Zen с другими кодинг-агентами?", + "zen.faq.a8": + "Хотя Zen отлично работает с OpenCode, вы можете использовать Zen с любым агентом. Следуйте инструкциям по настройке в вашем любимом агенте.", + "zen.faq.q9": "Могу ли я получить возврат средств?", + "zen.faq.a9": + "Вы можете претендовать на возврат, если списание произошло в течение последних 14 дней и средства, полученные при этой покупке, не были использованы. {{contact}}, чтобы запросить возврат.", + + "zen.cta.start": "Начать работу с Zen", + "zen.pricing.title": "Пополнить баланс на $20 (Pay as you go)", + "zen.pricing.fee": "(+$1.23 комиссия за обработку карты)", + "zen.pricing.body": "Используйте с любым агентом. Установите ежемесячные лимиты. Отмените в любое время.", + "zen.problem.title": "Какую проблему решает Zen?", + "zen.problem.body": + "Доступно множество моделей, но лишь немногие хорошо работают с кодинг-агентами. Большинство провайдеров настраивают их по-разному с разными результатами.", + "zen.problem.subtitle": "Мы исправляем это для всех, а не только для пользователей OpenCode.", + "zen.problem.item1": "Тестирование избранных моделей и консультации с их командами", + "zen.problem.item2": "Работа с провайдерами для обеспечения правильной доставки", + "zen.problem.item3": "Бенчмаркинг всех рекомендуемых нами комбинаций модель-провайдер", + "zen.how.title": "Как работает Zen", + "zen.how.body": "Хотя мы предлагаем использовать Zen с OpenCode, вы можете использовать его с любым агентом.", + "zen.how.step1.title": "Зарегистрируйтесь и пополните баланс на $20", + "zen.how.step1.beforeLink": "следуйте", + "zen.how.step1.link": "инструкциям по настройке", + "zen.how.step2.title": "Используйте Zen с прозрачным ценообразованием", + "zen.how.step2.link": "оплата за запрос", + "zen.how.step2.afterLink": "с нулевой наценкой", + "zen.how.step3.title": "Автопополнение", + "zen.how.step3.body": "когда ваш баланс достигнет $5, мы автоматически добавим $20", + "zen.privacy.title": "Ваша приватность важна для нас", + "zen.privacy.beforeExceptions": + "Все модели Zen размещены в США. Провайдеры следуют политике нулевого хранения и не используют ваши данные для обучения моделей, за", + "zen.privacy.exceptionsLink": "следующими исключениями", + + "go.title": "OpenCode Go | Недорогие модели для кодинга для всех", + "go.meta.description": + "Go стоит $10/месяц и предлагает щедрые лимиты использования и надежный доступ к ведущим моделям для кодинга.", + "go.hero.title": "Недорогие модели для кодинга для всех", + "go.hero.body": + "Go открывает доступ к агентам-программистам разработчикам по всему миру. Предлагая щедрые лимиты и надежный доступ к наиболее способным моделям с открытым исходным кодом, вы можете создавать проекты с мощными агентами, не беспокоясь о затратах или доступности.", + + "go.cta.start": "Подписаться на Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Подписаться на Go", + "go.cta.price": "$10/месяц", + "go.pricing.body": + "Используйте с любым агентом. $10/месяц. Пополняйте баланс при необходимости. Отменить можно в любое время.", + "go.graph.free": "Бесплатно", + "go.graph.freePill": "Big Pickle и бесплатные модели", + "go.graph.go": "Go", + "go.graph.label": "Запросов за 5 часов", + "go.graph.period": "Использование", + "go.graph.model": "Модель", + "go.graph.requests": "Примерное число запросов / 5 ч", + "go.graph.allowance": "Использование за месяц", + "go.graph.new": "Новое", + "go.graph.scale": "Нелинейная шкала числа запросов", + "go.graph.showAll": "Показать все модели ({{count}})", + "go.graph.showLess": "Показать меньше моделей", + "go.graph.limitedRegions": "доступно в отдельных регионах", + "go.graph.limitedTime": "ограниченное время", + "go.graph.usageLimits": "Лимиты использования", + "go.graph.aria": "Запросов за 5ч: {{free}} против {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "изменил мою жизнь, это действительно очевидный выбор.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Founder, SEED, PM, Melt, Pop, Dapt, Cadmus, и ViewPoint", + "go.testimonials.jay.quoteBefore": "4 из 5 человек в нашей команде любят использовать", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "Я не могу не порекомендовать", + "go.testimonials.adam.quoteAfter": "достаточно сильно. Серьезно, это очень круто.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "С", + "go.testimonials.david.quoteAfter": + "я знаю, что все модели протестированы и идеально подходят для агентов-программистов.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Intern, Nvidia (4 раза)", + "go.testimonials.frank.quote": "Жаль, что я больше не в Nvidia.", + "go.problem.title": "Какую проблему решает Go?", + "go.problem.body": + "Мы стремимся сделать OpenCode доступным для как можно большего числа людей. OpenCode Go - это недорогая подписка за $10/месяц. Она предоставляет щедрые лимиты и надежный доступ к самым мощным моделям с открытым исходным кодом.", + "go.problem.subtitle": " ", + "go.problem.item1": "Недорогая подписка", + "go.problem.item2": "Щедрые лимиты и надежный доступ", + "go.problem.item3": "Создан для максимального числа программистов", + "go.problem.item4": "Отобранные модели, протестированные для агентного программирования", + "go.how.title": "Как работает Go", + "go.how.body": "Go стоит $10/месяц. Вы можете использовать его с OpenCode или любым агентом.", + "go.how.step1.title": "Создайте аккаунт", + "go.how.step1.beforeLink": "следуйте", + "go.how.step1.link": "инструкциям по настройке", + "go.how.step2.title": "Подпишитесь на Go", + "go.how.step2.link": "$10/месяц", + "go.how.step2.afterLink": "с щедрыми лимитами", + "go.how.step3.title": "Начните кодить", + "go.how.step3.body": "с надежным доступом к open-source моделям", + "go.privacy.title": "Ваша приватность важна для нас", + "go.privacy.body": + "План разработан в первую очередь для международных пользователей, с моделями, размещенными в США, ЕС и Сингапуре для стабильного глобального доступа.", + "go.privacy.contactAfter": "если у вас есть вопросы.", + "go.privacy.beforeExceptions": + "Модели Go размещены в США. Провайдеры следуют политике нулевого хранения и не используют ваши данные для обучения моделей, за", + "go.privacy.exceptionsLink": "следующими исключениями", + "go.faq.q1": "Что такое OpenCode Go?", + "go.faq.a1": + "Go — это недорогая подписка, дающая надежный доступ к мощным моделям с открытым исходным кодом для агентов-программистов.", + "go.faq.q2": "Какие модели включает Go?", + "go.faq.a2": "Go включает перечисленные ниже модели с щедрыми лимитами и надежным доступом.", + "go.faq.q3": "Go — это то же самое, что и Zen?", + "go.faq.a3": + "Нет. Zen оплачивается по мере использования, а Go стоит $10/месяц и предлагает щедрые лимиты и надежный доступ к отобранным моделям.", + "go.faq.q4": "Сколько стоит Go?", + "go.faq.a4.p1.beforePricing": "Go стоит", + "go.faq.a4.p1.pricingLink": "$10/месяц", + "go.faq.a4.p1.afterPricing": "с щедрыми лимитами.", + "go.faq.a4.p2.beforeAccount": "Вы можете управлять подпиской в своем", + "go.faq.a4.p2.accountLink": "аккаунте", + "go.faq.a4.p3": "Отмена в любое время.", + "go.faq.q5": "Как насчет данных и приватности?", + "go.faq.a5.model": "Модель", + "go.faq.a5.training": "Обучение моделей", + "go.faq.a5.retention": "Хранение данных", + "go.faq.a5.retention30": "30 дней", + "go.faq.a5.retention0": "0 дней", + "go.faq.a5.used": "Используется", + "go.faq.a5.notUsed": "Не используется", + "go.faq.a5.noAgreement": "Нет соглашения", + "go.faq.a5.notZdr": "Не ZDR", + "go.faq.a5.grokRetention": + "ZDR отключает важные функции API, зависящие от сохраненных данных, включая Responses API с сохранением состояния, Files and Collections и Batch API.", + "go.faq.a5.gptRetention": + "Журналы мониторинга злоупотреблений создаются при любом использовании функций API и хранятся до 30 дней.", + "go.faq.a5.learnMore": "Подробнее", + "go.faq.a5.deepseekRetention": + "Соглашение ZDR продлевается ежемесячно. Текущее соглашение действует до 30 сентября 2026 года.", + "go.faq.a5.museRetention": + "Значительно сниженная стоимость токенов в обмен на разрешение использовать ваши промпты и ответы для обучения будущих моделей Meta.", + + "go.faq.a5.beforeExceptions": + "Модели Go размещены в США. Провайдеры следуют политике нулевого хранения и не используют ваши данные для обучения моделей, за", + "go.faq.a5.exceptionsLink": "следующими исключениями", + "go.faq.q6": "Могу ли я пополнить баланс?", + "go.faq.a6": "Если вам нужно больше использования, вы можете пополнить баланс в своем аккаунте.", + "go.faq.q7": "Могу ли я отменить подписку?", + "go.faq.a7": "Да, вы можете отменить подписку в любое время.", + "go.faq.q8": "Могу ли я использовать Go с другими кодинг-агентами?", + "go.faq.a8": + "Да, вы можете использовать Go с любым агентом. Следуйте инструкциям по настройке в вашем предпочитаемом агенте.", + + "go.faq.q9": "В чем разница между бесплатными моделями и Go?", + "go.faq.a9": + "Бесплатные модели включают Big Pickle и доступные на данный момент промо-модели с квотой 200 запросов/день. Go предлагает набор отобранных моделей с более высокими квотами запросов, применяемыми в скользящих окнах (5 часов, неделя и месяц), что примерно эквивалентно базовым лимитам $12 за 5 часов, $30 в неделю и $60 в месяц; лимиты для отдельных моделей могут отличаться (фактическое количество запросов зависит от модели и использования).", + "go.faq.q10": "Могу ли я получить возврат средств?", + "go.faq.a10": + "Вы можете претендовать на возврат, если списание произошло в течение последних 14 дней и вы не использовали лимит Go в этом расчетном периоде. {{contact}}, чтобы запросить возврат.", + + "zen.api.error.rateLimitExceeded": "Превышен лимит запросов. Пожалуйста, попробуйте позже.", + "zen.api.error.modelNotSupported": "Модель {{model}} не поддерживается", + "zen.api.error.modelFormatNotSupported": "Модель {{model}} не поддерживается для формата {{format}}", + "zen.api.error.noProviderAvailable": "Нет доступных провайдеров", + "zen.api.error.providerNotSupported": "Провайдер {{provider}} не поддерживается", + "zen.api.error.missingApiKey": "Отсутствует API ключ.", + "zen.api.error.invalidApiKey": "Неверный API ключ.", + "zen.api.error.requestBlockedByUpstreamProvider": "Запрос заблокирован вышестоящим провайдером.", + "zen.api.error.subscriptionQuotaExceeded": "Квота подписки превышена. Повторите попытку через {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "Достигнут лимит использования за 5 часов. Сбросится через {{retryIn}}. Чтобы продолжить использовать эту модель сейчас, включите оплату с доступного баланса: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Достигнут недельный лимит использования. Сбросится через {{retryIn}}. Чтобы продолжить использовать эту модель сейчас, включите оплату с доступного баланса: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Достигнут месячный лимит использования. Сбросится через {{retryIn}}. Чтобы продолжить использовать эту модель сейчас, включите оплату с доступного баланса: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Нет способа оплаты. Добавьте способ оплаты здесь: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Недостаточно средств. Управляйте оплатой здесь: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Ваше рабочее пространство достигло ежемесячного лимита расходов в ${{amount}}. Управляйте лимитами здесь: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Вы достигли ежемесячного лимита расходов в ${{amount}}. Управляйте лимитами здесь: {{membersUrl}}", + "zen.api.error.modelDisabled": "Модель отключена", + "zen.api.error.regionNotAllowed": + "Последняя версия этой модели размещена только в Китае. Чтобы использовать её, необходимо явно подтвердить согласие: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Эта модель недоступна в вашей стране.", + "zen.api.error.trainingNotAllowed": + "Эта модель собирает данные, которые используются для улучшения её качества, и требует явного согласия: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "Бесплатная акция для {{model}} завершена. Вы можете продолжить использование модели, подписавшись на OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | Доступ к лучшим моделям для кодинга в мире", + "black.meta.description": "Получите доступ к Claude, GPT, Gemini и другим моделям с подпиской OpenCode Black.", + "black.hero.title": "Доступ к лучшим моделям для кодинга в мире", + "black.hero.subtitle": "Включая Claude, GPT, Gemini и другие", + "black.title": "OpenCode Black | Цены", + "black.paused": "Регистрация на план Black временно приостановлена.", + "black.plan.icon20": "План Black 20", + "black.plan.icon100": "План Black 100", + "black.plan.icon200": "План Black 200", + "black.plan.multiplier100": "в 5x больше использования, чем Black 20", + "black.plan.multiplier200": "в 20x больше использования, чем Black 20", + "black.price.perMonth": "в месяц", + "black.price.perPersonBilledMonthly": "за человека при ежемесячной оплате", + "black.terms.1": "Ваша подписка начнется не сразу", + "black.terms.2": "Вы будете добавлены в список ожидания и активированы в ближайшее время", + "black.terms.3": "Оплата с карты будет списана только при активации подписки", + "black.terms.4": + "Действуют лимиты использования; интенсивное автоматизированное использование может исчерпать лимиты быстрее", + "black.terms.5": "Подписки предназначены для частных лиц, для команд обратитесь в Enterprise", + "black.terms.6": "Лимиты могут быть скорректированы, а планы могут быть прекращены в будущем", + "black.terms.7": "Отмените подписку в любое время", + "black.action.continue": "Продолжить", + "black.finePrint.beforeTerms": "Указанные цены не включают применимые налоги", + "black.finePrint.terms": "Условия обслуживания", + "black.workspace.title": "OpenCode Black | Выбор рабочего пространства", + "black.workspace.selectPlan": "Выберите рабочее пространство для этого плана", + "black.workspace.name": "Рабочее пространство {{n}}", + "black.subscribe.title": "Подписаться на OpenCode Black", + "black.subscribe.paymentMethod": "Способ оплаты", + "black.subscribe.loadingPaymentForm": "Загрузка формы оплаты...", + "black.subscribe.selectWorkspaceToContinue": "Выберите рабочее пространство для продолжения", + "black.subscribe.failurePrefix": "Ой!", + "black.subscribe.error.generic": "Произошла ошибка", + "black.subscribe.error.invalidPlan": "Неверный план", + "black.subscribe.error.workspaceRequired": "Требуется ID рабочего пространства", + "black.subscribe.error.alreadySubscribed": "У этого рабочего пространства уже есть подписка", + "black.subscribe.processing": "Обработка...", + "black.subscribe.submit": "Подписаться на ${{plan}}", + "black.subscribe.form.chargeNotice": "Оплата будет списана только при активации вашей подписки", + "black.subscribe.success.title": "Вы в списке ожидания OpenCode Black", + "black.subscribe.success.subscriptionPlan": "План подписки", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Сумма", + "black.subscribe.success.amountValue": "${{plan}} в месяц", + "black.subscribe.success.paymentMethod": "Способ оплаты", + "black.subscribe.success.dateJoined": "Дата присоединения", + "black.subscribe.success.chargeNotice": "С вашей карты будет списана оплата при активации подписки", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Использование", + "workspace.nav.apiKeys": "API Ключи", + "workspace.nav.members": "Участники", + "workspace.nav.billing": "Оплата", + "workspace.nav.settings": "Настройки", + + "workspace.home.banner.beforeLink": "Надежные оптимизированные модели для кодинг-агентов.", + "workspace.lite.banner.beforeLink": "Недорогие модели для кодинга, доступные каждому.", + "workspace.home.billing.loading": "Загрузка...", + "workspace.home.billing.enable": "Включить оплату", + "workspace.home.billing.currentBalance": "Текущий баланс", + + "workspace.newUser.feature.tested.title": "Протестированные и проверенные модели", + "workspace.newUser.feature.tested.body": + "Мы провели бенчмаркинг и тестирование моделей специально для кодинг-агентов, чтобы обеспечить лучшую производительность.", + "workspace.newUser.feature.quality.title": "Высочайшее качество", + "workspace.newUser.feature.quality.body": + "Доступ к моделям, настроенным для оптимальной производительности — никаких даунгрейдов или перенаправления к дешевым провайдерам.", + "workspace.newUser.feature.lockin.title": "Без привязки (Lock-in)", + "workspace.newUser.feature.lockin.body": + "Используйте Zen с любым кодинг-агентом и продолжайте использовать других провайдеров с opencode, когда захотите.", + "workspace.newUser.copyApiKey": "Копировать API ключ", + "workspace.newUser.copyKey": "Копировать ключ", + "workspace.newUser.copied": "Скопировано!", + "workspace.newUser.step.enableBilling": "Включить оплату", + "workspace.newUser.step.login.before": "Запустите", + "workspace.newUser.step.login.after": "и выберите opencode", + "workspace.newUser.step.pasteKey": "Вставьте ваш API ключ", + "workspace.newUser.step.models.before": "Запустите opencode и выполните", + "workspace.newUser.step.models.after": "для выбора модели", + + "workspace.models.title": "Модели", + "workspace.models.subtitle.beforeLink": + "Управляйте тем, к каким моделям имеют доступ участники рабочего пространства.", + "workspace.models.table.model": "Модель", + "workspace.models.table.enabled": "Включено", + + "workspace.providers.title": "Использовать свой ключ (BYOK)", + "workspace.providers.subtitle": "Настройте свои собственные API ключи от AI-провайдеров.", + "workspace.providers.placeholder": "Введите API ключ {{provider}} ({{prefix}}...)", + "workspace.providers.configure": "Настроить", + "workspace.providers.edit": "Изменить", + "workspace.providers.delete": "Удалить", + "workspace.providers.saving": "Сохранение...", + "workspace.providers.save": "Сохранить", + "workspace.providers.table.provider": "Провайдер", + "workspace.providers.table.apiKey": "API ключ", + + "workspace.usage.title": "История использования", + "workspace.usage.subtitle": "Недавнее использование API и расходы.", + "workspace.usage.empty": "Сделайте первый API вызов, чтобы начать.", + "workspace.usage.table.date": "Дата", + "workspace.usage.table.model": "Модель", + "workspace.usage.table.input": "Вход", + "workspace.usage.table.output": "Выход", + "workspace.usage.table.cost": "Стоимость", + "workspace.usage.table.session": "Сессия", + "workspace.usage.breakdown.input": "Вход", + "workspace.usage.breakdown.cacheRead": "Чтение кэша", + "workspace.usage.breakdown.cacheWrite": "Запись кэша", + "workspace.usage.breakdown.output": "Выход", + "workspace.usage.breakdown.reasoning": "Reasoning (рассуждения)", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Расходы", + "workspace.cost.subtitle": "Расходы на использование с разбивкой по моделям.", + "workspace.cost.allModels": "Все модели", + "workspace.cost.allKeys": "Все ключи", + "workspace.cost.deletedSuffix": "(удалено)", + "workspace.cost.empty": "Нет данных об использовании за выбранный период.", + "workspace.cost.subscriptionShort": "подписка", + + "workspace.keys.title": "API Ключи", + "workspace.keys.subtitle": "Управляйте вашими API ключами для доступа к сервисам opencode.", + "workspace.keys.create": "Создать API ключ", + "workspace.keys.placeholder": "Введите название ключа", + "workspace.keys.empty": "Создайте API ключ для шлюза opencode", + "workspace.keys.table.name": "Название", + "workspace.keys.table.key": "Ключ", + "workspace.keys.table.createdBy": "Создан", + "workspace.keys.table.lastUsed": "Использован", + "workspace.keys.copyApiKey": "Копировать API ключ", + "workspace.keys.delete": "Удалить", + + "workspace.members.title": "Участники", + "workspace.members.subtitle": "Управляйте участниками рабочего пространства и их правами.", + "workspace.members.invite": "Пригласить участника", + "workspace.members.inviting": "Отправка приглашения...", + "workspace.members.beta.beforeLink": "Рабочие пространства бесплатны для команд во время беты.", + "workspace.members.form.invitee": "Приглашаемый", + "workspace.members.form.emailPlaceholder": "Введите email", + "workspace.members.form.role": "Роль", + "workspace.members.form.monthlyLimit": "Ежемесячный лимит расходов", + "workspace.members.noLimit": "Без лимита", + "workspace.members.noLimitLowercase": "без лимита", + "workspace.members.invited": "приглашен", + "workspace.members.edit": "Изменить", + "workspace.members.delete": "Удалить", + "workspace.members.saving": "Сохранение...", + "workspace.members.save": "Сохранить", + "workspace.members.table.email": "Email", + "workspace.members.table.role": "Роль", + "workspace.members.table.monthLimit": "Лимит на месяц", + "workspace.members.role.admin": "Админ", + "workspace.members.role.adminDescription": "Может управлять моделями, участниками и оплатой", + "workspace.members.role.member": "Участник", + "workspace.members.role.memberDescription": "Может создавать API ключи только для себя", + + "workspace.settings.title": "Настройки", + "workspace.settings.subtitle": "Обновите название и настройки вашего рабочего пространства.", + "workspace.settings.workspaceName": "Название рабочего пространства", + "workspace.settings.defaultName": "По умолчанию", + "workspace.settings.updating": "Обновление...", + "workspace.settings.save": "Сохранить", + "workspace.settings.edit": "Изменить", + + "workspace.billing.title": "Оплата", + "workspace.billing.subtitle.beforeLink": "Управление способами оплаты.", + "workspace.billing.contactUs": "Свяжитесь с нами", + "workspace.billing.subtitle.afterLink": "если у вас есть вопросы.", + "workspace.billing.currentBalance": "Текущий баланс", + "workspace.billing.add": "Пополнить $", + "workspace.billing.enterAmount": "Введите сумму", + "workspace.billing.loading": "Загрузка...", + "workspace.billing.addAction": "Пополнить", + "workspace.billing.addBalance": "Пополнить баланс", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Привязано к Stripe", + "workspace.billing.manage": "Управление", + "workspace.billing.enable": "Включить оплату", + + "workspace.monthlyLimit.title": "Ежемесячный лимит", + "workspace.monthlyLimit.subtitle": "Установите ежемесячный лимит расходов для вашего аккаунта.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Сохранение...", + "workspace.monthlyLimit.set": "Установить", + "workspace.monthlyLimit.edit": "Изменить лимит", + "workspace.monthlyLimit.noLimit": "Лимит использования не установлен.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Текущее использование за", + "workspace.monthlyLimit.currentUsage.beforeAmount": "составляет $", + + "workspace.redeem.title": "Активировать купон", + "workspace.redeem.subtitle": "Активируйте код купона, чтобы получить кредит или бонусы.", + "workspace.redeem.placeholder": "Введите код купона", + "workspace.redeem.redeem": "Активировать", + "workspace.redeem.redeeming": "Активация...", + "workspace.redeem.success": "Купон успешно активирован.", + + "workspace.reload.title": "Автопополнение", + "workspace.reload.disabled.before": "Автопополнение", + "workspace.reload.disabled.state": "отключено", + "workspace.reload.disabled.after": "Включите для автоматического пополнения при низком балансе.", + "workspace.reload.enabled.before": "Автопополнение", + "workspace.reload.enabled.state": "включено", + "workspace.reload.enabled.middle": "Мы пополним на", + "workspace.reload.processingFee": "комиссия", + "workspace.reload.enabled.after": "когда баланс достигнет", + "workspace.reload.edit": "Изменить", + "workspace.reload.enable": "Включить", + "workspace.reload.enableAutoReload": "Включить автопополнение", + "workspace.reload.reloadAmount": "Пополнить на $", + "workspace.reload.whenBalanceReaches": "Когда баланс достигнет $", + "workspace.reload.saving": "Сохранение...", + "workspace.reload.save": "Сохранить", + "workspace.reload.failedAt": "Пополнение не удалось", + "workspace.reload.reason": "Причина:", + "workspace.reload.updatePaymentMethod": "Пожалуйста, обновите способ оплаты и попробуйте снова.", + "workspace.reload.retrying": "Повторная попытка...", + "workspace.reload.retry": "Повторить", + "workspace.reload.error.paymentFailed": "Ошибка оплаты.", + + "workspace.payments.title": "История платежей", + "workspace.payments.subtitle": "Недавние транзакции.", + "workspace.payments.table.date": "Дата", + "workspace.payments.table.paymentId": "ID платежа", + "workspace.payments.table.amount": "Сумма", + "workspace.payments.table.receipt": "Квитанция", + "workspace.payments.type.credit": "кредит", + "workspace.payments.type.subscription": "подписка", + "workspace.payments.view": "Просмотр", + + "workspace.black.loading": "Загрузка...", + "workspace.black.time.day": "день", + "workspace.black.time.days": "дней", + "workspace.black.time.hour": "час", + "workspace.black.time.hours": "часов", + "workspace.black.time.minute": "минута", + "workspace.black.time.minutes": "минут", + "workspace.black.time.fewSeconds": "несколько секунд", + "workspace.black.subscription.title": "Подписка", + "workspace.black.subscription.message": "Вы подписаны на OpenCode Black за ${{plan}} в месяц.", + "workspace.black.subscription.manage": "Управление подпиской", + "workspace.black.subscription.rollingUsage": "5-часовое использование", + "workspace.black.subscription.weeklyUsage": "Недельное использование", + "workspace.black.subscription.resetsIn": "Сброс через", + "workspace.black.subscription.useBalance": "Использовать доступный баланс после достижения лимитов", + "workspace.black.waitlist.title": "Список ожидания", + "workspace.black.waitlist.joined": "Вы в списке ожидания плана OpenCode Black за ${{plan}} в месяц.", + "workspace.black.waitlist.ready": "Мы готовы подключить вас к плану OpenCode Black за ${{plan}} в месяц.", + "workspace.black.waitlist.leave": "Покинуть список ожидания", + "workspace.black.waitlist.leaving": "Выход...", + "workspace.black.waitlist.left": "Вы покинули", + "workspace.black.waitlist.enroll": "Подключиться", + "workspace.black.waitlist.enrolling": "Подключение...", + "workspace.black.waitlist.enrolled": "Подключен", + "workspace.black.waitlist.enrollNote": + "Когда вы нажмете Подключиться, ваша подписка начнется немедленно, и с карты будет списана оплата.", + + "workspace.lite.loading": "Загрузка...", + "workspace.lite.time.day": "день", + "workspace.lite.time.days": "дней", + "workspace.lite.time.hour": "час", + "workspace.lite.time.hours": "часов", + "workspace.lite.time.minute": "минута", + "workspace.lite.time.minutes": "минут", + "workspace.lite.time.fewSeconds": "несколько секунд", + "workspace.lite.subscription.message": "Вы подписаны на OpenCode Go.", + "workspace.lite.subscription.manage": "Управление подпиской", + "workspace.lite.subscription.rollingUsage": "Использование за 5 часов", + "workspace.lite.subscription.rollingQuota": "Квота на 5 часов", + "workspace.lite.subscription.weeklyUsage": "Недельное использование", + "workspace.lite.subscription.weeklyQuota": "Недельная квота", + "workspace.lite.subscription.monthlyUsage": "Ежемесячное использование", + "workspace.lite.subscription.monthlyQuota": "Ежемесячная квота", + "workspace.lite.subscription.resetsIn": "Сброс через", + "workspace.lite.subscription.showDetails": "Показать подробности", + "workspace.lite.subscription.hideDetails": "Скрыть подробности", + "workspace.lite.subscription.model": "Модель", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Итого", + "workspace.lite.subscription.useBalance": "Использовать доступный баланс после достижения лимитов", + "workspace.lite.subscription.selectProvider": + 'Выберите "OpenCode Go" в качестве провайдера в настройках opencode для использования моделей Go.', + "workspace.lite.providers.title": "Провайдеры", + "workspace.lite.providers.description": "Управляйте провайдерами, используемыми для маршрутизации.", + "workspace.lite.providers.allowTraining": "Разрешить модели, обучающиеся на данных запросов", + "workspace.lite.providers.useChina": "Включить модели, размещенные в Китае", + "workspace.lite.black.message": + "Вы подписаны на OpenCode Black или находитесь в списке ожидания. Пожалуйста, сначала отмените подписку, если хотите перейти на Go.", + "workspace.lite.other.message": + "Другой участник в этом рабочем пространстве уже подписан на OpenCode Go. Только один участник в рабочем пространстве может оформить подписку.", + "workspace.lite.promo.description": + "OpenCode Go стоит {{price}} и предоставляет надежный доступ к популярным открытым моделям кодирования с щедрыми лимитами использования.", + "workspace.lite.promo.price": "$10/месяц", + "workspace.lite.promo.modelsTitle": "Что включено", + "workspace.lite.promo.footer": + "План предназначен в первую очередь для пользователей по всему миру и обеспечивает стабильный глобальный доступ. Цены и лимиты использования могут меняться по мере изучения первых результатов использования и отзывов.", + "workspace.lite.promo.subscribe": "Подписаться на Go", + "workspace.lite.promo.subscribing": "Перенаправление...", + "workspace.lite.promo.otherMethods": "Другие способы оплаты", + "workspace.lite.promo.selectMethod": "Выберите способ оплаты", + + "workspace.referral.copyLink": "Копировать ссылку", + "workspace.referral.copied": "Скопировано", + "workspace.referral.overview.title": "Пригласите друзей", + "workspace.referral.overview.subtitle": "Получите $5, когда друг оформит подписку. Он тоже получит $5.", + "workspace.referral.instructions.share": "Поделитесь своей реферальной ссылкой", + "workspace.referral.instructions.subscribe": "Ваш друг присоединяется и оформляет подписку на Go", + "workspace.referral.instructions.claim": + "Вы оба получаете кредит на использование $5, который можно применить к лимитам использования Go", + "workspace.referral.rewards.title": "Реферальные награды", + "workspace.referral.rewards.description": "Используйте доступные реферальные кредиты для оплаты использования Go.", + "workspace.referral.rewards.subtitle": "Использовано {{applied}} / {{total}} наград.", + "workspace.referral.rewards.empty": "Реферальных наград пока нет.", + "workspace.referral.table.reward": "Награда", + "workspace.referral.table.referral": "Описание", + "workspace.referral.table.date": "Дата", + "workspace.referral.reward.description.inviter": "Приглашён {{email}}", + "workspace.referral.reward.description.invitee": "Приглашены пользователем {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "Оформите подписку для разблокировки", + "workspace.referral.reward.action.view": "Посмотреть награду", + "workspace.referral.reward.action.applied": "Награда использована", + "workspace.referral.reward.source.pendingInviter": "Ожидание его подписки", + "workspace.referral.reward.source.pendingInvitee": "Подпишитесь, чтобы разблокировать награду", + "workspace.referral.reward.source.available": "Награда готова к применению", + "workspace.referral.reward.source.applied": "Награда использована", + "workspace.referral.reward.status.applied": "Награда использована", + "workspace.referral.reward.status.pendingInviter": "Оформите подписку для разблокировки", + "workspace.referral.reward.status.pendingInvitee": "Оформите подписку для разблокировки", + "workspace.referral.apply.noGo": "Оформите подписку для разблокировки", + "workspace.referral.apply.preview": "Посмотреть награду", + "workspace.referral.apply.action": "Применить", + "workspace.referral.apply.confirmTitle": "Применить награду", + "workspace.referral.apply.confirmBody": + "Используйте {{amount}}, чтобы уменьшить текущее использование этого workspace.", + "workspace.referral.apply.confirmAction": "Применить", + + "download.title": "OpenCode | Скачать", + "download.meta.description": "Скачать OpenCode для macOS, Windows и Linux", + "download.hero.title": "Скачать OpenCode Desktop", + "download.hero.subtitle": "Доступна бета для macOS, Windows и Linux", + "download.hero.button": "Скачать для {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "Расширения OpenCode", + "download.section.integrations": "Интеграции OpenCode", + "download.action.download": "Скачать", + "download.action.install": "Установить", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Не обязательно, но возможно. Вам понадобится AI подписка, если вы хотите подключить OpenCode к платному провайдеру, хотя вы можете работать с", + "download.faq.a3.localLink": "локальными моделями", + "download.faq.a3.afterLocal.beforeZen": "бесплатно. Хотя мы рекомендуем использовать", + "download.faq.a3.afterZen": + ", OpenCode работает со всеми популярными провайдерами, такими как OpenAI, Anthropic, xAI и др.", + + "download.faq.a5.p1": "OpenCode на 100% бесплатен.", + "download.faq.a5.p2.beforeZen": + "Любые дополнительные расходы будут связаны с вашей подпиской у провайдера моделей. Хотя OpenCode работает с любым провайдером моделей, мы рекомендуем использовать", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": "Ваши данные и информация сохраняются только при создании ссылок для шеринга в OpenCode.", + "download.faq.a6.p2.beforeShare": "Подробнее о", + "download.faq.a6.shareLink": "страницах шеринга", + + "enterprise.title": "OpenCode | Корпоративные решения для вашей организации", + "enterprise.meta.description": "Свяжитесь с OpenCode для корпоративных решений", + "enterprise.hero.title": "Ваш код принадлежит вам", + "enterprise.hero.body1": + "OpenCode безопасно работает внутри вашей организации: не хранит данные и контекст, без лицензионных ограничений и претензий на собственность. Начните пробный период с командой, затем разверните по всей организации, интегрировав с SSO и внутренним AI-шлюзом.", + "enterprise.hero.body2": "Сообщите нам, чем мы можем помочь.", + "enterprise.form.name.label": "Полное имя", + "enterprise.form.name.placeholder": "Джефф Безос", + "enterprise.form.role.label": "Роль", + "enterprise.form.role.placeholder": "Исполнительный председатель", + "enterprise.form.company.label": "Компания", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Корпоративная почта", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Номер телефона", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Какую проблему вы пытаетесь решить?", + "enterprise.form.message.placeholder": "Нам нужна помощь с...", + "enterprise.form.send": "Отправить", + "enterprise.form.sending": "Отправка...", + "enterprise.form.success": "Сообщение отправлено, мы скоро свяжемся с вами.", + "enterprise.form.success.submitted": "Форма успешно отправлена.", + "enterprise.form.error.allFieldsRequired": "Все поля обязательны.", + "enterprise.form.error.invalidEmailFormat": "Неверный формат email.", + "enterprise.form.error.internalServer": "Внутренняя ошибка сервера.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "Что такое OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise предназначен для организаций, которые хотят гарантировать, что их код и данные никогда не покинут их инфраструктуру. Это достигается за счет централизованной конфигурации, интегрированной с вашим SSO и внутренним AI-шлюзом.", + "enterprise.faq.q2": "Как начать работу с OpenCode Enterprise?", + "enterprise.faq.a2": + "Просто начните с внутреннего триала с вашей командой. OpenCode по умолчанию не хранит ваш код или контекстные данные, поэтому начать легко. Затем свяжитесь с нами, чтобы обсудить цены и варианты внедрения.", + "enterprise.faq.q3": "Как работает корпоративное ценообразование?", + "enterprise.faq.a3": + "Мы предлагаем модель ценообразования за рабочее место (per-seat). Если у вас есть собственный LLM-шлюз, мы не взимаем плату за использованные токены. Для получения подробной информации свяжитесь с нами для индивидуального расчета на основе потребностей вашей организации.", + "enterprise.faq.q4": "Безопасны ли мои данные с OpenCode Enterprise?", + "enterprise.faq.a4": + "Да. OpenCode не хранит ваш код или контекстные данные. Вся обработка происходит локально или через прямые вызовы API к вашему AI-провайдеру. Благодаря централизованной конфигурации и интеграции SSO ваши данные остаются защищенными внутри инфраструктуры вашей организации.", + + "brand.title": "OpenCode | Бренд", + "brand.meta.description": "Гайдлайны бренда OpenCode", + "brand.heading": "Гайдлайны бренда", + "brand.subtitle": "Ресурсы и активы, которые помогут вам работать с брендом OpenCode.", + "brand.downloadAll": "Скачать все ресурсы", + + "changelog.title": "OpenCode | Список изменений", + "changelog.meta.description": "Примечания к релизам и список изменений OpenCode", + "changelog.hero.title": "Список изменений", + "changelog.hero.subtitle": "Новые обновления и улучшения OpenCode", + "changelog.empty": "Записи в списке изменений не найдены.", + "changelog.viewJson": "Посмотреть JSON", + + "bench.list.title": "Бенчмарк", + "bench.list.heading": "Бенчмарки", + "bench.list.table.agent": "Агент", + "bench.list.table.model": "Модель", + "bench.list.table.score": "Оценка", + "bench.submission.error.allFieldsRequired": "Все поля обязательны.", + + "bench.detail.title": "Бенчмарк - {{task}}", + "bench.detail.notFound": "Задача не найдена", + "bench.detail.na": "Н/Д", + "bench.detail.labels.agent": "Агент", + "bench.detail.labels.model": "Модель", + "bench.detail.labels.task": "Задача", + "bench.detail.labels.repo": "Репозиторий", + "bench.detail.labels.from": "От", + "bench.detail.labels.to": "До", + "bench.detail.labels.prompt": "Промпт", + "bench.detail.labels.commit": "Коммит", + "bench.detail.labels.averageDuration": "Средняя длительность", + "bench.detail.labels.averageScore": "Средняя оценка", + "bench.detail.labels.averageCost": "Средняя стоимость", + "bench.detail.labels.summary": "Сводка", + "bench.detail.labels.runs": "Запуски", + "bench.detail.labels.score": "Оценка", + "bench.detail.labels.base": "База", + "bench.detail.labels.penalty": "Штраф", + "bench.detail.labels.weight": "вес", + "bench.detail.table.run": "Запуск", + "bench.detail.table.score": "Оценка (База - Штраф)", + "bench.detail.table.cost": "Стоимость", + "bench.detail.table.duration": "Длительность", + "bench.detail.run.title": "Запуск {{n}}", + "bench.detail.rawJson": "Raw JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/th.ts b/packages/console/app/src/i18n/th.ts new file mode 100644 index 0000000000000000000000000000000000000000..97a80f0394188cda89d979ab1b4ef0adab47bd6c --- /dev/null +++ b/packages/console/app/src/i18n/th.ts @@ -0,0 +1,871 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash เพิ่มโควตาการใช้งานเป็น 4 เท่าในช่วงเวลาจำกัด", + "go.graph.bonus": "ใช้งาน {{count}} เท่า", + "nav.github": "GitHub", + "nav.docs": "เอกสาร", + "nav.changelog": "บันทึกการเปลี่ยนแปลง", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "องค์กร", + "nav.zen": "Zen", + "nav.login": "เข้าสู่ระบบ", + "nav.free": "ดาวน์โหลด", + "nav.home": "หน้าหลัก", + "nav.openMenu": "เปิดเมนู", + "nav.getStartedFree": "เริ่มต้นฟรี", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "คัดลอกโลโก้เป็น SVG", + "nav.context.copyWordmark": "คัดลอกตัวอักษรแบรนด์เป็น SVG", + "nav.context.brandAssets": "แอสเซทแบรนด์", + + "footer.github": "GitHub", + "footer.docs": "เอกสาร", + "footer.changelog": "บันทึกการเปลี่ยนแปลง", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "แบรนด์", + "legal.privacy": "ความเป็นส่วนตัว", + "legal.terms": "ข้อกำหนด", + + "email.title": "รู้ก่อนใครเมื่อเราปล่อยผลิตภัณฑ์ใหม่", + "email.subtitle": "เข้าร่วมรายชื่อรอเพื่อรับสิทธิ์เข้าถึงก่อนใคร", + "email.placeholder": "ที่อยู่อีเมล", + "email.subscribe": "สมัครรับข่าวสาร", + "email.success": "เกือบเสร็จแล้ว ตรวจสอบกล่องจดหมายและยืนยันที่อยู่อีเมลของคุณ", + + "notFound.title": "ไม่พบหน้า | OpenCode", + "notFound.heading": "404 - ไม่พบหน้าที่ค้นหา", + "notFound.home": "หน้าหลัก", + "notFound.docs": "เอกสาร", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "โลโก้ opencode แบบสว่าง", + "notFound.logoDarkAlt": "โลโก้ opencode แบบมืด", + + "user.logout": "ออกจากระบบ", + + "auth.callback.error.codeMissing": "ไม่พบ authorization code", + + "workspace.select": "เลือก Workspace", + "workspace.createNew": "+ สร้าง Workspace ใหม่", + "workspace.modal.title": "สร้าง Workspace ใหม่", + "workspace.modal.placeholder": "กรอกชื่อ Workspace", + + "common.cancel": "ยกเลิก", + "common.creating": "กำลังสร้าง...", + "common.create": "สร้าง", + "common.contactUs": "ติดต่อเรา", + + "common.videoUnsupported": "เบราว์เซอร์ของคุณไม่รองรับแท็ก video", + "common.figure": "รูปที่ {{n}}", + "common.faq": "คำถามที่พบบ่อย", + "common.learnMore": "ดูเพิ่มเติม", + + "error.invalidPlan": "แผนไม่ถูกต้อง", + "error.workspaceRequired": "จำเป็นต้องมี Workspace ID", + "error.alreadySubscribed": "Workspace นี้มีการสมัครสมาชิกอยู่แล้ว", + "error.limitRequired": "จำเป็นต้องระบุขีดจำกัด", + "error.monthlyLimitInvalid": "โปรดระบุขีดจำกัดรายเดือนที่ถูกต้อง", + "error.workspaceNameRequired": "จำเป็นต้องระบุชื่อ Workspace", + "error.nameTooLong": "ชื่อต้องมีความยาวไม่เกิน 255 ตัวอักษร", + "error.emailRequired": "จำเป็นต้องระบุอีเมล", + "error.roleRequired": "จำเป็นต้องระบุบทบาท", + "error.idRequired": "จำเป็นต้องระบุ ID", + "error.nameRequired": "จำเป็นต้องระบุชื่อ", + "error.providerRequired": "จำเป็นต้องระบุผู้ให้บริการ", + "error.apiKeyRequired": "จำเป็นต้องระบุ API key", + "error.modelRequired": "จำเป็นต้องระบุโมเดล", + "error.reloadAmountMin": "จำนวนเงินที่โหลดซ้ำต้องมีอย่างน้อย ${{amount}}", + "error.reloadTriggerMin": "ยอดคงเหลือที่กระตุ้นต้องมีอย่างน้อย ${{amount}}", + + "app.meta.description": "OpenCode - เอเจนต์เขียนโค้ดแบบโอเพนซอร์ส", + + "home.title": "OpenCode | เอเจนต์เขียนโค้ดด้วย AI แบบโอเพนซอร์ส", + + "temp.title": "OpenCode | เอเจนต์เขียนโค้ด AI ที่สร้างมาเพื่อเทอร์มินัล", + "temp.hero.title": "เอเจนต์เขียนโค้ด AI ที่สร้างมาเพื่อเทอร์มินัล", + "temp.zen": "OpenCode Zen", + "temp.getStarted": "เริ่มต้นใช้งาน", + "temp.feature.native.title": "Native TUI", + "temp.feature.native.body": "UI เทอร์มินัลแบบเนทีฟที่ตอบสนองไวและปรับแต่งธีมได้", + "temp.feature.zen.beforeLink": "", + "temp.feature.zen.link": "รายการโมเดลที่คัดสรรแล้ว", + "temp.feature.zen.afterLink": "โดย OpenCode", + "temp.feature.models.beforeLink": "รองรับผู้ให้บริการ LLM กว่า 75 รายผ่าน", + "temp.feature.models.afterLink": "รวมถึงโมเดล Local", + "temp.screenshot.caption": "OpenCode TUI พร้อมธีม tokyonight", + "temp.screenshot.alt": "OpenCode TUI พร้อมธีม tokyonight", + "temp.logoLightAlt": "โลโก้ opencode แบบสว่าง", + "temp.logoDarkAlt": "โลโก้ opencode แบบมืด", + + "home.banner.badge": "ใหม่", + "home.banner.text": "ขอแนะนำแท็บสำหรับเดสก์ท็อป.", + "home.banner.platforms": "พร้อมใช้งานบน macOS, Windows และ Linux", + "home.banner.downloadNow": "ดาวน์โหลดตอนนี้", + "home.banner.downloadBetaNow": "ดาวน์โหลดเบต้าเดสก์ท็อปตอนนี้", + "home.promo.title": "ขอแนะนำแท็บสำหรับเดสก์ท็อป", + "home.promo.body": "จัดระเบียบงานและเซสชันที่ใช้งานอยู่ด้วยแท็บ", + "home.promo.cta": "ดาวน์โหลดเวอร์ชันล่าสุดเพื่อเริ่มต้นใช้งาน", + "home.promo.close": "ปิดประกาศเกี่ยวกับแอปเดสก์ท็อป", + + "home.hero.title": "เอเจนต์เขียนโค้ดด้วย AI แบบโอเพนซอร์ส", + "home.hero.subtitle.a": "มีโมเดลฟรีรวมอยู่ หรือเชื่อมต่อโมเดลใดก็ได้จากผู้ให้บริการรายใดก็ได้,", + "home.hero.subtitle.b": "รวมถึง Claude, GPT, Gemini และอีกมากมาย", + + "home.install.ariaLabel": "ตัวเลือกการติดตั้ง", + + "home.what.title": "OpenCode คืออะไร?", + "home.what.body": "OpenCode คือเอเจนต์โอเพนซอร์สที่ช่วยคุณเขียนโค้ดในเทอร์มินัล, IDE หรือเดสก์ท็อป", + "home.what.lsp.title": "รองรับ LSP", + "home.what.lsp.body": "โหลด LSP ที่เหมาะสมสำหรับ LLM โดยอัตโนมัติ", + "home.what.multiSession.title": "หลายเซสชัน", + "home.what.multiSession.body": "เริ่มเอเจนต์หลายตัวทำงานคู่ขนานกันในโปรเจกต์เดียวกัน", + "home.what.shareLinks.title": "แชร์ลิงก์", + "home.what.shareLinks.body": "แชร์ลิงก์ไปยังเซสชันใดก็ได้เพื่อการอ้างอิงหรือ Debug", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "เข้าสู่ระบบด้วย GitHub เพื่อใช้บัญชี Copilot ของคุณ", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "เข้าสู่ระบบด้วย OpenAI เพื่อใช้บัญชี ChatGPT Plus หรือ Pro ของคุณ", + "home.what.anyModel.title": "โมเดลใดก็ได้", + "home.what.anyModel.body": "ผู้ให้บริการ LLM กว่า 75 รายผ่าน Models.dev รวมถึงโมเดล Local", + "home.what.anyEditor.title": "อีดิเตอร์ใดก็ได้", + "home.what.anyEditor.body": "ใช้งานได้ทั้งแบบเทอร์มินัล, แอปเดสก์ท็อป และส่วนขยาย IDE", + "home.what.readDocs": "อ่านเอกสาร", + + "home.growth.title": "เอเจนต์เขียนโค้ดด้วย AI แบบโอเพนซอร์ส", + "home.growth.body": + "ด้วยยอดดาวบน GitHub กว่า {{stars}} ดวง, ผู้ร่วมพัฒนา {{contributors}} คน, และการคอมมิตกว่า {{commits}} ครั้ง, OpenCode ได้รับความไว้วางใจจากนักพัฒนากว่า {{monthlyUsers}} คนในทุกเดือน", + "home.growth.githubStars": "GitHub Stars", + "home.growth.contributors": "ผู้ร่วมพัฒนา", + "home.growth.monthlyDevs": "นักพัฒนารายเดือน", + + "home.privacy.title": "สร้างโดยคำนึงถึงความเป็นส่วนตัวเป็นหลัก", + "home.privacy.body": + "OpenCode ไม่จัดเก็บโค้ดหรือข้อมูลบริบทของคุณ เพื่อให้สามารถทำงานในสภาพแวดล้อมที่ให้ความสำคัญกับความเป็นส่วนตัวได้", + "home.privacy.learnMore": "เรียนรู้เพิ่มเติมเกี่ยวกับ", + "home.privacy.link": "ความเป็นส่วนตัว", + + "home.faq.q1": "OpenCode คืออะไร?", + "home.faq.a1": + "OpenCode เป็นเอเจนต์โอเพนซอร์สที่ช่วยให้คุณเขียนและรันโค้ดด้วยโมเดล AI ใดก็ได้ มีให้เลือกใช้ทั้งแบบอินเทอร์เฟซเทอร์มินัล, แอปเดสก์ท็อป หรือส่วนขยาย IDE", + "home.faq.q2": "ฉันจะเริ่มใช้ OpenCode ได้อย่างไร?", + "home.faq.a2.before": "วิธีเริ่มต้นที่ง่ายที่สุดคืออ่าน", + "home.faq.a2.link": "บทนำ", + "home.faq.q3": "ต้องสมัครสมาชิก AI เพิ่มเติมเพื่อใช้ OpenCode หรือไม่?", + "home.faq.a3.p1": "ไม่จำเป็นเสมอไป OpenCode มาพร้อมกับชุดโมเดลฟรีที่คุณสามารถใช้ได้โดยไม่ต้องสร้างบัญชี", + "home.faq.a3.p2.beforeZen": "นอกจากนี้ คุณสามารถใช้โมเดลยอดนิยมใดก็ได้โดยการสร้างบัญชี", + "home.faq.a3.p2.afterZen": "", + "home.faq.a3.p3": + "แม้เราจะแนะนำให้ใช้ Zen แต่ OpenCode ก็ทำงานร่วมกับผู้ให้บริการยอดนิยมทั้งหมด เช่น OpenAI, Anthropic, xAI เป็นต้น", + "home.faq.a3.p4.beforeLocal": "คุณยังสามารถเชื่อมต่อกับ", + "home.faq.a3.p4.localLink": "โมเดล Local ของคุณ", + "home.faq.q4": "ฉันสามารถใช้การสมัครสมาชิก AI ที่มีอยู่กับ OpenCode ได้หรือไม่?", + "home.faq.a4.p1": + "ได้ OpenCode รองรับแผนการสมัครสมาชิกจากผู้ให้บริการหลักทั้งหมด คุณสามารถใช้การสมัครสมาชิก Claude Pro/Max, ChatGPT Plus/Pro หรือ GitHub Copilot ของคุณได้", + "home.faq.q5": "ฉันใช้ OpenCode ได้เฉพาะในเทอร์มินัลใช่หรือไม่?", + "home.faq.a5.beforeDesktop": "ไม่อีกต่อไป! OpenCode มีแอปสำหรับ", + "home.faq.a5.desktop": "เดสก์ท็อป", + "home.faq.a5.and": "และ", + "home.faq.a5.web": "เว็บ", + "home.faq.q6": "OpenCode ราคาเท่าไหร่?", + "home.faq.a6": + "OpenCode ใช้งานได้ฟรี 100% และมาพร้อมกับชุดโมเดลฟรี อาจมีค่าใช้จ่ายเพิ่มเติมหากคุณเชื่อมต่อกับผู้ให้บริการรายอื่น", + "home.faq.q7": "แล้วเรื่องข้อมูลและความเป็นส่วนตัวล่ะ?", + "home.faq.a7.p1": "ข้อมูลของคุณจะถูกจัดเก็บเฉพาะเมื่อคุณใช้โมเดลฟรีของเราหรือสร้างลิงก์ที่แชร์ได้", + "home.faq.a7.p2.beforeModels": "เรียนรู้เพิ่มเติมเกี่ยวกับ", + "home.faq.a7.p2.modelsLink": "โมเดลของเรา", + "home.faq.a7.p2.and": "และ", + "home.faq.a7.p2.shareLink": "หน้าแชร์", + "home.faq.q8": "OpenCode เป็นโอเพนซอร์สหรือไม่?", + "home.faq.a8.p1": "ใช่ OpenCode เป็นโอเพนซอร์สเต็มรูปแบบ ซอร์สโค้ดเปิดเผยต่อสาธารณะบน", + "home.faq.a8.p2": "ภายใต้", + "home.faq.a8.mitLicense": "MIT License", + "home.faq.a8.p3": + " ซึ่งหมายความว่าใครๆ ก็สามารถใช้ แก้ไข หรือร่วมพัฒนาได้ ทุกคนในชุมชนสามารถเปิด issue, ส่ง pull request และขยายฟังก์ชันการทำงานได้", + + "home.zenCta.title": "เข้าถึงโมเดลที่เชื่อถือได้และปรับแต่งมาแล้วสำหรับเอเจนต์เขียนโค้ด", + "home.zenCta.body": + "Zen ให้คุณเข้าถึงชุดโมเดล AI ที่คัดสรรมาแล้ว ซึ่ง OpenCode ได้ทดสอบและทำเบนช์มาร์กโดยเฉพาะสำหรับเอเจนต์เขียนโค้ด ไม่ต้องกังวลเรื่องประสิทธิภาพและคุณภาพที่ไม่สม่ำเสมอจากผู้ให้บริการ ใช้โมเดลที่ผ่านการตรวจสอบแล้วว่าใช้งานได้จริง", + "home.zenCta.link": "เรียนรู้เกี่ยวกับ Zen", + + "zen.title": "OpenCode Zen | ชุดโมเดลที่คัดสรรมาอย่างดี เชื่อถือได้ และปรับแต่งแล้วสำหรับเอเจนต์เขียนโค้ด", + "zen.hero.title": "โมเดลที่ปรับแต่งมาอย่างดีและเชื่อถือได้สำหรับเอเจนต์เขียนโค้ด", + "zen.hero.body": + "Zen ให้คุณเข้าถึงชุดโมเดล AI ที่คัดสรรมาแล้ว ซึ่ง OpenCode ได้ทดสอบและทำเบนช์มาร์กโดยเฉพาะสำหรับเอเจนต์เขียนโค้ด ไม่ต้องกังวลเรื่องประสิทธิภาพและคุณภาพที่ไม่สม่ำเสมอ ใช้โมเดลที่ผ่านการตรวจสอบแล้วว่าใช้งานได้จริง", + + "zen.faq.q1": "OpenCode Zen คืออะไร?", + "zen.faq.a1": + "Zen คือชุดโมเดล AI ที่คัดสรรมาอย่างดี ผ่านการทดสอบและทำเบนช์มาร์กสำหรับเอเจนต์เขียนโค้ด สร้างโดยทีมงานผู้อยู่เบื้องหลัง OpenCode", + "zen.faq.q2": "อะไรทำให้ Zen แม่นยำกว่า?", + "zen.faq.a2": + "Zen ให้บริการเฉพาะโมเดลที่ได้รับการทดสอบและทำเบนช์มาร์กสำหรับเอเจนต์เขียนโค้ดโดยเฉพาะ คุณคงไม่ใช้มีดทาเนยมาหั่นสเต็ก ดังนั้นอย่าใช้โมเดลคุณภาพต่ำสำหรับการเขียนโค้ด", + "zen.faq.q3": "Zen ราคาถูกกว่าหรือไม่?", + "zen.faq.a3": + "Zen ไม่ได้แสวงหากำไร Zen ส่งผ่านต้นทุนจากผู้ให้บริการโมเดลมาถึงคุณ ยิ่งมีการใช้งาน Zen มากเท่าไหร่ OpenCode ก็ยิ่งสามารถต่อรองเรตราคาที่ดีกว่าและส่งต่อให้คุณได้มากขึ้นเท่านั้น", + "zen.faq.q4": "Zen ราคาเท่าไหร่?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "คิดค่าบริการต่อคำขอ", + "zen.faq.a4.p1.afterPricing": "โดยไม่มีการบวกเพิ่ม ดังนั้นคุณจ่ายเท่ากับที่ผู้ให้บริการโมเดลเรียกเก็บ", + "zen.faq.a4.p2.beforeAccount": + "ค่าใช้จ่ายรวมของคุณขึ้นอยู่กับการใช้งาน และคุณสามารถตั้งวงเงินการใช้จ่ายรายเดือนได้ใน", + "zen.faq.a4.p2.accountLink": "บัญชีของคุณ", + "zen.faq.a4.p3": + "เพื่อครอบคลุมต้นทุน OpenCode คิดค่าธรรมเนียมการประมวลผลการชำระเงินเพียงเล็กน้อย $1.23 ต่อการเติมเงิน $20", + "zen.faq.q5": "แล้วเรื่องข้อมูลและความเป็นส่วนตัวล่ะ?", + "zen.faq.a5.beforeExceptions": + "โมเดล Zen ทั้งหมดโฮสต์ในสหรัฐอเมริกา ผู้ให้บริการปฏิบัติตามนโยบายไม่เก็บรักษาข้อมูล (zero-retention policy) และไม่ใช้ข้อมูลของคุณสำหรับการฝึกโมเดล โดยมี", + "zen.faq.a5.exceptionsLink": "ข้อยกเว้นดังนี้", + "zen.faq.q6": "ฉันสามารถตั้งวงเงินการใช้จ่ายได้หรือไม่?", + "zen.faq.a6": "ได้ คุณสามารถตั้งวงเงินการใช้จ่ายรายเดือนได้ในบัญชีของคุณ", + "zen.faq.q7": "ฉันสามารถยกเลิกได้หรือไม่?", + "zen.faq.a7": "ได้ คุณสามารถปิดการเรียกเก็บเงินได้ตลอดเวลาและใช้ยอดเงินคงเหลือของคุณจนหมด", + "zen.faq.q8": "ฉันสามารถใช้ Zen กับเอเจนต์เขียนโค้ดอื่นได้หรือไม่?", + "zen.faq.a8": + "แม้ว่า Zen จะทำงานได้ดีเยี่ยมกับ OpenCode แต่คุณสามารถใช้ Zen กับเอเจนต์ใดก็ได้ เพียงทำตามคำแนะนำการตั้งค่าในเอเจนต์เขียนโค้ดที่คุณต้องการ", + "zen.faq.q9": "ฉันขอเงินคืนได้หรือไม่?", + "zen.faq.a9": + "หากมีการเรียกเก็บเงินภายใน 14 วันที่ผ่านมาและคุณยังไม่ได้ใช้เครดิตใดๆ จากการซื้อนั้น คุณอาจมีสิทธิ์ได้รับเงินคืน {{contact}}เพื่อขอเงินคืน", + + "zen.cta.start": "เริ่มต้นใช้งาน Zen", + "zen.pricing.title": "เติมเงิน $20 แบบ Pay as you go", + "zen.pricing.fee": "(+ค่าธรรมเนียมประมวลผลบัตร $1.23)", + "zen.pricing.body": "ใช้ได้กับทุกเอเจนต์ ตั้งวงเงินรายเดือนได้ ยกเลิกได้ตลอดเวลา", + "zen.problem.title": "Zen กำลังแก้ปัญหาอะไร?", + "zen.problem.body": + "มีโมเดลมากมายให้เลือก แต่มีเพียงไม่กี่ตัวที่ทำงานได้ดีกับเอเจนต์เขียนโค้ด ผู้ให้บริการส่วนใหญ่กำหนดค่าแตกต่างกันไปซึ่งให้ผลลัพธ์ที่หลากหลาย", + "zen.problem.subtitle": "เรากำลังแก้ไขปัญหานี้สำหรับทุกคน ไม่ใช่แค่ผู้ใช้ OpenCode เท่านั้น", + "zen.problem.item1": "ทดสอบโมเดลที่คัดเลือกมาและปรึกษากับทีมของโมเดลนั้นๆ", + "zen.problem.item2": "ทำงานร่วมกับผู้ให้บริการเพื่อให้มั่นใจว่าโมเดลถูกส่งมอบอย่างถูกต้อง", + "zen.problem.item3": "ทำเบนช์มาร์กทุกการจับคู่ระหว่างโมเดลและผู้ให้บริการที่เราแนะนำ", + "zen.how.title": "Zen ทำงานอย่างไร", + "zen.how.body": "แม้เราจะแนะนำให้คุณใช้ Zen กับ OpenCode แต่คุณสามารถใช้ Zen กับเอเจนต์ใดก็ได้", + "zen.how.step1.title": "ลงทะเบียนและเติมเงิน $20", + "zen.how.step1.beforeLink": "ทำตาม", + "zen.how.step1.link": "คำแนะนำการตั้งค่า", + "zen.how.step2.title": "ใช้ Zen ด้วยราคาที่โปร่งใส", + "zen.how.step2.link": "จ่ายตามคำขอ (pay per request)", + "zen.how.step2.afterLink": "โดยไม่มีการบวกเพิ่ม", + "zen.how.step3.title": "เติมเงินอัตโนมัติ", + "zen.how.step3.body": "เมื่อยอดเงินของคุณเหลือ $5 เราจะเติมเงิน $20 ให้โดยอัตโนมัติ", + "zen.privacy.title": "ความเป็นส่วนตัวของคุณสำคัญสำหรับเรา", + "zen.privacy.beforeExceptions": + "โมเดล Zen ทั้งหมดโฮสต์ในสหรัฐอเมริกา ผู้ให้บริการปฏิบัติตามนโยบายไม่เก็บรักษาข้อมูล (zero-retention policy) และไม่ใช้ข้อมูลของคุณสำหรับการฝึกโมเดล โดยมี", + "zen.privacy.exceptionsLink": "ข้อยกเว้นดังนี้", + + "go.title": "OpenCode Go | โมเดลเขียนโค้ดราคาประหยัดสำหรับทุกคน", + "go.meta.description": + "Go มีราคา $10/เดือน พร้อมขีดจำกัดการใช้งานที่เอื้อเฟื้อและการเข้าถึงโมเดลเขียนโค้ดชั้นนำอย่างเชื่อถือได้", + "go.hero.title": "โมเดลเขียนโค้ดราคาประหยัดสำหรับทุกคน", + "go.hero.body": + "Go นำการเขียนโค้ดแบบเอเจนต์มาสู่นักเขียนโปรแกรมทั่วโลก เสนอขีดจำกัดที่กว้างขวางและการเข้าถึงโมเดลโอเพนซอร์สที่มีความสามารถสูงสุดได้อย่างน่าเชื่อถือ เพื่อให้คุณสามารถสร้างสรรค์ด้วยเอเจนต์ที่ทรงพลังโดยไม่ต้องกังวลเรื่องค่าใช้จ่ายหรือความพร้อมใช้งาน", + + "go.cta.start": "สมัครสมาชิก Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "สมัครสมาชิก Go", + "go.cta.price": "$10/เดือน", + "go.pricing.body": "ใช้กับเอเจนต์ใดก็ได้ $10/เดือน เติมเครดิตหากจำเป็น ยกเลิกได้ตลอดเวลา", + "go.graph.free": "ฟรี", + "go.graph.freePill": "Big Pickle และโมเดลฟรี", + "go.graph.go": "Go", + "go.graph.label": "คำขอต่อ 5 ชั่วโมง", + "go.graph.period": "การใช้งาน", + "go.graph.model": "โมเดล", + "go.graph.requests": "requests โดยประมาณ / 5 ชม.", + "go.graph.allowance": "ปริมาณการใช้งานรายเดือน", + "go.graph.new": "ใหม่", + "go.graph.scale": "มาตราส่วนจำนวนคำขอแบบไม่เป็นเชิงเส้น", + "go.graph.showAll": "ดูโมเดลทั้งหมด {{count}} โมเดล", + "go.graph.showLess": "แสดงโมเดลน้อยลง", + "go.graph.limitedRegions": "เฉพาะบางภูมิภาค", + "go.graph.limitedTime": "ช่วงเวลาจำกัด", + "go.graph.usageLimits": "ขีดจำกัดการใช้งาน", + "go.graph.aria": "คำขอต่อ 5 ชม.: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "อดีต CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "เปลี่ยนชีวิตไปเลย มันเป็นสิ่งที่ต้องมีจริงๆ", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "อดีตผู้ก่อตั้ง SEED, PM, Melt, Pop, Dapt, Cadmus และ ViewPoint", + "go.testimonials.jay.quoteBefore": "4 ใน 5 คนในทีมของเราชอบใช้", + "go.testimonials.jay.quoteAfter": "", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "อดีต Hero, AWS", + "go.testimonials.adam.quoteBefore": "ผมแนะนำ", + "go.testimonials.adam.quoteAfter": "ได้ไม่พอจริงๆ พูดจริงนะ มันดีมากๆ", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "อดีตหัวหน้าฝ่ายออกแบบ, Laravel", + "go.testimonials.david.quoteBefore": "ด้วย", + "go.testimonials.david.quoteAfter": "ผมรู้ว่าโมเดลทั้งหมดผ่านการทดสอบและสมบูรณ์แบบสำหรับเอเจนต์เขียนโค้ด", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "อดีตเด็กฝึกงาน, Nvidia (4 ครั้ง)", + "go.testimonials.frank.quote": "ผมหวังว่าผมจะยังอยู่ที่ Nvidia", + "go.problem.title": "Go แก้ปัญหาอะไร?", + "go.problem.body": + "เรามุ่งมั่นที่จะนำประสบการณ์ OpenCode ไปสู่ผู้คนให้ได้มากที่สุด OpenCode Go เป็นการสมัครสมาชิกราคาประหยัด $10/เดือน โดยมอบขีดจำกัดที่เอื้อเฟื้อและการเข้าถึงโมเดลโอเพนซอร์สที่มีความสามารถสูงสุดอย่างเชื่อถือได้", + "go.problem.subtitle": " ", + "go.problem.item1": "ราคาการสมัครสมาชิกที่ต่ำ", + "go.problem.item2": "ขีดจำกัดที่กว้างขวางและการเข้าถึงที่เชื่อถือได้", + "go.problem.item3": "สร้างขึ้นเพื่อโปรแกรมเมอร์จำนวนมากที่สุดเท่าที่จะเป็นไปได้", + "go.problem.item4": "ชุดโมเดลที่คัดสรรและผ่านการทดสอบสำหรับการเขียนโค้ดแบบเอเจนต์", + "go.how.title": "Go ทำงานอย่างไร", + "go.how.body": "Go มีราคา $10/เดือน คุณสามารถใช้กับ OpenCode หรือเอเจนต์ใดก็ได้", + "go.how.step1.title": "สร้างบัญชี", + "go.how.step1.beforeLink": "ทำตาม", + "go.how.step1.link": "คำแนะนำการตั้งค่า", + "go.how.step2.title": "สมัครสมาชิก Go", + "go.how.step2.link": "$10/เดือน", + "go.how.step2.afterLink": "พร้อมขีดจำกัดที่เอื้อเฟื้อ", + "go.how.step3.title": "เริ่มเขียนโค้ด", + "go.how.step3.body": "ด้วยการเข้าถึงโมเดลโอเพนซอร์สที่เชื่อถือได้", + "go.privacy.title": "ความเป็นส่วนตัวของคุณสำคัญสำหรับเรา", + "go.privacy.body": + "แผนนี้ออกแบบมาเพื่อผู้ใช้งานระหว่างประเทศเป็นหลัก โดยมีโมเดลโฮสต์ในสหรัฐอเมริกา สหภาพยุโรป และสิงคโปร์ เพื่อการเข้าถึงทั่วโลกที่เสถียร", + "go.privacy.contactAfter": "หากคุณมีคำถามใดๆ", + "go.privacy.beforeExceptions": + "โมเดล Go โฮสต์ในสหรัฐอเมริกา ผู้ให้บริการปฏิบัติตามนโยบายไม่เก็บรักษาข้อมูล (zero-retention policy) และไม่ใช้ข้อมูลของคุณสำหรับการฝึกโมเดล โดยมี", + "go.privacy.exceptionsLink": "ข้อยกเว้นดังนี้", + "go.faq.q1": "OpenCode Go คืออะไร?", + "go.faq.a1": + "Go คือการสมัครสมาชิกราคาประหยัดที่ให้คุณเข้าถึงโมเดลโอเพนซอร์สที่มีความสามารถสำหรับการเขียนโค้ดแบบเอเจนต์ได้อย่างน่าเชื่อถือ", + "go.faq.q2": "Go รวมโมเดลอะไรบ้าง?", + "go.faq.a2": "Go รวมโมเดลด้านล่างนี้ พร้อมขีดจำกัดที่มากและการเข้าถึงที่เชื่อถือได้", + "go.faq.q3": "Go เหมือนกับ Zen หรือไม่?", + "go.faq.a3": + "ไม่ Zen เป็นแบบจ่ายตามการใช้งาน ขณะที่ Go มีราคา $10/เดือน พร้อมขีดจำกัดที่เอื้อเฟื้อและการเข้าถึงชุดโมเดลที่คัดสรรอย่างเชื่อถือได้", + "go.faq.q4": "Go ราคาเท่าไหร่?", + "go.faq.a4.p1.beforePricing": "Go ราคา", + "go.faq.a4.p1.pricingLink": "$10/เดือน", + "go.faq.a4.p1.afterPricing": "พร้อมขีดจำกัดที่เอื้อเฟื้อ", + "go.faq.a4.p2.beforeAccount": "คุณสามารถจัดการการสมัครสมาชิกของคุณได้ใน", + "go.faq.a4.p2.accountLink": "บัญชีของคุณ", + "go.faq.a4.p3": "ยกเลิกได้ตลอดเวลา", + "go.faq.q5": "แล้วเรื่องข้อมูลและความเป็นส่วนตัวล่ะ?", + "go.faq.a5.model": "โมเดล", + "go.faq.a5.training": "การฝึกโมเดล", + "go.faq.a5.retention": "การเก็บรักษาข้อมูล", + "go.faq.a5.retention30": "30 วัน", + "go.faq.a5.retention0": "0 วัน", + "go.faq.a5.used": "นำไปใช้", + "go.faq.a5.notUsed": "ไม่นำไปใช้", + "go.faq.a5.noAgreement": "ไม่มีข้อตกลง", + "go.faq.a5.notZdr": "ไม่ใช่ ZDR", + "go.faq.a5.grokRetention": + "ZDR ปิดใช้งานฟีเจอร์ API สำคัญที่ต้องอาศัยข้อมูลที่จัดเก็บไว้ ซึ่งรวมถึง Responses API แบบมีสถานะ, Files and Collections และ Batch API", + "go.faq.a5.gptRetention": + "ระบบจะสร้างบันทึกการตรวจสอบการใช้งานในทางที่ผิดสำหรับการใช้งานฟีเจอร์ API ทั้งหมด และเก็บรักษาไว้นานสูงสุด 30 วัน", + "go.faq.a5.museRetention": + "ราคาของ token ลดลงอย่างมาก โดยแลกกับการอนุญาตให้นำพรอมต์และผลลัพธ์ที่สร้างขึ้นของคุณไปใช้ฝึกโมเดล Meta ในอนาคต", + "go.faq.a5.learnMore": "ดูข้อมูลเพิ่มเติม", + "go.faq.a5.deepseekRetention": "ข้อตกลง ZDR จะต่ออายุทุกเดือน ข้อตกลงปัจจุบันมีผลใช้ถึงวันที่ 30 กันยายน 2026", + + "go.faq.a5.beforeExceptions": + "โมเดล Go โฮสต์ในสหรัฐอเมริกา ผู้ให้บริการปฏิบัติตามนโยบายไม่เก็บรักษาข้อมูล (zero-retention policy) และไม่ใช้ข้อมูลของคุณสำหรับการฝึกโมเดล โดยมี", + "go.faq.a5.exceptionsLink": "ข้อยกเว้นดังนี้", + "go.faq.q6": "ฉันสามารถเติมเครดิตได้หรือไม่?", + "go.faq.a6": "หากคุณต้องการใช้งานเพิ่ม คุณสามารถเติมเครดิตในบัญชีของคุณได้", + "go.faq.q7": "ฉันสามารถยกเลิกได้หรือไม่?", + "go.faq.a7": "ได้ คุณสามารถยกเลิกได้ตลอดเวลา", + "go.faq.q8": "ฉันสามารถใช้ Go กับเอเจนต์เขียนโค้ดอื่นได้หรือไม่?", + "go.faq.a8": "ได้ คุณสามารถใช้ Go กับเอเจนต์ใดก็ได้ ทำตามคำแนะนำการตั้งค่าในเอเจนต์เขียนโค้ดที่คุณต้องการ", + + "go.faq.q9": "ความแตกต่างระหว่างโมเดลฟรีและ Go คืออะไร?", + "go.faq.a9": + "โมเดลฟรีประกอบด้วย Big Pickle และโมเดลโปรโมชันที่มีให้บริการในขณะนั้น โดยมีโควตา 200 คำขอ/วัน Go นำเสนอชุดโมเดลที่คัดสรร พร้อมโควตาคำขอที่สูงกว่าซึ่งบังคับใช้ตามกรอบเวลาแบบต่อเนื่อง (5 ชั่วโมง, รายสัปดาห์ และรายเดือน) เทียบเท่าโควตาพื้นฐานประมาณ $12 ต่อ 5 ชั่วโมง, $30 ต่อสัปดาห์ และ $60 ต่อเดือน โดยโควตาเฉพาะอาจแตกต่างกันไปตามโมเดล (จำนวนคำขอจริงแตกต่างกันไปตามโมเดลและการใช้งาน)", + "go.faq.q10": "ฉันขอเงินคืนได้หรือไม่?", + "go.faq.a10": + "หากมีการเรียกเก็บเงินภายใน 14 วันที่ผ่านมาและคุณยังไม่ได้ใช้สิทธิ์การใช้งาน Go เลยในรอบการเรียกเก็บเงินนั้น คุณอาจมีสิทธิ์ได้รับเงินคืน {{contact}}เพื่อขอเงินคืน", + + "zen.api.error.rateLimitExceeded": "เกินขีดจำกัดอัตราการใช้งาน กรุณาลองใหม่ในภายหลัง", + "zen.api.error.modelNotSupported": "ไม่รองรับโมเดล {{model}}", + "zen.api.error.modelFormatNotSupported": "ไม่รองรับโมเดล {{model}} สำหรับรูปแบบ {{format}}", + "zen.api.error.noProviderAvailable": "ไม่มีผู้ให้บริการที่พร้อมใช้งาน", + "zen.api.error.providerNotSupported": "ไม่รองรับผู้ให้บริการ {{provider}}", + "zen.api.error.missingApiKey": "ไม่มี API key", + "zen.api.error.invalidApiKey": "API key ไม่ถูกต้อง", + "zen.api.error.requestBlockedByUpstreamProvider": "คำขอถูกบล็อกโดยผู้ให้บริการต้นทาง", + "zen.api.error.subscriptionQuotaExceeded": "โควต้าการสมัครสมาชิกเกินขีดจำกัด ลองใหม่ในอีก {{retryIn}}", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "ถึงขีดจำกัดการใช้งานในรอบ 5 ชั่วโมงแล้ว จะรีเซ็ตในอีก {{retryIn}} หากต้องการใช้โมเดลนี้ต่อทันที ให้เปิดใช้งานจากยอดเงินคงเหลือของคุณ: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "ถึงขีดจำกัดการใช้งานรายสัปดาห์แล้ว จะรีเซ็ตในอีก {{retryIn}} หากต้องการใช้โมเดลนี้ต่อทันที ให้เปิดใช้งานจากยอดเงินคงเหลือของคุณ: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "ถึงขีดจำกัดการใช้งานรายเดือนแล้ว จะรีเซ็ตในอีก {{retryIn}} หากต้องการใช้โมเดลนี้ต่อทันที ให้เปิดใช้งานจากยอดเงินคงเหลือของคุณ: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "ไม่มีวิธีการชำระเงิน เพิ่มวิธีการชำระเงินที่นี่: {{billingUrl}}", + "zen.api.error.insufficientBalance": "ยอดเงินคงเหลือไม่เพียงพอ จัดการการเรียกเก็บเงินของคุณที่นี่: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Workspace ของคุณถึงขีดจำกัดการใช้จ่ายรายเดือนที่ ${{amount}} แล้ว จัดการขีดจำกัดของคุณที่นี่: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "คุณถึงขีดจำกัดการใช้จ่ายรายเดือนที่ ${{amount}} แล้ว จัดการขีดจำกัดของคุณที่นี่: {{membersUrl}}", + "zen.api.error.modelDisabled": "โมเดลถูกปิดใช้งาน", + "zen.api.error.regionNotAllowed": + "โมเดลเวอร์ชันล่าสุดนี้ให้บริการเฉพาะผ่านระบบที่โฮสต์ในประเทศจีน และต้องให้ความยินยอมอย่างชัดแจ้งก่อนใช้งาน: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "โมเดลนี้ไม่พร้อมให้บริการในประเทศของคุณ", + "zen.api.error.trainingNotAllowed": + "โมเดลนี้เก็บรวบรวมข้อมูลที่ใช้เพื่อปรับปรุงคุณภาพของโมเดล และต้องได้รับความยินยอมอย่างชัดแจ้งก่อนใช้งาน: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "โปรโมชันฟรีสำหรับ {{model}} สิ้นสุดแล้ว คุณสามารถใช้โมเดลต่อได้โดยสมัครสมาชิก OpenCode Go - {{link}}", + + "black.meta.title": "OpenCode Black | เข้าถึงโมเดลเขียนโค้ดที่ดีที่สุดในโลก", + "black.meta.description": "เข้าถึง Claude, GPT, Gemini และอื่นๆ ด้วยแผนสมาชิก OpenCode Black", + "black.hero.title": "เข้าถึงโมเดลเขียนโค้ดที่ดีที่สุดในโลก", + "black.hero.subtitle": "รวมถึง Claude, GPT, Gemini และอื่นๆ อีกมากมาย", + "black.title": "OpenCode Black | ราคา", + "black.paused": "การสมัครแผน Black หยุดชั่วคราว", + "black.plan.icon20": "แผน Black 20", + "black.plan.icon100": "แผน Black 100", + "black.plan.icon200": "แผน Black 200", + "black.plan.multiplier100": "ใช้งานได้มากกว่า Black 20 ถึง 5 เท่า", + "black.plan.multiplier200": "ใช้งานได้มากกว่า Black 20 ถึง 20 เท่า", + "black.price.perMonth": "ต่อเดือน", + "black.price.perPersonBilledMonthly": "ต่อคน เรียกเก็บรายเดือน", + "black.terms.1": "การสมัครสมาชิกของคุณจะยังไม่เริ่มต้นทันที", + "black.terms.2": "คุณจะถูกเพิ่มในรายชื่อรอและจะได้รับการเปิดใช้งานเร็วๆ นี้", + "black.terms.3": "บัตรของคุณจะถูกตัดเงินเมื่อการสมัครสมาชิกของคุณถูกเปิดใช้งานเท่านั้น", + "black.terms.4": "มีขีดจำกัดการใช้งาน การใช้ระบบอัตโนมัติอย่างหนักอาจทำให้ถึงขีดจำกัดเร็วขึ้น", + "black.terms.5": "การสมัครสมาชิกสำหรับบุคคลธรรมดา ติดต่อฝ่ายองค์กรสำหรับทีม", + "black.terms.6": "ขีดจำกัดอาจมีการปรับเปลี่ยนและแผนอาจถูกยกเลิกในอนาคต", + "black.terms.7": "ยกเลิกการสมัครสมาชิกได้ตลอดเวลา", + "black.action.continue": "ดำเนินการต่อ", + "black.finePrint.beforeTerms": "ราคาที่แสดงยังไม่รวมภาษีที่เกี่ยวข้อง", + "black.finePrint.terms": "ข้อกำหนดการให้บริการ", + "black.workspace.title": "OpenCode Black | เลือก Workspace", + "black.workspace.selectPlan": "เลือก Workspace สำหรับแผนนี้", + "black.workspace.name": "Workspace {{n}}", + "black.subscribe.title": "สมัครสมาชิก OpenCode Black", + "black.subscribe.paymentMethod": "วิธีการชำระเงิน", + "black.subscribe.loadingPaymentForm": "กำลังโหลดแบบฟอร์มการชำระเงิน...", + "black.subscribe.selectWorkspaceToContinue": "เลือก Workspace เพื่อดำเนินการต่อ", + "black.subscribe.failurePrefix": "โอ๊ะโอ!", + "black.subscribe.error.generic": "เกิดข้อผิดพลาด", + "black.subscribe.error.invalidPlan": "แผนไม่ถูกต้อง", + "black.subscribe.error.workspaceRequired": "จำเป็นต้องมี Workspace ID", + "black.subscribe.error.alreadySubscribed": "Workspace นี้มีการสมัครสมาชิกอยู่แล้ว", + "black.subscribe.processing": "กำลังดำเนินการ...", + "black.subscribe.submit": "สมัครสมาชิก ${{plan}}", + "black.subscribe.form.chargeNotice": "คุณจะถูกเรียกเก็บเงินเมื่อการสมัครสมาชิกของคุณถูกเปิดใช้งานเท่านั้น", + "black.subscribe.success.title": "คุณอยู่ในรายชื่อรอ OpenCode Black แล้ว", + "black.subscribe.success.subscriptionPlan": "แผนการสมัครสมาชิก", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "จำนวนเงิน", + "black.subscribe.success.amountValue": "${{plan}} ต่อเดือน", + "black.subscribe.success.paymentMethod": "วิธีการชำระเงิน", + "black.subscribe.success.dateJoined": "วันที่เข้าร่วม", + "black.subscribe.success.chargeNotice": "บัตรของคุณจะถูกเรียกเก็บเงินเมื่อการสมัครสมาชิกของคุณถูกเปิดใช้งาน", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "การใช้งาน", + "workspace.nav.apiKeys": "API Keys", + "workspace.nav.members": "สมาชิก", + "workspace.nav.billing": "การเรียกเก็บเงิน", + "workspace.nav.settings": "การตั้งค่า", + + "workspace.home.banner.beforeLink": "โมเดลที่เชื่อถือได้และปรับแต่งแล้วสำหรับเอเจนต์เขียนโค้ด", + "workspace.lite.banner.beforeLink": "โมเดลเขียนโค้ดต้นทุนต่ำสำหรับทุกคน", + "workspace.home.billing.loading": "กำลังโหลด...", + "workspace.home.billing.enable": "เปิดใช้งานการเรียกเก็บเงิน", + "workspace.home.billing.currentBalance": "ยอดคงเหลือปัจจุบัน", + + "workspace.newUser.feature.tested.title": "โมเดลที่ผ่านการทดสอบและตรวจสอบแล้ว", + "workspace.newUser.feature.tested.body": + "เราได้ทำเบนช์มาร์กและทดสอบโมเดลสำหรับเอเจนต์เขียนโค้ดโดยเฉพาะเพื่อให้มั่นใจถึงประสิทธิภาพที่ดีที่สุด", + "workspace.newUser.feature.quality.title": "คุณภาพสูงสุด", + "workspace.newUser.feature.quality.body": + "เข้าถึงโมเดลที่กำหนดค่าไว้เพื่อประสิทธิภาพสูงสุด - ไม่มีการลดเกรดหรือส่งงานไปยังผู้ให้บริการที่ราคาถูกกว่า", + "workspace.newUser.feature.lockin.title": "ไม่มีการผูกมัด (Lock-in)", + "workspace.newUser.feature.lockin.body": + "ใช้ Zen กับเอเจนต์เขียนโค้ดใดก็ได้ และกลับมาใช้ผู้ให้บริการรายอื่นด้วย OpenCode ได้ทุกเมื่อที่คุณต้องการ", + "workspace.newUser.copyApiKey": "คัดลอก API key", + "workspace.newUser.copyKey": "คัดลอก Key", + "workspace.newUser.copied": "คัดลอกแล้ว!", + "workspace.newUser.step.enableBilling": "เปิดใช้งานการเรียกเก็บเงิน", + "workspace.newUser.step.login.before": "รัน", + "workspace.newUser.step.login.after": "และเลือก OpenCode", + "workspace.newUser.step.pasteKey": "วาง API key ของคุณ", + "workspace.newUser.step.models.before": "เริ่ม OpenCode และรัน", + "workspace.newUser.step.models.after": "เพื่อเลือกโมเดล", + + "workspace.models.title": "โมเดล", + "workspace.models.subtitle.beforeLink": "จัดการว่าโมเดลใดที่สมาชิกใน Workspace สามารถเข้าถึงได้", + "workspace.models.table.model": "โมเดล", + "workspace.models.table.enabled": "เปิดใช้งาน", + + "workspace.providers.title": "Bring Your Own Key", + "workspace.providers.subtitle": "กำหนดค่า API keys ของคุณเองจากผู้ให้บริการ AI", + "workspace.providers.placeholder": "ป้อน {{provider}} API key ({{prefix}}...)", + "workspace.providers.configure": "กำหนดค่า", + "workspace.providers.edit": "แก้ไข", + "workspace.providers.delete": "ลบ", + "workspace.providers.saving": "กำลังบันทึก...", + "workspace.providers.save": "บันทึก", + "workspace.providers.table.provider": "ผู้ให้บริการ", + "workspace.providers.table.apiKey": "API Key", + + "workspace.usage.title": "ประวัติการใช้งาน", + "workspace.usage.subtitle": "การใช้งานและต้นทุน API ล่าสุด", + "workspace.usage.empty": "ทำการเรียก API ครั้งแรกเพื่อเริ่มต้น", + "workspace.usage.table.date": "วันที่", + "workspace.usage.table.model": "โมเดล", + "workspace.usage.table.input": "Input", + "workspace.usage.table.output": "Output", + "workspace.usage.table.cost": "ค่าใช้จ่าย", + "workspace.usage.table.session": "เซสชัน", + "workspace.usage.breakdown.input": "Input", + "workspace.usage.breakdown.cacheRead": "Cache Read", + "workspace.usage.breakdown.cacheWrite": "Cache Write", + "workspace.usage.breakdown.output": "Output", + "workspace.usage.breakdown.reasoning": "Reasoning", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "ค่าใช้จ่าย", + "workspace.cost.subtitle": "ต้นทุนการใช้งานแยกตามโมเดล", + "workspace.cost.allModels": "ทุกโมเดล", + "workspace.cost.allKeys": "ทุก Key", + "workspace.cost.deletedSuffix": "(ลบแล้ว)", + "workspace.cost.empty": "ไม่มีข้อมูลการใช้งานในช่วงเวลาที่เลือก", + "workspace.cost.subscriptionShort": "sub", + + "workspace.keys.title": "API Keys", + "workspace.keys.subtitle": "จัดการ API keys ของคุณสำหรับการเข้าถึงบริการ OpenCode", + "workspace.keys.create": "สร้าง API Key", + "workspace.keys.placeholder": "ป้อนชื่อ Key", + "workspace.keys.empty": "สร้าง OpenCode Gateway API key", + "workspace.keys.table.name": "ชื่อ", + "workspace.keys.table.key": "Key", + "workspace.keys.table.createdBy": "สร้างโดย", + "workspace.keys.table.lastUsed": "ใช้ล่าสุด", + "workspace.keys.copyApiKey": "คัดลอก API key", + "workspace.keys.delete": "ลบ", + + "workspace.members.title": "สมาชิก", + "workspace.members.subtitle": "จัดการสมาชิก Workspace และสิทธิ์ของพวกเขา", + "workspace.members.invite": "เชิญสมาชิก", + "workspace.members.inviting": "กำลังเชิญ...", + "workspace.members.beta.beforeLink": "Workspace ให้บริการฟรีสำหรับทีมในช่วงเบต้า", + "workspace.members.form.invitee": "ผู้ได้รับเชิญ", + "workspace.members.form.emailPlaceholder": "ใส่อีเมล", + "workspace.members.form.role": "บทบาท", + "workspace.members.form.monthlyLimit": "วงเงินการใช้จ่ายรายเดือน", + "workspace.members.noLimit": "ไม่มีขีดจำกัด", + "workspace.members.noLimitLowercase": "ไม่มีขีดจำกัด", + "workspace.members.invited": "เชิญแล้ว", + "workspace.members.edit": "แก้ไข", + "workspace.members.delete": "ลบ", + "workspace.members.saving": "กำลังบันทึก...", + "workspace.members.save": "บันทึก", + "workspace.members.table.email": "อีเมล", + "workspace.members.table.role": "บทบาท", + "workspace.members.table.monthLimit": "วงเงินเดือน", + "workspace.members.role.admin": "แอดมิน", + "workspace.members.role.adminDescription": "สามารถจัดการโมเดล สมาชิก และการเรียกเก็บเงินได้", + "workspace.members.role.member": "สมาชิก", + "workspace.members.role.memberDescription": "สามารถสร้าง API keys สำหรับตัวเองได้เท่านั้น", + + "workspace.settings.title": "การตั้งค่า", + "workspace.settings.subtitle": "อัปเดตชื่อ Workspace และการตั้งค่าของคุณ", + "workspace.settings.workspaceName": "ชื่อ Workspace", + "workspace.settings.defaultName": "ค่าเริ่มต้น", + "workspace.settings.updating": "กำลังอัปเดต...", + "workspace.settings.save": "บันทึก", + "workspace.settings.edit": "แก้ไข", + + "workspace.billing.title": "การเรียกเก็บเงิน", + "workspace.billing.subtitle.beforeLink": "จัดการวิธีการชำระเงิน", + "workspace.billing.contactUs": "ติดต่อเรา", + "workspace.billing.subtitle.afterLink": "หากคุณมีคำถามใดๆ", + "workspace.billing.currentBalance": "ยอดคงเหลือปัจจุบัน", + "workspace.billing.add": "เพิ่ม $", + "workspace.billing.enterAmount": "ใส่จำนวนเงิน", + "workspace.billing.loading": "กำลังโหลด...", + "workspace.billing.addAction": "เพิ่ม", + "workspace.billing.addBalance": "เพิ่มยอดคงเหลือ", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "เชื่อมโยงกับ Stripe", + "workspace.billing.manage": "จัดการ", + "workspace.billing.enable": "เปิดใช้งานการเรียกเก็บเงิน", + + "workspace.monthlyLimit.title": "วงเงินรายเดือน", + "workspace.monthlyLimit.subtitle": "ตั้งขีดจำกัดการใช้งานรายเดือนสำหรับบัญชีของคุณ", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "กำลังตั้งค่า...", + "workspace.monthlyLimit.set": "ตั้งค่า", + "workspace.monthlyLimit.edit": "แก้ไขขีดจำกัด", + "workspace.monthlyLimit.noLimit": "ไม่ได้ตั้งขีดจำกัดการใช้งาน", + "workspace.monthlyLimit.currentUsage.beforeMonth": "การใช้งานปัจจุบันสำหรับ", + "workspace.monthlyLimit.currentUsage.beforeAmount": "คือ $", + + "workspace.redeem.title": "แลกคูปอง", + "workspace.redeem.subtitle": "แลกรหัสคูปองเพื่อรับเครดิตหรือสิทธิพิเศษ", + "workspace.redeem.placeholder": "กรอกรหัสคูปอง", + "workspace.redeem.redeem": "แลก", + "workspace.redeem.redeeming": "กำลังแลก...", + "workspace.redeem.success": "แลกคูปองสำเร็จ", + + "workspace.reload.title": "โหลดซ้ำอัตโนมัติ", + "workspace.reload.disabled.before": "การโหลดซ้ำอัตโนมัติ", + "workspace.reload.disabled.state": "ปิดใช้งานอยู่", + "workspace.reload.disabled.after": "เปิดใช้งานเพื่อเติมเงินอัตโนมัติเมื่อยอดคงเหลือต่ำ", + "workspace.reload.enabled.before": "การโหลดซ้ำอัตโนมัติ", + "workspace.reload.enabled.state": "เปิดใช้งานอยู่", + "workspace.reload.enabled.middle": "เราจะเติมเงิน", + "workspace.reload.processingFee": "ค่าธรรมเนียมดำเนินการ", + "workspace.reload.enabled.after": "เมื่อยอดคงเหลือถึง", + "workspace.reload.edit": "แก้ไข", + "workspace.reload.enable": "เปิดใช้งาน", + "workspace.reload.enableAutoReload": "เปิดใช้งานการโหลดซ้ำอัตโนมัติ", + "workspace.reload.reloadAmount": "เติมเงิน $", + "workspace.reload.whenBalanceReaches": "เมื่อยอดถึง $", + "workspace.reload.saving": "กำลังบันทึก...", + "workspace.reload.save": "บันทึก", + "workspace.reload.failedAt": "เติมเงินล้มเหลวเมื่อ", + "workspace.reload.reason": "เหตุผล:", + "workspace.reload.updatePaymentMethod": "โปรดอัปเดตวิธีการชำระเงินของคุณแล้วลองอีกครั้ง", + "workspace.reload.retrying": "กำลังลองอีกครั้ง...", + "workspace.reload.retry": "ลองอีกครั้ง", + "workspace.reload.error.paymentFailed": "การชำระเงินล้มเหลว", + + "workspace.payments.title": "ประวัติการชำระเงิน", + "workspace.payments.subtitle": "รายการธุรกรรมการชำระเงินล่าสุด", + "workspace.payments.table.date": "วันที่", + "workspace.payments.table.paymentId": "Payment ID", + "workspace.payments.table.amount": "จำนวนเงิน", + "workspace.payments.table.receipt": "ใบเสร็จ", + "workspace.payments.type.credit": "credit", + "workspace.payments.type.subscription": "subscription", + "workspace.payments.view": "ดู", + + "workspace.black.loading": "กำลังโหลด...", + "workspace.black.time.day": "วัน", + "workspace.black.time.days": "วัน", + "workspace.black.time.hour": "ชั่วโมง", + "workspace.black.time.hours": "ชั่วโมง", + "workspace.black.time.minute": "นาที", + "workspace.black.time.minutes": "นาที", + "workspace.black.time.fewSeconds": "ไม่กี่วินาที", + "workspace.black.subscription.title": "การสมัครสมาชิก", + "workspace.black.subscription.message": "คุณสมัครสมาชิก OpenCode Black ในราคา ${{plan}} ต่อเดือน", + "workspace.black.subscription.manage": "จัดการการสมัครสมาชิก", + "workspace.black.subscription.rollingUsage": "การใช้งาน 5 ชั่วโมง", + "workspace.black.subscription.weeklyUsage": "การใช้งานรายสัปดาห์", + "workspace.black.subscription.resetsIn": "รีเซ็ตใน", + "workspace.black.subscription.useBalance": "ใช้ยอดเงินคงเหลือของคุณหลังจากถึงขีดจำกัดการใช้งานแล้ว", + "workspace.black.waitlist.title": "รายชื่อรอ", + "workspace.black.waitlist.joined": "คุณอยู่ในรายชื่อรอสำหรับแผน OpenCode Black ราคา ${{plan}} ต่อเดือน", + "workspace.black.waitlist.ready": "เราพร้อมที่จะลงทะเบียนให้คุณเข้าสู่แผน OpenCode Black ราคา ${{plan}} ต่อเดือนแล้ว", + "workspace.black.waitlist.leave": "ออกจากรายชื่อรอ", + "workspace.black.waitlist.leaving": "กำลังออกจาก...", + "workspace.black.waitlist.left": "ออกแล้ว", + "workspace.black.waitlist.enroll": "ลงทะเบียน", + "workspace.black.waitlist.enrolling": "กำลังลงทะเบียน...", + "workspace.black.waitlist.enrolled": "ลงทะเบียนแล้ว", + "workspace.black.waitlist.enrollNote": + "เมื่อคุณคลิกลงทะเบียน การสมัครสมาชิกของคุณจะเริ่มต้นทันทีและบัตรของคุณจะถูกเรียกเก็บเงิน", + + "workspace.lite.loading": "กำลังโหลด...", + "workspace.lite.time.day": "วัน", + "workspace.lite.time.days": "วัน", + "workspace.lite.time.hour": "ชั่วโมง", + "workspace.lite.time.hours": "ชั่วโมง", + "workspace.lite.time.minute": "นาที", + "workspace.lite.time.minutes": "นาที", + "workspace.lite.time.fewSeconds": "ไม่กี่วินาที", + "workspace.lite.subscription.message": "คุณได้สมัครสมาชิก OpenCode Go แล้ว", + "workspace.lite.subscription.manage": "จัดการการสมัครสมาชิก", + "workspace.lite.subscription.rollingUsage": "การใช้งานใน 5 ชั่วโมง", + "workspace.lite.subscription.rollingQuota": "โควตา 5 ชั่วโมง", + "workspace.lite.subscription.weeklyUsage": "การใช้งานรายสัปดาห์", + "workspace.lite.subscription.weeklyQuota": "โควตารายสัปดาห์", + "workspace.lite.subscription.monthlyUsage": "การใช้งานรายเดือน", + "workspace.lite.subscription.monthlyQuota": "โควตารายเดือน", + "workspace.lite.subscription.resetsIn": "รีเซ็ตใน", + "workspace.lite.subscription.showDetails": "แสดงรายละเอียด", + "workspace.lite.subscription.hideDetails": "ซ่อนรายละเอียด", + "workspace.lite.subscription.model": "โมเดล", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "รวม", + "workspace.lite.subscription.useBalance": "ใช้ยอดคงเหลือของคุณหลังจากถึงขีดจำกัดการใช้งาน", + "workspace.lite.subscription.selectProvider": + 'เลือก "OpenCode Go" เป็นผู้ให้บริการในการตั้งค่า opencode ของคุณเพื่อใช้โมเดล Go', + "workspace.lite.providers.title": "ผู้ให้บริการ", + "workspace.lite.providers.description": "ควบคุมผู้ให้บริการที่ใช้สำหรับการกำหนดเส้นทาง", + "workspace.lite.providers.allowTraining": "อนุญาตโมเดลที่ฝึกด้วยข้อมูลคำขอ", + "workspace.lite.providers.useChina": "เปิดใช้โมเดลที่โฮสต์ในจีน", + "workspace.lite.black.message": + "ขณะนี้คุณสมัครสมาชิก OpenCode Black หรืออยู่ในรายการรอ โปรดยกเลิกการสมัครก่อนหากต้องการเปลี่ยนไปใช้ Go", + "workspace.lite.other.message": + "สมาชิกคนอื่นใน Workspace นี้ได้สมัคร OpenCode Go แล้ว สามารถสมัครได้เพียงหนึ่งคนต่อหนึ่ง Workspace เท่านั้น", + "workspace.lite.promo.description": + "OpenCode Go ราคา {{price}} และมอบการเข้าถึงโมเดลการเขียนโค้ดแบบเปิดยอดนิยมอย่างเสถียรพร้อมขีดจำกัดการใช้งานที่ให้มาอย่างเหลือเฟือ", + "workspace.lite.promo.price": "$10/เดือน", + "workspace.lite.promo.modelsTitle": "สิ่งที่รวมอยู่ด้วย", + "workspace.lite.promo.footer": + "แผนนี้ออกแบบมาสำหรับผู้ใช้งานต่างประเทศเป็นหลักและให้การเข้าถึงที่เสถียรทั่วโลก ราคาและขีดจำกัดการใช้งานอาจเปลี่ยนแปลงได้ตามสิ่งที่เราเรียนรู้จากการใช้งานและข้อเสนอแนะในช่วงแรก", + "workspace.lite.promo.subscribe": "สมัครสมาชิก Go", + "workspace.lite.promo.subscribing": "กำลังเปลี่ยนเส้นทาง...", + "workspace.lite.promo.otherMethods": "วิธีการชำระเงินอื่นๆ", + "workspace.lite.promo.selectMethod": "เลือกวิธีการชำระเงิน", + + "workspace.referral.copyLink": "คัดลอกลิงก์", + "workspace.referral.copied": "คัดลอกแล้ว", + "workspace.referral.overview.title": "ชวนเพื่อน", + "workspace.referral.overview.subtitle": "รับ $5 เมื่อเพื่อนสมัครสมาชิก เพื่อนก็จะได้รับ $5 เช่นกัน", + "workspace.referral.instructions.share": "แชร์ลิงก์แนะนำของคุณ", + "workspace.referral.instructions.subscribe": "เพื่อนของคุณเข้าร่วมและสมัครสมาชิก Go", + "workspace.referral.instructions.claim": "คุณทั้งคู่จะได้รับเครดิตการใช้งาน $5 เพื่อใช้กับขีดจำกัดการใช้งาน Go", + "workspace.referral.rewards.title": "รางวัลการแนะนำ", + "workspace.referral.rewards.description": "ใช้เครดิตการแนะนำที่มีอยู่กับการใช้งาน Go ของคุณ", + "workspace.referral.rewards.subtitle": "ใช้แล้ว {{applied}} / {{total}} รางวัล", + "workspace.referral.rewards.empty": "ยังไม่มีรางวัลการแนะนำ", + "workspace.referral.table.reward": "รางวัล", + "workspace.referral.table.referral": "คำอธิบาย", + "workspace.referral.table.date": "วันที่", + "workspace.referral.reward.description.inviter": "เชิญ {{email}}", + "workspace.referral.reward.description.invitee": "ได้รับเชิญจาก {{email}}", + "workspace.referral.reward.action.subscribeUnlock": "สมัครสมาชิกเพื่อปลดล็อก", + "workspace.referral.reward.action.view": "ดูรางวัล", + "workspace.referral.reward.action.applied": "ใช้รางวัลแล้ว", + "workspace.referral.reward.source.pendingInviter": "รอเพื่อนสมัครสมาชิก", + "workspace.referral.reward.source.pendingInvitee": "สมัครสมาชิกเพื่อปลดล็อกรางวัล", + "workspace.referral.reward.source.available": "รางวัลพร้อมใช้งาน", + "workspace.referral.reward.source.applied": "ใช้รางวัลแล้ว", + "workspace.referral.reward.status.applied": "ใช้รางวัลแล้ว", + "workspace.referral.reward.status.pendingInviter": "สมัครสมาชิกเพื่อปลดล็อก", + "workspace.referral.reward.status.pendingInvitee": "สมัครสมาชิกเพื่อปลดล็อก", + "workspace.referral.apply.noGo": "สมัครสมาชิกเพื่อปลดล็อก", + "workspace.referral.apply.preview": "ดูรางวัล", + "workspace.referral.apply.action": "ใช้", + "workspace.referral.apply.confirmTitle": "ใช้รางวัล", + "workspace.referral.apply.confirmBody": "ใช้ {{amount}} เพื่อลดการใช้งานปัจจุบันของ workspace นี้", + "workspace.referral.apply.confirmAction": "ใช้", + + "download.title": "OpenCode | ดาวน์โหลด", + "download.meta.description": "ดาวน์โหลด OpenCode สำหรับ macOS, Windows และ Linux", + "download.hero.title": "ดาวน์โหลด OpenCode สำหรับเดสก์ท็อป", + "download.hero.subtitle": "พร้อมใช้งานในเวอร์ชันเบต้าสำหรับ macOS, Windows และ Linux", + "download.hero.button": "ดาวน์โหลดสำหรับ {{os}}", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "ส่วนขยาย OpenCode", + "download.section.integrations": "การเชื่อมต่อ OpenCode", + "download.action.download": "ดาวน์โหลด", + "download.action.install": "ติดตั้ง", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "ไม่จำเป็นเสมอไป แต่อาจจะต้องมี คุณจะต้องมีการสมัครสมาชิก AI หากต้องการเชื่อมต่อ OpenCode กับผู้ให้บริการที่มีค่าใช้จ่าย แม้ว่าคุณจะสามารถทำงานกับ", + "download.faq.a3.localLink": "โมเดล Local", + "download.faq.a3.afterLocal.beforeZen": "ได้ฟรี แม้ว่าเราจะแนะนำให้ผู้ใช้ใช้งาน", + "download.faq.a3.afterZen": ", OpenCode ก็ทำงานร่วมกับผู้ให้บริการยอดนิยมทั้งหมด เช่น OpenAI, Anthropic, xAI เป็นต้น", + + "download.faq.a5.p1": "OpenCode ใช้งานได้ฟรี 100%", + "download.faq.a5.p2.beforeZen": + "ค่าใช้จ่ายเพิ่มเติมใดๆ จะมาจากการสมัครสมาชิกของคุณกับผู้ให้บริการโมเดล แม้ว่า OpenCode จะทำงานร่วมกับผู้ให้บริการโมเดลใดก็ได้ แต่เราแนะนำให้ใช้", + "download.faq.a5.p2.afterZen": "", + + "download.faq.a6.p1": "ข้อมูลของคุณจะถูกจัดเก็บเฉพาะเมื่อคุณสร้างลิงก์ที่แชร์ได้ใน OpenCode เท่านั้น", + "download.faq.a6.p2.beforeShare": "เรียนรู้เพิ่มเติมเกี่ยวกับ", + "download.faq.a6.shareLink": "หน้าแชร์", + + "enterprise.title": "OpenCode | โซลูชันระดับองค์กรสำหรับองค์กรของคุณ", + "enterprise.meta.description": "ติดต่อ OpenCode สำหรับโซลูชันระดับองค์กร", + "enterprise.hero.title": "โค้ดของคุณเป็นของคุณ", + "enterprise.hero.body1": + "OpenCode ทำงานอย่างปลอดภัยภายในองค์กรของคุณ โดยไม่มีการจัดเก็บข้อมูลหรือบริบท และไม่มีข้อจำกัดด้านไลเซนส์หรือการอ้างสิทธิ์ความเป็นเจ้าของ เริ่มทดลองใช้งานกับทีมของคุณ แล้วนำไปใช้งานทั่วทั้งองค์กรโดยการผสานรวมกับ SSO และ AI gateway ภายในของคุณ", + "enterprise.hero.body2": "บอกเราว่าเราจะช่วยได้อย่างไร", + "enterprise.form.name.label": "ชื่อ-นามสกุล", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "ตำแหน่ง", + "enterprise.form.role.placeholder": "ประธานกรรมการบริหาร", + "enterprise.form.company.label": "บริษัท", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "อีเมลบริษัท", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "หมายเลขโทรศัพท์", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "คุณกำลังพยายามแก้ปัญหาอะไร?", + "enterprise.form.message.placeholder": "เราต้องการความช่วยเหลือเรื่อง...", + "enterprise.form.send": "ส่ง", + "enterprise.form.sending": "กำลังส่ง...", + "enterprise.form.success": "ส่งข้อความแล้ว เราจะติดต่อกลับเร็วๆ นี้", + "enterprise.form.success.submitted": "ส่งแบบฟอร์มสำเร็จแล้ว", + "enterprise.form.error.allFieldsRequired": "จำเป็นต้องกรอกทุกช่อง", + "enterprise.form.error.invalidEmailFormat": "รูปแบบอีเมลไม่ถูกต้อง", + "enterprise.form.error.internalServer": "เกิดข้อผิดพลาดภายในเซิร์ฟเวอร์", + "enterprise.faq.title": "คำถามที่พบบ่อย", + "enterprise.faq.q1": "OpenCode Enterprise คืออะไร?", + "enterprise.faq.a1": + "OpenCode Enterprise สำหรับองค์กรที่ต้องการให้มั่นใจว่าโค้ดและข้อมูลจะไม่ออกนอกโครงสร้างพื้นฐานของตน ทำได้โดยใช้การตั้งค่าแบบศูนย์กลางที่ผสานรวมกับ SSO และ AI gateway ภายในของคุณ", + "enterprise.faq.q2": "จะเริ่มต้นกับ OpenCode Enterprise ได้อย่างไร?", + "enterprise.faq.a2": + "เพียงเริ่มจากการทดลองใช้งานภายในกับทีมของคุณ โดยค่าเริ่มต้น OpenCode ไม่จัดเก็บโค้ดหรือข้อมูลบริบทของคุณ ทำให้เริ่มต้นได้ง่าย จากนั้นติดต่อเราเพื่อพูดคุยเรื่องราคาและตัวเลือกการติดตั้งใช้งาน", + "enterprise.faq.q3": "ราคาสำหรับองค์กรคิดอย่างไร?", + "enterprise.faq.a3": + "เราเสนอราคาแบบต่อที่นั่ง (per-seat) หากคุณมี LLM gateway ของคุณเอง เราจะไม่คิดค่าบริการตามโทเค็นที่ใช้ สำหรับรายละเอียดเพิ่มเติม โปรดติดต่อเราเพื่อขอใบเสนอราคาตามความต้องการขององค์กรของคุณ", + "enterprise.faq.q4": "ข้อมูลของฉันปลอดภัยกับ OpenCode Enterprise หรือไม่?", + "enterprise.faq.a4": + "ใช่ OpenCode ไม่จัดเก็บโค้ดหรือข้อมูลบริบทของคุณ การประมวลผลทั้งหมดเกิดขึ้นในเครื่องหรือผ่านการเรียก API โดยตรงไปยังผู้ให้บริการ AI ของคุณ ด้วยการตั้งค่าแบบศูนย์กลางและการผสานรวม SSO ข้อมูลของคุณจะยังคงปลอดภัยอยู่ภายในโครงสร้างพื้นฐานขององค์กร", + + "brand.title": "OpenCode | แบรนด์", + "brand.meta.description": "แนวทางการใช้แบรนด์ OpenCode", + "brand.heading": "แนวทางการใช้แบรนด์", + "brand.subtitle": "ทรัพยากรและแอสเซทเพื่อช่วยให้คุณใช้งานแบรนด์ OpenCode", + "brand.downloadAll": "ดาวน์โหลดแอสเซททั้งหมด", + + "changelog.title": "OpenCode | บันทึกการเปลี่ยนแปลง", + "changelog.meta.description": "บันทึกการออกรุ่นและบันทึกการเปลี่ยนแปลง OpenCode", + "changelog.hero.title": "บันทึกการเปลี่ยนแปลง", + "changelog.hero.subtitle": "การอัปเดตและการปรับปรุงใหม่ใน OpenCode", + "changelog.empty": "ไม่พบรายการบันทึกการเปลี่ยนแปลง", + "changelog.viewJson": "ดู JSON", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarks", + "bench.list.table.agent": "เอเจนต์", + "bench.list.table.model": "โมเดล", + "bench.list.table.score": "คะแนน", + "bench.submission.error.allFieldsRequired": "จำเป็นต้องกรอกทุกช่อง", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "ไม่พบงาน", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "เอเจนต์", + "bench.detail.labels.model": "โมเดล", + "bench.detail.labels.task": "งาน", + "bench.detail.labels.repo": "Repo", + "bench.detail.labels.from": "จาก", + "bench.detail.labels.to": "ถึง", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "ระยะเวลาเฉลี่ย", + "bench.detail.labels.averageScore": "คะแนนเฉลี่ย", + "bench.detail.labels.averageCost": "ค่าใช้จ่ายเฉลี่ย", + "bench.detail.labels.summary": "สรุป", + "bench.detail.labels.runs": "Runs", + "bench.detail.labels.score": "คะแนน", + "bench.detail.labels.base": "ฐาน", + "bench.detail.labels.penalty": "บทลงโทษ", + "bench.detail.labels.weight": "น้ำหนัก", + "bench.detail.table.run": "Run", + "bench.detail.table.score": "คะแนน (ฐาน - บทลงโทษ)", + "bench.detail.table.cost": "ค่าใช้จ่าย", + "bench.detail.table.duration": "ระยะเวลา", + "bench.detail.run.title": "Run {{n}}", + "bench.detail.rawJson": "Raw JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/tr.ts b/packages/console/app/src/i18n/tr.ts new file mode 100644 index 0000000000000000000000000000000000000000..4289706cc66e6ac9bc8cdbbdd6849e170ca5e816 --- /dev/null +++ b/packages/console/app/src/i18n/tr.ts @@ -0,0 +1,880 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash sınırlı bir süre için 4x kullanım limiti sunuyor", + "go.graph.bonus": "{{count}}× kullanım", + "nav.github": "GitHub", + "nav.docs": "Dokümantasyon", + "nav.changelog": "Değişiklik günlüğü", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Kurumsal", + "nav.zen": "Zen", + "nav.login": "Giriş", + "nav.free": "İndir", + "nav.home": "Ana sayfa", + "nav.openMenu": "Menüyü aç", + "nav.getStartedFree": "Ücretsiz başla", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Logoyu SVG olarak kopyala", + "nav.context.copyWordmark": "Wordmark'ı SVG olarak kopyala", + "nav.context.brandAssets": "Marka varlıkları", + + "footer.github": "GitHub", + "footer.docs": "Dokümantasyon", + "footer.changelog": "Değişiklik günlüğü", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Marka", + "legal.privacy": "Gizlilik", + "legal.terms": "Koşullar", + + "email.title": "Yeni ürünler yayınladığımızda ilk siz haberdar olun", + "email.subtitle": "Erken erişim için bekleme listesine katılın.", + "email.placeholder": "E-posta adresi", + "email.subscribe": "Abone ol", + "email.success": "Neredeyse bitti, gelen kutunuzu kontrol edin ve e-postanızı onaylayın", + + "notFound.title": "Bulunamadı | opencode", + "notFound.heading": "404 - Sayfa bulunamadı", + "notFound.home": "Ana sayfa", + "notFound.docs": "Dokümantasyon", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode açık logo", + "notFound.logoDarkAlt": "opencode koyu logo", + + "user.logout": "Çıkış", + + "auth.callback.error.codeMissing": "Yetkilendirme kodu bulunamadı.", + + "workspace.select": "Çalışma alanı seç", + "workspace.createNew": "+ Yeni çalışma alanı oluştur", + "workspace.modal.title": "Yeni çalışma alanı oluştur", + "workspace.modal.placeholder": "Çalışma alanı adını girin", + + "common.cancel": "İptal", + "common.creating": "Oluşturuluyor...", + "common.create": "Oluştur", + "common.contactUs": "Bize ulaşın", + + "common.videoUnsupported": "Tarayıcınız video etiketini desteklemiyor.", + "common.figure": "Şekil {{n}}.", + "common.faq": "SSS", + "common.learnMore": "Daha fazla bilgi", + + "error.invalidPlan": "Geçersiz plan", + "error.workspaceRequired": "Çalışma alanı kimliği (ID) gerekli", + "error.alreadySubscribed": "Bu çalışma alanının zaten bir aboneliği var", + "error.limitRequired": "Limit gerekli.", + "error.monthlyLimitInvalid": "Geçerli bir aylık limit belirleyin.", + "error.workspaceNameRequired": "Çalışma alanı adı gerekli.", + "error.nameTooLong": "İsim 255 karakter veya daha az olmalıdır.", + "error.emailRequired": "E-posta gerekli", + "error.roleRequired": "Rol gerekli", + "error.idRequired": "Kimlik (ID) gerekli", + "error.nameRequired": "İsim gerekli", + "error.providerRequired": "Sağlayıcı gerekli", + "error.apiKeyRequired": "API anahtarı gerekli", + "error.modelRequired": "Model gerekli", + "error.reloadAmountMin": "Yükleme tutarı en az ${{amount}} olmalıdır", + "error.reloadTriggerMin": "Bakiye tetikleyicisi en az ${{amount}} olmalıdır", + + "app.meta.description": "OpenCode - Açık kaynaklı kodlama ajanı.", + + "home.title": "OpenCode | Açık kaynaklı yapay zeka kodlama ajanı", + + "temp.title": "opencode | Terminal için geliştirilmiş yapay zeka kodlama ajanı", + "temp.hero.title": "Terminal için geliştirilmiş yapay zeka kodlama ajanı", + "temp.zen": "opencode zen", + "temp.getStarted": "Başlayın", + "temp.feature.native.title": "Yerel (Native) TUI", + "temp.feature.native.body": "Duyarlı, yerel, temalandırılabilir bir terminal arayüzü", + "temp.feature.zen.beforeLink": "opencode tarafından sağlanan ", + "temp.feature.zen.link": "seçkin modeller listesi", + "temp.feature.zen.afterLink": "", + "temp.feature.models.beforeLink": "Yerel modeller dahil 75+ LLM sağlayıcısını ", + "temp.feature.models.afterLink": " üzerinden destekler", + "temp.screenshot.caption": "opencode TUI ve tokyonight teması", + "temp.screenshot.alt": "tokyonight temalı opencode TUI", + "temp.logoLightAlt": "opencode açık logo", + "temp.logoDarkAlt": "opencode koyu logo", + + "home.banner.badge": "Yeni", + "home.banner.text": "Masaüstü uygulamasında sekmelerle tanışın.", + "home.banner.platforms": "macOS, Windows ve Linux'ta kullanılabilir", + "home.banner.downloadNow": "Şimdi indir", + "home.banner.downloadBetaNow": "Masaüstü betayı şimdi indir", + "home.promo.title": "Masaüstü uygulamasında sekmelerle tanışın", + "home.promo.body": "Çalışmalarınızı ve etkin oturumlarınızı sekmelerle düzenleyin.", + "home.promo.cta": "Başlamak için en son sürümü indirin.", + "home.promo.close": "Masaüstü uygulaması duyurusunu kapat", + + "home.hero.title": "Açık kaynaklı yapay zeka kodlama ajanı", + "home.hero.subtitle.a": "Ücretsiz modeller dahil veya herhangi bir sağlayıcıdan herhangi bir modeli bağlayın,", + "home.hero.subtitle.b": "Claude, GPT, Gemini ve daha fazlası dahil.", + + "home.install.ariaLabel": "Kurulum seçenekleri", + + "home.what.title": "OpenCode nedir?", + "home.what.body": + "OpenCode, terminalinizde, IDE'nizde veya masaüstünde kod yazmanıza yardım eden açık kaynaklı bir ajandır.", + "home.what.lsp.title": "LSP etkin", + "home.what.lsp.body": "LLM için doğru LSP'leri otomatik olarak yükler", + "home.what.multiSession.title": "Çoklu oturum", + "home.what.multiSession.body": "Aynı projede birden fazla ajanı paralel çalıştırın", + "home.what.shareLinks.title": "Paylaşım bağlantıları", + "home.what.shareLinks.body": "Referans veya hata ayıklama için herhangi bir oturumu bağlantı olarak paylaşın", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Copilot hesabınızı kullanmak için GitHub ile giriş yapın", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "ChatGPT Plus veya Pro hesabınızı kullanmak için OpenAI ile giriş yapın", + "home.what.anyModel.title": "Herhangi bir model", + "home.what.anyModel.body": "Models.dev üzerinden 75+ LLM sağlayıcısı, yerel modeller dahil", + "home.what.anyEditor.title": "Herhangi bir editör", + "home.what.anyEditor.body": "Terminal arayüzü, masaüstü uygulaması ve IDE uzantısı olarak kullanılabilir", + "home.what.readDocs": "Dokümanları oku", + + "home.growth.title": "Açık kaynaklı yapay zeka kodlama ajanı", + "home.growth.body": + "GitHub'da {{stars}}+ yıldız, {{contributors}} katılımcı ve {{commits}}+ commit ile OpenCode, her ay {{monthlyUsers}}+ geliştirici tarafından kullanılıyor ve güveniliyor.", + "home.growth.githubStars": "GitHub Yıldızları", + "home.growth.contributors": "Katılımcılar", + "home.growth.monthlyDevs": "Aylık Geliştiriciler", + + "home.privacy.title": "Gizlilik öncelikli tasarlandı", + "home.privacy.body": + "OpenCode kodunuzu veya bağlam verilerinizi saklamaz; bu sayede gizliliğe duyarlı ortamlarda çalışabilir.", + "home.privacy.learnMore": "Hakkında daha fazla bilgi:", + "home.privacy.link": "gizlilik", + + "home.faq.q1": "OpenCode nedir?", + "home.faq.a1": + "OpenCode, herhangi bir AI modeliyle kod yazmanıza ve çalıştırmanıza yardım eden açık kaynaklı bir ajandır. Terminal arayüzü, masaüstü uygulaması veya IDE uzantısı olarak kullanılabilir.", + "home.faq.q2": "OpenCode'u nasıl kullanırım?", + "home.faq.a2.before": "Başlamanın en kolay yolu", + "home.faq.a2.link": "girişi okumaktır", + "home.faq.q3": "OpenCode için ek AI aboneliklerine ihtiyacım var mı?", + "home.faq.a3.p1": "Şart değil. OpenCode, hesap açmadan kullanabileceğiniz ücretsiz modellerle gelir.", + "home.faq.a3.p2.beforeZen": "Bunun dışında, popüler kodlama modellerini kullanmak için bir", + "home.faq.a3.p2.afterZen": " hesabı oluşturabilirsiniz.", + "home.faq.a3.p3": "Zen'i öneriyoruz, ancak OpenCode OpenAI, Anthropic, xAI gibi popüler sağlayıcılarla da çalışır.", + "home.faq.a3.p4.beforeLocal": "Hatta", + "home.faq.a3.p4.localLink": "yerel modellerinizi bağlayabilirsiniz", + "home.faq.q4": "Mevcut AI aboneliklerimi OpenCode ile kullanabilir miyim?", + "home.faq.a4.p1": + "Evet. OpenCode tüm büyük sağlayıcıların aboneliklerini destekler. Claude Pro/Max, ChatGPT Plus/Pro veya GitHub Copilot kullanabilirsiniz.", + "home.faq.q5": "OpenCode'u sadece terminalde mi kullanabilirim?", + "home.faq.a5.beforeDesktop": "Artık hayır! OpenCode artık sizin bu cihazlarınıza", + "home.faq.a5.desktop": "masaüstü", + "home.faq.a5.and": "ve", + "home.faq.a5.web": "web", + "home.faq.q6": "OpenCode ne kadar?", + "home.faq.a6": + "OpenCode %100 ücretsizdir. Ayrıca ücretsiz model setiyle gelir. Başka bir sağlayıcı bağlarsanız ek maliyetler olabilir.", + "home.faq.q7": "Veri ve gizlilik ne olacak?", + "home.faq.a7.p1": + "Verileriniz yalnızca ücretsiz modellerimizi kullandığınızda veya paylaşılabilir bağlantılar oluşturduğunuzda saklanır.", + "home.faq.a7.p2.beforeModels": "Daha fazla bilgi:", + "home.faq.a7.p2.modelsLink": "modellerimiz", + "home.faq.a7.p2.and": "ve", + "home.faq.a7.p2.shareLink": "paylaşım sayfaları", + "home.faq.q8": "OpenCode açık kaynak mı?", + "home.faq.a8.p1": "Evet, OpenCode tamamen açık kaynaktır. Kaynak kodu", + "home.faq.a8.p2": "'da", + "home.faq.a8.mitLicense": "MIT Lisansı", + "home.faq.a8.p3": + "altında herkese açıktır, yani herkes kullanabilir, değiştirebilir veya geliştirmeye katkıda bulunabilir. Topluluktan herkes issue açabilir, pull request gönderebilir ve işlevselliği genişletebilir.", + + "home.zenCta.title": "Kodlama ajanları için güvenilir, optimize modeller", + "home.zenCta.body": + "Zen, OpenCode'un kodlama ajanları için özel olarak test edip benchmark ettiği seçilmiş AI modellerine erişim sağlar. Sağlayıcılar arasında tutarsız performans ve kalite konusunda endişelenmeyin; çalışan, doğrulanmış modelleri kullanın.", + "home.zenCta.link": "Zen hakkında", + + "zen.title": "OpenCode Zen | Kodlama ajanları için güvenilir, optimize edilmiş modellerin seçilmiş seti", + "zen.hero.title": "Kodlama ajanları için güvenilir, optimize modeller", + "zen.hero.body": + "Zen, OpenCode'un kodlama ajanları için özel olarak test edip benchmark ettiği seçilmiş AI modellerine erişim sağlar. Sağlayıcılar arasında tutarsız performans ve kalite konusunda endişelenmeyin; çalışan, doğrulanmış modelleri kullanın.", + + "zen.faq.q1": "OpenCode Zen nedir?", + "zen.faq.a1": + "Zen, OpenCode ekibi tarafından oluşturulan ve kodlama ajanları için test edilip benchmark edilen seçilmiş bir AI model setidir.", + "zen.faq.q2": "Zen'i daha doğru yapan nedir?", + "zen.faq.a2": + "Zen yalnızca kodlama ajanları için özel olarak test edilip benchmark edilmiş modelleri sunar. Biftek kesmek için tereyağı bıçağı kullanmazsın; kodlama için kötü modeller kullanma.", + "zen.faq.q3": "Zen daha ucuz mu?", + "zen.faq.a3": + "Zen kâr amaçlı değildir. Zen, model sağlayıcılarının maliyetlerini size yansıtır. Zen'in kullanımı arttıkça OpenCode daha iyi fiyatlar pazarlayabilir ve bunları size yansıtabilir.", + "zen.faq.q4": "Zen ne kadar?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "istek başı ücret alır", + "zen.faq.a4.p1.afterPricing": + "ve hiçbir markup eklemez, yani model sağlayıcının ücretlendirdiği tutarı aynen ödersiniz.", + "zen.faq.a4.p2.beforeAccount": "Toplam maliyetiniz kullanım miktarına bağlıdır ve aylık harcama limitlerini", + "zen.faq.a4.p2.accountLink": "hesabınızda ayarlayabilirsiniz", + "zen.faq.a4.p3": + "Maliyetleri karşılamak için OpenCode, $20 bakiye yüklemesi başına yalnızca $1.23 tutarında küçük bir ödeme işleme ücreti ekler.", + "zen.faq.q5": "Veri ve gizlilik ne olacak?", + "zen.faq.a5.beforeExceptions": + "Tüm Zen modelleri ABD'de barındırılır. Sağlayıcılar sıfır-retention politikasını uygular ve verilerinizi model eğitimi için kullanmaz; şu", + "zen.faq.a5.exceptionsLink": "istisnalarla", + "zen.faq.q6": "Harcama limitleri ayarlayabilir miyim?", + "zen.faq.a6": "Evet, hesabınızda aylık harcama limitleri ayarlayabilirsiniz.", + "zen.faq.q7": "İptal edebilir miyim?", + "zen.faq.a7": + "Evet, istediğiniz zaman faturalandırmayı devre dışı bırakabilir ve kalan bakiyenizi kullanabilirsiniz.", + "zen.faq.q8": "Zen'i diğer kodlama ajanlarıyla kullanabilir miyim?", + "zen.faq.a8": + "Zen OpenCode ile harika çalışır, ama Zen'i herhangi bir ajan ile kullanabilirsiniz. Tercih ettiğiniz kodlama ajanında kurulum talimatlarını izleyin.", + "zen.faq.q9": "Para iadesi alabilir miyim?", + "zen.faq.a9": + "Ücret son 14 gün içinde tahsil edildiyse ve bu satın alımdan gelen kredilerin hiçbirini kullanmadıysanız para iadesine hak kazanabilirsiniz. {{contact}} ve para iadesi talep edin.", + + "zen.cta.start": "Zen'i kullanmaya başlayın", + "zen.pricing.title": "20$ Kullandıkça öde bakiyesi ekle", + "zen.pricing.fee": "(+1,23$ kart işlem ücreti)", + "zen.pricing.body": + "Herhangi bir ajan ile kullanın. Aylık harcama limitlerini belirleyin. İstediğiniz zaman iptal edin.", + "zen.problem.title": "Zen hangi sorunu çözüyor?", + "zen.problem.body": + "Pek çok model mevcut ancak yalnızca birkaçı kodlama ajanlarıyla iyi çalışıyor. Çoğu sağlayıcı, bunları değişen sonuçlarla farklı şekilde yapılandırır.", + "zen.problem.subtitle": "Bu sorunu yalnızca OpenCode kullanıcıları için değil, herkes için düzeltiyoruz.", + "zen.problem.item1": "Seçilen modelleri test etme ve ekiplerine danışmanlık yapma", + "zen.problem.item2": "Düzgün bir şekilde teslim edildiklerinden emin olmak için sağlayıcılarla çalışmak", + "zen.problem.item3": "Önerdiğimiz tüm model-sağlayıcı kombinasyonlarının karşılaştırılması", + "zen.how.title": "Zen nasıl çalışır?", + "zen.how.body": "Zen'i OpenCode ile kullanmanızı önersek de, Zen'i herhangi bir ajan ile kullanabilirsiniz.", + "zen.how.step1.title": "Kaydolun ve 20$ bakiye ekleyin", + "zen.how.step1.beforeLink": "takip edin", + "zen.how.step1.link": "kurulum talimatları", + "zen.how.step2.title": "Şeffaf fiyatlandırmayla Zen kullanın", + "zen.how.step2.link": "istek başına ödeme", + "zen.how.step2.afterLink": "sıfır işaretlemeyle", + "zen.how.step3.title": "Otomatik yükleme", + "zen.how.step3.body": "bakiyeniz 5$'a ulaştığında otomatik olarak 20$ ekleyeceğiz", + "zen.privacy.title": "Gizliliğiniz bizim için önemlidir", + "zen.privacy.beforeExceptions": + "Tüm Zen modelleri ABD'de barındırılmaktadır. Sağlayıcılar sıfır saklama politikası izler ve verilerinizi model eğitimi için kullanmaz; şu", + "zen.privacy.exceptionsLink": "aşağıdaki istisnalar", + + "go.title": "OpenCode Go | Herkes için düşük maliyetli kodlama modelleri", + "go.meta.description": + "Go ayda 10$'dır; cömert kullanım limitleri ve önde gelen kodlama modellerine güvenilir erişim sunar.", + "go.hero.title": "Herkes için düşük maliyetli kodlama modelleri", + "go.hero.body": + "Go, dünya çapındaki programcılara ajan tabanlı kodlama getiriyor. En yetenekli açık kaynaklı modellere cömert limitler ve güvenilir erişim sunarak, maliyet veya erişilebilirlik konusunda endişelenmeden güçlü ajanlarla geliştirme yapmanızı sağlar.", + + "go.cta.start": "Go'ya abone ol", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Go'ya abone ol", + "go.cta.price": "Ayda 10$", + "go.pricing.body": "Herhangi bir ajanla kullanın. Ayda 10$. Gerekirse kredi yükleyin. İstediğiniz zaman iptal edin.", + "go.graph.free": "Ücretsiz", + "go.graph.freePill": "Big Pickle ve ücretsiz modeller", + "go.graph.go": "Go", + "go.graph.label": "5 saat başına istekler", + "go.graph.period": "Kullanım", + "go.graph.model": "Model", + "go.graph.requests": "Tahmini istek / 5 saat", + "go.graph.allowance": "Aylık kullanım", + "go.graph.new": "Yeni", + "go.graph.scale": "Doğrusal olmayan istek ölçeği", + "go.graph.showAll": "{{count}} modelin tümünü göster", + "go.graph.showLess": "Daha az model göster", + "go.graph.limitedRegions": "sınırlı bölgeler", + "go.graph.limitedTime": "sınırlı süre", + "go.graph.usageLimits": "Kullanım limitleri", + "go.graph.aria": "5 saatlik istekler: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "Eski CEO, Terminal Ürünleri", + "go.testimonials.dax.quoteAfter": "hayat değiştirdi, gerçekten düşünmeye bile gerek yok.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "Eski Kurucu, SEED, PM, Melt, Pop, Dapt, Cadmus ve ViewPoint", + "go.testimonials.jay.quoteBefore": "Ekibimizdeki 5 kişiden 4'ü", + "go.testimonials.jay.quoteAfter": "kullanmayı seviyor.", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "Eski Hero, AWS", + "go.testimonials.adam.quoteBefore": "", + "go.testimonials.adam.quoteAfter": "için tavsiyem sonsuz. Cidden, gerçekten çok iyi.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "Eski Tasarım Başkanı, Laravel", + "go.testimonials.david.quoteBefore": "", + "go.testimonials.david.quoteAfter": + " ile modellerin test edildiğini ve kodlama ajanları için mükemmel olduğunu biliyorum.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "Eski Stajyer, Nvidia (4 kez)", + "go.testimonials.frank.quote": "Keşke hala Nvidia'da olsaydım.", + "go.problem.title": "Go hangi sorunu çözüyor?", + "go.problem.body": + "OpenCode deneyimini mümkün olduğunca çok kişiye ulaştırmaya odaklandık. OpenCode Go, ayda 10$ olan düşük maliyetli bir aboneliktir. Cömert limitler ve en yetenekli açık kaynak modellere güvenilir erişim sağlar.", + "go.problem.subtitle": " ", + "go.problem.item1": "Düşük maliyetli abonelik fiyatlandırması", + "go.problem.item2": "Cömert limitler ve güvenilir erişim", + "go.problem.item3": "Mümkün olduğunca çok programcı için geliştirildi", + "go.problem.item4": "Ajan tabanlı kodlama için test edilmiş, özenle seçilmiş model seçenekleri", + "go.how.title": "Go nasıl çalışır?", + "go.how.body": "Go ayda 10$'dır. OpenCode veya herhangi bir ajanla kullanabilirsiniz.", + "go.how.step1.title": "Bir hesap oluşturun", + "go.how.step1.beforeLink": "takip edin", + "go.how.step1.link": "kurulum talimatları", + "go.how.step2.title": "Go'ya abone olun", + "go.how.step2.link": "Ayda 10$", + "go.how.step2.afterLink": "cömert limitlerle", + "go.how.step3.title": "Kodlamaya başlayın", + "go.how.step3.body": "açık kaynaklı modellere güvenilir erişimle", + "go.privacy.title": "Gizliliğiniz bizim için önemlidir", + "go.privacy.body": + "Bu plan öncelikle uluslararası kullanıcılar için tasarlanmış olup, istikrarlı küresel erişim için modeller ABD, AB ve Singapur'da barındırılmaktadır.", + "go.privacy.contactAfter": "herhangi bir sorunuz varsa.", + "go.privacy.beforeExceptions": + "Go modelleri ABD'de barındırılmaktadır. Sağlayıcılar sıfır saklama politikası izler ve verilerinizi model eğitimi için kullanmaz; şu", + "go.privacy.exceptionsLink": "aşağıdaki istisnalar", + "go.faq.q1": "OpenCode Go nedir?", + "go.faq.a1": + "Go, ajan tabanlı kodlama için yetenekli açık kaynaklı modellere güvenilir erişim sağlayan düşük maliyetli bir aboneliktir.", + "go.faq.q2": "Go hangi modelleri içerir?", + "go.faq.a2": "Go, aşağıda listelenen modelleri cömert limitler ve güvenilir erişimle sunar.", + "go.faq.q3": "Go, Zen ile aynı mı?", + "go.faq.a3": + "Hayır. Zen kullandıkça öde modelidir; Go ise ayda 10$'dır ve özenle seçilmiş model seçeneklerine cömert limitlerle güvenilir erişim sunar.", + "go.faq.q4": "Go ne kadar?", + "go.faq.a4.p1.beforePricing": "Go'nun maliyeti", + "go.faq.a4.p1.pricingLink": "ayda 10$", + "go.faq.a4.p1.afterPricing": "cömert limitlerle.", + "go.faq.a4.p2.beforeAccount": "Aboneliğinizi", + "go.faq.a4.p2.accountLink": "hesabınızdan", + "go.faq.a4.p3": "yönetebilirsiniz. İstediğiniz zaman iptal edin.", + "go.faq.q5": "Veri ve gizlilik ne olacak?", + "go.faq.a5.model": "Model", + "go.faq.a5.training": "Model eğitimi", + "go.faq.a5.retention": "Veri saklama", + "go.faq.a5.retention30": "30 gün", + "go.faq.a5.retention0": "0 gün", + "go.faq.a5.used": "Kullanılır", + "go.faq.a5.notUsed": "Kullanılmaz", + "go.faq.a5.noAgreement": "Anlaşma yok", + "go.faq.a5.notZdr": "ZDR değil", + "go.faq.a5.grokRetention": + "ZDR, durum bilgisi tutan Responses API, Files and Collections ve Batch API dahil olmak üzere saklanan verilere bağlı önemli API özelliklerini devre dışı bırakır.", + "go.faq.a5.gptRetention": + "Tüm API özelliklerinin kullanımı için kötüye kullanım izleme günlükleri oluşturulur ve 30 güne kadar saklanır.", + "go.faq.a5.learnMore": "Daha fazla bilgi", + "go.faq.a5.deepseekRetention": + "ZDR anlaşması aylık olarak yenilenir. Mevcut anlaşma 30 Eylül 2026 tarihine kadar geçerlidir.", + "go.faq.a5.museRetention": + "İstemlerinizi ve tamamlamalarınızı gelecekteki Meta modellerini eğitmek için kullanma izni karşılığında büyük ölçüde indirimli token fiyatları.", + + "go.faq.a5.beforeExceptions": + "Go modelleri ABD'de barındırılmaktadır. Sağlayıcılar sıfır saklama politikası izler ve verilerinizi model eğitimi için kullanmaz; şu", + "go.faq.a5.exceptionsLink": "aşağıdaki istisnalar", + "go.faq.q6": "Kredi yükleyebilir miyim?", + "go.faq.a6": "Daha fazla kullanıma ihtiyacınız varsa, hesabınıza kredi yükleyebilirsiniz.", + "go.faq.q7": "İptal edebilir miyim?", + "go.faq.a7": "Evet, istediğiniz zaman iptal edebilirsiniz.", + "go.faq.q8": "Go'yu diğer kodlama ajanlarıyla kullanabilir miyim?", + "go.faq.a8": + "Evet, Go'yu herhangi bir ajanla kullanabilirsiniz. Tercih ettiğiniz kodlama ajanındaki kurulum talimatlarını izleyin.", + + "go.faq.q9": "Ücretsiz modeller ve Go arasındaki fark nedir?", + "go.faq.a9": + "Ücretsiz modeller, günlük 200 istek kotasıyla Big Pickle'ı ve o sırada mevcut olan promosyonel modelleri içerir. Go ise kayan zaman aralıklarında (5 saatlik, haftalık ve aylık) uygulanan daha yüksek istek kotalarıyla özenle seçilmiş model seçenekleri sunar. Bu kotalar kabaca her 5 saatte 12$, haftada 30$ ve ayda 60$ değerindeki temel kullanım haklarına eşdeğerdir; modele özgü kullanım hakları farklılık gösterebilir (gerçek istek sayıları modele ve kullanıma göre değişir).", + "go.faq.q10": "Para iadesi alabilir miyim?", + "go.faq.a10": + "Ücret son 14 gün içinde tahsil edildiyse ve ilgili faturalandırma döneminde Go kullanım hakkınızı hiç kullanmadıysanız para iadesine hak kazanabilirsiniz. {{contact}} ve para iadesi talep edin.", + + "zen.api.error.rateLimitExceeded": "İstek limiti aşıldı. Lütfen daha sonra tekrar deneyin.", + "zen.api.error.modelNotSupported": "{{model}} modeli desteklenmiyor", + "zen.api.error.modelFormatNotSupported": "{{model}} modeli {{format}} formatı için desteklenmiyor", + "zen.api.error.noProviderAvailable": "Kullanılabilir sağlayıcı yok", + "zen.api.error.providerNotSupported": "{{provider}} sağlayıcısı desteklenmiyor", + "zen.api.error.missingApiKey": "API anahtarı eksik.", + "zen.api.error.invalidApiKey": "Geçersiz API anahtarı.", + "zen.api.error.requestBlockedByUpstreamProvider": "İstek üst sağlayıcı tarafından engellendi.", + "zen.api.error.subscriptionQuotaExceeded": "Abonelik kotası aşıldı. {{retryIn}} içinde tekrar deneyin.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "5 saatlik kullanım limitine ulaşıldı. {{retryIn}} içinde sıfırlanır. Bu modeli şimdi kullanmaya devam etmek için kullanılabilir bakiyenizden kullanımı etkinleştirin: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Haftalık kullanım limitine ulaşıldı. {{retryIn}} içinde sıfırlanır. Bu modeli şimdi kullanmaya devam etmek için kullanılabilir bakiyenizden kullanımı etkinleştirin: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Aylık kullanım limitine ulaşıldı. {{retryIn}} içinde sıfırlanır. Bu modeli şimdi kullanmaya devam etmek için kullanılabilir bakiyenizden kullanımı etkinleştirin: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Ödeme yöntemi bulunamadı. Buradan bir ödeme yöntemi ekleyin: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Yetersiz bakiye. Faturalandırmanızı buradan yönetin: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Çalışma alanınız aylık ${{amount}} harcama limitine ulaştı. Limitlerinizi buradan yönetin: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Aylık ${{amount}} harcama limitinize ulaştınız. Limitlerinizi buradan yönetin: {{membersUrl}}", + "zen.api.error.modelDisabled": "Model devre dışı", + "zen.api.error.regionNotAllowed": + "Bu modelin en son sürümü yalnızca Çin'de barındırılıyor ve kullanabilmek için açıkça onay vermeniz gerekiyor: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Bu model ülkenizde kullanılamıyor.", + "zen.api.error.trainingNotAllowed": + "Bu model, kalitesini artırmak için kullanılan verileri toplar. Modeli kullanabilmek için açıkça onay vermeniz gerekir: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "{{model}} için ücretsiz promosyon sona erdi. OpenCode Go'ya abone olarak modeli kullanmaya devam edebilirsiniz - {{link}}", + + "black.meta.title": "OpenCode Black | Dünyanın en iyi kodlama modellerine erişin", + "black.meta.description": "OpenCode Black abonelik planlarıyla Claude, GPT, Gemini ve daha fazlasına erişin.", + "black.hero.title": "Dünyanın en iyi kodlama modellerine erişin", + "black.hero.subtitle": "Claude, GPT, Gemini ve daha fazlası dahil", + "black.title": "OpenCode Black | Fiyatlandırma", + "black.paused": "Black plan kaydı geçici olarak duraklatıldı.", + "black.plan.icon20": "Black 20 planı", + "black.plan.icon100": "Black 100 planı", + "black.plan.icon200": "Black 200 planı", + "black.plan.multiplier100": "Black 20'den 5 kat daha fazla kullanım", + "black.plan.multiplier200": "Black 20'den 20 kat daha fazla kullanım", + "black.price.perMonth": "aylık", + "black.price.perPersonBilledMonthly": "kişi başı aylık faturalandırılır", + "black.terms.1": "Aboneliğiniz hemen başlamayacak", + "black.terms.2": "Bekleme listesine ekleneceksiniz ve yakında aktive edileceksiniz", + "black.terms.3": "Kartınızdan sadece aboneliğiniz aktive edildiğinde ödeme alınacaktır", + "black.terms.4": "Kullanım limitleri geçerlidir, yoğun otomatik kullanım limitlere daha erken ulaşabilir", + "black.terms.5": "Abonelikler bireyler içindir, ekipler için Enterprise ile iletişime geçin", + "black.terms.6": "Limitler ayarlanabilir ve planlar gelecekte sonlandırılabilir", + "black.terms.7": "Aboneliğinizi istediğiniz zaman iptal edin", + "black.action.continue": "Devam et", + "black.finePrint.beforeTerms": "Gösterilen fiyatlara geçerli vergiler dahil değildir", + "black.finePrint.terms": "Hizmet Şartları", + "black.workspace.title": "OpenCode Black | Çalışma Alanı Seç", + "black.workspace.selectPlan": "Bu plan için bir çalışma alanı seçin", + "black.workspace.name": "Çalışma Alanı {{n}}", + "black.subscribe.title": "OpenCode Black'e Abone Ol", + "black.subscribe.paymentMethod": "Ödeme yöntemi", + "black.subscribe.loadingPaymentForm": "Ödeme formu yükleniyor...", + "black.subscribe.selectWorkspaceToContinue": "Devam etmek için bir çalışma alanı seçin", + "black.subscribe.failurePrefix": "Olamaz!", + "black.subscribe.error.generic": "Bir hata oluştu", + "black.subscribe.error.invalidPlan": "Geçersiz plan", + "black.subscribe.error.workspaceRequired": "Çalışma alanı ID'si gerekli", + "black.subscribe.error.alreadySubscribed": "Bu çalışma alanının zaten bir aboneliği var", + "black.subscribe.processing": "İşleniyor...", + "black.subscribe.submit": "${{plan}} Abone Ol", + "black.subscribe.form.chargeNotice": "Sadece aboneliğiniz aktive edildiğinde ücretlendirileceksiniz", + "black.subscribe.success.title": "OpenCode Black bekleme listesindesiniz", + "black.subscribe.success.subscriptionPlan": "Abonelik planı", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Tutar", + "black.subscribe.success.amountValue": "Aylık ${{plan}}", + "black.subscribe.success.paymentMethod": "Ödeme yöntemi", + "black.subscribe.success.dateJoined": "Katılma tarihi", + "black.subscribe.success.chargeNotice": "Aboneliğiniz aktive edildiğinde kartınızdan ödeme alınacaktır", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Kullanım", + "workspace.nav.apiKeys": "API Anahtarları", + "workspace.nav.members": "Üyeler", + "workspace.nav.billing": "Faturalandırma", + "workspace.nav.settings": "Ayarlar", + + "workspace.home.banner.beforeLink": "Kodlama ajanları için güvenilir optimize edilmiş modeller.", + "workspace.lite.banner.beforeLink": "Herkes için düşük maliyetli kodlama modelleri.", + "workspace.home.billing.loading": "Yükleniyor...", + "workspace.home.billing.enable": "Faturalandırmayı etkinleştir", + "workspace.home.billing.currentBalance": "Mevcut bakiye", + + "workspace.newUser.feature.tested.title": "Test Edilmiş ve Doğrulanmış Modeller", + "workspace.newUser.feature.tested.body": + "En iyi performansı sağlamak için modelleri özellikle kodlama ajanlarına yönelik olarak karşılaştırdık ve test ettik.", + "workspace.newUser.feature.quality.title": "En Yüksek Kalite", + "workspace.newUser.feature.quality.body": + "Optimum performans için yapılandırılmış modellere erişin; sürüm düşürme veya daha ucuz sağlayıcılara yönlendirme yok.", + "workspace.newUser.feature.lockin.title": "Kilitlenme Yok", + "workspace.newUser.feature.lockin.body": + "Zen'i herhangi bir kodlama ajanıyla kullanın ve istediğiniz zaman opencode ile diğer sağlayıcıları kullanmaya devam edin.", + "workspace.newUser.copyApiKey": "API anahtarını kopyala", + "workspace.newUser.copyKey": "Anahtarı Kopyala", + "workspace.newUser.copied": "Kopyalandı!", + "workspace.newUser.step.enableBilling": "Faturalandırmayı etkinleştir", + "workspace.newUser.step.login.before": "Çalıştır", + "workspace.newUser.step.login.after": "ve opencode seçeneğini seçin", + "workspace.newUser.step.pasteKey": "API anahtarınızı yapıştırın", + "workspace.newUser.step.models.before": "opencode'u başlatın ve çalıştırın", + "workspace.newUser.step.models.after": "bir model seçmek için", + + "workspace.models.title": "Modeller", + "workspace.models.subtitle.beforeLink": "Çalışma alanı üyelerinin hangi modellere erişebileceğini yönetin.", + "workspace.models.table.model": "Model", + "workspace.models.table.enabled": "Etkin", + + "workspace.providers.title": "Kendi Anahtarınızı Getirin", + "workspace.providers.subtitle": "Yapay zeka sağlayıcılarından kendi API anahtarlarınızı yapılandırın.", + "workspace.providers.placeholder": "{{provider}} API anahtarını girin ({{prefix}}...)", + "workspace.providers.configure": "Yapılandır", + "workspace.providers.edit": "Düzenle", + "workspace.providers.delete": "Sil", + "workspace.providers.saving": "Kaydediliyor...", + "workspace.providers.save": "Kaydet", + "workspace.providers.table.provider": "Sağlayıcı", + "workspace.providers.table.apiKey": "API Anahtarı", + + "workspace.usage.title": "Kullanım Geçmişi", + "workspace.usage.subtitle": "Son API kullanımı ve maliyetleri.", + "workspace.usage.empty": "Başlamak için ilk API çağrınızı yapın.", + "workspace.usage.table.date": "Tarih", + "workspace.usage.table.model": "Model", + "workspace.usage.table.input": "Giriş", + "workspace.usage.table.output": "Çıkış", + "workspace.usage.table.cost": "Maliyet", + "workspace.usage.table.session": "Oturum", + "workspace.usage.breakdown.input": "Giriş", + "workspace.usage.breakdown.cacheRead": "Önbellek Okuması", + "workspace.usage.breakdown.cacheWrite": "Önbellek Yazma", + "workspace.usage.breakdown.output": "Çıkış", + "workspace.usage.breakdown.reasoning": "Muhakeme", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Maliyet", + "workspace.cost.subtitle": "Modele göre ayrılmış kullanım maliyetleri.", + "workspace.cost.allModels": "Tüm Modeller", + "workspace.cost.allKeys": "Tüm Anahtarlar", + "workspace.cost.deletedSuffix": "(silindi)", + "workspace.cost.empty": "Seçilen döneme ait kullanım verisi yok.", + "workspace.cost.subscriptionShort": "abonelik", + + "workspace.keys.title": "API Anahtarları", + "workspace.keys.subtitle": "opencode hizmetlerine erişim için API anahtarlarınızı yönetin.", + "workspace.keys.create": "API Anahtarı Oluştur", + "workspace.keys.placeholder": "Anahtar adını girin", + "workspace.keys.empty": "Bir opencode Gateway API anahtarı oluşturun", + "workspace.keys.table.name": "İsim", + "workspace.keys.table.key": "Anahtar", + "workspace.keys.table.createdBy": "Oluşturan", + "workspace.keys.table.lastUsed": "Son Kullanılan", + "workspace.keys.copyApiKey": "API anahtarını kopyala", + "workspace.keys.delete": "Sil", + + "workspace.members.title": "Üyeler", + "workspace.members.subtitle": "Çalışma alanı üyelerini ve izinlerini yönetin.", + "workspace.members.invite": "Üyeyi Davet Et", + "workspace.members.inviting": "Davet ediliyor...", + "workspace.members.beta.beforeLink": "Beta süresince çalışma alanları ekipler için ücretsizdir.", + "workspace.members.form.invitee": "Davetli", + "workspace.members.form.emailPlaceholder": "E-posta girin", + "workspace.members.form.role": "Rol", + "workspace.members.form.monthlyLimit": "Aylık harcama limiti", + "workspace.members.noLimit": "Limit yok", + "workspace.members.noLimitLowercase": "limit yok", + "workspace.members.invited": "davet edildi", + "workspace.members.edit": "Düzenle", + "workspace.members.delete": "Sil", + "workspace.members.saving": "Kaydediliyor...", + "workspace.members.save": "Kaydet", + "workspace.members.table.email": "E-posta", + "workspace.members.table.role": "Rol", + "workspace.members.table.monthLimit": "Ay limiti", + "workspace.members.role.admin": "Yönetici", + "workspace.members.role.adminDescription": "Modelleri, üyeleri ve faturalamayı yönetebilir", + "workspace.members.role.member": "Üye", + "workspace.members.role.memberDescription": "Yalnızca kendileri için API anahtarları oluşturabilirler", + + "workspace.settings.title": "Ayarlar", + "workspace.settings.subtitle": "Çalışma alanı adınızı ve tercihlerinizi güncelleyin.", + "workspace.settings.workspaceName": "Çalışma alanı adı", + "workspace.settings.defaultName": "Varsayılan", + "workspace.settings.updating": "Güncelleniyor...", + "workspace.settings.save": "Kaydet", + "workspace.settings.edit": "Düzenle", + + "workspace.billing.title": "Faturalandırma", + "workspace.billing.subtitle.beforeLink": "Ödeme yöntemlerini yönetin.", + "workspace.billing.contactUs": "Bize Ulaşın", + "workspace.billing.subtitle.afterLink": "herhangi bir sorunuz varsa.", + "workspace.billing.currentBalance": "Güncel Bakiye", + "workspace.billing.add": "$ ekle", + "workspace.billing.enterAmount": "Tutarı girin", + "workspace.billing.loading": "Yükleniyor...", + "workspace.billing.addAction": "Ekle", + "workspace.billing.addBalance": "Bakiye Ekle", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Stripe'a bağlı", + "workspace.billing.manage": "Yönet", + "workspace.billing.enable": "Faturalandırmayı Etkinleştir", + + "workspace.monthlyLimit.title": "Aylık Limit", + "workspace.monthlyLimit.subtitle": "Hesabınız için aylık kullanım limiti belirleyin.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Ayarlanıyor...", + "workspace.monthlyLimit.set": "Ayarla", + "workspace.monthlyLimit.edit": "Limiti Düzenle", + "workspace.monthlyLimit.noLimit": "Kullanım limiti belirlenmedi.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Şu anki kullanım", + "workspace.monthlyLimit.currentUsage.beforeAmount": "$", + + "workspace.redeem.title": "Kupon Kullan", + "workspace.redeem.subtitle": "Kredi veya avantajlardan yararlanmak için bir kupon kodu kullanın.", + "workspace.redeem.placeholder": "Kupon kodunu girin", + "workspace.redeem.redeem": "Kullan", + "workspace.redeem.redeeming": "Kullanılıyor...", + "workspace.redeem.success": "Kupon başarıyla kullanıldı.", + + "workspace.reload.title": "Otomatik Yeniden Yükleme", + "workspace.reload.disabled.before": "Otomatik yeniden yükleme:", + "workspace.reload.disabled.state": "devre dışı", + "workspace.reload.disabled.after": "Bakiye azaldığında otomatik olarak yeniden yüklemeyi etkinleştirin.", + "workspace.reload.enabled.before": "Otomatik yeniden yükleme:", + "workspace.reload.enabled.state": "etkin", + "workspace.reload.enabled.middle": "Yeniden yükleyeceğiz", + "workspace.reload.processingFee": "işlem ücreti", + "workspace.reload.enabled.after": "dengeye ulaşıldığında", + "workspace.reload.edit": "Düzenle", + "workspace.reload.enable": "Etkinleştir", + "workspace.reload.enableAutoReload": "Otomatik Yeniden Yüklemeyi Etkinleştir", + "workspace.reload.reloadAmount": "Yükle $", + "workspace.reload.whenBalanceReaches": "Bakiye $ seviyesine ulaştığında", + "workspace.reload.saving": "Kaydediliyor...", + "workspace.reload.save": "Kaydet", + "workspace.reload.failedAt": "Yeniden yükleme başarısız oldu:", + "workspace.reload.reason": "Sebep:", + "workspace.reload.updatePaymentMethod": "Lütfen ödeme yönteminizi güncelleyin ve tekrar deneyin.", + "workspace.reload.retrying": "Yeniden deneniyor...", + "workspace.reload.retry": "Yeniden dene", + "workspace.reload.error.paymentFailed": "Ödeme başarısız.", + + "workspace.payments.title": "Ödeme Geçmişi", + "workspace.payments.subtitle": "Son ödeme işlemleri.", + "workspace.payments.table.date": "Tarih", + "workspace.payments.table.paymentId": "Ödeme Kimliği", + "workspace.payments.table.amount": "Tutar", + "workspace.payments.table.receipt": "Makbuz", + "workspace.payments.type.credit": "kredi", + "workspace.payments.type.subscription": "abonelik", + "workspace.payments.view": "Görüntüle", + + "workspace.black.loading": "Yükleniyor...", + "workspace.black.time.day": "gün", + "workspace.black.time.days": "gün", + "workspace.black.time.hour": "saat", + "workspace.black.time.hours": "saat", + "workspace.black.time.minute": "dakika", + "workspace.black.time.minutes": "dakika", + "workspace.black.time.fewSeconds": "birkaç saniye", + "workspace.black.subscription.title": "Abonelik", + "workspace.black.subscription.message": "Aylık ${{plan}} karşılığında OpenCode Black'e abonesiniz.", + "workspace.black.subscription.manage": "Aboneliği Yönet", + "workspace.black.subscription.rollingUsage": "5 Saatlik Kullanım", + "workspace.black.subscription.weeklyUsage": "Haftalık Kullanım", + "workspace.black.subscription.resetsIn": "Sıfırlama süresi", + "workspace.black.subscription.useBalance": "Kullanım limitlerine ulaştıktan sonra mevcut bakiyenizi kullanın", + "workspace.black.waitlist.title": "Bekleme listesi", + "workspace.black.waitlist.joined": "Aylık ${{plan}} OpenCode Black planı için bekleme listesindesiniz.", + "workspace.black.waitlist.ready": "Sizi ayda {{plan}} $ tutarındaki OpenCode Black planına kaydetmeye hazırız.", + "workspace.black.waitlist.leave": "Bekleme Listesinden Ayrıl", + "workspace.black.waitlist.leaving": "Ayrılıyor...", + "workspace.black.waitlist.left": "Ayrıldı", + "workspace.black.waitlist.enroll": "Kayıt ol", + "workspace.black.waitlist.enrolling": "Kaydediliyor...", + "workspace.black.waitlist.enrolled": "Kayıtlı", + "workspace.black.waitlist.enrollNote": + "Kayıt Ol'a tıkladığınızda aboneliğiniz hemen başlar ve kartınızdan çekim yapılır.", + + "workspace.lite.loading": "Yükleniyor...", + "workspace.lite.time.day": "gün", + "workspace.lite.time.days": "gün", + "workspace.lite.time.hour": "saat", + "workspace.lite.time.hours": "saat", + "workspace.lite.time.minute": "dakika", + "workspace.lite.time.minutes": "dakika", + "workspace.lite.time.fewSeconds": "birkaç saniye", + "workspace.lite.subscription.message": "OpenCode Go abonesisiniz.", + "workspace.lite.subscription.manage": "Aboneliği Yönet", + "workspace.lite.subscription.rollingUsage": "5 Saatlik Kullanım", + "workspace.lite.subscription.rollingQuota": "5 Saatlik Kota", + "workspace.lite.subscription.weeklyUsage": "Haftalık Kullanım", + "workspace.lite.subscription.weeklyQuota": "Haftalık Kota", + "workspace.lite.subscription.monthlyUsage": "Aylık Kullanım", + "workspace.lite.subscription.monthlyQuota": "Aylık Kota", + "workspace.lite.subscription.resetsIn": "Sıfırlama süresi", + "workspace.lite.subscription.showDetails": "Ayrıntıları göster", + "workspace.lite.subscription.hideDetails": "Ayrıntıları gizle", + "workspace.lite.subscription.model": "Model", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Toplam", + "workspace.lite.subscription.useBalance": "Kullanım limitlerine ulaştıktan sonra mevcut bakiyenizi kullanın", + "workspace.lite.subscription.selectProvider": + 'Go modellerini kullanmak için opencode yapılandırmanızda "OpenCode Go"\'yu sağlayıcı olarak seçin.', + "workspace.lite.providers.title": "Sağlayıcılar", + "workspace.lite.providers.description": "Yönlendirme için hangi sağlayıcıların kullanılacağını kontrol edin.", + "workspace.lite.providers.allowTraining": "İstek verileriyle eğitilen modellere izin ver", + "workspace.lite.providers.useChina": "Çin'de barındırılan modelleri etkinleştir", + "workspace.lite.black.message": + "Şu anda OpenCode Black abonesisiniz veya bekleme listesindesiniz. Go'ya geçmek istiyorsanız lütfen önce aboneliğinizi iptal edin.", + "workspace.lite.other.message": + "Bu çalışma alanındaki başka bir üye zaten OpenCode Go abonesi. Çalışma alanı başına yalnızca bir üye abone olabilir.", + "workspace.lite.promo.description": + "OpenCode Go {{price}} fiyatıyla cömert kullanım limitleri ve popüler açık kodlama modellerine güvenilir erişim sağlar.", + "workspace.lite.promo.price": "Ayda 10$", + "workspace.lite.promo.modelsTitle": "Neler Dahil", + "workspace.lite.promo.footer": + "Plan öncelikle uluslararası kullanıcılar için tasarlanmıştır ve istikrarlı küresel erişim sağlar. Erken kullanım ve geri bildirimlerden öğrendiklerimiz doğrultusunda fiyatlandırma ve kullanım limitleri değişebilir.", + "workspace.lite.promo.subscribe": "Go'ya Abone Ol", + "workspace.lite.promo.subscribing": "Yönlendiriliyor...", + "workspace.lite.promo.otherMethods": "Diğer ödeme yöntemleri", + "workspace.lite.promo.selectMethod": "Ödeme yöntemini seçin", + + "workspace.referral.copyLink": "Bağlantıyı Kopyala", + "workspace.referral.copied": "Kopyalandı", + "workspace.referral.overview.title": "Arkadaşlarını davet et", + "workspace.referral.overview.subtitle": "Bir arkadaşın abone olduğunda $5 kazan. O da $5 alacak.", + "workspace.referral.instructions.share": "Referans bağlantını paylaş", + "workspace.referral.instructions.subscribe": "Arkadaşın katılır ve Go'ya abone olur", + "workspace.referral.instructions.claim": + "İkiniz de Go kullanım limitlerinize uygulamak için $5 kullanım kredisi alırsınız", + "workspace.referral.rewards.title": "Davet ödülleri", + "workspace.referral.rewards.description": "Mevcut davet kredilerini Go kullanımınıza uygulayın.", + "workspace.referral.rewards.subtitle": "{{applied}} / {{total}} ödül kullanıldı.", + "workspace.referral.rewards.empty": "Henüz davet ödülü yok.", + "workspace.referral.table.reward": "Ödül", + "workspace.referral.table.referral": "Açıklama", + "workspace.referral.table.date": "Tarih", + "workspace.referral.reward.description.inviter": "{{email}} davet edildi", + "workspace.referral.reward.description.invitee": "{{email}} tarafından davet edildi", + "workspace.referral.reward.action.subscribeUnlock": "Kilidi açmak için abone ol", + "workspace.referral.reward.action.view": "Ödülü Görüntüle", + "workspace.referral.reward.action.applied": "Ödül Kullanıldı", + "workspace.referral.reward.source.pendingInviter": "Abone olması bekleniyor", + "workspace.referral.reward.source.pendingInvitee": "Ödülün kilidini açmak için abone ol", + "workspace.referral.reward.source.available": "Ödül kullanıma hazır", + "workspace.referral.reward.source.applied": "Ödül kullanıldı", + "workspace.referral.reward.status.applied": "Ödül Kullanıldı", + "workspace.referral.reward.status.pendingInviter": "Kilidi açmak için abone ol", + "workspace.referral.reward.status.pendingInvitee": "Kilidi açmak için abone ol", + "workspace.referral.apply.noGo": "Kilidi açmak için abone ol", + "workspace.referral.apply.preview": "Ödülü Görüntüle", + "workspace.referral.apply.action": "Kullan", + "workspace.referral.apply.confirmTitle": "Ödülü kullan", + "workspace.referral.apply.confirmBody": "Bu workspace'in mevcut kullanımını azaltmak için {{amount}} kullan.", + "workspace.referral.apply.confirmAction": "Kullan", + + "download.title": "OpenCode | İndir", + "download.meta.description": "OpenCode'u macOS, Windows ve Linux için indirin", + "download.hero.title": "OpenCode Desktop'u İndir", + "download.hero.subtitle": "macOS, Windows ve Linux için Beta olarak sunuluyor", + "download.hero.button": "{{os}} için indir", + "download.section.terminal": "OpenCode Terminal", + "download.section.desktop": "OpenCode Desktop", + "download.section.extensions": "OpenCode Eklentileri", + "download.section.integrations": "OpenCode Entegrasyonları", + "download.action.download": "İndir", + "download.action.install": "Kur", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Tam olarak değil, ama muhtemelen. OpenCode'u ücretli bir sağlayıcıya bağlamak istiyorsanız bir AI aboneliği gerekir, ancak", + "download.faq.a3.localLink": "yerel modeller", + "download.faq.a3.afterLocal.beforeZen": "ile ücretsiz çalışabilirsiniz. Kullanıcıları", + "download.faq.a3.afterZen": + " kullanmaya teşvik ediyoruz, ancak OpenCode OpenAI, Anthropic, xAI vb. gibi tüm popüler sağlayıcılarla çalışır.", + + "download.faq.a5.p1": "OpenCode %100 ücretsizdir.", + "download.faq.a5.p2.beforeZen": + "Ek maliyetler, bir model sağlayıcısına olan aboneliğinizden gelir. OpenCode herhangi bir model sağlayıcısıyla çalışır, ancak", + "download.faq.a5.p2.afterZen": " kullanmanızı öneririz.", + + "download.faq.a6.p1": + "Verileriniz ve bilginiz yalnızca OpenCode'da paylaşılabilir bağlantılar oluşturduğunuzda saklanır.", + "download.faq.a6.p2.beforeShare": "Daha fazla bilgi:", + "download.faq.a6.shareLink": "paylaşım sayfaları", + + "enterprise.title": "OpenCode | Kurumunuz için kurumsal çözümler", + "enterprise.meta.description": "Kurumsal çözümler için OpenCode ile iletişime geçin", + "enterprise.hero.title": "Kodunuz size aittir", + "enterprise.hero.body1": + "OpenCode, hiçbir veri veya bağlam saklamadan ve lisans kısıtlamaları ya da sahiplik iddiaları olmadan kuruluşunuzun içinde güvenli şekilde çalışır. Ekibinizle bir deneme başlatın, ardından SSO'nuz ve dahili AI geçidiniz ile entegre ederek tüm kuruluşunuzda devreye alın.", + "enterprise.hero.body2": "Nasıl yardımcı olabileceğimizi bize söyleyin.", + "enterprise.form.name.label": "Ad soyad", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "Rol", + "enterprise.form.role.placeholder": "Yönetim Kurulu Başkanı", + "enterprise.form.company.label": "Şirket", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Şirket e-postası", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Telefon numarası", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Hangi problemi çözmeye çalışıyorsunuz?", + "enterprise.form.message.placeholder": "Şu konuda yardıma ihtiyacımız var...", + "enterprise.form.send": "Gönder", + "enterprise.form.sending": "Gönderiliyor...", + "enterprise.form.success": "Mesaj gönderildi, yakında size dönüş yapacağız.", + "enterprise.form.success.submitted": "Form başarıyla gönderildi.", + "enterprise.form.error.allFieldsRequired": "Tüm alanlar gereklidir.", + "enterprise.form.error.invalidEmailFormat": "Geçersiz e-posta formatı.", + "enterprise.form.error.internalServer": "İç sunucu hatası.", + "enterprise.faq.title": "SSS", + "enterprise.faq.q1": "OpenCode Enterprise nedir?", + "enterprise.faq.a1": + "OpenCode Enterprise, kodunuzun ve verilerinizin asla altyapınızı terk etmemesini sağlamak isteyen kurumlar içindir. Bunu, SSO'nuz ve dahili AI geçidiniz ile entegre olan merkezileştirilmiş bir konfigürasyonla sağlar.", + "enterprise.faq.q2": "OpenCode Enterprise'a nasıl başlarım?", + "enterprise.faq.a2": + "Ekibinizle dahili bir deneme ile başlayın. OpenCode varsayılan olarak kodunuzu veya bağlam verilerinizi saklamaz, bu da başlamayı kolaylaştırır. Ardından fiyatlandırma ve uygulama seçeneklerini görüşmek için bize ulaşın.", + "enterprise.faq.q3": "Kurumsal fiyatlandırma nasıl çalışır?", + "enterprise.faq.a3": + "Kullanıcı başı (per-seat) kurumsal fiyatlandırma sunuyoruz. Kendi LLM geçidiniz varsa, kullanılan tokenlar için ücret almıyoruz. Daha fazla bilgi için, kurumunuzun ihtiyaçlarına göre özel bir teklif için bize ulaşın.", + "enterprise.faq.q4": "OpenCode Enterprise ile verilerim güvende mi?", + "enterprise.faq.a4": + "Evet. OpenCode kodunuzu veya bağlam verilerinizi saklamaz. Tüm işleme yerel olarak ya da AI sağlayıcınıza doğrudan API çağrıları ile gerçekleştirilir. Merkezileştirilmiş konfigürasyon ve SSO entegrasyonu ile verileriniz kurumunuzun altyapısı içinde güvende kalır.", + + "brand.title": "OpenCode | Marka", + "brand.meta.description": "OpenCode marka kılavuzu", + "brand.heading": "Marka kılavuzu", + "brand.subtitle": "OpenCode markası ile çalışmanıza yardımcı olacak kaynaklar ve varlıklar.", + "brand.downloadAll": "Tüm varlıkları indir", + + "changelog.title": "OpenCode | Değişiklik günlüğü", + "changelog.meta.description": "OpenCode sürüm notları ve değişiklik günlüğü", + "changelog.hero.title": "Değişiklik günlüğü", + "changelog.hero.subtitle": "OpenCode için yeni güncellemeler ve iyileştirmeler", + "changelog.empty": "Değişiklik günlüğü kaydı bulunamadı.", + "changelog.viewJson": "JSON'u görüntüle", + + "bench.list.title": "Benchmark", + "bench.list.heading": "Benchmarklar", + "bench.list.table.agent": "Ajan", + "bench.list.table.model": "Model", + "bench.list.table.score": "Puan", + "bench.submission.error.allFieldsRequired": "Tüm alanlar gereklidir.", + + "bench.detail.title": "Benchmark - {{task}}", + "bench.detail.notFound": "Görev bulunamadı", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "Ajan", + "bench.detail.labels.model": "Model", + "bench.detail.labels.task": "Görev", + "bench.detail.labels.repo": "Repo", + "bench.detail.labels.from": "Başlangıç", + "bench.detail.labels.to": "Bitiş", + "bench.detail.labels.prompt": "İstem", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "Ortalama Süre", + "bench.detail.labels.averageScore": "Ortalama Puan", + "bench.detail.labels.averageCost": "Ortalama Maliyet", + "bench.detail.labels.summary": "Özet", + "bench.detail.labels.runs": "Çalıştırmalar", + "bench.detail.labels.score": "Puan", + "bench.detail.labels.base": "Baz", + "bench.detail.labels.penalty": "Ceza", + "bench.detail.labels.weight": "ağırlık", + "bench.detail.table.run": "Çalıştırma", + "bench.detail.table.score": "Puan (Baz - Ceza)", + "bench.detail.table.cost": "Maliyet", + "bench.detail.table.duration": "Süre", + "bench.detail.run.title": "Çalıştırma {{n}}", + "bench.detail.rawJson": "Ham JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/uk.ts b/packages/console/app/src/i18n/uk.ts new file mode 100644 index 0000000000000000000000000000000000000000..4efac1d76762860f5e26cc5a60af0353fdf416ef --- /dev/null +++ b/packages/console/app/src/i18n/uk.ts @@ -0,0 +1,837 @@ +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash отримує 4x ліміти використання протягом обмеженого часу", + "go.graph.bonus": "Ліміт ×{{count}}", + "nav.github": "GitHub", + "nav.docs": "Документація", + "nav.changelog": "Журнал змін", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "Enterprise", + "nav.zen": "Zen", + "nav.login": "Увійти", + "nav.free": "Завантажити", + "nav.home": "Головна", + "nav.openMenu": "Відкрити меню", + "nav.getStartedFree": "Почати безкоштовно", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "Копіювати логотип як SVG", + "nav.context.copyWordmark": "Копіювати знак як SVG", + "nav.context.brandAssets": "Бренд-матеріали", + + "footer.github": "GitHub", + "footer.docs": "Документація", + "footer.changelog": "Журнал змін", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "Бренд", + "legal.privacy": "Конфіденційність", + "legal.terms": "Умови", + + "email.title": "Дізнайтеся першими про нові продукти", + "email.subtitle": "Приєднуйтесь до списку очікування для раннього доступу.", + "email.placeholder": "Електронна адреса", + "email.subscribe": "Підписатися", + "email.success": "Майже готово! Перевірте пошту та підтвердьте адресу", + + "notFound.title": "Не знайдено | opencode", + "notFound.heading": "404 — Сторінку не знайдено", + "notFound.home": "Головна", + "notFound.docs": "Документація", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "світлий логотип opencode", + "notFound.logoDarkAlt": "темний логотип opencode", + + "user.logout": "Вийти", + + "auth.callback.error.codeMissing": "Не знайдено код авторизації.", + + "workspace.select": "Виберіть робочий простір", + "workspace.createNew": "+ Створити новий робочий простір", + "workspace.modal.title": "Створити новий робочий простір", + "workspace.modal.placeholder": "Введіть назву робочого простору", + + "common.cancel": "Скасувати", + "common.creating": "Створення...", + "common.create": "Створити", + "common.contactUs": "Зв'яжіться з нами", + + "common.videoUnsupported": "Ваш браузер не підтримує відео.", + "common.figure": "Рис. {{n}}.", + "common.faq": "FAQ", + "common.learnMore": "Дізнатися більше", + + "error.invalidPlan": "Недійсний план", + "error.workspaceRequired": "ID робочого простору обов'язкове", + "error.alreadySubscribed": "Цей робочий простір уже має підписку", + "error.limitRequired": "Ліміт обов'язковий.", + "error.monthlyLimitInvalid": "Встановіть дійсний місячний ліміт.", + "error.workspaceNameRequired": "Назва робочого простору обов'язкова.", + "error.nameTooLong": "Назва має містити не більше 255 символів.", + "error.emailRequired": "Електронна адреса обов'язкова", + "error.roleRequired": "Роль обов'язкова", + "error.idRequired": "ID обов'язкове", + "error.nameRequired": "Назва обов'язкова", + "error.providerRequired": "Провайдер обов'язковий", + "error.apiKeyRequired": "Ключ API обов'язковий", + "error.modelRequired": "Модель обов'язкова", + "error.reloadAmountMin": "Сума поповнення має бути щонайменше ${{amount}}", + "error.reloadTriggerMin": "Поріг балансу має бути щонайменше ${{amount}}", + + "app.meta.description": "OpenCode — відкритий агент для програмування.", + + "home.title": "OpenCode | Відкритий AI-агент для кодування", + + "temp.title": "opencode | AI-агент для кодування, створений для термінала", + "temp.hero.title": "AI-агент для кодування, створений для термінала", + "temp.zen": "opencode zen", + "temp.getStarted": "Почати", + "temp.feature.native.title": "Рідний TUI", + "temp.feature.native.body": "Чуйний, рідний інтерфейс термінала з темами", + "temp.feature.zen.beforeLink": "A", + "temp.feature.zen.link": "добірка моделей", + "temp.feature.zen.afterLink": "від opencode", + "temp.feature.models.beforeLink": "Підтримує 75+ LLM-провайдерів через", + "temp.feature.models.afterLink": ", включаючи локальні моделі", + "temp.screenshot.caption": "OpenCode TUI з темою tokyonight", + "temp.screenshot.alt": "OpenCode TUI з темою tokyonight", + "temp.logoLightAlt": "світлий логотип opencode", + "temp.logoDarkAlt": "темний логотип opencode", + + "home.banner.badge": "Нове", + "home.banner.text": "Представляємо вкладки в десктопному застосунку.", + "home.banner.platforms": "Доступно на macOS, Windows та Linux", + "home.banner.downloadNow": "Завантажити зараз", + "home.banner.downloadBetaNow": "Завантажити бета-версію десктопного застосунку", + "home.promo.title": "Представляємо вкладки в десктопному застосунку", + "home.promo.body": "Упорядковуйте роботу й активні сесії за допомогою вкладок.", + "home.promo.cta": "Завантажте останню версію, щоб почати.", + "home.promo.close": "Закрити оголошення про десктопний застосунок", + + "home.hero.title": "Відкритий AI-агент для кодування", + "home.hero.subtitle.a": "Безкоштовні моделі включено або підключіть будь-яку модель від будь-якого провайдера,", + "home.hero.subtitle.b": "включно з Claude, GPT, Gemini та іншими.", + + "home.install.ariaLabel": "Параметри встановлення", + + "home.what.title": "Що таке OpenCode?", + "home.what.body": "OpenCode — це відкритий агент, який допомагає писати код у терміналі, IDE або на десктопі.", + "home.what.lsp.title": "LSP увімкнено", + "home.what.lsp.body": "Автоматично завантажує потрібні LSP для LLM", + "home.what.multiSession.title": "Багатосесійність", + "home.what.multiSession.body": "Запускайте кількох агентів паралельно в одному проекті", + "home.what.shareLinks.title": "Посилання для обміну", + "home.what.shareLinks.body": "Діліться посиланням на будь-яку сесію для обговорення або налагодження", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "Увійдіть через GitHub, щоб використовувати свій обліковий запис Copilot", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "Увійдіть через OpenAI, щоб використовувати ChatGPT Plus або Pro", + "home.what.anyModel.title": "Будь-яка модель", + "home.what.anyModel.body": "75+ LLM-провайдерів через Models.dev, включаючи локальні моделі", + "home.what.anyEditor.title": "Будь-який редактор", + "home.what.anyEditor.body": "Доступний як термінальний інтерфейс, десктопний застосунок та розширення IDE", + "home.what.readDocs": "Читати документацію", + + "home.growth.title": "Відкритий AI-агент для кодування", + "home.growth.body": + "З понад {{stars}} зірками на GitHub, {{contributors}} учасниками та понад {{commits}} комітами, OpenCode використовують понад {{monthlyUsers}} розробників щомісяця.", + "home.growth.githubStars": "Зірки GitHub", + "home.growth.contributors": "Учасники", + "home.growth.monthlyDevs": "Розробників на місяць", + + "home.privacy.title": "Створено для конфіденційності", + "home.privacy.body": + "OpenCode не зберігає ваш код або контекстні дані, тому може працювати в середовищах з чутливими даними.", + "home.privacy.learnMore": "Дізнатися більше про", + "home.privacy.link": "конфіденційність", + + "home.faq.q1": "Що таке OpenCode?", + "home.faq.a1": + "OpenCode — це відкритий агент, який допомагає писати та запускати код з будь-якою AI-моделлю. Доступний як термінальний інтерфейс, десктопний застосунок або розширення IDE.", + "home.faq.q2": "Як почати користуватися OpenCode?", + "home.faq.a2.before": "Найпростіший спосіб почати — прочитати", + "home.faq.a2.link": "вступ", + "home.faq.q3": "Чи потрібні додаткові AI-підписки для використання OpenCode?", + "home.faq.a3.p1": + "Не обов'язково, OpenCode має набір безкоштовних моделей, які можна використовувати без реєстрації.", + "home.faq.a3.p2.beforeZen": + "Крім цього, ви можете використовувати будь-які популярні моделі, створивши обліковий запис", + "home.faq.a3.p2.afterZen": ".", + "home.faq.a3.p3": + "Хоча ми рекомендуємо Zen, OpenCode також працює з усіма популярними провайдерами, такими як OpenAI, Anthropic, xAI тощо.", + "home.faq.a3.p4.beforeLocal": "Ви навіть можете підключити свої", + "home.faq.a3.p4.localLink": "локальні моделі", + "home.faq.q4": "Чи можу я використовувати свої наявні AI-підписки з OpenCode?", + "home.faq.a4.p1": + "Так, OpenCode підтримує підписки всіх основних провайдерів. Ви можете використовувати Claude Pro/Max, ChatGPT Plus/Pro або GitHub Copilot.", + "home.faq.q5": "Чи можна використовувати OpenCode лише в терміналі?", + "home.faq.a5.beforeDesktop": "Вже ні! OpenCode тепер доступний як застосунок для", + "home.faq.a5.desktop": "десктопа", + "home.faq.a5.and": "та", + "home.faq.a5.web": "вебу", + "home.faq.q6": "Скільки коштує OpenCode?", + "home.faq.a6": + "OpenCode є 100% безкоштовним. Він також має набір безкоштовних моделей. Додаткові витрати можливі, якщо ви підключите іншого провайдера.", + "home.faq.q7": "А як щодо даних та конфіденційності?", + "home.faq.a7.p1": + "Ваші дані зберігаються лише тоді, коли ви використовуєте безкоштовні моделі або створюєте посилання для обміну.", + "home.faq.a7.p2.beforeModels": "Дізнайтеся більше про", + "home.faq.a7.p2.modelsLink": "наші моделі", + "home.faq.a7.p2.and": "та", + "home.faq.a7.p2.shareLink": "сторінки обміну", + "home.faq.q8": "Чи є OpenCode відкритим?", + "home.faq.a8.p1": "Так, OpenCode повністю відкритий. Вихідний код доступний публічно на", + "home.faq.a8.p2": "під ліцензією", + "home.faq.a8.mitLicense": "MIT License", + "home.faq.a8.p3": + ", тобто кожен може використовувати, змінювати або сприяти його розвитку. Будь-хто зі спільноти може створювати issues, надсилати pull request'и та розширювати функціональність.", + + "home.zenCta.title": "Отримайте доступ до надійних оптимізованих моделей для агентів кодування", + "home.zenCta.body": + "Zen дає доступ до добірки AI-моделей, які OpenCode протестував спеціально для агентів кодування. Не турбуйтеся про нестабільну якість — використовуйте перевірені моделі.", + "home.zenCta.link": "Дізнатися про Zen", + + "zen.title": "OpenCode Zen | Добірка надійних оптимізованих моделей для агентів кодування", + "zen.hero.title": "Надійні оптимізовані моделі для агентів кодування", + "zen.hero.body": + "Zen дає доступ до добірки AI-моделей, які OpenCode протестував спеціально для агентів кодування. Не турбуйтеся про нестабільну якість — використовуйте перевірені моделі.", + + "zen.faq.q1": "Що таке OpenCode Zen?", + "zen.faq.a1": "Zen — це добірка AI-моделей, протестованих для агентів кодування, створена командою OpenCode.", + "zen.faq.q2": "Чому Zen точніший?", + "zen.faq.a2": + "Zen надає лише моделі, спеціально протестовані для агентів кодування. Ви ж не використовуєте масло ніж для стейка — не використовуйте погані моделі для кодування.", + "zen.faq.q3": "Чи Zen дешевший?", + "zen.faq.a3": + "Zen не є прибутковим. Zen передає вам вартість від провайдерів моделей. Чим вище використання Zen, тим кращі ціни OpenCode може узгодити та передати вам.", + "zen.faq.q4": "Скільки коштує Zen?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "стягує плату за запит", + "zen.faq.a4.p1.afterPricing": "без націнок — ви платите рівно стільки, скільки стягує провайдер моделі.", + "zen.faq.a4.p2.beforeAccount": "Загальна вартість залежить від використання. Ви можете встановити місячні ліміти в", + "zen.faq.a4.p2.accountLink": "обліковому записі", + "zen.faq.a4.p3": + "Щоб покрити витрати, OpenCode додає лише невелику комісію за обробку платежу в розмірі $1.23 за кожне поповнення балансу $20.", + "zen.faq.q5": "А як щодо даних та конфіденційності?", + "zen.faq.a5.beforeExceptions": + "Усі моделі Zen розміщені в США. Провайдери дотримуються політики нульового зберігання та не використовують ваші дані для навчання моделей, за", + "zen.faq.a5.exceptionsLink": "такими винятками", + "zen.faq.q6": "Чи можна встановити ліміти витрат?", + "zen.faq.a6": "Так, ви можете встановити місячні ліміти витрат в обліковому записі.", + "zen.faq.q7": "Чи можна скасувати?", + "zen.faq.a7": "Так, ви можете вимкнути оплату в будь-який час і використовувати залишок.", + "zen.faq.q8": "Чи можна використовувати Zen з іншими агентами кодування?", + "zen.faq.a8": + "Хоча Zen чудово працює з OpenCode, ви можете використовувати Zen з будь-яким агентом. Дотримуйтесь інструкцій з налаштування у вашому агенті.", + "zen.faq.q9": "Чи можу я отримати повернення коштів?", + "zen.faq.a9": + "Ви можете претендувати на повернення, якщо кошти було списано протягом останніх 14 днів і ви не використали кошти, отримані внаслідок цієї покупки. {{contact}}, щоб подати запит на повернення.", + + "zen.cta.start": "Почати з Zen", + "zen.pricing.title": "Додати $20 балансу Pay as you go", + "zen.pricing.fee": "(+$1.23 комісія за обробку карти)", + "zen.pricing.body": "Використовуйте з будь-яким агентом. Встановлюйте місячні ліміти. Скасуйте в будь-який час.", + "zen.problem.title": "Яку проблему вирішує Zen?", + "zen.problem.body": + "Доступно багато моделей, але лише деякі добре працюють з агентами кодування. Більшість провайдерів налаштовують їх по-різному з різними результатами.", + "zen.problem.subtitle": "Ми вирішуємо це для всіх, а не лише для користувачів OpenCode.", + "zen.problem.item1": "Тестування вибраних моделей та консультації з їхніми командами", + "zen.problem.item2": "Співпраця з провайдерами для забезпечення правильної доставки", + "zen.problem.item3": "Бенчмаркінг усіх комбінацій моделей та провайдерів, які ми рекомендуємо", + "zen.how.title": "Як працює Zen", + "zen.how.body": + "Хоча ми пропонуємо використовувати Zen з OpenCode, ви можете використовувати Zen з будь-яким агентом.", + "zen.how.step1.title": "Зареєструйтеся та додайте $20 балансу", + "zen.how.step1.beforeLink": "дотримуйтесь", + "zen.how.step1.link": "інструкцій з налаштування", + "zen.how.step2.title": "Використовуйте Zen із прозорими цінами", + "zen.how.step2.link": "платіть за запит", + "zen.how.step2.afterLink": "без націнок", + "zen.how.step3.title": "Автоматичне поповнення", + "zen.how.step3.body": "коли баланс досягає $5, ми автоматично додаємо $20", + "zen.privacy.title": "Ваша конфіденційність важлива для нас", + "zen.privacy.beforeExceptions": + "Усі моделі Zen розміщені в США. Провайдери дотримуються політики нульового зберігання та не використовують ваші дані для навчання моделей, за", + "zen.privacy.exceptionsLink": "такими винятками", + + "go.title": "OpenCode Go | Недорогі моделі кодування для всіх", + "go.meta.description": + "Go коштує $10/місяць, зі щедрими лімітами використання та надійним доступом до провідних моделей для кодування.", + "go.hero.title": "Недорогі моделі кодування для всіх", + "go.hero.body": + "Go надає агентне програмування програмістам у всьому світі, пропонуючи щедрі ліміти та надійний доступ до найкращих моделей з відкритим кодом.", + + "go.cta.start": "Підписатися на Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "Підписатися на Go", + "go.cta.price": "$10/місяць", + "go.pricing.body": "Використовуйте з будь-яким агентом. $10/місяць. Поповнюйте за потреби. Скасуйте в будь-який час.", + "go.graph.free": "Безкоштовно", + "go.graph.freePill": "Big Pickle та безкоштовні моделі", + "go.graph.go": "Go", + "go.graph.label": "Запитів за 5 годин", + "go.graph.period": "Використання", + "go.graph.model": "Модель", + "go.graph.requests": "Оцінка запитів / 5 год", + "go.graph.allowance": "Використання за місяць", + "go.graph.new": "Нове", + "go.graph.scale": "Нелінійна шкала кількості запитів", + "go.graph.showAll": "Показати всі моделі ({{count}})", + "go.graph.showLess": "Показати менше моделей", + "go.graph.limitedRegions": "обмежені регіони", + "go.graph.limitedTime": "обмежений час", + "go.graph.usageLimits": "Ліміти використання", + "go.graph.aria": "Запитів за 5 год: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "ex-CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "змінило моє життя, це справді очевидний вибір.", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "ex-Founder, SEED, PM, Melt, Pop, Dapt, Cadmus, and ViewPoint", + "go.testimonials.jay.quoteBefore": "4 з 5 людей у нашій команді люблять використовувати", + "go.testimonials.jay.quoteAfter": ".", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "ex-Hero, AWS", + "go.testimonials.adam.quoteBefore": "Я не можу достатньо рекомендувати", + "go.testimonials.adam.quoteAfter": ". Серйозно, це дійсно добре.", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "ex-Head of Design, Laravel", + "go.testimonials.david.quoteBefore": "Завдяки", + "go.testimonials.david.quoteAfter": "я знаю, що всі моделі протестовані та ідеальні для агентів кодування.", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "ex-Intern, Nvidia (4 times)", + "go.testimonials.frank.quote": "Хотів би я досі бути в Nvidia.", + "go.problem.title": "Яку проблему вирішує Go?", + "go.problem.body": + "Ми зосереджені на тому, щоб зробити досвід OpenCode доступним для якомога більшої кількості людей. OpenCode Go — це недорога підписка за $10/місяць. Вона надає щедрі ліміти та надійний доступ до найкращих моделей з відкритим кодом.", + "go.problem.subtitle": " ", + "go.problem.item1": "Недорога підписка", + "go.problem.item2": "Щедрі ліміти та надійний доступ", + "go.problem.item3": "Створено для якомога більшої кількості програмістів", + "go.problem.item4": "Добірка моделей, протестованих для агентного кодування", + "go.how.title": "Як працює Go", + "go.how.body": "Go коштує $10/місяць. Використовуйте з OpenCode або будь-яким агентом.", + "go.how.step1.title": "Створіть обліковий запис", + "go.how.step1.beforeLink": "дотримуйтесь", + "go.how.step1.link": "інструкцій з налаштування", + "go.how.step2.title": "Підпишіться на Go", + "go.how.step2.link": "$10/місяць", + "go.how.step2.afterLink": "із щедрими лімітами", + "go.how.step3.title": "Почніть кодувати", + "go.how.step3.body": "з надійним доступом до моделей з відкритим кодом", + "go.privacy.title": "Ваша конфіденційність важлива для нас", + "go.privacy.body": + "План розроблений переважно для міжнародних користувачів, з моделями, розміщеними в США, ЄС та Сінгапурі для стабільного глобального доступу.", + "go.privacy.contactAfter": "якщо у вас є запитання.", + "go.privacy.beforeExceptions": + "Моделі Go розміщені в США. Провайдери дотримуються політики нульового зберігання та не використовують ваші дані для навчання моделей, за", + "go.privacy.exceptionsLink": "такими винятками", + "go.faq.q1": "Що таке OpenCode Go?", + "go.faq.a1": + "Go — це недорога підписка, яка надає надійний доступ до найкращих моделей з відкритим кодом для агентного кодування.", + "go.faq.q2": "Які моделі включає Go?", + "go.faq.a2": "Go включає моделі, перелічені нижче, із щедрими лімітами та надійним доступом.", + "go.faq.q3": "Чи Go те саме, що Zen?", + "go.faq.a3": + "Ні. Zen — це плата за використання, тоді як Go коштує $10/місяць, із щедрими лімітами та надійним доступом до добірки моделей.", + "go.faq.q4": "Скільки коштує Go?", + "go.faq.a4.p1.beforePricing": "Go коштує", + "go.faq.a4.p1.pricingLink": "$10/місяць", + "go.faq.a4.p1.afterPricing": "із щедрими лімітами.", + "go.faq.a4.p2.beforeAccount": "Ви можете керувати підпискою в", + "go.faq.a4.p2.accountLink": "обліковому записі", + "go.faq.a4.p3": "Скасуйте в будь-який час.", + "go.faq.q5": "А як щодо даних та конфіденційності?", + "go.faq.a5.model": "Модель", + "go.faq.a5.training": "Навчання моделей", + "go.faq.a5.retention": "Зберігання даних", + "go.faq.a5.retention30": "30 днів", + "go.faq.a5.retention0": "0 днів", + "go.faq.a5.used": "Використовується", + "go.faq.a5.notUsed": "Не використовується", + "go.faq.a5.noAgreement": "Немає угоди", + "go.faq.a5.notZdr": "Не ZDR", + "go.faq.a5.grokRetention": + "ZDR вимикає важливі функції API, які залежать від збережених даних, зокрема Responses API зі збереженням стану, Files and Collections та Batch API.", + "go.faq.a5.gptRetention": + "Журнали моніторингу зловживань створюються для всіх випадків використання функцій API та зберігаються до 30 днів.", + "go.faq.a5.learnMore": "Докладніше", + "go.faq.a5.deepseekRetention": "Угода ZDR поновлюється щомісяця. Поточна угода дійсна до 30 вересня 2026 року.", + "go.faq.a5.museRetention": + "Значно знижені ціни на токени в обмін на дозвіл використовувати ваші промпти та відповіді для навчання майбутніх моделей Meta.", + + "go.faq.a5.beforeExceptions": + "Моделі Go розміщені в США. Провайдери дотримуються політики нульового зберігання та не використовують ваші дані для навчання моделей, за", + "go.faq.a5.exceptionsLink": "такими винятками", + "go.faq.q6": "Чи можна поповнити баланс?", + "go.faq.a6": "Якщо вам потрібно більше використання, ви можете поповнити баланс в обліковому записі.", + "go.faq.q7": "Чи можна скасувати?", + "go.faq.a7": "Так, ви можете скасувати в будь-який час.", + "go.faq.q8": "Чи можна використовувати Go з іншими агентами кодування?", + "go.faq.a8": "Так, ви можете використовувати Go з будь-яким агентом.", + + "go.faq.q9": "Яка різниця між безкоштовними моделями та Go?", + "go.faq.a9": + "Безкоштовні моделі включають Big Pickle та доступні на той момент акційні моделі з квотою 200 запитів/день. Go пропонує добірку моделей із вищими квотами запитів, що застосовуються протягом ковзних періодів (5 годин, тижня та місяця), приблизно еквівалентними базовим лімітам $12 за 5 годин, $30 на тиждень і $60 на місяць; ліміти для окремих моделей можуть відрізнятися (фактична кількість запитів залежить від моделі та використання).", + "go.faq.q10": "Чи можу я отримати повернення коштів?", + "go.faq.a10": + "Ви можете претендувати на повернення, якщо кошти було списано протягом останніх 14 днів і ви не використали ліміт Go протягом цього розрахункового періоду. {{contact}}, щоб подати запит на повернення.", + + "zen.api.error.rateLimitExceeded": "Перевищено ліміт запитів. Спробуйте пізніше.", + "zen.api.error.modelNotSupported": "Модель {{model}} не підтримується", + "zen.api.error.modelFormatNotSupported": "Модель {{model}} не підтримується для формату {{format}}", + "zen.api.error.noProviderAvailable": "Немає доступного провайдера", + "zen.api.error.providerNotSupported": "Провайдер {{provider}} не підтримується", + "zen.api.error.missingApiKey": "Відсутній ключ API.", + "zen.api.error.invalidApiKey": "Недійсний ключ API.", + "zen.api.error.requestBlockedByUpstreamProvider": "Запит заблоковано зовнішнім провайдером.", + "zen.api.error.subscriptionQuotaExceeded": "Перевищено квоту підписки. Повторіть через {{retryIn}}.", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "Досягнуто 5-годинного ліміту використання. Скидається через {{retryIn}}. Щоб продовжити, увімкніть використання з доступного балансу: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "Досягнуто тижневого ліміту використання. Скидається через {{retryIn}}. Щоб продовжити, увімкніть використання з доступного балансу: {{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "Досягнуто місячного ліміту використання. Скидається через {{retryIn}}. Щоб продовжити, увімкніть використання з доступного балансу: {{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "Немає способу оплати. Додайте метод оплати: {{billingUrl}}", + "zen.api.error.insufficientBalance": "Недостатньо коштів. Керуйте оплатою: {{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "Ваш робочий простір досяг місячного ліміту витрат ${{amount}}. Керуйте лімітами: {{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": + "Ви досягли місячного ліміту витрат ${{amount}}. Керуйте лімітами: {{membersUrl}}", + "zen.api.error.modelDisabled": "Модель вимкнено", + "zen.api.error.regionNotAllowed": + "Остання версія цієї моделі доступна лише на серверах у Китаї, і для її використання потрібно надати явну згоду: {{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "Ця модель недоступна у вашій країні.", + "zen.api.error.trainingNotAllowed": + "Ця модель збирає дані, які використовуються для покращення її якості; для її використання потрібна ваша явна згода: {{consoleGoUrl}}", + "zen.api.error.trialEnded": + "Безкоштовна акція для {{model}} закінчилася. Ви можете продовжити використання, підписавшись на OpenCode Go — {{link}}", + + "black.meta.title": "OpenCode Black | Доступ до найкращих моделей кодування", + "black.meta.description": "Отримайте доступ до Claude, GPT, Gemini та інших із планами підписки OpenCode Black.", + "black.hero.title": "Доступ до найкращих моделей кодування", + "black.hero.subtitle": "Включаючи Claude, GPT, Gemini та інші", + "black.title": "OpenCode Black | Ціни", + "black.paused": "Реєстрація в план Black тимчасово призупинена.", + "black.plan.icon20": "План Black 20", + "black.plan.icon100": "План Black 100", + "black.plan.icon200": "План Black 200", + "black.plan.multiplier100": "5x більше використання ніж Black 20", + "black.plan.multiplier200": "20x більше використання ніж Black 20", + "black.price.perMonth": "на місяць", + "black.price.perPersonBilledMonthly": "за особу з щомісячною оплатою", + "black.terms.1": "Ваша підписка не розпочнеться негайно", + "black.terms.2": "Вас додадуть до списку очікування та активують незабаром", + "black.terms.3": "Картку буде списано лише після активації підписки", + "black.terms.4": "Діють ліміти використання, інтенсивне автоматичне використання може швидше вичерпати ліміти", + "black.terms.5": "Підписки призначені для фізичних осіб, зверніться в Enterprise для команд", + "black.terms.6": "Ліміти можуть бути змінені, а плани можуть бути припинені в майбутньому", + "black.terms.7": "Скасуйте підписку в будь-який час", + "black.action.continue": "Продовжити", + "black.finePrint.beforeTerms": "Зазначені ціни не включають податки", + "black.finePrint.terms": "Умови надання послуг", + "black.workspace.title": "OpenCode Black | Виберіть робочий простір", + "black.workspace.selectPlan": "Виберіть робочий простір для цього плану", + "black.workspace.name": "Робочий простір {{n}}", + "black.subscribe.title": "Підписатися на OpenCode Black", + "black.subscribe.paymentMethod": "Спосіб оплати", + "black.subscribe.loadingPaymentForm": "Завантаження форми оплати...", + "black.subscribe.selectWorkspaceToContinue": "Виберіть робочий простір для продовження", + "black.subscribe.failurePrefix": "Ой!", + "black.subscribe.error.generic": "Сталася помилка", + "black.subscribe.error.invalidPlan": "Недійсний план", + "black.subscribe.error.workspaceRequired": "ID робочого простору обов'язкове", + "black.subscribe.error.alreadySubscribed": "Цей робочий простір уже має підписку", + "black.subscribe.processing": "Обробка...", + "black.subscribe.submit": "Підписатися ${{plan}}", + "black.subscribe.form.chargeNotice": "Платіж буде списано лише після активації підписки", + "black.subscribe.success.title": "Ви в списку очікування OpenCode Black", + "black.subscribe.success.subscriptionPlan": "План підписки", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "Сума", + "black.subscribe.success.amountValue": "${{plan}} на місяць", + "black.subscribe.success.paymentMethod": "Спосіб оплати", + "black.subscribe.success.dateJoined": "Дата приєднання", + "black.subscribe.success.chargeNotice": "Вашу картку буде списано після активації підписки", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "Використання", + "workspace.nav.apiKeys": "Ключі API", + "workspace.nav.members": "Учасники", + "workspace.nav.billing": "Оплата", + "workspace.nav.settings": "Налаштування", + + "workspace.home.banner.beforeLink": "Надійні оптимізовані моделі для агентів кодування.", + "workspace.lite.banner.beforeLink": "Недорогі моделі кодування для всіх.", + "workspace.home.billing.loading": "Завантаження...", + "workspace.home.billing.enable": "Увімкнути оплату", + "workspace.home.billing.currentBalance": "Поточний баланс", + + "workspace.newUser.feature.tested.title": "Протестовані та перевірені моделі", + "workspace.newUser.feature.tested.body": + "Ми протестували моделі спеціально для агентів кодування, щоб забезпечити найкращу продуктивність.", + "workspace.newUser.feature.quality.title": "Найвища якість", + "workspace.newUser.feature.quality.body": + "Доступ до моделей, налаштованих для оптимальної продуктивності — без зниження якості.", + "workspace.newUser.feature.lockin.title": "Без блокування (Lock-in)", + "workspace.newUser.feature.lockin.body": + "Використовуйте Zen з будь-яким агентом і продовжуйте користуватися іншими провайдерами.", + "workspace.newUser.copyApiKey": "Копіювати ключ API", + "workspace.newUser.copyKey": "Копіювати ключ", + "workspace.newUser.copied": "Скопійовано!", + "workspace.newUser.step.enableBilling": "Увімкнути оплату", + "workspace.newUser.step.login.before": "Запустіть", + "workspace.newUser.step.login.after": "і виберіть opencode", + "workspace.newUser.step.pasteKey": "Вставте ключ API", + "workspace.newUser.step.models.before": "Запустіть opencode і виконайте", + "workspace.newUser.step.models.after": "щоб вибрати модель", + + "workspace.models.title": "Моделі", + "workspace.models.subtitle.beforeLink": "Керуйте доступом учасників до моделей.", + "workspace.models.table.model": "Модель", + "workspace.models.table.enabled": "Увімкнено", + + "workspace.providers.title": "Принесіть власний ключ (BYOK)", + "workspace.providers.subtitle": "Налаштуйте власні ключі API від AI-провайдерів.", + "workspace.providers.placeholder": "Введіть ключ API {{provider}} ({{prefix}}...)", + "workspace.providers.configure": "Налаштувати", + "workspace.providers.edit": "Редагувати", + "workspace.providers.delete": "Видалити", + "workspace.providers.saving": "Збереження...", + "workspace.providers.save": "Зберегти", + "workspace.providers.table.provider": "Провайдер", + "workspace.providers.table.apiKey": "Ключ API", + + "workspace.usage.title": "Історія використання", + "workspace.usage.subtitle": "Останнє використання API та витрати.", + "workspace.usage.empty": "Зробіть перший API-запит, щоб почати.", + "workspace.usage.table.date": "Дата", + "workspace.usage.table.model": "Модель", + "workspace.usage.table.input": "Вхід", + "workspace.usage.table.output": "Вихід", + "workspace.usage.table.cost": "Вартість", + "workspace.usage.table.session": "Сесія", + "workspace.usage.breakdown.input": "Вхід", + "workspace.usage.breakdown.cacheRead": "Читання кешу", + "workspace.usage.breakdown.cacheWrite": "Запис кешу", + "workspace.usage.breakdown.output": "Вихід", + "workspace.usage.breakdown.reasoning": "Міркування", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "Вартість", + "workspace.cost.subtitle": "Витрати в розрізі моделей.", + "workspace.cost.allModels": "Усі моделі", + "workspace.cost.allKeys": "Усі ключі", + "workspace.cost.deletedSuffix": "(видалено)", + "workspace.cost.empty": "Немає даних про використання за вибраний період.", + "workspace.cost.subscriptionShort": "підп", + + "workspace.keys.title": "Ключі API", + "workspace.keys.subtitle": "Керуйте ключами API для доступу до сервісів opencode.", + "workspace.keys.create": "Створити ключ API", + "workspace.keys.placeholder": "Введіть назву ключа", + "workspace.keys.empty": "Створіть ключ API шлюзу opencode", + "workspace.keys.table.name": "Назва", + "workspace.keys.table.key": "Ключ", + "workspace.keys.table.createdBy": "Створено", + "workspace.keys.table.lastUsed": "Останнє використання", + "workspace.keys.copyApiKey": "Копіювати ключ API", + "workspace.keys.delete": "Видалити", + + "workspace.members.title": "Учасники", + "workspace.members.subtitle": "Керуйте учасниками робочого простору та їхніми дозволами.", + "workspace.members.invite": "Запросити учасника", + "workspace.members.inviting": "Запрошення...", + "workspace.members.beta.beforeLink": "Робочі простори безкоштовні для команд під час бета-версії.", + "workspace.members.form.invitee": "Запрошений", + "workspace.members.form.emailPlaceholder": "Введіть email", + "workspace.members.form.role": "Роль", + "workspace.members.form.monthlyLimit": "Місячний ліміт витрат", + "workspace.members.noLimit": "Без ліміту", + "workspace.members.noLimitLowercase": "без ліміту", + "workspace.members.invited": "запрошено", + "workspace.members.edit": "Редагувати", + "workspace.members.delete": "Видалити", + "workspace.members.saving": "Збереження...", + "workspace.members.save": "Зберегти", + "workspace.members.table.email": "Email", + "workspace.members.table.role": "Роль", + "workspace.members.table.monthLimit": "Ліміт на місяць", + "workspace.members.role.admin": "Адміністратор", + "workspace.members.role.adminDescription": "Може керувати моделями, учасниками та оплатою", + "workspace.members.role.member": "Учасник", + "workspace.members.role.memberDescription": "Може створювати ключі API лише для себе", + + "workspace.settings.title": "Налаштування", + "workspace.settings.subtitle": "Оновіть назву робочого простору та налаштування.", + "workspace.settings.workspaceName": "Назва робочого простору", + "workspace.settings.defaultName": "Стандартна", + "workspace.settings.updating": "Оновлення...", + "workspace.settings.save": "Зберегти", + "workspace.settings.edit": "Редагувати", + + "workspace.billing.title": "Оплата", + "workspace.billing.subtitle.beforeLink": "Керуйте способами оплати.", + "workspace.billing.contactUs": "Зв'яжіться з нами", + "workspace.billing.subtitle.afterLink": "якщо у вас є запитання.", + "workspace.billing.currentBalance": "Поточний баланс", + "workspace.billing.add": "Додати $", + "workspace.billing.enterAmount": "Введіть суму", + "workspace.billing.loading": "Завантаження...", + "workspace.billing.addAction": "Додати", + "workspace.billing.addBalance": "Поповнити баланс", + "workspace.billing.alipay": "Alipay", + "workspace.billing.wechat": "WeChat Pay", + "workspace.billing.linkedToStripe": "Підключено до Stripe", + "workspace.billing.manage": "Керувати", + "workspace.billing.enable": "Увімкнути оплату", + + "workspace.monthlyLimit.title": "Місячний ліміт", + "workspace.monthlyLimit.subtitle": "Встановіть місячний ліміт використання для облікового запису.", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "Встановлення...", + "workspace.monthlyLimit.set": "Встановити", + "workspace.monthlyLimit.edit": "Редагувати ліміт", + "workspace.monthlyLimit.noLimit": "Ліміт використання не встановлено.", + "workspace.monthlyLimit.currentUsage.beforeMonth": "Поточне використання за", + "workspace.monthlyLimit.currentUsage.beforeAmount": "становить $", + + "workspace.redeem.title": "Активувати купон", + "workspace.redeem.subtitle": "Активуйте код купона для отримання коштів або бонусів.", + "workspace.redeem.placeholder": "Введіть код купона", + "workspace.redeem.redeem": "Активувати", + "workspace.redeem.redeeming": "Активація...", + "workspace.redeem.success": "Купон успішно активовано.", + + "workspace.reload.title": "Автоматичне поповнення", + "workspace.reload.disabled.before": "Автоматичне поповнення", + "workspace.reload.disabled.state": "вимкнено", + "workspace.reload.disabled.after": "Увімкніть для автоматичного поповнення при низькому балансі.", + "workspace.reload.enabled.before": "Автоматичне поповнення", + "workspace.reload.enabled.state": "увімкнено", + "workspace.reload.enabled.middle": "Ми поповнимо", + "workspace.reload.processingFee": "комісія за обробку", + "workspace.reload.enabled.after": "коли баланс досягне", + "workspace.reload.edit": "Редагувати", + "workspace.reload.enable": "Увімкнути", + "workspace.reload.enableAutoReload": "Увімкнути автоматичне поповнення", + "workspace.reload.reloadAmount": "Поповнити на $", + "workspace.reload.whenBalanceReaches": "Коли баланс досягне $", + "workspace.reload.saving": "Збереження...", + "workspace.reload.save": "Зберегти", + "workspace.reload.failedAt": "Поповнення не вдалося о", + "workspace.reload.reason": "Причина:", + "workspace.reload.updatePaymentMethod": "Оновіть спосіб оплати та спробуйте ще раз.", + "workspace.reload.retrying": "Повтор...", + "workspace.reload.retry": "Повторити", + "workspace.reload.error.paymentFailed": "Платіж не вдався.", + + "workspace.payments.title": "Історія платежів", + "workspace.payments.subtitle": "Останні платіжні транзакції.", + "workspace.payments.table.date": "Дата", + "workspace.payments.table.paymentId": "ID платежу", + "workspace.payments.table.amount": "Сума", + "workspace.payments.table.receipt": "Квитанція", + "workspace.payments.type.credit": "кредит", + "workspace.payments.type.subscription": "підписка", + "workspace.payments.view": "Переглянути", + + "workspace.black.loading": "Завантаження...", + "workspace.black.time.day": "день", + "workspace.black.time.days": "дні", + "workspace.black.time.hour": "година", + "workspace.black.time.hours": "годин(и)", + "workspace.black.time.minute": "хвилина", + "workspace.black.time.minutes": "хвилин(и)", + "workspace.black.time.fewSeconds": "кілька секунд", + "workspace.black.subscription.title": "Підписка", + "workspace.black.subscription.message": "Ви підписані на OpenCode Black за ${{plan}} на місяць.", + "workspace.black.subscription.manage": "Керувати підпискою", + "workspace.black.subscription.rollingUsage": "Використання (5 год)", + "workspace.black.subscription.weeklyUsage": "Тижневе використання", + "workspace.black.subscription.resetsIn": "Скидається через", + "workspace.black.subscription.useBalance": "Використовуйте доступний баланс після досягнення лімітів", + "workspace.black.waitlist.title": "Список очікування", + "workspace.black.waitlist.joined": "Ви в списку очікування на план OpenCode Black за ${{plan}} на місяць.", + "workspace.black.waitlist.ready": "Ми готові зареєструвати вас на план OpenCode Black за ${{plan}} на місяць.", + "workspace.black.waitlist.leave": "Залишити список очікування", + "workspace.black.waitlist.leaving": "Вихід...", + "workspace.black.waitlist.left": "Вишли", + "workspace.black.waitlist.enroll": "Зареєструватися", + "workspace.black.waitlist.enrolling": "Реєстрація...", + "workspace.black.waitlist.enrolled": "Зареєстровано", + "workspace.black.waitlist.enrollNote": + "Після натискання «Зареєструватися» підписка почнеться негайно, а картку буде списано.", + + "workspace.lite.loading": "Завантаження...", + "workspace.lite.time.day": "день", + "workspace.lite.time.days": "дні", + "workspace.lite.time.hour": "година", + "workspace.lite.time.hours": "годин(и)", + "workspace.lite.time.minute": "хвилина", + "workspace.lite.time.minutes": "хвилин(и)", + "workspace.lite.time.fewSeconds": "кілька секунд", + "workspace.lite.subscription.message": "Ви підписані на OpenCode Go.", + "workspace.lite.subscription.manage": "Керувати підпискою", + "workspace.lite.subscription.rollingUsage": "Використання за 5 годин", + "workspace.lite.subscription.rollingQuota": "Квота на 5 годин", + "workspace.lite.subscription.weeklyUsage": "Тижневе використання", + "workspace.lite.subscription.weeklyQuota": "Тижнева квота", + "workspace.lite.subscription.monthlyUsage": "Місячне використання", + "workspace.lite.subscription.monthlyQuota": "Місячна квота", + "workspace.lite.subscription.resetsIn": "Скидається через", + "workspace.lite.subscription.showDetails": "Показати подробиці", + "workspace.lite.subscription.hideDetails": "Приховати подробиці", + "workspace.lite.subscription.model": "Модель", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "Усього", + "workspace.lite.subscription.useBalance": "Використовуйте доступний баланс після досягнення лімітів", + "workspace.lite.subscription.selectProvider": 'Виберіть "OpenCode Go" як провайдера в конфігурації opencode.', + "workspace.lite.providers.title": "Провайдери", + "workspace.lite.providers.description": "Керуйте провайдерами, які використовуються для маршрутизації.", + "workspace.lite.providers.allowTraining": "Дозволити моделі, що навчаються на даних запитів", + "workspace.lite.providers.useChina": "Увімкнути моделі, розміщені в Китаї", + "workspace.lite.black.message": + "Ви вже підписані на OpenCode Black або в списку очікування. Спочатку скасуйте підписку, якщо хочете перейти на Go.", + "workspace.lite.other.message": "Інший учасник цього робочого простору вже підписаний на OpenCode Go.", + "workspace.lite.promo.description": "OpenCode Go коштує {{price}} і має щедрі ліміти.", + "workspace.lite.promo.price": "$10/місяць", + "workspace.lite.promo.modelsTitle": "Що включено", + "workspace.lite.promo.footer": + "План призначений насамперед для міжнародних користувачів і забезпечує стабільний глобальний доступ. Ціни та ліміти використання можуть змінюватися з урахуванням перших даних про використання та відгуків.", + "workspace.lite.promo.subscribe": "Підписатися на Go", + "workspace.lite.promo.subscribing": "Перенаправлення...", + "workspace.lite.promo.otherMethods": "Інші способи оплати", + "workspace.lite.promo.selectMethod": "Виберіть спосіб оплати", + + "download.title": "OpenCode | Завантажити", + "download.meta.description": "Завантажте OpenCode для macOS, Windows та Linux", + "download.hero.title": "Завантажити OpenCode Desktop", + "download.hero.subtitle": "Доступно в бета-версії для macOS, Windows та Linux", + "download.hero.button": "Завантажити для {{os}}", + "download.section.terminal": "Термінал OpenCode", + "download.section.desktop": "Десктоп OpenCode", + "download.section.extensions": "Розширення OpenCode", + "download.section.integrations": "Інтеграції OpenCode", + "download.action.download": "Завантажити", + "download.action.install": "Встановити", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "Не обов'язково, але ймовірно. Вам знадобиться AI-підписка, якщо ви хочете підключити платного провайдера, хоча ви можете працювати з", + "download.faq.a3.localLink": "локальними моделями", + "download.faq.a3.afterLocal.beforeZen": "безкоштовно. Хоча ми рекомендуємо", + "download.faq.a3.afterZen": + ", OpenCode працює з усіма популярними провайдерами, такими як OpenAI, Anthropic, xAI тощо.", + + "download.faq.a5.p1": "OpenCode є 100% безкоштовним.", + "download.faq.a5.p2.beforeZen": + "Будь-які додаткові витрати будуть з вашої підписки у провайдера моделі. Ми рекомендуємо", + "download.faq.a5.p2.afterZen": ".", + + "download.faq.a6.p1": "Ваші дані зберігаються лише при створенні посилань для обміну в OpenCode.", + "download.faq.a6.p2.beforeShare": "Дізнайтеся більше про", + "download.faq.a6.shareLink": "сторінки обміну", + + "enterprise.title": "OpenCode | Enterprise-рішення для вашої організації", + "enterprise.meta.description": "Зв'яжіться з OpenCode для Enterprise-рішень", + "enterprise.hero.title": "Ваш код належить вам", + "enterprise.hero.body1": + "OpenCode працює безпечно всередині вашої організації без зберігання даних, ліцензійних обмежень. Почніть пробний період із командою, потім розгорніть через SSO та внутрішній AI-шлюз.", + "enterprise.hero.body2": "Дайте знати, чим ми можемо допомогти.", + "enterprise.form.name.label": "Повне ім'я", + "enterprise.form.name.placeholder": "Джеф Безос", + "enterprise.form.role.label": "Посада", + "enterprise.form.role.placeholder": "Голова правління", + "enterprise.form.company.label": "Компанія", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "Робоча електронна адреса", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "Номер телефону", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "Яку проблему ви намагаєтеся вирішити?", + "enterprise.form.message.placeholder": "Нам потрібна допомога з...", + "enterprise.form.send": "Надіслати", + "enterprise.form.sending": "Надсилання...", + "enterprise.form.success": "Повідомлення надіслано, ми зв'яжемося найближчим часом.", + "enterprise.form.success.submitted": "Форму успішно надіслано.", + "enterprise.form.error.allFieldsRequired": "Усі поля обов'язкові.", + "enterprise.form.error.invalidEmailFormat": "Недійсний формат email.", + "enterprise.form.error.internalServer": "Внутрішня помилка сервера.", + "enterprise.faq.title": "FAQ", + "enterprise.faq.q1": "Що таке OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise для організацій, які хочуть гарантувати, що код і дані ніколи не залишають їхню інфраструктуру.", + "enterprise.faq.q2": "Як почати з OpenCode Enterprise?", + "enterprise.faq.a2": + "Почніть із внутрішнього тестування з командою. OpenCode за замовчуванням не зберігає код. Потім зв'яжіться з нами для обговорення цін.", + "enterprise.faq.q3": "Як працює ціноутворення enterprise?", + "enterprise.faq.a3": + "Ми пропонуємо ціну за робоче місце. Якщо у вас власний LLM-шлюз, ми не стягуємо плату за токени.", + "enterprise.faq.q4": "Чи безпечні мої дані з OpenCode Enterprise?", + "enterprise.faq.a4": + "Так. OpenCode не зберігає ваш код або контекст. Вся обробка відбувається локально або через прямі API-виклики.", + + "brand.title": "OpenCode | Бренд", + "brand.meta.description": "Рекомендації щодо бренду OpenCode", + "brand.heading": "Рекомендації щодо бренду", + "brand.subtitle": "Ресурси та матеріали для роботи з брендом OpenCode.", + "brand.downloadAll": "Завантажити всі матеріали", + + "changelog.title": "OpenCode | Журнал змін", + "changelog.meta.description": "Нотатки про випуски та журнал змін OpenCode", + "changelog.hero.title": "Журнал змін", + "changelog.hero.subtitle": "Нові оновлення та покращення OpenCode", + "changelog.empty": "Записів у журналі змін не знайдено.", + "changelog.viewJson": "Переглянути JSON", + + "bench.list.title": "Бенчмарк", + "bench.list.heading": "Бенчмарки", + "bench.list.table.agent": "Агент", + "bench.list.table.model": "Модель", + "bench.list.table.score": "Результат", + "bench.submission.error.allFieldsRequired": "Усі поля обов'язкові.", + + "bench.detail.title": "Бенчмарк — {{task}}", + "bench.detail.notFound": "Завдання не знайдено", + "bench.detail.na": "Н/Д", + "bench.detail.labels.agent": "Агент", + "bench.detail.labels.model": "Модель", + "bench.detail.labels.task": "Завдання", + "bench.detail.labels.repo": "Репозиторій", + "bench.detail.labels.from": "Від", + "bench.detail.labels.to": "До", + "bench.detail.labels.prompt": "Prompt", + "bench.detail.labels.commit": "Коміт", + "bench.detail.labels.averageDuration": "Середня тривалість", + "bench.detail.labels.averageScore": "Середній результат", + "bench.detail.labels.averageCost": "Середня вартість", + "bench.detail.labels.summary": "Підсумок", + "bench.detail.labels.runs": "Запуски", + "bench.detail.labels.score": "Результат", + "bench.detail.labels.base": "База", + "bench.detail.labels.penalty": "Штраф", + "bench.detail.labels.weight": "вага", + "bench.detail.table.run": "Запуск", + "bench.detail.table.score": "Результат (База — Штраф)", + "bench.detail.table.cost": "Вартість", + "bench.detail.table.duration": "Тривалість", + "bench.detail.run.title": "Запуск {{n}}", + "bench.detail.rawJson": "Сирий JSON", +} diff --git a/packages/console/app/src/i18n/zh.ts b/packages/console/app/src/i18n/zh.ts new file mode 100644 index 0000000000000000000000000000000000000000..8c1aff6f6083ef891c7fee93ad94c5359df8ba2f --- /dev/null +++ b/packages/console/app/src/i18n/zh.ts @@ -0,0 +1,844 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash 限时享受 4 倍使用额度", + "go.graph.bonus": "{{count}} 倍用量", + "nav.github": "GitHub", + "nav.docs": "文档", + "nav.changelog": "更新日志", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "企业版", + "nav.zen": "Zen", + "nav.login": "登录", + "nav.free": "下载", + "nav.home": "首页", + "nav.openMenu": "打开菜单", + "nav.getStartedFree": "免费开始", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "复制 Logo (SVG)", + "nav.context.copyWordmark": "复制商标 (SVG)", + "nav.context.brandAssets": "品牌资产", + + "footer.github": "GitHub", + "footer.docs": "文档", + "footer.changelog": "更新日志", + "footer.feishu": "飞书", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "品牌", + "legal.privacy": "隐私", + "legal.terms": "条款", + + "email.title": "第一时间获知我们的新产品发布", + "email.subtitle": "加入候补名单,获取抢先体验资格。", + "email.placeholder": "电子邮箱地址", + "email.subscribe": "订阅", + "email.success": "即将完成,请检查您的收件箱并确认您的邮箱地址", + + "notFound.title": "未找到页面 | OpenCode", + "notFound.heading": "404 - 页面未找到", + "notFound.home": "首页", + "notFound.docs": "文档", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode logo 亮色", + "notFound.logoDarkAlt": "opencode logo 暗色", + + "user.logout": "退出登录", + + "auth.callback.error.codeMissing": "未找到授权码。", + + "workspace.select": "选择工作区", + "workspace.createNew": "+ 新建工作区", + "workspace.modal.title": "新建工作区", + "workspace.modal.placeholder": "输入工作区名称", + + "common.cancel": "取消", + "common.creating": "正在创建...", + "common.create": "创建", + "common.contactUs": "联系我们", + + "common.videoUnsupported": "您的浏览器不支持 video 标签。", + "common.figure": "图 {{n}}.", + "common.faq": "常见问题", + "common.learnMore": "了解更多", + + "error.invalidPlan": "无效的计划", + "error.workspaceRequired": "缺少工作区 ID", + "error.alreadySubscribed": "此工作区已有订阅", + "error.limitRequired": "缺少限制设置。", + "error.monthlyLimitInvalid": "设置有效的每月限额。", + "error.workspaceNameRequired": "缺少工作区名称。", + "error.nameTooLong": "名称必须少于 255 个字符。", + "error.emailRequired": "缺少电子邮箱", + "error.roleRequired": "缺少角色", + "error.idRequired": "缺少 ID", + "error.nameRequired": "缺少名称", + "error.providerRequired": "缺少提供商", + "error.apiKeyRequired": "缺少 API 密钥", + "error.modelRequired": "缺少模型", + "error.reloadAmountMin": "充值金额必须至少为 ${{amount}}", + "error.reloadTriggerMin": "余额触发阈值必须至少为 ${{amount}}", + + "app.meta.description": "OpenCode - 开源编程代理。", + + "home.title": "OpenCode | 开源 AI 编程代理", + + "temp.title": "OpenCode | 专为终端打造的 AI 编程代理", + "temp.hero.title": "专为终端打造的 AI 编程代理", + "temp.zen": "OpenCode Zen", + "temp.getStarted": "开始使用", + "temp.feature.native.title": "原生 TUI", + "temp.feature.native.body": "响应迅速、原生的、可定制主题的终端 UI", + "temp.feature.zen.beforeLink": "由 OpenCode 提供的", + "temp.feature.zen.link": "精选模型列表", + "temp.feature.zen.afterLink": "", + "temp.feature.models.beforeLink": "通过 Models.dev 支持 75+ LLM 提供商", + "temp.feature.models.afterLink": ",包括本地模型", + "temp.screenshot.caption": "使用 Tokyonight 主题的 OpenCode TUI", + "temp.screenshot.alt": "使用 Tokyonight 主题的 OpenCode TUI", + "temp.logoLightAlt": "opencode logo 亮色", + "temp.logoDarkAlt": "opencode logo 暗色", + + "home.banner.badge": "新", + "home.banner.text": "桌面版标签页现已推出。", + "home.banner.platforms": "适用于 macOS、Windows 和 Linux", + "home.banner.downloadNow": "立即下载", + "home.banner.downloadBetaNow": "立即下载桌面 Beta 版", + "home.promo.title": "桌面版标签页现已推出", + "home.promo.body": "使用标签页整理工作和活跃会话。", + "home.promo.cta": "下载最新版本即可开始使用。", + "home.promo.close": "关闭桌面应用公告", + + "home.hero.title": "开源 AI 编程代理", + "home.hero.subtitle.a": "内置免费模型,或连接任意提供商的任意模型,", + "home.hero.subtitle.b": "包括 Claude, GPT, Gemini 等。", + + "home.install.ariaLabel": "安装选项", + + "home.what.title": "什么是 OpenCode?", + "home.what.body": "OpenCode 是一个开源代理,帮助您在终端、IDE 或桌面端编写代码。", + "home.what.lsp.title": "支持 LSP", + "home.what.lsp.body": "为 LLM 自动加载合适的 LSP", + "home.what.multiSession.title": "多会话", + "home.what.multiSession.body": "在同一个项目中并行启动多个代理", + "home.what.shareLinks.title": "分享链接", + "home.what.shareLinks.body": "分享任意会话链接以供参考或调试", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "使用 GitHub 登录以使用您的 Copilot 账户", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "使用 OpenAI 登录以使用您的 ChatGPT Plus 或 Pro 账户", + "home.what.anyModel.title": "任意模型", + "home.what.anyModel.body": "通过 Models.dev 支持 75+ LLM 提供商,包括本地模型", + "home.what.anyEditor.title": "任意编辑器", + "home.what.anyEditor.body": "提供终端界面、桌面应用及 IDE 扩展", + "home.what.readDocs": "阅读文档", + + "home.growth.title": "开源 AI 编程代理", + "home.growth.body": + "拥有超过 {{stars}} 颗 GitHub Star,{{contributors}} 位贡献者,以及超过 {{commits}} 次提交,OpenCode 每月被超过 {{monthlyUsers}} 名开发者使用并信赖。", + "home.growth.githubStars": "GitHub Stars", + "home.growth.contributors": "贡献者", + "home.growth.monthlyDevs": "月活开发者", + + "home.privacy.title": "隐私优先的设计", + "home.privacy.body": "OpenCode 不存储您的任何代码或上下文数据,确保可以在对隐私敏感的环境中运行。", + "home.privacy.learnMore": "了解更多关于", + "home.privacy.link": "隐私", + + "home.faq.q1": "什么是 OpenCode?", + "home.faq.a1": "OpenCode 是一个开源代理,帮助您使用任意 AI 模型编写和运行代码。它提供终端界面、桌面应用及 IDE 扩展。", + "home.faq.q2": "如何使用 OpenCode?", + "home.faq.a2.before": "最简单的入门方式是阅读", + "home.faq.a2.link": "介绍", + "home.faq.q3": "使用 OpenCode 需要额外的 AI 订阅吗?", + "home.faq.a3.p1": "不一定。OpenCode 自带一组免费模型,无需创建账户即可使用。", + "home.faq.a3.p2.beforeZen": "此外,您可以通过创建", + "home.faq.a3.p2.afterZen": "账户来使用流行的编程模型。", + "home.faq.a3.p3": "虽然我们鼓励使用 Zen,但 OpenCode 也支持所有主流提供商,如 OpenAI, Anthropic, xAI 等。", + "home.faq.a3.p4.beforeLocal": "您甚至可以连接您的", + "home.faq.a3.p4.localLink": "本地模型", + "home.faq.q4": "我可以使用现有的 AI 订阅吗?", + "home.faq.a4.p1": + "可以,OpenCode 支持所有主流提供商的订阅计划。您可以使用您的 Claude Pro/Max, ChatGPT Plus/Pro, 或 GitHub Copilot 订阅。", + "home.faq.q5": "OpenCode 只能在终端使用吗?", + "home.faq.a5.beforeDesktop": "不再是了!OpenCode 现在也提供", + "home.faq.a5.desktop": "桌面端应用", + "home.faq.a5.and": "和", + "home.faq.a5.web": "网页端", + "home.faq.q6": "OpenCode 多少钱?", + "home.faq.a6": "OpenCode 是 100% 免费使用的。它还自带一组免费模型。如果您连接其他提供商,可能会产生额外费用。", + "home.faq.q7": "数据和隐私如何?", + "home.faq.a7.p1": "只有当您使用我们的免费模型或创建分享链接时,您的数据和信息才会被存储。", + "home.faq.a7.p2.beforeModels": "了解更多关于", + "home.faq.a7.p2.modelsLink": "我们的模型", + "home.faq.a7.p2.and": "和", + "home.faq.a7.p2.shareLink": "分享页面", + "home.faq.q8": "OpenCode 是开源的吗?", + "home.faq.a8.p1": "是的,OpenCode 是完全开源的。源代码公开在", + "home.faq.a8.p2": "遵循", + "home.faq.a8.mitLicense": "MIT 许可证", + "home.faq.a8.p3": + ",这意味着任何人都可以使用、修改或为它的发展做贡献。社区中的任何人都可以提交 issue、提交 PR 并扩展功能。", + + "home.zenCta.title": "访问可靠、优化的编程代理模型", + "home.zenCta.body": + "Zen 为您提供一组精选的 AI 模型,这些模型经过 OpenCode 专门针对编程代理的测试和基准测试。无需担心不同提供商之间不稳定的性能和质量,直接使用行之有效的验证模型。", + "home.zenCta.link": "了解 Zen", + + "zen.title": "OpenCode Zen | 为编程代理精选的可靠、优化模型", + "zen.hero.title": "为编程代理打造的可靠、优化模型", + "zen.hero.body": + "Zen 为您提供一组精选的 AI 模型,这些模型经过 OpenCode 专门针对编程代理的测试和基准测试。无需担心不稳定的性能和质量,直接使用行之有效的验证模型。", + + "zen.faq.q1": "什么是 OpenCode Zen?", + "zen.faq.a1": "Zen 是一组由 OpenCode 团队创建的,专门针对编程代理进行测试和基准测试的 AI 模型精选集。", + "zen.faq.q2": "为什么 Zen 更准确?", + "zen.faq.a2": + "Zen 仅提供经过专门针对编程代理测试和基准测试的模型。正如你不会用黄油刀切牛排一样,也不要用糟糕的模型来写代码。", + "zen.faq.q3": "Zen 更便宜吗?", + "zen.faq.a3": + "Zen 不以盈利为目的。Zen 将模型提供商的成本直接传递给您。Zen 的使用量越高,OpenCode 就越能协商出更好的费率并回馈给您。", + "zen.faq.q4": "Zen 多少钱?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "按请求收费", + "zen.faq.a4.p1.afterPricing": "零加价,所以您只需支付模型提供商收取的费用。", + "zen.faq.a4.p2.beforeAccount": "您的总费用取决于使用量,且您可以在您的", + "zen.faq.a4.p2.accountLink": "账户中设置每月支出限额", + "zen.faq.a4.p3": "为覆盖成本,OpenCode 仅收取少量支付处理费,每充值 $20 收取 $1.23。", + "zen.faq.q5": "数据和隐私如何?", + "zen.faq.a5.beforeExceptions": "所有 Zen 模型均托管在美国。提供商遵循零留存政策,不使用您的数据进行模型训练,", + "zen.faq.a5.exceptionsLink": "以下例外情况除外", + "zen.faq.q6": "我可以设置支出限额吗?", + "zen.faq.a6": "可以,您可以在账户中设置每月支出限额。", + "zen.faq.q7": "我可以取消吗?", + "zen.faq.a7": "可以,您可以随时禁用计费并使用剩余余额。", + "zen.faq.q8": "我可以在其他编程代理中使用 Zen 吗?", + "zen.faq.a8": + "虽然 Zen 与 OpenCode 配合效果极佳,但您可以在任何代理中使用 Zen。请按照您首选编程代理中的设置说明进行操作。", + "zen.faq.q9": "我可以退款吗?", + "zen.faq.a9": + "如果扣款发生在过去 14 天内,并且您尚未使用该次购买的任何额度,您可能符合退款条件。请{{contact}}申请退款。", + + "zen.cta.start": "开始使用 Zen", + "zen.pricing.title": "充值 $20 (即用即付)", + "zen.pricing.fee": "(+ $1.23 银行卡手续费)", + "zen.pricing.body": "可配合任何代理使用。支持设置月度消费限额。随时取消。", + "zen.problem.title": "Zen 解决了什么问题?", + "zen.problem.body": "市面上有太多模型,但只有少数能与编程代理良好配合。大多数提供商配置不同,导致结果参差不齐。", + "zen.problem.subtitle": "我们要为所有人解决这个问题,不仅仅是 OpenCode 用户。", + "zen.problem.item1": "测试精选模型并咨询其团队", + "zen.problem.item2": "与提供商合作确保正确交付", + "zen.problem.item3": "对所有推荐的模型-提供商组合进行基准测试", + "zen.how.title": "Zen 如何工作", + "zen.how.body": "虽然我们建议您配合 OpenCode 使用 Zen,但您也可以将其用于任何代理。", + "zen.how.step1.title": "注册并充值 $20", + "zen.how.step1.beforeLink": "遵循", + "zen.how.step1.link": "设置说明", + "zen.how.step2.title": "使用 Zen,价格透明", + "zen.how.step2.link": "按请求付费", + "zen.how.step2.afterLink": "零加价", + "zen.how.step3.title": "自动充值", + "zen.how.step3.body": "当您的余额低于 $5 时,我们将自动充值 $20", + "zen.privacy.title": "您的隐私对我们很重要", + "zen.privacy.beforeExceptions": "所有 Zen 模型均托管在美国。提供商遵循零留存政策,不使用您的数据进行模型训练,", + "zen.privacy.exceptionsLink": "以下例外情况除外", + + "go.title": "OpenCode Go | 人人可用的低成本编程模型", + "go.meta.description": "Go 每月 $10,提供充裕的使用限额,并可可靠访问领先的编程模型。", + "go.hero.title": "人人可用的低成本编程模型", + "go.hero.body": + "Go 将代理编程带给全世界的程序员。提供充裕的限额和对最强大的开源模型的可靠访问,让您可以利用强大的代理进行构建,而无需担心成本或可用性。", + + "go.cta.start": "订阅 Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "订阅 Go", + "go.cta.price": "$10/月", + "go.pricing.body": "可配合任何代理使用。每月 $10。如有需要可充值。随时取消。", + "go.graph.free": "免费", + "go.graph.freePill": "Big Pickle 和免费模型", + "go.graph.go": "Go", + "go.graph.label": "每 5 小时请求数", + "go.graph.period": "使用额度", + "go.graph.model": "模型", + "go.graph.requests": "预估请求数 / 5 小时", + "go.graph.allowance": "每月使用额度", + "go.graph.new": "新", + "go.graph.scale": "请求数采用非线性刻度", + "go.graph.showAll": "查看全部 {{count}} 个模型", + "go.graph.showLess": "收起模型", + "go.graph.limitedRegions": "仅限部分地区", + "go.graph.limitedTime": "限时", + "go.graph.usageLimits": "使用限制", + "go.graph.aria": "每 5 小时请求数: {{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "前 CEO, Terminal Products", + "go.testimonials.dax.quoteAfter": "彻底改变了我的生活,这绝对是不二之选。", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "前创始人, SEED, PM, Melt, Pop, Dapt, Cadmus, 和 ViewPoint", + "go.testimonials.jay.quoteBefore": "我们团队 5 个人里有 4 个都爱用", + "go.testimonials.jay.quoteAfter": "。", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "前 Hero, AWS", + "go.testimonials.adam.quoteBefore": "我强烈推荐", + "go.testimonials.adam.quoteAfter": "。真的,非常好用。", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "前设计主管, Laravel", + "go.testimonials.david.quoteBefore": "有了", + "go.testimonials.david.quoteAfter": "我知道所有模型都经过测试,非常适合编程代理。", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "前实习生, Nvidia (4 次)", + "go.testimonials.frank.quote": "我希望我还在 Nvidia。", + "go.problem.title": "Go 解决了什么问题?", + "go.problem.body": + "我们致力于将 OpenCode 体验带给尽可能多的人。OpenCode Go 是一款每月 $10 的低成本订阅服务。它提供充裕的额度,并让您能可靠地使用最强大的开源模型。", + "go.problem.subtitle": " ", + "go.problem.item1": "低成本订阅定价", + "go.problem.item2": "充裕的限额和可靠的访问", + "go.problem.item3": "为尽可能多的程序员打造", + "go.problem.item4": "经过代理编程测试的精选模型阵容", + "go.how.title": "Go 如何工作", + "go.how.body": "Go 每月 $10。您可以将其与 OpenCode 或任何代理搭配使用。", + "go.how.step1.title": "创建账户", + "go.how.step1.beforeLink": "遵循", + "go.how.step1.link": "设置说明", + "go.how.step2.title": "订阅 Go", + "go.how.step2.link": "每月 $10", + "go.how.step2.afterLink": "额度充裕", + "go.how.step3.title": "开始编程", + "go.how.step3.body": "可靠访问开源模型", + "go.privacy.title": "您的隐私对我们很重要", + "go.privacy.body": "该计划主要面向国际用户设计,模型部署在美国、欧盟和新加坡,以确保稳定的全球访问。", + "go.privacy.contactAfter": "如果您有任何问题。", + "go.privacy.beforeExceptions": "Go 模型托管在美国。提供商遵循零留存政策,不使用您的数据进行模型训练,", + "go.privacy.exceptionsLink": "以下例外情况除外", + "go.faq.q1": "什么是 OpenCode Go?", + "go.faq.a1": "Go 是一项低成本订阅服务,为您提供对强大的开源模型的可靠访问,用于代理编程。", + "go.faq.q2": "Go 包含哪些模型?", + "go.faq.a2": "Go 包含下方列出的模型,提供充足的限额和可靠的访问。", + "go.faq.q3": "Go 和 Zen 一样吗?", + "go.faq.a3": "不。Zen 是按量付费,而 Go 每月 $10,提供充裕的限额,并可可靠访问精选模型阵容。", + "go.faq.q4": "Go 多少钱?", + "go.faq.a4.p1.beforePricing": "Go 费用为", + "go.faq.a4.p1.pricingLink": "每月 $10", + "go.faq.a4.p1.afterPricing": "额度充裕。", + "go.faq.a4.p2.beforeAccount": "您可以在您的", + "go.faq.a4.p2.accountLink": "账户", + "go.faq.a4.p3": "中管理订阅。随时取消。", + "go.faq.q5": "数据和隐私如何?", + "go.faq.a5.model": "模型", + "go.faq.a5.training": "模型训练", + "go.faq.a5.retention": "数据留存", + "go.faq.a5.retention30": "30 天", + "go.faq.a5.retention0": "0 天", + "go.faq.a5.used": "使用", + "go.faq.a5.notUsed": "不使用", + "go.faq.a5.noAgreement": "无协议", + "go.faq.a5.notZdr": "非 ZDR", + "go.faq.a5.grokRetention": + "ZDR 会禁用依赖所存储数据的重要 API 功能,包括有状态的 Responses API、Files and Collections 和 Batch API。", + "go.faq.a5.gptRetention": "所有 API 功能的使用都会生成滥用监控日志,并最多保留 30 天。", + "go.faq.a5.museRetention": "以允许使用你的提示词和补全结果训练未来的 Meta 模型为交换,token 价格可获得大幅折扣。", + "go.faq.a5.learnMore": "了解更多", + "go.faq.a5.deepseekRetention": "ZDR 协议每月续签。当前协议有效期至 2026 年 9 月 30 日。", + "go.faq.a5.beforeExceptions": "Go 模型托管在美国。提供商遵循零留存政策,不使用您的数据进行模型训练,", + "go.faq.a5.exceptionsLink": "以下例外情况除外", + "go.faq.q6": "我可以充值余额吗?", + "go.faq.a6": "如果您需要更多用量,可以在账户中充值余额。", + "go.faq.q7": "我可以取消吗?", + "go.faq.a7": "可以,您可以随时取消。", + "go.faq.q8": "我可以在其他编程代理中使用 Go 吗?", + "go.faq.a8": "可以,您可以在任何代理中使用 Go。请遵循您首选编程代理中的设置说明。", + + "go.faq.q9": "免费模型和 Go 之间的区别是什么?", + "go.faq.a9": + "免费模型包含 Big Pickle 加上当时可用的促销模型,每天有 200 次请求的配额。Go 提供精选模型阵容,并在滚动窗口(5 小时、每周和每月)内执行更高的请求配额,大致相当于每 5 小时 $12、每周 $30 和每月 $60 的基础额度;具体额度可能因模型而异(实际请求计数因模型和使用情况而异)。", + "go.faq.q10": "我可以退款吗?", + "go.faq.a10": + "如果扣款发生在过去 14 天内,并且您在该计费周期内尚未使用任何 Go 额度,您可能符合退款条件。请{{contact}}申请退款。", + + "zen.api.error.rateLimitExceeded": "超出速率限制。请稍后重试。", + "zen.api.error.modelNotSupported": "不支持模型 {{model}}", + "zen.api.error.modelFormatNotSupported": "格式 {{format}} 不支持模型 {{model}}", + "zen.api.error.noProviderAvailable": "没有可用的提供商", + "zen.api.error.providerNotSupported": "不支持提供商 {{provider}}", + "zen.api.error.missingApiKey": "缺少 API 密钥。", + "zen.api.error.invalidApiKey": "无效的 API 密钥。", + "zen.api.error.requestBlockedByUpstreamProvider": "请求被上游提供商阻止。", + "zen.api.error.subscriptionQuotaExceeded": "超出订阅配额。请在 {{retryIn}} 后重试。", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "已达到 5 小时使用限额。将在 {{retryIn}} 后重置。如需立即继续使用该模型,请启用从可用余额扣费:{{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "已达到每周使用限额。将在 {{retryIn}} 后重置。如需立即继续使用该模型,请启用从可用余额扣费:{{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "已达到每月使用限额。将在 {{retryIn}} 后重置。如需立即继续使用该模型,请启用从可用余额扣费:{{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "没有付款方式。请在此处添加付款方式:{{billingUrl}}", + "zen.api.error.insufficientBalance": "余额不足。请在此处管理您的计费:{{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "您的工作区已达到每月支出限额 ${{amount}}。请在此处管理您的限额:{{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": "您已达到每月支出限额 ${{amount}}。请在此处管理您的限额:{{membersUrl}}", + "zen.api.error.modelDisabled": "模型已禁用", + "zen.api.error.regionNotAllowed": "该模型的最新版本仅在中国提供托管服务,需明确选择启用:{{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "该模型在你所在的国家或地区不可用。", + "zen.api.error.trainingNotAllowed": "该模型会收集用于提升其质量的数据,使用前需要你明确同意:{{consoleGoUrl}}", + "zen.api.error.trialEnded": "{{model}} 的限免活动已结束。您可以订阅 OpenCode Go 继续使用该模型 - {{link}}", + + "black.meta.title": "OpenCode Black | 访问全球顶尖编程模型", + "black.meta.description": "通过 OpenCode Black 订阅计划使用 Claude, GPT, Gemini 等模型。", + "black.hero.title": "访问全球顶尖编程模型", + "black.hero.subtitle": "包括 Claude, GPT, Gemini 等", + "black.title": "OpenCode Black | 定价", + "black.paused": "Black 订阅已暂时暂停注册。", + "black.plan.icon20": "Black 20 计划", + "black.plan.icon100": "Black 100 计划", + "black.plan.icon200": "Black 200 计划", + "black.plan.multiplier100": "用量是 Black 20 的 5 倍", + "black.plan.multiplier200": "用量是 Black 20 的 20 倍", + "black.price.perMonth": "/ 月", + "black.price.perPersonBilledMonthly": "每人每月", + "black.terms.1": "您的订阅不会立即开始", + "black.terms.2": "您将被加入候补名单,并很快激活", + "black.terms.3": "您的卡只会在订阅激活时扣费", + "black.terms.4": "适用使用限制,高度自动化的使用可能会更快达到限制", + "black.terms.5": "订阅仅限个人,团队请联系企业版", + "black.terms.6": "未来可能会调整限制或停止计划", + "black.terms.7": "随时取消订阅", + "black.action.continue": "继续", + "black.finePrint.beforeTerms": "显示价格不含税", + "black.finePrint.terms": "服务条款", + "black.workspace.title": "OpenCode Black | 选择工作区", + "black.workspace.selectPlan": "为此计划选择一个工作区", + "black.workspace.name": "工作区 {{n}}", + "black.subscribe.title": "订阅 OpenCode Black", + "black.subscribe.paymentMethod": "付款方式", + "black.subscribe.loadingPaymentForm": "正在加载付款表单...", + "black.subscribe.selectWorkspaceToContinue": "选择一个工作区以继续", + "black.subscribe.failurePrefix": "哎呀!", + "black.subscribe.error.generic": "发生错误", + "black.subscribe.error.invalidPlan": "无效的计划", + "black.subscribe.error.workspaceRequired": "缺少工作区 ID", + "black.subscribe.error.alreadySubscribed": "此工作区已有订阅", + "black.subscribe.processing": "处理中...", + "black.subscribe.submit": "订阅 ${{plan}}", + "black.subscribe.form.chargeNotice": "您的卡只会在订阅激活时扣费", + "black.subscribe.success.title": "您已加入 OpenCode Black 候补名单", + "black.subscribe.success.subscriptionPlan": "订阅计划", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "金额", + "black.subscribe.success.amountValue": "${{plan}} / 月", + "black.subscribe.success.paymentMethod": "付款方式", + "black.subscribe.success.dateJoined": "加入日期", + "black.subscribe.success.chargeNotice": "您的卡将在订阅激活时扣费", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "使用量", + "workspace.nav.apiKeys": "API 密钥", + "workspace.nav.members": "成员", + "workspace.nav.billing": "计费", + "workspace.nav.settings": "设置", + + "workspace.home.banner.beforeLink": "可靠、优化的编程代理模型。", + "workspace.lite.banner.beforeLink": "低成本编码模型,人人可用。", + "workspace.home.billing.loading": "加载中...", + "workspace.home.billing.enable": "启用计费", + "workspace.home.billing.currentBalance": "当前余额", + + "workspace.newUser.feature.tested.title": "经过测试与验证的模型", + "workspace.newUser.feature.tested.body": "我们专门针对编程代理对模型进行了基准测试和测试,以确保最佳性能。", + "workspace.newUser.feature.quality.title": "最高质量", + "workspace.newUser.feature.quality.body": "访问配置为最佳性能的模型 - 无需降级或路由到更便宜的提供商。", + "workspace.newUser.feature.lockin.title": "无锁定", + "workspace.newUser.feature.lockin.body": + "将 Zen 与任何编程代理结合使用,并在需要时继续在 OpenCode 中使用其他提供商。", + "workspace.newUser.copyApiKey": "复制 API 密钥", + "workspace.newUser.copyKey": "复制密钥", + "workspace.newUser.copied": "已复制!", + "workspace.newUser.step.enableBilling": "启用计费", + "workspace.newUser.step.login.before": "运行", + "workspace.newUser.step.login.after": "并选择 OpenCode", + "workspace.newUser.step.pasteKey": "粘贴您的 API 密钥", + "workspace.newUser.step.models.before": "启动 OpenCode 并运行", + "workspace.newUser.step.models.after": "以选择模型", + + "workspace.models.title": "模型", + "workspace.models.subtitle.beforeLink": "管理工作区成员可以访问哪些模型。", + "workspace.models.table.model": "模型", + "workspace.models.table.enabled": "已启用", + + "workspace.providers.title": "自带密钥 (BYOK)", + "workspace.providers.subtitle": "配置您自己的 AI 提供商 API 密钥。", + "workspace.providers.placeholder": "输入 {{provider}} API 密钥 ({{prefix}}...)", + "workspace.providers.configure": "配置", + "workspace.providers.edit": "编辑", + "workspace.providers.delete": "删除", + "workspace.providers.saving": "正在保存...", + "workspace.providers.save": "保存", + "workspace.providers.table.provider": "提供商", + "workspace.providers.table.apiKey": "API 密钥", + + "workspace.usage.title": "使用历史", + "workspace.usage.subtitle": "近期 API 使用情况和成本。", + "workspace.usage.empty": "发起第一个 API 调用以开始。", + "workspace.usage.table.date": "日期", + "workspace.usage.table.model": "模型", + "workspace.usage.table.input": "输入", + "workspace.usage.table.output": "输出", + "workspace.usage.table.cost": "成本", + "workspace.usage.table.session": "会话", + "workspace.usage.breakdown.input": "输入", + "workspace.usage.breakdown.cacheRead": "缓存读取", + "workspace.usage.breakdown.cacheWrite": "缓存写入", + "workspace.usage.breakdown.output": "输出", + "workspace.usage.breakdown.reasoning": "推理", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "成本", + "workspace.cost.subtitle": "按模型细分的使用成本。", + "workspace.cost.allModels": "所有模型", + "workspace.cost.allKeys": "所有密钥", + "workspace.cost.deletedSuffix": "(已删除)", + "workspace.cost.empty": "所选期间无可用使用数据。", + "workspace.cost.subscriptionShort": "订阅", + + "workspace.keys.title": "API 密钥", + "workspace.keys.subtitle": "管理访问 OpenCode 服务的 API 密钥。", + "workspace.keys.create": "创建 API 密钥", + "workspace.keys.placeholder": "输入密钥名称", + "workspace.keys.empty": "创建 OpenCode 网关 API 密钥", + "workspace.keys.table.name": "名称", + "workspace.keys.table.key": "密钥", + "workspace.keys.table.createdBy": "创建者", + "workspace.keys.table.lastUsed": "最后使用", + "workspace.keys.copyApiKey": "复制 API 密钥", + "workspace.keys.delete": "删除", + + "workspace.members.title": "成员", + "workspace.members.subtitle": "管理工作区成员及其权限。", + "workspace.members.invite": "邀请成员", + "workspace.members.inviting": "正在邀请...", + "workspace.members.beta.beforeLink": "Beta 期间工作区对团队免费。", + "workspace.members.form.invitee": "受邀者", + "workspace.members.form.emailPlaceholder": "输入电子邮箱", + "workspace.members.form.role": "角色", + "workspace.members.form.monthlyLimit": "每月消费限额", + "workspace.members.noLimit": "无限制", + "workspace.members.noLimitLowercase": "无限制", + "workspace.members.invited": "已邀请", + "workspace.members.edit": "编辑", + "workspace.members.delete": "删除", + "workspace.members.saving": "正在保存...", + "workspace.members.save": "保存", + "workspace.members.table.email": "邮箱", + "workspace.members.table.role": "角色", + "workspace.members.table.monthLimit": "月限额", + "workspace.members.role.admin": "管理员", + "workspace.members.role.adminDescription": "可以管理模型、成员和计费", + "workspace.members.role.member": "成员", + "workspace.members.role.memberDescription": "只能为自己生成 API 密钥", + + "workspace.settings.title": "设置", + "workspace.settings.subtitle": "更新您的工作区名称和偏好。", + "workspace.settings.workspaceName": "工作区名称", + "workspace.settings.defaultName": "默认", + "workspace.settings.updating": "正在更新...", + "workspace.settings.save": "保存", + "workspace.settings.edit": "编辑", + + "workspace.billing.title": "计费", + "workspace.billing.subtitle.beforeLink": "管理付款方式。", + "workspace.billing.contactUs": "联系我们", + "workspace.billing.subtitle.afterLink": "如果您有任何问题。", + "workspace.billing.currentBalance": "当前余额", + "workspace.billing.add": "充值 $", + "workspace.billing.enterAmount": "输入金额", + "workspace.billing.loading": "加载中...", + "workspace.billing.addAction": "充值", + "workspace.billing.addBalance": "充值余额", + "workspace.billing.alipay": "支付宝", + "workspace.billing.wechat": "微信支付", + "workspace.billing.linkedToStripe": "已关联 Stripe", + "workspace.billing.manage": "管理", + "workspace.billing.enable": "启用计费", + + "workspace.monthlyLimit.title": "每月限额", + "workspace.monthlyLimit.subtitle": "为您的账户设置每月使用限额。", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "正在设置...", + "workspace.monthlyLimit.set": "设置", + "workspace.monthlyLimit.edit": "编辑限额", + "workspace.monthlyLimit.noLimit": "未设置使用限额。", + "workspace.monthlyLimit.currentUsage.beforeMonth": "当前", + "workspace.monthlyLimit.currentUsage.beforeAmount": "的使用量为 $", + + "workspace.redeem.title": "兑换优惠券", + "workspace.redeem.subtitle": "兑换优惠码以领取充值额度或权益。", + "workspace.redeem.placeholder": "输入优惠码", + "workspace.redeem.redeem": "兑换", + "workspace.redeem.redeeming": "兑换中...", + "workspace.redeem.success": "优惠券兑换成功。", + + "workspace.reload.title": "自动充值", + "workspace.reload.disabled.before": "自动充值已", + "workspace.reload.disabled.state": "禁用", + "workspace.reload.disabled.after": "启用后将在余额不足时自动充值。", + "workspace.reload.enabled.before": "自动充值已", + "workspace.reload.enabled.state": "启用", + "workspace.reload.enabled.middle": "我们将自动充值", + "workspace.reload.processingFee": "手续费", + "workspace.reload.enabled.after": "当余额达到", + "workspace.reload.edit": "编辑", + "workspace.reload.enable": "启用", + "workspace.reload.enableAutoReload": "启用自动充值", + "workspace.reload.reloadAmount": "充值 $", + "workspace.reload.whenBalanceReaches": "当余额达到 $", + "workspace.reload.saving": "正在保存...", + "workspace.reload.save": "保存", + "workspace.reload.failedAt": "充值失败于", + "workspace.reload.reason": "原因:", + "workspace.reload.updatePaymentMethod": "请更新您的付款方式并重试。", + "workspace.reload.retrying": "正在重试...", + "workspace.reload.retry": "重试", + "workspace.reload.error.paymentFailed": "支付失败。", + + "workspace.payments.title": "支付历史", + "workspace.payments.subtitle": "近期支付交易。", + "workspace.payments.table.date": "日期", + "workspace.payments.table.paymentId": "支付 ID", + "workspace.payments.table.amount": "金额", + "workspace.payments.table.receipt": "收据", + "workspace.payments.type.credit": "充值", + "workspace.payments.type.subscription": "订阅", + "workspace.payments.view": "查看", + + "workspace.black.loading": "加载中...", + "workspace.black.time.day": "天", + "workspace.black.time.days": "天", + "workspace.black.time.hour": "小时", + "workspace.black.time.hours": "小时", + "workspace.black.time.minute": "分钟", + "workspace.black.time.minutes": "分钟", + "workspace.black.time.fewSeconds": "几秒钟", + "workspace.black.subscription.title": "订阅", + "workspace.black.subscription.message": "您已订阅 OpenCode Black,价格为每月 ${{plan}}。", + "workspace.black.subscription.manage": "管理订阅", + "workspace.black.subscription.rollingUsage": "5 小时用量", + "workspace.black.subscription.weeklyUsage": "每周用量", + "workspace.black.subscription.resetsIn": "重置于", + "workspace.black.subscription.useBalance": "达到使用限额后使用您的可用余额", + "workspace.black.waitlist.title": "候补名单", + "workspace.black.waitlist.joined": "您已加入每月 ${{plan}} 的 OpenCode Black 计划候补名单。", + "workspace.black.waitlist.ready": "我们已准备好将您加入每月 ${{plan}} 的 OpenCode Black 计划。", + "workspace.black.waitlist.leave": "退出候补名单", + "workspace.black.waitlist.leaving": "正在退出...", + "workspace.black.waitlist.left": "已退出", + "workspace.black.waitlist.enroll": "加入", + "workspace.black.waitlist.enrolling": "正在加入...", + "workspace.black.waitlist.enrolled": "已加入", + "workspace.black.waitlist.enrollNote": "点击加入后,您的订阅将立即开始,并将从您的卡中扣费。", + + "workspace.lite.loading": "加载中...", + "workspace.lite.time.day": "天", + "workspace.lite.time.days": "天", + "workspace.lite.time.hour": "小时", + "workspace.lite.time.hours": "小时", + "workspace.lite.time.minute": "分钟", + "workspace.lite.time.minutes": "分钟", + "workspace.lite.time.fewSeconds": "几秒钟", + "workspace.lite.subscription.message": "您已订阅 OpenCode Go。", + "workspace.lite.subscription.manage": "管理订阅", + "workspace.lite.subscription.rollingUsage": "5 小时用量", + "workspace.lite.subscription.rollingQuota": "5 小时配额", + "workspace.lite.subscription.weeklyUsage": "每周用量", + "workspace.lite.subscription.weeklyQuota": "每周配额", + "workspace.lite.subscription.monthlyUsage": "每月用量", + "workspace.lite.subscription.monthlyQuota": "每月配额", + "workspace.lite.subscription.resetsIn": "重置于", + "workspace.lite.subscription.showDetails": "显示详情", + "workspace.lite.subscription.hideDetails": "隐藏详情", + "workspace.lite.subscription.model": "模型", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "总计", + "workspace.lite.subscription.useBalance": "达到使用限额后使用您的可用余额", + "workspace.lite.subscription.selectProvider": + "在你的 opencode 配置中选择「OpenCode Go」作为提供商,即可使用 Go 模型。", + "workspace.lite.providers.title": "提供商", + "workspace.lite.providers.description": "控制用于路由的提供商。", + "workspace.lite.providers.allowTraining": "允许使用请求数据进行训练的模型", + "workspace.lite.providers.useChina": "启用部署在中国的模型", + "workspace.lite.black.message": "您当前已订阅 OpenCode Black 或在候补名单中。如需切换到 Go,请先取消订阅。", + "workspace.lite.other.message": "此工作区中的另一位成员已经订阅了 OpenCode Go。每个工作区只有一名成员可以订阅。", + "workspace.lite.promo.description": + "OpenCode Go 每月 {{price}},并提供对流行开放编码模型的可靠访问,同时享有充裕的使用限额。", + "workspace.lite.promo.price": "$10/月", + "workspace.lite.promo.modelsTitle": "包含模型", + "workspace.lite.promo.footer": + "该计划主要面向国际用户,提供稳定的全球访问体验。随着我们持续了解早期使用情况并收集反馈,定价和使用限额可能会有所调整。", + "workspace.lite.promo.subscribe": "订阅 Go", + "workspace.lite.promo.subscribing": "正在重定向...", + "workspace.lite.promo.otherMethods": "其他付款方式", + "workspace.lite.promo.selectMethod": "选择付款方式", + + "workspace.referral.copyLink": "复制链接", + "workspace.referral.copied": "已复制", + "workspace.referral.overview.title": "邀请好友", + "workspace.referral.overview.subtitle": "好友订阅后,您可获得 $5,对方也可获得 $5。", + "workspace.referral.instructions.share": "分享您的推荐链接。", + "workspace.referral.instructions.subscribe": "好友加入并订阅 Go。", + "workspace.referral.instructions.claim": "你们都将获得 $5 使用额度,可用于您的 Go 使用限额。", + "workspace.referral.rewards.title": "邀请奖励", + "workspace.referral.rewards.description": "将可用的邀请积分应用到您的 Go 用量。", + "workspace.referral.rewards.subtitle": "已使用 {{applied}} / {{total}} 个奖励。", + "workspace.referral.rewards.empty": "暂无邀请奖励。", + "workspace.referral.table.reward": "奖励", + "workspace.referral.table.referral": "描述", + "workspace.referral.table.date": "日期", + "workspace.referral.reward.description.inviter": "已邀请 {{email}}", + "workspace.referral.reward.description.invitee": "由 {{email}} 邀请", + "workspace.referral.reward.action.subscribeUnlock": "订阅以解锁", + "workspace.referral.reward.action.view": "查看奖励", + "workspace.referral.reward.action.applied": "奖励已使用", + "workspace.referral.reward.source.pendingInviter": "等待对方订阅", + "workspace.referral.reward.source.pendingInvitee": "订阅即可解锁奖励", + "workspace.referral.reward.source.available": "奖励可使用", + "workspace.referral.reward.source.applied": "奖励已使用", + "workspace.referral.reward.status.applied": "奖励已使用", + "workspace.referral.reward.status.pendingInviter": "订阅以解锁", + "workspace.referral.reward.status.pendingInvitee": "订阅以解锁", + "workspace.referral.apply.noGo": "订阅以解锁", + "workspace.referral.apply.preview": "查看奖励", + "workspace.referral.apply.action": "使用", + "workspace.referral.apply.confirmTitle": "使用奖励", + "workspace.referral.apply.confirmBody": "使用 {{amount}} 抵扣当前工作区的用量。", + "workspace.referral.apply.confirmAction": "使用", + + "download.title": "OpenCode | 下载", + "download.meta.description": "下载适用于 macOS, Windows, 和 Linux 的 OpenCode", + "download.hero.title": "下载 OpenCode 桌面版", + "download.hero.subtitle": "适用于 macOS, Windows, 和 Linux 的 Beta 版", + "download.hero.button": "下载 {{os}} 版", + "download.section.terminal": "OpenCode 终端", + "download.section.desktop": "OpenCode 桌面版", + "download.section.extensions": "OpenCode 扩展", + "download.section.integrations": "OpenCode 集成", + "download.action.download": "下载", + "download.action.install": "安装", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "不一定,但可能需要。如果您想将 OpenCode 连接到付费提供商,您需要 AI 订阅,尽管您可以配合", + "download.faq.a3.localLink": "本地模型", + "download.faq.a3.afterLocal.beforeZen": "免费使用。虽然我们鼓励用户使用", + "download.faq.a3.afterZen": ",但 OpenCode 支持所有主流提供商,如 OpenAI, Anthropic, xAI 等。", + + "download.faq.a5.p1": "OpenCode 是 100% 免费使用的。", + "download.faq.a5.p2.beforeZen": + "任何额外费用都来自您对模型提供商的订阅。虽然 OpenCode 支持任何模型提供商,但我们建议使用", + "download.faq.a5.p2.afterZen": "。", + + "download.faq.a6.p1": "只有当您在 OpenCode 中创建分享链接时,您的数据和信息才会被存储。", + "download.faq.a6.p2.beforeShare": "了解更多关于", + "download.faq.a6.shareLink": "分享页面", + + "enterprise.title": "OpenCode | 面向组织的 OpenCode 企业版解决方案", + "enterprise.meta.description": "联系 OpenCode 获取企业版解决方案", + "enterprise.hero.title": "您的代码属于您", + "enterprise.hero.body1": + "OpenCode 在您的组织内部安全运行,不存储任何数据或上下文,也没有许可限制或所有权主张。您可以先与团队开始试用,然后通过集成 SSO 和内部 AI 网关将其部署到整个组织。", + "enterprise.hero.body2": "告诉我们如何为您提供帮助。", + "enterprise.form.name.label": "全名", + "enterprise.form.name.placeholder": "Jeff Bezos", + "enterprise.form.role.label": "角色", + "enterprise.form.role.placeholder": "执行主席", + "enterprise.form.company.label": "公司", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "公司邮箱", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "电话号码", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "您想解决什么问题?", + "enterprise.form.message.placeholder": "我们需要帮助...", + "enterprise.form.send": "发送", + "enterprise.form.sending": "正在发送...", + "enterprise.form.success": "消息已发送,我们会尽快与您联系。", + "enterprise.form.success.submitted": "表单提交成功。", + "enterprise.form.error.allFieldsRequired": "所有字段均为必填项。", + "enterprise.form.error.invalidEmailFormat": "邮箱格式无效。", + "enterprise.form.error.internalServer": "内部服务器错误。", + "enterprise.faq.title": "常见问题", + "enterprise.faq.q1": "什么是 OpenCode 企业版?", + "enterprise.faq.a1": + "OpenCode 企业版专为那些希望确保代码和数据永远不离开其基础设施的组织而设计。它通过使用集中式配置,与您的 SSO 和内部 AI 网关集成来实现这一点。", + "enterprise.faq.q2": "如何开始使用 OpenCode 企业版?", + "enterprise.faq.a2": + "只需从您的团队内部试用开始即可。OpenCode 默认不存储您的代码或上下文数据,使得入门非常容易。然后联系我们讨论定价和实施选项。", + "enterprise.faq.q3": "企业版定价如何运作?", + "enterprise.faq.a3": + "我们提供按席位计费的企业定价。如果您拥有自己的 LLM 网关,我们不收取 token 使用费。如需了解更多详情,请联系我们获取基于您组织需求的定制报价。", + "enterprise.faq.q4": "OpenCode 企业版安全吗?", + "enterprise.faq.a4": + "是的。OpenCode 不存储您的代码或上下文数据。所有处理均在本地进行,或通过直接 API 调用您的 AI 提供商。通过集中配置和 SSO 集成,您的数据始终保留在您组织的基础设施内。", + + "brand.title": "OpenCode | 品牌", + "brand.meta.description": "OpenCode 品牌指南", + "brand.heading": "品牌指南", + "brand.subtitle": "帮助您使用 OpenCode 品牌的资源和资产。", + "brand.downloadAll": "下载所有资产", + + "changelog.title": "OpenCode | 更新日志", + "changelog.meta.description": "OpenCode 发布说明和更新日志", + "changelog.hero.title": "更新日志", + "changelog.hero.subtitle": "OpenCode 的新更新和改进", + "changelog.empty": "未找到更新日志条目。", + "changelog.viewJson": "查看 JSON", + + "bench.list.title": "基准测试", + "bench.list.heading": "基准测试", + "bench.list.table.agent": "代理", + "bench.list.table.model": "模型", + "bench.list.table.score": "分数", + "bench.submission.error.allFieldsRequired": "所有字段均为必填项。", + + "bench.detail.title": "基准测试 - {{task}}", + "bench.detail.notFound": "未找到任务", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "代理", + "bench.detail.labels.model": "模型", + "bench.detail.labels.task": "任务", + "bench.detail.labels.repo": "仓库", + "bench.detail.labels.from": "来源", + "bench.detail.labels.to": "目标", + "bench.detail.labels.prompt": "提示词", + "bench.detail.labels.commit": "Commit", + "bench.detail.labels.averageDuration": "平均耗时", + "bench.detail.labels.averageScore": "平均分数", + "bench.detail.labels.averageCost": "平均成本", + "bench.detail.labels.summary": "摘要", + "bench.detail.labels.runs": "运行次数", + "bench.detail.labels.score": "分数", + "bench.detail.labels.base": "基础", + "bench.detail.labels.penalty": "惩罚", + "bench.detail.labels.weight": "权重", + "bench.detail.table.run": "运行", + "bench.detail.table.score": "分数 (基础 - 惩罚)", + "bench.detail.table.cost": "成本", + "bench.detail.table.duration": "耗时", + "bench.detail.run.title": "运行 {{n}}", + "bench.detail.rawJson": "原始 JSON", +} satisfies Dict diff --git a/packages/console/app/src/i18n/zht.ts b/packages/console/app/src/i18n/zht.ts new file mode 100644 index 0000000000000000000000000000000000000000..a4a5f4bd4a73775a74f5e2964a915e9d72a36a18 --- /dev/null +++ b/packages/console/app/src/i18n/zht.ts @@ -0,0 +1,842 @@ +import type { Dict } from "./en" +import { dict as en } from "./en" + +export const dict = { + ...en, + "go.promo.deepseek": "DeepSeek V4.1 Flash 限時享有 4 倍使用額度", + "go.graph.bonus": "{{count}} 倍用量", + "nav.github": "GitHub", + "nav.docs": "文件", + "nav.changelog": "更新日誌", + "nav.discord": "Discord", + "nav.x": "X", + "nav.enterprise": "企業", + "nav.zen": "Zen", + "nav.login": "登入", + "nav.free": "下載", + "nav.home": "首頁", + "nav.openMenu": "開啟選單", + "nav.getStartedFree": "免費開始使用", + "nav.logoAlt": "OpenCode", + + "nav.context.copyLogo": "複製標誌(SVG)", + "nav.context.copyWordmark": "複製字標(SVG)", + "nav.context.brandAssets": "品牌資產", + + "footer.github": "GitHub", + "footer.docs": "文件", + "footer.changelog": "更新日誌", + "footer.feishu": "飞书", + "footer.discord": "Discord", + "footer.x": "X", + + "legal.brand": "品牌", + "legal.privacy": "隱私", + "legal.terms": "條款", + + "email.title": "第一時間獲取我們發布新產品的消息", + "email.subtitle": "加入候補名單,搶先體驗。", + "email.placeholder": "電子郵件地址", + "email.subscribe": "訂閱", + "email.success": "就差一步,請查收你的信箱並確認電子郵件地址", + + "notFound.title": "找不到頁面 | OpenCode", + "notFound.heading": "404 - 找不到頁面", + "notFound.home": "首頁", + "notFound.docs": "文件", + "notFound.github": "GitHub", + "notFound.discord": "Discord", + "notFound.logoLightAlt": "opencode 淺色標誌", + "notFound.logoDarkAlt": "opencode 深色標誌", + + "user.logout": "登出", + + "auth.callback.error.codeMissing": "找不到授權碼。", + + "workspace.select": "選取工作區", + "workspace.createNew": "+ 建立新工作區", + "workspace.modal.title": "建立新工作區", + "workspace.modal.placeholder": "輸入工作區名稱", + + "common.cancel": "取消", + "common.creating": "正在建立...", + "common.create": "建立", + "common.contactUs": "聯絡我們", + + "common.videoUnsupported": "你的瀏覽器不支援 video 標籤。", + "common.figure": "圖 {{n}}.", + "common.faq": "常見問題", + "common.learnMore": "了解更多", + + "error.invalidPlan": "無效的方案", + "error.workspaceRequired": "需要工作區 ID", + "error.alreadySubscribed": "此工作區已有訂閱", + "error.limitRequired": "需要設定限額。", + "error.monthlyLimitInvalid": "請設定有效的每月限額。", + "error.workspaceNameRequired": "需要工作區名稱。", + "error.nameTooLong": "名稱長度不能超過 255 個字元。", + "error.emailRequired": "需要電子郵件", + "error.roleRequired": "需要角色", + "error.idRequired": "需要 ID", + "error.nameRequired": "需要名稱", + "error.providerRequired": "需要供應商", + "error.apiKeyRequired": "需要 API 金鑰", + "error.modelRequired": "需要模型", + "error.reloadAmountMin": "儲值金額必須至少為 ${{amount}}", + "error.reloadTriggerMin": "餘額觸發門檻必須至少為 ${{amount}}", + + "app.meta.description": "OpenCode - 開源編碼代理。", + + "home.title": "OpenCode | 開源 AI 編碼代理", + + "temp.title": "OpenCode | 專為終端打造的 AI 編碼代理", + "temp.hero.title": "專為終端打造的 AI 編碼代理", + "temp.zen": "OpenCode Zen", + "temp.getStarted": "開始使用", + "temp.feature.native.title": "原生 TUI", + "temp.feature.native.body": "響應式、原生、可自訂主題的終端介面", + "temp.feature.zen.beforeLink": "", + "temp.feature.zen.link": "精選模型列表", + "temp.feature.zen.afterLink": "由 OpenCode 提供", + "temp.feature.models.beforeLink": "透過", + "temp.feature.models.afterLink": "支援 75+ 家 LLM 供應商,包括本地模型", + "temp.screenshot.caption": "使用 tokyonight 主題的 OpenCode TUI", + "temp.screenshot.alt": "使用 tokyonight 主題的 OpenCode TUI", + "temp.logoLightAlt": "opencode 淺色標誌", + "temp.logoDarkAlt": "opencode 深色標誌", + + "home.banner.badge": "新", + "home.banner.text": "桌面版分頁功能全新推出。", + "home.banner.platforms": "適用於 macOS、Windows 與 Linux", + "home.banner.downloadNow": "立即下載", + "home.banner.downloadBetaNow": "立即下載桌面 Beta 版", + "home.promo.title": "桌面版分頁功能全新推出", + "home.promo.body": "使用分頁整理工作和作用中的工作階段。", + "home.promo.cta": "下載最新版本即可開始使用。", + "home.promo.close": "關閉桌面應用程式公告", + + "home.hero.title": "開源 AI 編碼代理", + "home.hero.subtitle.a": "內建免費模型,或連接任意供應商的任意模型,", + "home.hero.subtitle.b": "包括 Claude、GPT、Gemini 等。", + + "home.install.ariaLabel": "安裝選項", + + "home.what.title": "什麼是 OpenCode?", + "home.what.body": "OpenCode 是一個開源代理,幫助你在終端、IDE 或桌面端編寫程式碼。", + "home.what.lsp.title": "支援 LSP", + "home.what.lsp.body": "為 LLM 自動載入合適的 LSP", + "home.what.multiSession.title": "多工作階段", + "home.what.multiSession.body": "在同一專案中平行啟動多個代理", + "home.what.shareLinks.title": "分享連結", + "home.what.shareLinks.body": "將任意階段的連結分享給他人供參考或除錯", + "home.what.copilot.title": "GitHub Copilot", + "home.what.copilot.body": "使用 GitHub 登入以使用你的 Copilot 帳號", + "home.what.chatgptPlus.title": "ChatGPT Plus/Pro", + "home.what.chatgptPlus.body": "使用 OpenAI 登入以使用你的 ChatGPT Plus 或 Pro 帳號", + "home.what.anyModel.title": "任意模型", + "home.what.anyModel.body": "透過 Models.dev 連接 75+ 家 LLM 供應商,包括本地模型", + "home.what.anyEditor.title": "任意編輯器", + "home.what.anyEditor.body": "可作為終端介面、桌面應用程式與 IDE 擴充功能使用", + "home.what.readDocs": "閱讀文件", + + "home.growth.title": "開源 AI 編碼代理", + "home.growth.body": + "擁有超過 {{stars}} 個 GitHub Star、{{contributors}} 位貢獻者以及超過 {{commits}} 次提交,OpenCode 每月被超過 {{monthlyUsers}} 名開發者使用並信賴。", + "home.growth.githubStars": "GitHub Star", + "home.growth.contributors": "貢獻者", + "home.growth.monthlyDevs": "每月活躍開發者", + + "home.privacy.title": "隱私優先", + "home.privacy.body": "OpenCode 不儲存你的程式碼或上下文資料,因此可以在注重隱私的環境中運作。", + "home.privacy.learnMore": "了解更多關於", + "home.privacy.link": "隱私", + + "home.faq.q1": "什麼是 OpenCode?", + "home.faq.a1": + "OpenCode 是一個開源代理,幫助你使用任意 AI 模型編寫並執行程式碼。它提供終端介面、桌面應用程式或 IDE 擴充功能。", + "home.faq.q2": "如何使用 OpenCode?", + "home.faq.a2.before": "最簡單的方式是先閱讀", + "home.faq.a2.link": "入門介紹", + "home.faq.q3": "使用 OpenCode 需要額外的 AI 訂閱嗎?", + "home.faq.a3.p1": "不一定。OpenCode 自帶一組免費模型,無需建立帳號即可使用。", + "home.faq.a3.p2.beforeZen": "此外,你可以透過建立", + "home.faq.a3.p2.afterZen": "帳號使用常見的編碼模型。", + "home.faq.a3.p3": "我們鼓勵使用 Zen,但 OpenCode 也支援 OpenAI、Anthropic、xAI 等主流供應商。", + "home.faq.a3.p4.beforeLocal": "你還可以連接你的", + "home.faq.a3.p4.localLink": "本地模型", + "home.faq.q4": "可以使用我現有的 AI 訂閱嗎?", + "home.faq.a4.p1": + "可以。OpenCode 支援主流供應商的訂閱方案,包括 Claude Pro/Max、ChatGPT Plus/Pro 與 GitHub Copilot。", + "home.faq.q5": "OpenCode 只能在終端中使用嗎?", + "home.faq.a5.beforeDesktop": "不再是了!OpenCode 現在也提供", + "home.faq.a5.desktop": "桌面端", + "home.faq.a5.and": "與", + "home.faq.a5.web": "網頁端", + "home.faq.q6": "OpenCode 價格如何?", + "home.faq.a6": "OpenCode 100% 免費使用。它也自帶一組免費模型。如果你連接其他供應商,可能會產生額外費用。", + "home.faq.q7": "資料與隱私怎麼辦?", + "home.faq.a7.p1": "僅當你使用我們的免費模型或建立可分享連結時,才會儲存你的資料與資訊。", + "home.faq.a7.p2.beforeModels": "了解更多關於", + "home.faq.a7.p2.modelsLink": "我們的模型", + "home.faq.a7.p2.and": "與", + "home.faq.a7.p2.shareLink": "分享頁面", + "home.faq.q8": "OpenCode 是開源的嗎?", + "home.faq.a8.p1": "是的,OpenCode 完全開源。原始碼公開在", + "home.faq.a8.p2": "並採用", + "home.faq.a8.mitLicense": "MIT 授權條款", + "home.faq.a8.p3": ",意味著任何人都可以使用、修改或貢獻。社群中的任何人都可以提交 issue、pull requests 並擴充功能。", + + "home.zenCta.title": "存取可靠且最佳化的編碼代理模型", + "home.zenCta.body": + "Zen 提供一組精選的 AI 模型,這些模型是 OpenCode 為了編碼代理專門測試與評測過的。無需擔心不同供應商之間效能與品質參差不齊,使用經過驗證的模型即可。", + "home.zenCta.link": "了解 Zen", + + "zen.title": "OpenCode Zen | 專為編碼代理精選的可靠最佳化模型", + "zen.hero.title": "專為編碼代理提供的可靠最佳化模型", + "zen.hero.body": + "Zen 提供一組精選的 AI 模型,這些模型是 OpenCode 為了編碼代理專門測試與評測過的。無需擔心效能與品質參差不齊,使用經過驗證的模型即可。", + + "zen.faq.q1": "什麼是 OpenCode Zen?", + "zen.faq.a1": "Zen 是由 OpenCode 團隊打造、專為編碼代理測試與評測的 AI 模型精選集合。", + "zen.faq.q2": "是什麼讓 Zen 更準確?", + "zen.faq.a2": "Zen 只提供專為編碼代理測試與評測的模型。你不會用奶油刀切牛排,也別用糟糕的模型來寫程式。", + "zen.faq.q3": "Zen 更便宜嗎?", + "zen.faq.a3": + "Zen 不以營利為目的。Zen 會把模型供應商的成本原樣轉給你。Zen 的使用量越高,OpenCode 就越能談到更好的價格並把優惠讓利給你。", + "zen.faq.q4": "Zen 費用是多少?", + "zen.faq.a4.p1.beforePricing": "Zen", + "zen.faq.a4.p1.pricingLink": "按請求付費", + "zen.faq.a4.p1.afterPricing": "且零加價,因此你支付的就是模型供應商的原價。", + "zen.faq.a4.p2.beforeAccount": "總費用取決於使用量,你可以在", + "zen.faq.a4.p2.accountLink": "帳戶中設定每月支出上限", + "zen.faq.a4.p3": "為了覆蓋成本,OpenCode 只會收取很小的支付處理費:每次儲值 $20 會額外收取 $1.23。", + "zen.faq.q5": "資料與隱私如何?", + "zen.faq.a5.beforeExceptions": "所有 Zen 模型都託管在美國。供應商遵循零留存政策,不會將你的資料用於模型訓練,但有", + "zen.faq.a5.exceptionsLink": "以下例外", + "zen.faq.q6": "我可以設定支出上限嗎?", + "zen.faq.a6": "可以,你可以在帳戶中設定每月支出上限。", + "zen.faq.q7": "我可以取消嗎?", + "zen.faq.a7": "可以,你可以隨時停用計費並使用剩餘餘額。", + "zen.faq.q8": "我可以在其他編碼代理中使用 Zen 嗎?", + "zen.faq.a8": + "Zen 與 OpenCode 搭配得很好,但你也可以在任何代理中使用 Zen。請在你偏好的編碼代理中按照設定說明進行配置。", + "zen.faq.q9": "我可以退款嗎?", + "zen.faq.a9": "若扣款發生在過去 14 天內,且你尚未使用該次購買的任何額度,你可能符合退款資格。請{{contact}}申請退款。", + + "zen.cta.start": "開始使用 Zen", + "zen.pricing.title": "儲值 $20 即用即付餘額", + "zen.pricing.fee": "(+$1.23 刷卡手續費)", + "zen.pricing.body": "可與任何代理一起使用。設定每月支出限額。隨時取消。", + "zen.problem.title": "Zen 正在解決什麼問題?", + "zen.problem.body": + "可用的模型有很多,但只有少數可以與編碼代理配合良好。大多數供應商以不同的方式配置它們,導致結果參差不齊。", + "zen.problem.subtitle": "我們正在為所有人解決此問題,而不僅僅是 OpenCode 使用者。", + "zen.problem.item1": "測試選定的模型並諮詢其團隊", + "zen.problem.item2": "與供應商合作以確保正確交付", + "zen.problem.item3": "對我們推薦的所有模型-供應商組合進行基準測試", + "zen.how.title": "Zen 如何運作", + "zen.how.body": "雖然我們建議你將 Zen 與 OpenCode 一起使用,但你可以將 Zen 與任何代理一起使用。", + "zen.how.step1.title": "註冊並儲值 $20 餘額", + "zen.how.step1.beforeLink": "遵循", + "zen.how.step1.link": "設定說明", + "zen.how.step2.title": "使用 Zen 並享有透明定價", + "zen.how.step2.link": "按請求付費", + "zen.how.step2.afterLink": "零加價", + "zen.how.step3.title": "自動儲值", + "zen.how.step3.body": "當你的餘額達到 $5 時,我們會自動儲值 $20", + "zen.privacy.title": "你的隱私對我們很重要", + "zen.privacy.beforeExceptions": "所有 Zen 模型均在美國託管。供應商遵循零留存政策,不會將你的資料用於模型訓練,並且有", + "zen.privacy.exceptionsLink": "以下例外情況", + + "go.title": "OpenCode Go | 低成本全民編碼模型", + "go.meta.description": "Go 每月 $10,提供充裕的使用限額,並可穩定存取領先的編碼模型。", + "go.hero.title": "低成本全民編碼模型", + "go.hero.body": + "Go 將代理編碼帶給全世界的程式設計師。提供寬裕的限額以及對最強大開源模型的穩定存取,讓你可以使用強大的代理進行構建,而無需擔心成本或可用性。", + + "go.cta.start": "訂閱 Go", + "go.cta.template": "{{text}} {{price}}", + "go.cta.text": "訂閱 Go", + "go.cta.price": "$10/月", + "go.pricing.body": "可搭配任何代理使用。每月 $10。如有需要可儲值。隨時取消。", + "go.graph.free": "免費", + "go.graph.freePill": "Big Pickle 與免費模型", + "go.graph.go": "Go", + "go.graph.label": "每 5 小時請求數", + "go.graph.period": "使用額度", + "go.graph.model": "模型", + "go.graph.requests": "預估請求次數 / 5 小時", + "go.graph.allowance": "每月使用額度", + "go.graph.new": "新", + "go.graph.scale": "請求數採用非線性刻度", + "go.graph.showAll": "查看全部 {{count}} 個模型", + "go.graph.showLess": "收起模型", + "go.graph.limitedRegions": "僅限部分地區", + "go.graph.limitedTime": "限時", + "go.graph.usageLimits": "使用限制", + "go.graph.aria": "每 5 小時請求數:{{free}} vs {{go}}", + + "go.testimonials.brand.zen": "Zen", + "go.testimonials.brand.go": "Go", + "go.testimonials.handle": "@OpenCode", + "go.testimonials.dax.name": "Dax Raad", + "go.testimonials.dax.title": "前 Terminal Products CEO", + "go.testimonials.dax.quoteAfter": "改變了我的生活,這絕對是不二之選。", + "go.testimonials.jay.name": "Jay V", + "go.testimonials.jay.title": "前 SEED、Melt、Pop、Dapt、Cadmus 與 ViewPoint 創辦人", + "go.testimonials.jay.quoteBefore": "我們團隊中 5 個人有 4 個人喜歡使用", + "go.testimonials.jay.quoteAfter": "。", + "go.testimonials.adam.name": "Adam Elmore", + "go.testimonials.adam.title": "前 AWS Hero", + "go.testimonials.adam.quoteBefore": "我強烈推薦", + "go.testimonials.adam.quoteAfter": "。認真說,真的很好用。", + "go.testimonials.david.name": "David Hill", + "go.testimonials.david.title": "前 Laravel 設計總監", + "go.testimonials.david.quoteBefore": "有了", + "go.testimonials.david.quoteAfter": ",我知道所有模型都經過測試並且完美適用於編碼代理。", + "go.testimonials.frank.name": "Frank Wang", + "go.testimonials.frank.title": "前 Nvidia 實習生(4 次)", + "go.testimonials.frank.quote": "我希望我還在 Nvidia。", + "go.problem.title": "Go 正在解決什麼問題?", + "go.problem.body": + "我們致力於將 OpenCode 體驗帶給盡可能多的人。OpenCode Go 是一款每月 $10 的低成本訂閱服務。它提供充裕的額度,並讓您能可靠地使用最強大的開源模型。", + "go.problem.subtitle": " ", + "go.problem.item1": "低成本訂閱定價", + "go.problem.item2": "寬裕的限額與穩定存取", + "go.problem.item3": "專為盡可能多的程式設計師打造", + "go.problem.item4": "針對代理編碼測試的精選模型陣容", + "go.how.title": "Go 如何運作", + "go.how.body": "Go 每月 $10。您可以將其與 OpenCode 或任何代理搭配使用。", + "go.how.step1.title": "建立帳號", + "go.how.step1.beforeLink": "遵循", + "go.how.step1.link": "設定說明", + "go.how.step2.title": "訂閱 Go", + "go.how.step2.link": "每月 $10", + "go.how.step2.afterLink": "額度充裕", + "go.how.step3.title": "開始編碼", + "go.how.step3.body": "穩定存取開源模型", + "go.privacy.title": "你的隱私對我們很重要", + "go.privacy.body": "該方案主要面向國際用戶設計,模型託管在美國、歐盟和新加坡,以確保全球穩定存取。", + "go.privacy.contactAfter": "如果你有任何問題。", + "go.privacy.beforeExceptions": "Go 模型託管在美國。供應商遵循零留存政策,不會將你的資料用於模型訓練,但有", + "go.privacy.exceptionsLink": "以下例外", + "go.faq.q1": "什麼是 OpenCode Go?", + "go.faq.a1": "Go 是一個低成本訂閱方案,讓你穩定存取強大的開源模型以進行代理編碼。", + "go.faq.q2": "Go 包含哪些模型?", + "go.faq.a2": "Go 包含下方列出的模型,提供充足的額度與穩定的存取。", + "go.faq.q3": "Go 與 Zen 一樣嗎?", + "go.faq.a3": "不。Zen 是按量付費,而 Go 每月 $10,提供充裕的限額,並可穩定存取精選模型陣容。", + "go.faq.q4": "Go 費用是多少?", + "go.faq.a4.p1.beforePricing": "Go 費用為", + "go.faq.a4.p1.pricingLink": "每月 $10", + "go.faq.a4.p1.afterPricing": "額度充裕。", + "go.faq.a4.p2.beforeAccount": "你可以在你的", + "go.faq.a4.p2.accountLink": "帳戶", + "go.faq.a4.p3": "中管理訂閱。隨時取消。", + "go.faq.q5": "資料與隱私怎麼辦?", + "go.faq.a5.model": "模型", + "go.faq.a5.training": "模型訓練", + "go.faq.a5.retention": "資料保留", + "go.faq.a5.retention30": "30 天", + "go.faq.a5.retention0": "0 天", + "go.faq.a5.used": "使用", + "go.faq.a5.notUsed": "不使用", + "go.faq.a5.noAgreement": "無協議", + "go.faq.a5.notZdr": "非 ZDR", + "go.faq.a5.grokRetention": + "ZDR 會停用依賴儲存資料的重要 API 功能,包括具狀態的 Responses API、Files and Collections 與 Batch API。", + "go.faq.a5.gptRetention": "所有 API 功能的使用都會產生濫用監控日誌,並保留最多 30 天。", + "go.faq.a5.museRetention": "以允許使用您的提示詞和生成結果來訓練未來的 Meta 模型為交換,token 價格可享大幅折扣。", + "go.faq.a5.learnMore": "了解更多", + "go.faq.a5.deepseekRetention": "ZDR 協議每月續簽。目前的協議有效至 2026 年 9 月 30 日。", + "go.faq.a5.beforeExceptions": "Go 模型託管在美國。供應商遵循零留存政策,不會將你的資料用於模型訓練,但有", + "go.faq.a5.exceptionsLink": "以下例外", + "go.faq.q6": "我可以儲值額度嗎?", + "go.faq.a6": "如果你需要更多使用量,可以在帳戶中儲值額度。", + "go.faq.q7": "我可以取消嗎?", + "go.faq.a7": "可以,你可以隨時取消。", + "go.faq.q8": "我可以在其他編碼代理中使用 Go 嗎?", + "go.faq.a8": "可以,你可以將 Go 與任何代理一起使用。請在你偏好的編碼代理中按照設定說明進行配置。", + + "go.faq.q9": "免費模型與 Go 有什麼區別?", + "go.faq.a9": + "免費模型包括 Big Pickle 以及當時可用的促銷模型,配額為 200 次請求/天。Go 提供精選模型陣容,並在滾動視窗(5 小時、每週和每月)內提供更高的請求配額,大約相當於每 5 小時 $12、每週 $30 和每月 $60 的基礎額度;具體額度可能因模型而異(實際請求數因模型和使用情況而異)。", + "go.faq.q10": "我可以退款嗎?", + "go.faq.a10": + "若扣款發生在過去 14 天內,且你在該計費期間尚未使用任何 Go 額度,你可能符合退款資格。請{{contact}}申請退款。", + + "zen.api.error.rateLimitExceeded": "超出頻率限制。請稍後再試。", + "zen.api.error.modelNotSupported": "不支援模型 {{model}}", + "zen.api.error.modelFormatNotSupported": "模型 {{model}} 不支援格式 {{format}}", + "zen.api.error.noProviderAvailable": "無可用的供應商", + "zen.api.error.providerNotSupported": "不支援供應商 {{provider}}", + "zen.api.error.missingApiKey": "缺少 API 金鑰。", + "zen.api.error.invalidApiKey": "無效的 API 金鑰。", + "zen.api.error.requestBlockedByUpstreamProvider": "請求遭上游供應商封鎖。", + "zen.api.error.subscriptionQuotaExceeded": "超出訂閱配額。請在 {{retryIn}} 後重試。", + "zen.api.error.goSubscriptionRollingLimitExceeded": + "已達 5 小時使用上限,將在 {{retryIn}} 後重置。若要立即繼續使用此模型,請從可用餘額啟用使用量:{{consoleGoUrl}}", + "zen.api.error.goSubscriptionWeeklyLimitExceeded": + "已達每週使用上限,將在 {{retryIn}} 後重置。若要立即繼續使用此模型,請從可用餘額啟用使用量:{{consoleGoUrl}}", + "zen.api.error.goSubscriptionMonthlyLimitExceeded": + "已達每月使用上限,將在 {{retryIn}} 後重置。若要立即繼續使用此模型,請從可用餘額啟用使用量:{{consoleGoUrl}}", + "zen.api.error.noPaymentMethod": "無付款方式。請在此處新增付款方式:{{billingUrl}}", + "zen.api.error.insufficientBalance": "餘額不足。請在此處管理你的帳務:{{billingUrl}}", + "zen.api.error.workspaceMonthlyLimitReached": + "你的工作區已達到每月支出限額 ${{amount}}。請在此處管理你的限額:{{billingUrl}}", + "zen.api.error.userMonthlyLimitReached": "你已達到每月支出限額 ${{amount}}。請在此處管理你的限額:{{membersUrl}}", + "zen.api.error.modelDisabled": "模型已停用", + "zen.api.error.regionNotAllowed": "此模型的最新版本僅於中國託管,且需明確選擇啟用:{{consoleGoUrl}}", + "zen.api.error.countryNotAllowed": "此模型無法在你所在的國家或地區使用。", + "zen.api.error.trainingNotAllowed": "此模型會收集用於提升其品質的資料,使用前須經你明確同意:{{consoleGoUrl}}", + "zen.api.error.trialEnded": "{{model}} 的限免活动已結束。您可以訂閱 OpenCode Go 繼續使用該模型 - {{link}}", + + "black.meta.title": "OpenCode Black | 存取全球最佳編碼模型", + "black.meta.description": "透過 OpenCode Black 訂閱方案存取 Claude、GPT、Gemini 等模型。", + "black.hero.title": "存取全球最佳編碼模型", + "black.hero.subtitle": "包括 Claude、GPT、Gemini 等", + "black.title": "OpenCode Black | 定價", + "black.paused": "Black 訂閱暫時暫停註冊。", + "black.plan.icon20": "Black 20 方案", + "black.plan.icon100": "Black 100 方案", + "black.plan.icon200": "Black 200 方案", + "black.plan.multiplier100": "比 Black 20 多 5 倍使用量", + "black.plan.multiplier200": "比 Black 20 多 20 倍使用量", + "black.price.perMonth": "每月", + "black.price.perPersonBilledMonthly": "每人每月計費", + "black.terms.1": "你的訂閱不會立即開始", + "black.terms.2": "你將被加入候補名單並在不久後啟用", + "black.terms.3": "你的卡片僅在訂閱啟用時才會扣款", + "black.terms.4": "適用使用限制,高度自動化的使用可能會更快達到限制", + "black.terms.5": "訂閱僅限個人使用,團隊請聯繫企業版", + "black.terms.6": "未來可能會調整限制或終止方案", + "black.terms.7": "隨時取消你的訂閱", + "black.action.continue": "繼續", + "black.finePrint.beforeTerms": "顯示價格未包含適用稅項", + "black.finePrint.terms": "服務條款", + "black.workspace.title": "OpenCode Black | 選擇工作區", + "black.workspace.selectPlan": "為此方案選擇一個工作區", + "black.workspace.name": "工作區 {{n}}", + "black.subscribe.title": "訂閱 OpenCode Black", + "black.subscribe.paymentMethod": "付款方式", + "black.subscribe.loadingPaymentForm": "正在載入付款表單...", + "black.subscribe.selectWorkspaceToContinue": "選擇一個工作區以繼續", + "black.subscribe.failurePrefix": "噢不!", + "black.subscribe.error.generic": "發生錯誤", + "black.subscribe.error.invalidPlan": "無效的方案", + "black.subscribe.error.workspaceRequired": "需要工作區 ID", + "black.subscribe.error.alreadySubscribed": "此工作區已有訂閱", + "black.subscribe.processing": "處理中...", + "black.subscribe.submit": "訂閱 ${{plan}}", + "black.subscribe.form.chargeNotice": "你僅在訂閱啟用時才會被扣款", + "black.subscribe.success.title": "你已在 OpenCode Black 候補名單上", + "black.subscribe.success.subscriptionPlan": "訂閱方案", + "black.subscribe.success.planName": "OpenCode Black {{plan}}", + "black.subscribe.success.amount": "金額", + "black.subscribe.success.amountValue": "${{plan}} 每月", + "black.subscribe.success.paymentMethod": "付款方式", + "black.subscribe.success.dateJoined": "加入日期", + "black.subscribe.success.chargeNotice": "你的卡片將在訂閱啟用時扣款", + + "workspace.nav.zen": "Zen", + "workspace.nav.go": "Go", + "workspace.nav.usage": "使用量", + "workspace.nav.apiKeys": "API 金鑰", + "workspace.nav.members": "成員", + "workspace.nav.billing": "帳務", + "workspace.nav.settings": "設定", + + "workspace.home.banner.beforeLink": "編碼代理的可靠最佳化模型。", + "workspace.lite.banner.beforeLink": "低成本編碼模型,人人可用。", + "workspace.home.billing.loading": "載入中...", + "workspace.home.billing.enable": "啟用帳務", + "workspace.home.billing.currentBalance": "目前餘額", + + "workspace.newUser.feature.tested.title": "經過測試與驗證的模型", + "workspace.newUser.feature.tested.body": "我們專門針對編碼代理對模型進行了基準測試和測試,以確保最佳效能。", + "workspace.newUser.feature.quality.title": "最高品質", + "workspace.newUser.feature.quality.body": "存取配置為最佳效能的模型 - 無需降級或路由到更便宜的供應商。", + "workspace.newUser.feature.lockin.title": "無綁定", + "workspace.newUser.feature.lockin.body": + "將 Zen 與任何編碼代理結合使用,並在需要時隨時使用 OpenCode 連接其他供應商。", + "workspace.newUser.copyApiKey": "複製 API 金鑰", + "workspace.newUser.copyKey": "複製金鑰", + "workspace.newUser.copied": "已複製!", + "workspace.newUser.step.enableBilling": "啟用帳務", + "workspace.newUser.step.login.before": "執行", + "workspace.newUser.step.login.after": "並選擇 OpenCode", + "workspace.newUser.step.pasteKey": "貼上你的 API 金鑰", + "workspace.newUser.step.models.before": "啟動 OpenCode 並執行", + "workspace.newUser.step.models.after": "以選擇模型", + + "workspace.models.title": "模型", + "workspace.models.subtitle.beforeLink": "管理工作區成員可以存取哪些模型。", + "workspace.models.table.model": "模型", + "workspace.models.table.enabled": "啟用", + + "workspace.providers.title": "自帶金鑰", + "workspace.providers.subtitle": "設定你自己的 AI 供應商 API 金鑰。", + "workspace.providers.placeholder": "輸入 {{provider}} API 金鑰({{prefix}}...)", + "workspace.providers.configure": "設定", + "workspace.providers.edit": "編輯", + "workspace.providers.delete": "刪除", + "workspace.providers.saving": "儲存中...", + "workspace.providers.save": "儲存", + "workspace.providers.table.provider": "供應商", + "workspace.providers.table.apiKey": "API 金鑰", + + "workspace.usage.title": "使用紀錄", + "workspace.usage.subtitle": "最近的 API 使用情況與成本。", + "workspace.usage.empty": "進行第一次 API 呼叫即可開始。", + "workspace.usage.table.date": "日期", + "workspace.usage.table.model": "模型", + "workspace.usage.table.input": "輸入", + "workspace.usage.table.output": "輸出", + "workspace.usage.table.cost": "成本", + "workspace.usage.table.session": "會話", + "workspace.usage.breakdown.input": "輸入", + "workspace.usage.breakdown.cacheRead": "快取讀取", + "workspace.usage.breakdown.cacheWrite": "快取寫入", + "workspace.usage.breakdown.output": "輸出", + "workspace.usage.breakdown.reasoning": "推理", + "workspace.usage.subscription": "Black (${{amount}})", + "workspace.usage.lite": "Go (${{amount}})", + "workspace.usage.byok": "BYOK (${{amount}})", + + "workspace.cost.title": "成本", + "workspace.cost.subtitle": "按模型細分的使用成本。", + "workspace.cost.allModels": "所有模型", + "workspace.cost.allKeys": "所有金鑰", + "workspace.cost.deletedSuffix": "(已刪除)", + "workspace.cost.empty": "所選期間沒有可用的使用資料。", + "workspace.cost.subscriptionShort": "訂", + + "workspace.keys.title": "API 金鑰", + "workspace.keys.subtitle": "管理你的 API 金鑰以存取 OpenCode 服務。", + "workspace.keys.create": "建立 API 金鑰", + "workspace.keys.placeholder": "輸入金鑰名稱", + "workspace.keys.empty": "建立 OpenCode 閘道器 API 金鑰", + "workspace.keys.table.name": "名稱", + "workspace.keys.table.key": "金鑰", + "workspace.keys.table.createdBy": "建立者", + "workspace.keys.table.lastUsed": "最後使用", + "workspace.keys.copyApiKey": "複製 API 金鑰", + "workspace.keys.delete": "刪除", + + "workspace.members.title": "成員", + "workspace.members.subtitle": "管理工作區成員及其權限。", + "workspace.members.invite": "邀請成員", + "workspace.members.inviting": "邀請中...", + "workspace.members.beta.beforeLink": "Beta 測試期間,工作區對團隊免費。", + "workspace.members.form.invitee": "受邀者", + "workspace.members.form.emailPlaceholder": "輸入電子郵件", + "workspace.members.form.role": "角色", + "workspace.members.form.monthlyLimit": "每月支出限額", + "workspace.members.noLimit": "無限制", + "workspace.members.noLimitLowercase": "無限制", + "workspace.members.invited": "已邀請", + "workspace.members.edit": "編輯", + "workspace.members.delete": "刪除", + "workspace.members.saving": "儲存中...", + "workspace.members.save": "儲存", + "workspace.members.table.email": "電子郵件", + "workspace.members.table.role": "角色", + "workspace.members.table.monthLimit": "月限額", + "workspace.members.role.admin": "管理員", + "workspace.members.role.adminDescription": "可以管理模型、成員和帳務", + "workspace.members.role.member": "成員", + "workspace.members.role.memberDescription": "只能為自己生成 API 金鑰", + + "workspace.settings.title": "設定", + "workspace.settings.subtitle": "更新你的工作區名稱與偏好設定。", + "workspace.settings.workspaceName": "工作區名稱", + "workspace.settings.defaultName": "預設", + "workspace.settings.updating": "更新中...", + "workspace.settings.save": "儲存", + "workspace.settings.edit": "編輯", + + "workspace.billing.title": "帳務", + "workspace.billing.subtitle.beforeLink": "管理付款方式。", + "workspace.billing.contactUs": "聯絡我們", + "workspace.billing.subtitle.afterLink": "如果你有任何問題。", + "workspace.billing.currentBalance": "目前餘額", + "workspace.billing.add": "儲值 $", + "workspace.billing.enterAmount": "輸入金額", + "workspace.billing.loading": "載入中...", + "workspace.billing.addAction": "儲值", + "workspace.billing.addBalance": "儲值餘額", + "workspace.billing.alipay": "支付寶", + "workspace.billing.wechat": "微信支付", + "workspace.billing.linkedToStripe": "已連結 Stripe", + "workspace.billing.manage": "管理", + "workspace.billing.enable": "啟用帳務", + + "workspace.monthlyLimit.title": "每月限額", + "workspace.monthlyLimit.subtitle": "為你的帳戶設定每月使用限額。", + "workspace.monthlyLimit.placeholder": "50", + "workspace.monthlyLimit.setting": "設定中...", + "workspace.monthlyLimit.set": "設定", + "workspace.monthlyLimit.edit": "編輯限額", + "workspace.monthlyLimit.noLimit": "未設定使用限額。", + "workspace.monthlyLimit.currentUsage.beforeMonth": "目前", + "workspace.monthlyLimit.currentUsage.beforeAmount": "的使用量為 $", + + "workspace.redeem.title": "兌換優惠券", + "workspace.redeem.subtitle": "兌換優惠碼以領取儲值額度或權益。", + "workspace.redeem.placeholder": "輸入優惠碼", + "workspace.redeem.redeem": "兌換", + "workspace.redeem.redeeming": "兌換中...", + "workspace.redeem.success": "優惠券兌換成功。", + + "workspace.reload.title": "自動儲值", + "workspace.reload.disabled.before": "自動儲值已", + "workspace.reload.disabled.state": "停用", + "workspace.reload.disabled.after": "啟用後會在餘額偏低時自動儲值。", + "workspace.reload.enabled.before": "自動儲值已", + "workspace.reload.enabled.state": "啟用", + "workspace.reload.enabled.middle": "我們將自動儲值", + "workspace.reload.processingFee": "手續費", + "workspace.reload.enabled.after": "當餘額達到", + "workspace.reload.edit": "編輯", + "workspace.reload.enable": "啟用", + "workspace.reload.enableAutoReload": "啟用自動儲值", + "workspace.reload.reloadAmount": "儲值 $", + "workspace.reload.whenBalanceReaches": "當餘額達到 $", + "workspace.reload.saving": "儲存中...", + "workspace.reload.save": "儲存", + "workspace.reload.failedAt": "儲值失敗於", + "workspace.reload.reason": "原因:", + "workspace.reload.updatePaymentMethod": "請更新你的付款方式並重試。", + "workspace.reload.retrying": "重試中...", + "workspace.reload.retry": "重試", + "workspace.reload.error.paymentFailed": "付款失敗。", + + "workspace.payments.title": "付款紀錄", + "workspace.payments.subtitle": "最近的付款交易。", + "workspace.payments.table.date": "日期", + "workspace.payments.table.paymentId": "付款 ID", + "workspace.payments.table.amount": "金額", + "workspace.payments.table.receipt": "收據", + "workspace.payments.type.credit": "信用額度", + "workspace.payments.type.subscription": "訂閱", + "workspace.payments.view": "檢視", + + "workspace.black.loading": "載入中...", + "workspace.black.time.day": "天", + "workspace.black.time.days": "天", + "workspace.black.time.hour": "小時", + "workspace.black.time.hours": "小時", + "workspace.black.time.minute": "分鐘", + "workspace.black.time.minutes": "分鐘", + "workspace.black.time.fewSeconds": "幾秒鐘", + "workspace.black.subscription.title": "訂閱", + "workspace.black.subscription.message": "你已訂閱 OpenCode Black,費用為每月 ${{plan}}。", + "workspace.black.subscription.manage": "管理訂閱", + "workspace.black.subscription.rollingUsage": "5 小時使用量", + "workspace.black.subscription.weeklyUsage": "每週使用量", + "workspace.black.subscription.resetsIn": "重置於", + "workspace.black.subscription.useBalance": "達到使用限額後使用你的可用餘額", + "workspace.black.waitlist.title": "候補名單", + "workspace.black.waitlist.joined": "你已加入每月 ${{plan}} 的 OpenCode Black 方案候補名單。", + "workspace.black.waitlist.ready": "我們已準備好將你加入每月 ${{plan}} 的 OpenCode Black 方案。", + "workspace.black.waitlist.leave": "離開候補名單", + "workspace.black.waitlist.leaving": "離開中...", + "workspace.black.waitlist.left": "已離開", + "workspace.black.waitlist.enroll": "加入", + "workspace.black.waitlist.enrolling": "加入中...", + "workspace.black.waitlist.enrolled": "已加入", + "workspace.black.waitlist.enrollNote": "當你點選「加入」後,你的訂閱將立即開始,並且將從你的卡片中扣款。", + + "workspace.lite.loading": "載入中...", + "workspace.lite.time.day": "天", + "workspace.lite.time.days": "天", + "workspace.lite.time.hour": "小時", + "workspace.lite.time.hours": "小時", + "workspace.lite.time.minute": "分鐘", + "workspace.lite.time.minutes": "分鐘", + "workspace.lite.time.fewSeconds": "幾秒", + "workspace.lite.subscription.message": "您已訂閱 OpenCode Go。", + "workspace.lite.subscription.manage": "管理訂閱", + "workspace.lite.subscription.rollingUsage": "5 小時使用量", + "workspace.lite.subscription.rollingQuota": "5 小時配額", + "workspace.lite.subscription.weeklyUsage": "每週使用量", + "workspace.lite.subscription.weeklyQuota": "每週配額", + "workspace.lite.subscription.monthlyUsage": "每月使用量", + "workspace.lite.subscription.monthlyQuota": "每月配額", + "workspace.lite.subscription.resetsIn": "重置時間:", + "workspace.lite.subscription.showDetails": "顯示詳情", + "workspace.lite.subscription.hideDetails": "隱藏詳情", + "workspace.lite.subscription.model": "模型", + "workspace.lite.subscription.contribution": "%", + "workspace.lite.subscription.total": "總計", + "workspace.lite.subscription.useBalance": "達到使用限制後使用您的可用餘額", + "workspace.lite.subscription.selectProvider": + "在您的 opencode 設定中選擇「OpenCode Go」作為提供商,即可使用 Go 模型。", + "workspace.lite.providers.title": "提供商", + "workspace.lite.providers.description": "控制用於路由的提供商。", + "workspace.lite.providers.allowTraining": "允許使用請求資料進行訓練的模型", + "workspace.lite.providers.useChina": "啟用部署在中國的模型", + "workspace.lite.black.message": "您目前已訂閱 OpenCode Black 或在候補名單中。若要切換至 Go,請先取消訂閱。", + "workspace.lite.other.message": "此工作區中的另一位成員已訂閱 OpenCode Go。每個工作區只能有一位成員訂閱。", + "workspace.lite.promo.description": + "OpenCode Go 每月 {{price}},並提供對熱門開放編碼模型的可靠存取,同時享有充裕的使用額度。", + "workspace.lite.promo.price": "$10/月", + "workspace.lite.promo.modelsTitle": "包含模型", + "workspace.lite.promo.footer": + "此方案主要為國際使用者設計,提供穩定的全球存取服務。隨著我們從初期使用情況和回饋中持續了解需求,價格和使用額度可能會有所調整。", + "workspace.lite.promo.subscribe": "訂閱 Go", + "workspace.lite.promo.subscribing": "重新導向中...", + "workspace.lite.promo.otherMethods": "其他付款方式", + "workspace.lite.promo.selectMethod": "選擇付款方式", + + "workspace.referral.copyLink": "複製連結", + "workspace.referral.copied": "已複製", + "workspace.referral.overview.title": "邀請朋友", + "workspace.referral.overview.subtitle": "朋友訂閱後,您可獲得 $5,對方也可獲得 $5。", + "workspace.referral.instructions.share": "分享您的推薦連結。", + "workspace.referral.instructions.subscribe": "朋友加入並訂閱 Go。", + "workspace.referral.instructions.claim": "你們都將獲得 $5 使用額度,可用於您的 Go 使用限額。", + "workspace.referral.rewards.title": "邀請獎勵", + "workspace.referral.rewards.description": "將可用的邀請點數套用至您的 Go 使用量。", + "workspace.referral.rewards.subtitle": "已使用 {{applied}} / {{total}} 個獎勵。", + "workspace.referral.rewards.empty": "暫無邀請獎勵。", + "workspace.referral.table.reward": "獎勵", + "workspace.referral.table.referral": "描述", + "workspace.referral.table.date": "日期", + "workspace.referral.reward.description.inviter": "已邀請 {{email}}", + "workspace.referral.reward.description.invitee": "由 {{email}} 邀請", + "workspace.referral.reward.action.subscribeUnlock": "訂閱以解鎖", + "workspace.referral.reward.action.view": "查看獎勵", + "workspace.referral.reward.action.applied": "獎勵已使用", + "workspace.referral.reward.source.pendingInviter": "等待對方訂閱", + "workspace.referral.reward.source.pendingInvitee": "訂閱即可解鎖獎勵", + "workspace.referral.reward.source.available": "獎勵可使用", + "workspace.referral.reward.source.applied": "獎勵已使用", + "workspace.referral.reward.status.applied": "獎勵已使用", + "workspace.referral.reward.status.pendingInviter": "訂閱以解鎖", + "workspace.referral.reward.status.pendingInvitee": "訂閱以解鎖", + "workspace.referral.apply.noGo": "訂閱以解鎖", + "workspace.referral.apply.preview": "查看獎勵", + "workspace.referral.apply.action": "使用", + "workspace.referral.apply.confirmTitle": "使用獎勵", + "workspace.referral.apply.confirmBody": "使用 {{amount}} 抵扣目前工作區的用量。", + "workspace.referral.apply.confirmAction": "使用", + + "download.title": "OpenCode | 下載", + "download.meta.description": "下載適用於 macOS、Windows 與 Linux 的 OpenCode", + "download.hero.title": "下載 OpenCode 桌面版", + "download.hero.subtitle": "適用於 macOS、Windows 與 Linux 的 Beta 版現已提供", + "download.hero.button": "下載 {{os}} 版", + "download.section.terminal": "OpenCode 終端", + "download.section.desktop": "OpenCode 桌面版", + "download.section.extensions": "OpenCode 擴充功能", + "download.section.integrations": "OpenCode 整合", + "download.action.download": "下載", + "download.action.install": "安裝", + + "download.platform.macosAppleSilicon": "macOS (Apple Silicon)", + "download.platform.macosIntel": "macOS (Intel)", + "download.platform.windowsX64": "Windows (x64)", + "download.platform.linuxDeb": "Linux (.deb)", + "download.platform.linuxRpm": "Linux (.rpm)", + + "download.faq.a3.beforeLocal": + "不一定,但很可能需要。如果你想將 OpenCode 連接到付費供應商,你需要 AI 訂閱,不過你也可以使用", + "download.faq.a3.localLink": "本地模型", + "download.faq.a3.afterLocal.beforeZen": "免費。我們也推薦使用", + "download.faq.a3.afterZen": ",但 OpenCode 同樣支援 OpenAI、Anthropic、xAI 等所有主流供應商。", + + "download.faq.a5.p1": "OpenCode 100% 免費使用。", + "download.faq.a5.p2.beforeZen": "額外費用來自你對模型供應商的訂閱。雖然 OpenCode 支援任何模型供應商,但我們建議使用", + "download.faq.a5.p2.afterZen": "。", + + "download.faq.a6.p1": "你的資料與資訊只會在你於 OpenCode 中建立可分享連結時被儲存。", + "download.faq.a6.p2.beforeShare": "了解更多關於", + "download.faq.a6.shareLink": "分享頁面", + + "enterprise.title": "OpenCode | 面向組織的企業解決方案", + "enterprise.meta.description": "聯絡 OpenCode 取得企業解決方案", + "enterprise.hero.title": "你的程式碼屬於你", + "enterprise.hero.body1": + "OpenCode 在你的組織內部安全運作,不會儲存任何資料或上下文,也沒有授權限制或所有權主張。你可以先與團隊進行試用,然後透過與你的 SSO 與內部 AI 閘道器整合,將其部署到整個組織。", + "enterprise.hero.body2": "告訴我們能如何幫助你。", + "enterprise.form.name.label": "全名", + "enterprise.form.name.placeholder": "傑夫·貝佐斯", + "enterprise.form.role.label": "職稱", + "enterprise.form.role.placeholder": "執行董事長", + "enterprise.form.company.label": "公司", + "enterprise.form.company.placeholder": "Acme Inc", + "enterprise.form.email.label": "公司 Email", + "enterprise.form.email.placeholder": "jeff@amazon.com", + "enterprise.form.phone.label": "電話號碼", + "enterprise.form.phone.placeholder": "+1 234 567 8900", + "enterprise.form.message.label": "你想解決什麼問題?", + "enterprise.form.message.placeholder": "我們需要幫助來...", + "enterprise.form.send": "傳送", + "enterprise.form.sending": "傳送中...", + "enterprise.form.success": "訊息已傳送,我們會盡快與你聯絡。", + "enterprise.form.success.submitted": "表單已成功送出。", + "enterprise.form.error.allFieldsRequired": "所有欄位均為必填。", + "enterprise.form.error.invalidEmailFormat": "無效的電子郵件格式。", + "enterprise.form.error.internalServer": "內部伺服器錯誤。", + "enterprise.faq.title": "常見問題", + "enterprise.faq.q1": "什麼是 OpenCode Enterprise?", + "enterprise.faq.a1": + "OpenCode Enterprise 適用於希望確保程式碼與資料絕不離開自己基礎設施的組織。透過中央化設定,它可與你的 SSO 與內部 AI 閘道器整合,以達成此目標。", + "enterprise.faq.q2": "如何開始使用 OpenCode Enterprise?", + "enterprise.faq.a2": + "只要先以團隊的內部試用開始。OpenCode 預設不會儲存你的程式碼或上下文資料,所以上手非常容易。之後聯絡我們,討論定價與完整實作方案。", + "enterprise.faq.q3": "企業定價是如何進行的?", + "enterprise.faq.a3": + "我們提供按席位的企業定價。如果你有自己的 LLM 閘道器,我們不會對使用的 token 另外收費。更多詳情,請聯絡我們以獲得依據組織需求的客製報價。", + "enterprise.faq.q4": "我的資料在 OpenCode Enterprise 中是安全的嗎?", + "enterprise.faq.a4": + "是的。OpenCode 不會儲存你的程式碼或上下文資料。所有處理都會在本地或透過直接呼叫你的 AI 供應商 API 完成。透過中央化設定與 SSO 整合,你的資料會安全保留在組織的基礎設施內部。", + + "brand.title": "OpenCode | 品牌", + "brand.meta.description": "OpenCode 品牌指南", + "brand.heading": "品牌指南", + "brand.subtitle": "協助你使用 OpenCode 品牌的資源與素材。", + "brand.downloadAll": "下載所有素材", + + "changelog.title": "OpenCode | 更新日誌", + "changelog.meta.description": "OpenCode 發布說明與更新日誌", + "changelog.hero.title": "更新日誌", + "changelog.hero.subtitle": "OpenCode 的新更新與改善", + "changelog.empty": "找不到更新日誌項目。", + "changelog.viewJson": "檢視 JSON", + + "bench.list.title": "評測", + "bench.list.heading": "評測", + "bench.list.table.agent": "代理", + "bench.list.table.model": "模型", + "bench.list.table.score": "分數", + "bench.submission.error.allFieldsRequired": "所有欄位均為必填。", + + "bench.detail.title": "評測 - {{task}}", + "bench.detail.notFound": "找不到任務", + "bench.detail.na": "N/A", + "bench.detail.labels.agent": "代理", + "bench.detail.labels.model": "模型", + "bench.detail.labels.task": "任務", + "bench.detail.labels.repo": "儲存庫", + "bench.detail.labels.from": "起點", + "bench.detail.labels.to": "終點", + "bench.detail.labels.prompt": "提示詞", + "bench.detail.labels.commit": "提交", + "bench.detail.labels.averageDuration": "平均耗時", + "bench.detail.labels.averageScore": "平均分數", + "bench.detail.labels.averageCost": "平均成本", + "bench.detail.labels.summary": "摘要", + "bench.detail.labels.runs": "執行次數", + "bench.detail.labels.score": "分數", + "bench.detail.labels.base": "基準", + "bench.detail.labels.penalty": "扣分", + "bench.detail.labels.weight": "權重", + "bench.detail.table.run": "執行", + "bench.detail.table.score": "分數(基準 - 扣分)", + "bench.detail.table.cost": "成本", + "bench.detail.table.duration": "耗時", + "bench.detail.run.title": "執行 {{n}}", + "bench.detail.rawJson": "原始 JSON", +} satisfies Dict diff --git a/packages/console/app/src/lib/changelog.ts b/packages/console/app/src/lib/changelog.ts new file mode 100644 index 0000000000000000000000000000000000000000..93a0d423c6709316d9f1f7291cd630c6435183f5 --- /dev/null +++ b/packages/console/app/src/lib/changelog.ts @@ -0,0 +1,146 @@ +import { query } from "@solidjs/router" + +type Release = { + tag_name: string + name: string + body: string + published_at: string + html_url: string +} + +export type HighlightMedia = + | { type: "video"; src: string } + | { type: "image"; src: string; width: string; height: string } + +export type HighlightItem = { + title: string + description: string + shortDescription?: string + media: HighlightMedia +} + +export type HighlightGroup = { + source: string + items: HighlightItem[] +} + +export type ChangelogRelease = { + tag: string + name: string + date: string + url: string + highlights: HighlightGroup[] + sections: { title: string; items: string[] }[] +} + +export type ChangelogData = { + ok: boolean + releases: ChangelogRelease[] +} + +export async function loadChangelog(): Promise { + const response = await fetch("https://api.github.com/repos/anomalyco/opencode/releases?per_page=20", { + headers: { + Accept: "application/vnd.github.v3+json", + "User-Agent": "OpenCode-Console", + }, + cf: { + // best-effort edge caching (ignored outside Cloudflare) + cacheTtl: 60 * 5, + cacheEverything: true, + }, + } as RequestInit).catch(() => undefined) + + if (!response?.ok) return { ok: false, releases: [] } + + const data = await response.json().catch(() => undefined) + if (!Array.isArray(data)) return { ok: false, releases: [] } + + const releases = (data as Release[]).map((release) => { + const parsed = parseMarkdown(release.body || "") + return { + tag: release.tag_name, + name: release.name, + date: release.published_at, + url: release.html_url, + highlights: parsed.highlights, + sections: parsed.sections, + } + }) + + return { ok: true, releases } +} + +export const changelog = query(async () => { + "use server" + const result = await loadChangelog() + return result.releases +}, "changelog") + +function parseHighlights(body: string): HighlightGroup[] { + const groups = new Map() + const regex = /([\s\S]*?)<\/highlight>/g + let match + + while ((match = regex.exec(body)) !== null) { + const source = match[1] + const content = match[2] + + const titleMatch = content.match(/

([^<]+)<\/h2>/) + const pMatch = content.match(/([^<]+)<\/p>/) + const imgMatch = content.match(/ { + if (videoMatch) return { type: "video", src: videoMatch[1] } satisfies HighlightMedia + if (imgMatch) { + return { + type: "image", + src: imgMatch[3], + width: imgMatch[1], + height: imgMatch[2], + } satisfies HighlightMedia + } + })() + + if (!titleMatch || !media) continue + + const item: HighlightItem = { + title: titleMatch[1], + description: pMatch?.[2] || "", + shortDescription: pMatch?.[1], + media, + } + + if (!groups.has(source)) groups.set(source, []) + groups.get(source)!.push(item) + } + + return Array.from(groups.entries()).map(([source, items]) => ({ source, items })) +} + +function parseMarkdown(body: string) { + const lines = body.split("\n") + const sections: { title: string; items: string[] }[] = [] + let current: { title: string; items: string[] } | null = null + let skip = false + + for (const line of lines) { + if (line.startsWith("## ")) { + if (current) sections.push(current) + current = { title: line.slice(3).trim(), items: [] } + skip = false + continue + } + + if (line.startsWith("**Thank you")) { + skip = true + continue + } + + if (line.startsWith("- ") && !skip) current?.items.push(line.slice(2).trim()) + } + + if (current) sections.push(current) + return { sections, highlights: parseHighlights(body) } +} diff --git a/packages/console/app/src/lib/form-error.ts b/packages/console/app/src/lib/form-error.ts new file mode 100644 index 0000000000000000000000000000000000000000..d643a98f14b0fb5c8d06d4f9df76f9067af6accc --- /dev/null +++ b/packages/console/app/src/lib/form-error.ts @@ -0,0 +1,86 @@ +import type { Key } from "~/i18n" + +export const formError = { + invalidPlan: "error.invalidPlan", + workspaceRequired: "error.workspaceRequired", + alreadySubscribed: "error.alreadySubscribed", + limitRequired: "error.limitRequired", + monthlyLimitInvalid: "error.monthlyLimitInvalid", + workspaceNameRequired: "error.workspaceNameRequired", + nameTooLong: "error.nameTooLong", + emailRequired: "error.emailRequired", + roleRequired: "error.roleRequired", + idRequired: "error.idRequired", + nameRequired: "error.nameRequired", + providerRequired: "error.providerRequired", + apiKeyRequired: "error.apiKeyRequired", + modelRequired: "error.modelRequired", +} as const + +const map = { + [formError.invalidPlan]: "error.invalidPlan", + [formError.workspaceRequired]: "error.workspaceRequired", + [formError.alreadySubscribed]: "error.alreadySubscribed", + [formError.limitRequired]: "error.limitRequired", + [formError.monthlyLimitInvalid]: "error.monthlyLimitInvalid", + [formError.workspaceNameRequired]: "error.workspaceNameRequired", + [formError.nameTooLong]: "error.nameTooLong", + [formError.emailRequired]: "error.emailRequired", + [formError.roleRequired]: "error.roleRequired", + [formError.idRequired]: "error.idRequired", + [formError.nameRequired]: "error.nameRequired", + [formError.providerRequired]: "error.providerRequired", + [formError.apiKeyRequired]: "error.apiKeyRequired", + [formError.modelRequired]: "error.modelRequired", + "Invalid plan": "error.invalidPlan", + "Workspace ID is required": "error.workspaceRequired", + "Workspace ID is required.": "error.workspaceRequired", + "This workspace already has a subscription": "error.alreadySubscribed", + "Limit is required.": "error.limitRequired", + "Set a valid monthly limit": "error.monthlyLimitInvalid", + "Set a valid monthly limit.": "error.monthlyLimitInvalid", + "Workspace name is required.": "error.workspaceNameRequired", + "Name must be 255 characters or less.": "error.nameTooLong", + "Email is required": "error.emailRequired", + "Role is required": "error.roleRequired", + "ID is required": "error.idRequired", + "Name is required": "error.nameRequired", + "Provider is required": "error.providerRequired", + "API key is required": "error.apiKeyRequired", + "Model is required": "error.modelRequired", + "workspace.reload.error.paymentFailed": "workspace.reload.error.paymentFailed", + "Payment failed": "workspace.reload.error.paymentFailed", + "Payment failed.": "workspace.reload.error.paymentFailed", +} as const satisfies Record + +export function formErrorReloadAmountMin(amount: number) { + return `error.reloadAmountMin:${amount}` +} + +export function formErrorReloadTriggerMin(amount: number) { + return `error.reloadTriggerMin:${amount}` +} + +export function localizeError(t: (key: Key, params?: Record) => string, error?: string) { + if (!error) return "" + + if (error.startsWith("error.reloadAmountMin:")) { + const amount = Number(error.split(":")[1] ?? 0) + return t("error.reloadAmountMin", { amount }) + } + + if (error.startsWith("error.reloadTriggerMin:")) { + const amount = Number(error.split(":")[1] ?? 0) + return t("error.reloadTriggerMin", { amount }) + } + + const amount = error.match(/^Reload amount must be at least \$(\d+)$/) + if (amount) return t("error.reloadAmountMin", { amount: Number(amount[1]) }) + + const trigger = error.match(/^Balance trigger must be at least \$(\d+)$/) + if (trigger) return t("error.reloadTriggerMin", { amount: Number(trigger[1]) }) + + const key = map[error as keyof typeof map] + if (key) return t(key) + return error +} diff --git a/packages/console/app/src/lib/format-reset-time.ts b/packages/console/app/src/lib/format-reset-time.ts new file mode 100644 index 0000000000000000000000000000000000000000..2462a87a3f4b074ad16c144cdc0033afccb1636c --- /dev/null +++ b/packages/console/app/src/lib/format-reset-time.ts @@ -0,0 +1,47 @@ +import type { Key } from "~/i18n" +import type { useI18n } from "~/context/i18n" + +type ResetTimeKeys = { + day: Key + days: Key + hour: Key + hours: Key + minute: Key + minutes: Key + fewSeconds: Key +} + +export const liteResetTimeKeys = { + day: "workspace.lite.time.day", + days: "workspace.lite.time.days", + hour: "workspace.lite.time.hour", + hours: "workspace.lite.time.hours", + minute: "workspace.lite.time.minute", + minutes: "workspace.lite.time.minutes", + fewSeconds: "workspace.lite.time.fewSeconds", +} satisfies ResetTimeKeys + +export const blackResetTimeKeys = { + day: "workspace.black.time.day", + days: "workspace.black.time.days", + hour: "workspace.black.time.hour", + hours: "workspace.black.time.hours", + minute: "workspace.black.time.minute", + minutes: "workspace.black.time.minutes", + fewSeconds: "workspace.black.time.fewSeconds", +} satisfies ResetTimeKeys + +export function formatResetTime(seconds: number, i18n: ReturnType, keys: ResetTimeKeys) { + const days = Math.floor(seconds / 86400) + if (days >= 1) { + const hours = Math.floor((seconds % 86400) / 3600) + return `${days} ${days === 1 ? i18n.t(keys.day) : i18n.t(keys.days)} ${hours} ${hours === 1 ? i18n.t(keys.hour) : i18n.t(keys.hours)}` + } + + const hours = Math.floor(seconds / 3600) + const minutes = Math.floor((seconds % 3600) / 60) + if (hours >= 1) + return `${hours} ${hours === 1 ? i18n.t(keys.hour) : i18n.t(keys.hours)} ${minutes} ${minutes === 1 ? i18n.t(keys.minute) : i18n.t(keys.minutes)}` + if (minutes === 0) return i18n.t(keys.fewSeconds) + return `${minutes} ${minutes === 1 ? i18n.t(keys.minute) : i18n.t(keys.minutes)}` +} diff --git a/packages/console/app/src/lib/github.ts b/packages/console/app/src/lib/github.ts new file mode 100644 index 0000000000000000000000000000000000000000..ccde5972d37e9ba736097fcba0756cf43dc89a94 --- /dev/null +++ b/packages/console/app/src/lib/github.ts @@ -0,0 +1,38 @@ +import { query } from "@solidjs/router" +import { config } from "~/config" + +export const github = query(async () => { + "use server" + const headers = { + "User-Agent": + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + } + const apiBaseUrl = config.github.repoUrl.replace("https://github.com/", "https://api.github.com/repos/") + try { + const [meta, releases, contributors] = await Promise.all([ + fetch(apiBaseUrl, { headers }).then((res) => res.json()), + fetch(`${apiBaseUrl}/releases`, { headers }).then((res) => res.json()), + fetch(`${apiBaseUrl}/contributors?per_page=1`, { headers }), + ]) + if (!Array.isArray(releases) || releases.length === 0) { + return undefined + } + const [release] = releases + const linkHeader = contributors.headers.get("Link") + const contributorCount = linkHeader + ? Number.parseInt(linkHeader.match(/&page=(\d+)>; rel="last"/)?.at(1) ?? "0") + : 0 + return { + stars: meta.stargazers_count, + release: { + name: release.name, + url: release.html_url, + tag_name: release.tag_name, + }, + contributors: contributorCount, + } + } catch (e) { + console.error(e) + } + return undefined +}, "github") diff --git a/packages/console/app/src/lib/inference-proxy.ts b/packages/console/app/src/lib/inference-proxy.ts new file mode 100644 index 0000000000000000000000000000000000000000..1eade3ff8feec8ded63288ad3da235771303ad98 --- /dev/null +++ b/packages/console/app/src/lib/inference-proxy.ts @@ -0,0 +1,119 @@ +import { Resource } from "@opencode-ai/console-resource" +import { and, Database, eq, isNotNull, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js" +import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js" +import { ProviderTable } from "@opencode-ai/console-core/schema/provider.sql.js" +import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js" + +const paths: Record = { + "POST /zen/v1/chat/completions": "/openai/v1/chat/completions", + "POST /zen/v1/responses": "/openai/v1/responses", + "POST /zen/v1/messages": "/anthropic/v1/messages", + "POST /zen/go/v1/chat/completions": "/go/openai/v1/chat/completions", + "POST /zen/go/v1/responses": "/go/openai/v1/responses", + "POST /zen/go/v1/messages": "/go/anthropic/v1/messages", + "GET /zen/v1/models": "/v1/models", + "GET /zen/go/v1/models": "/go/v1/models", + "GET /zen/go/v1/usage": "/go/v1/usage", +} + +export async function proxyInference( + request: Request, + generation?: { + provider?: "openai" | "anthropic" | "google" + /** The provider's native model ID, not the public Zen alias. */ + model?: string + body: (model?: string) => ReadableStream + }, +): Promise { + const url = new URL(request.url) + const path = + paths[`${request.method} ${url.pathname}`] ?? + (request.method === "POST" && + /^\/zen\/v1\/models\/[^/]+:(?:generateContent|streamGenerateContent)$/.test(url.pathname) + ? url.pathname.replace("/zen/v1/models/", "/google/v1beta/models/") + : undefined) + if (!path) return undefined + + const key = url.pathname.endsWith("/messages") + ? request.headers.get("x-api-key") + : path.startsWith("/google/") + ? request.headers.get("x-goog-api-key") + : request.headers.get("authorization")?.split(" ")[1] + if (!key || key === "public") return undefined + + // New Console keys are never in the legacy key table; every legacy key is `sk-`. + const legacy = !key.startsWith("oc_sk_") + const workspace = legacy ? await migratedWorkspace(key, generation?.provider) : undefined + if (legacy && !workspace) return undefined + const model = workspace?.provider ? generation?.model : undefined + if (workspace?.provider && !model) throw new Error("Legacy BYOK model mapping is unavailable") + + const destination = new URL(Resource.ConsoleMigration.inferenceUrl) + // Imported connections must use this same workspace/provider-derived ID. + const target = + model && workspace + ? `/custom/conn_${workspace.id.slice(4)}_${workspace.provider}${ + path.startsWith("/google/") + ? `/models/${encodeURIComponent(model)}${url.pathname.slice(url.pathname.lastIndexOf(":"))}` + : url.pathname.slice("/zen/v1".length) + }` + : path + destination.pathname = `${destination.pathname.replace(/\/$/, "")}${target}` + destination.search = url.search + destination.hash = "" + + // Model extraction has already read part of the body; forward its replay stream. + const forwarded = new Request( + destination, + generation ? new Request(request, { method: request.method, body: generation.body(model) }) : request, + ) + // Migrated requests use ordinary destination authentication and accounting. + for (const name of [ + "x-zen", + "x-zen-model", + "x-zen-ip", + "cf-access-client-id", + "cf-access-client-secret", + "host", + "content-length", + ]) + forwarded.headers.delete(name) + forwarded.headers.set("authorization", `Bearer ${key}`) + const ip = request.headers.get("cf-connecting-ip") + if (ip) forwarded.headers.set("x-real-ip", ip) + const requestID = request.headers.get("x-opencode-request-id") ?? request.headers.get("x-opencode-request") + if (requestID) forwarded.headers.set("x-opencode-request-id", requestID) + + return fetch(forwarded, { redirect: "manual" }) +} + +// Routing only; the destination owns authentication and revocation after cutover. +function migratedWorkspace(key: string, provider?: string) { + return Database.use((tx) => + tx + .select({ id: WorkspaceTable.id, provider: ProviderTable.provider }) + .from(KeyTable) + .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID)) + .leftJoin( + ProviderTable, + provider + ? and( + eq(ProviderTable.workspaceID, KeyTable.workspaceID), + eq(ProviderTable.provider, provider), + isNull(ProviderTable.timeDeleted), + sql`length(${ProviderTable.credentials}) > 0`, + ) + : sql`false`, + ) + .where(and(eq(KeyTable.key, key), isNotNull(WorkspaceTable.migrated_at))) + .limit(1) + .then((rows) => rows[0]), + ) +} + +export function inferenceUnavailable() { + return Response.json( + { error: { type: "api_error", message: "Inference routing is unavailable. Please retry later." } }, + { status: 503, headers: { "Cache-Control": "no-store" } }, + ) +} diff --git a/packages/console/app/src/lib/language.ts b/packages/console/app/src/lib/language.ts new file mode 100644 index 0000000000000000000000000000000000000000..773f63d61508d109dd914e3c79712cde9cf8c913 --- /dev/null +++ b/packages/console/app/src/lib/language.ts @@ -0,0 +1,359 @@ +export const LOCALES = [ + "en", + "zh", + "zht", + "ko", + "de", + "es", + "fr", + "it", + "da", + "ja", + "pl", + "ru", + "uk", + "ar", + "no", + "br", + "th", + "tr", +] as const + +export type Locale = (typeof LOCALES)[number] + +export const LOCALE_COOKIE = "oc_locale" as const +export const LOCALE_HEADER = "x-opencode-locale" as const + +function fix(pathname: string) { + if (pathname.startsWith("/")) return pathname + return `/${pathname}` +} + +const LABEL = { + en: "English", + zh: "简体中文", + zht: "繁體中文", + ko: "한국어", + de: "Deutsch", + es: "Español", + fr: "Français", + it: "Italiano", + da: "Dansk", + ja: "日本語", + pl: "Polski", + ru: "Русский", + uk: "Українська", + ar: "العربية", + no: "Norsk", + br: "Português (Brasil)", + th: "ไทย", + tr: "Türkçe", +} satisfies Record + +const TAG = { + en: "en", + zh: "zh-Hans", + zht: "zh-Hant", + ko: "ko", + de: "de", + es: "es", + fr: "fr", + it: "it", + da: "da", + ja: "ja", + pl: "pl", + ru: "ru", + uk: "uk", + ar: "ar", + no: "no", + br: "pt-BR", + th: "th", + tr: "tr", +} satisfies Record + +const DOCS = { + en: "root", + zh: "zh-cn", + zht: "zh-tw", + ko: "ko", + de: "de", + es: "es", + fr: "fr", + it: "it", + da: "da", + ja: "ja", + pl: "pl", + ru: "ru", + uk: "uk", + ar: "ar", + no: "nb", + br: "pt-br", + th: "th", + tr: "tr", +} satisfies Record + +const DOCS_SEGMENT = new Set([ + "ar", + "bs", + "da", + "de", + "es", + "fr", + "it", + "ja", + "ko", + "nb", + "pl", + "pt-br", + "ru", + "th", + "tr", + "uk", + "zh-cn", + "zh-tw", +]) + +const DOCS_LOCALE = { + ar: "ar", + da: "da", + de: "de", + en: "en", + es: "es", + fr: "fr", + it: "it", + ja: "ja", + ko: "ko", + nb: "no", + "pt-br": "br", + root: "en", + ru: "ru", + th: "th", + tr: "tr", + uk: "uk", + "zh-cn": "zh", + "zh-tw": "zht", +} as const satisfies Record + +// Heading IDs from the localized Go documentation. +const GO_USAGE_LIMITS = { + en: "usage-limits", + zh: "使用限制", + zht: "使用限制", + ko: "사용-한도", + de: "nutzungslimits", + es: "límites-de-uso", + fr: "limites-dutilisation", + it: "limiti-di-utilizzo", + da: "forbrugsgrænser", + ja: "利用制限", + pl: "limity-użycia", + ru: "лимиты-использования", + uk: "usage-limits", + ar: "حدود-الاستخدام", + no: "bruksgrenser", + br: "limites-de-uso", + th: "usage-limits", + tr: "kullanım-limitleri", +} satisfies Record + +export function goUsageLimits(locale: Locale) { + // No Ukrainian Go docs yet; the explicit English path overrides the locale cookie. + if (locale === "uk") return "/docs/en/go/#usage-limits" + return docs(locale, `/docs/go/#${GO_USAGE_LIMITS[locale]}`) +} + +function suffix(pathname: string) { + const index = pathname.search(/[?#]/) + if (index === -1) { + return { + path: fix(pathname), + suffix: "", + } + } + + return { + path: fix(pathname.slice(0, index)), + suffix: pathname.slice(index), + } +} + +export function docs(locale: Locale, pathname: string) { + const value = DOCS[locale] + const next = suffix(pathname) + if (next.path !== "/docs" && next.path !== "/docs/" && !next.path.startsWith("/docs/")) { + return `${next.path}${next.suffix}` + } + + if (value === "root") { + if (next.path === "/docs/en") return `/docs${next.suffix}` + if (next.path === "/docs/en/") return `/docs/${next.suffix}` + if (next.path.startsWith("/docs/en/")) return `/docs/${next.path.slice("/docs/en/".length)}${next.suffix}` + return `${next.path}${next.suffix}` + } + + if (next.path === "/docs") return `/docs/${value}${next.suffix}` + if (next.path === "/docs/") return `/docs/${value}/${next.suffix}` + + const head = next.path.slice("/docs/".length).split("/")[0] ?? "" + if (!head) return `/docs/${value}/${next.suffix}` + if (DOCS_SEGMENT.has(head)) return `${next.path}${next.suffix}` + if (head.startsWith("_")) return `${next.path}${next.suffix}` + if (head.includes(".")) return `${next.path}${next.suffix}` + + return `/docs/${value}${next.path.slice("/docs".length)}${next.suffix}` +} + +export function parseLocale(value: unknown): Locale | null { + if (typeof value !== "string") return null + if ((LOCALES as readonly string[]).includes(value)) return value as Locale + return null +} + +export function fromPathname(pathname: string) { + return parseLocale(fix(pathname).split("/")[1]) +} + +export function fromDocsPathname(pathname: string) { + const next = fix(pathname) + const value = next.split("/")[2]?.toLowerCase() + if (!value) return null + if (!next.startsWith("/docs/")) return null + if (!(value in DOCS_LOCALE)) return null + return DOCS_LOCALE[value as keyof typeof DOCS_LOCALE] +} + +export function strip(pathname: string) { + const locale = fromPathname(pathname) + if (!locale) return fix(pathname) + + const next = fix(pathname).slice(locale.length + 1) + if (!next) return "/" + if (next.startsWith("/")) return next + return `/${next}` +} + +export function route(locale: Locale, pathname: string) { + const next = strip(pathname) + if (next.startsWith("/docs")) return docs(locale, next) + if (next.startsWith("/auth")) return next + if (next.startsWith("/workspace")) return next + if (locale === "en") return next + if (next === "/") return `/${locale}` + return `/${locale}${next}` +} + +export function label(locale: Locale) { + return LABEL[locale] +} + +export function tag(locale: Locale) { + return TAG[locale] +} + +export function dir(locale: Locale) { + if (locale === "ar") return "rtl" + return "ltr" +} + +function match(input: string): Locale | null { + const value = input.trim().toLowerCase() + if (!value) return null + + if (value.startsWith("zh")) { + if (value.includes("hant") || value.includes("-tw") || value.includes("-hk") || value.includes("-mo")) return "zht" + return "zh" + } + + if (value.startsWith("ko")) return "ko" + if (value.startsWith("de")) return "de" + if (value.startsWith("es")) return "es" + if (value.startsWith("fr")) return "fr" + if (value.startsWith("it")) return "it" + if (value.startsWith("da")) return "da" + if (value.startsWith("ja")) return "ja" + if (value.startsWith("pl")) return "pl" + if (value.startsWith("ru")) return "ru" + if (value.startsWith("uk")) return "uk" + if (value.startsWith("ar")) return "ar" + if (value.startsWith("tr")) return "tr" + if (value.startsWith("th")) return "th" + if (value.startsWith("pt")) return "br" + if (value.startsWith("no") || value.startsWith("nb") || value.startsWith("nn")) return "no" + if (value.startsWith("en")) return "en" + return null +} + +export function detectFromLanguages(languages: readonly string[]) { + for (const language of languages) { + const locale = match(language) + if (locale) return locale + } + return "en" satisfies Locale +} + +export function detectFromAcceptLanguage(header: string | null) { + if (!header) return "en" satisfies Locale + + const items = header + .split(",") + .map((raw) => raw.trim()) + .filter(Boolean) + .map((raw) => { + const parts = raw.split(";").map((x) => x.trim()) + const lang = parts[0] ?? "" + const q = parts + .slice(1) + .find((x) => x.startsWith("q=")) + ?.slice(2) + return { + lang, + q: q ? Number.parseFloat(q) : 1, + } + }) + .sort((a, b) => b.q - a.q) + + for (const item of items) { + if (!item.lang || item.lang === "*") continue + const locale = match(item.lang) + if (locale) return locale + } + + return "en" satisfies Locale +} + +export function localeFromCookieHeader(header: string | null) { + if (!header) return null + + const raw = header + .split(";") + .map((x) => x.trim()) + .find((x) => x.startsWith(`${LOCALE_COOKIE}=`)) + ?.slice(`${LOCALE_COOKIE}=`.length) + + if (!raw) return null + return parseLocale(decodeURIComponent(raw)) +} + +export function localeFromRequest(request: Request) { + const fromHeader = parseLocale(request.headers.get(LOCALE_HEADER)) + if (fromHeader) return fromHeader + + const fromPath = fromPathname(new URL(request.url).pathname) + if (fromPath) return fromPath + + const fromDocsPath = fromDocsPathname(new URL(request.url).pathname) + if (fromDocsPath) return fromDocsPath + + return ( + localeFromCookieHeader(request.headers.get("cookie")) ?? + detectFromAcceptLanguage(request.headers.get("accept-language")) + ) +} + +export function cookie(locale: Locale) { + return `${LOCALE_COOKIE}=${encodeURIComponent(locale)}; Path=/; Max-Age=31536000; SameSite=Lax` +} + +export function clearCookie() { + return `${LOCALE_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax` +} diff --git a/packages/console/app/src/lib/lite-usage.ts b/packages/console/app/src/lib/lite-usage.ts new file mode 100644 index 0000000000000000000000000000000000000000..618c89e92d75ae69a5eeb925f3be3fdad22583d2 --- /dev/null +++ b/packages/console/app/src/lib/lite-usage.ts @@ -0,0 +1,73 @@ +export type LiteUsageBreakdownSource = { + model: string + name: string + cost: number + quotaCost: number + multiplier?: number + estimated: boolean +} + +export type LiteUsageBreakdownItem = { + model: string + name: string + cost?: number + multiplier?: number + quotaCost: number + contributionPercent: number + estimated: boolean +} + +export function buildLiteUsageBreakdown(input: { usage: number; limit: number; sources: LiteUsageBreakdownSource[] }) { + // Legacy usage can resolve to the same rate as a separately grouped recorded multiplier. + const groups = new Map() + input.sources.forEach((item) => { + const key = JSON.stringify([item.model, item.multiplier]) + const row = groups.get(key) + if (!row) { + groups.set(key, { ...item }) + return + } + row.cost += item.cost + row.quotaCost += item.quotaCost + row.estimated ||= item.estimated + }) + const rows: LiteUsageBreakdownItem[] = Array.from(groups.values()) + .filter((item) => item.cost !== 0 || item.quotaCost !== 0) + .sort((a, b) => b.quotaCost - a.quotaCost) + .map((item) => ({ + ...item, + contributionPercent: 0, + })) + + const usagePercent = getUsagePercent(input.usage, input.limit) + const target = Math.max(0, Math.round(usagePercent * 10)) + const totalQuota = rows.reduce((total, item) => total + Math.max(0, item.quotaCost), 0) + const units = rows.map((item) => { + const exact = totalQuota === 0 ? 0 : (Math.max(0, item.quotaCost) / totalQuota) * target + const value = Math.floor(exact) + return { item, exact, value } + }) + const remaining = target - units.reduce((total, item) => total + item.value, 0) + const ranked = units.toSorted((a, b) => b.exact - b.value - (a.exact - a.value)) + Array.from({ length: ranked.length === 0 ? 0 : remaining }).forEach((_, index) => { + ranked[index % ranked.length].value += 1 + }) + units.forEach((unit) => (unit.item.contributionPercent = unit.value / 10)) + + return { + usage: input.usage, + limit: input.limit, + usagePercent, + rows, + } +} + +export function getModelQuotaLimit(limit: number, multiplier?: number) { + if (multiplier === undefined || multiplier <= 0) return + return limit / multiplier +} + +export function getUsagePercent(amount: number, limit: number) { + if (limit === 0) return 0 + return Math.round((amount / limit) * 1000) / 10 +} diff --git a/packages/console/app/src/lib/referral-invite.ts b/packages/console/app/src/lib/referral-invite.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc83ff0f4cde7537ed1228f8ac7181eb6135d5c8 --- /dev/null +++ b/packages/console/app/src/lib/referral-invite.ts @@ -0,0 +1,44 @@ +import { Actor } from "@opencode-ai/console-core/actor.js" +import { Referral } from "@opencode-ai/console-core/referral.js" +import { getRequestEvent } from "solid-js/web" + +const REFERRAL_COOKIE = "oc_referral" +const REFERRAL_MAX_AGE = 60 * 60 * 24 * 30 + +export function normalizeReferralCode(code?: string | null) { + return Referral.normalizeCode(code) +} + +export function referralCookie(code: string) { + return `${REFERRAL_COOKIE}=${encodeURIComponent(code)}; Path=/; Max-Age=${REFERRAL_MAX_AGE}; SameSite=Lax; HttpOnly` +} + +export function clearReferralCookie() { + return `${REFERRAL_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax; HttpOnly` +} + +export function referralCodeFromCookieHeader(header: string | null) { + if (!header) return undefined + + return normalizeReferralCode( + header + .split(";") + .map((x) => x.trim()) + .find((x) => x.startsWith(`${REFERRAL_COOKIE}=`)) + ?.slice(`${REFERRAL_COOKIE}=`.length), + ) +} + +export async function createReferralFromCookie() { + const event = getRequestEvent() + const referralCode = referralCodeFromCookieHeader(event?.request.headers.get("cookie") ?? null) + if (!referralCode) return + + await Referral.createFromAccount({ + accountID: Actor.account(), + referralCode, + }).catch((error) => { + console.error("Referral create failed", error) + }) + event?.response.headers.append("set-cookie", clearReferralCookie()) +} diff --git a/packages/console/app/src/lib/request-country.ts b/packages/console/app/src/lib/request-country.ts new file mode 100644 index 0000000000000000000000000000000000000000..5806fc2f64acedf0c1e4f39115b7e80a18208437 --- /dev/null +++ b/packages/console/app/src/lib/request-country.ts @@ -0,0 +1,43 @@ +const MUSE_SPARK_BLOCKED_COUNTRIES = new Set([ + "AF", + "BY", + "CN", + "CU", + "EH", + "ER", + "ET", + "HK", + "HT", + "IQ", + "IR", + "KH", + "KP", + "LY", + "MM", + "MO", + "NI", + "PK", + "RU", + "SO", + "SY", + "VE", +]) + +export function countryFromRequest(request: Request | undefined) { + if (!request) return undefined + const cloudflareRequest = request as Request & { cf?: { country?: string } } + return cloudflareRequest.cf?.country ?? request.headers.get("cf-ipcountry") ?? undefined +} + +export function isModelCountryRestricted(model: string, country: string | undefined) { + return ( + [ + "muse-spark-1.3-contributor", + "muse-spark-1.3-contributor-free", + "muse-spark-1.2-contributor", + "muse-spark-1.2-contributor-free", + ].includes(model) && + country !== undefined && + MUSE_SPARK_BLOCKED_COUNTRIES.has(country.toUpperCase()) + ) +} diff --git a/packages/console/app/src/lib/salesforce.ts b/packages/console/app/src/lib/salesforce.ts new file mode 100644 index 0000000000000000000000000000000000000000..48e0caee7d0608aa810a6075209de9e58babf021 --- /dev/null +++ b/packages/console/app/src/lib/salesforce.ts @@ -0,0 +1,81 @@ +import { Resource } from "@opencode-ai/console-resource" + +async function login() { + const url = Resource.SALESFORCE_INSTANCE_URL.value.replace(/\/$/, "") + const clientId = Resource.SALESFORCE_CLIENT_ID.value + const clientSecret = Resource.SALESFORCE_CLIENT_SECRET.value + + const params = new URLSearchParams({ + grant_type: "client_credentials", + client_id: clientId, + client_secret: clientSecret, + }) + + const res = await fetch(`${url}/services/oauth2/token`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: params.toString(), + }).catch((err) => { + console.error("Failed to fetch Salesforce access token:", err) + }) + + if (!res) return + + if (!res.ok) { + console.error("Failed to fetch Salesforce access token:", res.status, await res.text()) + return + } + + const data = (await res.json()) as { access_token?: string; instance_url?: string } + if (!data.access_token) { + console.error("Salesforce auth response did not include an access token") + return + } + + return { + token: data.access_token, + url: data.instance_url ?? url, + } +} + +export interface SalesforceLeadInput { + name: string + role: string + company?: string + email: string + phone?: string + message: string +} + +export async function createLead(input: SalesforceLeadInput): Promise { + const auth = await login() + if (!auth) return false + + const res = await fetch(`${auth.url}/services/data/v59.0/sobjects/Lead`, { + method: "POST", + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + LastName: input.name, + Company: input.company?.trim() || "Website", + Email: input.email, + Phone: input.phone ?? null, + Title: input.role, + Description: input.message, + LeadSource: "Website", + }), + }).catch((err) => { + console.error("Failed to create Salesforce lead:", err) + }) + + if (!res) return false + + if (!res.ok) { + console.error("Failed to create Salesforce lead:", res.status, await res.text()) + return false + } + + return true +} diff --git a/packages/console/app/src/lib/server-action.ts b/packages/console/app/src/lib/server-action.ts new file mode 100644 index 0000000000000000000000000000000000000000..1d82b5697824ebf4ee0a6b317ca184ff90f7f9a0 --- /dev/null +++ b/packages/console/app/src/lib/server-action.ts @@ -0,0 +1,11 @@ +export function sanitizeServerActionRequest(request: Request) { + const requestUrl = new URL(request.url) + if (requestUrl.pathname !== "/_server") return request + + const referer = request.headers.get("referer") + if (referer && URL.canParse(referer) && new URL(referer).origin === requestUrl.origin) return request + + const sanitized = new Request(request) + sanitized.headers.set("referer", requestUrl.origin) + return sanitized +} diff --git a/packages/console/app/src/lib/stats-proxy.ts b/packages/console/app/src/lib/stats-proxy.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8db97c06396a8c01aaefe7f24008131d118edc2 --- /dev/null +++ b/packages/console/app/src/lib/stats-proxy.ts @@ -0,0 +1,164 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Resource, waitUntil } from "@opencode-ai/console-resource" +import { LOCALE_HEADER, cookie, localeFromRequest, route, tag } from "~/lib/language" + +const dataPath = "/data" +const statsCacheParam = "__opencode_stats_locale" + +export async function statsProxy(evt: APIEvent) { + const req = evt.request.clone() + const locale = localeFromRequest(req) + const redirect = redirectToLocalizedData(req, new URL(req.url), locale) + if (redirect) return redirect + + const cache = defaultCache(caches) + const cacheKey = statsCacheKey(req, locale) + if (cacheKey) { + const cached = await cache.match(cacheKey) + if (cached) return withStatsCacheStatus(cached, "HIT") + } + + const targetUrl = new URL(req.url) + targetUrl.protocol = "https:" + targetUrl.hostname = Resource.App.stage === "production" ? "stats.opencode.ai" : "stats.dev.opencode.ai" + targetUrl.port = "" + + if ( + targetUrl.pathname.startsWith(`${dataPath}/_build/`) || + targetUrl.pathname === `${dataPath}/banner.jpg` || + targetUrl.pathname === `${dataPath}/banner.png` || + targetUrl.pathname === `${dataPath}/sitemap.xml` + ) { + targetUrl.pathname = targetUrl.pathname.slice(dataPath.length) + } + + const requestHeaders = new Headers(req.headers) + requestHeaders.set(LOCALE_HEADER, locale) + requestHeaders.set("accept-language", tag(locale)) + + const response = await fetch(targetUrl, { + method: req.method, + headers: requestHeaders, + body: req.body, + }) + + if (!response.headers.get("content-type")?.includes("text/html")) return response + + const headers = new Headers(response.headers) + headers.delete("content-encoding") + headers.delete("content-length") + headers.delete("etag") + headers.delete("set-cookie") + appendVary(headers, "Accept-Language", "Cookie", LOCALE_HEADER) + + const result = new Response(rewriteStatsHtml(await response.text()), { + status: response.status, + statusText: response.statusText, + headers, + }) + if (!cacheKey || !response.ok) return result + + void waitUntil(cache.put(cacheKey, result.clone())) + return withStatsCacheStatus(result, "MISS") +} + +export function statsRedirect(evt: APIEvent) { + const url = new URL(evt.request.url) + url.pathname = `${dataPath}${url.pathname.slice("/stats".length)}` + return new Response(null, { + status: 308, + headers: { + Location: url.toString(), + }, + }) +} + +function rewriteStatsHtml(html: string) { + return html.replaceAll('"/_build/', `"${dataPath}/_build/`).replaceAll("'/_build/", `'${dataPath}/_build/`) +} + +function statsCacheKey(request: Request, locale: ReturnType): Request | undefined { + if (request.method !== "GET") return undefined + if (!acceptsHtml(request)) return undefined + if (isDataBypassPath(new URL(request.url).pathname)) return undefined + + const url = new URL(request.url) + const additionalModels = url.searchParams.get("add") + url.search = "" + if (additionalModels) url.searchParams.set("add", additionalModels) + url.searchParams.set(statsCacheParam, locale) + return new Request(url) +} + +function defaultCache(storage: CacheStorage) { + if (!isCloudflareCacheStorage(storage)) throw new Error("Cloudflare default cache is unavailable") + return storage.default +} + +function isCloudflareCacheStorage(storage: CacheStorage): storage is CacheStorage & { default: Cache } { + return "default" in storage +} + +function withStatsCacheStatus(response: Response, status: "HIT" | "MISS") { + const headers = new Headers(response.headers) + headers.set("x-opencode-stats-cache", status) + return new Response(response.body, { status: response.status, statusText: response.statusText, headers }) +} + +function redirectToLocalizedData(request: Request, url: URL, locale: ReturnType) { + if (locale === "en") return null + if (request.headers.get(LOCALE_HEADER)) return null + if (request.method !== "GET" && request.method !== "HEAD") return null + if (!acceptsHtml(request)) return null + if (!url.pathname.startsWith(`${dataPath}/`) && url.pathname !== dataPath) return null + if (isDataBypassPath(url.pathname)) return null + + const next = new URL(url) + next.pathname = route(locale, url.pathname) + + const headers = new Headers({ + Location: next.toString(), + }) + headers.append("set-cookie", cookie(locale)) + appendVary(headers, "Accept-Language", "Cookie", LOCALE_HEADER) + + return new Response(null, { + status: 308, + headers, + }) +} + +function acceptsHtml(request: Request) { + const accept = request.headers.get("accept") + return !accept || accept.includes("text/html") || accept.includes("*/*") +} + +function isDataBypassPath(pathname: string) { + return ( + pathname.startsWith(`${dataPath}/_build/`) || + pathname.startsWith(`${dataPath}/api/`) || + pathname.startsWith(`${dataPath}/_server`) || + pathname === `${dataPath}/banner.jpg` || + pathname === `${dataPath}/banner.png` || + pathname === `${dataPath}/sitemap.xml` + ) +} + +function appendVary(headers: Headers, ...values: string[]) { + const existing = headers + .get("vary") + ?.split(",") + .map((value) => value.trim()) + .filter(Boolean) + + headers.set( + "vary", + values + .reduce( + (result, value) => + result.some((item) => item.toLowerCase() === value.toLowerCase()) ? result : [...result, value], + existing ?? [], + ) + .join(", "), + ) +} diff --git a/packages/console/app/src/middleware.ts b/packages/console/app/src/middleware.ts new file mode 100644 index 0000000000000000000000000000000000000000..614cc87bcf00b9e46608c29e266778d88d40f8bf --- /dev/null +++ b/packages/console/app/src/middleware.ts @@ -0,0 +1,23 @@ +import { createMiddleware } from "@solidjs/start/middleware" +import { LOCALE_HEADER, cookie, fromPathname, strip } from "~/lib/language" +import { normalizeReferralCode, referralCookie } from "~/lib/referral-invite" +import { sanitizeServerActionRequest } from "~/lib/server-action" + +export default createMiddleware({ + async onRequest(event) { + event.request = sanitizeServerActionRequest(event.request) + + const url = new URL(event.request.url) + const locale = fromPathname(url.pathname) + if (locale) { + url.pathname = strip(url.pathname) + const request = new Request(url, event.request) + request.headers.set(LOCALE_HEADER, locale) + event.request = request + event.response.headers.append("set-cookie", cookie(locale)) + } + + const referralCode = normalizeReferralCode(url.searchParams.get("ref")) + if (referralCode) event.response.headers.append("set-cookie", referralCookie(referralCode)) + }, +}) diff --git a/packages/console/app/src/routes/[...404].css b/packages/console/app/src/routes/[...404].css new file mode 100644 index 0000000000000000000000000000000000000000..1edbd0a5a70cdd935a1685f5499739add29a028b --- /dev/null +++ b/packages/console/app/src/routes/[...404].css @@ -0,0 +1,130 @@ +[data-page="not-found"] { + --color-text: hsl(224, 10%, 10%); + --color-text-secondary: hsl(224, 7%, 46%); + --color-text-dimmed: hsl(224, 6%, 63%); + --color-text-inverted: hsl(0, 0%, 100%); + + --color-border: hsl(224, 6%, 77%); +} + +[data-page="not-found"] { + @media (prefers-color-scheme: dark) { + --color-text: hsl(0, 0%, 100%); + --color-text-secondary: hsl(224, 6%, 66%); + --color-text-dimmed: hsl(224, 7%, 46%); + --color-text-inverted: hsl(224, 10%, 10%); + + --color-border: hsl(224, 6%, 36%); + } +} + +[data-page="not-found"] { + --padding: 3rem; + --vertical-padding: 1.5rem; + --heading-font-size: 1.375rem; + + @media (max-width: 30rem) { + --padding: 1rem; + --vertical-padding: 0.75rem; + --heading-font-size: 1rem; + } + + font-family: var(--font-mono); + color: var(--color-text); + padding: calc(var(--padding) + 1rem); + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + + a { + color: var(--color-text); + text-decoration: underline; + text-underline-offset: var(--space-0-75); + text-decoration-thickness: 1px; + } + + [data-component="content"] { + max-width: 40rem; + width: 100%; + border: 1px solid var(--color-border); + } + + [data-component="top"] { + padding: var(--padding); + display: flex; + flex-direction: column; + align-items: center; + gap: calc(var(--vertical-padding) / 2); + text-align: center; + + [data-slot="logo-link"] { + text-decoration: none; + } + + img { + height: auto; + width: clamp(200px, 85vw, 400px); + } + + [data-slot="logo dark"] { + display: none; + } + + @media (prefers-color-scheme: dark) { + [data-slot="logo light"] { + display: none; + } + [data-slot="logo dark"] { + display: block; + } + } + + [data-slot="title"] { + line-height: 1.25; + font-weight: 500; + text-align: center; + font-size: var(--heading-font-size); + color: var(--color-text); + text-transform: uppercase; + margin: 0; + } + } + + [data-component="actions"] { + border-top: 1px solid var(--color-border); + display: flex; + + [data-slot="action"] { + flex: 1; + text-align: center; + line-height: 1.4; + padding: var(--vertical-padding) 1rem; + text-transform: uppercase; + font-size: 1rem; + + a { + display: block; + width: 100%; + height: 100%; + color: var(--color-text); + text-decoration: underline; + text-underline-offset: var(--space-0-75); + text-decoration-thickness: 1px; + } + } + + [data-slot="action"] + [data-slot="action"] { + border-left: 1px solid var(--color-border); + } + + @media (max-width: 40rem) { + flex-direction: column; + + [data-slot="action"] + [data-slot="action"] { + border-left: none; + border-top: 1px solid var(--color-border); + } + } + } +} diff --git a/packages/console/app/src/routes/[...404].tsx b/packages/console/app/src/routes/[...404].tsx new file mode 100644 index 0000000000000000000000000000000000000000..e20ec36fd6695f1d6be5fcfe8df49d3efb0d441e --- /dev/null +++ b/packages/console/app/src/routes/[...404].tsx @@ -0,0 +1,42 @@ +import "./[...404].css" +import { Title } from "@solidjs/meta" +import { HttpStatusCode } from "@solidjs/start" +import logoLight from "../asset/logo-ornate-light.svg" +import logoDark from "../asset/logo-ornate-dark.svg" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" + +export default function NotFound() { + const i18n = useI18n() + const language = useLanguage() + return ( +
+ {i18n.t("notFound.title")} + + +
+ ) +} diff --git a/packages/console/app/src/routes/api/enterprise.ts b/packages/console/app/src/routes/api/enterprise.ts new file mode 100644 index 0000000000000000000000000000000000000000..65f5c72b23115b1975093c8af0d580668842a1b5 --- /dev/null +++ b/packages/console/app/src/routes/api/enterprise.ts @@ -0,0 +1,129 @@ +import type { APIEvent } from "@solidjs/start/server" +import { AWS } from "@opencode-ai/console-core/aws.js" +import { Resource } from "@opencode-ai/console-resource" +import { i18n } from "~/i18n" +import { localeFromRequest } from "~/lib/language" +import { createLead } from "~/lib/salesforce" + +interface EnterpriseFormData { + name: string + role: string + company?: string + email: string + phone?: string + alias?: string + message: string +} + +const EMAIL_OCTOPUS_LIST_ID = "1b381e5e-39bd-11f1-ba4a-cdd4791f0c43" + +function splitFullName(fullName: string) { + const parts = fullName + .trim() + .split(/\s+/) + .filter((p) => p.length > 0) + if (parts.length === 0) return { firstName: "", lastName: "" } + if (parts.length === 1) return { firstName: parts[0], lastName: "" } + return { firstName: parts[0], lastName: parts.slice(1).join(" ") } +} + +function subscribe(email: string, fullName: string) { + const name = splitFullName(fullName) + const fields: Record = {} + if (name.firstName) fields.FirstName = name.firstName + if (name.lastName) fields.LastName = name.lastName + + const payload: { email_address: string; fields?: Record } = { email_address: email } + if (Object.keys(fields).length) payload.fields = fields + + return fetch(`https://api.emailoctopus.com/lists/${EMAIL_OCTOPUS_LIST_ID}/contacts`, { + method: "PUT", + headers: { + Authorization: `Bearer ${Resource.EMAILOCTOPUS_API_KEY.value}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + }).then( + async (res) => { + if (!res.ok) { + console.error("EmailOctopus subscribe failed:", res.status, res.statusText, await res.text()) + return false + } + return true + }, + (err) => { + console.error("Failed to subscribe enterprise email:", err) + return false + }, + ) +} + +export async function POST(event: APIEvent) { + const dict = i18n(localeFromRequest(event.request)) + try { + const body = (await event.request.json()) as EnterpriseFormData + const trap = typeof body.alias === "string" ? body.alias.trim() : "" + + if (trap) { + return Response.json({ success: true, message: dict["enterprise.form.success.submitted"] }, { status: 200 }) + } + + if (!body.name || !body.role || !body.email || !body.message) { + return Response.json({ error: dict["enterprise.form.error.allFieldsRequired"] }, { status: 400 }) + } + + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + if (!emailRegex.test(body.email)) { + return Response.json({ error: dict["enterprise.form.error.invalidEmailFormat"] }, { status: 400 }) + } + + const emailContent = ` +${body.message}

+--
+${body.name}
+${body.role}
+${body.company ? `${body.company}
` : ""}${body.email}
+${body.phone ? `${body.phone}
` : ""}`.trim() + + const [lead, mail, octopus] = await Promise.all([ + createLead({ + name: body.name, + role: body.role, + company: body.company, + email: body.email, + phone: body.phone, + message: body.message, + }).catch((err) => { + console.error("Failed to create Salesforce lead:", err) + return false + }), + AWS.sendEmail({ + to: Resource.ENTERPRISE_SALES_INBOX_EMAIL.value, + subject: `Enterprise Inquiry from ${body.name}`, + body: emailContent, + replyTo: body.email, + }).then( + () => true, + (err) => { + console.error("Failed to send enterprise email:", err) + return false + }, + ), + subscribe(body.email, body.name), + ]) + + if (!lead && !mail && !octopus) { + if (import.meta.env.DEV) { + console.warn("Enterprise inquiry accepted in dev mode without integrations", { email: body.email }) + return Response.json({ success: true, message: dict["enterprise.form.success.submitted"] }, { status: 200 }) + } + console.error("Enterprise inquiry delivery failed", { email: body.email }) + return Response.json({ error: dict["enterprise.form.error.internalServer"] }, { status: 500 }) + } + + return Response.json({ success: true, message: dict["enterprise.form.success.submitted"] }, { status: 200 }) + } catch (error) { + console.error("Error processing enterprise form:", error) + return Response.json({ error: dict["enterprise.form.error.internalServer"] }, { status: 500 }) + } +} diff --git a/packages/console/app/src/routes/api/support/actions/block-workspaces.ts b/packages/console/app/src/routes/api/support/actions/block-workspaces.ts new file mode 100644 index 0000000000000000000000000000000000000000..9f1fc0e9a3eb1e03b4a439848e0d3fcfd5eb80fb --- /dev/null +++ b/packages/console/app/src/routes/api/support/actions/block-workspaces.ts @@ -0,0 +1,22 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Workspace } from "@opencode-ai/console-core/workspace.js" +import { safeEqual } from "@opencode-ai/console-core/util/crypto.js" +import { Resource } from "@opencode-ai/console-resource" +import z from "zod" + +const Body = z.object({ workspaceIDs: z.array(z.string().startsWith("wrk_")).min(1) }) + +export async function POST(event: APIEvent) { + if (!safeEqual(event.request.headers.get("authorization") ?? "", `Bearer ${Resource.SUPPORT_API_KEY.value}`)) { + return Response.json({ error: "Unauthorized" }, { status: 401 }) + } + + const body = Body.safeParse(await event.request.json().catch(() => undefined)) + if (!body.success) { + return Response.json({ error: "Invalid request", issues: body.error.issues }, { status: 400 }) + } + // Missing IDs do not fail the batch; they are reported per item in the result. + return Workspace.blockBatch(body.data) + .then((result) => Response.json({ success: true, message: "Workspaces blocked", result })) + .catch((error) => Response.json({ error: error instanceof Error ? error.message : String(error) }, { status: 400 })) +} diff --git a/packages/console/app/src/routes/api/support/actions/create-referral.ts b/packages/console/app/src/routes/api/support/actions/create-referral.ts new file mode 100644 index 0000000000000000000000000000000000000000..ac4d107bee10e540ec0850002a6bb47c2e5cbf26 --- /dev/null +++ b/packages/console/app/src/routes/api/support/actions/create-referral.ts @@ -0,0 +1,24 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Referral } from "@opencode-ai/console-core/referral.js" +import { safeEqual } from "@opencode-ai/console-core/util/crypto.js" +import { Resource } from "@opencode-ai/console-resource" +import z from "zod" + +const Body = z.object({ + inviterWorkspaceID: z.string().startsWith("wrk_"), + inviteeWorkspaceID: z.string().startsWith("wrk_"), +}) + +export async function POST(event: APIEvent) { + if (!safeEqual(event.request.headers.get("authorization") ?? "", `Bearer ${Resource.SUPPORT_API_KEY.value}`)) { + return Response.json({ error: "Unauthorized" }, { status: 401 }) + } + + const body = Body.safeParse(await event.request.json().catch(() => undefined)) + if (!body.success) { + return Response.json({ error: "Invalid request", issues: body.error.issues }, { status: 400 }) + } + return Referral.create(body.data) + .then((result) => Response.json({ success: true, message: "Referral created", result })) + .catch((error) => Response.json({ error: error instanceof Error ? error.message : String(error) }, { status: 400 })) +} diff --git a/packages/console/app/src/routes/api/support/actions/delete-account.ts b/packages/console/app/src/routes/api/support/actions/delete-account.ts new file mode 100644 index 0000000000000000000000000000000000000000..a713107df64dff7baadd272e0b51256d6f108cd1 --- /dev/null +++ b/packages/console/app/src/routes/api/support/actions/delete-account.ts @@ -0,0 +1,21 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Account } from "@opencode-ai/console-core/account.js" +import { safeEqual } from "@opencode-ai/console-core/util/crypto.js" +import { Resource } from "@opencode-ai/console-resource" +import z from "zod" + +const Body = z.object({ email: z.email() }) + +export async function DELETE(event: APIEvent) { + if (!safeEqual(event.request.headers.get("authorization") ?? "", `Bearer ${Resource.SUPPORT_API_KEY.value}`)) { + return Response.json({ error: "Unauthorized" }, { status: 401 }) + } + + const body = Body.safeParse(await event.request.json().catch(() => undefined)) + if (!body.success) { + return Response.json({ error: "Invalid request", issues: body.error.issues }, { status: 400 }) + } + return Account.remove(body.data.email) + .then(() => Response.json({ success: true, message: "Account deleted" })) + .catch((error) => Response.json({ error: error instanceof Error ? error.message : String(error) }, { status: 400 })) +} diff --git a/packages/console/app/src/routes/api/support/actions/reset-quota.ts b/packages/console/app/src/routes/api/support/actions/reset-quota.ts new file mode 100644 index 0000000000000000000000000000000000000000..6f5c2812cfe017773eabd3bd5ec5abfd354cf2bb --- /dev/null +++ b/packages/console/app/src/routes/api/support/actions/reset-quota.ts @@ -0,0 +1,24 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Quota } from "@opencode-ai/console-core/quota.js" +import { safeEqual } from "@opencode-ai/console-core/util/crypto.js" +import { Resource } from "@opencode-ai/console-resource" +import z from "zod" + +const Body = z.object({ + workspaceID: z.string().startsWith("wrk_"), + plan: z.enum(["lite", "subscription"]), +}) + +export async function POST(event: APIEvent) { + if (!safeEqual(event.request.headers.get("authorization") ?? "", `Bearer ${Resource.SUPPORT_API_KEY.value}`)) { + return Response.json({ error: "Unauthorized" }, { status: 401 }) + } + + const body = Body.safeParse(await event.request.json().catch(() => undefined)) + if (!body.success) { + return Response.json({ error: "Invalid request", issues: body.error.issues }, { status: 400 }) + } + return Quota.reset(body.data) + .then((result) => Response.json({ success: true, message: "Usage counters reset to zero", result })) + .catch((error) => Response.json({ error: error instanceof Error ? error.message : String(error) }, { status: 400 })) +} diff --git a/packages/console/app/src/routes/api/support/actions/unblock-workspace.ts b/packages/console/app/src/routes/api/support/actions/unblock-workspace.ts new file mode 100644 index 0000000000000000000000000000000000000000..fd4baa07fda16b74967d21603e5e8972b74f150a --- /dev/null +++ b/packages/console/app/src/routes/api/support/actions/unblock-workspace.ts @@ -0,0 +1,21 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Workspace } from "@opencode-ai/console-core/workspace.js" +import { safeEqual } from "@opencode-ai/console-core/util/crypto.js" +import { Resource } from "@opencode-ai/console-resource" +import z from "zod" + +const Body = z.object({ workspaceID: z.string().startsWith("wrk_") }) + +export async function POST(event: APIEvent) { + if (!safeEqual(event.request.headers.get("authorization") ?? "", `Bearer ${Resource.SUPPORT_API_KEY.value}`)) { + return Response.json({ error: "Unauthorized" }, { status: 401 }) + } + + const body = Body.safeParse(await event.request.json().catch(() => undefined)) + if (!body.success) { + return Response.json({ error: "Invalid request", issues: body.error.issues }, { status: 400 }) + } + return Workspace.unblock(body.data) + .then(() => Response.json({ success: true, message: "Workspace unblocked" })) + .catch((error) => Response.json({ error: error instanceof Error ? error.message : String(error) }, { status: 400 })) +} diff --git a/packages/console/app/src/routes/api/support/actions/unblock-workspaces.ts b/packages/console/app/src/routes/api/support/actions/unblock-workspaces.ts new file mode 100644 index 0000000000000000000000000000000000000000..59ac1f354ebf8ea5bcc9a7038c29c4eb1cdf7b81 --- /dev/null +++ b/packages/console/app/src/routes/api/support/actions/unblock-workspaces.ts @@ -0,0 +1,22 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Workspace } from "@opencode-ai/console-core/workspace.js" +import { safeEqual } from "@opencode-ai/console-core/util/crypto.js" +import { Resource } from "@opencode-ai/console-resource" +import z from "zod" + +const Body = z.object({ workspaceIDs: z.array(z.string().startsWith("wrk_")).min(1) }) + +export async function POST(event: APIEvent) { + if (!safeEqual(event.request.headers.get("authorization") ?? "", `Bearer ${Resource.SUPPORT_API_KEY.value}`)) { + return Response.json({ error: "Unauthorized" }, { status: 401 }) + } + + const body = Body.safeParse(await event.request.json().catch(() => undefined)) + if (!body.success) { + return Response.json({ error: "Invalid request", issues: body.error.issues }, { status: 400 }) + } + // Missing IDs do not fail the batch; they are reported per item in the result. + return Workspace.unblockBatch(body.data) + .then((result) => Response.json({ success: true, message: "Workspaces unblocked", result })) + .catch((error) => Response.json({ error: error instanceof Error ? error.message : String(error) }, { status: 400 })) +} diff --git a/packages/console/app/src/routes/auth/[...callback].ts b/packages/console/app/src/routes/auth/[...callback].ts new file mode 100644 index 0000000000000000000000000000000000000000..00bb89406fc8787c011eb35bf3c414b796fbf8ff --- /dev/null +++ b/packages/console/app/src/routes/auth/[...callback].ts @@ -0,0 +1,46 @@ +import { redirect } from "@solidjs/router" +import type { APIEvent } from "@solidjs/start/server" +import { AuthClient } from "~/context/auth" +import { useAuthSession } from "~/context/auth" +import { i18n } from "~/i18n" +import { localeFromRequest, route } from "~/lib/language" + +export async function GET(input: APIEvent) { + const url = new URL(input.request.url) + const locale = localeFromRequest(input.request) + const dict = i18n(locale) + + try { + const code = url.searchParams.get("code") + if (!code) throw new Error(dict["auth.callback.error.codeMissing"]) + const result = await AuthClient.exchange(code, `${url.origin}${url.pathname}`) + if (result.err) throw new Error(result.err.message) + const decoded = AuthClient.decode(result.tokens.access, {} as any) + if (decoded.err) throw new Error(decoded.err.message) + const session = await useAuthSession() + const id = decoded.subject.properties.accountID + await session.update((value) => { + return { + ...value, + account: { + ...value.account, + [id]: { + id, + email: decoded.subject.properties.email, + }, + }, + current: id, + } + }) + const next = url.pathname === "/auth/callback" ? "/auth" : url.pathname.replace("/auth/callback", "") + return redirect(route(locale, next)) + } catch (e: any) { + return new Response( + JSON.stringify({ + error: e.message, + cause: Object.fromEntries(url.searchParams.entries()), + }), + { status: 500 }, + ) + } +} diff --git a/packages/console/app/src/routes/auth/authorize.ts b/packages/console/app/src/routes/auth/authorize.ts new file mode 100644 index 0000000000000000000000000000000000000000..0f0651ae36b0309a0db86976aa87de8938406dfd --- /dev/null +++ b/packages/console/app/src/routes/auth/authorize.ts @@ -0,0 +1,10 @@ +import type { APIEvent } from "@solidjs/start/server" +import { AuthClient } from "~/context/auth" + +export async function GET(input: APIEvent) { + const url = new URL(input.request.url) + const cont = url.searchParams.get("continue") ?? "" + const callbackUrl = new URL(`./callback${cont}`, input.request.url) + const result = await AuthClient.authorize(callbackUrl.toString(), "code") + return Response.redirect(result.url, 302) +} diff --git a/packages/console/app/src/routes/auth/index.ts b/packages/console/app/src/routes/auth/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..0fefb98933eaaecb5fbb7fb6185f743cdae235de --- /dev/null +++ b/packages/console/app/src/routes/auth/index.ts @@ -0,0 +1,14 @@ +import { redirect } from "@solidjs/router" +import type { APIEvent } from "@solidjs/start/server" +import { getLastSeenWorkspaceID } from "../workspace/common" +import { localeFromRequest, route } from "~/lib/language" + +export async function GET(input: APIEvent) { + const locale = localeFromRequest(input.request) + try { + const workspaceID = await getLastSeenWorkspaceID() + return redirect(route(locale, `/workspace/${workspaceID}`)) + } catch { + return redirect("/auth/authorize") + } +} diff --git a/packages/console/app/src/routes/auth/logout.ts b/packages/console/app/src/routes/auth/logout.ts new file mode 100644 index 0000000000000000000000000000000000000000..9aaac37e224f3170aa48332e5b3e50223b9126c7 --- /dev/null +++ b/packages/console/app/src/routes/auth/logout.ts @@ -0,0 +1,17 @@ +import { redirect } from "@solidjs/router" +import { APIEvent } from "@solidjs/start" +import { useAuthSession } from "~/context/auth" + +export async function GET(event: APIEvent) { + const auth = await useAuthSession() + const current = auth.data.current + if (current) + await auth.update((val) => { + delete val.account?.[current] + const first = Object.keys(val.account ?? {})[0] + val.current = first + event!.locals.actor = undefined + return val + }) + return redirect("/zen") +} diff --git a/packages/console/app/src/routes/auth/status.ts b/packages/console/app/src/routes/auth/status.ts new file mode 100644 index 0000000000000000000000000000000000000000..ed522d7404f26c5ec60c647297de812c3b8bf0b4 --- /dev/null +++ b/packages/console/app/src/routes/auth/status.ts @@ -0,0 +1,7 @@ +import { APIEvent } from "@solidjs/start" +import { useAuthSession } from "~/context/auth" + +export async function GET(_input: APIEvent) { + const session = await useAuthSession() + return Response.json(session.data) +} diff --git a/packages/console/app/src/routes/bench/[id].tsx b/packages/console/app/src/routes/bench/[id].tsx new file mode 100644 index 0000000000000000000000000000000000000000..c6d10826b3c6a16b4e5dd8033cd38665b57ad620 --- /dev/null +++ b/packages/console/app/src/routes/bench/[id].tsx @@ -0,0 +1,375 @@ +import { Title } from "@solidjs/meta" +import { createAsync, query, useParams } from "@solidjs/router" +import { createSignal, For, Show } from "solid-js" +import { Database, eq } from "@opencode-ai/console-core/drizzle/index.js" +import { BenchmarkTable } from "@opencode-ai/console-core/schema/benchmark.sql.js" +import { useI18n } from "~/context/i18n" + +interface TaskSource { + repo: string + from: string + to: string +} + +interface Judge { + score: number + rationale: string + judge: string +} + +interface ScoreDetail { + criterion: string + weight: number + average: number + variance?: number + judges?: Judge[] +} + +interface RunUsage { + input: number + output: number + cost: number +} + +interface Run { + task: string + model: string + agent: string + score: { + final: number + base: number + penalty: number + } + scoreDetails: ScoreDetail[] + usage?: RunUsage + duration?: number +} + +interface Prompt { + commit: string + prompt: string +} + +interface AverageUsage { + input: number + output: number + cost: number +} + +interface Task { + averageScore: number + averageDuration?: number + averageUsage?: AverageUsage + model?: string + agent?: string + summary?: string + runs?: Run[] + task: { + id: string + source: TaskSource + prompts?: Prompt[] + } +} + +interface BenchmarkResult { + averageScore: number + tasks: Task[] +} + +async function getTaskDetail(benchmarkId: string, taskId: string) { + "use server" + const rows = await Database.use((tx) => + tx.select().from(BenchmarkTable).where(eq(BenchmarkTable.id, benchmarkId)).limit(1), + ) + if (!rows[0]) return null + const parsed = JSON.parse(rows[0].result) as BenchmarkResult + const task = parsed.tasks.find((t) => t.task.id === taskId) + return task ?? null +} + +const queryTaskDetail = query(getTaskDetail, "benchmark.task.detail") + +function formatDuration(ms: number): string { + const seconds = Math.floor(ms / 1000) + const minutes = Math.floor(seconds / 60) + const remainingSeconds = seconds % 60 + if (minutes > 0) { + return `${minutes}m ${remainingSeconds}s` + } + return `${remainingSeconds}s` +} + +export default function BenchDetail() { + const params = useParams() + const i18n = useI18n() + const [benchmarkId, taskId] = (params.id ?? "").split(":") + const task = createAsync(() => queryTaskDetail(benchmarkId, taskId)) + + return ( +
+ {i18n.t("bench.detail.title", { task: taskId })} +
+ {i18n.t("bench.detail.notFound")}

}> +
+
+ {i18n.t("bench.detail.labels.agent")}: + {task()?.agent ?? i18n.t("bench.detail.na")} +
+
+ {i18n.t("bench.detail.labels.model")}: + {task()?.model ?? i18n.t("bench.detail.na")} +
+
+ {i18n.t("bench.detail.labels.task")}: + {task()!.task.id} +
+
+ +
+
+ {i18n.t("bench.detail.labels.repo")}: + + {task()!.task.source.repo} + +
+
+ {i18n.t("bench.detail.labels.from")}: + + {task()!.task.source.from.slice(0, 7)} + +
+
+ {i18n.t("bench.detail.labels.to")}: + + {task()!.task.source.to.slice(0, 7)} + +
+
+ + 0}> +
+ {i18n.t("bench.detail.labels.prompt")}: + + {(p) => ( +
+
+ {i18n.t("bench.detail.labels.commit")}: {p.commit.slice(0, 7)} +
+

{p.prompt}

+
+ )} +
+
+
+ +
+ +
+
+ {i18n.t("bench.detail.labels.averageDuration")}: + {task()?.averageDuration ? formatDuration(task()!.averageDuration!) : i18n.t("bench.detail.na")} +
+
+ {i18n.t("bench.detail.labels.averageScore")}: + {task()?.averageScore?.toFixed(3) ?? i18n.t("bench.detail.na")} +
+
+ {i18n.t("bench.detail.labels.averageCost")}: + {task()?.averageUsage?.cost ? `$${task()!.averageUsage!.cost.toFixed(4)}` : i18n.t("bench.detail.na")} +
+
+ + +
+ {i18n.t("bench.detail.labels.summary")}: +

{task()!.summary}

+
+
+ + 0}> +
+ {i18n.t("bench.detail.labels.runs")}: + + + + + + + + + {(detail) => ( + + )} + + + + + + {(run, index) => ( + + + + + + + {(detail) => ( + + )} + + + )} + + +
+ {i18n.t("bench.detail.table.run")} + + {i18n.t("bench.detail.table.score")} + + {i18n.t("bench.detail.table.cost")} + + {i18n.t("bench.detail.table.duration")} + + {detail.criterion} ({detail.weight}) +
{index() + 1} + {run.score.final.toFixed(3)} ({run.score.base.toFixed(3)} - {run.score.penalty.toFixed(3)}) + + {run.usage?.cost ? `$${run.usage.cost.toFixed(4)}` : i18n.t("bench.detail.na")} + + {run.duration ? formatDuration(run.duration) : i18n.t("bench.detail.na")} + + + {(judge) => ( + + {judge.score === 1 ? "✓" : judge.score === 0 ? "✗" : judge.score} + + )} + +
+ + {(run, index) => ( +
+

{i18n.t("bench.detail.run.title", { n: index() + 1 })}

+
+ {i18n.t("bench.detail.labels.score")}: + {run.score.final.toFixed(3)} ({i18n.t("bench.detail.labels.base")}: {run.score.base.toFixed(3)} -{" "} + {i18n.t("bench.detail.labels.penalty")}: {run.score.penalty.toFixed(3)}) +
+ + {(detail) => ( +
+
+ {detail.criterion} ({i18n.t("bench.detail.labels.weight")}: {detail.weight}){" "} + + {(judge) => ( + + {judge.score === 1 ? "✓" : judge.score === 0 ? "✗" : judge.score} + + )} + +
+ 0}> + + {(judge) => { + const [expanded, setExpanded] = createSignal(false) + return ( +
+
setExpanded(!expanded())} + > + {expanded() ? "▼" : "▶"} + + {judge.score === 1 ? "✓" : judge.score === 0 ? "✗" : judge.score} + {" "} + {judge.judge} +
+ +

+ {judge.rationale} +

+
+
+ ) + }} +
+
+
+ )} +
+
+ )} +
+
+
+ + {(() => { + const [jsonExpanded, setJsonExpanded] = createSignal(false) + return ( +
+ + +
{JSON.stringify(task(), null, 2)}
+
+
+ ) + })()} +
+
+
+ ) +} diff --git a/packages/console/app/src/routes/bench/index.tsx b/packages/console/app/src/routes/bench/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..17798eff4e1f12a2d8140e84debc4b4c6b81a8ac --- /dev/null +++ b/packages/console/app/src/routes/bench/index.tsx @@ -0,0 +1,88 @@ +import { Title } from "@solidjs/meta" +import { A, createAsync, query } from "@solidjs/router" +import { createMemo, For, Show } from "solid-js" +import { Database, desc } from "@opencode-ai/console-core/drizzle/index.js" +import { BenchmarkTable } from "@opencode-ai/console-core/schema/benchmark.sql.js" +import { useI18n } from "~/context/i18n" + +interface BenchmarkResult { + averageScore: number + tasks: { averageScore: number; task: { id: string } }[] +} + +async function getBenchmarks() { + "use server" + const rows = await Database.use((tx) => + tx.select().from(BenchmarkTable).orderBy(desc(BenchmarkTable.timeCreated)).limit(100), + ) + return rows.map((row) => { + const parsed = JSON.parse(row.result) as BenchmarkResult + const taskScores: Record = {} + for (const t of parsed.tasks) { + taskScores[t.task.id] = t.averageScore + } + return { + id: row.id, + agent: row.agent, + model: row.model, + averageScore: parsed.averageScore, + taskScores, + } + }) +} + +const queryBenchmarks = query(getBenchmarks, "benchmarks.list") + +export default function Bench() { + const i18n = useI18n() + const benchmarks = createAsync(() => queryBenchmarks()) + + const taskIds = createMemo(() => { + const ids = new Set() + for (const row of benchmarks() ?? []) { + for (const id of Object.keys(row.taskScores)) { + ids.add(id) + } + } + return [...ids].sort() + }) + + return ( +
+ {i18n.t("bench.list.title")} +

{i18n.t("bench.list.heading")}

+ + + + + + + {(id) => } + + + + + {(row) => ( + + + + + + {(id) => ( + + )} + + + )} + + +
{i18n.t("bench.list.table.agent")}{i18n.t("bench.list.table.model")}{i18n.t("bench.list.table.score")}{id}
{row.agent}{row.model}{row.averageScore.toFixed(3)} + + + {row.taskScores[id]?.toFixed(3)} + + +
+
+ ) +} diff --git a/packages/console/app/src/routes/bench/submission.ts b/packages/console/app/src/routes/bench/submission.ts new file mode 100644 index 0000000000000000000000000000000000000000..969ff1659317d1b7d27cb1ab3c834762fcc2da52 --- /dev/null +++ b/packages/console/app/src/routes/bench/submission.ts @@ -0,0 +1,32 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Database } from "@opencode-ai/console-core/drizzle/index.js" +import { BenchmarkTable } from "@opencode-ai/console-core/schema/benchmark.sql.js" +import { Identifier } from "@opencode-ai/console-core/identifier.js" +import { i18n } from "~/i18n" +import { localeFromRequest } from "~/lib/language" + +interface SubmissionBody { + model: string + agent: string + result: string +} + +export async function POST(event: APIEvent) { + const dict = i18n(localeFromRequest(event.request)) + const body = (await event.request.json()) as SubmissionBody + + if (!body.model || !body.agent || !body.result) { + return Response.json({ error: dict["bench.submission.error.allFieldsRequired"] }, { status: 400 }) + } + + await Database.use((tx) => + tx.insert(BenchmarkTable).values({ + id: Identifier.create("benchmark"), + model: body.model, + agent: body.agent, + result: body.result, + }), + ) + + return Response.json({ success: true }, { status: 200 }) +} diff --git a/packages/console/app/src/routes/black.css b/packages/console/app/src/routes/black.css new file mode 100644 index 0000000000000000000000000000000000000000..648a79c33fe2407b8a1868bbbd20f68c33d9eb72 --- /dev/null +++ b/packages/console/app/src/routes/black.css @@ -0,0 +1,843 @@ +::view-transition-group(*) { + animation-duration: 250ms; + animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +::view-transition-old(root), +::view-transition-new(root) { + animation-duration: 250ms; + animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +::view-transition-image-pair(root) { + isolation: isolate; +} + +::view-transition-old(root) { + animation: none; + mix-blend-mode: normal; +} + +::view-transition-new(root) { + animation: none; + mix-blend-mode: normal; +} + +@keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes fade-out { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +@keyframes fade-in-up { + from { + opacity: 0; + transform: translateY(8px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes reveal-terms { + from { + mask-position: 0% 200%; + } + to { + mask-position: 0% 50%; + } +} + +@keyframes hide-terms { + from { + mask-position: 0% 50%; + } + to { + mask-position: 0% 200%; + } +} + +::view-transition-old(terms-20), +::view-transition-old(terms-100), +::view-transition-old(terms-200) { + mask-image: linear-gradient(to bottom, transparent, black 25% 75%, transparent); + mask-repeat: no-repeat; + mask-size: 100% 200%; + animation: hide-terms 200ms cubic-bezier(0.25, 0, 0.5, 1) forwards; +} + +::view-transition-new(terms-20), +::view-transition-new(terms-100), +::view-transition-new(terms-200) { + mask-image: linear-gradient(to bottom, transparent, black 25% 75%, transparent); + mask-repeat: no-repeat; + mask-position: 0% 200%; + mask-size: 100% 200%; + animation: reveal-terms 300ms cubic-bezier(0.25, 0, 0.5, 1) 50ms forwards; +} + +::view-transition-old(actions-20), +::view-transition-old(actions-100), +::view-transition-old(actions-200) { + animation: fade-out 80ms cubic-bezier(0.4, 0, 0.2, 1) forwards; +} + +::view-transition-new(actions-20), +::view-transition-new(actions-100), +::view-transition-new(actions-200) { + animation: fade-in-up 300ms cubic-bezier(0.16, 1, 0.3, 1) 300ms forwards; + opacity: 0; +} + +::view-transition-group(card-20), +::view-transition-group(card-100), +::view-transition-group(card-200) { + animation-duration: 250ms; + animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +[data-page="black"] { + background: #000; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: stretch; + font-family: var(--font-mono); + color: #fff; + + [data-component="header-logo"] { + filter: drop-shadow(0 8px 24px rgba(0, 0, 0, 0.25)) drop-shadow(0 4px 16px rgba(0, 0, 0, 0.1)); + position: relative; + z-index: 1; + } + + .header-light-rays { + position: absolute; + inset: 0 0 auto 0; + height: 30dvh; + pointer-events: none; + z-index: 0; + } + + [data-component="header"] { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding-top: 40px; + flex-shrink: 0; + } + + [data-component="content"] { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + flex-grow: 1; + + [data-slot="hero"] { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: 8px; + margin-top: 40px; + padding: 0 20px; + + @media (min-width: 768px) { + margin-top: 60px; + } + + h1 { + color: rgba(255, 255, 255, 0.92); + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 1.45; + margin: 0; + + @media (min-width: 768px) { + font-size: 20px; + } + + @media (max-width: 480px) { + font-size: 14px; + } + } + + p { + color: rgba(255, 255, 255, 0.59); + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 1.45; + margin: 0; + + @media (min-width: 768px) { + font-size: 20px; + } + + @media (max-width: 480px) { + font-size: 14px; + } + } + } + + [data-slot="hero-black"] { + margin-top: 40px; + padding: 0 20px; + position: relative; + + @media (min-width: 768px) { + margin-top: 60px; + } + + svg { + width: 100%; + max-width: 590px; + height: auto; + overflow: visible; + filter: drop-shadow(0 0 20px rgba(255, 255, 255, calc(0.1 + var(--hero-black-glow-intensity, 0) * 0.15))) + drop-shadow(0 -5px 30px rgba(255, 255, 255, calc(var(--hero-black-glow-intensity, 0) * 0.2))); + mask-image: linear-gradient(to bottom, black, transparent); + stroke-width: 1.5; + + [data-slot="black-base"] { + fill: url(#hero-black-fill-gradient); + stroke: url(#hero-black-stroke-gradient); + } + + [data-slot="black-glow"] { + fill: url(#hero-black-top-glow); + pointer-events: none; + } + + [data-slot="black-shimmer"] { + fill: url(#hero-black-shimmer-gradient); + pointer-events: none; + mix-blend-mode: overlay; + } + } + } + + [data-slot="cta"] { + display: flex; + flex-direction: column; + gap: 16px; + align-items: center; + text-align: center; + margin-top: -40px; + width: 100%; + + @media (min-width: 768px) { + margin-top: -20px; + } + + [data-slot="heading"] { + color: rgba(255, 255, 255, 0.92); + text-align: center; + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: 160%; + + span { + display: inline-block; + } + } + [data-slot="subheading"] { + color: rgba(255, 255, 255, 0.59); + font-size: 15px; + font-style: normal; + font-weight: 400; + line-height: 160%; + + @media (min-width: 768px) { + font-size: 18px; + line-height: 160%; + } + } + [data-slot="button"] { + display: inline-flex; + height: 40px; + padding: 0 12px; + justify-content: center; + align-items: center; + gap: 8px; + border-radius: 4px; + background: rgba(255, 255, 255, 0.92); + text-decoration: none; + color: #000; + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: normal; + + &:hover { + background: #e0e0e0; + } + + &:active { + transform: scale(0.98); + } + } + [data-slot="back-soon"] { + color: rgba(255, 255, 255, 0.59); + text-align: center; + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: 160%; /* 20.8px */ + } + [data-slot="follow-us"] { + display: inline-flex; + height: 40px; + padding: 0 12px; + justify-content: center; + align-items: center; + gap: 8px; + border-radius: 4px; + border: 1px solid rgba(255, 255, 255, 0.17); + color: rgba(255, 255, 255, 0.59); + font-family: var(--font-mono); + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-decoration: none; + } + + [data-slot="pricing"] { + display: flex; + flex-direction: column; + gap: 16px; + width: 100%; + max-width: 660px; + padding: 0 20px; + + @media (min-width: 768px) { + padding: 0; + } + } + + [data-slot="paused"] { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + color: rgba(255, 255, 255, 0.59); + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: 160%; + padding: 120px 20px; + } + + [data-slot="pricing-card"] { + display: flex; + flex-direction: column; + gap: 12px; + padding: 24px; + border: 1px solid rgba(255, 255, 255, 0.17); + background: black; + background-clip: padding-box; + border-radius: 4px; + text-decoration: none; + transition: border-color 0.15s ease; + cursor: pointer; + text-align: left; + + @media (max-width: 480px) { + padding: 16px; + } + + &:hover:not(:active) { + border-color: rgba(255, 255, 255, 0.35); + } + + [data-slot="icon"] { + color: rgba(255, 255, 255, 0.59); + } + + [data-slot="price"] { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 8px; + } + + [data-slot="amount"] { + color: rgba(255, 255, 255, 0.92); + font-size: 24px; + font-weight: 500; + } + + [data-slot="period"] { + color: rgba(255, 255, 255, 0.59); + font-size: 14px; + } + + [data-slot="multiplier"] { + color: rgba(255, 255, 255, 0.39); + font-size: 14px; + + &::before { + content: "·"; + margin-right: 8px; + } + } + } + + [data-slot="selected-plan"] { + display: flex; + flex-direction: column; + gap: 32px; + width: 100%; + max-width: 660px; + margin: 0 auto; + position: relative; + background-color: rgba(0, 0, 0, 0.75); + z-index: 1; + + @media (max-width: 480px) { + margin: 0 20px; + width: calc(100% - 40px); + } + } + + [data-slot="selected-card"] { + display: flex; + flex-direction: column; + gap: 12px; + padding: 24px; + border: 1px solid rgba(255, 255, 255, 0.17); + border-radius: 4px; + width: 100%; + + [data-slot="icon"] { + color: rgba(255, 255, 255, 0.59); + } + + [data-slot="price"] { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 8px; + } + + [data-slot="amount"] { + color: rgba(255, 255, 255, 0.92); + font-size: 24px; + font-weight: 500; + } + + [data-slot="period"] { + color: rgba(255, 255, 255, 0.59); + font-size: 14px; + } + + [data-slot="multiplier"] { + color: rgba(255, 255, 255, 0.39); + font-size: 14px; + + &::before { + content: "·"; + margin-right: 8px; + } + } + + [data-slot="terms"] { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: 8px; + text-align: left; + + li { + color: rgba(255, 255, 255, 0.59); + font-size: 14px; + line-height: 1.5; + padding-left: 16px; + position: relative; + + &::before { + content: "▪"; + position: absolute; + left: 0; + color: rgba(255, 255, 255, 0.39); + } + + @media (max-width: 768px) { + font-size: 12px; + } + } + } + + [data-slot="actions"] { + display: flex; + gap: 16px; + margin-top: 8px; + + button, + a { + flex: 1; + display: inline-flex; + height: 48px; + padding: 0 16px; + justify-content: center; + align-items: center; + border-radius: 4px; + font-family: var(--font-mono); + font-size: 16px; + font-weight: 400; + text-decoration: none; + cursor: pointer; + } + + [data-slot="cancel"] { + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.17); + color: rgba(255, 255, 255, 0.92); + transition-property: background-color, border-color; + transition-duration: 150ms; + transition-timing-function: cubic-bezier(0.25, 0, 0.5, 1); + + &:hover { + background-color: rgba(255, 255, 255, 0.08); + border-color: rgba(255, 255, 255, 0.25); + } + } + + [data-slot="continue"] { + background: rgb(255, 255, 255); + color: rgb(0, 0, 0); + transition: background-color 150ms cubic-bezier(0.25, 0, 0.5, 1); + + &:hover { + background: rgba(255, 255, 255, 0.9); + } + } + } + } + + [data-slot="fine-print"] { + color: rgba(255, 255, 255, 0.39); + text-align: center; + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: 160%; /* 20.8px */ + font-style: italic; + + a { + color: rgba(255, 255, 255, 0.39); + text-decoration: underline; + } + } + } + + /* Subscribe page styles */ + [data-slot="subscribe-form"] { + display: flex; + flex-direction: column; + gap: 32px; + align-items: center; + margin-top: -18px; + width: 100%; + max-width: 660px; + padding: 0 20px; + + @media (min-width: 768px) { + margin-top: 40px; + padding: 0; + } + + [data-slot="form-card"] { + width: 100%; + border: 1px solid rgba(255, 255, 255, 0.17); + border-radius: 4px; + padding: 24px; + display: flex; + flex-direction: column; + gap: 20px; + } + + [data-slot="plan-header"] { + display: flex; + flex-direction: column; + gap: 8px; + } + + [data-slot="title"] { + color: rgba(255, 255, 255, 0.92); + font-size: 16px; + font-weight: 400; + margin-bottom: 8px; + } + + [data-slot="icon"] { + color: rgba(255, 255, 255, 0.59); + isolation: isolate; + transform: translateZ(0); + } + + [data-slot="price"] { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 8px; + } + + [data-slot="amount"] { + color: rgba(255, 255, 255, 0.92); + font-size: 24px; + font-weight: 500; + } + + [data-slot="period"] { + color: rgba(255, 255, 255, 0.59); + font-size: 14px; + } + + [data-slot="multiplier"] { + color: rgba(255, 255, 255, 0.39); + font-size: 14px; + + &::before { + content: "·"; + margin: 0 8px; + } + } + + [data-slot="divider"] { + height: 1px; + background: rgba(255, 255, 255, 0.17); + } + + [data-slot="section-title"] { + color: rgba(255, 255, 255, 0.92); + font-size: 16px; + font-weight: 400; + } + + [data-slot="checkout-form"] { + display: flex; + flex-direction: column; + gap: 20px; + } + + [data-slot="error"] { + color: #ff6b6b; + font-size: 14px; + } + + [data-slot="submit-button"] { + width: 100%; + height: 48px; + background: rgba(255, 255, 255, 0.92); + border: none; + border-radius: 4px; + color: #000; + font-family: var(--font-mono); + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: background 0.15s ease; + + &:hover:not(:disabled) { + background: #e0e0e0; + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + } + + [data-slot="charge-notice"] { + color: #d4a500; + font-size: 14px; + text-align: center; + } + + [data-slot="loading"] { + display: flex; + justify-content: center; + padding: 40px 0; + + p { + color: rgba(255, 255, 255, 0.59); + font-size: 14px; + } + } + + [data-slot="fine-print"] { + color: rgba(255, 255, 255, 0.39); + text-align: center; + font-size: 13px; + font-style: italic; + view-transition-name: fine-print; + + a { + color: rgba(255, 255, 255, 0.39); + text-decoration: underline; + } + } + } + } + + [data-component="footer"] { + display: flex; + flex-direction: column; + width: 100%; + justify-content: center; + align-items: center; + gap: 24px; + flex-shrink: 0; + + @media (min-width: 768px) { + height: 120px; + } + + [data-slot="footer-content"] { + display: flex; + gap: 24px; + align-items: center; + justify-content: center; + + @media (min-width: 768px) { + gap: 40px; + } + + span, + a { + color: rgba(255, 255, 255, 0.39); + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-decoration: none; + } + + [data-slot="github-stars"] { + color: rgba(255, 255, 255, 0.25); + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + } + + [data-slot="anomaly"] { + display: none; + + @media (min-width: 768px) { + display: block; + } + } + } + [data-slot="anomaly-alt"] { + color: rgba(255, 255, 255, 0.39); + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-decoration: none; + margin-bottom: 24px; + + a { + color: rgba(255, 255, 255, 0.39); + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-decoration: none; + } + + @media (min-width: 768px) { + display: none; + } + } + } +} + +[data-component="black-workspace-picker-modal"] { + font-family: var(--font-mono); + + [data-slot="workspace-list"] { + width: 100%; + padding: 0; + margin: 0; + list-style: none; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + align-self: stretch; + outline: none; + overflow-y: auto; + max-height: 240px; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } + } + + [data-slot="workspace-item"] { + width: 100%; + display: flex; + padding: 8px 12px; + align-items: center; + gap: 8px; + align-self: stretch; + cursor: pointer; + + [data-slot="selected-icon"] { + visibility: hidden; + color: rgba(255, 255, 255, 0.39); + font-family: "IBM Plex Mono", monospace; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 160%; + } + + span:last-child { + color: rgba(255, 255, 255, 0.92); + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 160%; + } + + &:hover, + &[data-active="true"] { + background: #161616; + + [data-slot="selected-icon"] { + visibility: visible; + } + } + } +} diff --git a/packages/console/app/src/routes/black.tsx b/packages/console/app/src/routes/black.tsx new file mode 100644 index 0000000000000000000000000000000000000000..243ae687de3bdfe694990cd88008585e4ab59957 --- /dev/null +++ b/packages/console/app/src/routes/black.tsx @@ -0,0 +1,283 @@ +import { A, createAsync, RouteSectionProps } from "@solidjs/router" +import { Title, Meta } from "@solidjs/meta" +import { createMemo, createSignal } from "solid-js" +import { github } from "~/lib/github" +import { config } from "~/config" +import { useLanguage } from "~/context/language" +import { LanguagePicker } from "~/component/language-picker" +import { useI18n } from "~/context/i18n" +import Spotlight, { defaultConfig, type SpotlightAnimationState } from "~/component/spotlight" +import { LocaleLinks } from "~/component/locale-links" +import "./black.css" + +export default function BlackLayout(props: RouteSectionProps) { + const language = useLanguage() + const i18n = useI18n() + const githubData = createAsync(() => github()) + const starCount = createMemo(() => + githubData()?.stars + ? new Intl.NumberFormat(language.tag(language.locale()), { + notation: "compact", + compactDisplay: "short", + }).format(githubData()!.stars!) + : config.github.starsFormatted.compact, + ) + + const [spotlightAnimationState, setSpotlightAnimationState] = createSignal({ + time: 0, + intensity: 0.5, + pulseValue: 1, + }) + + const svgLightingValues = createMemo(() => { + const state = spotlightAnimationState() + const t = state.time + + const wave1 = Math.sin(t * 1.5) * 0.5 + 0.5 + const wave2 = Math.sin(t * 2.3 + 1.2) * 0.5 + 0.5 + const wave3 = Math.sin(t * 0.8 + 2.5) * 0.5 + 0.5 + + const shimmerPos = Math.sin(t * 0.7) * 0.5 + 0.5 + const glowIntensity = Math.max(state.intensity * state.pulseValue * 0.35, 0.15) + const fillOpacity = Math.max(0.1 + wave1 * 0.08 * state.pulseValue, 0.12) + const strokeBrightness = Math.max(55 + wave2 * 25 * state.pulseValue, 60) + + const shimmerIntensity = Math.max(wave3 * 0.15 * state.pulseValue, 0.08) + + return { + glowIntensity, + fillOpacity, + strokeBrightness, + shimmerPos, + shimmerIntensity, + } + }) + + const svgLightingStyle = createMemo(() => { + const values = svgLightingValues() + return { + "--hero-black-glow-intensity": values.glowIntensity.toFixed(3), + "--hero-black-stroke-brightness": `${values.strokeBrightness.toFixed(0)}%`, + } as Record + }) + + const handleAnimationFrame = (state: SpotlightAnimationState) => { + setSpotlightAnimationState(state) + } + + const spotlightConfig = () => defaultConfig + + return ( +
+ {i18n.t("black.meta.title")} + + + + + + + + + + + + + + +
+ + + opencode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

{i18n.t("black.hero.title")}

+

{i18n.t("black.hero.subtitle")}

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {props.children} +
+ +
+ ) +} diff --git a/packages/console/app/src/routes/black/common.tsx b/packages/console/app/src/routes/black/common.tsx new file mode 100644 index 0000000000000000000000000000000000000000..8932a967e4d3120f6908f890c50ca69932a2cf24 --- /dev/null +++ b/packages/console/app/src/routes/black/common.tsx @@ -0,0 +1,65 @@ +import { Match, Switch } from "solid-js" +import { useI18n } from "~/context/i18n" + +export const plans = [ + { id: "20", multiplier: null }, + { id: "100", multiplier: "black.plan.multiplier100" }, + { id: "200", multiplier: "black.plan.multiplier200" }, +] as const + +export type PlanID = (typeof plans)[number]["id"] +export type Plan = (typeof plans)[number] + +export function PlanIcon(props: { plan: string }) { + const i18n = useI18n() + + return ( + + + + {i18n.t("black.plan.icon20")} + + + + + + {i18n.t("black.plan.icon100")} + + + + + + + + + {i18n.t("black.plan.icon200")} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/packages/console/app/src/routes/black/index.tsx b/packages/console/app/src/routes/black/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b8f01842d0c2a8b645962f09ed025ff78ff2ff9f --- /dev/null +++ b/packages/console/app/src/routes/black/index.tsx @@ -0,0 +1,122 @@ +import { A, createAsync, query, useSearchParams } from "@solidjs/router" +import { Title } from "@solidjs/meta" +import { createMemo, createSignal, For, Match, onMount, Show, Switch } from "solid-js" +import { PlanIcon, plans } from "./common" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import { Resource } from "@opencode-ai/console-resource" + +const getPaused = query(async () => { + "use server" + return Resource.App.stage === "production" +}, "black.paused") + +export default function Black() { + const [params] = useSearchParams() + const i18n = useI18n() + const language = useLanguage() + const paused = createAsync(() => getPaused()) + const [selected, setSelected] = createSignal((params.plan as string) || null) + const [mounted, setMounted] = createSignal(false) + const selectedPlan = createMemo(() => plans.find((p) => p.id === selected())) + + onMount(() => { + requestAnimationFrame(() => setMounted(true)) + }) + + const transition = (action: () => void) => { + if (mounted() && "startViewTransition" in document) { + ;(document as any).startViewTransition(action) + return + } + + action() + } + + const select = (planId: string) => { + if (selected() === planId) { + return + } + + transition(() => setSelected(planId)) + } + + const cancel = () => { + transition(() => setSelected(null)) + } + + return ( + <> + {i18n.t("black.title")} +
+ {i18n.t("black.paused")}

}> + + +
+ + {(plan) => ( + + )} + +
+
+ + {(plan) => ( +
+
+
+ +
+

+ ${plan().id}{" "} + {i18n.t("black.price.perPersonBilledMonthly")} + + {(multiplier) => {i18n.t(multiplier())}} + +

+
    +
  • {i18n.t("black.terms.1")}
  • +
  • {i18n.t("black.terms.2")}
  • +
  • {i18n.t("black.terms.3")}
  • +
  • {i18n.t("black.terms.4")}
  • +
  • {i18n.t("black.terms.5")}
  • +
  • {i18n.t("black.terms.6")}
  • +
  • {i18n.t("black.terms.7")}
  • +
+
+ +
+
+
+ )} +
+
+
+ +

+ {i18n.t("black.finePrint.beforeTerms")} ·{" "} + {i18n.t("black.finePrint.terms")} +

+
+
+ + ) +} diff --git a/packages/console/app/src/routes/black/workspace.css b/packages/console/app/src/routes/black/workspace.css new file mode 100644 index 0000000000000000000000000000000000000000..bf9d948786f6f5ec5502bb099a5c8719308be809 --- /dev/null +++ b/packages/console/app/src/routes/black/workspace.css @@ -0,0 +1,214 @@ +[data-page="black"] { + background: #000; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: stretch; + font-family: var(--font-mono); + color: #fff; + + [data-component="header-gradient"] { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 288px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.16) 0%, rgba(0, 0, 0, 0) 100%); + } + + [data-component="header"] { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding-top: 40px; + flex-shrink: 0; + + /* [data-component="header-logo"] { */ + /* } */ + } + + [data-component="content"] { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + flex-grow: 1; + + [data-slot="hero-black"] { + margin-top: 110px; + + @media (min-width: 768px) { + margin-top: 150px; + } + } + + [data-slot="select-workspace"] { + display: flex; + margin-top: -24px; + width: 100%; + max-width: 480px; + height: 305px; + padding: 32px 20px 0 20px; + flex-direction: column; + align-items: flex-start; + gap: 24px; + + border: 1px solid #303030; + background: #0a0a0a; + box-shadow: + 0 100px 80px 0 rgba(0, 0, 0, 0.04), + 0 41.778px 33.422px 0 rgba(0, 0, 0, 0.05), + 0 22.336px 17.869px 0 rgba(0, 0, 0, 0.06), + 0 12.522px 10.017px 0 rgba(0, 0, 0, 0.08), + 0 6.65px 5.32px 0 rgba(0, 0, 0, 0.09), + 0 2.767px 2.214px 0 rgba(0, 0, 0, 0.13); + + [data-slot="select-workspace-title"] { + flex-shrink: 0; + align-self: stretch; + color: rgba(255, 255, 255, 0.59); + text-align: center; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 160%; /* 25.6px */ + } + + [data-slot="workspaces"] { + width: 100%; + padding: 0; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + align-self: stretch; + outline: none; + overflow-y: auto; + flex: 1; + min-height: 0; + + scrollbar-width: none; + &::-webkit-scrollbar { + display: none; + } + + [data-slot="workspace"] { + width: 100%; + display: flex; + padding: 8px 12px; + align-items: center; + gap: 8px; + align-self: stretch; + cursor: pointer; + + [data-slot="selected-icon"] { + visibility: hidden; + color: rgba(255, 255, 255, 0.39); + font-family: "IBM Plex Mono"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 160%; /* 25.6px */ + } + + a { + color: rgba(255, 255, 255, 0.92); + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 160%; /* 25.6px */ + text-decoration: none; + } + } + + [data-slot="workspace"]:hover, + [data-slot="workspace"][data-active="true"] { + background: #161616; + + [data-slot="selected-icon"] { + visibility: visible; + } + } + } + } + } + + [data-component="footer"] { + display: flex; + flex-direction: column; + width: 100%; + justify-content: center; + align-items: center; + gap: 24px; + flex-shrink: 0; + + @media (min-width: 768px) { + height: 120px; + } + + [data-slot="footer-content"] { + display: flex; + gap: 24px; + align-items: center; + justify-content: center; + + @media (min-width: 768px) { + gap: 40px; + } + + span, + a { + color: rgba(255, 255, 255, 0.39); + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-decoration: none; + } + + [data-slot="github-stars"] { + color: rgba(255, 255, 255, 0.25); + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + } + + [data-slot="anomaly"] { + display: none; + + @media (min-width: 768px) { + display: block; + } + } + } + [data-slot="anomaly-alt"] { + color: rgba(255, 255, 255, 0.39); + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-decoration: none; + margin-bottom: 24px; + + a { + color: rgba(255, 255, 255, 0.39); + font-family: "JetBrains Mono Nerd Font"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-decoration: none; + } + + @media (min-width: 768px) { + display: none; + } + } + } +} diff --git a/packages/console/app/src/routes/black/workspace.tsx b/packages/console/app/src/routes/black/workspace.tsx new file mode 100644 index 0000000000000000000000000000000000000000..106e8a23ea8f879708939bb085d7467a3e1988d6 --- /dev/null +++ b/packages/console/app/src/routes/black/workspace.tsx @@ -0,0 +1,238 @@ +import { A, createAsync, useNavigate } from "@solidjs/router" +import "./workspace.css" +import { Title } from "@solidjs/meta" +import { github } from "~/lib/github" +import { createEffect, createMemo, For, onMount } from "solid-js" +import { config } from "~/config" +import { createList } from "solid-list" +import { useLanguage } from "~/context/language" +import { LanguagePicker } from "~/component/language-picker" +import { useI18n } from "~/context/i18n" + +export default function BlackWorkspace() { + const navigate = useNavigate() + const language = useLanguage() + const i18n = useI18n() + const githubData = createAsync(() => github()) + const starCount = createMemo(() => + githubData()?.stars + ? new Intl.NumberFormat(language.tag(language.locale()), { + notation: "compact", + compactDisplay: "short", + }).format(githubData()!.stars!) + : config.github.starsFormatted.compact, + ) + + // TODO: Frank, replace with real workspaces + const workspaces = [ + { id: "wrk_123", n: 1 }, + { id: "wrk_456", n: 2 }, + { id: "wrk_789", n: 3 }, + { id: "wrk_111", n: 4 }, + { id: "wrk_222", n: 5 }, + { id: "wrk_333", n: 6 }, + { id: "wrk_444", n: 7 }, + { id: "wrk_555", n: 8 }, + ].map((workspace) => ({ + ...workspace, + name: i18n.t("black.workspace.name", { n: workspace.n }), + })) + + let listRef: HTMLUListElement | undefined + + const { active, setActive, onKeyDown } = createList({ + items: () => workspaces.map((w) => w.id), + initialActive: workspaces[0]?.id ?? null, + handleTab: true, + }) + + onMount(() => { + listRef?.focus() + }) + + createEffect(() => { + const id = active() + if (!id || !listRef) return + const el = listRef.querySelector(`[data-id="${id}"]`) + el?.scrollIntoView({ block: "nearest" }) + }) + + return ( +
+ {i18n.t("black.workspace.title")} +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + +
+
+

{i18n.t("black.workspace.selectPlan")}

+
    { + if (e.key === "Enter" && active()) { + navigate(`/black/workspace/${active()}`) + } else if (e.key === "Tab") { + e.preventDefault() + onKeyDown(e) + } else { + onKeyDown(e) + } + }} + > + + {(workspace) => ( +
  • setActive(workspace.id)} + onClick={() => navigate(`/black/workspace/${workspace.id}`)} + > + [*] + {workspace.name} +
  • + )} +
    +
+
+
+ +
+ ) +} diff --git a/packages/console/app/src/routes/brand/index.css b/packages/console/app/src/routes/brand/index.css new file mode 100644 index 0000000000000000000000000000000000000000..0e39f3742f260c56dc71134e5d3ea2d721b55590 --- /dev/null +++ b/packages/console/app/src/routes/brand/index.css @@ -0,0 +1,555 @@ +::selection { + background: var(--color-background-interactive); + color: var(--color-text-strong); + + @media (prefers-color-scheme: dark) { + background: var(--color-background-interactive); + color: var(--color-text-inverted); + } +} + +[data-page="enterprise"], +[data-page="legal"] { + --color-background: hsl(0, 20%, 99%); + --color-background-weak: hsl(0, 8%, 97%); + --color-background-weak-hover: hsl(0, 8%, 94%); + --color-background-strong: hsl(0, 5%, 12%); + --color-background-strong-hover: hsl(0, 5%, 18%); + --color-background-interactive: hsl(62, 84%, 88%); + --color-background-interactive-weaker: hsl(64, 74%, 95%); + + --color-text: hsl(0, 1%, 39%); + --color-text-weak: hsl(0, 1%, 60%); + --color-text-weaker: hsl(30, 2%, 81%); + --color-text-strong: hsl(0, 5%, 12%); + --color-text-inverted: hsl(0, 20%, 99%); + --color-text-success: hsl(119, 100%, 35%); + + --color-border: hsl(30, 2%, 81%); + --color-border-weak: hsl(0, 1%, 85%); + + --color-icon: hsl(0, 1%, 55%); + --color-success: hsl(142, 76%, 36%); + + background: var(--color-background); + font-family: var(--font-mono); + color: var(--color-text); + padding-bottom: 5rem; + + @media (prefers-color-scheme: dark) { + --color-background: hsl(0, 9%, 7%); + --color-background-weak: hsl(0, 6%, 10%); + --color-background-weak-hover: hsl(0, 6%, 15%); + --color-background-strong: hsl(0, 15%, 94%); + --color-background-strong-hover: hsl(0, 15%, 97%); + --color-background-interactive: hsl(62, 100%, 90%); + --color-background-interactive-weaker: hsl(60, 20%, 8%); + + --color-text: hsl(0, 4%, 71%); + --color-text-weak: hsl(0, 2%, 49%); + --color-text-weaker: hsl(0, 3%, 28%); + --color-text-strong: hsl(0, 15%, 94%); + --color-text-inverted: hsl(0, 9%, 7%); + --color-text-success: hsl(119, 60%, 72%); + + --color-border: hsl(0, 3%, 28%); + --color-border-weak: hsl(0, 4%, 23%); + + --color-icon: hsl(10, 3%, 43%); + --color-success: hsl(142, 76%, 46%); + } + + /* Header and Footer styles - copied from index.css */ + [data-component="top"] { + padding: 24px 5rem; + height: 80px; + position: sticky; + top: 0; + display: flex; + justify-content: space-between; + align-items: center; + background: var(--color-background); + border-bottom: 1px solid var(--color-border-weak); + z-index: 10; + + @media (max-width: 60rem) { + padding: 24px 1.5rem; + } + + img { + height: 34px; + width: auto; + } + + [data-component="nav-desktop"] { + ul { + display: flex; + justify-content: space-between; + align-items: center; + gap: 32px; + + @media (max-width: 55rem) { + gap: 24px; + } + + @media (max-width: 48rem) { + gap: 24px; + } + li { + display: inline-block; + a { + text-decoration: none; + span { + color: var(--color-text-weak); + } + } + a:hover { + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + [data-slot="cta-button"] { + background: var(--color-background-strong); + color: var(--color-text-inverted); + padding: 8px 16px 8px 10px; + border-radius: 4px; + font-weight: 500; + text-decoration: none; + display: flex; + align-items: center; + gap: 8px; + white-space: nowrap; + + @media (max-width: 55rem) { + display: none; + } + } + [data-slot="cta-button"]:hover { + background: var(--color-background-strong-hover); + text-decoration: none; + } + } + } + + @media (max-width: 40rem) { + display: none; + } + } + + [data-component="nav-mobile"] { + button > svg { + color: var(--color-icon); + } + } + + [data-component="nav-mobile-toggle"] { + border: none; + background: none; + outline: none; + height: 40px; + width: 40px; + cursor: pointer; + margin-right: -8px; + } + + [data-component="nav-mobile-toggle"]:hover { + background: var(--color-background-weak); + } + + [data-component="nav-mobile"] { + display: none; + + @media (max-width: 40rem) { + display: block; + + [data-component="nav-mobile-icon"] { + cursor: pointer; + height: 40px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + } + + [data-component="nav-mobile-menu-list"] { + position: fixed; + background: var(--color-background); + top: 80px; + left: 0; + right: 0; + height: 100vh; + + ul { + list-style: none; + padding: 20px 0; + + li { + a { + text-decoration: none; + padding: 20px; + display: block; + + span { + color: var(--color-text-weak); + } + } + + a:hover { + background: var(--color-background-weak); + } + } + } + } + } + } + + [data-slot="logo dark"] { + display: none; + } + + @media (prefers-color-scheme: dark) { + [data-slot="logo light"] { + display: none; + } + [data-slot="logo dark"] { + display: block; + } + } + } + + [data-component="footer"] { + border-top: 1px solid var(--color-border-weak); + display: flex; + flex-direction: row; + + @media (max-width: 65rem) { + border-bottom: 1px solid var(--color-border-weak); + } + + [data-slot="cell"] { + flex: 1; + text-align: center; + + a { + text-decoration: none; + padding: 2rem 0; + width: 100%; + display: block; + + span { + color: var(--color-text-weak); + + @media (max-width: 40rem) { + display: none; + } + } + } + + a:hover { + background: var(--color-background-weak); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + } + + [data-slot="cell"] + [data-slot="cell"] { + border-left: 1px solid var(--color-border-weak); + + @media (max-width: 40rem) { + border-left: none; + } + } + + /* Mobile: third column on its own row */ + @media (max-width: 25rem) { + flex-wrap: wrap; + + [data-slot="cell"] { + flex: 1 0 100%; + border-left: none; + border-top: 1px solid var(--color-border-weak); + } + + [data-slot="cell"]:nth-child(1) { + border-top: none; + } + } + } + + [data-component="container"] { + max-width: 67.5rem; + margin: 0 auto; + border: 1px solid var(--color-border-weak); + border-top: none; + + @media (max-width: 65rem) { + border: none; + } + } + + [data-component="content"] { + } + + [data-component="brand-content"] { + padding: 4rem 5rem; + + h1 { + font-size: 1.5rem; + font-weight: 700; + color: var(--color-text-strong); + margin-bottom: 1rem; + } + + h3 { + font-size: 1.25rem; + font-weight: 500; + color: var(--color-text-strong); + margin: 2rem 0 1rem 0; + } + + p { + line-height: 1.6; + margin-bottom: 2.5rem; + color: var(--color-text); + } + + [data-component="download-button"] { + padding: 8px 12px 8px 20px; + background: var(--color-background-strong); + color: var(--color-text-inverted); + border: none; + border-radius: 4px; + font-weight: 500; + cursor: pointer; + display: flex; + width: fit-content; + align-items: center; + gap: 12px; + transition: all 0.2s ease; + text-decoration: none; + + &:hover:not(:disabled) { + background: var(--color-background-strong-hover); + } + + &:active { + transform: scale(0.98); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + } + + [data-component="brand-grid"] { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin-top: 4rem; + margin-bottom: 2rem; + } + + [data-component="brand-grid"] img { + width: 100%; + height: auto; + display: block; + border-radius: 4px; + border: 1px solid var(--color-border-weak); + } + + [data-component="brand-grid"] > div { + position: relative; + } + + [data-component="actions"] { + position: absolute; + background: rgba(4, 0, 0, 0.08); + border-radius: 4px; + bottom: 0; + right: 0; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + gap: 16px; + opacity: 0; + + @media (max-width: 40rem) { + position: static; + opacity: 1; + background: none; + margin-top: 1rem; + justify-content: start; + } + } + + [data-component="brand-grid"] > div:hover [data-component="actions"] { + opacity: 1; + + @media (max-width: 40rem) { + opacity: 1; + } + } + + [data-component="actions"] button { + padding: 6px 12px; + background: var(--color-background); + color: var(--color-text); + border: none; + border-radius: 4px; + font-weight: 500; + display: flex; + align-items: center; + gap: 12px; + transition: all 0.2s ease; + cursor: pointer; + box-shadow: + 0 0 0 1px rgba(19, 16, 16, 0.08), + 0 6px 8px -4px rgba(19, 16, 16, 0.12), + 0 4px 3px -2px rgba(19, 16, 16, 0.12), + 0 1px 2px -1px rgba(19, 16, 16, 0.12); + + @media (max-width: 40rem) { + box-shadow: 0 0 0 1px rgba(19, 16, 16, 0.16); + } + + &:hover { + background: var(--color-background); + } + + &:active { + transform: scale(0.98); + box-shadow: + 0 0 0 1px rgba(19, 16, 16, 0.08), + 0 6px 8px -8px rgba(19, 16, 16, 0.5); + } + } + + @media (max-width: 60rem) { + padding: 2rem 1.5rem; + } + } + + [data-component="faq"] { + border-top: 1px solid var(--color-border-weak); + padding: 4rem 5rem; + + @media (max-width: 60rem) { + padding: 2rem 1.5rem; + } + + [data-slot="section-title"] { + margin-bottom: 24px; + + h3 { + font-size: 16px; + font-weight: 500; + color: var(--color-text-strong); + margin-bottom: 12px; + } + + p { + margin-bottom: 12px; + color: var(--color-text); + } + } + + ul { + padding: 0; + + li { + list-style: none; + margin-bottom: 24px; + line-height: 200%; + + @media (max-width: 60rem) { + line-height: 180%; + } + } + } + + [data-slot="faq-question"] { + display: flex; + gap: 16px; + margin-bottom: 8px; + color: var(--color-text-strong); + font-weight: 500; + cursor: pointer; + background: none; + border: none; + padding: 0; + + [data-slot="faq-icon-plus"] { + flex-shrink: 0; + color: var(--color-text-weak); + margin-top: 2px; + + [data-closed] & { + display: block; + } + [data-expanded] & { + display: none; + } + } + [data-slot="faq-icon-minus"] { + flex-shrink: 0; + color: var(--color-text-weak); + margin-top: 2px; + + [data-closed] & { + display: none; + } + [data-expanded] & { + display: block; + } + } + [data-slot="faq-question-text"] { + flex-grow: 1; + text-align: left; + } + } + + [data-slot="faq-answer"] { + margin-left: 40px; + margin-bottom: 32px; + color: var(--color-text); + } + } + + [data-component="legal"] { + color: var(--color-text-weak); + text-align: center; + padding: 2rem 5rem; + display: flex; + gap: 32px; + justify-content: center; + + @media (max-width: 60rem) { + padding: 2rem 1.5rem; + } + + a { + color: var(--color-text-weak); + text-decoration: none; + } + + a:hover { + color: var(--color-text); + text-decoration: underline; + } + } + + a { + color: var(--color-text-strong); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + + &:hover { + text-decoration-thickness: 2px; + } + } +} diff --git a/packages/console/app/src/routes/brand/index.tsx b/packages/console/app/src/routes/brand/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..af89f498510b31c040dcde347eaf954515893a8f --- /dev/null +++ b/packages/console/app/src/routes/brand/index.tsx @@ -0,0 +1,315 @@ +import "./index.css" +import { Title, Meta } from "@solidjs/meta" +import { Header } from "~/component/header" +import { Footer } from "~/component/footer" +import { Legal } from "~/component/legal" +import { useI18n } from "~/context/i18n" +import { LocaleLinks } from "~/component/locale-links" +import previewLogoLight from "../../asset/brand/preview-opencode-logo-light.png" +import previewLogoDark from "../../asset/brand/preview-opencode-logo-dark.png" +import previewLogoLightSquare from "../../asset/brand/preview-opencode-logo-light-square.png" +import previewLogoDarkSquare from "../../asset/brand/preview-opencode-logo-dark-square.png" +import previewWordmarkLight from "../../asset/brand/preview-opencode-wordmark-light.png" +import previewWordmarkDark from "../../asset/brand/preview-opencode-wordmark-dark.png" +import previewWordmarkSimpleLight from "../../asset/brand/preview-opencode-wordmark-simple-light.png" +import previewWordmarkSimpleDark from "../../asset/brand/preview-opencode-wordmark-simple-dark.png" +import logoLightPng from "../../asset/brand/opencode-logo-light.png" +import logoDarkPng from "../../asset/brand/opencode-logo-dark.png" +import logoLightSquarePng from "../../asset/brand/opencode-logo-light-square.png" +import logoDarkSquarePng from "../../asset/brand/opencode-logo-dark-square.png" +import wordmarkLightPng from "../../asset/brand/opencode-wordmark-light.png" +import wordmarkDarkPng from "../../asset/brand/opencode-wordmark-dark.png" +import wordmarkSimpleLightPng from "../../asset/brand/opencode-wordmark-simple-light.png" +import wordmarkSimpleDarkPng from "../../asset/brand/opencode-wordmark-simple-dark.png" +import logoLightSvg from "../../asset/brand/opencode-logo-light.svg" +import logoDarkSvg from "../../asset/brand/opencode-logo-dark.svg" +import logoLightSquareSvg from "../../asset/brand/opencode-logo-light-square.svg" +import logoDarkSquareSvg from "../../asset/brand/opencode-logo-dark-square.svg" +import wordmarkLightSvg from "../../asset/brand/opencode-wordmark-light.svg" +import wordmarkDarkSvg from "../../asset/brand/opencode-wordmark-dark.svg" +import wordmarkSimpleLightSvg from "../../asset/brand/opencode-wordmark-simple-light.svg" +import wordmarkSimpleDarkSvg from "../../asset/brand/opencode-wordmark-simple-dark.svg" +const brandAssets = "/opencode-brand-assets.zip" + +export default function Brand() { + const i18n = useI18n() + const alt = i18n.t("brand.meta.description") + const downloadFile = async (url: string, filename: string) => { + try { + const response = await fetch(url) + const blob = await response.blob() + const blobUrl = window.URL.createObjectURL(blob) + + const link = document.createElement("a") + link.href = blobUrl + link.download = filename + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + + window.URL.revokeObjectURL(blobUrl) + } catch (error) { + console.error("Download failed:", error) + const link = document.createElement("a") + link.href = url + link.target = "_blank" + link.rel = "noopener noreferrer" + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + } + } + + return ( +
+ {i18n.t("brand.title")} + + +
+
+ +
+
+

{i18n.t("brand.heading")}

+

{i18n.t("brand.subtitle")}

+ + +
+
+ {alt} +
+ + +
+
+
+ {alt} +
+ + +
+
+
+ {alt} +
+ + +
+
+
+ {alt} +
+ + +
+
+
+ {alt} +
+ + +
+
+
+ {alt} +
+ + +
+
+
+ {alt} +
+ + +
+
+
+ {alt} +
+ + +
+
+
+
+
+
+
+ +
+ ) +} diff --git a/packages/console/app/src/routes/changelog.json.ts b/packages/console/app/src/routes/changelog.json.ts new file mode 100644 index 0000000000000000000000000000000000000000..f06c1be9b40304113c27f5efd8cd1dd0846278e2 --- /dev/null +++ b/packages/console/app/src/routes/changelog.json.ts @@ -0,0 +1,30 @@ +import { loadChangelog } from "~/lib/changelog" + +const cors = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type, Authorization", +} + +const ok = "public, max-age=1, s-maxage=300, stale-while-revalidate=86400, stale-if-error=86400" +const error = "public, max-age=1, s-maxage=60, stale-while-revalidate=600, stale-if-error=86400" + +export async function GET() { + const result = await loadChangelog().catch(() => ({ ok: false, releases: [] })) + + return new Response(JSON.stringify({ releases: result.releases }), { + status: result.ok ? 200 : 503, + headers: { + "Content-Type": "application/json", + "Cache-Control": result.ok ? ok : error, + ...cors, + }, + }) +} + +export async function OPTIONS() { + return new Response(null, { + status: 200, + headers: cors, + }) +} diff --git a/packages/console/app/src/routes/changelog/index.css b/packages/console/app/src/routes/changelog/index.css new file mode 100644 index 0000000000000000000000000000000000000000..27b44f062754f680ab04caca5963320cfb5b434e --- /dev/null +++ b/packages/console/app/src/routes/changelog/index.css @@ -0,0 +1,604 @@ +::selection { + background: var(--color-background-interactive); + color: var(--color-text-strong); + + @media (prefers-color-scheme: dark) { + background: var(--color-background-interactive); + color: var(--color-text-inverted); + } +} + +[data-page="changelog"] { + --color-background: hsl(0, 20%, 99%); + --color-background-weak: hsl(0, 8%, 97%); + --color-background-weak-hover: hsl(0, 8%, 94%); + --color-background-strong: hsl(0, 5%, 12%); + --color-background-strong-hover: hsl(0, 5%, 18%); + --color-background-interactive: hsl(62, 84%, 88%); + --color-background-interactive-weaker: hsl(64, 74%, 95%); + + --color-text: hsl(0, 1%, 39%); + --color-text-weak: hsl(0, 1%, 60%); + --color-text-weaker: hsl(30, 2%, 81%); + --color-text-strong: hsl(0, 5%, 12%); + --color-text-inverted: hsl(0, 20%, 99%); + + --color-border: hsl(30, 2%, 81%); + --color-border-weak: hsl(0, 1%, 85%); + + --color-icon: hsl(0, 1%, 55%); + + background: var(--color-background); + font-family: var(--font-mono); + color: var(--color-text); + padding-bottom: 5rem; + + @media (prefers-color-scheme: dark) { + --color-background: hsl(0, 9%, 7%); + --color-background-weak: hsl(0, 6%, 10%); + --color-background-weak-hover: hsl(0, 6%, 15%); + --color-background-strong: hsl(0, 15%, 94%); + --color-background-strong-hover: hsl(0, 15%, 97%); + --color-background-interactive: hsl(62, 100%, 90%); + --color-background-interactive-weaker: hsl(60, 20%, 8%); + + --color-text: hsl(0, 4%, 71%); + --color-text-weak: hsl(0, 2%, 49%); + --color-text-weaker: hsl(0, 3%, 28%); + --color-text-strong: hsl(0, 15%, 94%); + --color-text-inverted: hsl(0, 9%, 7%); + + --color-border: hsl(0, 3%, 28%); + --color-border-weak: hsl(0, 4%, 23%); + + --color-icon: hsl(10, 3%, 43%); + } + + /* Header styles - copied from download */ + [data-component="top"] { + padding: 24px 5rem; + height: 80px; + position: sticky; + top: 0; + display: flex; + justify-content: space-between; + align-items: center; + background: var(--color-background); + border-bottom: 1px solid var(--color-border-weak); + z-index: 10; + + @media (max-width: 60rem) { + padding: 24px 1.5rem; + } + + img { + height: 34px; + width: auto; + } + + [data-component="nav-desktop"] { + ul { + display: flex; + justify-content: space-between; + align-items: center; + gap: 32px; + + @media (max-width: 55rem) { + gap: 24px; + } + + @media (max-width: 48rem) { + gap: 24px; + } + li { + display: inline-block; + a { + text-decoration: none; + span { + color: var(--color-text-weak); + } + } + a:hover { + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + [data-slot="cta-button"] { + background: var(--color-background-strong); + color: var(--color-text-inverted); + padding: 8px 16px 8px 10px; + border-radius: 4px; + font-weight: 500; + text-decoration: none; + display: flex; + align-items: center; + gap: 8px; + white-space: nowrap; + + @media (max-width: 55rem) { + display: none; + } + } + [data-slot="cta-button"]:hover { + background: var(--color-background-strong-hover); + text-decoration: none; + } + } + } + + @media (max-width: 40rem) { + display: none; + } + } + + [data-component="nav-mobile"] { + button > svg { + color: var(--color-icon); + } + } + + [data-component="nav-mobile-toggle"] { + border: none; + background: none; + outline: none; + height: 40px; + width: 40px; + cursor: pointer; + margin-right: -8px; + } + + [data-component="nav-mobile-toggle"]:hover { + background: var(--color-background-weak); + } + + [data-component="nav-mobile"] { + display: none; + + @media (max-width: 40rem) { + display: block; + + [data-component="nav-mobile-icon"] { + cursor: pointer; + height: 40px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + } + + [data-component="nav-mobile-menu-list"] { + position: fixed; + background: var(--color-background); + top: 80px; + left: 0; + right: 0; + height: 100vh; + + ul { + list-style: none; + padding: 20px 0; + + li { + a { + text-decoration: none; + padding: 20px; + display: block; + + span { + color: var(--color-text-weak); + } + } + + a:hover { + background: var(--color-background-weak); + } + } + } + } + } + } + + [data-slot="logo dark"] { + display: none; + } + + @media (prefers-color-scheme: dark) { + [data-slot="logo light"] { + display: none; + } + [data-slot="logo dark"] { + display: block; + } + } + } + + [data-component="footer"] { + border-top: 1px solid var(--color-border-weak); + display: flex; + flex-direction: row; + margin-top: 4rem; + + @media (max-width: 65rem) { + border-bottom: 1px solid var(--color-border-weak); + } + + [data-slot="cell"] { + flex: 1; + text-align: center; + + a { + text-decoration: none; + padding: 2rem 0; + width: 100%; + display: block; + + span { + color: var(--color-text-weak); + + @media (max-width: 40rem) { + display: none; + } + } + } + + a:hover { + background: var(--color-background-weak); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + } + + [data-slot="cell"] + [data-slot="cell"] { + border-left: 1px solid var(--color-border-weak); + + @media (max-width: 40rem) { + border-left: none; + } + } + + @media (max-width: 25rem) { + flex-wrap: wrap; + + [data-slot="cell"] { + flex: 1 0 100%; + border-left: none; + border-top: 1px solid var(--color-border-weak); + } + + [data-slot="cell"]:nth-child(1) { + border-top: none; + } + } + } + + [data-component="container"] { + max-width: 67.5rem; + margin: 0 auto; + border: 1px solid var(--color-border-weak); + border-top: none; + + @media (max-width: 65rem) { + border: none; + } + } + + [data-component="content"] { + padding: 6rem 5rem; + + @media (max-width: 60rem) { + padding: 4rem 1.5rem; + } + } + + [data-component="legal"] { + color: var(--color-text-weak); + text-align: center; + padding: 2rem 5rem; + display: flex; + gap: 32px; + justify-content: center; + + @media (max-width: 60rem) { + padding: 2rem 1.5rem; + } + + a { + color: var(--color-text-weak); + text-decoration: none; + } + + a:hover { + color: var(--color-text); + text-decoration: underline; + } + } + + /* Changelog Hero */ + [data-component="changelog-hero"] { + margin-bottom: 4rem; + padding-bottom: 2rem; + border-bottom: 1px solid var(--color-border-weak); + + @media (max-width: 50rem) { + margin-bottom: 2rem; + padding-bottom: 1.5rem; + } + + h1 { + font-size: 1.5rem; + font-weight: 700; + color: var(--color-text-strong); + margin-bottom: 8px; + } + + p { + color: var(--color-text); + } + } + + /* Releases */ + [data-component="releases"] { + display: flex; + flex-direction: column; + gap: 0; + } + + [data-component="release"] { + display: grid; + grid-template-columns: 180px 1fr; + gap: 3rem; + padding: 2rem 0; + border-bottom: 1px solid var(--color-border-weak); + + @media (max-width: 50rem) { + grid-template-columns: 1fr; + gap: 1rem; + } + + &:first-child { + padding-top: 0; + } + + &:last-child { + border-bottom: none; + } + + header { + display: flex; + flex-direction: column; + gap: 4px; + position: sticky; + top: 80px; + align-self: start; + background: var(--color-background); + padding: 44px 0 8px; + + @media (max-width: 50rem) { + position: static; + flex-direction: row; + align-items: center; + gap: 12px; + padding: 0; + } + + [data-slot="version"] { + a { + font-weight: 600; + color: var(--color-text-strong); + text-decoration: none; + + &:hover { + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + } + } + + time { + color: var(--color-text-weak); + font-size: 14px; + } + } + + [data-slot="content"] { + display: flex; + flex-direction: column; + gap: 1.5rem; + } + + [data-component="section"] { + h3 { + font-size: 13px; + font-weight: 600; + color: var(--color-text-strong); + margin-bottom: 6px; + } + + ul { + list-style: none; + padding: 0; + margin: 0; + padding-left: 16px; + display: flex; + flex-direction: column; + gap: 4px; + + li { + color: var(--color-text); + font-size: 13px; + line-height: 1.5; + padding-left: 12px; + position: relative; + + &::before { + content: "-"; + position: absolute; + left: 0; + color: var(--color-text-weak); + } + + [data-slot="author"] { + color: var(--color-text-weak); + font-size: 12px; + margin-left: 4px; + text-decoration: none; + + &:hover { + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + } + } + } + } + + [data-component="contributors"] { + font-size: 13px; + color: var(--color-text-weak); + padding-top: 0.5rem; + + span { + color: var(--color-text-weak); + } + + a { + color: var(--color-text); + text-decoration: none; + + &:hover { + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + } + } + + [data-component="highlights"] { + display: flex; + flex-direction: column; + gap: 3rem; + margin-bottom: 0.75rem; + } + + [data-component="collapsible-sections"] { + display: flex; + flex-direction: column; + gap: 0; + } + + [data-component="collapsible-section"] { + [data-slot="toggle"] { + display: flex; + align-items: center; + gap: 6px; + background: none; + border: none; + padding: 6px 0; + cursor: pointer; + font-family: inherit; + font-size: 13px; + font-weight: 600; + color: var(--color-text-weak); + + &:hover { + color: var(--color-text); + } + + [data-slot="icon"] { + font-size: 10px; + } + } + + ul { + list-style: none; + padding: 0; + margin: 0; + padding-left: 16px; + padding-bottom: 8px; + + li { + color: var(--color-text); + font-size: 13px; + line-height: 1.5; + padding-left: 12px; + position: relative; + + &::before { + content: "-"; + position: absolute; + left: 0; + color: var(--color-text-weak); + } + + [data-slot="author"] { + color: var(--color-text-weak); + font-size: 12px; + margin-left: 4px; + text-decoration: none; + + &:hover { + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + } + } + } + } + + [data-component="highlight"] { + h4 { + font-size: 14px; + font-weight: 600; + color: var(--color-text-strong); + margin-bottom: 8px; + } + + hr { + border: none; + border-top: 1px solid var(--color-border-weak); + margin-bottom: 16px; + } + + [data-slot="highlight-item"] { + margin-bottom: 48px; + + &:last-child { + margin-bottom: 0; + } + + p[data-slot="title"] { + font-weight: 600; + font-size: 16px; + margin-bottom: 4px; + } + + p { + font-size: 14px; + margin-bottom: 12px; + } + } + + img, + video { + max-width: 100%; + height: auto; + border-radius: 4px; + } + } + } + + a { + color: var(--color-text-strong); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + + &:hover { + text-decoration-thickness: 2px; + } + } +} diff --git a/packages/console/app/src/routes/changelog/index.tsx b/packages/console/app/src/routes/changelog/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..54f037479aa867354d78db406a1ad2dbbd941796 --- /dev/null +++ b/packages/console/app/src/routes/changelog/index.tsx @@ -0,0 +1,176 @@ +import "./index.css" +import { Title, Meta } from "@solidjs/meta" +import { createAsync } from "@solidjs/router" +import { Header } from "~/component/header" +import { Footer } from "~/component/footer" +import { Legal } from "~/component/legal" +import { changelog } from "~/lib/changelog" +import type { HighlightGroup } from "~/lib/changelog" +import { For, Show, createSignal } from "solid-js" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import { LocaleLinks } from "~/component/locale-links" + +function formatDate(dateString: string, locale: string) { + const date = new Date(dateString) + return date.toLocaleDateString(locale, { + year: "numeric", + month: "short", + day: "numeric", + }) +} + +function ReleaseItem(props: { item: string }) { + const parts = () => { + const match = props.item.match(/^(.+?)(\s*\(@([\w-]+)\))?$/) + if (match) { + return { + text: match[1], + username: match[3], + } + } + return { text: props.item, username: undefined } + } + + return ( +
  • + {parts().text} + + + (@{parts().username}) + + +
  • + ) +} + +function HighlightSection(props: { group: HighlightGroup }) { + return ( +
    +

    {props.group.source}

    +
    + + {(item) => ( +
    +

    {item.title}

    +

    {item.description}

    + + + + {item.title} + +
    + )} +
    +
    + ) +} + +function CollapsibleSection(props: { section: { title: string; items: string[] } }) { + const [open, setOpen] = createSignal(false) + + return ( +
    + + +
      + {(item) => } +
    +
    +
    + ) +} + +function CollapsibleSections(props: { sections: { title: string; items: string[] }[] }) { + return ( +
    + {(section) => } +
    + ) +} + +export default function Changelog() { + const i18n = useI18n() + const language = useLanguage() + const data = createAsync(() => changelog()) + const releases = () => data() ?? [] + + return ( +
    + {i18n.t("changelog.title")} + + + +
    +
    + +
    +
    +

    {i18n.t("changelog.hero.title")}

    +

    {i18n.t("changelog.hero.subtitle")}

    +
    + +
    + +

    + {i18n.t("changelog.empty")}{" "} + {i18n.t("changelog.viewJson")} +

    +
    + + {(release) => { + return ( +
    +
    + + +
    +
    + 0}> +
    + {(group) => } +
    +
    + 0 && release.sections.length > 0}> + + + + + {(section) => ( +
    +

    {section.title}

    +
      + {(item) => } +
    +
    + )} +
    +
    +
    +
    + ) + }} +
    +
    +
    + +
    +
    + + +
    + ) +} diff --git a/packages/console/app/src/routes/data/[...path].ts b/packages/console/app/src/routes/data/[...path].ts new file mode 100644 index 0000000000000000000000000000000000000000..d1899215df0b3469894998c3d8c9b6f1d7d550e5 --- /dev/null +++ b/packages/console/app/src/routes/data/[...path].ts @@ -0,0 +1,8 @@ +import { statsProxy } from "~/lib/stats-proxy" + +export const GET = statsProxy +export const POST = statsProxy +export const PUT = statsProxy +export const DELETE = statsProxy +export const OPTIONS = statsProxy +export const PATCH = statsProxy diff --git a/packages/console/app/src/routes/data/index.ts b/packages/console/app/src/routes/data/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..d1899215df0b3469894998c3d8c9b6f1d7d550e5 --- /dev/null +++ b/packages/console/app/src/routes/data/index.ts @@ -0,0 +1,8 @@ +import { statsProxy } from "~/lib/stats-proxy" + +export const GET = statsProxy +export const POST = statsProxy +export const PUT = statsProxy +export const DELETE = statsProxy +export const OPTIONS = statsProxy +export const PATCH = statsProxy diff --git a/packages/console/app/src/routes/desktop-feedback.ts b/packages/console/app/src/routes/desktop-feedback.ts new file mode 100644 index 0000000000000000000000000000000000000000..1916cdb4cf74a0d7596bbfaecdce0c1d807986f7 --- /dev/null +++ b/packages/console/app/src/routes/desktop-feedback.ts @@ -0,0 +1,5 @@ +import { redirect } from "@solidjs/router" + +export async function GET() { + return redirect("https://discord.gg/h5TNnkFVNy") +} diff --git a/packages/console/app/src/routes/discord.ts b/packages/console/app/src/routes/discord.ts new file mode 100644 index 0000000000000000000000000000000000000000..7088295da5cce8e5ef8a6e62357babde2f35b631 --- /dev/null +++ b/packages/console/app/src/routes/discord.ts @@ -0,0 +1,5 @@ +import { redirect } from "@solidjs/router" + +export async function GET() { + return redirect("https://discord.gg/opencode") +} diff --git a/packages/console/app/src/routes/docs/[...path].ts b/packages/console/app/src/routes/docs/[...path].ts new file mode 100644 index 0000000000000000000000000000000000000000..164bd2872e365dbfb40e0fcfd77a908321bbe5e2 --- /dev/null +++ b/packages/console/app/src/routes/docs/[...path].ts @@ -0,0 +1,30 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Resource } from "@opencode-ai/console-resource" +import { cookie, docs, localeFromRequest, tag } from "~/lib/language" + +async function handler(evt: APIEvent) { + const req = evt.request.clone() + const url = new URL(req.url) + const locale = localeFromRequest(req) + const host = Resource.App.stage === "production" ? "docs.opencode.ai" : "docs.dev.opencode.ai" + const targetUrl = `https://${host}${docs(locale, url.pathname)}${url.search}` + + const headers = new Headers(req.headers) + headers.set("accept-language", tag(locale)) + + const response = await fetch(targetUrl, { + method: req.method, + headers, + body: req.body, + }) + const next = new Response(response.body, response) + next.headers.append("set-cookie", cookie(locale)) + return next +} + +export const GET = handler +export const POST = handler +export const PUT = handler +export const DELETE = handler +export const OPTIONS = handler +export const PATCH = handler diff --git a/packages/console/app/src/routes/docs/index.ts b/packages/console/app/src/routes/docs/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..164bd2872e365dbfb40e0fcfd77a908321bbe5e2 --- /dev/null +++ b/packages/console/app/src/routes/docs/index.ts @@ -0,0 +1,30 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Resource } from "@opencode-ai/console-resource" +import { cookie, docs, localeFromRequest, tag } from "~/lib/language" + +async function handler(evt: APIEvent) { + const req = evt.request.clone() + const url = new URL(req.url) + const locale = localeFromRequest(req) + const host = Resource.App.stage === "production" ? "docs.opencode.ai" : "docs.dev.opencode.ai" + const targetUrl = `https://${host}${docs(locale, url.pathname)}${url.search}` + + const headers = new Headers(req.headers) + headers.set("accept-language", tag(locale)) + + const response = await fetch(targetUrl, { + method: req.method, + headers, + body: req.body, + }) + const next = new Response(response.body, response) + next.headers.append("set-cookie", cookie(locale)) + return next +} + +export const GET = handler +export const POST = handler +export const PUT = handler +export const DELETE = handler +export const OPTIONS = handler +export const PATCH = handler diff --git a/packages/console/app/src/routes/download/[channel]/[platform].ts b/packages/console/app/src/routes/download/[channel]/[platform].ts new file mode 100644 index 0000000000000000000000000000000000000000..4a4be13f4bd3e070f2abe8e9cce8ba10a04bdeb2 --- /dev/null +++ b/packages/console/app/src/routes/download/[channel]/[platform].ts @@ -0,0 +1,64 @@ +import type { APIEvent } from "@solidjs/start" +import { waitUntil } from "@opencode-ai/console-resource" +import type { DownloadPlatform } from "../types" + +const prodAssetNames: Record = { + "darwin-aarch64-dmg": "opencode-desktop-mac-arm64.dmg", + "darwin-x64-dmg": "opencode-desktop-mac-x64.dmg", + "windows-x64-nsis": "opencode-desktop-win-x64.exe", + "linux-x64-deb": "opencode-desktop-linux-amd64.deb", + "linux-x64-appimage": "opencode-desktop-linux-x86_64.AppImage", + "linux-x64-rpm": "opencode-desktop-linux-x86_64.rpm", +} satisfies Record + +const betaAssetNames: Record = { + "darwin-aarch64-dmg": "opencode-desktop-mac-arm64.dmg", + "darwin-x64-dmg": "opencode-desktop-mac-x64.dmg", + "windows-x64-nsis": "opencode-desktop-win-x64.exe", + "linux-x64-deb": "opencode-desktop-linux-amd64.deb", + "linux-x64-appimage": "opencode-desktop-linux-x86_64.AppImage", + "linux-x64-rpm": "opencode-desktop-linux-x86_64.rpm", +} satisfies Record + +// Doing this on the server lets us preserve the original name for platforms we don't care to rename for +const downloadNames: Record = { + "darwin-aarch64-dmg": "OpenCode Desktop.dmg", + "darwin-x64-dmg": "OpenCode Desktop.dmg", + "windows-x64-nsis": "OpenCode Desktop Installer.exe", +} satisfies { [K in DownloadPlatform]?: string } + +export async function GET({ params: { platform, channel } }: APIEvent) { + const assetName = channel === "stable" ? prodAssetNames[platform] : betaAssetNames[platform] + if (!assetName) return new Response(null, { status: 404 }) + + const latest = await fetch( + `https://github.com/anomalyco/${channel === "stable" ? "opencode" : "opencode-beta"}/releases/latest/download/${assetName}`, + { redirect: "manual" }, + ) + const location = latest.headers.get("location") + if (!location) return new Response(null, { status: 502 }) + + const key = new Request(location) + const cache = (caches as CacheStorage & { default: Cache }).default + const cached = await cache.match(key) + if (cached) return download(cached, platform, "HIT") + + const resp = await fetch(location) + if (!resp.ok) return resp + + const headers = new Headers(resp.headers) + headers.set("cache-control", "public, max-age=31536000, immutable") + headers.delete("set-cookie") + const result = new Response(resp.body, { status: resp.status, statusText: resp.statusText, headers }) + waitUntil(cache.put(key, result.clone())) + return download(result, platform, "MISS") +} + +function download(resp: Response, platform: string, cache: "HIT" | "MISS") { + const downloadName = downloadNames[platform] + const headers = new Headers(resp.headers) + if (downloadName) headers.set("content-disposition", `attachment; filename="${downloadName}"`) + headers.set("x-opencode-cache", cache) + + return new Response(resp.body, { status: resp.status, statusText: resp.statusText, headers }) +} diff --git a/packages/console/app/src/routes/download/index.css b/packages/console/app/src/routes/download/index.css new file mode 100644 index 0000000000000000000000000000000000000000..1dde6e61051976308e817853c0bc485f884087fc --- /dev/null +++ b/packages/console/app/src/routes/download/index.css @@ -0,0 +1,728 @@ +::selection { + background: var(--color-background-interactive); + color: var(--color-text-strong); + + @media (prefers-color-scheme: dark) { + background: var(--color-background-interactive); + color: var(--color-text-inverted); + } +} + +[data-page="download"] { + --color-background: hsl(0, 20%, 99%); + --color-background-weak: hsl(0, 8%, 97%); + --color-background-weak-hover: hsl(0, 8%, 94%); + --color-background-strong: hsl(0, 5%, 12%); + --color-background-strong-hover: hsl(0, 5%, 18%); + --color-background-interactive: hsl(62, 84%, 88%); + --color-background-interactive-weaker: hsl(64, 74%, 95%); + + --color-text: hsl(0, 1%, 39%); + --color-text-weak: hsl(0, 1%, 60%); + --color-text-weaker: hsl(30, 2%, 81%); + --color-text-strong: hsl(0, 5%, 12%); + --color-text-inverted: hsl(0, 20%, 99%); + --color-text-success: hsl(119, 100%, 35%); + + --color-border: hsl(30, 2%, 81%); + --color-border-weak: hsl(0, 1%, 85%); + + --color-icon: hsl(0, 1%, 55%); + --color-success: hsl(142, 76%, 36%); + + background: var(--color-background); + font-family: var(--font-mono); + color: var(--color-text); + padding-bottom: 5rem; + + @media (prefers-color-scheme: dark) { + --color-background: hsl(0, 9%, 7%); + --color-background-weak: hsl(0, 6%, 10%); + --color-background-weak-hover: hsl(0, 6%, 15%); + --color-background-strong: hsl(0, 15%, 94%); + --color-background-strong-hover: hsl(0, 15%, 97%); + --color-background-interactive: hsl(62, 100%, 90%); + --color-background-interactive-weaker: hsl(60, 20%, 8%); + + --color-text: hsl(0, 4%, 71%); + --color-text-weak: hsl(0, 2%, 49%); + --color-text-weaker: hsl(0, 3%, 28%); + --color-text-strong: hsl(0, 15%, 94%); + --color-text-inverted: hsl(0, 9%, 7%); + --color-text-success: hsl(119, 60%, 72%); + + --color-border: hsl(0, 3%, 28%); + --color-border-weak: hsl(0, 4%, 23%); + + --color-icon: hsl(10, 3%, 43%); + --color-success: hsl(142, 76%, 46%); + } + + /* Header and Footer styles - copied from enterprise */ + [data-component="top"] { + padding: 24px 5rem; + height: 80px; + position: sticky; + top: 0; + display: flex; + justify-content: space-between; + align-items: center; + background: var(--color-background); + border-bottom: 1px solid var(--color-border-weak); + z-index: 10; + + @media (max-width: 60rem) { + padding: 24px 1.5rem; + } + + img { + height: 34px; + width: auto; + } + + [data-component="nav-desktop"] { + ul { + display: flex; + justify-content: space-between; + align-items: center; + gap: 32px; + + @media (max-width: 55rem) { + gap: 24px; + } + + @media (max-width: 48rem) { + gap: 24px; + } + li { + display: inline-block; + a { + text-decoration: none; + span { + color: var(--color-text-weak); + } + } + a:hover { + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + [data-slot="cta-button"] { + background: var(--color-background-strong); + color: var(--color-text-inverted); + padding: 8px 16px; + border-radius: 4px; + font-weight: 500; + text-decoration: none; + white-space: nowrap; + + @media (max-width: 55rem) { + display: none; + } + } + [data-slot="cta-button"]:hover { + background: var(--color-background-strong-hover); + text-decoration: none; + } + } + } + + @media (max-width: 40rem) { + display: none; + } + } + + [data-component="nav-mobile"] { + button > svg { + color: var(--color-icon); + } + } + + [data-component="nav-mobile-toggle"] { + border: none; + background: none; + outline: none; + height: 40px; + width: 40px; + cursor: pointer; + margin-right: -8px; + } + + [data-component="nav-mobile-toggle"]:hover { + background: var(--color-background-weak); + } + + [data-component="nav-mobile"] { + display: none; + + @media (max-width: 40rem) { + display: block; + + [data-component="nav-mobile-icon"] { + cursor: pointer; + height: 40px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + } + + [data-component="nav-mobile-menu-list"] { + position: fixed; + background: var(--color-background); + top: 80px; + left: 0; + right: 0; + height: 100vh; + + ul { + list-style: none; + padding: 20px 0; + + li { + a { + text-decoration: none; + padding: 20px; + display: block; + + span { + color: var(--color-text-weak); + } + } + + a:hover { + background: var(--color-background-weak); + } + } + } + } + } + } + + [data-slot="logo dark"] { + display: none; + } + + @media (prefers-color-scheme: dark) { + [data-slot="logo light"] { + display: none; + } + [data-slot="logo dark"] { + display: block; + } + } + } + + [data-component="footer"] { + border-top: 1px solid var(--color-border-weak); + display: flex; + flex-direction: row; + + @media (max-width: 65rem) { + border-bottom: 1px solid var(--color-border-weak); + } + + [data-slot="cell"] { + flex: 1; + text-align: center; + + a { + text-decoration: none; + padding: 2rem 0; + width: 100%; + display: block; + + span { + color: var(--color-text-weak); + + @media (max-width: 40rem) { + display: none; + } + } + } + + a:hover { + background: var(--color-background-weak); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + } + + [data-slot="cell"] + [data-slot="cell"] { + border-left: 1px solid var(--color-border-weak); + + @media (max-width: 40rem) { + border-left: none; + } + } + + @media (max-width: 25rem) { + flex-wrap: wrap; + + [data-slot="cell"] { + flex: 1 0 100%; + border-left: none; + border-top: 1px solid var(--color-border-weak); + } + + [data-slot="cell"]:nth-child(1) { + border-top: none; + } + } + } + + [data-component="container"] { + max-width: 67.5rem; + margin: 0 auto; + border: 1px solid var(--color-border-weak); + border-top: none; + + @media (max-width: 65rem) { + border: none; + } + } + + [data-component="content"] { + padding: 3rem 5rem 6rem; + + @media (max-width: 60rem) { + padding: 4rem 1.5rem; + } + } + + [data-component="legal"] { + color: var(--color-text-weak); + text-align: center; + padding: 2rem 5rem; + display: flex; + gap: 32px; + justify-content: center; + + @media (max-width: 60rem) { + padding: 2rem 1.5rem; + } + + a { + color: var(--color-text-weak); + text-decoration: none; + } + + a:hover { + color: var(--color-text); + text-decoration: underline; + } + } + + /* Download Hero Section */ + [data-component="download-hero"] { + display: grid; + grid-template-columns: 255px 1fr; + gap: 4rem; + padding: 4px; + border: 1px solid var(--color-border-weak); + border-radius: 8px; + margin-bottom: 4rem; + + @media (max-width: 50rem) { + grid-template-columns: 1fr; + gap: 0; + margin-bottom: 2rem; + } + + [data-component="hero-video"] { + video { + display: block; + width: 100%; + aspect-ratio: 1; + object-fit: cover; + border-radius: 4px; + + @media (max-width: 50rem) { + aspect-ratio: 16 / 9; + } + } + } + + [data-component="hero-text"] { + display: flex; + flex-direction: column; + justify-content: center; + padding-right: 3rem; + + @media (max-width: 50rem) { + padding: 1.5rem; + } + + h1 { + font-size: 1.5rem; + font-weight: 700; + color: var(--color-text-strong); + margin-bottom: 4px; + + @media (max-width: 40rem) { + margin-bottom: 1rem; + } + } + + p { + color: var(--color-text); + margin-bottom: 12px; + + @media (max-width: 40rem) { + margin-bottom: 2.5rem; + line-height: 1.6; + } + } + + [data-component="download-button"] { + padding: 8px 20px 8px 16px; + background: var(--color-background-strong); + color: var(--color-text-inverted); + border: none; + border-radius: 4px; + font-weight: 500; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 10px; + transition: all 0.2s ease; + text-decoration: none; + width: fit-content; + + &:hover:not(:disabled) { + background: var(--color-background-strong-hover); + } + + &:active { + transform: scale(0.98); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + } + } + } + + /* Download Sections */ + [data-component="download-section"] { + display: grid; + grid-template-columns: 260px 1fr; + gap: 4rem; + margin-bottom: 4rem; + + @media (max-width: 50rem) { + grid-template-columns: 1fr; + gap: 1rem; + margin-bottom: 3rem; + } + + &:last-child { + margin-bottom: 0; + } + + [data-component="section-label"] { + font-weight: 500; + color: var(--color-text-strong); + padding-top: 1rem; + + span { + color: var(--color-text-weaker); + } + + @media (max-width: 50rem) { + padding-top: 0; + padding-bottom: 0.5rem; + } + } + + [data-component="section-content"] { + display: flex; + flex-direction: column; + gap: 0; + } + } + + /* CLI Rows */ + button[data-component="cli-row"] { + display: flex; + align-items: center; + gap: 12px; + padding: 1rem 0.5rem 1rem 1.5rem; + margin: 0 -0.5rem 0 -1.5rem; + background: none; + border: none; + border-radius: 4px; + width: calc(100% + 2rem); + text-align: left; + cursor: pointer; + transition: background 0.15s ease; + + &:hover { + background: var(--color-background-weak); + } + + code { + font-family: var(--font-mono); + color: var(--color-text-weak); + + strong { + color: var(--color-text-strong); + font-weight: 500; + } + } + + [data-component="copy-status"] { + display: flex; + align-items: center; + opacity: 0; + transition: opacity 0.15s ease; + color: var(--color-icon); + + svg { + width: 18px; + height: 18px; + } + + [data-slot="copy"] { + display: block; + } + + [data-slot="check"] { + display: none; + } + } + + &:hover [data-component="copy-status"] { + opacity: 1; + } + + &[data-copied] [data-component="copy-status"] { + opacity: 1; + + [data-slot="copy"] { + display: none; + } + + [data-slot="check"] { + display: block; + } + } + } + + /* Download Rows */ + [data-component="download-row"] { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.75rem 0.5rem 0.75rem 1.5rem; + margin: 0 -0.5rem 0 -1.5rem; + border-radius: 4px; + transition: background 0.15s ease; + + &:hover { + background: var(--color-background-weak); + } + + [data-component="download-info"] { + display: flex; + align-items: center; + gap: 0.75rem; + + [data-slot="icon"] { + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + color: var(--color-icon); + + svg { + width: 20px; + height: 20px; + } + + img { + width: 20px; + height: 20px; + } + } + + span { + color: var(--color-text); + } + } + + [data-component="action-button"] { + padding: 6px 16px; + background: var(--color-background); + color: var(--color-text); + border: 1px solid var(--color-border); + border-radius: 4px; + font-weight: 500; + cursor: pointer; + text-decoration: none; + transition: all 0.2s ease; + + &:hover { + background: var(--color-background-weak); + border-color: var(--color-border); + text-decoration: none; + } + + &:active { + transform: scale(0.98); + } + } + } + + a { + color: var(--color-text-strong); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + + &:hover { + text-decoration-thickness: 2px; + } + } + + /* Narrow screen font sizes */ + @media (max-width: 40rem) { + [data-component="download-section"] { + [data-component="section-label"] { + font-size: 14px; + } + } + + button[data-component="cli-row"] { + margin: 0; + padding: 1rem 0; + width: 100%; + overflow: hidden; + + code { + font-size: 14px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + display: block; + max-width: calc(100vw - 80px); + } + + [data-component="copy-status"] { + opacity: 1 !important; + flex-shrink: 0; + } + } + + [data-component="download-row"] { + margin: 0; + padding: 0.75rem 0; + + [data-component="download-info"] span { + font-size: 14px; + } + + [data-component="action-button"] { + font-size: 14px; + padding-left: 8px; + padding-right: 8px; + } + } + } + + @media (max-width: 22.5rem) { + [data-slot="hide-narrow"] { + display: none; + } + } + + /* FAQ Section */ + [data-component="faq"] { + border-top: 1px solid var(--color-border-weak); + padding: 4rem 5rem; + margin-top: 4rem; + + @media (max-width: 60rem) { + padding: 3rem 1.5rem; + margin-top: 3rem; + } + + [data-slot="section-title"] { + margin-bottom: 24px; + + h3 { + font-size: 16px; + font-weight: 700; + color: var(--color-text-strong); + margin-bottom: 12px; + } + } + + ul { + padding: 0; + + li { + list-style: none; + margin-bottom: 24px; + line-height: 200%; + } + } + + [data-slot="faq-question"] { + display: flex; + gap: 16px; + margin-bottom: 8px; + color: var(--color-text-strong); + font-weight: 500; + cursor: pointer; + background: none; + border: none; + padding: 0; + align-items: start; + min-height: 24px; + + svg { + margin-top: 2px; + } + + [data-slot="faq-icon-plus"] { + flex-shrink: 0; + color: var(--color-text-weak); + margin-top: 2px; + + [data-closed] & { + display: block; + } + [data-expanded] & { + display: none; + } + } + [data-slot="faq-icon-minus"] { + flex-shrink: 0; + color: var(--color-text-weak); + margin-top: 2px; + + [data-closed] & { + display: none; + } + [data-expanded] & { + display: block; + } + } + [data-slot="faq-question-text"] { + flex-grow: 1; + text-align: left; + } + } + + [data-slot="faq-answer"] { + margin-left: 40px; + margin-bottom: 32px; + line-height: 200%; + } + } +} diff --git a/packages/console/app/src/routes/download/index.tsx b/packages/console/app/src/routes/download/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c69895e4f24a0f9821240967c8eeb3e2ce3fba02 --- /dev/null +++ b/packages/console/app/src/routes/download/index.tsx @@ -0,0 +1,488 @@ +import "./index.css" +import { Meta, Title } from "@solidjs/meta" +import { A } from "@solidjs/router" +import { createSignal, type JSX, onMount, Show } from "solid-js" +import { Faq } from "~/component/faq" +import { Footer } from "~/component/footer" +import { Header } from "~/component/header" +import { IconCheck, IconCopy } from "~/component/icon" +import { Legal } from "~/component/legal" +import { LocaleLinks } from "~/component/locale-links" +import { config } from "~/config" +import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import desktopTabsVideo from "../../asset/lander/desktop-tabs-landscape.mp4" +import type { DownloadPlatform } from "./types" + +type OS = "macOS" | "Windows" | "Linux" | null + +function detectOS(): OS { + if (typeof navigator === "undefined") return null + const platform = navigator.platform.toLowerCase() + const userAgent = navigator.userAgent.toLowerCase() + + if (platform.includes("mac") || userAgent.includes("mac")) return "macOS" + if (platform.includes("win") || userAgent.includes("win")) return "Windows" + if (platform.includes("linux") || userAgent.includes("linux")) return "Linux" + return null +} + +function getDownloadPlatform(os: OS): DownloadPlatform { + switch (os) { + case "macOS": + return "darwin-aarch64-dmg" + case "Windows": + return "windows-x64-nsis" + case "Linux": + return "linux-x64-deb" + default: + return "darwin-aarch64-dmg" + } +} + +function getDownloadHref(platform: DownloadPlatform, channel: "stable" | "beta" = "stable") { + return `/download/${channel}/${platform}` +} + +function IconDownload(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +function CopyStatus() { + return ( + + + + + ) +} + +export default function Download() { + const i18n = useI18n() + const language = useLanguage() + const [detectedOS, setDetectedOS] = createSignal(null) + + onMount(() => { + setDetectedOS(detectOS()) + }) + + const handleCopyClick = (command: string) => (event: Event) => { + const button = event.currentTarget as HTMLButtonElement + void navigator.clipboard.writeText(command) + button.setAttribute("data-copied", "") + setTimeout(() => { + button.removeAttribute("data-copied") + }, 1500) + } + return ( +
    + {i18n.t("download.title")} + + +
    +
    + +
    +
    +
    +
    +
    +

    {i18n.t("download.hero.title")}

    +

    + {i18n.t("home.promo.body")} {i18n.t("home.promo.cta")} +

    + + + + {i18n.t("download.hero.button", { os: detectedOS()! })} + + +
    +
    + +
    +
    + [1] {i18n.t("download.section.terminal")} +
    +
    + + + + + +
    +
    + +
    +
    + [2] {i18n.t("download.section.desktop")} +
    +
    + +
    +
    + + + + + + {i18n.t("download.platform.macosAppleSilicon")} +
    + + {i18n.t("download.action.download")} + +
    +
    +
    + + + + + + {i18n.t("download.platform.macosIntel")} +
    + + {i18n.t("download.action.download")} + +
    +
    +
    + + + + + + + + + + + + + {i18n.t("download.platform.windowsX64")} +
    + + {i18n.t("download.action.download")} + +
    +
    +
    + + + + + + {i18n.t("download.platform.linuxDeb")} +
    + + {i18n.t("download.action.download")} + +
    +
    +
    + + + + + + {i18n.t("download.platform.linuxRpm")} +
    + + {i18n.t("download.action.download")} + +
    + {/* Disabled temporarily as it doesn't work */} + {/*
    +
    + + + + + + Linux (.AppImage) +
    + + Download + +
    */} +
    +
    + +
    +
    + [3] {i18n.t("download.section.extensions")} +
    +
    +
    +
    + + + + + + + + + + + + + VS Code +
    + + {i18n.t("download.action.install")} + +
    + +
    +
    + + + + + + + + + + + + + Cursor +
    + + {i18n.t("download.action.install")} + +
    + + + +
    +
    + + + + + + Windsurf +
    + + {i18n.t("download.action.install")} + +
    + +
    +
    + + + + + + VSCodium +
    + + {i18n.t("download.action.install")} + +
    +
    +
    + +
    +
    + [4] {i18n.t("download.section.integrations")} +
    +
    + + + +
    +
    +
    + +
    +
    +

    {i18n.t("common.faq")}

    +
    + +
    + +
    +
    + +
    + ) +} diff --git a/packages/console/app/src/routes/download/types.ts b/packages/console/app/src/routes/download/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..916f97022e3077d51ee2fea14fcbff765d31c169 --- /dev/null +++ b/packages/console/app/src/routes/download/types.ts @@ -0,0 +1,4 @@ +export type DownloadPlatform = + | `darwin-${"x64" | "aarch64"}-dmg` + | "windows-x64-nsis" + | `linux-x64-${"deb" | "rpm" | "appimage"}` diff --git a/packages/console/app/src/routes/enterprise/index.css b/packages/console/app/src/routes/enterprise/index.css new file mode 100644 index 0000000000000000000000000000000000000000..5c594bb51b015ce954067f91ac0bb47c7aa695f8 --- /dev/null +++ b/packages/console/app/src/routes/enterprise/index.css @@ -0,0 +1,588 @@ +::selection { + background: var(--color-background-interactive); + color: var(--color-text-strong); + + @media (prefers-color-scheme: dark) { + background: var(--color-background-interactive); + color: var(--color-text-inverted); + } +} + +[data-page="enterprise"] { + --color-background: hsl(0, 20%, 99%); + --color-background-weak: hsl(0, 8%, 97%); + --color-background-weak-hover: hsl(0, 8%, 94%); + --color-background-strong: hsl(0, 5%, 12%); + --color-background-strong-hover: hsl(0, 5%, 18%); + --color-background-interactive: hsl(62, 84%, 88%); + --color-background-interactive-weaker: hsl(64, 74%, 95%); + + --color-text: hsl(0, 1%, 39%); + --color-text-weak: hsl(0, 1%, 60%); + --color-text-weaker: hsl(30, 2%, 81%); + --color-text-strong: hsl(0, 5%, 12%); + --color-text-inverted: hsl(0, 20%, 99%); + --color-text-success: hsl(119, 100%, 35%); + --color-text-error: hsl(4, 72%, 45%); + + --color-border: hsl(30, 2%, 81%); + --color-border-weak: hsl(0, 1%, 85%); + + --color-icon: hsl(0, 1%, 55%); + --color-success: hsl(142, 76%, 36%); + + background: var(--color-background); + font-family: var(--font-mono); + color: var(--color-text); + padding-bottom: 5rem; + + @media (prefers-color-scheme: dark) { + --color-background: hsl(0, 9%, 7%); + --color-background-weak: hsl(0, 6%, 10%); + --color-background-weak-hover: hsl(0, 6%, 15%); + --color-background-strong: hsl(0, 15%, 94%); + --color-background-strong-hover: hsl(0, 15%, 97%); + --color-background-interactive: hsl(62, 100%, 90%); + --color-background-interactive-weaker: hsl(60, 20%, 8%); + + --color-text: hsl(0, 4%, 71%); + --color-text-weak: hsl(0, 2%, 49%); + --color-text-weaker: hsl(0, 3%, 28%); + --color-text-strong: hsl(0, 15%, 94%); + --color-text-inverted: hsl(0, 9%, 7%); + --color-text-success: hsl(119, 60%, 72%); + --color-text-error: hsl(4, 76%, 72%); + + --color-border: hsl(0, 3%, 28%); + --color-border-weak: hsl(0, 4%, 23%); + + --color-icon: hsl(10, 3%, 43%); + --color-success: hsl(142, 76%, 46%); + } + + /* Header and Footer styles - copied from index.css */ + [data-component="top"] { + padding: 24px 5rem; + height: 80px; + position: sticky; + top: 0; + display: flex; + justify-content: space-between; + align-items: center; + background: var(--color-background); + border-bottom: 1px solid var(--color-border-weak); + z-index: 10; + + @media (max-width: 60rem) { + padding: 24px 1.5rem; + } + + img { + height: 34px; + width: auto; + } + + [data-component="nav-desktop"] { + ul { + display: flex; + justify-content: space-between; + align-items: center; + gap: 32px; + + @media (max-width: 55rem) { + gap: 24px; + } + + @media (max-width: 48rem) { + gap: 24px; + } + li { + display: inline-block; + a { + text-decoration: none; + span { + color: var(--color-text-weak); + } + } + a:hover { + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + [data-slot="cta-button"] { + background: var(--color-background-strong); + color: var(--color-text-inverted); + padding: 8px 16px 8px 10px; + border-radius: 4px; + font-weight: 500; + text-decoration: none; + display: flex; + align-items: center; + gap: 8px; + white-space: nowrap; + + @media (max-width: 55rem) { + display: none; + } + } + [data-slot="cta-button"]:hover { + background: var(--color-background-strong-hover); + text-decoration: none; + } + } + } + + @media (max-width: 40rem) { + display: none; + } + } + + [data-component="nav-mobile"] { + button > svg { + color: var(--color-icon); + } + } + + [data-component="nav-mobile-toggle"] { + border: none; + background: none; + outline: none; + height: 40px; + width: 40px; + cursor: pointer; + margin-right: -8px; + } + + [data-component="nav-mobile-toggle"]:hover { + background: var(--color-background-weak); + } + + [data-component="nav-mobile"] { + display: none; + + @media (max-width: 40rem) { + display: block; + + [data-component="nav-mobile-icon"] { + cursor: pointer; + height: 40px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + } + + [data-component="nav-mobile-menu-list"] { + position: fixed; + background: var(--color-background); + top: 80px; + left: 0; + right: 0; + height: 100vh; + + ul { + list-style: none; + padding: 20px 0; + + li { + a { + text-decoration: none; + padding: 20px; + display: block; + + span { + color: var(--color-text-weak); + } + } + + a:hover { + background: var(--color-background-weak); + } + } + } + } + } + } + + [data-slot="logo dark"] { + display: none; + } + + @media (prefers-color-scheme: dark) { + [data-slot="logo light"] { + display: none; + } + [data-slot="logo dark"] { + display: block; + } + } + } + + [data-component="footer"] { + border-top: 1px solid var(--color-border-weak); + display: flex; + flex-direction: row; + + @media (max-width: 65rem) { + border-bottom: 1px solid var(--color-border-weak); + } + + [data-slot="cell"] { + flex: 1; + text-align: center; + + a { + text-decoration: none; + padding: 2rem 0; + width: 100%; + display: block; + + span { + color: var(--color-text-weak); + + @media (max-width: 40rem) { + display: none; + } + } + } + + a:hover { + background: var(--color-background-weak); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + } + } + + [data-slot="cell"] + [data-slot="cell"] { + border-left: 1px solid var(--color-border-weak); + + @media (max-width: 40rem) { + border-left: none; + } + } + + /* Mobile: third column on its own row */ + @media (max-width: 25rem) { + flex-wrap: wrap; + + [data-slot="cell"] { + flex: 1 0 100%; + border-left: none; + border-top: 1px solid var(--color-border-weak); + } + + [data-slot="cell"]:nth-child(1) { + border-top: none; + } + } + } + + [data-component="container"] { + max-width: 67.5rem; + margin: 0 auto; + border: 1px solid var(--color-border-weak); + border-top: none; + + @media (max-width: 65rem) { + border: none; + } + } + + [data-component="content"] { + } + + [data-component="enterprise-content"] { + padding: 4rem 0; + + @media (max-width: 60rem) { + padding: 2rem 0; + } + } + + [data-component="enterprise-columns"] { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4rem; + padding: 4rem 5rem; + + @media (max-width: 80rem) { + gap: 3rem; + } + + @media (max-width: 60rem) { + grid-template-columns: 1fr; + gap: 3rem; + padding: 2rem 1.5rem; + } + } + + [data-component="enterprise-column-1"] { + h1 { + font-size: 1.5rem; + font-weight: 700; + color: var(--color-text-strong); + margin-bottom: 1rem; + } + + h3 { + font-size: 1.25rem; + font-weight: 500; + color: var(--color-text-strong); + margin: 2rem 0 1rem 0; + } + + p { + line-height: 1.6; + margin-bottom: 1.5rem; + color: var(--color-text); + } + + [data-component="testimonial"] { + margin-top: 4rem; + font-weight: 500; + color: var(--color-text-strong); + + [data-component="quotation"] { + svg { + margin-bottom: 1rem; + opacity: 20%; + } + } + + [data-component="testimonial-logo"] { + svg { + margin-top: 1.5rem; + } + } + } + } + + [data-component="enterprise-column-2"] { + [data-component="enterprise-form"] { + padding: 0; + + h2 { + font-size: 1.5rem; + font-weight: 500; + color: var(--color-text-strong); + margin-bottom: 1.5rem; + } + + [data-component="form-group"] { + margin-bottom: 1.5rem; + + label { + display: block; + font-weight: 500; + color: var(--color-text-weak); + margin-bottom: 0.5rem; + font-size: 0.875rem; + } + + input:-webkit-autofill, + input:-webkit-autofill:hover, + input:-webkit-autofill:focus, + input:-webkit-autofill:active { + transition: background-color 5000000s ease-in-out 0s; + } + + input:-webkit-autofill { + -webkit-text-fill-color: var(--color-text-strong) !important; + } + + input:-moz-autofill { + -moz-text-fill-color: var(--color-text-strong) !important; + } + + input, + textarea { + width: 100%; + padding: 0.75rem; + border: 1px solid var(--color-border-weak); + border-radius: 4px; + background: var(--color-background-weak); + color: var(--color-text-strong); + font-family: inherit; + + &::placeholder { + color: var(--color-text-weak); + } + + &:focus { + background: var(--color-background-interactive-weaker); + outline: none; + border: none; + color: var(--color-text-strong); + border: 1px solid var(--color-background-strong); + box-shadow: 0 0 0 3px var(--color-background-interactive); + + @media (prefers-color-scheme: dark) { + box-shadow: none; + border: 1px solid var(--color-background-interactive); + } + } + } + + textarea { + resize: vertical; + min-height: 120px; + } + } + + [data-component="submit-button"] { + padding: 0.5rem 1.5rem; + background: var(--color-background-strong); + color: var(--color-text-inverted); + border: none; + border-radius: 4px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s ease; + + &:hover:not(:disabled) { + background: var(--color-background-strong-hover); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + } + + [data-component="success-message"] { + margin-top: 1rem; + padding: 1rem 0; + color: var(--color-text-success); + text-align: left; + } + + [data-component="error-message"] { + margin-top: 1rem; + padding: 1rem 0; + color: var(--color-text-error); + text-align: left; + } + } + } + + [data-component="faq"] { + border-top: 1px solid var(--color-border-weak); + padding: 4rem 5rem; + + @media (max-width: 60rem) { + padding: 2rem 1.5rem; + } + + [data-slot="section-title"] { + margin-bottom: 24px; + + h3 { + font-size: 16px; + font-weight: 700; + color: var(--color-text-strong); + margin-bottom: 12px; + } + + p { + margin-bottom: 12px; + color: var(--color-text); + } + } + + ul { + padding: 0; + + li { + list-style: none; + margin-bottom: 24px; + line-height: 200%; + + @media (max-width: 60rem) { + line-height: 180%; + } + } + } + + [data-slot="faq-question"] { + display: flex; + gap: 16px; + margin-bottom: 8px; + color: var(--color-text-strong); + font-weight: 500; + cursor: pointer; + background: none; + border: none; + padding: 0; + + [data-slot="faq-icon-plus"] { + flex-shrink: 0; + color: var(--color-text-weak); + margin-top: 2px; + + [data-closed] & { + display: block; + } + [data-expanded] & { + display: none; + } + } + [data-slot="faq-icon-minus"] { + flex-shrink: 0; + color: var(--color-text-weak); + margin-top: 2px; + + [data-closed] & { + display: none; + } + [data-expanded] & { + display: block; + } + } + [data-slot="faq-question-text"] { + flex-grow: 1; + text-align: left; + } + } + + [data-slot="faq-answer"] { + margin-left: 40px; + margin-bottom: 32px; + color: var(--color-text); + } + } + + [data-component="legal"] { + color: var(--color-text-weak); + text-align: center; + padding: 2rem 5rem; + display: flex; + gap: 32px; + justify-content: center; + + @media (max-width: 60rem) { + padding: 2rem 1.5rem; + } + + a { + color: var(--color-text-weak); + text-decoration: none; + } + + a:hover { + color: var(--color-text); + text-decoration: underline; + } + } + + a { + color: var(--color-text-strong); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-thickness: 1px; + + &:hover { + text-decoration-thickness: 2px; + } + } +} diff --git a/packages/console/app/src/routes/enterprise/index.tsx b/packages/console/app/src/routes/enterprise/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..216fb470fffd5f966bf5f777eb51e6ff4353acea --- /dev/null +++ b/packages/console/app/src/routes/enterprise/index.tsx @@ -0,0 +1,290 @@ +import "./index.css" +import { Title, Meta } from "@solidjs/meta" +import { createSignal, Show } from "solid-js" +import { Header } from "~/component/header" +import { Footer } from "~/component/footer" +import { Legal } from "~/component/legal" +import { Faq } from "~/component/faq" +import { useI18n } from "~/context/i18n" +import { LocaleLinks } from "~/component/locale-links" + +export default function Enterprise() { + const i18n = useI18n() + const [formData, setFormData] = createSignal({ + name: "", + role: "", + company: "", + email: "", + phone: "", + alias: "", + message: "", + }) + const [isSubmitting, setIsSubmitting] = createSignal(false) + const [showSuccess, setShowSuccess] = createSignal(false) + const [error, setError] = createSignal("") + + const handleInputChange = (field: string) => (e: Event) => { + const target = e.target as HTMLInputElement | HTMLTextAreaElement + setFormData((prev) => ({ ...prev, [field]: target.value })) + } + + const handleSubmit = async (e: Event) => { + e.preventDefault() + setError("") + setShowSuccess(false) + setIsSubmitting(true) + + try { + const response = await fetch("/api/enterprise", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(formData()), + }) + + if (response.ok) { + setShowSuccess(true) + setFormData({ + name: "", + role: "", + company: "", + email: "", + phone: "", + alias: "", + message: "", + }) + setTimeout(() => setShowSuccess(false), 5000) + return + } + + const data = (await response.json().catch(() => null)) as { error?: string } | null + setError(data?.error ?? i18n.t("enterprise.form.error.internalServer")) + } catch (error) { + console.error("Failed to submit form:", error) + setError(i18n.t("enterprise.form.error.internalServer")) + } finally { + setIsSubmitting(false) + } + } + + return ( +
    + {i18n.t("enterprise.title")} + + +
    +
    + +
    +
    +
    +
    +

    {i18n.t("enterprise.hero.title")}

    +

    {i18n.t("enterprise.hero.body1")}

    +

    {i18n.t("enterprise.hero.body2")}

    + + +
    +
    + + + +
    + Thanks to OpenCode, we found a way to create software to track all our assets — even the imaginary + ones. +
    + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    + + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + +