mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-07 01:54:24 +08:00
feat(i18n): implement internationalization framework and update UI components for language support
This commit is contained in:
@@ -0,0 +1,589 @@
|
||||
export default {
|
||||
meta: {
|
||||
title: "Infinite Canvas",
|
||||
description: "An infinite canvas creation tool",
|
||||
},
|
||||
theme: { toggle: "Toggle theme" },
|
||||
common: {
|
||||
cancel: "Cancel",
|
||||
save: "Save",
|
||||
edit: "Edit",
|
||||
done: "Done",
|
||||
delete: "Delete",
|
||||
copy: "Copy",
|
||||
copied: "Copied",
|
||||
details: "Details",
|
||||
addToAssets: "Add to My Assets",
|
||||
addedToAssets: "Added to My Assets",
|
||||
copyPrompt: "Copy prompt",
|
||||
promptCopied: "Prompt copied",
|
||||
created: "Created: {{date}}",
|
||||
updated: "Updated: {{date}}",
|
||||
all: "All",
|
||||
view: "View",
|
||||
download: "Download",
|
||||
upload: "Upload",
|
||||
requestCanceled: "Request canceled",
|
||||
durationMinutes: "{{minutes}}m {{seconds}}s",
|
||||
durationSeconds: "{{seconds}}s",
|
||||
imageReadFailed: "Failed to read image",
|
||||
},
|
||||
settingsPanels: {
|
||||
common: { auto: "Auto", low: "Low", medium: "Medium", high: "High", xhigh: "Extra high" },
|
||||
image: { title: "Image settings", quality: "Quality", size: "Size", align16: "Align to multiples of 16", align16Hint: "Round dimensions up to the next multiple of 16 after input", aspectRatio: "Aspect ratio", transparent: "Transparent background", transparentHint: "Generate an image without a background when supported by the model", count: "Image count", images: "{{count}} images" },
|
||||
video: { title: "Video settings", quality: "Quality", size: "Size", seconds: "Seconds", resolution: "Resolution", ratio: "Aspect ratio", duration: "Duration", smart: "Smart", output: "Output", generateAudio: "Generate audio", watermark: "Add watermark", adaptive: "Adaptive", sizes: { landscape: "Landscape", portrait: "Portrait", square: "Square", widescreen: "Widescreen", tall: "Tall", auto: "Auto" }, ratios: { landscape: "Landscape", portrait: "Portrait", square: "Square", standardLandscape: "Standard landscape", standardPortrait: "Standard portrait", cinematic: "Cinematic", adaptive: "Adaptive" } },
|
||||
audio: { title: "Audio settings", voice: "Voice", format: "Format", speed: "Speed", instructions: "Voice instructions", instructionsPlaceholder: "For example: natural, warm, and suitable for narration." },
|
||||
text: { title: "Text settings", reasoning: "Reasoning effort" },
|
||||
model: { select: "Select model", assign: "Assign a model for {{capability}} in the provider settings", noMatch: "No matching {{capability}} models", addFirst: "Add a provider and models in Settings first", capabilities: { image: "image generation", video: "video", text: "text", audio: "audio" } },
|
||||
},
|
||||
generation: { pending: ["Creating image", "Almost there", "Just a little longer", "Refining details"] },
|
||||
imageReferences: { label: "Image {{index}}", separator: ", ", promptPrefix: "Reference image labels: {{labels}}. Use these labels to interpret image references in the prompt.\n\n{{prompt}}" },
|
||||
seedance: { autoMatch: "Automatic", separator: ", ", references: { image: "Image {{index}}", video: "Video {{index}}", audio: "Audio {{index}}" }, promptPrefix: "Reference asset labels: {{labels}}. Use these labels to interpret image, video, and audio references in the prompt.\n\n{{prompt}}", referenceHint: "Reference videos must be mp4/mov, H.264/H.265, and 24–60 FPS. Use authorized Volcengine asset:// assets when real faces are included.", errors: { format: "{{label}} supports mp4/mov only", size: "{{label}} exceeds 200 MB. Compress it before uploading.", duration: "{{label}} must be 2–15 seconds", dimensions: "{{label}} dimensions must be between 300 and 6000px", ratio: "{{label}} aspect ratio must be between 0.4 and 2.5", pixels: "{{label}} total pixel count must be between 409600 and 8295044", totalDuration: "Seedance reference videos cannot exceed 15 seconds in total" } },
|
||||
modelPlugin: {
|
||||
pollTimeout: "Plugin polling timed out. Check the request script or try again later.", executionFailed: "Model request script failed: {{message}}", noImages: "The model request script did not return any images",
|
||||
variables: { prompt: "User prompt with the system prompt already included", images: "Reference images as a data URL array, available for image editing and image-to-video", messages: "Conversation message array including the system message", params: "Generation parameters: image {size,quality,count}, video {seconds,size,resolution,ratio,generateAudio,watermark}, audio {voice,format,speed,instructions}", model: "Model name without the provider prefix", baseUrl: "Provider endpoint as entered, without appending /v1", apiKey: "Provider API key; add it to request headers yourself", systemPrompt: "Original system prompt", reasoningEffort: "Text reasoning effort; auto lets the script decide whether to send it", http: "Convenience client: http.post(path, body, {headers,params,responseType}), http.get(path, opts), and http.url(path). Authorization: Bearer apiKey is included by default and can be overridden. Relative paths append /v1 to baseUrl.", request: "Raw request({ method, url, headers, params, data, responseType }) with no default headers. Add authentication yourself. Relative URLs are joined to baseUrl without /v1.", poll: "poll(request, extract, {intervalMs,timeoutMs}) continues until extract returns a truthy value", sleep: "Delay with sleep(ms)", signal: "Cancellation signal that can be passed to http/request", onDelta: "Push streaming text with onDelta(text) for text models" },
|
||||
returns: { image: "Text-to-image and image editing use different APIs; distinguish them by whether images is empty. Return an image URL or data URL, an array of them, or [{ dataUrl }] / [{ url }] / [{ b64_json }].", video: "Poll inside the script and return { url }, { blob }, or a video URL string.", audio: "Return a Blob, base64/data URL string, or { b64_json } / { data } / { url }.", text: "Push streaming output with onDelta(text), then return the complete text string." },
|
||||
templates: { openai: "OpenAI format", gemini: "Gemini format", imageOpenai: "Image generation and editing use different endpoints; distinguish them by whether images is empty.", availableImage: "Available: prompt, images(dataURL[]), params{size,quality,count}, model, baseUrl, apiKey", textToImage: "Text to image: /images/generations (JSON)", imageToImage: "Image editing: /images/edits (multipart/form-data with reference images uploaded as files)", formDataHeader: "Do not set Content-Type manually; let the browser add the boundary", imageGemini: "Gemini image generation and editing both use generateContent, with references in parts.inline_data.", availableImageGemini: "Available: prompt, images(dataURL[]), model, baseUrl, apiKey", videoOpenai: "Video with polling handled inside the script. Available: prompt, images(dataURL[]), params{seconds,size,resolution,ratio}", videoGemini: "Gemini (Veo) video: submit with predictLongRunning and poll the operation for the video URI.", availableVideoGemini: "Available: prompt, images(dataURL[]), params, model, baseUrl, apiKey", geminiNoVideoUri: "Gemini did not return a video URI", audioOpenai: "Audio TTS. Available: prompt, params{voice,format,speed,instructions}, model", audioGemini: "Gemini TTS: generateContent with AUDIO modality, returning base64 PCM in inlineData.data.", availableAudioGemini: "Available: prompt, params{voice}, model, baseUrl, apiKey", geminiNoAudio: "Gemini did not return audio", textOpenai: "Text chat using the OpenAI Responses API. Available: messages([{role,content}]), systemPrompt, model, reasoningEffort", textGemini: "Gemini text: generateContent with the system message in systemInstruction.", availableTextGemini: "Available: messages([{role,content}]), systemPrompt, model, baseUrl, apiKey" },
|
||||
},
|
||||
apiErrors: { requestFailed: "Request failed", requestCanceled: "Request canceled", baseUrlRequired: "Configure the Base URL first", apiKeyRequired: "Configure the API key first", authenticationFailed: "Authentication failed. Check the API key, plan permissions, and model permissions.", rateLimited: "The request was rate-limited or the quota is insufficient. Try again later.", notFound: "The endpoint was not found (404). Check the Base URL and selected model.", badGateway: "Gateway error (502). The API service is temporarily unavailable.", serviceBusy: "Service unavailable (503). Try again later.", httpFailed: "Request failed (HTTP {{status}}). Check the Base URL and API key.", htmlError: "The service returned an HTML error page ({{preview}})", audioModelRequired: "Configure an audio model first", audioGenerationFailed: "Audio generation failed", scriptNoAudio: "The model request script did not return audio", geminiAudioUnsupported: "The Gemini API format does not support audio generation. Use an OpenAI-format provider.", invalidImageSizeFormat: "Unsupported image size. Use auto, 9:16, or 1024x1024.", positiveImageRatio: "The image ratio must use positive numbers, such as 9:16.", imageRatioLimit: "The image aspect ratio cannot exceed 3:1. Adjust the dimensions.", positiveImageDimensions: "Image dimensions must be positive integers, such as 1024x1024.", imageDimensionStep: "Image width and height must be multiples of 16.", imageEdgeLimit: "The longest image edge cannot exceed 3840px.", imagePixelLimit: "The total image pixel count must be between 655360 and 8294400.", unknownImageResponse: "The API returned data in an unknown format (fields: {{fields}}). Check model or API compatibility.", noImageReturned: "The API did not return an image. The prompt may have triggered safety review or the model may not support this operation.", geminiRejected: "Gemini rejected the request: {{reason}}", geminiNoImage: "The Gemini API did not return an image", geminiMaskUnsupported: "The Gemini API format does not support mask editing", maskModelUnsupported: "This model does not support mask editing. Use another provider.", noContent: "No content returned", modelReadFailed: "Failed to load models", videoTimeout: "{{provider}}video generation timed out. Try again later.", videoReferencesUnsupported: "This video API does not support reference video or audio. Switch to Seedance 2.0 / Volcengine Agent Plan, or remove the reference assets.", pluginVideoExpired: "The plugin video task has expired. Generate it again.", scriptNoVideo: "The model request script did not return a video", noPlayableVideo: "The video API did not return a playable video", noVideoTaskId: "The video API did not return a task ID", videoTaskCreateFailed: "Failed to create video task", videoGenerationFailed: "Video generation failed", videoTaskQueryFailed: "Failed to query video task", seedanceAudioRequiresVisual: "Seedance reference audio cannot be used alone. Add a reference image or video.", videoPromptRequired: "Enter a video prompt or connect a reference image, video, or audio asset", seedanceNoTaskId: "The Seedance API did not return a task ID", seedanceTaskCreateFailed: "Failed to create Seedance task", seedanceNoVideoUrl: "The Seedance task succeeded but did not return a video URL", seedanceVideoTimeout: "Seedance video generation timed out", seedanceVideoFailed: "Seedance video generation failed", seedanceTaskQueryFailed: "Failed to query Seedance task", seedanceVideoDuration: "Each Seedance reference video must be 2–15 seconds", seedanceVideoTotalDuration: "Seedance reference videos cannot exceed 15 seconds in total", seedanceAudioDuration: "Each Seedance reference audio file must be 2–15 seconds", seedanceAudioTotalDuration: "Seedance reference audio cannot exceed 15 seconds in total", referenceImageReadFailed: "Failed to read the reference image. Choose another image or upload it again.", invalidReferenceVideo: "A reference video must be a public URL, asset ID, or locally saved video", invalidReferenceAudio: "Reference audio must be a public URL, asset ID, or locally saved audio file", videoModelRequired: "Configure a video model first", geminiVideoUnsupported: "The Gemini API format does not support video generation. Use an OpenAI-format provider.", noVideoTask: "The API did not return a video task", seedanceNoTask: "The Seedance API did not return a task", videoDownloadFailed: "Failed to download video", localAssetReadFailed: "Failed to read local asset" },
|
||||
prompts: {
|
||||
title: "Prompt Center",
|
||||
library: "Prompt Library",
|
||||
total: "{{count}} prompts",
|
||||
category: "Category",
|
||||
tags: "Tags",
|
||||
search: "Search titles, content, or tags",
|
||||
searchTitle: "Search by title",
|
||||
loadFailed: "Failed to load prompts",
|
||||
sourceMissing: "Prompt source not found",
|
||||
use: "Use this prompt",
|
||||
empty: "No matching prompts found",
|
||||
loading: "Loading...",
|
||||
loadMore: "Scroll down to load more",
|
||||
end: "You've reached the end",
|
||||
},
|
||||
assets: {
|
||||
title: "My Assets",
|
||||
description: "Save frequently used text and images, then find them quickly by type, title, or tag.",
|
||||
search: "Search titles, content, tags, or sources",
|
||||
type: "Type",
|
||||
export: "Export assets",
|
||||
import: "Import assets",
|
||||
add: "Add asset",
|
||||
edit: "Edit asset",
|
||||
empty: "No assets found",
|
||||
manual: "Added manually",
|
||||
selectImage: "Select an image file",
|
||||
updated: "Asset updated",
|
||||
saved: "Asset saved",
|
||||
textCopied: "Text copied",
|
||||
noneToExport: "No assets to export",
|
||||
imported: "Imported {{count}} assets",
|
||||
importFailed: "Import failed. Select a valid asset package.",
|
||||
deleted: "Asset deleted",
|
||||
packageName: "my-assets.zip",
|
||||
kinds: { text: "Text", image: "Image", video: "Video" },
|
||||
fields: {
|
||||
title: "Title",
|
||||
titleRequired: "Enter a title",
|
||||
titlePlaceholder: "Give the asset an easy-to-find name",
|
||||
coverUrl: "Cover URL",
|
||||
coverPlaceholder: "Paste an image URL or upload a local cover",
|
||||
tags: "Tags",
|
||||
tagsPlaceholder: "Type a tag and press Enter",
|
||||
source: "Source",
|
||||
sourcePlaceholder: "Added manually / Canvas / Prompt Library",
|
||||
note: "Note",
|
||||
optional: "Optional",
|
||||
textContent: "Text content",
|
||||
textRequired: "Enter text content",
|
||||
textPlaceholder: "Save prompts, copy, reference descriptions, and other text assets",
|
||||
imageContent: "Image content",
|
||||
},
|
||||
selectImageFile: "Select image file",
|
||||
noImageSelected: "No image selected",
|
||||
preview: "Preview",
|
||||
noCover: "No cover",
|
||||
untitled: "Untitled asset",
|
||||
noTags: "No tags",
|
||||
untagged: "Untagged",
|
||||
unknownSource: "Source not specified",
|
||||
details: "Asset details",
|
||||
deleteTitle: "Delete asset",
|
||||
deleteConfirm: "Delete “{{name}}”? It will be removed from My Assets.",
|
||||
copyText: "Copy text",
|
||||
downloadImage: "Download image",
|
||||
downloadVideo: "Download video",
|
||||
},
|
||||
notFound: {
|
||||
title: "Page not found",
|
||||
description: "There is no page at this address. It may have moved or been merged into another section.",
|
||||
home: "Back to home",
|
||||
},
|
||||
workbench: {
|
||||
logs: "Generation history",
|
||||
settings: "Settings",
|
||||
prompt: "Prompt",
|
||||
viewPrompts: "Browse prompts",
|
||||
viewAssets: "Browse My Assets",
|
||||
clipboard: "Clipboard",
|
||||
upload: "Upload",
|
||||
adjust: "Adjust",
|
||||
generate: "Generate",
|
||||
results: "Results",
|
||||
waiting: "Waiting {{time}}",
|
||||
model: "Model",
|
||||
generating: "Generating",
|
||||
success: "Succeeded",
|
||||
failed: "Generation failed",
|
||||
retry: "Retry",
|
||||
new: "New",
|
||||
selectAll: "Select all",
|
||||
noLogs: "No generation history",
|
||||
deleteLogs: "Delete generation history",
|
||||
deleteLogsConfirm: "Delete the selected {{count}} generation records?",
|
||||
successCount: "{{count}} succeeded",
|
||||
failCount: "{{count}} failed",
|
||||
itemCount: "{{count}} images",
|
||||
untitled: "Untitled",
|
||||
configFirst: "Complete the configuration first",
|
||||
generationFailed: "Generation failed",
|
||||
retrySuccess: "Retry succeeded",
|
||||
},
|
||||
imageWorkbench: {
|
||||
title: "Image Studio",
|
||||
promptPlaceholder: "Describe the subject, style, composition, lighting, and intended use",
|
||||
references: "Reference images",
|
||||
removeReference: "Remove reference image",
|
||||
dropReferences: "Drop to add reference images",
|
||||
noReferences: "No reference images. Drag images here to add them.",
|
||||
clipboardEmpty: "No readable images found on the clipboard",
|
||||
clipboardAdded: "Added {{count}} reference images",
|
||||
promptRequired: "Enter an image prompt",
|
||||
configIncomplete: "Image generation configuration is incomplete",
|
||||
invalidParams: "Invalid image generation parameters",
|
||||
busy: "The Image Studio is already running a task",
|
||||
generated: "Images generated",
|
||||
addedReference: "Added to reference images",
|
||||
resultTitle: "Generated image {{count}}",
|
||||
source: "Image Studio",
|
||||
unsupportedAsset: "Image Studio only supports text and image assets",
|
||||
missingResult: "The API returned no image",
|
||||
empty: "No images generated yet",
|
||||
resultAlt: "Generated image {{count}}",
|
||||
addReference: "Add as reference",
|
||||
},
|
||||
videoWorkbench: {
|
||||
title: "Video Studio",
|
||||
promptPlaceholder: "Describe camera movement, subject action, atmosphere, and visual style",
|
||||
references: "Reference images",
|
||||
videoReferences: "Reference videos",
|
||||
audioReferences: "Reference audio",
|
||||
removeImage: "Remove reference image",
|
||||
removeVideo: "Remove reference video",
|
||||
removeAudio: "Remove reference audio",
|
||||
dropReferences: "Drop to upload reference assets",
|
||||
noImages: "No reference images. Drag in up to 9 files.",
|
||||
noVideos: "No reference videos. Drag in up to 3 files.",
|
||||
noAudio: "No reference audio. Drag in up to 3 MP3/WAV files, each under 15 MB.",
|
||||
unsupportedFiles: "Unsupported reference assets were ignored. Use images, MP4/MOV video, or MP3/WAV audio.",
|
||||
imageTooLarge: "Reference images over 30 MB were ignored",
|
||||
videoTooLarge: "Reference videos over 200 MB were ignored",
|
||||
audioTooLarge: "Reference audio over 15 MB was ignored",
|
||||
audioDurationInvalid: "Reference audio outside the duration limits was ignored: 2–15 seconds each, 15 seconds total.",
|
||||
clipboardEmpty: "No readable images found on the clipboard",
|
||||
clipboardAdded: "Added {{count}} reference images",
|
||||
promptRequired: "Enter a video prompt",
|
||||
referenceError: "{{error}}. {{hint}}",
|
||||
invalidParams: "Invalid video generation parameters",
|
||||
busy: "The Video Studio is already running a task",
|
||||
generated: "Video generated",
|
||||
timeout: "Video generation timed out. Try again later.",
|
||||
resultTitle: "Generated video",
|
||||
source: "Video Studio",
|
||||
empty: "No video generated yet",
|
||||
},
|
||||
canvas: {
|
||||
defaultTitle: "Infinite Canvas {{count}}",
|
||||
library: "Canvas library",
|
||||
title: "Infinite Canvas",
|
||||
imported: "Imported {{count}} canvases",
|
||||
importFailed: "Import failed. Select a valid canvas package.",
|
||||
opening: "Opening canvas...",
|
||||
loading: "Loading canvases...",
|
||||
exportSelected: "Export selected",
|
||||
deleteSelected: "Delete selected",
|
||||
deleteAll: "Delete all",
|
||||
import: "Import canvas",
|
||||
create: "New canvas",
|
||||
empty: "No canvases yet",
|
||||
emptyDescription: "Create a canvas to save its nodes, connections, and appearance independently.",
|
||||
collapsePanel: "Collapse panel",
|
||||
expandPanel: "Expand panel",
|
||||
home: "Home",
|
||||
docs: "Documentation",
|
||||
projects: "My Canvases",
|
||||
deleteCurrent: "Delete current canvas",
|
||||
importAsset: "Import asset",
|
||||
exportCurrent: "Export current canvas",
|
||||
undo: "Undo",
|
||||
redo: "Redo",
|
||||
openMenu: "Open canvas menu",
|
||||
renameHint: "Double-click to rename the canvas",
|
||||
shortcuts: "Keyboard shortcuts",
|
||||
miniMapOpen: "Open minimap",
|
||||
miniMapClose: "Close minimap",
|
||||
resetView: "Reset view",
|
||||
zoom: "Zoom canvas",
|
||||
agentConnected: "Codex connected",
|
||||
agentConnecting: "Codex {{activity}}",
|
||||
agentDisconnected: "Codex disconnected",
|
||||
connecting: "Connecting",
|
||||
openAgent: "Open local Codex panel",
|
||||
nodeTypes: { image: "Image", text: "Text", config: "Generation config", video: "Video", audio: "Audio", group: "Group" },
|
||||
toolbar: {
|
||||
move: "Move/select", text: "Text", image: "Image", video: "Video", audio: "Audio", config: "Generation config", group: "Group", extensions: "Extension nodes", upload: "Upload assets", appearance: "Canvas appearance", clear: "Clear canvas",
|
||||
themeMode: "Theme", light: "Light", dark: "Dark", gridStyle: "Grid style", dots: "Dots", lines: "Lines", blank: "Blank", imageInfo: "Image info",
|
||||
},
|
||||
project: {
|
||||
untitled: "Untitled canvas", imported: "Imported canvas",
|
||||
select: "Select {{name}}", stats: "{{nodes}} nodes · {{connections}} connections", updated: "Updated {{date}}", saveName: "Save name", cancelRename: "Cancel rename", export: "Export", rename: "Rename", delete: "Delete",
|
||||
deleteTitle: "Delete canvases?", deleteDescription: "This will delete {{count}} canvases along with their nodes and connections.",
|
||||
},
|
||||
export: { defaultProjectName: "Infinite Canvas", defaultNodesName: "Canvas elements", item: "Element" },
|
||||
createMenu: {
|
||||
fromNode: "Generate from this node", close: "Close", text: "Generate text", textDescription: "Scripts, ad copy, and brand content", image: "Generate image", video: "Generate video", audio: "Audio reference", config: "Configuration node", configDescription: "Model, size, count, and input order", select: "Select a node",
|
||||
},
|
||||
node: {
|
||||
node: "Node",
|
||||
untitled: "Untitled node", renameHint: "Double-click to rename the node", group: "Group", nodeCount: "{{count}} nodes", generating: "Generating", failed: "Generation failed", retry: "Retry", missingPlugin: "Plugin missing", missingPluginDescription: "The plugin for node type “{{type}}” is not installed or enabled", generateImage: "Generate image from text", generate: "Generate", editText: "Double-click to edit text", emptyImage: "Empty image node", emptyVideo: "Empty video node", emptyAudio: "Empty audio node", audio: "Audio", batchExpanded: "Image group expanded", batchCollapsed: "Image group collapsed", setPrimary: "Set as primary",
|
||||
},
|
||||
sidePanel: {
|
||||
canvas: "Canvas", assets: "Assets", prompts: "Prompt Library", resize: "Resize left panel", elements: "Canvas elements", select: "Select", searchNodes: "Search nodes", focusNode: "Focus node", preview: "Large preview", noNodes: "No nodes on this canvas", clearAll: "Clear all", selected: "{{count}} selected", exporting: "Exporting selected elements…", exportName: "canvas-elements-{{count}}", exported: "Exported {{count}} elements", exportFailed: "Export failed. Try again.",
|
||||
addingAssets: "Adding assets…", addedAssets: "Added {{count}} assets", mediaOnly: "Only image and video files are supported", addFailed: "Failed to add assets. Try again.", searchAssets: "Search assets", add: "Add", noAssets: "No assets", inserted: "Insert into canvas", removeAssetTitle: "Remove this asset?", remove: "Remove", removeAsset: "Remove asset", assetRemoved: "Asset removed",
|
||||
searchPrompts: "Search prompts", noPrompts: "No prompts", promptCopied: "Prompt copied", copyFailed: "Copy failed", loadFailedRetry: "Load failed. Click to retry.", noMatchingPrompts: "No matching prompts", sourceEmpty: "No prompts from this source", viewDetails: "View details",
|
||||
filter: { image: "Image", video: "Video", text: "Text", audio: "Audio", config: "Configuration", group: "Group" },
|
||||
},
|
||||
assetPicker: { title: "Select assets", insert: "Insert", search: "Search assets", empty: "No assets" },
|
||||
imageTools: { copyPrompt: "Copy prompt", copyPromptTitle: "Copy the prompt used to generate this image", reversePrompt: "Reverse prompt", reversePromptTitle: "Create text and configuration nodes to infer the prompt", replace: "Replace image", locked: "Lock ratio", free: "Free ratio", lockTitle: "Switch to proportional scaling", freeTitle: "Switch to free resizing", mask: "Local edit", maskTitle: "Paint a mask and edit the selected area", crop: "Crop", cropTitle: "Crop into a new node", split: "Split", splitTitle: "Split the image by rows and columns", upscale: "Upscale", upscaleTitle: "Increase image resolution", superResolve: "Super resolution", superResolveTitle: "AI super resolution", angle: "Multi-angle", angleTitle: "Generate another angle", view: "View image", viewTitle: "View image details", more: "More", configure: "Configure quick tools", customize: "Customize toolbar", showLabels: "Show button labels", description: "Choose the quick tools shown in the image-node toolbar.", preview: "Node preview", imageNode: "Image node", quickTools: "Quick tools" },
|
||||
nodeToolbar: { noPrompt: "No prompt to copy", infoTitle: "View node information", info: "Info", removeTitle: "Remove node", retryTitle: "Generate again", saveAsset: "Save asset", downloadAudio: "Download audio", downloadVideo: "Download video", downloadImage: "Download image", editTextTitle: "Edit text", editText: "Edit text", decreaseFont: "Decrease font size", increaseFont: "Increase font size", zoomOut: "Smaller", zoomIn: "Larger", uploadImage: "Upload image", replaceVideo: "Replace video", uploadVideo: "Upload video", replaceAudio: "Replace audio", uploadAudio: "Upload audio", nodeInfo: "Node information", name: "Name", type: "Type", size: "Size", position: "Position", status: "Status", imageGroup: "Image group", imageSize: "Image size" },
|
||||
configNode: { title: "Generation config", image: "Image", text: "Text", video: "Video", audio: "Audio", prompt: "Prompt", references: "Reference images", videoReferences: "Reference videos", audioReferences: "Reference audio", items: "{{count}} items", images: "{{count}} images", compose: "Compose prompt", stop: "Stop", generate: "Generate" },
|
||||
projectPage: {
|
||||
stopTitle: "Stop generation?", stopDescription: "The current request will be interrupted. Completed results will be kept.", stop: "Stop", continue: "Continue generating", configConnection: "Configuration nodes cannot be connected to each other", notFound: "Current canvas not found", exporting: "Exporting current canvas…", exported: "Current canvas exported", clipboardText: "Clipboard text", clipboardImageAdded: "Added image from clipboard", clipboardTextAdded: "Added text from clipboard", noTextToSave: "No text to save", canvasText: "Canvas text", noVideoToSave: "No video to save", canvasVideo: "Canvas video", noImageToSave: "No image to save", canvasImage: "Canvas image", emptyReverse: "The image node is empty, so its prompt cannot be inferred", reverseTitle: "Reverse prompt", reverseConfigTitle: "Reverse prompt configuration", splitTitle: "{{name}} {{row}}-{{column}}", splitSuccess: "Split into {{count}} child nodes", maskResult: "Local edit result", maskFailed: "Local edit failed", generationFailed: "Generation failed", partialFailed: "Some images failed to generate", allFailed: "All images failed to generate", retryPromptMissing: "No prompt found for retry", referenceMissing: "The reference image is missing, so retry cannot continue", emptyTextImage: "The text node is empty, so an image cannot be generated", untitledCanvas: "Untitled canvas", superResolve: "AI super resolution", notImplemented: "Not implemented yet", imageDetails: "Image details", clearTitle: "Clear canvas?", clear: "Clear", clearDescription: "This will delete every node and connection on the current canvas.", reversePreset: "Infer a prompt suitable for AI image generation from the reference image.\n\nRequirements:\n1. Output only the prompt, with no explanation.\n2. Cover the subject, composition, style, lighting, color, materials, lens, and atmosphere.\n3. Write a complete prompt that can be used directly with an image model.", maskPrompt: "Only modify the transparent masked area and keep everything else unchanged. {{prompt}}", editTextPrompt: "Revise the text according to the instructions.\n\nOriginal:\n{{source}}\n\nInstructions:\n{{prompt}}"
|
||||
},
|
||||
reverseComposer: "Reference image: @[node:{{imageId}}]\nTask: @[node:{{textId}}]",
|
||||
editors: {
|
||||
reset: "Reset", zoomOut: "Zoom out", zoomIn: "Zoom in", loading: "Loading", unknown: "Unknown", cancel: "Cancel",
|
||||
angleTitle: "AI Multi-angle", angleDescription: "The left side previews direction only; the result is regenerated from the original image", horizontal: "Horizontal angle", pitch: "Pitch angle", distance: "Camera distance", lens: "Wide-angle lens", standard: "Standard", wide: "Wide", aiGenerate: "Generate with AI",
|
||||
upscaleTitle: "Upscale image", source: "Source", targetPixels: "Target pixels", maxReached: "The image is already 4K and does not need upscaling", targetReached: "The image already meets the target pixel count", algorithm: "Upscaling algorithm", outputSize: "Output size", upscale: "Generate upscaled image", high: "High-quality interpolation", highDescription: "Best for photos and detailed images", bilinear: "Bilinear", bilinearDescription: "Smooth and fast", nearest: "Nearest neighbor", nearestDescription: "Best for pixel art",
|
||||
cropTitle: "Crop image", adjustCrop: "Adjust crop box", cropHint: "Mouse wheel to zoom · middle button or Space + left drag to pan", cropSize: "Crop size {{size}}", ratio: "Ratio {{ratio}}", original: "Original {{width}} x {{height}}", confirmCrop: "Crop", free: "Free", fixed: "Fixed", originalMode: "Original",
|
||||
maskTitle: "Local mask edit", maskHint: "Mouse wheel to zoom · middle button or Space + left drag to pan · Alt + left/right drag to resize brush · Ctrl/Cmd+Z to undo · Ctrl/Cmd+Shift+Z to redo", brush: "Brush", erase: "Erase", undoMaskTitle: "Undo mask stroke (Ctrl/Cmd+Z)", undoMask: "Undo mask stroke", redoMaskTitle: "Redo mask stroke (Ctrl/Cmd+Shift+Z)", redoMask: "Redo mask stroke", brushSize: "Brush size", editInstructions: "Edit instructions", maskPlaceholder: "For example: change the selected area to metal while preserving the original lighting", maskPromptRequired: "Enter edit instructions", maskRequired: "Paint the area to edit first", aiEdit: "Edit with AI",
|
||||
splitTitle: "Split image", splitDescription: "Create {{count}} image nodes and arrange them in the original grid to the right of the canvas", splitHint: "Mouse wheel to zoom · middle button or Space + left drag to pan · Delete removes the selected line · Ctrl/Cmd+Z to undo · Ctrl/Cmd+Shift+Z to redo", undoSplitTitle: "Undo split adjustment (Ctrl/Cmd+Z)", undoSplit: "Undo split adjustment", redoSplitTitle: "Redo split adjustment (Ctrl/Cmd+Shift+Z)", redoSplit: "Redo split adjustment", rows: "Rows", columns: "Columns", horizontalLine: "Horizontal line", verticalLine: "Vertical line", deleteLine: "Delete line", resetLines: "Reset lines", pieceCount: "Pieces", pieces: "{{count}}", averageSize: "Average size", generateChildren: "Create child nodes",
|
||||
},
|
||||
plugins: { title: "Node plugins", installedPlugin: "Installed plugin {{name}}", installed: "Installed {{name}}", installFailed: "Installation failed: {{error}}", enabled: "Enabled", disabled: "Disabled", upgradeAvailable: "New version available — click to upgrade", updateFromSource: "Update from source", updated: "Updated", uninstallTitle: "Uninstall this plugin?", uninstall: "Uninstall", newVersion: "A new version is available", officialDescription: "Official plugins from this project's registry", refresh: "Refresh", loadFailed: "Failed to load: {{error}}", loadingOfficial: "Loading official plugins…", noOfficial: "No official plugins", install: "Install", urlPlaceholder: "Enter a plugin JavaScript URL, for example https://.../plugin.js", noThirdParty: "No third-party plugins installed", official: "Official", local: "Local", thirdParty: "Third-party", warning: "Plugin code runs directly on this page and can access local data, including your AI API key. Only install plugins from sources you trust.", aiConfigRequired: "AI configuration is not ready. Configure a model and API key in Settings first.", interactiveTitle: "Interaction mode is active. Click to switch to Move mode and drag the node.", movableTitle: "Move mode is active. Click to switch to Interaction mode and operate the node content.", move: "Move", interact: "Interact" },
|
||||
promptPanel: { video: "Describe the video you want to generate", audio: "Describe the audio you want to generate", image: "Describe the image you want to generate", text: "Describe the text you want to generate", editImage: "Describe how you want to change this image", editText: "Describe how you want to revise this text", stopGeneration: "Stop generation", generate: "Generate", stop: "Stop" },
|
||||
composer: { title: "Compose prompt", description: "Use @ to reference connected assets; references are renumbered before sending", placeholder: "Enter a prompt and use @ to reference connected images or text", imagePreview: "Referenced image preview", resources: { image: "Image {{index}}", video: "Video {{index}}", audio: "Audio {{index}}", text: "Text {{index}}" } },
|
||||
controls: { ratio: "Ratio", duplicate: "Duplicate", delete: "Delete", images: "{{count}} images", reasoning: "Reasoning" },
|
||||
generation: { interrupted: "Generation was interrupted by a page refresh. Generate again.", front: "front view", rotateRight: "rotated {{angle}} degrees right", rotateLeft: "rotated {{angle}} degrees left", level: "eye-level view", topDown: "{{angle}}-degree top-down view", lowAngle: "{{angle}}-degree low-angle view", angleLabel: "AI multi-angle: {{horizontal}}, {{pitch}}, camera distance {{distance}}, {{lens}} lens", anglePrompt: "Regenerate a new view of the same subject from the reference image. Preserve the subject, colors, materials, and visual style; do not merely apply perspective distortion. {{angle}}." },
|
||||
agentOps: { add_node: "Add node", update_node: "Update node", delete_node: "Delete node", delete_connections: "Delete connections", connect_nodes: "Connect", set_viewport: "Adjust view", select_nodes: "Select nodes", run_generation: "Run generation" },
|
||||
pluginErrors: { invalidExport: "The plugin did not export a valid object", missingFields: "The plugin is missing id or nodes", downloadFailed: "Download failed (HTTP {{status}})", registryFailed: "Failed to load the official plugin registry (HTTP {{status}})" },
|
||||
shortcut: {
|
||||
dragCanvas: "Drag canvas",
|
||||
pan: "Pan view",
|
||||
wheel: "Mouse wheel",
|
||||
zoom: "Zoom canvas",
|
||||
zoomSlider: "Zoom slider",
|
||||
preciseZoom: "Adjust zoom precisely",
|
||||
boxSelect: "Select multiple nodes",
|
||||
addSelection: "Add nodes to selection",
|
||||
selectAll: "Select all nodes",
|
||||
copyPaste: "Copy/paste nodes or paste clipboard text/images",
|
||||
copyPasteNodes: "Copy/paste nodes",
|
||||
delete: "Delete selection",
|
||||
escape: "Clear selection and close overlays",
|
||||
dropMedia: "Drop images/videos/audio",
|
||||
upload: "Upload to canvas",
|
||||
drag: "Drag",
|
||||
click: "Click",
|
||||
},
|
||||
},
|
||||
navigation: {
|
||||
canvas: "My Canvases",
|
||||
image: "Image Studio",
|
||||
video: "Video Studio",
|
||||
prompts: "Prompt Library",
|
||||
assets: "My Assets",
|
||||
config: "Settings",
|
||||
},
|
||||
topNav: {
|
||||
openMenu: "Open navigation menu",
|
||||
menu: "Navigation menu",
|
||||
navigation: "Navigation",
|
||||
openAgent: "Open Agent",
|
||||
closeAgent: "Close Agent",
|
||||
plugins: "Node plugins",
|
||||
docs: "Documentation",
|
||||
shortcuts: "Keyboard shortcuts",
|
||||
lightTheme: "Switch to light theme",
|
||||
darkTheme: "Switch to dark theme",
|
||||
},
|
||||
home: {
|
||||
promptError: "Failed to load prompts",
|
||||
description: "Generate, connect, and reshape <content>images, text, and graphics</content> in <canvas>Infinite Canvas</canvas>, turning one-off generations into a continuous creative process.",
|
||||
start: "Get started",
|
||||
openCanvas: "Open canvas",
|
||||
showcaseTitle: "Keep every great result",
|
||||
showcaseDescription: "Save reliable prompts, visual references, and generated images so your next creation starts from proven ideas.",
|
||||
viewPrompts: "View prompt library",
|
||||
},
|
||||
version: {
|
||||
viewUpdates: "View release updates",
|
||||
title: "Release updates",
|
||||
currentVersion: "Current version",
|
||||
latestVersion: "Latest version",
|
||||
checking: "Checking...",
|
||||
checkUpdates: "Check for updates",
|
||||
unreleased: "Unreleased",
|
||||
latest: "Latest",
|
||||
current: "Current",
|
||||
readFailed: "Failed to read version",
|
||||
changelogFailed: "Failed to read changelog",
|
||||
updated: "Latest version information loaded",
|
||||
updateFailed: "Failed to load the latest version information",
|
||||
types: { added: "Added", fixed: "Fixed", changed: "Changed", optimized: "Optimized", docs: "Docs" },
|
||||
},
|
||||
config: {
|
||||
title: "Settings & Preferences",
|
||||
invalidFile: "The settings file format is invalid",
|
||||
description: "Provider aggregation, model selection, and sync preferences",
|
||||
modalDescription: "Provider aggregation, default models, and sync preferences",
|
||||
tabs: {
|
||||
channels: "Providers",
|
||||
preferences: "Preferences",
|
||||
promptSources: "Prompt sources",
|
||||
},
|
||||
promptSources: {
|
||||
add: "Add source",
|
||||
deleteTitle: "Delete “{{name}}”?",
|
||||
deleteDescription: "The source configuration will be removed. Items already saved to My Assets are unaffected.",
|
||||
refreshed: "Updated {{count}} prompts from “{{name}}”",
|
||||
refreshFailedCached: "Update failed; the previous cache was kept",
|
||||
refreshPartial: "Update complete: {{success}} succeeded and {{failed}} failed. Failed sources kept their previous cache.",
|
||||
refreshAllSuccess: "Updated {{sources}} sources with {{total}} prompts",
|
||||
refreshFailed: "Update failed",
|
||||
builtIn: "Built-in",
|
||||
itemCount: "{{count}} prompts",
|
||||
failed: "Failed",
|
||||
healthy: "Healthy",
|
||||
unsynced: "Not synced",
|
||||
lastSuccess: "Last successful {{time}}",
|
||||
neverFetched: "Not fetched yet",
|
||||
view: "View content",
|
||||
refresh: "Fetch now",
|
||||
edit: "Edit source",
|
||||
schedule: "Scheduled fetch",
|
||||
interval: "Fetch interval",
|
||||
refreshAll: "Fetch all now",
|
||||
lastFetched: "Last fetched {{time}}",
|
||||
neverScheduled: "No scheduled fetch yet",
|
||||
scheduleDescription: "When enabled, all active sources are fetched on this interval while the page is open.",
|
||||
intervals: {
|
||||
disabled: "Disabled",
|
||||
minutes30: "Every 30 minutes",
|
||||
hour1: "Every hour",
|
||||
hours6: "Every 6 hours",
|
||||
hours24: "Every 24 hours",
|
||||
},
|
||||
editor: {
|
||||
addTitle: "Add prompt source",
|
||||
editTitle: "Edit prompt source",
|
||||
nameRequired: "Enter a source name",
|
||||
invalidUrl: "Enter a valid JSON URL",
|
||||
invalidHomepage: "Enter a valid homepage URL",
|
||||
name: "Source name",
|
||||
namePlaceholder: "Used for categories and labels",
|
||||
homepage: "Source homepage (optional)",
|
||||
enabled: "Enable source",
|
||||
jsonFormat: "JSON format",
|
||||
},
|
||||
content: {
|
||||
loadFailed: "Failed to fetch prompts",
|
||||
title: "{{name}} · Prompt content",
|
||||
count: "{{count}} prompts",
|
||||
refresh: "Update now",
|
||||
empty: "No prompts",
|
||||
cover: "Cover",
|
||||
titleColumn: "Title",
|
||||
tags: "Tags",
|
||||
actions: "Actions",
|
||||
},
|
||||
runtime: { requestFailed: "Request failed ({{status}})", urlRequired: "JSON URL is required", fetchFailed: "Failed to fetch “{{name}}”: {{error}}", noPrompts: "No valid prompts were parsed from “{{name}}”", invalidRoot: "Invalid “{{name}}” format: the root value must be an array" },
|
||||
},
|
||||
fileSecurity: "The JSON file contains API keys and WebDAV credentials. Keep it secure.",
|
||||
import: "Import settings",
|
||||
export: "Export settings",
|
||||
imported: "Settings and preferences imported",
|
||||
importedDirectConfig: "Local direct connection settings imported",
|
||||
importFailed: "Failed to read the settings file",
|
||||
saved: "Settings saved",
|
||||
savedContinue: "Settings saved. Continue with your previous request.",
|
||||
channels: {
|
||||
description: "Choose a protocol for each provider, fetch its models, assign capabilities, and optionally customize request scripts.",
|
||||
add: "Add provider",
|
||||
unnamed: "Unnamed provider",
|
||||
numberedName: "Provider {{count}}",
|
||||
modelCount: "{{count}} models",
|
||||
missingUrl: "API endpoint not set",
|
||||
keepOne: "Keep at least one provider",
|
||||
defaultName: "Default provider",
|
||||
newName: "New provider",
|
||||
indexedName: "Provider {{index}}",
|
||||
},
|
||||
preferences: {
|
||||
interface: "Interface",
|
||||
language: "Display language",
|
||||
languageDescription: "Change the language used by the interface and components.",
|
||||
defaultModels: "Default models",
|
||||
defaultImageModel: "Default image model",
|
||||
defaultVideoModel: "Default video model",
|
||||
defaultTextModel: "Default text model",
|
||||
defaultAudioModel: "Default audio model",
|
||||
generation: "Generation preferences",
|
||||
canvasImageCount: "Default canvas image count",
|
||||
canvasImageCountDescription: "Used by new canvas image and configuration nodes. Individual nodes can override it.",
|
||||
audioVoice: "Default audio voice",
|
||||
audioFormat: "Default audio format",
|
||||
audioSpeed: "Default audio speed",
|
||||
audioInstructions: "Default audio instructions",
|
||||
audioInstructionsPlaceholder: "For example: natural, warm, and suitable for narration.",
|
||||
systemPrompt: "System prompt",
|
||||
systemPromptPlaceholder: "For example: You are a visual director specializing in cinematic, photorealistic imagery.",
|
||||
},
|
||||
channelEditor: {
|
||||
title: "Edit provider",
|
||||
name: "Provider name",
|
||||
protocol: "Protocol",
|
||||
baseUrl: "API endpoint",
|
||||
models: "Provider models",
|
||||
modelDescription: "{{count}} selected; assign a capability to each model and optionally customize its request script.",
|
||||
selectModels: "Select models",
|
||||
scriptReady: "Script set",
|
||||
script: "Request script",
|
||||
empty: "Select models to fetch or manually add models.",
|
||||
capabilities: {
|
||||
image: "Image",
|
||||
video: "Video",
|
||||
text: "Text",
|
||||
audio: "Audio",
|
||||
},
|
||||
},
|
||||
modelSelect: {
|
||||
missingConfig: "Enter an API endpoint and API key first",
|
||||
fetched: "Fetched {{count}} models",
|
||||
fetchFailed: "Failed to fetch models",
|
||||
title: "Select provider models",
|
||||
selected: "{{selected}} / {{total}} selected",
|
||||
confirm: "Confirm",
|
||||
search: "Search models",
|
||||
modelName: "Enter a model name",
|
||||
add: "Add model",
|
||||
fetch: "Fetch model list",
|
||||
description: "If the provider does not expose an OpenAI /models endpoint, add model names manually here.",
|
||||
fetchedTab: "Fetched models ({{count}})",
|
||||
existingTab: "Selected models ({{count}})",
|
||||
visibleSelected: "{{selected}} / {{total}} selected in this list",
|
||||
selectVisible: "Select this list",
|
||||
clearVisible: "Clear this list",
|
||||
fetchedEmpty: "Fetch models from the provider or add a model name manually.",
|
||||
existingEmpty: "No models selected.",
|
||||
},
|
||||
scriptEditor: {
|
||||
description: "The script is an async function body. Use the variables below and return the result; leave it empty to use the default request.",
|
||||
insertTemplate: "Insert {{name}} template",
|
||||
restoreDefault: "Restore default request",
|
||||
returnRequirements: "Return requirements",
|
||||
variables: "Available variables",
|
||||
insert: "Click to insert",
|
||||
placeholder: "// Leave empty to use the default request; insert a template to view an example.",
|
||||
},
|
||||
webdav: {
|
||||
title: "WebDAV sync",
|
||||
description: "Sync canvases, assets, generation history, and local media files. AI API keys are excluded; the browser connects directly to WebDAV.",
|
||||
lastSynced: "Last synced {{time}}",
|
||||
neverSynced: "Not synced yet",
|
||||
url: "WebDAV URL",
|
||||
directory: "Remote directory",
|
||||
directoryDescription: "Business directories are created here, each containing {{manifest}} and files/",
|
||||
username: "Username",
|
||||
password: "Password / app password",
|
||||
test: "Test connection",
|
||||
syncing: "Syncing",
|
||||
syncNow: "Sync now",
|
||||
missingUrl: "Enter a WebDAV URL first",
|
||||
available: "WebDAV connection is available",
|
||||
testFailed: "WebDAV connection test failed",
|
||||
preparing: "Preparing to sync",
|
||||
failed: "WebDAV sync failed",
|
||||
completed: "Sync complete: {{projects}} canvases, {{assets}} assets, {{records}} records, and {{files}} files ({{bytes}}) uploaded",
|
||||
domains: {
|
||||
canvas: "Canvases",
|
||||
assets: "My Assets",
|
||||
imageWorkbench: "Image Studio",
|
||||
videoWorkbench: "Video Studio",
|
||||
},
|
||||
stages: {
|
||||
waiting: "Waiting",
|
||||
localWaiting: "Waiting for local data",
|
||||
syncComplete: "Sync complete",
|
||||
remoteManifest: "Reading remote manifest",
|
||||
localData: "Reading local data",
|
||||
downloadMedia: "Downloading missing media",
|
||||
writeMerge: "Writing merged local data",
|
||||
uploadMedia: "Uploading new media",
|
||||
mediaReady: "Media is up to date",
|
||||
mediaSkipped: "No media to upload",
|
||||
checkMissingMedia: "Checking for missing media",
|
||||
downloadMediaFile: "Downloading media",
|
||||
checkLocalMedia: "Checking local media",
|
||||
uploadMediaFile: "Uploading media {{size}}",
|
||||
uploadManifest: "Uploading manifest {{size}}",
|
||||
complete: "Complete",
|
||||
},
|
||||
errors: { testFailed: "WebDAV connection test failed", downloadFailed: "Failed to read the WebDAV sync file", downloadTimeout: "Timed out while reading the WebDAV sync file", emptyUpload: "The upload file is empty; upload canceled", uploadFailed: "Failed to upload the WebDAV sync file", directoryFailed: "Failed to create the remote WebDAV directory", requestTimeout: "The WebDAV request timed out. Check the network or remote service.", connectionFailed: "Could not connect to WebDAV. Check the address, HTTPS certificate, CORS, and network.", urlRequired: "Enter a WebDAV URL first", authenticationFailed: "WebDAV authentication failed. Check the username, password, or app password.", pathMissing: "The WebDAV path does not exist. Check the address and remote directory.", responseFailed: "{{fallback}}: {{status}}{{detail}}", syncFailed: "Sync failed", invalidManifest: "The {{domain}} sync manifest does not belong to this app" },
|
||||
},
|
||||
protocols: {
|
||||
ark: "Volcengine Ark",
|
||||
},
|
||||
},
|
||||
agent: {
|
||||
status: { failed: "Connection failed", connected: "Connected", connecting: "Connecting", disconnected: "Disconnected" },
|
||||
state: { ready: "Ready", connectionRequired: "Enter the Local URL and Connect token", invalidUrl: "The Local URL is invalid", offline: "Offline", skillReadFailed: "Failed to read Skill", skillParseFailed: "Failed to parse Skill", requestFailed: "Local Agent request failed" },
|
||||
siteTools: { canvasList: "Canvas list", generationStatus: "Generation task status", imageConfig: "Image configuration", imageGenerate: "Generate in Image Studio", videoConfig: "Video configuration", videoGenerate: "Generate in Video Studio", promptSearch: "Search prompts", assetList: "Asset list", assetAdd: "Add asset", unknownTool: "Unknown tool: {{name}}", canvasLoading: "The canvas is still loading. Try again shortly.", canvasHint: "Use site_navigate to open /canvas/{id}", assetsLoading: "Assets are still loading. Try again shortly.", assetTitleRequired: "Provide the asset title", textContentRequired: "content is required when kind=text", imageUrlRequired: "imageUrl is required when kind=image", imageReadFailed: "Could not read the image. Use a data URL or a cross-origin accessible image URL.", assetKindUnsupported: "assets_add supports only kind=text or kind=image", imageGenerationStarted: "Opened Image Studio and started generation. Use generation_get_status to query the task.", imageConfigApplied: "Opened Image Studio and applied the parameters without starting generation.", videoGenerationStarted: "Opened Video Studio and started generation. Use generation_get_status to query the task.", videoConfigApplied: "Opened Video Studio and applied the parameters without starting generation." },
|
||||
connect: { pluginTitle: "Option 1: Use the Codex plugin", pluginText: "Install the Infinite Canvas plugin in the Codex app and launch the canvas through it. The plugin starts the local Agent and supplies the connection details automatically.", directTitle: "Option 2: Run the Agent directly", directText: "Without the Codex plugin, run the command below in a terminal, then return here to connect or enter the Local URL and Connect token manually.", commandCopied: "Command copied", pluginReminder: "Codex plugin note", pluginReminderText: "The tool list enters the Codex context and consumes additional tokens only after installing the Codex plugin or adding MCP manually. Running npx -y @basketikun/canvas-agent alone does not install MCP.", removePlugin: "Remove plugin", removeMcp: "Remove manual MCP", copyCommand: "Copy command", title: "Connect local Agent", description: "Choose the connection method that fits your workflow.", webConnection: "Web connection", autoDiscover: "The Local URL and Connect token are discovered automatically by default. Enter them manually only if discovery fails.", disconnect: "Disconnect", connect: "Connect", localAddress: "Local address", urlPlaceholder: "For example http://127.0.0.1:17371", token: "Connection token", tokenPlaceholder: "Discover automatically or enter the Connect token" },
|
||||
history: { workspace: "Workspace", defaultWorkspace: "Default canvas directory", selected: "{{count}} selected", count: "{{count}} conversations", empty: "No history", deleteCount: "Delete {{count}}", refresh: "Refresh", newThread: "New chat", selectThread: "Select {{name}}", untitled: "Untitled conversation", current: "Current", noWorkspaceThreads: "No conversations in this workspace yet", connectHint: "Connect the local Agent to view conversation history" },
|
||||
skills: { selectLocal: "Select local Skill", search: "Search Skills", loading: "Loading Skills…", noMatch: "No matching enabled Skills", none: "No Skills available", select: "Select Skill", connectHint: "Connect the Agent to use Skills" },
|
||||
skillManager: {
|
||||
codexBusy: "Codex is running. Finish the current task before extracting a Skill.", noConversation: "This conversation has no completed content to extract", noCanvas: "There is no canvas on this page to extract", connecting: "This page is still connecting to the Agent. Try again shortly.", syncFailed: "Failed to sync the current canvas. Check the Agent connection and try again.", noDraft: "No Skill draft was generated", draftCreated: "Draft generated. Review it on the Skills tab before creating it.", draftFailed: "Failed to generate Skill draft", contentMissing: "Skill content was not returned", readFailed: "Failed to read Skill", defaultPromptMention: "The default prompt must include ${{name}}", created: "Skill created", updated: "Skill updated", saveFailed: "Failed to save Skill", deleteTitle: "Delete {{name}}", deleteDescription: "The local files cannot be recovered after deletion. Continue?", delete: "Delete", deleted: "Skill deleted", deleteFailed: "Failed to delete Skill", statusFailed: "Failed to update Skill status",
|
||||
fromConversation: "Generate draft from this conversation", availableAfterRun: "Available when Codex finishes running", conversationDescription: "Extract reusable workflows from this conversation", noCompletedContent: "This conversation has no completed content", startConversation: "Start a conversation first", fromCanvas: "Generate draft from this canvas", canvasDescription: "Extract nodes and generation workflows from this page", canvasUnavailable: "There is no available canvas on this page", blankCreate: "Create from scratch", blankDescription: "Start with an empty form", localSkills: "Local Skills", localDescription: "Installed locally and run directly by Codex", reload: "Reload", reloadSkill: "Reload Skills", createSkill: "Create Skill", filterBySource: "Filter Skills by source", scopes: { all: "All sources", repo: "Project", user: "Personal", system: "System", admin: "Admin" }, loadErrors: "{{count}} Skills could not be loaded", externalReadonly: "External Skills can only be used or enabled and disabled", noDescription: "No description", enabled: "Enabled", disabled: "Disabled", selected: "Selected", use: "Use", editNamed: "Edit {{name}}", deleteNamed: "Delete {{name}}", connectToView: "Connect the Agent to view Skills", noMatch: "No matching Skills", none: "No local Skills yet", connectDescription: "Installed local Skills will load after connection", tryAnotherFilter: "Try another keyword or source", createOrInstall: "Create one, or install one locally and refresh", saveChanges: "Save changes", saveLocation: "Save to the local Agent workspace", basicInfo: "Basic information",
|
||||
identifier: "Skill identifier", identifierExtra: "Used as the folder name and for $skill-name invocation.", identifierRequired: "Enter a Skill identifier", identifierMax: "The Skill identifier cannot exceed 64 characters", identifierPattern: "Use lowercase letters, numbers, and hyphens only; hyphens cannot repeat or appear at either end", identifierPlaceholder: "For example, product-grid", displayName: "Display name", displayNameMax: "The display name cannot exceed 64 characters", displayNamePlaceholder: "For example, Product grid generator", whenToUse: "When to use", whenToUseExtra: "Describe the Skill's capabilities and use cases so Codex can decide when to invoke it.", whenToUseRequired: "Describe when to use this Skill", whenToUseMax: "The use-case description cannot exceed 1,024 characters", noAngleBrackets: "The use-case description cannot contain angle brackets", whenToUsePlaceholder: "For example: Use when planning and generating a set of product images from product information", instructions: "Instructions", instructionsExtra: "Describe the steps, constraints, and output requirements in execution order.", instructionsRequired: "Enter the instructions", instructionsPlaceholder: "Describe execution steps, required checks, and the final output", advanced: "Advanced settings", shortDescription: "Card summary", shortDescriptionExtra: "Use 25–64 characters for easy scanning.", shortDescriptionMin: "The card summary must contain at least 25 characters", shortDescriptionMax: "The card summary cannot exceed 64 characters", shortDescriptionPlaceholder: "Optional; shown in the list", defaultPrompt: "Default prompt", defaultPromptExtra: "Must include the exact $skill-name, such as $product-grid.", defaultPromptMax: "The default prompt cannot exceed 1,024 characters", defaultPromptPlaceholder: "Optional; prefilled when the Skill is selected",
|
||||
},
|
||||
composer: { removeImage: "Remove image", removeSkill: "Remove Skill", uploadImage: "Upload image", stop: "Stop", send: "Send", model: "Model: {{model}}", selectModel: "Select a Codex model. Current: {{model}}", reasoning: "Reasoning effort: {{effort}}", selectReasoning: "Select reasoning effort. Current: {{effort}}", permissionLabel: "Permissions: {{mode}}", selectPermission: "Select Codex permission mode. Current: {{mode}}", effort: { minimal: "Minimal", low: "Low", medium: "Medium", high: "High", xhigh: "Extra high", max: "Maximum", ultra: "Ultra" }, permission: { request: "Ask for approval", requestDescription: "Always ask before editing outside the workspace or accessing the network", automatic: "Automatic review", automaticDescription: "Codex reviews risky actions and asks only when needed", full: "Full access", fullShort: "Full access", fullDescription: "Unrestricted access to the network and local files" }, tools: { label: "Tool confirmation: {{mode}}", manual: "Manual", manualDescription: "Ask before the Agent writes to the canvas", automatic: "Automatic", automaticDescription: "Let the Agent perform canvas writes automatically", select: "Select tool confirmation mode. Current: {{mode}}" } },
|
||||
panel: { connectionSettings: "Connection settings · {{status}}", connectionSettingsLabel: "Connection settings. Current status: {{status}}", chat: "Chat", history: "History", skills: "Skills", logs: "Logs", collapse: "Collapse chat", collapseLabel: "Collapse Agent panel", resize: "Resize right panel", content: "Agent content", mcpInitializing: "MCP is initializing. You can send messages when it is ready.", initFailed: "Codex conversation initialization failed. Start or resume a conversation.", placeholder: "Ask Codex or have it operate the site or canvas" },
|
||||
chat: { latestMessages: "View latest messages", latestCall: "Latest call", input: "Input", cached: "Cached", output: "Output" },
|
||||
logs: { copied: "Logs copied", selectedManual: "Logs selected; copy them manually", copyFailed: "Copy failed. Switch to raw JSON and copy manually.", title: "Runtime logs", diagnostics: "Diagnostics", rawJson: "Raw JSON", messages: "{{count}} messages", tool: "Tool: {{tool}}", noPendingTool: "No pending tool", all: "All {{count}}", errors: "Errors {{count}}", warnings: "Warnings {{count}}", info: "Info {{count}}", list: "Diagnostics log list", noFiltered: "No logs match this filter", empty: "No event logs", new: "{{count}} new logs", newLabel: "{{count}} new logs. View latest logs.", latest: "View latest logs", fullData: "Full diagnostics · {{count}} entries", copyAll: "Copy all logs", copyLastError: "Copy latest error", lastErrorCopied: "Latest error copied", clear: "Clear logs", repeated: "Repeated {{count}} times", details: "Details", skillLoading: "Skill loading", plugin: "Plugin", terminal: "Terminal", conversationStorage: "Conversation storage" },
|
||||
message: { close: "Close", copied: "Copied", copyCode: "Copy code", copyLink: "Copy link", externalWarning: "You are about to open an external link. Make sure you trust it.", openExternal: "Open external link?", continueOpen: "Open", revealed: "Revealed in file manager", openLocalFailed: "Could not open the local file", openLocal: "Open local file?", localDescription: "This path will be revealed in your local file manager and will not be opened in the browser.", externalDescription: "You are about to open an external link. Make sure you trust it.", pathCopied: "Path copied", linkCopied: "Link copied", copyPath: "Copy path", showInFolder: "Show in file manager", toolCall: "Tool call", awaitingConfirmation: "Awaiting confirmation", reject: "Reject", approve: "Approve", networkApproval: "Network access request", fileApproval: "File edit request", permissionApproval: "Extended permission request", commandApproval: "Command execution request", decline: "Decline", allowOnce: "Allow once", allowSession: "Allow for session", thinking: "Thinking", commandsRunning: "Running {{count}} commands", commandRunning: "Running command", commandsCompleted: "Ran {{count}} commands{{failed}}", commandsFailed: " · {{count}} failed", failed: "Failed", running: "In progress", completed: "Completed", command: "Command", slowResponse: "The response is taking longer, but the task is still running. You can keep waiting or use the stop button beside the input to end this turn.", waitingSeconds: "Waited {{seconds}} seconds", waitingMinutes: "Waited {{minutes}}m {{seconds}}s", files: "Files", errorInfo: "Error", output: "Output", viewLarge: "View full image", attachmentPreview: "Image attachment preview", noEffect: "No effect", canceled: "Canceled", recorded: "Recorded", stopped: "Stopped", finished: "Finished", pending: "Pending" },
|
||||
events: { analyzing: "Analyzing the task…", reasoning: "Reasoning summary", plan: "Execution plan", commandFailed: "Command failed", commandCompleted: "Command completed", executeCommand: "Run command", editFiles: "Edit files", searchWeb: "Search the web", viewImage: "View image", imageViewed: "Image viewed", viewingImage: "Viewing image", imageGeneration: "Generate image", imageFailed: "Image generation failed", imageCompleted: "Image generation completed", generatingImage: "Generating image…", compactContext: "Compact context", contextCompacted: "Conversation context compacted; continuing the task", compactingContext: "Compacting conversation context…", collaboration: "Collaborate", collaborationFailed: "Collaboration task failed", collaborationCompleted: "Collaboration task completed", collaborating: "Working with collaborators…", progress: "Task progress", progressCount: "{{completed}}/{{total}} completed", planning: "Preparing execution steps…", executingCommand: "Running command…", workingDirectory: "Working directory", exitStatus: "Exit status", duration: "Duration", seconds: "{{value}} seconds", filesCompleted: "File changes completed", preparingFiles: "Preparing file changes…", fileCompleted: "{{action}} completed: {{path}}", editingFile: "{{action}} in progress: {{path}}", filesEdited: "Edited {{count}} files: {{names}}{{more}}", editingFiles: "Editing {{count}} files: {{names}}{{more}}", andMore: " and more", openPage: "Open page: {{url}}", findInPage: "Find “{{pattern}}” on page", content: "content", search: "Search: {{query}}", relatedInfo: "related information", keyword: "Keyword", webpage: "Web page", add: "Add", delete: "Delete", edit: "Edit", diagnostics: "Infinite Canvas Agent diagnostics", address: "Address: {{endpoint}}", connection: "Connection: {{connection}} · Status: {{status}}", online: "Online", connecting: "Connecting", disabled: "Disabled", messageTool: "Messages: {{messages}} · Tool: {{tool}}", none: "None", noLogs: "No event logs", threadCreated: "Conversation created", turnStarted: "Processing started", progressUpdated: "Task progress updated", turnFailed: "Processing failed", turnStopped: "Processing stopped", turnCompleted: "Processing completed", toolCalled: "Tool called", toolFailed: "Tool failed", toolCompleted: "Tool completed", replyReceived: "Reply received", completed: "Completed", modelBusy: "Model temporarily busy", modelBusyDescription: "The selected model is receiving too many requests. Try again later or switch models.", taskFailed: "Task failed", taskFailedDescription: "Codex could not complete this task. Try again later." },
|
||||
eventExtra: { toolNamed: "Call tool: {{name}}", toolOperation: "Tool operation", targetPage: "Target page", searchContent: "Search query", textContent: "Text content", operationContent: "Operations", imageCount: "Image count", tools: { generateImage: "Generate image", viewImage: "View image", executeCommand: "Run command", editFiles: "Edit files", searchWeb: "Search the web", canvasOps: "Canvas operations", readCanvas: "Read canvas", readSelection: "Read selection", exportSnapshot: "Export snapshot", createNode: "Create node", addAttachments: "Add attachment images", createText: "Create text", createTexts: "Create text nodes", createConfig: "Create generation config", createImageFlow: "Create image flow", createGenerationFlow: "Create generation flow", generateText: "Generate text", generateVideo: "Generate video", generateAudio: "Generate audio", updateNode: "Update node", updateText: "Update text", moveNodes: "Move nodes", resizeNode: "Resize node", deleteNodes: "Delete nodes", connectNodes: "Connect nodes", selectNodes: "Select nodes", setViewport: "Adjust viewport", runGeneration: "Run generation", openPage: "Open page" } },
|
||||
eventMore: { toolRunning: "{{action}}…", openedRoute: "Opened {{route}}", canvasCount: "{{count}} canvases", promptCount: "Found {{count}} prompts", assetCount: "{{count}} assets", assetAdded: "Added to My Assets", generationStatus: "{{total}} tasks: {{queued}} queued, {{running}} running, {{succeeded}} succeeded, {{failed}} failed", workbenchExecuted: "Executed in the workbench", workbenchConfigRead: "Workbench configuration read", canvasRead: "Current canvas read", selectionRead: "Current selection read", textNodes: "{{count}} text nodes", imageNodes: "{{count}} images", configNodes: "{{count}} config nodes", videoNodes: "{{count}} videos", audioNodes: "{{count}} audio nodes", groupNodes: "{{count}} groups", otherNodes: "{{count}} other nodes", connections: "{{count}} connections", emptyCanvas: "The canvas is empty", executeTool: "Run {{tool}}", thinking: "Thinking...", operationRunning: "{{operation}} is running...", organizingCanvas: "Canvas read; Codex is organizing the result...", operationCompleted: "{{operation}} completed; Codex is continuing...", attachmentPrompt: "Please process the uploaded image attachments.", routes: { home: "Home", canvas: "Canvas", canvasProject: "Selected canvas", image: "Image Studio", video: "Video Studio", prompts: "Prompt Center", assets: "My Assets", config: "Settings" } },
|
||||
runtime: {
|
||||
mcpStarting: "Starting MCP: {{name}}", mcpConnecting: "Connecting tools and loading the available tool list", mcpReadyNamed: "MCP ready: {{name}}", toolsReady: "Tool list loaded. You can start chatting.", mcpFailedNamed: "MCP failed to start: {{name}}", mcpCanceledNamed: "MCP startup canceled: {{name}}", toolInitFailed: "The tool service could not finish initializing", mcpServicesStarting: "Starting MCP services", toolServicesPending: "{{count}} tool services are still initializing", checkingToolServices: "Checking tool service status", conversationInitializing: "Initializing the Codex conversation", conversationCreating: "Creating the conversation and starting canvas tools", someMcpFailed: "Some MCP services failed to initialize", remainingToolsReady: "The remaining tools are ready. You can start chatting.", conversationInitFailed: "Codex conversation initialization failed", conversationCreateFailed: "Could not create the Codex conversation", mcpServicesReady: "{{count}} MCP services initialized", toolInitCanceled: "Tool service initialization was canceled", mcpStatusComplete: "MCP status check completed", mcpListRead: "Loaded the complete tool service list returned by Codex",
|
||||
historyReadFailed: "Failed to read history", conversationSyncFailed: "Failed to sync conversation", agentOutdated: "The local Agent is outdated. Restart Canvas Agent and reconnect.", restartRequired: "Agent restart required", versionMismatch: "Agent version mismatch", awaitingApproval: "Awaiting approval", codexRunning: "Codex is running", connected: "Connected", localAgentConnected: "Local Agent connected", processingFailed: "Processing failed", completed: "Completed", approvalGranted: "Permission approved", approvalCanceled: "Permission canceled", log: "Log", connectionLostDescription: "The local Agent connection failed or was interrupted", connectionFailedDescription: "Connection failed. Check the address and token.", connectionLost: "Connection lost", connectionFailed: "Connection failed", modelListFailed: "Failed to load model list",
|
||||
imageTooLarge: "Image too large", imagePayloadTooLarge: "Image attachments exceed 30 MB. Remove some before sending.", imagesSent: "Sent {{count}} images", sending: "Sending", defaultModel: "Default model", defaultEffort: "Default effort", sendTask: "Send task", attachmentCount: "{{count}} attachments", attachmentsOnly: "Attachments only", startConversationFailed: "Failed to start conversation", attachmentHistoryFailed: "Failed to save attachment history", sendFailed: "Send failed", conversationSynced: "Conversation synced", taskStillRunning: "Task is still running", stopping: "Stopping", stopTask: "Stop task", taskStopped: "Task stopped", stopFailed: "Failed to stop", imageLimit: "Image attachments are limited to about 30 MB.", imageReadFailed: "Failed to read image", pendingCanvasTool: "Another canvas tool call is awaiting confirmation", awaitingConfirmation: "Awaiting confirmation", toolCompleted: "{{tool}} completed", toolExecutionFailed: "Tool execution failed", openCanvasFirst: "The canvas is not open. Use site_navigate to open it first.", canvasOperationFailed: "Canvas operation failed", canvasToolCanceled: "The user canceled the canvas tool call",
|
||||
submittingApproval: "Submitting permission decision", waitingCodexApproval: "Waiting for Codex to confirm permission", approvalFailed: "Permission approval failed", enableFullAccess: "Enable full access", fullAccessDescription: "Codex will run without sandbox restrictions and can access the internet and any local files. Use this only when you trust the current task.", enableFullAccessAction: "Enable full access", offline: "Offline", addressRequired: "Enter the local Agent address", agentNotFound: "No local Agent was found. Use the Codex plugin or start Canvas Agent manually.", invalidAddress: "The local Agent address is invalid", connecting: "Connecting", creatingConversation: "Creating conversation", newConversation: "New conversation", newConversationFailed: "Failed to create conversation", conversationResumed: "Conversation resumed", resumeConversationFailed: "Failed to resume conversation", recordsDeleted: "Deleted {{count}} records", deleteConversationFailed: "Failed to delete conversation", deleteConversations: "Delete {{count}} conversations", deleteConversationsDescription: "This cannot be undone. Continue?", importGeneratedImages: "Import generated images", addedToSourceCanvas: "Added to the source canvas", imageGenerated: "Image generated", noImageAttachments: "No image attachments to add", invalidAttachmentNode: "Invalid image attachment node parameters", attachmentReadFailed: "Failed to read image attachment", referenceImage: "Reference image", generatedImageReadFailed: "Failed to read the image generated by Codex", generatedImageName: "Generated image {{index}}",
|
||||
},
|
||||
},
|
||||
locale: {
|
||||
zhCN: "简体中文",
|
||||
enUS: "English",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,589 @@
|
||||
export default {
|
||||
meta: {
|
||||
title: "无限画布",
|
||||
description: "一个无限画布创作工具",
|
||||
},
|
||||
theme: { toggle: "切换主题" },
|
||||
common: {
|
||||
cancel: "取消",
|
||||
save: "保存",
|
||||
edit: "编辑",
|
||||
done: "完成",
|
||||
delete: "删除",
|
||||
copy: "复制",
|
||||
copied: "已复制",
|
||||
details: "详情",
|
||||
addToAssets: "加入我的资产",
|
||||
addedToAssets: "已加入我的资产",
|
||||
copyPrompt: "复制提示词",
|
||||
promptCopied: "提示词已复制",
|
||||
created: "创建:{{date}}",
|
||||
updated: "更新:{{date}}",
|
||||
all: "全部",
|
||||
view: "查看",
|
||||
download: "下载",
|
||||
upload: "上传",
|
||||
requestCanceled: "请求已取消",
|
||||
durationMinutes: "{{minutes}}分{{seconds}}秒",
|
||||
durationSeconds: "{{seconds}}秒",
|
||||
imageReadFailed: "读取图片失败",
|
||||
},
|
||||
settingsPanels: {
|
||||
common: { auto: "自动", low: "低", medium: "中", high: "高", xhigh: "极高" },
|
||||
image: { title: "图像设置", quality: "质量", size: "尺寸", align16: "16 倍数对齐", align16Hint: "输入完成后自动向上补成 16 的倍数", aspectRatio: "宽高比", transparent: "透明背景", transparentHint: "开启后生成无背景的透明图像(仅部分模型可用)", count: "生成张数", images: "{{count}} 张" },
|
||||
video: { title: "视频设置", quality: "清晰度", size: "尺寸", seconds: "秒数", resolution: "分辨率", ratio: "比例", duration: "时长", smart: "智能", output: "输出", generateAudio: "生成声音", watermark: "添加水印", adaptive: "自适应", sizes: { landscape: "横屏", portrait: "竖屏", square: "方形", widescreen: "宽屏", tall: "长图", auto: "自动" }, ratios: { landscape: "横屏", portrait: "竖屏", square: "方形", standardLandscape: "标准横屏", standardPortrait: "标准竖屏", cinematic: "宽银幕", adaptive: "自适应" } },
|
||||
audio: { title: "音频设置", voice: "声音", format: "格式", speed: "语速", instructions: "声音指令", instructionsPlaceholder: "例如:自然、温暖、适合旁白。" },
|
||||
text: { title: "文本设置", reasoning: "推理强度" },
|
||||
model: { select: "选择模型", assign: "请先在渠道里为{{capability}}指定模型", noMatch: "暂无匹配的{{capability}}模型", addFirst: "请先到配置里添加渠道和模型", capabilities: { image: "生图", video: "视频", text: "文本", audio: "音频" } },
|
||||
},
|
||||
generation: { pending: ["正在创建图片", "马上就好了", "再等等", "正在整理细节"] },
|
||||
imageReferences: { label: "图片{{index}}", separator: "、", promptPrefix: "参考图片编号:{{labels}}。请按这些编号理解提示词中的图片引用。\n\n{{prompt}}" },
|
||||
seedance: { autoMatch: "自动匹配", separator: "、", references: { image: "图片{{index}}", video: "视频{{index}}", audio: "音频{{index}}" }, promptPrefix: "参考资产编号:{{labels}}。请按这些编号理解提示词中的图片、视频和音频引用。\n\n{{prompt}}", referenceHint: "参考视频需为 mp4/mov,H.264/H.265,FPS 24-60;含真人人脸资产请使用火山授权 asset:// 资产。", errors: { format: "{{label}} 仅支持 mp4/mov 格式", size: "{{label}} 超过 200MB,请压缩后再上传", duration: "{{label}} 时长需要在 2-15 秒之间", dimensions: "{{label}} 宽高需要在 300-6000px 之间", ratio: "{{label}} 宽高比需要在 0.4-2.5 之间", pixels: "{{label}} 总像素需要在 409600-8295044 之间", totalDuration: "Seedance 参考视频总时长不能超过 15 秒" } },
|
||||
modelPlugin: {
|
||||
pollTimeout: "插件轮询超时,请检查调用脚本或稍后重试", executionFailed: "模型调用脚本执行失败:{{message}}", noImages: "模型调用脚本没有返回图片",
|
||||
variables: { prompt: "用户输入的提示词(已拼接系统提示词)", images: "参考图,dataURL 数组(改图 / 图生视频时有值)", messages: "对话消息数组,含系统消息", params: "生成参数:生图 {size,quality,count}、视频 {seconds,size,resolution,ratio,generateAudio,watermark}、音频 {voice,format,speed,instructions}", model: "模型名称(不含渠道前缀)", baseUrl: "渠道接口地址(原样,未拼 /v1)", apiKey: "渠道 API Key,请求头里自己带上", systemPrompt: "系统提示词原文", reasoningEffort: "文本推理强度;auto 表示由脚本决定是否传递", http: "便捷请求:http.post(path, body, {headers,params,responseType})、http.get(path, opts)、http.url(path);默认带 Authorization: Bearer apiKey,可用 headers 覆盖;path 相对时按 baseUrl 拼 /v1", request: "原始请求 request({ method, url, headers, params, data, responseType }),不加任何默认头,鉴权头自己写;url 相对时按 baseUrl 拼接(不加 /v1)", poll: "轮询 poll(request, extract, {intervalMs,timeoutMs}),extract 返回真值即结束", sleep: "sleep(ms) 延时", signal: "取消信号,可透传给 http/request", onDelta: "onDelta(text) 推送流式文本(文本模型)" },
|
||||
returns: { image: "文生图(images 为空)和图生图(images 有参考图)接口不同,脚本需自行区分;返回图片 URL 或 dataURL 字符串,也可返回它们的数组,或 [{ dataUrl }] / [{ url }] / [{ b64_json }]", video: "脚本内部完成轮询,返回 { url } 或 { blob } 或视频 URL 字符串", audio: "返回 Blob,或 base64 / dataURL 字符串,或 { b64_json } / { data } / { url }", text: "用 onDelta(text) 推送流式,最终 return 完整文本字符串" },
|
||||
templates: { openai: "OpenAI 规范", gemini: "Gemini 规范", imageOpenai: "生图 / 改图:两者接口不同,用 images 是否为空来区分。", availableImage: "可用:prompt、images(dataURL[])、params{size,quality,count}、model、baseUrl、apiKey", textToImage: "文生图:/images/generations(JSON)", imageToImage: "图生图:/images/edits(multipart/form-data,参考图作为文件上传)", formDataHeader: "不要手动设 Content-Type,交给浏览器带 boundary", imageGemini: "Gemini 文生图 / 图生图:都走 generateContent,参考图放进 parts 的 inline_data。", availableImageGemini: "可用:prompt、images(dataURL[])、model、baseUrl、apiKey", videoOpenai: "视频(脚本内部自行轮询)。可用:prompt、images(dataURL[])、params{seconds,size,resolution,ratio}", videoGemini: "Gemini(Veo) 视频:predictLongRunning 提交,轮询 operation 拿视频 URI。", availableVideoGemini: "可用:prompt、images(dataURL[])、params、model、baseUrl、apiKey", geminiNoVideoUri: "Gemini 未返回视频 URI", audioOpenai: "音频 TTS。可用:prompt、params{voice,format,speed,instructions}、model", audioGemini: "Gemini TTS:generateContent + AUDIO 模态,返回 base64 PCM(音频数据在 inlineData.data)。", availableAudioGemini: "可用:prompt、params{voice}、model、baseUrl、apiKey", geminiNoAudio: "Gemini 未返回音频", textOpenai: "文本对话(OpenAI Responses 接口)。可用:messages([{role,content}])、systemPrompt、model、reasoningEffort", textGemini: "Gemini 文本:generateContent,system 消息放 systemInstruction。", availableTextGemini: "可用:messages([{role,content}])、systemPrompt、model、baseUrl、apiKey" },
|
||||
},
|
||||
apiErrors: { requestFailed: "请求失败", requestCanceled: "请求已取消", baseUrlRequired: "请先配置 Base URL", apiKeyRequired: "请先配置 API Key", authenticationFailed: "鉴权失败,请检查 API Key、套餐权限或模型权限", rateLimited: "请求被限流或额度不足,请稍后重试", notFound: "接口地址不存在(404),请检查 Base URL 和模型选择", badGateway: "网关错误(502),接口服务暂时不可用,请稍后重试", serviceBusy: "服务繁忙(503),请稍后重试", httpFailed: "请求失败(HTTP {{status}}),请检查 Base URL 和 API Key 是否正确", htmlError: "服务返回了 HTML 错误页面({{preview}})", audioModelRequired: "请先配置音频模型", audioGenerationFailed: "音频生成失败", scriptNoAudio: "模型调用脚本没有返回音频", geminiAudioUnsupported: "Gemini 调用格式暂不支持音频生成,请使用 OpenAI 格式渠道", invalidImageSizeFormat: "图像尺寸格式不支持,请使用 auto、9:16 或 1024x1024", positiveImageRatio: "图像比例必须是正数,例如 9:16", imageRatioLimit: "图像宽高比不能超过 3:1,请调整尺寸", positiveImageDimensions: "图像尺寸必须是正整数,例如 1024x1024", imageDimensionStep: "图像尺寸的宽高必须是 16 的倍数,请调整尺寸", imageEdgeLimit: "图像尺寸最长边不能超过 3840px,请调整尺寸", imagePixelLimit: "图像总像素需在 655360 到 8294400 之间,请调整尺寸", unknownImageResponse: "接口返回了未知格式的数据(字段:{{fields}}),请检查模型或接口兼容性", noImageReturned: "接口没有返回图片,请检查提示词是否触发安全审核或模型是否支持该操作", geminiRejected: "Gemini 拒绝了本次请求:{{reason}}", geminiNoImage: "Gemini 接口没有返回图片", geminiMaskUnsupported: "Gemini 调用格式暂不支持蒙版编辑", maskModelUnsupported: "蒙版编辑暂不支持该模型,请使用其他渠道", noContent: "没有返回内容", modelReadFailed: "读取模型失败", videoTimeout: "{{provider}}视频生成超时,请稍后重试", videoReferencesUnsupported: "当前视频接口不支持参考视频或参考音频,请切换到 Seedance 2.0 / 火山 Agent Plan 模型,或移除参考资产", pluginVideoExpired: "插件视频任务已失效,请重新生成", scriptNoVideo: "模型调用脚本没有返回视频", noPlayableVideo: "视频接口没有返回可播放的视频", noVideoTaskId: "视频接口没有返回任务 ID", videoTaskCreateFailed: "视频任务创建失败", videoGenerationFailed: "视频生成失败", videoTaskQueryFailed: "视频任务查询失败", seedanceAudioRequiresVisual: "Seedance 参考音频不能单独使用,请同时添加参考图或参考视频", videoPromptRequired: "请输入视频提示词,或连接参考图片/视频/音频", seedanceNoTaskId: "Seedance 接口没有返回任务 ID", seedanceTaskCreateFailed: "Seedance 任务创建失败", seedanceNoVideoUrl: "Seedance 任务成功但没有返回视频 URL", seedanceVideoTimeout: "Seedance 视频生成超时", seedanceVideoFailed: "Seedance 视频生成失败", seedanceTaskQueryFailed: "Seedance 任务查询失败", seedanceVideoDuration: "Seedance 参考视频单个时长需要在 2-15 秒之间", seedanceVideoTotalDuration: "Seedance 参考视频总时长不能超过 15 秒", seedanceAudioDuration: "Seedance 参考音频单个时长需要在 2-15 秒之间", seedanceAudioTotalDuration: "Seedance 参考音频总时长不能超过 15 秒", referenceImageReadFailed: "参考图读取失败,请换一张图片或重新上传", invalidReferenceVideo: "参考视频必须是公网 URL、资产 ID,或本地已保存的视频", invalidReferenceAudio: "参考音频必须是公网 URL、资产 ID,或本地已保存的音频", videoModelRequired: "请先配置视频模型", geminiVideoUnsupported: "Gemini 调用格式暂不支持视频生成,请使用 OpenAI 格式渠道", noVideoTask: "接口没有返回视频任务", seedanceNoTask: "Seedance 接口没有返回任务", videoDownloadFailed: "视频下载失败", localAssetReadFailed: "读取本地资产失败" },
|
||||
prompts: {
|
||||
title: "提示词中心",
|
||||
library: "提示词库",
|
||||
total: "当前共 {{count}} 条提示词",
|
||||
category: "分类",
|
||||
tags: "标签",
|
||||
search: "搜索标题、内容或标签",
|
||||
searchTitle: "按标题查询",
|
||||
loadFailed: "获取提示词失败",
|
||||
sourceMissing: "提示词来源不存在",
|
||||
use: "使用此提示词",
|
||||
empty: "没有找到匹配的提示词",
|
||||
loading: "加载中...",
|
||||
loadMore: "继续向下滚动加载更多",
|
||||
end: "已经到底了",
|
||||
},
|
||||
assets: {
|
||||
title: "我的资产",
|
||||
description: "收藏常用文本和图片,按类型、标题和标签快速查找。",
|
||||
search: "搜索标题、内容、标签或来源",
|
||||
type: "类型",
|
||||
export: "导出资产",
|
||||
import: "导入资产",
|
||||
add: "新增资产",
|
||||
edit: "编辑资产",
|
||||
empty: "没有找到资产",
|
||||
manual: "手动添加",
|
||||
selectImage: "请选择图片文件",
|
||||
updated: "资产已更新",
|
||||
saved: "资产已保存",
|
||||
textCopied: "文本已复制",
|
||||
noneToExport: "暂无资产可导出",
|
||||
imported: "已导入 {{count}} 个资产",
|
||||
importFailed: "导入失败,请选择有效的资产压缩包",
|
||||
deleted: "资产已删除",
|
||||
packageName: "我的资产.zip",
|
||||
kinds: { text: "文本", image: "图片", video: "视频" },
|
||||
fields: {
|
||||
title: "标题",
|
||||
titleRequired: "请输入标题",
|
||||
titlePlaceholder: "给资产起一个容易检索的名字",
|
||||
coverUrl: "封面 URL",
|
||||
coverPlaceholder: "可粘贴图片 URL,也可以上传本地封面",
|
||||
tags: "标签",
|
||||
tagsPlaceholder: "输入标签后回车",
|
||||
source: "来源",
|
||||
sourcePlaceholder: "手动添加 / 画布 / 提示词库",
|
||||
note: "备注",
|
||||
optional: "可选",
|
||||
textContent: "文本内容",
|
||||
textRequired: "请输入文本内容",
|
||||
textPlaceholder: "保存提示词、说明文案、参考描述等文本资产",
|
||||
imageContent: "图片内容",
|
||||
},
|
||||
selectImageFile: "选择图片文件",
|
||||
noImageSelected: "未选择图片",
|
||||
preview: "预览",
|
||||
noCover: "暂无封面",
|
||||
untitled: "未命名资产",
|
||||
noTags: "无标签",
|
||||
untagged: "未打标签",
|
||||
unknownSource: "未标注来源",
|
||||
details: "资产详情",
|
||||
deleteTitle: "删除资产",
|
||||
deleteConfirm: "确定删除「{{name}}」吗?删除后会从我的资产中移除。",
|
||||
copyText: "复制文本",
|
||||
downloadImage: "下载图片",
|
||||
downloadVideo: "下载视频",
|
||||
},
|
||||
notFound: {
|
||||
title: "页面不存在",
|
||||
description: "这个地址没有对应的页面,可能已经移动或被合并到其他入口。",
|
||||
home: "返回首页",
|
||||
},
|
||||
workbench: {
|
||||
logs: "生成记录",
|
||||
settings: "参数",
|
||||
prompt: "提示词",
|
||||
viewPrompts: "查看提示词库",
|
||||
viewAssets: "查看我的资产",
|
||||
clipboard: "剪切板",
|
||||
upload: "上传",
|
||||
adjust: "调整",
|
||||
generate: "开始生成",
|
||||
results: "生成结果",
|
||||
waiting: "等待 {{time}}",
|
||||
model: "模型",
|
||||
generating: "生成中",
|
||||
success: "成功",
|
||||
failed: "生成失败",
|
||||
retry: "重试",
|
||||
new: "新建",
|
||||
selectAll: "全选",
|
||||
noLogs: "暂无生成记录",
|
||||
deleteLogs: "删除生成记录",
|
||||
deleteLogsConfirm: "确定删除选中的 {{count}} 条生成记录吗?",
|
||||
successCount: "成功 {{count}}",
|
||||
failCount: "失败 {{count}}",
|
||||
itemCount: "{{count}} 张",
|
||||
untitled: "未命名",
|
||||
configFirst: "请先完成配置",
|
||||
generationFailed: "生成失败",
|
||||
retrySuccess: "重试成功",
|
||||
},
|
||||
imageWorkbench: {
|
||||
title: "生图工作台",
|
||||
promptPlaceholder: "描述画面主体、风格、构图、光线和用途",
|
||||
references: "参考图",
|
||||
removeReference: "移除参考图",
|
||||
dropReferences: "松开即可添加参考图",
|
||||
noReferences: "暂无参考图,可将图片拖到这里",
|
||||
clipboardEmpty: "剪切板里没有可读取的图片",
|
||||
clipboardAdded: "已读取 {{count}} 张参考图",
|
||||
promptRequired: "请输入生图提示词",
|
||||
configIncomplete: "生图配置不完整",
|
||||
invalidParams: "生图参数无效",
|
||||
busy: "生图工作台已有任务正在运行",
|
||||
generated: "图片已生成",
|
||||
addedReference: "已加入参考图",
|
||||
resultTitle: "生成结果 {{count}}",
|
||||
source: "生图工作台",
|
||||
unsupportedAsset: "生图工作台只能使用文本或图片资产",
|
||||
missingResult: "接口没有返回图片",
|
||||
empty: "还没有生成图片",
|
||||
resultAlt: "生成结果 {{count}}",
|
||||
addReference: "加入参考图",
|
||||
},
|
||||
videoWorkbench: {
|
||||
title: "视频创作台",
|
||||
promptPlaceholder: "描述镜头运动、主体动作、场景氛围和画面风格",
|
||||
references: "参考图",
|
||||
videoReferences: "参考视频",
|
||||
audioReferences: "参考音频",
|
||||
removeImage: "移除参考图",
|
||||
removeVideo: "移除参考视频",
|
||||
removeAudio: "移除参考音频",
|
||||
dropReferences: "松开即可上传参考资产",
|
||||
noImages: "暂无参考图,可拖入文件,最多 9 张",
|
||||
noVideos: "暂无参考视频,可拖入文件,最多 3 个",
|
||||
noAudio: "暂无参考音频,可拖入文件,最多 3 个,mp3/wav,单个 15MB 内",
|
||||
unsupportedFiles: "已忽略不支持的参考资产,请使用图片、mp4/mov 视频或 mp3/wav 音频",
|
||||
imageTooLarge: "已忽略超过 30MB 的参考图",
|
||||
videoTooLarge: "已忽略超过 200MB 的参考视频",
|
||||
audioTooLarge: "已忽略超过 15MB 的参考音频",
|
||||
audioDurationInvalid: "已忽略不符合时长要求的参考音频:单个 2-15 秒,总时长不超过 15 秒",
|
||||
clipboardEmpty: "剪切板里没有可读取的图片",
|
||||
clipboardAdded: "已读取 {{count}} 张参考图",
|
||||
promptRequired: "请输入视频提示词",
|
||||
referenceError: "{{error}}。{{hint}}",
|
||||
invalidParams: "视频生成参数无效",
|
||||
busy: "视频工作台已有任务正在运行",
|
||||
generated: "视频已生成",
|
||||
timeout: "视频生成超时,请稍后重试",
|
||||
resultTitle: "生成视频",
|
||||
source: "视频创作台",
|
||||
empty: "还没有生成视频",
|
||||
},
|
||||
canvas: {
|
||||
defaultTitle: "无限画布 {{count}}",
|
||||
library: "画布库",
|
||||
title: "无限画布",
|
||||
imported: "已导入 {{count}} 个画布",
|
||||
importFailed: "导入失败,请选择有效的画布压缩包",
|
||||
opening: "正在打开画布...",
|
||||
loading: "正在加载画布...",
|
||||
exportSelected: "导出选中",
|
||||
deleteSelected: "删除选中",
|
||||
deleteAll: "删除全部",
|
||||
import: "导入画布",
|
||||
create: "新建画布",
|
||||
empty: "还没有画布",
|
||||
emptyDescription: "新建一个画布后,就可以独立保存节点、连线和画布外观。",
|
||||
collapsePanel: "收起面板",
|
||||
expandPanel: "展开面板",
|
||||
home: "主页",
|
||||
docs: "文档",
|
||||
projects: "我的画布",
|
||||
deleteCurrent: "删除当前画布",
|
||||
importAsset: "导入资产",
|
||||
exportCurrent: "导出当前画布",
|
||||
undo: "撤销",
|
||||
redo: "重做",
|
||||
openMenu: "打开画布菜单",
|
||||
renameHint: "双击修改画布名称",
|
||||
shortcuts: "快捷键",
|
||||
miniMapOpen: "打开小地图",
|
||||
miniMapClose: "关闭小地图",
|
||||
resetView: "重置视图",
|
||||
zoom: "放大/缩小画布",
|
||||
agentConnected: "Codex 已连接",
|
||||
agentConnecting: "Codex {{activity}}",
|
||||
agentDisconnected: "Codex 未连接",
|
||||
connecting: "连接中",
|
||||
openAgent: "打开本地 Codex 面板",
|
||||
nodeTypes: { image: "图片", text: "文本", config: "生成配置", video: "视频", audio: "音频", group: "组" },
|
||||
toolbar: {
|
||||
move: "移动/选择", text: "文本", image: "图片", video: "视频", audio: "音频", config: "生成配置", group: "组", extensions: "扩展节点", upload: "上传资产", appearance: "画布外观", clear: "清空画布",
|
||||
themeMode: "主题模式", light: "浅色", dark: "深色", gridStyle: "网格样式", dots: "点", lines: "线", blank: "空白", imageInfo: "图片信息",
|
||||
},
|
||||
project: {
|
||||
untitled: "未命名画布", imported: "导入画布",
|
||||
select: "选择 {{name}}", stats: "{{nodes}} 个节点 · {{connections}} 条连线", updated: "更新于 {{date}}", saveName: "保存名称", cancelRename: "取消重命名", export: "导出", rename: "重命名", delete: "删除",
|
||||
deleteTitle: "删除画布?", deleteDescription: "将删除 {{count}} 个画布,里面的节点和连线也会一起移除。",
|
||||
},
|
||||
export: { defaultProjectName: "无限画布", defaultNodesName: "画布元素", item: "元素" },
|
||||
createMenu: {
|
||||
fromNode: "引用该节点生成", close: "关闭", text: "文本生成", textDescription: "脚本、广告词、品牌文案", image: "图片生成", video: "视频生成", audio: "音频参考", config: "配置节点", configDescription: "模型、尺寸、数量和输入顺序", select: "选择节点",
|
||||
},
|
||||
node: {
|
||||
node: "节点",
|
||||
untitled: "未命名节点", renameHint: "双击修改节点名称", group: "组", nodeCount: "{{count}} 个节点", generating: "生成中", failed: "生成失败", retry: "重试", missingPlugin: "缺少插件", missingPluginDescription: "节点类型“{{type}}”的插件未安装或未启用", generateImage: "用文本生图", generate: "生图", editText: "双击编辑文字", emptyImage: "空图片节点", emptyVideo: "空视频节点", emptyAudio: "空音频节点", audio: "音频", batchExpanded: "图片组已展开", batchCollapsed: "图片组已收起", setPrimary: "设为主图",
|
||||
},
|
||||
sidePanel: {
|
||||
canvas: "画布", assets: "资产", prompts: "提示词库", resize: "调整左侧面板宽度", elements: "画布元素", select: "选择", searchNodes: "搜索节点", focusNode: "定位到节点", preview: "放大预览", noNodes: "画布暂无节点", clearAll: "取消全选", selected: "已选 {{count}}", exporting: "正在导出选中元素…", exportName: "画布元素-{{count}}个", exported: "已导出 {{count}} 个元素", exportFailed: "导出失败,请重试",
|
||||
addingAssets: "正在添加资产…", addedAssets: "已添加 {{count}} 个资产", mediaOnly: "仅支持图片或视频文件", addFailed: "添加失败,请重试", searchAssets: "搜索资产", add: "添加", noAssets: "暂无资产", inserted: "插入画布", removeAssetTitle: "移除该资产?", remove: "移除", removeAsset: "移除资产", assetRemoved: "资产已移除",
|
||||
searchPrompts: "搜索提示词", noPrompts: "暂无提示词", promptCopied: "已复制提示词", copyFailed: "复制失败", loadFailedRetry: "加载失败,点击重试", noMatchingPrompts: "无匹配提示词", sourceEmpty: "该来源暂无提示词", viewDetails: "查看详情",
|
||||
filter: { image: "图片", video: "视频", text: "文本", audio: "音频", config: "配置", group: "分组" },
|
||||
},
|
||||
assetPicker: { title: "选择资产", insert: "插入", search: "搜索资产", empty: "没有资产" },
|
||||
imageTools: { copyPrompt: "复制提示词", copyPromptTitle: "复制生成该图片的提示词", reversePrompt: "反推提示词", reversePromptTitle: "创建反推提示词的文本和配置节点", replace: "替换图片", locked: "锁比例", free: "自由比例", lockTitle: "切换为等比缩放", freeTitle: "切换为自由比例", mask: "局部编辑", maskTitle: "添加蒙版遮罩后局部修改", crop: "裁剪", cropTitle: "裁剪并生成新节点", split: "切图", splitTitle: "按行列切分图片", upscale: "放大", upscaleTitle: "放大图片分辨率", superResolve: "超分", superResolveTitle: "AI 超分", angle: "多角度", angleTitle: "生成角度", view: "查看大图", viewTitle: "查看图片详情", more: "更多", configure: "配置快捷工具", customize: "自定义工具栏", showLabels: "显示按钮文字", description: "选择你想在图片节点编辑栏中使用的快捷工具。", preview: "节点预览", imageNode: "图片节点", quickTools: "快捷工具" },
|
||||
nodeToolbar: { noPrompt: "暂无可复制的提示词", infoTitle: "查看节点信息", info: "信息", removeTitle: "移除节点", retryTitle: "重新生成", saveAsset: "存资产", downloadAudio: "下载音频", downloadVideo: "下载视频", downloadImage: "下载图片", editTextTitle: "编辑文本", editText: "编辑文字", decreaseFont: "减小字号", increaseFont: "增大字号", zoomOut: "缩小", zoomIn: "放大", uploadImage: "上传图片", replaceVideo: "替换视频", uploadVideo: "上传视频", replaceAudio: "替换音频", uploadAudio: "上传音频", nodeInfo: "节点信息", name: "名称", type: "类型", size: "尺寸", position: "位置", status: "状态", imageGroup: "图片组", imageSize: "图片大小" },
|
||||
configNode: { title: "生成配置", image: "生图", text: "文本", video: "视频", audio: "音频", prompt: "提示词", references: "参考图", videoReferences: "参考视频", audioReferences: "参考音频", items: "{{count}} 个", images: "{{count}} 张", compose: "组装提示词", stop: "停止", generate: "开始生成" },
|
||||
projectPage: {
|
||||
stopTitle: "停止生成?", stopDescription: "当前生成请求会被中断,已经生成完成的内容会保留。", stop: "停止", continue: "继续生成", configConnection: "配置节点之间不能连接", notFound: "未找到当前画布", exporting: "正在导出当前画布…", exported: "已导出当前画布", clipboardText: "剪切板文本", clipboardImageAdded: "已从剪切板添加图片", clipboardTextAdded: "已从剪切板添加文本", noTextToSave: "没有可保存的文本", canvasText: "画布文本", noVideoToSave: "没有可保存的视频", canvasVideo: "画布视频", noImageToSave: "没有可保存的图片", canvasImage: "画布图片", emptyReverse: "图片节点为空,无法反推提示词", reverseTitle: "反推提示词", reverseConfigTitle: "反推提示词配置", splitTitle: "{{name}} {{row}}-{{column}}", splitSuccess: "已切分为 {{count}} 个子节点", maskResult: "局部编辑结果", maskFailed: "局部修改失败", generationFailed: "生成失败", partialFailed: "部分图片生成失败", allFailed: "全部图片生成失败", retryPromptMissing: "找不到提示词,无法重试", referenceMissing: "参考图片已丢失,无法继续重试", emptyTextImage: "文本节点为空,无法生图", untitledCanvas: "未命名画布", superResolve: "AI 超分", notImplemented: "暂未实现", imageDetails: "图片详情", clearTitle: "清空画布?", clear: "清空", clearDescription: "这会删除当前画布上的所有节点和连线。", reversePreset: "请根据参考图片反推一段适合用于 AI 生图的提示词。\n\n要求:\n1. 只输出提示词正文,不要解释。\n2. 覆盖主体、构图、风格、光线、色彩、材质、镜头和氛围。\n3. 尽量写成可直接用于生图模型的完整提示词。", maskPrompt: "只修改蒙版透明区域,其他区域保持不变。{{prompt}}", editTextPrompt: "请根据要求修改以下文本。\n\n原文:\n{{source}}\n\n修改要求:\n{{prompt}}"
|
||||
},
|
||||
reverseComposer: "参考图片:@[node:{{imageId}}]\n任务说明:@[node:{{textId}}]",
|
||||
editors: {
|
||||
reset: "重置", zoomOut: "缩小", zoomIn: "放大", loading: "读取中", unknown: "未知", cancel: "取消",
|
||||
angleTitle: "AI 多角度", angleDescription: "左侧只预览方向,结果会基于原图重新生成", horizontal: "左右角度", pitch: "俯仰角度", distance: "镜头距离", lens: "广角镜头", standard: "标准", wide: "广角", aiGenerate: "AI 生成",
|
||||
upscaleTitle: "图片放大", source: "源图", targetPixels: "目标像素", maxReached: "图片已达到 4K,无需放大", targetReached: "图片已达到当前目标像素,无需放大", algorithm: "放大算法", outputSize: "输出尺寸", upscale: "生成放大图", high: "高清插值", highDescription: "适合照片和细节图", bilinear: "双线性", bilinearDescription: "平滑、速度快", nearest: "最近邻", nearestDescription: "适合像素风格",
|
||||
cropTitle: "裁剪图片", adjustCrop: "调整裁剪框", cropHint: "滚轮缩放 · 中键或空格+左键拖动画面", cropSize: "裁剪尺寸 {{size}}", ratio: "比例 {{ratio}}", original: "原图 {{width}} x {{height}}", confirmCrop: "确认裁剪", free: "自由", fixed: "固定", originalMode: "原图",
|
||||
maskTitle: "局部遮罩编辑", maskHint: "滚轮缩放 · 中键或空格+左键拖动画面 · Alt+左/右键横拖调笔刷 · Ctrl/Cmd+Z 撤回 · Ctrl/Cmd+Shift+Z 重做", brush: "画笔", erase: "擦除", undoMaskTitle: "撤回局部涂抹 (Ctrl/Cmd+Z)", undoMask: "撤回局部涂抹", redoMaskTitle: "重做局部涂抹 (Ctrl/Cmd+Shift+Z)", redoMask: "重做局部涂抹", brushSize: "笔刷大小", editInstructions: "修改要求", maskPlaceholder: "例如:把选中区域改成金属材质,保持原图光影", maskPromptRequired: "请输入修改要求", maskRequired: "请先涂抹局部区域", aiEdit: "AI 修改",
|
||||
splitTitle: "切分图片", splitDescription: "生成 {{count}} 个图片子节点,并按原图网格排列到画布右侧", splitHint: "滚轮缩放 · 中键或空格+左键拖动画面 · Delete 删除选中线 · Ctrl/Cmd+Z 撤回 · Ctrl/Cmd+Shift+Z 重做", undoSplitTitle: "撤回切图调整 (Ctrl/Cmd+Z)", undoSplit: "撤回切图调整", redoSplitTitle: "重做切图调整 (Ctrl/Cmd+Shift+Z)", redoSplit: "重做切图调整", rows: "行数", columns: "列数", horizontalLine: "横向线", verticalLine: "纵向线", deleteLine: "删除线", resetLines: "重置线", pieceCount: "切片数量", pieces: "{{count}} 个", averageSize: "平均约", generateChildren: "生成子节点",
|
||||
},
|
||||
plugins: { title: "节点插件", installedPlugin: "已安装插件 {{name}}", installed: "已安装 {{name}}", installFailed: "安装失败:{{error}}", enabled: "已启用", disabled: "已禁用", upgradeAvailable: "有新版本,点击升级", updateFromSource: "从来源更新", updated: "已更新", uninstallTitle: "卸载该插件?", uninstall: "卸载", newVersion: "有新版本可升级", officialDescription: "本项目官方插件,来自仓库注册表", refresh: "刷新", loadFailed: "加载失败:{{error}}", loadingOfficial: "正在获取官方插件…", noOfficial: "暂无官方插件", install: "安装", urlPlaceholder: "输入插件 JS 文件 URL,例如 https://.../plugin.js", noThirdParty: "还没有安装第三方插件", official: "官方插件", local: "本地插件", thirdParty: "第三方插件", warning: "插件代码会在当前页面内直接执行,可访问本地数据(包含 AI API Key)。请仅安装你信任来源的插件。", aiConfigRequired: "AI 配置未就绪,请先在设置里配置模型与密钥", interactiveTitle: "当前:交互中。点击切回「移动」——拖动可移动节点", movableTitle: "当前:可移动。点击切到「交互」——可操作节点内容(如转动全景)", move: "移动", interact: "交互" },
|
||||
promptPanel: { video: "描述要生成的视频内容", audio: "描述要生成的音频内容", image: "描述要生成的图片内容", text: "请输入你想要生成的文本内容", editImage: "请输入你想要把这张图修改成什么", editText: "请输入你想要将本段文本修改成什么", stopGeneration: "停止生成", generate: "生成", stop: "停止" },
|
||||
composer: { title: "组装提示词", description: "@ 引用已连接资产,发送前按当前连接重新编号", placeholder: "输入提示词,按 @ 引用连接的图片或文本", imagePreview: "引用图片预览", resources: { image: "图片{{index}}", video: "视频{{index}}", audio: "音频{{index}}", text: "文本{{index}}" } },
|
||||
controls: { ratio: "比例", duplicate: "复制", delete: "删除", images: "{{count}} 张", reasoning: "推理" },
|
||||
generation: { interrupted: "页面刷新后生成已中断,请重新生成。", front: "正面视角", rotateRight: "向右旋转 {{angle}} 度", rotateLeft: "向左旋转 {{angle}} 度", level: "水平视角", topDown: "俯视 {{angle}} 度", lowAngle: "仰视 {{angle}} 度", angleLabel: "AI 多角度:{{horizontal}},{{pitch}},镜头距离 {{distance}},{{lens}}镜头", anglePrompt: "基于参考图重新生成同一主体的新视角,保持主体、颜色、材质和画面风格一致,不要只做透视变形。{{angle}}。" },
|
||||
agentOps: { add_node: "新增节点", update_node: "更新节点", delete_node: "删除节点", delete_connections: "删除连线", connect_nodes: "连接", set_viewport: "调整视图", select_nodes: "选择节点", run_generation: "触发生成" },
|
||||
pluginErrors: { invalidExport: "插件未导出有效对象", missingFields: "插件缺少 id 或 nodes", downloadFailed: "下载失败 (HTTP {{status}})", registryFailed: "获取官方插件列表失败 (HTTP {{status}})" },
|
||||
shortcut: {
|
||||
dragCanvas: "拖动画布",
|
||||
pan: "平移视图",
|
||||
wheel: "滚轮",
|
||||
zoom: "缩放画布",
|
||||
zoomSlider: "缩放滑杆",
|
||||
preciseZoom: "精确调整缩放",
|
||||
boxSelect: "框选多个节点",
|
||||
addSelection: "追加选择节点",
|
||||
selectAll: "全选节点",
|
||||
copyPaste: "复制 / 粘贴节点,或粘贴剪切板文本/图片",
|
||||
copyPasteNodes: "复制 / 粘贴节点",
|
||||
delete: "删除选中",
|
||||
escape: "取消选择并关闭浮层",
|
||||
dropMedia: "拖入图片/视频/音频",
|
||||
upload: "上传到画布",
|
||||
drag: "拖动",
|
||||
click: "点击",
|
||||
},
|
||||
},
|
||||
navigation: {
|
||||
canvas: "我的画布",
|
||||
image: "生图工作台",
|
||||
video: "视频创作台",
|
||||
prompts: "提示词库",
|
||||
assets: "我的资产",
|
||||
config: "配置",
|
||||
},
|
||||
topNav: {
|
||||
openMenu: "打开导航菜单",
|
||||
menu: "导航菜单",
|
||||
navigation: "导航",
|
||||
openAgent: "打开 Agent",
|
||||
closeAgent: "收起 Agent",
|
||||
plugins: "节点插件",
|
||||
docs: "文档",
|
||||
shortcuts: "快捷键",
|
||||
lightTheme: "切换到浅色主题",
|
||||
darkTheme: "切换到深色主题",
|
||||
},
|
||||
home: {
|
||||
promptError: "获取提示词失败",
|
||||
description: "在 <canvas>无限画布</canvas> 中生成、连接和重组 <content>图片、文字与图形</content>,让创作从单次生成变成连续推演。",
|
||||
start: "开始使用",
|
||||
openCanvas: "打开画布",
|
||||
showcaseTitle: "沉淀每一次好结果",
|
||||
showcaseDescription: "收藏稳定出图的提示词、参考风格和结果图片,让下一次创作从已有经验开始。",
|
||||
viewPrompts: "查看提示词库",
|
||||
},
|
||||
version: {
|
||||
viewUpdates: "查看版本更新",
|
||||
title: "版本更新",
|
||||
currentVersion: "当前版本",
|
||||
latestVersion: "最新版本",
|
||||
checking: "检查中...",
|
||||
checkUpdates: "检查更新",
|
||||
unreleased: "未发布",
|
||||
latest: "最新",
|
||||
current: "当前",
|
||||
readFailed: "版本读取失败",
|
||||
changelogFailed: "更新日志读取失败",
|
||||
updated: "已获取最新版本信息",
|
||||
updateFailed: "获取最新版本信息失败",
|
||||
types: { added: "新增", fixed: "修复", changed: "调整", optimized: "优化", docs: "文档" },
|
||||
},
|
||||
config: {
|
||||
title: "配置与用户偏好",
|
||||
invalidFile: "配置文件格式不正确",
|
||||
description: "渠道聚合、模型选择和同步偏好",
|
||||
modalDescription: "渠道聚合、默认模型和同步偏好",
|
||||
tabs: {
|
||||
channels: "渠道",
|
||||
preferences: "偏好设置",
|
||||
promptSources: "提示词来源",
|
||||
},
|
||||
promptSources: {
|
||||
add: "新增来源",
|
||||
deleteTitle: "删除「{{name}}」?",
|
||||
deleteDescription: "来源配置会被移除,已经加入我的资产的内容不受影响。",
|
||||
refreshed: "「{{name}}」已更新 {{count}} 条",
|
||||
refreshFailedCached: "更新失败,已保留旧缓存",
|
||||
refreshPartial: "更新完成:{{success}} 个成功,{{failed}} 个失败,失败来源已保留旧缓存",
|
||||
refreshAllSuccess: "已更新 {{sources}} 个来源,共 {{total}} 条",
|
||||
refreshFailed: "更新失败",
|
||||
builtIn: "内置",
|
||||
itemCount: "{{count}} 条",
|
||||
failed: "失败",
|
||||
healthy: "正常",
|
||||
unsynced: "未同步",
|
||||
lastSuccess: "上次成功 {{time}}",
|
||||
neverFetched: "尚未拉取",
|
||||
view: "查看内容",
|
||||
refresh: "立即拉取",
|
||||
edit: "编辑来源",
|
||||
schedule: "定时拉取",
|
||||
interval: "拉取周期",
|
||||
refreshAll: "全部立即拉取",
|
||||
lastFetched: "上次拉取 {{time}}",
|
||||
neverScheduled: "尚未定时拉取",
|
||||
scheduleDescription: "开启周期后,页面打开期间会按周期自动拉取所有启用的来源。",
|
||||
intervals: {
|
||||
disabled: "关闭定时",
|
||||
minutes30: "每 30 分钟",
|
||||
hour1: "每 1 小时",
|
||||
hours6: "每 6 小时",
|
||||
hours24: "每 24 小时",
|
||||
},
|
||||
editor: {
|
||||
addTitle: "新增提示词来源",
|
||||
editTitle: "编辑提示词来源",
|
||||
nameRequired: "请输入来源名称",
|
||||
invalidUrl: "请输入有效的 JSON URL",
|
||||
invalidHomepage: "请输入有效的主页地址",
|
||||
name: "来源名称",
|
||||
namePlaceholder: "用于分类展示",
|
||||
homepage: "来源主页(可选)",
|
||||
enabled: "启用来源",
|
||||
jsonFormat: "JSON 格式",
|
||||
},
|
||||
content: {
|
||||
loadFailed: "拉取提示词失败",
|
||||
title: "{{name}} · 提示词内容",
|
||||
count: "共 {{count}} 条",
|
||||
refresh: "立即更新",
|
||||
empty: "暂无提示词",
|
||||
cover: "封面",
|
||||
titleColumn: "标题",
|
||||
tags: "标签",
|
||||
actions: "操作",
|
||||
},
|
||||
runtime: { requestFailed: "请求失败({{status}})", urlRequired: "JSON URL 不能为空", fetchFailed: "「{{name}}」拉取失败:{{error}}", noPrompts: "「{{name}}」未解析到有效提示词", invalidRoot: "「{{name}}」格式错误:根节点必须是数组" },
|
||||
},
|
||||
fileSecurity: "JSON 文件包含 API Key 和 WebDAV 凭据,请妥善保管。",
|
||||
import: "导入配置",
|
||||
export: "导出配置",
|
||||
imported: "配置与用户偏好已导入",
|
||||
importedDirectConfig: "已导入本地直连配置",
|
||||
importFailed: "配置文件读取失败",
|
||||
saved: "配置已保存",
|
||||
savedContinue: "配置已保存,请继续刚才的请求",
|
||||
channels: {
|
||||
description: "每个渠道选择一个协议并拉取模型,为每个模型指定能力(生图/视频/文本/音频),并可自定义调用脚本。",
|
||||
add: "新增渠道",
|
||||
unnamed: "未命名渠道",
|
||||
numberedName: "渠道 {{count}}",
|
||||
modelCount: "{{count}} 个模型",
|
||||
missingUrl: "未填写接口地址",
|
||||
keepOne: "至少保留一个渠道",
|
||||
defaultName: "默认渠道",
|
||||
newName: "新渠道",
|
||||
indexedName: "渠道 {{index}}",
|
||||
},
|
||||
preferences: {
|
||||
interface: "界面偏好",
|
||||
language: "界面语言",
|
||||
languageDescription: "切换应用界面及组件语言。",
|
||||
defaultModels: "默认模型",
|
||||
defaultImageModel: "默认生图模型",
|
||||
defaultVideoModel: "默认视频模型",
|
||||
defaultTextModel: "默认文本模型",
|
||||
defaultAudioModel: "默认音频模型",
|
||||
generation: "生成偏好",
|
||||
canvasImageCount: "画布默认生图张数",
|
||||
canvasImageCountDescription: "新建画布生图和配置节点默认使用,单个节点仍可单独覆盖。",
|
||||
audioVoice: "默认音频声音",
|
||||
audioFormat: "默认音频格式",
|
||||
audioSpeed: "默认音频语速",
|
||||
audioInstructions: "默认音频指令",
|
||||
audioInstructionsPlaceholder: "例如:自然、温暖、适合旁白。",
|
||||
systemPrompt: "系统提示词",
|
||||
systemPromptPlaceholder: "例如:你是一位擅长电影感写实摄影的视觉导演。",
|
||||
},
|
||||
channelEditor: {
|
||||
title: "编辑渠道",
|
||||
name: "渠道名称",
|
||||
protocol: "协议",
|
||||
baseUrl: "接口地址",
|
||||
models: "渠道模型",
|
||||
modelDescription: "已选 {{count}} 个;为每个模型指定能力并可自定义调用脚本。",
|
||||
selectModels: "选择模型",
|
||||
scriptReady: "脚本已设",
|
||||
script: "调用脚本",
|
||||
empty: "点击「选择模型」拉取或手动增加模型。",
|
||||
capabilities: {
|
||||
image: "生图",
|
||||
video: "视频",
|
||||
text: "文本",
|
||||
audio: "音频",
|
||||
},
|
||||
},
|
||||
modelSelect: {
|
||||
missingConfig: "请先填写接口地址和 API Key",
|
||||
fetched: "已拉取 {{count}} 个模型",
|
||||
fetchFailed: "拉取模型失败",
|
||||
title: "选择渠道模型",
|
||||
selected: "已选择 {{selected}} / {{total}}",
|
||||
confirm: "确定",
|
||||
search: "搜索模型",
|
||||
modelName: "输入模型名称",
|
||||
add: "增加模型",
|
||||
fetch: "拉取模型列表",
|
||||
description: "如果上游不提供 OpenAI /models 模型列表接口,请在这里手动增加模型名称。",
|
||||
fetchedTab: "新获取的模型 ({{count}})",
|
||||
existingTab: "已有的模型 ({{count}})",
|
||||
visibleSelected: "当前列表已选择 {{selected}} / {{total}}",
|
||||
selectVisible: "全选当前列表",
|
||||
clearVisible: "取消当前列表",
|
||||
fetchedEmpty: "点击「拉取模型列表」获取上游模型,或手动增加模型名称。",
|
||||
existingEmpty: "暂无已选择的模型。",
|
||||
},
|
||||
scriptEditor: {
|
||||
description: "脚本是一段异步函数体,直接使用下方变量,最后 return 结果;留空则使用系统默认调用。",
|
||||
insertTemplate: "插入{{name}}模板",
|
||||
restoreDefault: "恢复默认调用",
|
||||
returnRequirements: "返回要求",
|
||||
variables: "可用变量",
|
||||
insert: "点击插入",
|
||||
placeholder: "// 留空使用系统默认调用;点击右下角「插入模板」查看示例。",
|
||||
},
|
||||
webdav: {
|
||||
title: "WebDAV 同步",
|
||||
description: "同步画布、我的资产、生成记录和本地媒体文件,不包含 AI API Key;浏览器会直接连接 WebDAV 服务。",
|
||||
lastSynced: "上次同步 {{time}}",
|
||||
neverSynced: "尚未同步",
|
||||
url: "WebDAV 地址",
|
||||
directory: "远程目录",
|
||||
directoryDescription: "会在该目录下分业务目录保存,每个目录包含 {{manifest}} 和 files/",
|
||||
username: "用户名",
|
||||
password: "密码 / 应用密码",
|
||||
test: "测试连接",
|
||||
syncing: "同步中",
|
||||
syncNow: "立即同步",
|
||||
missingUrl: "请先填写 WebDAV 地址",
|
||||
available: "WebDAV 连接可用",
|
||||
testFailed: "WebDAV 连接测试失败",
|
||||
preparing: "准备同步",
|
||||
failed: "WebDAV 同步失败",
|
||||
completed: "同步完成:{{projects}} 个画布,{{assets}} 个资产,{{records}} 条记录,本次上传 {{files}} 个文件 {{bytes}}",
|
||||
domains: {
|
||||
canvas: "画布",
|
||||
assets: "我的资产",
|
||||
imageWorkbench: "生图工作台",
|
||||
videoWorkbench: "视频创作台",
|
||||
},
|
||||
stages: {
|
||||
waiting: "等待同步",
|
||||
localWaiting: "等待本地数据加载",
|
||||
syncComplete: "同步完成",
|
||||
remoteManifest: "读取远端清单",
|
||||
localData: "读取本地数据",
|
||||
downloadMedia: "下载缺失媒体",
|
||||
writeMerge: "写入本地合并结果",
|
||||
uploadMedia: "上传新增媒体",
|
||||
mediaReady: "媒体已齐全",
|
||||
mediaSkipped: "媒体无需上传",
|
||||
checkMissingMedia: "检查缺失媒体",
|
||||
downloadMediaFile: "下载媒体",
|
||||
checkLocalMedia: "检查本地媒体",
|
||||
uploadMediaFile: "上传媒体 {{size}}",
|
||||
uploadManifest: "上传清单 {{size}}",
|
||||
complete: "完成",
|
||||
},
|
||||
errors: { testFailed: "WebDAV 连接测试失败", downloadFailed: "读取 WebDAV 同步文件失败", downloadTimeout: "读取 WebDAV 同步文件超时", emptyUpload: "上传文件为空,已取消上传", uploadFailed: "上传 WebDAV 同步文件失败", directoryFailed: "创建 WebDAV 远程目录失败", requestTimeout: "WebDAV 请求超时,请检查网络或远端服务状态", connectionFailed: "无法连接 WebDAV,请检查地址、HTTPS 证书、CORS 或网络状态", urlRequired: "请先填写 WebDAV 地址", authenticationFailed: "WebDAV 认证失败,请检查用户名、密码或应用密码", pathMissing: "WebDAV 路径不存在,请检查地址和远程目录", responseFailed: "{{fallback}}:{{status}}{{detail}}", syncFailed: "同步失败", invalidManifest: "{{domain}} 同步清单不是当前应用的数据" },
|
||||
},
|
||||
protocols: {
|
||||
ark: "火山方舟",
|
||||
},
|
||||
},
|
||||
agent: {
|
||||
status: { failed: "连接失败", connected: "已连接", connecting: "连接中", disconnected: "未连接" },
|
||||
state: { ready: "就绪", connectionRequired: "请填写 Local URL 和 Connect token", invalidUrl: "Local URL 格式不正确", offline: "离线", skillReadFailed: "读取 Skill 失败", skillParseFailed: "Skill 解析失败", requestFailed: "本地 Agent 请求失败" },
|
||||
siteTools: { canvasList: "画布列表", generationStatus: "生成任务状态", imageConfig: "生图配置", imageGenerate: "生图工作台生成", videoConfig: "视频配置", videoGenerate: "视频创作台生成", promptSearch: "搜索提示词", assetList: "资产列表", assetAdd: "添加资产", unknownTool: "未知工具:{{name}}", canvasLoading: "画布还在加载中,请稍后重试", canvasHint: "用 site_navigate 跳转 /canvas/{id} 打开对应画布", assetsLoading: "资产还在加载中,请稍后重试", assetTitleRequired: "请提供资产标题 title", textContentRequired: "kind=text 时需要提供 content 文本内容", imageUrlRequired: "kind=image 时需要提供 imageUrl(图片地址或 dataURL)", imageReadFailed: "无法读取该图片地址,请改用 dataURL 或可跨域访问的图片链接", assetKindUnsupported: "assets_add 仅支持 kind=text 或 kind=image", imageGenerationStarted: "已跳转生图工作台并触发生成,可用 generation_get_status 查询任务", imageConfigApplied: "已跳转生图工作台并填入参数,未触发生成", videoGenerationStarted: "已跳转视频创作台并触发生成,可用 generation_get_status 查询任务", videoConfigApplied: "已跳转视频创作台并填入参数,未触发生成" },
|
||||
connect: { pluginTitle: "方式一:在 Codex 中使用插件", pluginText: "在 Codex app 安装 Infinite Canvas 插件后,通过插件启动画布,插件会自动启动本地 Agent 并带上连接信息。", directTitle: "方式二:直接运行 Agent", directText: "不使用 Codex 插件时,在终端运行下面命令,再回到网页里连接或手动填入 Local URL 和 Connect token。", commandCopied: "命令已复制", pluginReminder: "Codex 插件提醒", pluginReminderText: "只有安装 Codex 插件或手动添加 MCP 后,工具列表才会进入 Codex 上下文并增加 token 消耗;仅运行 npx -y @basketikun/canvas-agent 启动本地 Agent 不会安装 MCP。", removePlugin: "移除插件", removeMcp: "移除手动 MCP", copyCommand: "复制命令", title: "连接本地 Agent", description: "按使用场景选择一种连接方式。", webConnection: "网页连接", autoDiscover: "默认自动读取 Local URL 和 Connect token,失败时再手动填写。", disconnect: "断开", connect: "连接", localAddress: "本地地址", urlPlaceholder: "例如 http://127.0.0.1:17371", token: "连接 Token", tokenPlaceholder: "自动发现,或手动填入 Connect token" },
|
||||
history: { workspace: "工作空间", defaultWorkspace: "默认画布目录", selected: "已选 {{count}} 条", count: "{{count}} 条历史", empty: "暂无历史", deleteCount: "删除 {{count}} 条", refresh: "刷新", newThread: "新对话", selectThread: "选择{{name}}", untitled: "未命名对话", current: "当前", noWorkspaceThreads: "当前工作空间还没有对话记录", connectHint: "连接本地 Agent 后显示历史记录" },
|
||||
skills: { selectLocal: "选择本地 Skill", search: "搜索 Skill", loading: "正在读取 Skill…", noMatch: "没有匹配的已启用 Skill", none: "还没有可用的 Skill", select: "选择 Skill", connectHint: "连接 Agent 后使用 Skill" },
|
||||
skillManager: {
|
||||
codexBusy: "Codex 正在运行,请完成当前任务后再提炼 Skill", noConversation: "当前对话还没有可提炼的已完成内容", noCanvas: "当前页面没有可提炼的画布", connecting: "当前页面仍在连接 Agent,请稍后再试", syncFailed: "同步当前画布失败,请检查 Agent 连接后重试", noDraft: "未生成 Skill 草稿", draftCreated: "草稿已生成,可在技能页确认后创建", draftFailed: "生成 Skill 草稿失败", contentMissing: "未读取到 Skill 内容", readFailed: "读取 Skill 失败", defaultPromptMention: "默认提示词需要包含 ${{name}}", created: "Skill 已创建", updated: "Skill 已更新", saveFailed: "保存 Skill 失败", deleteTitle: "删除 {{name}}", deleteDescription: "删除后本地文件无法恢复,确定继续吗?", delete: "删除", deleted: "Skill 已删除", deleteFailed: "删除 Skill 失败", statusFailed: "更新 Skill 状态失败",
|
||||
fromConversation: "从当前对话生成草稿", availableAfterRun: "Codex 运行结束后可用", conversationDescription: "整理当前对话中的可复用流程", noCompletedContent: "当前对话还没有已完成内容", startConversation: "请先开始一段对话", fromCanvas: "从当前画布生成草稿", canvasDescription: "整理当前页面的节点与生成流程", canvasUnavailable: "当前页面没有可用画布", blankCreate: "空白创建", blankDescription: "从空白表单开始编写", localSkills: "本地 Skill", localDescription: "安装在本机,由 Codex 直接执行", reload: "重新读取", reloadSkill: "重新读取 Skill", createSkill: "创建 Skill", filterBySource: "按来源筛选 Skill", scopes: { all: "全部来源", repo: "项目", user: "个人", system: "系统", admin: "管理员" }, loadErrors: "{{count}} 个 Skill 未能加载", externalReadonly: "外部 Skill 只能使用或启停", noDescription: "暂无说明", enabled: "已启用", disabled: "已停用", selected: "已选择", use: "使用", editNamed: "编辑 {{name}}", deleteNamed: "删除 {{name}}", connectToView: "连接 Agent 后查看 Skill", noMatch: "没有匹配的 Skill", none: "还没有本地 Skill", connectDescription: "连接成功后会读取本机已安装的 Skill", tryAnotherFilter: "换个关键词或来源试试", createOrInstall: "创建一个,或在本机安装后刷新", saveChanges: "保存更改", saveLocation: "保存到本地 Agent 工作区", basicInfo: "基本信息",
|
||||
identifier: "Skill 标识", identifierExtra: "用于文件夹名和 $skill-name 调用。", identifierRequired: "请输入 Skill 标识", identifierMax: "Skill 标识不能超过 64 个字符", identifierPattern: "仅支持小写字母、数字和连字符,连字符不能连续或位于首尾", identifierPlaceholder: "例如 product-grid", displayName: "显示名称", displayNameMax: "显示名称不能超过 64 个字符", displayNamePlaceholder: "例如 产品九宫格生成", whenToUse: "何时使用", whenToUseExtra: "说明这个 Skill 的能力和适用场景,Codex 会据此判断是否调用。", whenToUseRequired: "请输入使用场景", whenToUseMax: "使用场景不能超过 1024 个字符", noAngleBrackets: "使用场景不能包含尖括号", whenToUsePlaceholder: "例如:当用户需要基于商品信息规划并生成一组产品图时使用", instructions: "执行说明", instructionsExtra: "按实际执行顺序写清步骤、约束和输出要求。", instructionsRequired: "请输入执行说明", instructionsPlaceholder: "写清楚执行步骤、必要检查和最终输出", advanced: "高级设置", shortDescription: "卡片短说明", shortDescriptionExtra: "填写时控制在 25–64 个字符,便于快速浏览。", shortDescriptionMin: "卡片短说明不能少于 25 个字符", shortDescriptionMax: "卡片短说明不能超过 64 个字符", shortDescriptionPlaceholder: "可选,用于列表展示", defaultPrompt: "默认提示词", defaultPromptExtra: "填写时必须准确包含 $skill-name,例如 $product-grid。", defaultPromptMax: "默认提示词不能超过 1024 个字符", defaultPromptPlaceholder: "可选,选择 Skill 时预填到输入框",
|
||||
},
|
||||
composer: { removeImage: "移除图片", removeSkill: "移除 Skill", uploadImage: "上传图片", stop: "停止", send: "发送", model: "模型:{{model}}", selectModel: "选择 Codex 模型,当前为 {{model}}", reasoning: "思考程度:{{effort}}", selectReasoning: "选择思考程度,当前为 {{effort}}", permissionLabel: "权限:{{mode}}", selectPermission: "选择 Codex 权限模式,当前为 {{mode}}", effort: { minimal: "最低", low: "轻度", medium: "中", high: "高", xhigh: "极高", max: "最高", ultra: "Ultra" }, permission: { request: "请求批准", requestDescription: "编辑工作区外文件或联网时始终询问", automatic: "自动审查", automaticDescription: "由 Codex 审查风险操作,必要时再询问", full: "完全访问权限", fullShort: "完全访问", fullDescription: "不受限制地访问网络和本机文件" }, tools: { label: "工具确认:{{mode}}", manual: "手动确认", manualDescription: "Agent 执行画布写入前会请求确认", automatic: "自动确认", automaticDescription: "Agent 会自动执行画布写入操作", select: "选择工具确认模式,当前为 {{mode}}" } },
|
||||
panel: { connectionSettings: "连接设置 · {{status}}", connectionSettingsLabel: "连接设置,当前{{status}}", chat: "对话", history: "历史", skills: "技能", logs: "日志", collapse: "收起对话", collapseLabel: "收起 Agent 面板", resize: "调整右侧面板宽度", content: "Agent 内容", mcpInitializing: "MCP 初始化中,完成后即可发送", initFailed: "Codex 对话初始化失败,请新建或恢复对话", placeholder: "询问 Codex,或让它操作网站/画布" },
|
||||
chat: { latestMessages: "查看最新消息", latestCall: "最新调用", input: "输入", cached: "缓存", output: "输出" },
|
||||
logs: { copied: "日志已复制", selectedManual: "已选中日志,请手动复制", copyFailed: "复制失败,请切换到原始 JSON 后手动复制", title: "运行日志", diagnostics: "排查日志", rawJson: "原始 JSON", messages: "{{count}} 条消息", tool: "工具:{{tool}}", noPendingTool: "无待处理工具", all: "全部 {{count}}", errors: "错误 {{count}}", warnings: "警告 {{count}}", info: "信息 {{count}}", list: "排查日志列表", noFiltered: "当前筛选下没有日志", empty: "暂无事件日志", new: "{{count}} 条新日志", newLabel: "{{count}} 条新日志,查看最新日志", latest: "查看最新日志", fullData: "完整诊断数据 · {{count}} 条", copyAll: "复制全部日志", copyLastError: "复制最近错误", lastErrorCopied: "最近错误已复制", clear: "清空日志", repeated: "重复 {{count}} 次", details: "详细信息", skillLoading: "技能加载", plugin: "插件", terminal: "终端", conversationStorage: "会话存储" },
|
||||
message: { close: "关闭", copied: "已复制", copyCode: "复制代码", copyLink: "复制链接", externalWarning: "即将打开以下外部链接,请确认链接可信。", openExternal: "打开外部链接?", continueOpen: "继续打开", revealed: "已在文件管理器中定位", openLocalFailed: "无法打开本地文件", openLocal: "打开本地文件?", localDescription: "将在本机文件管理器中定位该路径,不会通过浏览器打开。", externalDescription: "即将打开以下外部链接,请确认链接可信。", pathCopied: "路径已复制", linkCopied: "链接已复制", copyPath: "复制路径", showInFolder: "在文件管理器中显示", toolCall: "工具调用", awaitingConfirmation: "等待确认", reject: "拒绝执行", approve: "批准执行", networkApproval: "请求网络访问", fileApproval: "请求编辑文件", permissionApproval: "请求扩展权限", commandApproval: "请求执行命令", decline: "拒绝", allowOnce: "允许一次", allowSession: "本会话允许", thinking: "正在思考", commandsRunning: "正在执行 {{count}} 条命令", commandRunning: "正在执行命令", commandsCompleted: "已执行 {{count}} 条命令{{failed}}", commandsFailed: " · {{count}} 条失败", failed: "执行失败", running: "进行中", completed: "已完成", command: "命令", slowResponse: "响应时间较长,但任务仍在运行。可以继续等待,或点击输入框右侧的停止按钮结束本轮。", waitingSeconds: "已等待 {{seconds}} 秒", waitingMinutes: "已等待 {{minutes}} 分 {{seconds}} 秒", files: "涉及文件", errorInfo: "错误信息", output: "运行输出", viewLarge: "点击查看大图", attachmentPreview: "图片附件预览", noEffect: "未生效", canceled: "已取消", recorded: "已记录", stopped: "已停止", finished: "已结束", pending: "待处理" },
|
||||
events: { analyzing: "正在分析任务…", reasoning: "思考摘要", plan: "执行计划", commandFailed: "命令执行失败", commandCompleted: "命令已完成", executeCommand: "执行命令", editFiles: "修改文件", searchWeb: "搜索资料", viewImage: "查看图片", imageViewed: "已查看图片", viewingImage: "正在查看图片", imageGeneration: "内置生图", imageFailed: "图片生成失败", imageCompleted: "图片生成完成", generatingImage: "正在生成图片…", compactContext: "整理上下文", contextCompacted: "已整理当前对话,继续处理任务", compactingContext: "正在整理当前对话…", collaboration: "协作处理", collaborationFailed: "协作任务失败", collaborationCompleted: "已完成协作任务", collaborating: "正在协作处理任务…", progress: "任务进度", progressCount: "已完成 {{completed}}/{{total}} 项", planning: "正在整理执行步骤…", executingCommand: "正在执行命令…", workingDirectory: "工作目录", exitStatus: "退出状态", duration: "耗时", seconds: "{{value}} 秒", filesCompleted: "已完成文件修改", preparingFiles: "正在准备文件修改…", fileCompleted: "已{{action}} {{path}}", editingFile: "正在{{action}} {{path}}", filesEdited: "已修改 {{count}} 个文件:{{names}}{{more}}", editingFiles: "正在修改 {{count}} 个文件:{{names}}{{more}}", andMore: " 等", openPage: "打开网页:{{url}}", findInPage: "在网页中查找“{{pattern}}”", content: "内容", search: "搜索:{{query}}", relatedInfo: "相关资料", keyword: "关键词", webpage: "网页", add: "新增", delete: "删除", edit: "修改", diagnostics: "Infinite Canvas Agent 诊断", address: "地址:{{endpoint}}", connection: "连接:{{connection}} · 状态:{{status}}", online: "在线", connecting: "连接中", disabled: "未启用", messageTool: "消息:{{messages}} · 工具:{{tool}}", none: "无", noLogs: "暂无事件日志", threadCreated: "创建会话", turnStarted: "开始处理", progressUpdated: "更新任务进度", turnFailed: "处理失败", turnStopped: "处理已停止", turnCompleted: "处理完成", toolCalled: "调用工具", toolFailed: "工具失败", toolCompleted: "工具完成", replyReceived: "收到回复", completed: "完成", modelBusy: "模型暂时繁忙", modelBusyDescription: "当前选择的模型请求量过大,暂时无法处理。请稍后重试,或切换其他模型后再试。", taskFailed: "任务失败", taskFailedDescription: "Codex 未能完成本次任务,请稍后重试。" },
|
||||
eventExtra: { toolNamed: "调用工具:{{name}}", toolOperation: "工具操作", targetPage: "目标页面", searchContent: "搜索内容", textContent: "文本内容", operationContent: "操作内容", imageCount: "图片数量", tools: { generateImage: "生成图片", viewImage: "查看图片", executeCommand: "执行命令", editFiles: "修改文件", searchWeb: "搜索资料", canvasOps: "画布操作", readCanvas: "读取画布", readSelection: "读取选区", exportSnapshot: "导出快照", createNode: "创建节点", addAttachments: "添加附件图片", createText: "创建文本", createTexts: "批量创建文本", createConfig: "创建生成配置", createImageFlow: "创建生图流程", createGenerationFlow: "创建生成流程", generateText: "生成文本", generateVideo: "生成视频", generateAudio: "生成音频", updateNode: "更新节点", updateText: "更新文本", moveNodes: "移动节点", resizeNode: "调整节点尺寸", deleteNodes: "删除节点", connectNodes: "连接节点", selectNodes: "选择节点", setViewport: "调整视口", runGeneration: "触发生成", openPage: "打开页面" } },
|
||||
eventMore: { toolRunning: "{{action}}中…", openedRoute: "已打开{{route}}", canvasCount: "共 {{count}} 个画布", promptCount: "找到 {{count}} 条提示词", assetCount: "共 {{count}} 个资产", assetAdded: "已加入我的素材", generationStatus: "共 {{total}} 个任务,排队 {{queued}},运行中 {{running}},成功 {{succeeded}},失败 {{failed}}", workbenchExecuted: "已在工作台执行", workbenchConfigRead: "已读取工作台配置", canvasRead: "已读取当前画布内容", selectionRead: "已读取当前选中内容", textNodes: "{{count}} 个文本", imageNodes: "{{count}} 张图片", configNodes: "{{count}} 个配置", videoNodes: "{{count}} 个视频", audioNodes: "{{count}} 个音频", groupNodes: "{{count}} 个分组", otherNodes: "{{count}} 个其他节点", connections: "{{count}} 条连线", emptyCanvas: "当前画布为空", executeTool: "执行{{tool}}", thinking: "正在思考...", operationRunning: "{{operation}}正在进行...", organizingCanvas: "画布已读取,Codex 正在整理结果...", operationCompleted: "{{operation}}已完成,Codex 正在继续处理...", attachmentPrompt: "请处理上传的图片附件。", routes: { home: "首页", canvas: "画布页面", canvasProject: "指定画布", image: "生图工作台", video: "视频工作台", prompts: "提示词中心", assets: "我的素材", config: "配置页面" } },
|
||||
runtime: {
|
||||
mcpStarting: "正在启动 MCP:{{name}}", mcpConnecting: "正在建立工具连接并读取可用工具列表", mcpReadyNamed: "MCP 已就绪:{{name}}", toolsReady: "工具列表加载完成,可以开始对话", mcpFailedNamed: "MCP 启动失败:{{name}}", mcpCanceledNamed: "MCP 启动已取消:{{name}}", toolInitFailed: "工具服务未能完成初始化", mcpServicesStarting: "正在启动 MCP 服务", toolServicesPending: "还有 {{count}} 个工具服务正在初始化", checkingToolServices: "正在确认工具服务状态", conversationInitializing: "正在初始化 Codex 对话", conversationCreating: "正在创建会话并启动画布工具服务", someMcpFailed: "部分 MCP 服务初始化失败", remainingToolsReady: "其余工具已就绪,可以开始对话", conversationInitFailed: "Codex 对话初始化失败", conversationCreateFailed: "无法创建 Codex 会话", mcpServicesReady: "{{count}} 个 MCP 服务已完成初始化", toolInitCanceled: "工具服务初始化已取消", mcpStatusComplete: "MCP 状态确认完成", mcpListRead: "已读取 Codex 返回的完整工具服务清单",
|
||||
historyReadFailed: "读取历史失败", conversationSyncFailed: "同步会话失败", agentOutdated: "本地 Agent 版本过旧,请重启 Canvas Agent 后重新连接", restartRequired: "需要重启 Agent", versionMismatch: "Agent 版本不匹配", awaitingApproval: "等待权限确认", codexRunning: "Codex 正在运行", connected: "已连接", localAgentConnected: "本地 Agent 已连接", processingFailed: "处理失败", completed: "完成", approvalGranted: "已批准权限", approvalCanceled: "已取消权限", log: "日志", connectionLostDescription: "本地 Agent 连接失败或已断开", connectionFailedDescription: "连接失败,请检查地址和 token", connectionLost: "连接断开", connectionFailed: "连接失败", modelListFailed: "读取模型列表失败",
|
||||
imageTooLarge: "图片过大", imagePayloadTooLarge: "图片附件超过 30MB,请删减后再发送。", imagesSent: "发送了 {{count}} 张图片", sending: "发送中", defaultModel: "默认模型", defaultEffort: "默认强度", sendTask: "发送任务", attachmentCount: "附件 {{count}}", attachmentsOnly: "仅附件", startConversationFailed: "启动对话失败", attachmentHistoryFailed: "保存附件历史失败", sendFailed: "发送失败", conversationSynced: "会话已同步", taskStillRunning: "任务仍在运行", stopping: "停止中", stopTask: "停止任务", taskStopped: "任务已停止", stopFailed: "停止失败", imageLimit: "图片附件最多约 30MB。", imageReadFailed: "图片读取失败", pendingCanvasTool: "仍有待确认的画布工具调用", awaitingConfirmation: "等待确认", toolCompleted: "{{tool}}完成", toolExecutionFailed: "工具执行失败", openCanvasFirst: "当前不在画布页,请先用 site_navigate 打开画布", canvasOperationFailed: "画布操作失败", canvasToolCanceled: "用户取消了画布工具调用",
|
||||
submittingApproval: "正在提交权限决定", waitingCodexApproval: "等待 Codex 确认权限", approvalFailed: "权限审批失败", enableFullAccess: "启用完全访问权限", fullAccessDescription: "Codex 将不受沙箱限制,可访问互联网及本机任意文件。请仅在信任当前任务时使用。", enableFullAccessAction: "启用完全访问", offline: "离线", addressRequired: "请填写本地 Agent 地址", agentNotFound: "没有发现本地 Agent,请先在 Codex 使用插件或手动启动 Canvas Agent", invalidAddress: "本地 Agent 地址格式不正确", connecting: "连接中", creatingConversation: "正在新建对话", newConversation: "新对话", newConversationFailed: "新建对话失败", conversationResumed: "已恢复会话", resumeConversationFailed: "恢复对话失败", recordsDeleted: "已删除 {{count}} 条记录", deleteConversationFailed: "删除对话失败", deleteConversations: "删除 {{count}} 条对话记录", deleteConversationsDescription: "删除后无法恢复,确定继续吗?", importGeneratedImages: "导入生成图片", addedToSourceCanvas: "已添加到发起任务的画布", imageGenerated: "图片已生成", noImageAttachments: "没有可添加的图片附件", invalidAttachmentNode: "图片附件节点参数无效", attachmentReadFailed: "读取图片附件失败", referenceImage: "参考图", generatedImageReadFailed: "读取 Codex 生成图片失败", generatedImageName: "生成图片 {{index}}",
|
||||
},
|
||||
},
|
||||
locale: {
|
||||
zhCN: "简体中文",
|
||||
enUS: "English",
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user