{ "common": { "save": "Save", "cancel": "Cancel", "close": "Close", "confirm": "Confirm", "clear": "Clear", "edit": "Edit", "delete": "Delete", "loading": "Loading..", "new": "NEW" }, "nav": { "about": "About", "editor": "Editor", "newChat": "Start fresh chat", "github": "GitHub", "settings": "Settings", "hidePanel": "Hide chat panel (Ctrl+B)", "showPanel": "Show chat panel (Ctrl+B)", "aiChat": "AI Chat" }, "providers": { "useServerDefault": "Use Server Default", "openai": "OpenAI", "anthropic": "Anthropic", "google": "Google", "azure": "Azure OpenAI", "openrouter": "OpenRouter", "deepseek": "DeepSeek", "siliconflow": "SiliconFlow", "modelscope": "ModelScope", "minimax": "MiniMax", "glm": "GLM", "qwen": "Qwen", "kimi": "Kimi", "qiniu": "Qiniu" }, "chat": { "placeholder": "Describe your diagram or upload a file...", "send": "Send", "stopGeneration": "Stop generation", "sendMessage": "Send message", "clearConversation": "Clear conversation", "diagramHistory": "Diagram history", "saveDiagram": "Save diagram", "uploadFile": "Upload file (image, PDF, text)", "minimalStyle": "Minimal", "styledMode": "Styled", "minimalTooltip": "Use minimal for faster generation (no colors)", "regenerate": "Regenerate response", "copyResponse": "Copy response", "copied": "Copied!", "failedToCopy": "Failed to copy", "failedToCopyDetail": "Failed to copy message. Please copy manually or check clipboard permissions.", "goodResponse": "Good response", "badResponse": "Bad response", "clickToEdit": "Click to edit", "editMessage": "Edit message", "saveAndSubmit": "Save & Submit", "ExtractURL": "Extract from URL" }, "examples": { "title": "Create diagrams with AI", "subtitle": "Describe what you want to create or upload an image to replicate", "quickExamples": "Quick Examples", "paperToDiagram": "Paper to Diagram", "paperDescription": "Upload .pdf, .txt, .md, .json, .csv, .py, .js, .ts and more", "animatedDiagram": "Animated Diagram", "animatedDescription": "Draw a transformer architecture with animated connectors", "awsArchitecture": "AWS Architecture", "awsDescription": "Create a cloud architecture diagram with AWS icons", "replicateFlowchart": "Replicate Flowchart", "replicateDescription": "Upload and replicate an existing flowchart", "creativeDrawing": "Creative Drawing", "creativeDescription": "Draw something fun and creative", "cachedNote": "Examples are cached for instant response", "mcpServer": "MCP Server", "mcpDescription": "Use in Claude Desktop, VS Code & Cursor" }, "settings": { "title": "Settings", "description": "Configure your application settings.", "apiKeysModels": "API Keys & Models", "apiKeysModelsDescription": "Configure AI providers and API keys.", "accessCode": "Access Code", "accessCodePlaceholder": "Enter access code", "accessCodeDescription": "Required to use this application.", "aiProvider": "AI Provider Settings", "aiProviderDescription": "Use your own API key to bypass usage limits. Your key is stored locally in your browser and is never stored on the server.", "provider": "Provider", "modelId": "Model ID", "apiKey": "API Key", "apiKeyPlaceholder": "Your API key", "baseUrl": "Base URL (optional)", "customEndpoint": "Custom endpoint URL", "overrides": "Overrides", "clearSettings": "Clear Settings", "useServerDefault": "Use Server Default", "language": "Language", "languageDescription": "Choose your interface language.", "theme": "Theme", "themeDescription": "Dark/Light mode for interface and DrawIO canvas.", "drawioStyle": "DrawIO Style", "drawioStyleDescription": "Canvas style", "themeDefault": "Default", "themeDark": "Dark", "themeMinimal": "Minimal", "themeSketch": "Sketch", "themeSimple": "Simple", "diagramStyle": "Diagram Style", "diagramStyleDescription": "Toggle between minimal and styled diagram output.", "sendShortcut": "Send Shortcut", "sendShortcutDescription": "Choose how to send messages.", "enterToSend": "Enter to send", "ctrlEnterToSend": "Cmd/Ctrl+Enter to send", "diagramActions": "Diagram Actions", "diagramActionsDescription": "Manage diagram history and exports", "history": "History", "download": "Download", "proxy": "Proxy Settings", "proxyDescription": "Configure HTTP/HTTPS proxy for API requests (Desktop only)", "httpProxy": "HTTP Proxy", "httpsProxy": "HTTPS Proxy", "applyProxy": "Apply", "proxyApplied": "Proxy settings applied", "diagramValidation": "Diagram Validation (Experimental)", "diagramValidationDescription": "Use a vision language model to validate generated diagrams. Requires a VLM like GPT-5.2 or Sonnet-4.5.", "enabled": "Enabled", "disabled": "Disabled", "customSystemMessage": "Custom System Message", "customSystemMessageDescription": "Add custom instructions appended to the AI's system prompt.", "customSystemMessagePlaceholder": "e.g., Always use blue color scheme for diagrams...", "panelVisibility": "Lobby Panels", "panelVisibilityDescription": "Choose which panels to show on the chat lobby.", "showRecentChats": "Recent Chats", "showMyTemplates": "My Templates", "showQuickExamples": "Quick Examples" }, "save": { "title": "Save Diagram", "description": "Choose a format and filename to save your diagram.", "format": "Format", "filename": "Filename", "filenamePlaceholder": "Enter filename", "formats": { "drawio": "Draw.io XML", "png": "PNG Image", "svg": "SVG Image", "xmlsvg": "Editable SVG" }, "savedSuccessfully": "Saved successfully!" }, "history": { "title": "Diagram History", "description": "Here saved each diagram before AI modification.\nClick on a diagram to restore it", "noHistory": "No history available yet. Send messages to create diagram history.", "version": "Version", "restoreTo": "Restore to Version {version}?" }, "dialogs": { "clearTitle": "Clear Everything?", "clearDescription": "This will clear the current conversation and reset the diagram. This action cannot be undone.", "clearEverything": "Clear Everything", "clearSuccess": "Started a fresh chat" }, "errors": { "maxFiles": "Too many files. Maximum {max} allowed.", "onlyMoreAllowed": "Only {slots} more file(s) allowed", "fileExceeds": "\"{name}\" is {size} (exceeds {max}MB)", "unsupportedType": "\"{name}\" is not a supported file type", "filesRejected": "{count} files rejected:", "andMore": "...and {count} more", "invalidAccessCode": "Invalid or missing access code. Please configure it in Settings.", "networkError": "Network error. Please check your connection.", "retryLimit": "Auto-retry limit reached ({max}). Please try again manually.", "continuationRetryLimit": "Continuation retry limit reached ({max}). The diagram may be too complex.", "validationFailed": "Diagram validation failed. Please try regenerating.", "malformedXml": "AI generated invalid diagram XML. Please try regenerating.", "failedToProcess": "Failed to process diagram. Please try regenerating.", "sessionCorrupted": "Session data was corrupted. Starting fresh.", "failedToSave": "Failed to save messages to localStorage", "failedToRestore": "Failed to restore from localStorage", "failedToPersist": "Failed to persist state before unload", "failedToExport": "Error fetching chart data", "failedToLoadExample": "Error loading example image", "failedToRecordFeedback": "Failed to record your feedback. Please try again.", "storageUpdateFailed": "Chat cleared but browser storage could not be updated" }, "quota": { "dailyLimit": "Daily Quota Reached", "tokenLimit": "Daily Token Limit Reached", "tpmLimit": "Rate Limit", "tpmMessage": "Too many requests. Please wait a moment.", "tpmMessageDetailed": "Rate limit reached ({limit} tokens/min). Please wait {seconds} seconds before sending another request.", "messageApi": "Looks like you've reached today's demo limit. We're thrilled you're enjoying it, and while ByteDance Doubao generously sponsors this demo, we've had to set a few boundaries to keep things fair for everyone.", "messageApiSelfHosted": null, "messageToken": "Looks like you've reached today's token limit. We're thrilled you're enjoying it, and while ByteDance Doubao generously sponsors this demo, we've had to set a few boundaries to keep things fair for everyone.", "messageTokenSelfHosted": null, "tip": "Tip: You can use your own API key (click the Settings icon) or self-host the project to bypass these limits.", "tipSelfHosted": "Tip: You can configure your own API key in the settings to continue using the service.", "reset": "Your limit resets tomorrow. Thanks for understanding.", "doubaoSponsorship": "Register here to get 500K free tokens per model (including Doubao, DeepSeek and Kimi), then configure your API key in model settings.", "configModel": "Use Your API Key", "selfHost": "Self-host", "sponsor": "Sponsor", "learnMore": "Learn more →", "usedOf": "{used}/{limit}" }, "tools": { "generateDiagram": "Generate Diagram", "editDiagram": "Edit Diagram", "appendDiagram": "Continue Diagram", "complete": "Complete", "error": "Error", "truncated": "Truncated" }, "file": { "reading": "Reading...", "chars": "chars", "removeFile": "Remove file" }, "url": { "title": "Extract Content from URL", "description": "Paste a URL to extract and analyze its content", "Extracting": "Extracting...", "extract": "Extract", "Cancel": "Cancel", "enterUrl": "Please enter a URL", "invalidFormat": "Invalid URL format" }, "reasoning": { "thinking": "Thinking...", "thoughtFor": "Thought for {duration} seconds", "thoughtBrief": "Thought for a few seconds" }, "dev": { "title": "Dev: XML Streaming Simulator", "preset": "Preset:", "selectPreset": "Select a preset...", "clear": "Clear", "placeholder": "Paste mxCell XML here or select a preset...", "interval": "Interval:", "chars": "Chars:", "streaming": "Streaming...", "simulate": "Simulate", "stop": "Stop", "testQuotaToast": "Test Quota Toast", "simulatingMessage": "[Dev] Simulating XML streaming", "successMessage": "Successfully displayed the diagram." }, "about": { "modelChange": "Model Change & Usage Limits", "walletCrying": "(Or: Why My Wallet is Crying)", "seekingSponsorship": "Call for Sponsorship", "contactMe": "Contact Me", "usageNotice": "Due to high usage, I have changed the model from Claude to minimax-m2 and added some usage limits. See About page for details." }, "sessionHistory": { "tooltip": "Chat History", "newChat": "New Chat", "empty": "No chat history yet", "emptyHint": "Start a conversation to begin", "today": "Today", "yesterday": "Yesterday", "thisWeek": "This Week", "earlier": "Earlier", "deleteTitle": "Delete this chat?", "deleteDescription": "This will permanently delete this chat session and its diagram. This action cannot be undone.", "recentChats": "Recent Chats", "justNow": "Just now", "searchPlaceholder": "Search chats...", "noResults": "No chats found" }, "templates": { "title": "My Templates", "subtitle": "Your personal prompt library for quick diagram creation", "emptyTitle": "No templates yet", "emptyDescription": "Create your first template to start building your personal prompt library", "createFirst": "Create First Template", "neverUsed": "Not used yet", "usedCount": "{count} uses", "myTemplates": "My Templates", "createTitle": "Create Template", "createDescription": "Save a prompt for repeated use. Templates help you quickly start common workflows.", "promptLabel": "Prompt", "promptPlaceholder": "Describe the diagram you want to create...", "promptRequired": "Prompt is required", "titleLabel": "Title", "titlePlaceholder": "Enter a title", "titleHint": "Leave empty to use the first 20 characters of prompt", "descriptionLabel": "Description", "descriptionPlaceholder": "Add a description for this template", "pinnedLabel": "Pin Template", "pinnedHint": "Pinned templates appear at the top of the list", "createButton": "Create Template", "createFailed": "Failed to create template. Please try again.", "editTitle": "Edit Template", "editDescription": "Update your template content and settings.", "updateFailed": "Failed to update template. Please try again.", "duplicate": "Duplicate", "copySuffix": "(copy)", "deleteTitle": "Delete this template?", "deleteDescription": "This will permanently delete this template. This action cannot be undone.", "confirmSendTitle": "Replace current input?", "confirmSendDescription": "You have unsent content in the input. Sending this template will replace it.", "confirmSendButton": "Send Template", "searchPlaceholder": "Search templates...", "searchNoResults": "No templates match your search", "pin": "Pin to top", "unpin": "Unpin from top", "saveAsTemplate": "Save as Template", "exportTemplates": "Export Templates", "importTemplates": "Import Templates", "exportEmpty": "No templates to export", "exportSuccess": "Exported {count} template(s) successfully", "importNoFile": "Please select a JSON file", "importFailed": "Import failed: {error}", "importSuccess": "Imported {imported} template(s), skipped {skipped} duplicate(s)" }, "validation": { "title": "Validate Diagram", "capturing": "Capturing", "validating": "Validating", "validatingWithAttempt": "Validating ({attempt}/{max})", "valid": "Valid", "validWithWarnings": "Valid with Warnings", "issuesFound": "Issues Found", "error": "Error", "skipped": "Skipped", "capturedScreenshot": "Captured Screenshot:", "issuesFoundLabel": "Issues Found:", "suggestions": "Suggestions:", "passedValidation": "Diagram passed visual validation - no issues detected.", "improvementRequested": "Improvement requested - check the new diagram below", "improveWithSuggestions": "Improve with Suggestions", "regenerateWithFeedback": "Regenerate the diagram using the validation feedback" }, "modelConfig": { "title": "AI Model Configuration", "description": "Configure multiple AI providers and models", "configure": "Configure", "addProvider": "Add Provider", "addModel": "Add Model", "modelId": "Model ID", "modelLabel": "Display Label", "streaming": "Enable Streaming", "deleteProvider": "Delete Provider", "deleteModel": "Delete Model", "noModels": "No models configured. Add a model to get started.", "selectProvider": "Select a provider or add a new one", "configureMultiple": "Configure multiple AI providers and switch between them easily", "apiKeyStored": "API keys are stored locally in your browser", "test": "Test", "validationError": "Validation failed", "addModelFirst": "Add at least one model to validate", "providers": "Providers", "addProviderHint": "Add a provider to get started", "verified": "Verified", "configuration": "Configuration", "displayName": "Display Name", "awsAccessKeyId": "AWS Access Key ID", "awsSecretAccessKey": "AWS Secret Access Key", "awsRegion": "AWS Region", "selectRegion": "Select region", "apiKey": "API Key", "enterApiKey": "Enter your API key", "enterSecretKey": "Enter your secret access key", "baseUrl": "Base URL", "optional": "(optional)", "baseUrlWithExample": "Base URL (optional, e.g. {example})", "customEndpoint": "Custom endpoint URL", "minimaxBaseUrlHint": "Use /anthropic for Anthropic-compatible API (recommended), or /v1 for OpenAI-compatible API", "models": "Models", "customModelId": "Custom model ID...", "allAdded": "All added", "suggested": "Suggested", "noModelsConfigured": "No models configured", "modelIdEmpty": "Model ID cannot be empty", "modelIdExists": "This model ID already exists", "configureProviders": "Configure AI Providers", "selectProviderHint": "Select a provider from the list or add a new one to configure API keys and models", "deleteConfirmDesc": "Are you sure you want to delete {name}? This will remove all configured models and cannot be undone.", "typeToConfirm": "Type \"{name}\" to confirm", "typeProviderName": "Type provider name...", "modelsConfiguredCount": "{count} model(s) configured", "validationFailedCount": "{count} model(s) failed validation", "cancel": "Cancel", "delete": "Delete", "clickToChange": "(click to change)", "usingServerDefault": "Using server default model", "selectModel": "Select Model", "searchModels": "Search models...", "noVerifiedModels": "No verified models. Test your models first.", "noModelsFound": "No models found.", "default": "Default", "serverDefault": "Server Default", "serverModels": "Server Models", "userModels": "User Models", "configureModels": "Configure Models...", "onlyVerifiedShown": "Only verified models are shown", "showUnvalidatedModels": "Show unvalidated models", "allModelsShown": "All models are shown (including unvalidated)", "unvalidatedModelWarning": "This model has not been validated", "serverDefaultModel": "Server default model", "showValue": "Show value", "hideValue": "Hide value" }, "admin": { "title": "Admin Settings", "loginPrompt": "Enter the admin password (the ADMIN_PASSWORD environment variable) to manage server settings.", "password": "Password", "signIn": "Sign In", "signingIn": "Signing In…", "loginFailed": "Login failed", "precedence": "File overrides env · env overrides defaults", "notWritable": "The settings file is not writable on this deployment (serverless platforms have no persistent disk). Settings are shown read-only — configure via environment variables instead.", "settingGroups": "Setting groups", "enabled": "Enabled", "disabled": "Disabled", "enableGroup": "Enable {group}", "unsavedChanges": "Unsaved changes", "saved": "Settings saved. Changes apply immediately.", "saveFailed": "Save failed. Check your connection and try again.", "invalidSettings": "Some settings are invalid.", "discard": "Discard", "saveChanges": "Save Changes", "saving": "Saving…", "sourceSaved": "Saved", "sourceEnv": "Env", "sourceSavedTitle": "Set in the admin settings file", "sourceEnvTitle": "Set by an environment variable", "restartRequired": "Restart Required", "modified": "Modified", "notSet": "Not set", "savedReplace": "Saved ({hint}) — type to replace", "showValue": "Show value", "hideValue": "Hide value", "removeValue": "Remove value", "removeValueTitle": "Remove the stored value", "resetToDefault": "Reset to default", "models": "Models", "modelsDescription": "Server-side providers and models available to all users — no personal API key needed. The default provider's first model is used when users don't pick one.", "addProviderHint": "Add a provider to offer server-side models to all users.", "selectProviderHint": "Select or add a provider to configure its credentials and models.", "addProviderToOfferModels": "Add at least one model to expose this provider to users.", "managedViaEnv": "(managed via env)", "envReadOnly": "Defined in AI_MODELS_CONFIG / ai-models.json — read-only here. Edit the environment configuration to change it.", "defaultModel": "Default Model", "noModelsConfigured": "No models configured", "modelCount": "{count} model", "modelCountPlural": "{count} models", "default": "Default", "setAsDefault": "Set as default provider", "defaultProvider": "Default provider", "modelIdPlaceholder": "Model ID…", "addModel": "Add model", "suggested": "Suggested", "test": "Test", "testOk": "OK ({ms}ms)", "testFailed": "Failed", "removeModel": "Remove {model}", "deleteProviderTitle": "Delete {name}?", "deleteProviderDesc": "Its credentials and models will be removed from the server after you save.", "cancel": "Cancel", "delete": "Delete", "groups": { "generation": { "title": "Generation", "description": "Output parameters applied to all chat requests." }, "access": { "title": "Access Control", "description": "Restrict who can use this deployment." }, "features": { "title": "Features", "description": "Optional features and security toggles." }, "observability": { "title": "Observability", "description": "Langfuse tracing for LLM calls." }, "quota": { "title": "Quota & Rate Limits", "description": "Per-IP usage limits. Enforcement requires a DynamoDB table." } }, "settings": { "TEMPERATURE": { "label": "Temperature", "description": "Leave unset for reasoning models that reject temperature." }, "MAX_OUTPUT_TOKENS": { "label": "Max Output Tokens" }, "ACCESS_CODE_LIST": { "label": "Access Codes", "description": "Comma-separated list. Users must enter one to chat. Empty = open access." }, "ENABLE_VLM_VALIDATION": { "label": "VLM Diagram Validation", "description": "Visually validate generated diagrams with a vision model." }, "VALIDATION_MODEL": { "label": "Validation Model", "description": "Falls back to the default AI model when empty." }, "VALIDATION_TIMEOUT": { "label": "Validation Timeout (ms)" }, "ENABLE_HISTORY_XML_REPLACE": { "label": "History XML Compression", "description": "Replace old diagram XML in history with placeholders." }, "ALLOW_PRIVATE_URLS": { "label": "Allow Private URLs", "description": "Turn off to block requests to private IPs and internal hostnames (SSRF protection)." }, "LANGFUSE_PUBLIC_KEY": { "label": "Langfuse Public Key" }, "LANGFUSE_SECRET_KEY": { "label": "Langfuse Secret Key" }, "LANGFUSE_BASEURL": { "label": "Langfuse Base URL" }, "DAILY_REQUEST_LIMIT": { "label": "Daily Request Limit", "description": "Per IP per day." }, "DAILY_TOKEN_LIMIT": { "label": "Daily Token Limit", "description": "Per IP per day." }, "TPM_LIMIT": { "label": "Tokens Per Minute" }, "DYNAMODB_QUOTA_TABLE": { "label": "DynamoDB Table", "description": "Quota enforcement is disabled when empty." }, "DYNAMODB_REGION": { "label": "DynamoDB Region" }, "QUOTA_TIMEZONE": { "label": "Quota Timezone", "description": "Timezone for the daily reset boundary." } } } }