export default {
// Navigation
nav: {
printers: 'Printers',
archives: 'Archives',
queue: 'Queue',
stats: 'Statistics',
profiles: 'Profiles',
maintenance: 'Maintenance',
projects: 'Projects',
files: 'File Manager',
settings: 'Settings',
system: 'System',
collapseSidebar: 'Collapse sidebar',
expandSidebar: 'Expand sidebar',
update: 'Update',
updateAvailable: 'Update available: v{{version}}',
updateAvailableBanner: 'Version {{version}} is available!',
viewUpdate: 'View update',
viewOnGithub: 'View on GitHub',
keyboardShortcuts: 'Keyboard shortcuts (?)',
switchToLight: 'Switch to light mode',
switchToDark: 'Switch to dark mode',
smartSwitches: 'Smart Switches',
logout: 'Logout',
},
// Common
common: {
save: 'Save',
saving: 'Saving...',
cancel: 'Cancel',
delete: 'Delete',
edit: 'Edit',
add: 'Add',
close: 'Close',
confirm: 'Confirm',
loading: 'Loading...',
error: 'Error',
success: 'Success',
warning: 'Warning',
enabled: 'Enabled',
disabled: 'Disabled',
yes: 'Yes',
no: 'No',
on: 'On',
off: 'Off',
all: 'All',
none: 'None',
search: 'Search',
filter: 'Filter',
sort: 'Sort',
refresh: 'Refresh',
download: 'Download',
upload: 'Upload',
actions: 'Actions',
status: 'Status',
name: 'Name',
description: 'Description',
date: 'Date',
time: 'Time',
hours: 'hours',
minutes: 'minutes',
seconds: 'seconds',
days: 'days',
enable: 'Enable',
disable: 'Disable',
permissions: 'Permissions',
noPrinters: 'No printers configured',
noData: 'No data available',
linkNotFound: 'Link not found',
required: 'Required',
optional: 'Optional',
dismiss: 'Dismiss',
apply: 'Apply',
reset: 'Reset',
clear: 'Clear',
selectAll: 'Select All',
deselectAll: 'Deselect All',
noChange: '— No change —',
unchanged: 'Unchanged',
unassigned: 'Unassigned',
unknown: 'Unknown',
unknownError: 'Unknown error',
today: 'Today',
asap: 'ASAP',
overdue: 'Overdue',
now: 'Now',
collapse: 'Collapse',
expand: 'Expand',
viewArchive: 'View archive',
viewInFileManager: 'View in File Manager',
addedBy: 'Added by {{username}}',
prints: 'prints',
more: '+{{count}} more',
ascending: 'Ascending',
descending: 'Descending',
printer: 'Printer',
remove: 'Remove',
type: 'Type',
print: 'Print',
rename: 'Rename',
move: 'Move',
create: 'Create',
duplicate: 'Duplicate',
left: 'Left',
right: 'Right',
},
// Printers page
printers: {
title: 'Printers',
addPrinter: 'Add Printer',
editPrinter: 'Edit Printer',
deletePrinter: 'Delete Printer',
printerName: 'Printer Name',
serialNumber: 'Serial Number',
ipAddress: 'IP Address / Hostname',
accessCode: 'Access Code',
model: 'Model',
nozzleCount: 'Nozzle Count',
autoArchive: 'Auto Archive',
status: {
idle: 'Idle',
printing: 'Printing',
paused: 'Paused',
offline: 'Offline',
error: 'Error',
finished: 'Finished',
unknown: 'Unknown',
},
temperatures: {
nozzle: 'Nozzle',
bed: 'Bed',
chamber: 'Chamber',
},
progress: '{{percent}}% complete',
timeRemaining: '{{time}} remaining',
deleteConfirm: 'Are you sure you want to delete "{{name}}"?',
maintenanceOk: 'Maintenance OK',
maintenanceWarning: '{{count}} warning',
maintenanceWarning_plural: '{{count}} warnings',
maintenanceDue: '{{count}} due',
maintenanceDue_plural: '{{count}} due',
// Sort options
sort: {
name: 'Name',
status: 'Status',
model: 'Model',
location: 'Location',
ascending: 'Sort ascending',
descending: 'Sort descending',
},
// Card size
cardSize: {
small: 'Small cards',
medium: 'Medium cards',
large: 'Large cards',
extraLarge: 'Extra large cards',
},
// Controls
hideOffline: 'Hide offline',
powerOn: 'Power On',
offlinePrintersWithPlugs: 'Offline printers with smart plugs',
noPrintersConfigured: 'No printers configured yet',
// Printer card
readyToPrint: 'Ready to print',
external: 'External',
deleteArchives: 'Delete print archives',
noLabel: 'No label',
printPreview: 'Print preview',
width: 'Width',
height: 'Height',
noObjectsFound: 'No objects found',
objectsLoadedOnPrintStart: 'Objects are loaded when a print starts',
willBeSkipped: 'Will be skipped',
name: 'Name',
serialCannotBeChanged: 'Serial number cannot be changed',
locationHelp: 'Used to group printers and filter queue jobs',
// WiFi signal strength
wifiSignal: {
veryWeak: 'Very weak',
weak: 'Weak',
fair: 'Fair',
good: 'Good',
excellent: 'Excellent',
},
// Maintenance
maintenanceUpToDate: 'All maintenance up to date - Click to view',
// Chamber light
chamberLightOn: 'Turn on chamber light',
chamberLightOff: 'Turn off chamber light',
// Files
browseFiles: 'Browse printer files',
// Smart plug
autoOffAfterPrint: 'Auto power-off after print',
autoOffExecuted: 'Auto-off was executed - turn printer on to reset',
// HMS errors
hmsErrors: 'HMS Errors',
viewHmsErrors: 'View {{count}} HMS error(s)',
// Actions
resume: 'Resume',
pause: 'Pause',
stop: 'Stop',
camera: 'Camera',
skipObject: 'Skip Object',
reconnect: 'Reconnect',
mqttDebug: 'MQTT Debug',
activeNozzle: 'Active: {{nozzle}} nozzle',
// Firmware
firmwareUpdate: 'Firmware Update',
firmwareInstructions: 'On the printer\'s touchscreen, go to',
firmwareNav: 'Navigate to',
settings: 'Settings',
firmware: 'Firmware',
// Discovery
discoverPrinters: 'Discover Printers',
searching: 'Searching...',
manualEntry: 'Manual Entry',
addFromCloud: 'Add from Cloud',
// Toast messages
toast: {
printerDeleted: 'Printer deleted',
printerAdded: 'Printer added',
printerUpdated: 'Printer updated',
failedToDelete: 'Failed to delete printer',
failedToAdd: 'Failed to add printer',
failedToUpdate: 'Failed to update printer',
commandSent: 'Command sent',
failedToSendCommand: 'Failed to send command',
turnedOn: '{{name}} turned on',
failedToPowerOn: 'Failed to power on {{name}}',
scriptTriggered: 'Script triggered',
printStopped: 'Print stopped',
printPaused: 'Print paused',
printResumed: 'Print resumed',
referenceDeleted: 'Reference deleted',
detectionAreaSaved: 'Detection area saved',
failedToRunScript: 'Failed to run script',
failedToStopPrint: 'Failed to stop print',
failedToPausePrint: 'Failed to pause print',
failedToResumePrint: 'Failed to resume print',
failedToControlChamberLight: 'Failed to control chamber light',
failedToUpdateSetting: 'Failed to update setting',
failedToSkipObjects: 'Failed to skip objects',
failedToRereadRfid: 'Failed to re-read RFID',
failedToCheckPlate: 'Failed to check plate',
failedToUpdateLabel: 'Failed to update label',
failedToDeleteReference: 'Failed to delete reference',
failedToSaveDetectionArea: 'Failed to save detection area',
plateCheckEnabled: 'Plate check enabled',
plateCheckDisabled: 'Plate check disabled',
calibrationSaved: 'Calibration saved!',
calibrationFailed: 'Calibration failed',
rfidRereadInitiated: 'RFID re-read initiated',
},
// Connection status
connection: {
connected: 'Connected',
offline: 'Offline',
},
// Queue info
queue: {
inQueue: '{{count}} print in queue',
inQueue_plural: '{{count}} prints in queue',
},
// Controls section
controls: 'Controls',
// RFID
rfid: {
reread: 'Re-read RFID',
},
// Permissions
permission: {
noAdd: 'You do not have permission to add printers',
noEdit: 'You do not have permission to edit printers',
noDelete: 'You do not have permission to delete printers',
noControl: 'You do not have permission to control printers',
noFiles: 'You do not have permission to access printer files',
noAmsRfid: 'You do not have permission to re-read AMS RFID',
noSmartPlugControl: 'You do not have permission to control smart plugs',
},
// Add/Edit modal
modal: {
addTitle: 'Add Printer',
editTitle: 'Edit Printer',
myPrinter: 'My Printer',
selectModel: 'Select model...',
locationGroup: 'Location / Group (optional)',
locationPlaceholder: 'e.g., Workshop, Office, Basement',
autoArchiveLabel: 'Auto-archive completed prints',
fromPrinterSettings: 'From printer settings',
modelOptional: 'Model (optional)',
saveChanges: 'Save Changes',
},
// Skip objects
skipObjects: {
tooltip: 'Skip objects',
onlyWhilePrinting: 'Skip objects (only while printing)',
requiresMultiple: 'Skip objects (requires 2+ objects)',
title: 'Skip Objects',
matchIdsInfo: 'Match IDs with your printer display',
printerShowsIds: 'The printer screen shows object IDs on the build plate',
skipSelected: 'Skip Selected',
skipping: 'Skipping...',
noObjectsSelected: 'No objects selected',
selectObjectsToSkip: 'Select objects you want to skip from the current print',
skipped: 'skipped',
objectsSkipped: 'Objects skipped',
activeCount: '{{count}} active',
waitForLayer: 'Wait for layer 2+ to skip objects (currently layer {{layer}})',
skip: 'Skip',
},
// Confirm modals
confirm: {
deleteTitle: 'Delete Printer',
deleteMessage: 'Are you sure you want to delete "{{name}}"? This will remove all connection settings.',
deleteArchivesNote: 'All print history for this printer will be permanently deleted.',
keepArchivesNote: 'Print history will be kept but no longer associated with this printer.',
stopTitle: 'Stop Print',
stopMessage: 'Are you sure you want to stop the current print on "{{name}}"? This will cancel the print job.',
stopButton: 'Stop Print',
pauseTitle: 'Pause Print',
pauseMessage: 'Are you sure you want to pause the current print on "{{name}}"?',
pauseButton: 'Pause Print',
resumeTitle: 'Resume Print',
resumeMessage: 'Are you sure you want to resume the print on "{{name}}"?',
resumeButton: 'Resume Print',
powerOnTitle: 'Power On Printer',
powerOnMessage: 'Are you sure you want to turn ON the power for "{{name}}"?',
powerOnButton: 'Power On',
powerOffTitle: 'Power Off Printer',
powerOffMessage: 'Are you sure you want to turn OFF the power for "{{name}}"?',
powerOffWarning: 'WARNING: "{{name}}" is currently printing! Are you sure you want to turn OFF the power? This will interrupt the print and may damage the printer.',
powerOffButton: 'Power Off',
},
// Discovery
discovery: {
title: 'Discover Printers',
searching: 'Searching...',
scanning: 'Scanning...',
scanProgress: 'Scanning... {{scanned}}/{{total}}',
foundPrinters: 'Found {{count}} printer(s)',
noPrintersFound: 'No printers found',
noPrintersFoundSubnet: 'No printers found in the specified subnet.',
noPrintersFoundNetwork: 'No printers found on the network.',
allConfigured: 'All discovered printers are already configured.',
alreadyAdded: 'Already added',
select: 'Select',
manualEntry: 'Manual Entry',
addFromCloud: 'Add from Cloud',
subnetToScan: 'Subnet to scan',
dockerNote: 'Docker detected. Enter your printer\'s subnet in CIDR notation. Requires network_mode: host in docker-compose.yml.',
scanSubnet: 'Scan Subnet for Printers',
discoverNetwork: 'Discover Printers on Network',
scanningSubnet: 'Scanning subnet for Bambu printers...',
scanningNetwork: 'Scanning network...',
serialRequired: 'Serial required',
unknown: 'Unknown',
failedToStart: 'Failed to start discovery',
},
// Filaments section
filaments: 'Filaments',
// Camera
openCameraOverlay: 'Open camera overlay',
openCameraWindow: 'Open camera in new window',
// Firmware
firmwareUpdateAvailable: 'Firmware update available: {{current}} → {{latest}}',
firmwareUpdateButton: 'Update',
// Plate detection
plateDetection: {
noPermission: 'You do not have permission to update printers',
enabledClick: 'Plate check enabled - Click to disable',
disabledClick: 'Plate check disabled - Click to enable',
manageCalibration: 'Manage plate detection calibration',
calibrationRequired: 'Calibration Required',
calibrationInstructions: 'Please ensure the build plate is completely empty, then click Calibrate.',
calibrationDescription: 'Calibration captures a reference image of the empty plate. Future checks will compare against this reference to detect objects.',
calibrationTip: 'Tip: You can store up to 5 calibrations for different plates. The system automatically uses the best match when checking.',
plateEmpty: 'Plate appears empty',
objectsDetected: 'Objects detected on plate',
confidence: 'Confidence',
difference: 'Difference',
analysisPreview: 'Analysis preview:',
analysisLegend: 'Green box = detection area, Red overlay = differences from calibration',
savedReferences: 'Saved References ({{count}}/{{max}})',
deleteReference: 'Delete reference',
labelPlaceholder: 'Label...',
clickToEdit: '{{label}} - Click to edit',
clickToAddLabel: 'Click to add label',
},
// Fans
fans: {
partCooling: 'Part Cooling Fan',
auxiliary: 'Auxiliary Fan',
chamber: 'Chamber Fan',
},
// HMS errors
clickToViewHmsErrors: 'Click to view HMS errors',
estimatedCompletion: 'Estimated completion time',
slotOptions: 'Slot options',
// Firmware modal
firmwareModal: {
title: 'Firmware Update',
currentVersion: 'Current:',
latestVersion: 'Latest:',
releaseNotes: 'Release Notes',
checkingPrereqs: 'Checking prerequisites...',
sdCardReady: 'SD card ready. Click below to upload firmware.',
uploadedSuccess: 'Firmware uploaded to SD card!',
applyInstructions: 'To apply the update on your printer:',
step1: 'On the printer\'s touchscreen, go to Settings',
step2: 'Navigate to Firmware',
step3: 'Select Update from SD card',
step4: 'The update will take 10-20 minutes',
done: 'Done',
starting: 'Starting...',
uploadFirmware: 'Upload Firmware',
uploadedToast: 'Firmware uploaded! Trigger update from printer screen.',
},
accessCodePlaceholder: 'Leave empty to keep current',
// ROI editor
roi: {
title: 'Detection Area (ROI)',
xStart: 'X Start',
yStart: 'Y Start',
width: 'Width',
height: 'Height',
instruction: 'Adjust the detection area to focus on the build plate. The green box in the preview shows the current area.',
},
},
// Archives page
archives: {
title: 'Print Archives',
searchPlaceholder: 'Search archives...',
filterByPrinter: 'Filter by printer',
filterByStatus: 'Filter by status',
sortBy: 'Sort by',
sortNewest: 'Newest first',
sortOldest: 'Oldest first',
sortName: 'Name',
sortDuration: 'Duration',
sortLargest: 'Largest first',
sortSmallest: 'Smallest first',
sortSize: 'Size',
noArchives: 'No archives found',
noArchivesSearch: 'No archives match your search',
noArchivesYet: 'No archives yet',
loadingArchives: 'Loading archives...',
releaseToUpload: 'Release to upload',
showAll: 'Show all',
showFavoritesOnly: 'Show favorites only',
gridView: 'Grid view',
listView: 'List view',
calendarView: 'Calendar view',
manageTags: 'Manage Tags',
showFailedPrints: 'Show failed prints',
hideFailedPrints: 'Hide failed prints',
printTime: 'Print Time',
filamentUsed: 'Filament Used',
cost: 'Cost',
reprint: 'Reprint',
preview: 'Preview',
deleteArchive: 'Delete Archive',
deleteConfirm: 'Are you sure you want to delete this archive?',
favorite: 'Favorite',
unfavorite: 'Remove from favorites',
viewDetails: 'View Details',
status: {
completed: 'Completed',
failed: 'Failed',
stopped: 'Stopped',
},
toast: {
source3mfAttached: 'Source 3MF attached: {{filename}}',
failedUploadSource3mf: 'Failed to upload source 3MF',
source3mfRemoved: 'Source 3MF removed',
failedRemoveSource3mf: 'Failed to remove source 3MF',
f3dAttached: 'F3D attached: {{filename}}',
failedUploadF3d: 'Failed to upload F3D',
f3dRemoved: 'F3D removed',
failedRemoveF3d: 'Failed to remove F3D',
timelapseAttached: 'Timelapse attached: {{filename}}',
timelapseAlreadyAttached: 'Timelapse already attached',
noMatchingTimelapse: 'No matching timelapse found',
failedScanTimelapse: 'Failed to scan for timelapse',
failedAttachTimelapse: 'Failed to attach timelapse',
archiveDeleted: 'Archive deleted',
failedDeleteArchive: 'Failed to delete archive',
addedToFavorites: 'Added to favorites',
removedFromFavorites: 'Removed from favorites',
projectUpdated: 'Project updated',
failedUpdateProject: 'Failed to update project',
linkCopied: 'Link copied to clipboard',
failedCopyLink: 'Failed to copy link',
photoDeleted: 'Photo deleted',
failedDeletePhoto: 'Failed to delete photo',
failedDeleteArchives: 'Failed to delete archives',
failedUpdateFavorites: 'Failed to update favorites',
exportDownloaded: 'Export downloaded',
exportFailed: 'Export failed',
},
menu: {
print: 'Print',
schedule: 'Schedule',
openInBambuStudio: 'Open in Bambu Studio',
slice: 'Slice',
externalLink: 'External Link',
viewOnMakerWorld: 'View on MakerWorld',
preview3d: '3D Preview',
viewTimelapse: 'View Timelapse',
scanForTimelapse: 'Scan for Timelapse',
downloadSource3mf: 'Download Source 3MF',
uploadSource3mf: 'Upload Source 3MF',
replaceSource3mf: 'Replace Source 3MF',
removeSource3mf: 'Remove Source 3MF',
uploadF3d: 'Upload F3D',
replaceF3d: 'Replace F3D',
downloadF3d: 'Download F3D',
removeF3d: 'Remove F3D',
download: 'Download',
copyDownloadLink: 'Copy Download Link',
qrCode: 'QR Code',
viewPhotos: 'View Photos',
viewPhotosCount: 'View Photos ({{count}})',
projectPage: 'Project Page',
addToFavorites: 'Add to Favorites',
removeFromFavorites: 'Remove from Favorites',
edit: 'Edit',
goToProject: 'Go to Project: {{name}}',
addToProject: 'Add to Project',
removeFromProject: 'Remove from Project',
loading: 'Loading...',
noProjectsAvailable: 'No projects available',
select: 'Select',
deselect: 'Deselect',
delete: 'Delete',
},
permission: {
noReprint: 'You do not have permission to reprint this archive',
noAddToQueue: 'You do not have permission to add to queue',
noUpdateArchives: 'You do not have permission to update archives',
noUploadFiles: 'You do not have permission to upload files',
noDownload: 'You do not have permission to download archives',
noCopyLink: 'You do not have permission to copy download links',
noDelete: 'You do not have permission to delete this archive',
noCreate: 'You do not have permission to create archives',
},
card: {
previousPlate: 'Previous plate',
nextPlate: 'Next plate',
plateNumber: 'Plate {{index}}',
moreOptions: 'Right-click for more options',
addToFavorites: 'Add to favorites',
removeFromFavorites: 'Remove from favorites',
cancelled: 'cancelled',
failed: 'failed',
duplicate: 'duplicate',
duplicateTitle: 'This model has been printed before',
openSource3mf: 'Open source 3MF in Bambu Studio (right-click for more options)',
downloadF3d: 'Download Fusion 360 design file',
viewTimelapse: 'View timelapse',
viewPhoto: 'View 1 photo',
viewPhotos: 'View {{count}} photos',
openFolder: 'Open folder: {{name}}',
slicedFile: 'Sliced file - ready to print',
sourceFile: 'Source file only - no AMS mapping available',
gcode: 'GCODE',
source: 'SOURCE',
project: 'Project: {{name}}',
estimated: 'Estimated: {{time}}',
actual: 'Actual: {{time}}',
accuracy: 'Accuracy: {{percent}}%',
filament: '{{weight}}g',
layer: '{{count}} layer',
layers: '{{count}} layers',
object: '{{count}} object',
objects: '{{count}} objects',
slicedFor: 'Sliced for {{model}}',
uploadedBy: 'Uploaded By',
noPermissionReprint: 'You do not have permission to reprint',
noPermissionEdit: 'You do not have permission to edit archives',
noPermissionDelete: 'You do not have permission to delete archives',
reprint: 'Reprint',
schedulePrint: 'Schedule Print',
schedule: 'Schedule',
openInBambuStudio: 'Open in Bambu Studio',
openInBambuStudioToSlice: 'Open in Bambu Studio to slice',
slice: 'Slice',
externalLink: 'External Link',
makerWorld: 'MakerWorld: {{designer}}',
viewProject: 'View project',
noExternalLink: 'No external link',
preview3d: '3D Preview',
download: 'Download',
edit: 'Edit',
delete: 'Delete',
},
modal: {
deleteArchive: 'Delete Archive',
deleteConfirm: 'Are you sure you want to delete "{{name}}"? This action cannot be undone.',
deleteButton: 'Delete',
removeSource3mf: 'Remove Source 3MF',
removeSource3mfConfirm: 'Are you sure you want to remove the source 3MF file from "{{name}}"? This will delete the original slicer project file.',
removeButton: 'Remove',
removeF3d: 'Remove F3D',
removeF3dConfirm: 'Are you sure you want to remove the Fusion 360 design file from "{{name}}"?',
timelapse: '{{name}} - Timelapse',
selectTimelapse: 'Select Timelapse',
selectTimelapseDesc: 'No auto-match found. Select the timelapse for this print:',
deleteArchives: 'Delete Archives',
deleteArchivesConfirm: 'Are you sure you want to delete {{count}} archive(s)? This action cannot be undone.',
deleteCount: 'Delete {{count}}',
},
page: {
title: 'Archives',
printsCount: '{{filtered}} of {{total}} prints',
dropFilesHere: 'Drop .3mf files here',
releaseToUpload: 'Release to upload',
only3mfSupported: 'Only .3mf files are supported',
close: 'Close',
selected: '{{count}} selected',
selectAll: 'Select All',
tags: 'Tags',
project: 'Project',
favorite: 'Favorite',
delete: 'Delete',
toggledFavorites: 'Toggled favorites for {{count}} archive(s)',
failedUpdateFavorites: 'Failed to update favorites',
archivesDeleted: '{{count}} archive(s) deleted',
failedDeleteArchives: 'Failed to delete archives',
photoDeleted: 'Photo deleted',
failedDeletePhoto: 'Failed to delete photo',
},
list: {
name: 'Name',
printer: 'Printer',
date: 'Date',
size: 'Size',
actions: 'Actions',
hasTimelapse: 'Has timelapse',
},
},
// Queue page
queue: {
title: 'Print Queue',
subtitle: 'Schedule and manage your print jobs',
addToQueue: 'Add to Queue',
// Print modal
print: 'Print',
reprint: 'Re-print',
schedulePrint: 'Schedule Print',
editQueueItem: 'Edit Queue Item',
printToPrinters: 'Print to {{count}} Printers',
queueToPrinters: 'Queue to {{count}} Printers',
sending: 'Sending...',
sendingProgress: 'Sending {{current}}/{{total}}...',
adding: 'Adding...',
addingProgress: 'Adding {{current}}/{{total}}...',
savingProgress: 'Saving {{current}}/{{total}}...',
clearQueue: 'Clear Queue',
clearHistory: 'Clear History',
emptyQueue: 'Queue is empty',
position: 'Position',
scheduledTime: 'Scheduled Time',
moveUp: 'Move Up',
moveDown: 'Move Down',
startNow: 'Start Now',
printingInProgress: 'Printing in progress...',
viewArchive: 'View archive',
viewInFileManager: 'View in File Manager',
itemCount: '{{count}} item',
itemCount_plural: '{{count}} items',
dragToReorder: 'Drag to reorder (ASAP only)',
reorderHint: 'Position only affects ASAP items. Scheduled items run at their set time.',
addedBy: 'Added by {{name}}',
// Sections
sections: {
currentlyPrinting: 'Currently Printing',
queued: 'Queued',
history: 'History',
},
// Status
status: {
pending: 'Pending',
waiting: 'Waiting',
printing: 'Printing',
paused: 'Paused',
completed: 'Completed',
failed: 'Failed',
skipped: 'Skipped',
cancelled: 'Cancelled',
},
// Summary cards
summary: {
printing: 'Printing',
queued: 'Queued',
totalTime: 'Total Queue Time',
history: 'History',
},
// Filters
filter: {
allPrinters: 'All Printers',
unassigned: 'Unassigned',
allStatus: 'All Status',
allLocations: 'All Locations',
any: 'Any',
},
// Sort
sort: {
byPosition: 'Sort by Position',
byName: 'Sort by Name',
byPrinter: 'Sort by Printer',
bySchedule: 'Sort by Schedule',
byDate: 'Sort by Date',
ascendingOldest: 'Ascending (oldest first)',
descendingNewest: 'Descending (newest first)',
},
// Badges
badges: {
staged: 'Staged',
requiresPrevious: 'Requires previous success',
autoPowerOff: 'Auto power off',
},
// Empty state
empty: {
title: 'No prints scheduled',
description: 'Schedule a print from the Archives page using the "Schedule" option in the context menu, or drag and drop files to get started.',
},
// Time
time: {
asap: 'ASAP',
overdue: 'Overdue',
now: 'Now',
lessThanMinute: 'In less than a minute',
inMinutes: 'In {{count}} min',
inHours: 'In {{count}} hours',
},
// Actions
actions: {
stopPrint: 'Stop Print',
startPrint: 'Start Print',
requeue: 'Re-queue',
},
// Bulk edit
bulkEdit: {
title: 'Edit {{count}} Item',
title_plural: 'Edit {{count}} Items',
description: 'Only changed settings will be applied to selected items.',
printer: 'Printer',
noChange: '— No change —',
queueOptions: 'Queue Options',
staged: 'Staged (manual start)',
autoPowerOff: 'Auto power off after print',
requirePrevious: 'Require previous success',
printOptions: 'Print Options',
bedLevelling: 'Bed levelling',
flowCalibration: 'Flow calibration',
vibrationCalibration: 'Vibration calibration',
layerInspection: 'First layer inspection',
timelapse: 'Timelapse',
useAms: 'Use AMS',
applyChanges: 'Apply Changes',
selectAll: 'Select All',
deselectAll: 'Deselect All',
selected: '{{count}} selected',
editSelected: 'Edit Selected',
cancelSelected: 'Cancel Selected',
},
// Confirmations
confirm: {
cancelTitle: 'Cancel Scheduled Print',
cancelMessage: 'Are you sure you want to cancel "{{name}}"?',
stopTitle: 'Stop Print',
stopMessage: 'Are you sure you want to stop the current print "{{name}}"? This will cancel the print job on the printer.',
removeTitle: 'Remove from History',
removeMessage: 'Are you sure you want to remove "{{name}}" from the queue history?',
clearHistoryTitle: 'Clear History',
clearHistoryMessage: 'Are you sure you want to remove all {{count}} item(s) from the history?',
cancelButton: 'Cancel Print',
stopButton: 'Stop Print',
thisPrint: 'this print',
thisItem: 'this item',
},
// Toast messages
toast: {
cancelled: 'Queue item cancelled',
cancelFailed: 'Failed to cancel item',
removed: 'Queue item removed',
removeFailed: 'Failed to remove item',
stopped: 'Print stopped',
stopFailed: 'Failed to stop print',
released: 'Print released to queue',
startFailed: 'Failed to start print',
reorderFailed: 'Failed to reorder queue',
historyCleared: 'Cleared {{count}} history item(s)',
clearHistoryFailed: 'Failed to clear history',
updateFailed: 'Failed to update items',
bulkCancelled: 'Cancelled {{count}} item(s)',
bulkCancelFailed: 'Failed to cancel items',
},
// Permissions
permissions: {
noStopPrint: 'You do not have permission to stop prints',
noStartPrint: 'You do not have permission to start prints',
noEdit: 'You do not have permission to edit this queue item',
noCancel: 'You do not have permission to cancel this queue item',
noRequeue: 'You do not have permission to re-queue items',
noRemove: 'You do not have permission to remove this queue item',
noClearHistory: 'You do not have permission to clear all history',
noEditItems: 'You do not have permission to edit queue items',
noCancelItems: 'You do not have permission to cancel queue items',
},
},
// Statistics page
stats: {
title: 'Dashboard',
subtitle: 'Drag widgets to rearrange. Click the eye icon to hide.',
overview: 'Overview',
totalPrints: 'Total Prints',
successRate: 'Success Rate',
totalPrintTime: 'Total Print Time',
printTime: 'Print Time',
totalFilament: 'Total Filament Used',
filamentUsed: 'Filament Used',
filamentCost: 'Filament Cost',
totalCost: 'Total Cost',
energyUsed: 'Energy Used',
energyCost: 'Energy Cost',
averagePrintTime: 'Average Print Time',
printsPerDay: 'Prints per Day',
byPrinter: 'By Printer',
printsByPrinter: 'Prints by Printer',
byMaterial: 'By Material',
byMonth: 'By Month',
last7Days: 'Last 7 Days',
last30Days: 'Last 30 Days',
last90Days: 'Last 90 Days',
allTime: 'All Time',
// Widgets
quickStats: 'Quick Stats',
printActivity: 'Print Activity',
filamentTypes: 'Filament Types',
filamentTrends: 'Filament Trends',
failureAnalysis: 'Failure Analysis',
timeAccuracy: 'Time Accuracy',
successful: 'Successful:',
failed: 'Failed:',
perfectEstimate: '100% = perfect estimate',
noTimeAccuracyData: 'No time accuracy data yet',
noFilamentData: 'No filament data available',
noPrinterData: 'No printer data available',
noPrintData: 'No print data available',
noPrintDataLast30Days: 'No print data in the last 30 days',
failureReasons: 'Failure Reasons',
topFailureReasons: 'Top Failure Reasons',
failedPrintsCount: '{{failed}} / {{total}} prints failed',
lastWeekRate: 'Last week: {{rate}}%',
// Actions
resetLayout: 'Reset Layout',
recalculateCosts: 'Recalculate Costs',
recalculateCostsHint: 'Recalculate all archive costs using current filament prices',
exportStats: 'Export Stats',
exportAsCsv: 'Export as CSV',
exportAsExcel: 'Export as Excel',
hiddenCount: '{{count}} Hidden',
// Toast
exportDownloaded: 'Export downloaded',
exportFailed: 'Export failed',
layoutReset: 'Layout reset',
recalculatedCosts: 'Recalculated costs for {{count}} archives',
recalculateFailed: 'Failed to recalculate costs',
// Loading
loadingStats: 'Loading statistics...',
// Permissions
noPermissionResetLayout: 'You do not have permission to reset layout',
noPermissionRecalculate: 'You do not have permission to recalculate costs',
},
// Maintenance page
maintenance: {
title: 'Maintenance',
overview: 'Overview',
allOk: 'All maintenance up to date',
dueCount: '{{count}} item due',
dueCount_plural: '{{count}} items due',
warningCount: '{{count}} warning',
warningCount_plural: '{{count}} warnings',
totalPrintTime: 'Total Print Time',
nextMaintenance: 'Next Maintenance',
nothingDue: 'Nothing due',
tasks: 'Tasks',
lastPerformed: 'Last performed',
interval: 'Interval',
hoursRemaining: '{{hours}}h remaining',
hoursOverdue: '{{hours}}h overdue',
markDone: 'Mark as Done',
performMaintenance: 'Perform Maintenance',
history: 'History',
noHistory: 'No maintenance history',
editPrintHours: 'Edit Print Hours',
currentHours: 'Current Hours',
// Tabs
statusTab: 'Status',
settingsTab: 'Settings',
// Status
overdueCount: '{{count}} overdue',
dueSoonCount: '{{count}} due soon',
dueSoon: 'Due soon',
allGood: 'All good',
overdueBy: 'Overdue by {{duration}}',
dueIn: 'Due in {{duration}}',
timeLeft: '{{duration}} left',
// Duration formats
day: '1 day',
days: '{{count}} days',
week: '1 week',
weeks: '{{count}} weeks',
month: '1 month',
months: '{{count}} months',
year: '1 year',
// Settings
maintenanceTypes: 'Maintenance Types',
maintenanceTypesDescription: 'System types and your custom maintenance tasks',
addCustomType: 'Add Custom Type',
intervalType: 'Interval Type',
intervalValue: 'Interval ({{type}})',
icon: 'Icon',
documentationLink: 'Documentation Link (optional)',
assignToPrinters: 'Assign to Printers',
selectAtLeastOnePrinter: 'Select at least one printer',
addType: 'Add Type',
custom: 'Custom',
printHours: 'Print Hours',
calendarDays: 'Calendar Days',
exampleName: 'e.g., Replace HEPA Filter',
viewDocumentation: 'View documentation',
timeBasedInterval: 'Time-based interval',
// Interval overrides
intervalOverrides: 'Interval Overrides',
intervalOverridesDescription: 'Customize intervals for specific printers',
// Printer assignment
assignedToPrinters: 'Assigned to printers:',
noPrintersAssigned: 'No printers assigned',
addPrinterShort: 'Add:',
printersAssignedClick: '{{count}} printer(s) assigned - click to manage',
removeFromPrinter: 'Remove from this printer',
// Types
types: {
lubricateRails: 'Lubricate Linear Rails',
cleanNozzle: 'Clean Nozzle/Hotend',
checkBelts: 'Check Belt Tension',
cleanBuildPlate: 'Clean Build Plate',
checkExtruder: 'Check Extruder Gears',
checkCooling: 'Check Cooling Fans',
generalInspection: 'General Inspection',
cleanCarbonRods: 'Clean Carbon Rods',
checkPtfeTube: 'Check PTFE Tube',
replaceHepaFilter: 'Replace HEPA Filter',
replaceCarbonFilter: 'Replace Carbon Filter',
lubricateLeftNozzleRail: 'Lubricate Left Nozzle Rail',
},
// Toast
maintenanceComplete: 'Maintenance marked as complete',
typeUpdated: 'Maintenance type updated',
typeDeleted: 'Maintenance type deleted',
printHoursUpdated: 'Print hours updated',
printerAssigned: 'Printer assigned',
printerRemoved: 'Printer removed',
// Confirmation
deleteTypeConfirm: 'Delete "{{name}}"?',
// Permissions
noPermissionUpdate: 'You do not have permission to update maintenance items',
noPermissionPerform: 'You do not have permission to perform maintenance',
noPermissionEditTypes: 'You do not have permission to edit maintenance types',
noPermissionDeleteTypes: 'You do not have permission to delete maintenance types',
noPermissionEditHours: 'You do not have permission to edit print hours',
noPermissionRemovePrinter: 'You do not have permission to remove printer assignments',
noPermissionAssignPrinter: 'You do not have permission to assign printers',
noPermissionEditIntervals: 'You do not have permission to edit intervals',
// Configure link
configureSettings: 'Configure maintenance types and intervals',
},
// Settings page
settings: {
title: 'Settings',
general: 'General',
// Tab names
tabs: {
general: 'General',
smartPlugs: 'Smart Plugs',
notifications: 'Notifications',
filament: 'Filament',
network: 'Network',
apiKeys: 'API Keys',
virtualPrinter: 'Virtual Printer',
users: 'Users',
backup: 'Backup',
},
appearance: 'Appearance',
notifications: 'Notifications',
smartPlugs: 'Smart Plugs',
spoolman: 'Spoolman',
updates: 'Updates',
language: 'Language',
languageDescription: 'Select your preferred language',
theme: 'Theme',
themeLight: 'Light',
themeDark: 'Dark',
themeSystem: 'System',
defaultView: 'Default View',
defaultViewDescription: 'Page to show when opening the app',
checkForUpdates: 'Check for Updates',
autoUpdate: 'Auto Update',
currentVersion: 'Current Version',
latestVersion: 'Latest Version',
upToDate: 'You are up to date',
updateAvailable: 'Update available',
// Notifications
notificationLanguage: 'Notification Language',
notificationLanguageDescription: 'Language for push notifications',
notificationProviders: 'Notification Providers',
addProvider: 'Add Provider',
editProvider: 'Edit Provider',
providerType: 'Provider Type',
testNotification: 'Test Notification',
testSuccess: 'Test notification sent successfully',
testFailed: 'Failed to send test notification',
quietHours: 'Quiet Hours',
quietHoursDescription: 'Do not disturb during these hours',
quietHoursStart: 'Start',
quietHoursEnd: 'End',
events: {
title: 'Notification Events',
printStart: 'Print Started',
printComplete: 'Print Completed',
printFailed: 'Print Failed',
printStopped: 'Print Stopped',
printProgress: 'Progress Milestones',
printProgressDescription: 'Notify at 25%, 50%, 75%',
printerOffline: 'Printer Offline',
printerError: 'Printer Error',
filamentLow: 'Low Filament',
maintenanceDue: 'Maintenance Due',
maintenanceDueDescription: 'Notify when maintenance is needed',
},
// Smart Plugs
smartPlug: {
title: 'Smart Plugs',
add: 'Add Smart Plug',
edit: 'Edit Smart Plug',
name: 'Name',
ipAddress: 'IP Address',
linkedPrinter: 'Linked Printer',
autoOn: 'Auto Power On',
autoOnDescription: 'Turn on when print starts',
autoOff: 'Auto Power Off',
autoOffDescription: 'Turn off after print completes',
offDelay: 'Off Delay',
offDelayMinutes: 'Minutes after print',
offDelayTemp: 'When nozzle below temperature',
currentState: 'Current State',
turnOn: 'Turn On',
turnOff: 'Turn Off',
},
// Spoolman
spoolmanEnabled: 'Enable Spoolman Integration',
spoolmanUrl: 'Spoolman URL',
spoolmanConnected: 'Connected',
spoolmanDisconnected: 'Disconnected',
// Default printer
noDefaultPrinter: 'No default (ask each time)',
// Sidebar
sidebarOrder: 'Sidebar order',
// Camera
saveThumbnails: 'Save thumbnails',
captureFinishPhoto: 'Capture finish photo',
noPrintersConfigured: 'No printers configured',
// Archive settings
archiveMode: {
always: 'Always create archive entry',
never: 'Never create archive entry',
ask: 'Ask each time',
},
// Updates
checkForUpdatesLabel: 'Check for updates',
checkPrinterFirmware: 'Check printer firmware',
// Queue
enableRetry: 'Enable retry',
// Home Assistant
homeAssistantDescription: 'Control smart plugs via Home Assistant',
environmentManagedLabel: '(Environment Managed)',
autoEnabledViaEnv: 'Automatically enabled via environment variables',
urlFromEnvReadOnly: 'Value set by HA_URL environment variable (read-only)',
tokenFromEnvReadOnly: 'Value set by HA_TOKEN environment variable (read-only)',
// MQTT
mqttConnectedTo: 'Connected to',
// Prometheus
prometheusDescription: 'Expose printer data in Prometheus format',
// Smart plugs empty state
noSmartPlugsTitle: 'No smart plugs configured',
noSmartPlugsDescription: 'Add a Tasmota-based smart plug to track energy usage and automate power control.',
// Notifications empty state
noProvidersTitle: 'No providers configured',
noProvidersDescription: 'Add a provider to receive alerts.',
noTemplatesAvailable: 'No templates available. Restart the backend to seed default templates.',
// API permissions
apiPermissionView: 'View printer status and queue',
apiPermissionEdit: 'Add and remove items from print queue',
// API keys
apiKeysEmptyTitle: 'No API keys',
apiKeysEmptyDescription: 'Create an API key to integrate with external services.',
// Users
noUsersFound: 'No users found',
noGroupsFound: 'No groups found',
noGroupsAvailable: 'No groups available',
passwordsDoNotMatch: 'Passwords do not match',
systemGroupWarning: 'System group names cannot be changed',
// Auth disabled
authDisabledTitle: 'Authentication is Disabled',
authDisabledFeature1: 'Require login to access the system',
authDisabledFeature2: 'Create multiple users with group-based permissions',
authDisabledFeature3: 'Control access with 50+ granular permissions',
// User deletion
userHasCreated: 'This user has created:',
userItemsQuestion: 'What would you like to do with these items?',
deleteUserConfirm: 'Are you sure you want to delete this user?',
actionCannotBeUndone: 'This action cannot be undone.',
// Smart plugs
addFirstSmartPlug: 'Add Your First Smart Plug',
// Notifications
providers: 'Providers',
log: 'Log',
testAll: 'Test All',
testResults: 'Test Results',
testPassedCount: '{{count}} passed',
testFailedCount: '{{count}} failed',
messageTemplates: 'Message Templates',
messageTemplatesDescription: 'Customize notification messages for each event.',
// API Keys section
apiKeys: 'API Keys',
apiKeysDescription: 'Create API keys for external integrations and webhooks.',
createKey: 'Create Key',
apiKeyCreated: 'API Key Created Successfully',
apiKeyCopyWarning: "Copy this key now - it won't be shown again!",
useInApiBrowser: 'Use in API Browser',
createNewApiKey: 'Create New API Key',
keyName: 'Key Name',
keyNamePlaceholder: 'e.g., Home Assistant, OctoPrint',
readStatus: 'Read Status',
readStatusDescription: 'View printer status and queue',
manageQueue: 'Manage Queue',
manageQueueDescription: 'Add and remove items from print queue',
controlPrinter: 'Control Printer',
controlPrinterDescription: 'Pause, resume, and stop prints',
unnamedKey: 'Unnamed Key',
lastUsed: 'Last used',
read: 'Read',
control: 'Control',
createFirstKey: 'Create Your First Key',
webhookEndpoints: 'Webhook Endpoints',
webhookApiKeyHint: 'Use your API key in the X-API-Key header.',
webhook: {
getAllStatus: 'Get all printer status',
getSpecificStatus: 'Get specific printer status',
addToQueue: 'Add to print queue',
pausePrint: 'Pause print',
resumePrint: 'Resume print',
stopPrint: 'Stop print',
},
apiBrowser: 'API Browser',
apiBrowserDescription: 'Explore and test all available API endpoints.',
apiKeyForTesting: 'API Key for Testing',
apiKeyPlaceholder: 'Paste your API key here to test authenticated endpoints...',
apiKeyHint: 'This key will be sent as X-API-Key header with requests.',
deleteApiKeyTitle: 'Delete API Key',
deleteApiKeyMessage: 'Are you sure you want to delete this API key? Any integrations using this key will stop working.',
deleteKey: 'Delete Key',
// Filament tab
amsDisplayThresholds: 'AMS Display Thresholds',
amsThresholdsDescription: 'Configure color thresholds for AMS humidity and temperature indicators.',
humidity: 'Humidity',
goodGreen: 'Good (green)',
fairOrange: 'Fair (orange)',
aboveFairBad: 'Above fair threshold shows as red (bad)',
temperature: 'Temperature',
goodBlue: 'Good (blue)',
aboveFairHot: 'Above fair threshold shows as red (hot)',
historyRetention: 'History Retention',
keepSensorHistory: 'Keep sensor history for',
historyRetentionDescription: 'Older humidity and temperature data will be automatically deleted',
printModal: 'Print Modal',
expandCustomMapping: 'Expand custom mapping by default',
expandCustomMappingDescription: 'When printing to multiple printers, show per-printer AMS mapping expanded',
// User management
authentication: 'Authentication',
authEnabledDescription: 'Your instance is secured with user authentication',
authDisabledDescription: 'Enable to require login and manage user access',
authDisabledMessage: 'Enable authentication to create user accounts, manage permissions, and secure your Bambuddy instance.',
enableAuthentication: 'Enable Authentication',
currentUser: 'Current User',
changePassword: 'Change Password',
admin: 'Admin',
users: 'Users',
addUser: 'Add User',
groups: 'Groups',
addGroup: 'Add Group',
system: 'System',
noDescription: 'No description',
userCount: '{{count}} users',
permissionCount: '{{count}} permissions',
createUser: 'Create User',
username: 'Username',
enterUsername: 'Enter username',
password: 'Password',
enterPassword: 'Enter password (min 6 characters)',
confirmPassword: 'Confirm Password',
confirmPasswordPlaceholder: 'Confirm password',
// Title tooltips
viewReleaseOnGitHub: 'View release on GitHub',
turnAllPlugsOn: 'Turn all plugs on',
turnAllPlugsOff: 'Turn all plugs off',
// Modal: Clear logs
clearNotificationLogs: 'Clear Notification Logs',
clearLogsMessage: 'This will permanently delete all notification logs older than 30 days. This action cannot be undone.',
clearLogs: 'Clear Logs',
// Modal: Reset UI
resetUiPreferences: 'Reset UI Preferences',
resetUiPreferencesMessage: 'This will reset all UI preferences to defaults: sidebar order, theme, dashboard layout, view modes, and sorting preferences. Your printers, archives, and server settings will NOT be affected. The page will reload after clearing.',
resetPreferences: 'Reset Preferences',
// Modal: Delete group
deleteGroupTitle: 'Delete Group',
deleteGroupMessage: 'Are you sure you want to delete this group? Users in this group will lose these permissions.',
deleteGroup: 'Delete Group',
// Modal: Disable auth
disableAuthenticationTitle: 'Disable Authentication',
disableAuthenticationMessage: 'Are you sure you want to disable authentication? This will make your Bambuddy instance accessible without login. All users will remain in the database but authentication will be disabled.',
disableAuthentication: 'Disable Authentication',
// Additional settings
configureBambuddy: 'Configure Bambuddy',
systemDefault: 'System Default',
archiveSettings: 'Archive Settings',
newWindow: 'New Window',
embeddedOverlay: 'Embedded Overlay',
externalCameras: 'External Cameras',
costTracking: 'Cost Tracking',
printsOnly: 'Prints Only',
totalConsumption: 'Total Consumption',
dataManagement: 'Data Management',
clearNotificationLogsDescription: 'Delete notification logs older than 30 days',
resetUiPreferencesDescription: 'Reset sidebar order, theme, view modes, and layout preferences. Printers, archives, and settings are not affected.',
enableHomeAssistant: 'Enable Home Assistant',
enableMqtt: 'Enable MQTT',
useTls: 'Use TLS',
enableMetricsEndpoint: 'Enable Metrics Endpoint',
availableMetrics: 'Available Metrics',
editUser: 'Edit User',
deleteUserTitle: 'Delete User',
groupName: 'Group Name',
// Placeholders
leaveEmptyForAnonymous: 'Leave empty for anonymous',
leaveEmptyForNoAuth: 'Leave empty for no authentication',
enterNewPassword: 'Enter new password',
confirmNewPassword: 'Confirm new password',
enterGroupName: 'Enter group name',
enterDescriptionOptional: 'Enter description (optional)',
enterCurrentPassword: 'Enter current password',
enterNewPasswordMin6: 'Enter new password (min 6 characters)',
toast: {
keyCopied: 'Key copied to clipboard',
copyFailed: 'Failed to copy key',
keyAddedToBrowser: 'Key added to API Browser',
clearLogsFailed: 'Failed to clear logs',
uiPreferencesReset: 'UI preferences reset. Refreshing...',
authDisabled: 'Authentication disabled successfully',
authDisableFailed: 'Failed to disable authentication',
apiKeyCreated: 'API key created',
apiKeyDeleted: 'API key deleted',
userCreated: 'User created successfully',
userUpdated: 'User updated successfully',
userDeleted: 'User deleted successfully',
groupCreated: 'Group created successfully',
groupUpdated: 'Group updated successfully',
groupDeleted: 'Group deleted successfully',
fillRequiredFields: 'Please fill in all required fields',
passwordsDoNotMatch: 'Passwords do not match',
passwordTooShort: 'Password must be at least 6 characters',
enterGroupName: 'Please enter a group name',
settingsSaved: 'Settings saved',
cameraSettingsSaved: 'Camera settings saved',
enterCameraUrl: 'Please enter a camera URL',
passwordChanged: 'Password changed successfully',
connectionFailed: 'Connection failed',
testFailed: 'Test failed',
cameraConnected: 'Camera connected{{resolution}}',
},
testConnection: 'Test Connection',
},
// Notifications (for push notifications)
notification: {
printStarted: {
title: 'Print Started',
body: '{{printer}}: {{filename}} has started printing',
},
printCompleted: {
title: 'Print Completed',
body: '{{printer}}: {{filename}} completed successfully',
},
printFailed: {
title: 'Print Failed',
body: '{{printer}}: {{filename}} has failed',
},
printStopped: {
title: 'Print Stopped',
body: '{{printer}}: {{filename}} was stopped',
},
printProgress: {
title: 'Print Progress',
body: '{{printer}}: {{filename}} is {{percent}}% complete',
},
printerOffline: {
title: 'Printer Offline',
body: '{{printer}} is offline',
},
printerError: {
title: 'Printer Error',
body: '{{printer}}: {{error}}',
},
filamentLow: {
title: 'Low Filament',
body: '{{printer}}: Filament is running low',
},
maintenanceDue: {
title: 'Maintenance Due',
body: '{{printer}}: {{items}} need attention',
},
},
// Errors
errors: {
generic: 'Something went wrong',
networkError: 'Network error. Please check your connection.',
notFound: 'Not found',
unauthorized: 'Unauthorized',
serverError: 'Server error',
validationError: 'Please check your input',
printerConnectionFailed: 'Failed to connect to printer',
saveFailed: 'Failed to save changes',
deleteFailed: 'Failed to delete',
loadFailed: 'Failed to load data',
},
// HMS Errors modal
hmsErrors: {
title: 'Errors - {{name}}',
noErrors: 'No errors',
viewOnWiki: 'View on Bambu Lab Wiki',
clearInstructions: 'Clear errors on the printer to dismiss them here.',
},
// MQTT Debug modal
mqttDebug: {
title: 'MQTT Debug Log',
searchPlaceholder: 'Search topic or payload...',
noMessages: 'No messages logged yet',
startLoggingHint: 'Click "Start Logging" to begin capturing MQTT messages',
noMessagesMatch: 'No messages match your filter',
adjustFilterHint: 'Try adjusting your search or filter criteria',
incoming: 'Incoming',
outgoing: 'Outgoing',
loggingStopped: 'Logging stopped',
loggingActive: 'Logging active - messages will auto-refresh',
startLogging: 'Start Logging',
stopLogging: 'Stop Logging',
clearLog: 'Clear Log',
topic: 'Topic',
timestamp: 'Timestamp',
direction: 'Direction',
all: 'All',
},
// Printer File Manager modal (printer internal storage)
printerFiles: {
title: 'File Manager',
storageUsed: 'Used:',
storageFree: 'Free:',
filterPlaceholder: 'Filter files...',
deleteButton: 'Delete',
deleteFiles: 'Delete {{count}} Files',
deleteFileConfirm: 'Delete "{{name}}"? This cannot be undone.',
deleteFilesConfirm: 'Delete {{count}} selected files? This cannot be undone.',
noFiles: 'No files on printer',
loadingFiles: 'Loading files...',
failedToLoad: 'Failed to load files',
toast: {
filesDeleted: 'Deleted {{count}} file(s)',
deleteFailed: 'Delete failed: {{error}}',
},
},
// Confirmations
confirm: {
delete: 'Are you sure you want to delete this?',
unsavedChanges: 'You have unsaved changes. Are you sure you want to leave?',
clearQueue: 'Are you sure you want to clear the queue?',
},
// Login page
login: {
title: 'Bambuddy Login',
subtitle: 'Sign in to your account',
username: 'Username',
usernamePlaceholder: 'Enter your username',
password: 'Password',
passwordPlaceholder: 'Enter your password',
signIn: 'Sign in',
signingIn: 'Logging in...',
forgotPassword: 'Forgot your password?',
loginSuccess: 'Logged in successfully',
loginFailed: 'Login failed',
enterCredentials: 'Please enter username and password',
forgotPasswordTitle: 'Forgot Password',
forgotPasswordMessage: "If you've forgotten your password, please contact your system administrator to reset it.",
howToReset: 'How to reset your password:',
resetStep1: 'Contact your Bambuddy administrator',
resetStep2: 'Ask them to reset your password in User Management',
resetStep3: 'They can set a new temporary password for you',
resetStep4: 'Log in with the new password and change it in Settings',
gotIt: 'Got it',
},
// Setup page
setup: {
title: 'Bambuddy Setup',
subtitle: 'Configure authentication for your Bambuddy instance',
enableAuth: 'Enable Authentication',
adminAccount: 'Admin Account',
adminAccountDesc: 'If admin users already exist, authentication will be enabled using the existing admin accounts. Leave the fields below empty to use existing admins, or enter new credentials to create a new admin user.',
adminUsername: 'Admin Username',
adminPassword: 'Admin Password',
optionalIfAdminExists: '(optional if admin users exist)',
adminUsernamePlaceholder: 'Enter admin username (optional)',
adminPasswordPlaceholder: 'Enter admin password (optional)',
confirmPassword: 'Confirm Password',
confirmPasswordPlaceholder: 'Confirm admin password',
settingUp: 'Setting up...',
completeSetup: 'Complete Setup',
toast: {
authEnabledAdminCreated: 'Authentication enabled and admin user created',
authEnabledExistingAdmins: 'Authentication enabled using existing admin users',
setupCompleted: 'Setup completed',
enterBothCredentials: 'Please enter both admin username and password, or leave both empty to use existing admin users',
passwordsDoNotMatch: 'Passwords do not match',
passwordTooShort: 'Password must be at least 6 characters',
},
},
// Password change
changePassword: {
title: 'Change Password',
currentPassword: 'Current Password',
currentPasswordPlaceholder: 'Enter current password',
newPassword: 'New Password',
newPasswordPlaceholder: 'Enter new password (min 6 characters)',
confirmPassword: 'Confirm New Password',
confirmPasswordPlaceholder: 'Confirm new password',
passwordsDoNotMatch: 'Passwords do not match',
passwordTooShort: 'Password must be at least 6 characters',
changing: 'Changing...',
success: 'Password changed successfully',
failed: 'Failed to change password',
},
// Plate detection alert
plateAlert: {
title: 'Print Paused!',
message: 'Objects detected on build plate. The print has been automatically paused. Please clear the plate and resume the print.',
understand: 'I Understand',
},
// Camera page
camera: {
title: 'Camera View',
invalidPrinterId: 'Invalid printer ID',
live: 'Live',
snapshot: 'Snapshot',
restartStream: 'Restart stream',
refreshSnapshot: 'Refresh snapshot',
fullscreen: 'Fullscreen',
exitFullscreen: 'Exit fullscreen',
connectingToCamera: 'Connecting to camera...',
capturingSnapshot: 'Capturing snapshot...',
connectionLost: 'Connection lost',
connectionFailed: 'Camera connection failed',
reconnecting: 'Reconnecting in {{countdown}}s... (attempt {{attempt}}/{{max}})',
reconnectNow: 'Reconnect now',
cameraUnavailable: 'Camera unavailable',
cameraUnavailableDesc: 'Make sure the printer is powered on and connected.',
noCamera: 'No camera available',
retry: 'Retry',
cameraStream: 'Camera stream',
zoomOut: 'Zoom out',
zoomIn: 'Zoom in',
resetZoom: 'Reset zoom',
recording: 'Recording',
startRecording: 'Start Recording',
stopRecording: 'Stop Recording',
chamberLight: 'Toggle chamber light',
},
// Groups management
groups: {
title: 'Group Management',
subtitle: 'Manage permission groups for access control',
backToSettings: 'Back to Settings',
createGroup: 'Create Group',
noPermission: 'You do not have permission to access this page.',
system: 'System',
noDescription: 'No description',
usersCount: '{{count}} users',
permissionsCount: '{{count}} permissions',
edit: 'Edit',
delete: 'Delete',
toast: {
created: 'Group created successfully',
updated: 'Group updated successfully',
deleted: 'Group deleted successfully',
enterGroupName: 'Please enter a group name',
},
modal: {
editGroup: 'Edit Group',
createGroup: 'Create Group',
cancel: 'Cancel',
saving: 'Saving...',
creating: 'Creating...',
saveChanges: 'Save Changes',
},
form: {
groupName: 'Group Name',
groupNamePlaceholder: 'Enter group name',
systemGroupWarning: 'System group names cannot be changed',
description: 'Description',
descriptionPlaceholder: 'Enter description (optional)',
permissions: 'Permissions ({{count}} selected)',
},
deleteModal: {
title: 'Delete Group',
message: 'Are you sure you want to delete this group? Users in this group will lose these permissions.',
confirm: 'Delete Group',
},
},
// Users management
users: {
title: 'User Management',
subtitle: 'Manage users and their access to your Bambuddy instance',
backToSettings: 'Back to Settings',
createUser: 'Create User',
noPermission: 'You do not have permission to access this page.',
admin: 'Admin',
noGroups: 'No groups',
active: 'Active',
inactive: 'Inactive',
edit: 'Edit',
delete: 'Delete',
system: 'System',
noGroupsAvailable: 'No groups available',
table: {
username: 'Username',
groups: 'Groups',
status: 'Status',
actions: 'Actions',
},
toast: {
created: 'User created successfully',
updated: 'User updated successfully',
deleted: 'User deleted successfully',
fillRequired: 'Please fill in all required fields',
passwordsDoNotMatch: 'Passwords do not match',
passwordTooShort: 'Password must be at least 6 characters',
},
modal: {
createUser: 'Create User',
editUser: 'Edit User',
cancel: 'Cancel',
creating: 'Creating...',
saving: 'Saving...',
saveChanges: 'Save Changes',
},
form: {
username: 'Username',
usernamePlaceholder: 'Enter username',
password: 'Password',
passwordPlaceholder: 'Enter password',
confirmPassword: 'Confirm Password',
confirmPasswordPlaceholder: 'Confirm password',
newPasswordPlaceholder: 'Enter new password',
confirmNewPasswordPlaceholder: 'Confirm new password',
leaveBlankToKeep: 'leave blank to keep current',
groups: 'Groups',
},
deleteModal: {
title: 'Delete User',
message: 'Are you sure you want to delete this user? This action cannot be undone.',
confirm: 'Delete User',
},
},
// Stream overlay
streamOverlay: {
title: 'Stream Overlay',
invalidPrinterId: 'Invalid printer ID',
cameraStream: 'Camera stream',
progress: 'Progress',
eta: 'ETA',
tomorrow: 'Tomorrow',
printerIdle: 'Printer is idle',
printerOffline: 'Printer offline',
status: {
printing: 'Printing',
paused: 'Paused',
finished: 'Finished',
failed: 'Failed',
idle: 'Idle',
unknown: 'Unknown',
},
},
// Profiles
profiles: {
title: 'Profiles',
subtitle: 'Manage your slicer presets and pressure advance calibrations',
tabs: {
cloud: 'Cloud Profiles',
kprofiles: 'K-Profiles',
},
connectedAs: 'Connected as',
logout: 'Logout',
noLogoutPermission: 'You do not have permission to logout',
failedToLoad: 'Failed to load profiles',
retry: 'Retry',
time: {
justNow: 'Just now',
minsAgo: '{{count}}m ago',
hoursAgo: '{{count}}h ago',
daysAgo: '{{count}}d ago',
},
toast: {
loggedOut: 'Logged out',
},
login: {
title: 'Connect to Bambu Cloud',
subtitle: 'Sync your slicer presets across devices',
email: 'Email',
password: 'Password',
region: 'Region',
regionGlobal: 'Global',
regionChina: 'China',
verificationCode: 'Verification Code',
totpCode: 'Authenticator Code',
checkEmail: 'Check your email ({{email}}) for a 6-digit code',
enterTotpHint: 'Enter the 6-digit code from your authenticator app',
accessToken: 'Access Token',
accessTokenHint: 'Paste your Bambu Lab access token (from Bambu Studio)',
back: 'Back',
loginButton: 'Login',
verifyButton: 'Verify',
setTokenButton: 'Set Token',
useToken: 'Use access token instead',
useEmail: 'Login with email instead',
toast: {
loggedIn: 'Logged in successfully',
codeSent: 'Verification code sent to your email',
enterTotp: 'Enter code from your authenticator app',
tokenSet: 'Token set successfully',
},
},
presets: {
myPreset: 'My preset (editable)',
duplicate: 'Duplicate',
editable: 'Editable',
failedToLoadDetails: 'Failed to load preset details',
deleteConfirm: 'Delete this preset?',
deleteWarning: 'This will permanently delete "{{name}}" from Bambu Cloud. This cannot be undone.',
noDuplicatePermission: 'You do not have permission to duplicate presets',
noEditPermission: 'You do not have permission to edit presets',
noDeletePermission: 'You do not have permission to delete presets',
types: {
filament: 'Filament preset',
printer: 'Printer preset',
process: 'Process preset',
},
toast: {
deleted: 'Preset deleted',
created: 'Preset created',
updated: 'Preset updated',
duplicated: 'Preset duplicated',
fieldAdded: 'Field "{{key}}" added',
exported: 'Preset exported',
},
baseLabel: 'Base: {{name}}',
currentLabel: 'Current: {{name}}',
newPreset: 'New Preset',
editPreset: 'Edit Preset',
duplicatePreset: 'Duplicate Preset',
createNewPreset: 'Create New Preset',
customizeSettings: 'Customize settings for your new preset',
compareWithBase: 'Compare with base preset',
compare: 'Compare',
// CreatePresetModal - Basic Info
basePreset: 'Base Preset',
selectBasePreset: 'Select base preset...',
presetName: 'Preset Name',
myCustomPreset: 'My custom preset',
inheritsFrom: 'Inherits from',
dropJsonToImport: 'Drop JSON to import',
// CreatePresetModal - Tabs
tabs: {
common: 'Common',
allFields: 'All Fields',
},
// CreatePresetModal - All Fields Tab
availableFields: 'Available Fields',
searchFieldsPlaceholder: 'Search fields...',
noMatchingFields: 'No matching fields',
allFieldsAdded: 'All fields added',
addCustomField: 'Add custom field',
yourOverrides: 'Your Overrides',
noOverridesYet: 'No overrides yet',
clickFieldsToAdd: 'Click fields on the left to add them',
saveAsTemplate: 'Save as template',
jsonTip: 'Tip: Drag & drop a .json file anywhere on this modal to import settings',
},
cloudView: {
searchPlaceholder: 'Search presets...',
templates: 'Templates',
refresh: 'Refresh',
newPreset: 'New Preset',
clearFilters: 'Clear filters',
// Compare mode
compareMode: 'Compare Mode',
selectAnotherPreset: 'Select another {{type}} preset',
clickTwoPresets: 'Click two presets of the same type to compare',
selectFirst: '1. Select first',
selectSecond: '2. Select second',
compareNow: 'Compare Now',
// Status row
lastSynced: 'Last synced:',
showingCount: 'Showing {{showing}} of {{total}} presets',
noPresetsFound: 'No presets found',
// Column headers
columns: {
filament: 'Filament',
process: 'Process',
printer: 'Printer',
},
noFilamentPresets: 'No filament presets',
noProcessPresets: 'No process presets',
noPrinterPresets: 'No printer presets',
// Filters
filters: {
type: 'Type',
owner: 'Owner',
printer: 'Printer',
nozzle: 'Nozzle',
filament: 'Filament',
layer: 'Layer',
all: 'All',
myPresets: 'My Presets',
builtIn: 'Built-in',
process: 'Process',
},
// Permissions
noTemplatesPermission: 'You do not have permission to manage templates',
noRefreshPermission: 'You do not have permission to refresh profiles',
noCreatePermission: 'You do not have permission to create presets',
},
templates: {
title: 'Quick Templates',
noTemplates: 'No templates yet',
createFirst: 'Create templates from the preset editor',
typeFilter: 'Type:',
deleteTitle: 'Delete Template',
deleteWarning: 'This action cannot be undone',
deleteConfirm: 'Are you sure you want to delete "{{name}}"?',
namePlaceholder: 'Template name',
descriptionPlaceholder: 'Description',
settingsJson: 'Settings (JSON)',
fieldsCount: '{{count}} fields',
shownInModals: 'Shown in modals',
hiddenInModals: 'Hidden in modals',
apply: 'Apply',
toast: {
deleted: 'Template deleted',
updated: 'Template updated',
created: 'Template created',
applied: 'Template applied',
},
},
},
// Support/Debug
support: {
debugLoggingActive: 'Debug logging is active',
manageLogs: 'Manage',
},
// File manager
fileManager: {
title: 'File Manager',
subtitle: 'Organize and manage your print files',
uploadFiles: 'Upload Files',
newFolder: 'New Folder',
folderName: 'Folder Name',
folderNamePlaceholder: 'e.g., Functional Parts',
renameFile: 'Rename File',
renameFolder: 'Rename Folder',
moveFiles: 'Move {{count}} File(s)',
rootNoFolder: 'Root (No Folder)',
current: 'current',
linkFolder: 'Link Folder',
linkFolderDescription: 'Link "{{name}}" to a project or archive for quick access.',
project: 'Project',
archive: 'Archive',
noProjectsFound: 'No projects found',
noArchivesFound: 'No archives found',
unlink: 'Unlink',
link: 'Link',
dragDropFiles: 'Drag & drop files here',
dropFilesHere: 'Drop files here',
orClickToBrowse: 'or click to browse',
allFileTypesSupported: 'All file types supported. ZIP files will be extracted.',
zipFilesDetected: 'ZIP files detected',
zipExtractOptions: 'ZIP files will be extracted. Choose how to handle folder structure:',
preserveZipStructure: 'Preserve folder structure from ZIP',
createFolderFromZip: 'Create folder from ZIP filename',
stlThumbnailGeneration: 'STL thumbnail generation',
zipMayContainStl: 'ZIP files may contain STL files. Thumbnails can be generated during extraction.',
thumbnailsCanBeGenerated: 'Thumbnails can be generated for STL files. Large models may take longer to process.',
generateThumbnailsForStl: 'Generate thumbnails for STL files',
threemfDetected: '3MF files detected',
threemfExtractionInfo: 'Printer model, material, color, and print settings will be automatically extracted from 3MF files.',
willBeExtracted: 'Will be extracted',
filesExtracted: '{{count}} files extracted',
uploadComplete: 'Upload complete: {{succeeded}} succeeded',
uploadFailed: '{{count}} failed',
uploading: 'Uploading...',
changeLink: 'Change Link...',
linkTo: 'Link to...',
linkToProjectOrArchive: 'Link to project or archive',
addToQueue: 'Add to Queue',
schedulePrint: 'Schedule',
generateThumbnail: 'Generate Thumbnail',
generateThumbnails: 'Generate Thumbnails',
generateThumbnailsForMissing: 'Generate thumbnails for STL files missing them',
gridView: 'Grid view',
listView: 'List view',
lowDiskSpaceWarning: 'Low disk space warning',
lowDiskSpaceDetails: 'Only {{free}} free of {{total}} total. Threshold is set to {{threshold}} GB in settings.',
files: 'Files',
folders: 'Folders',
size: 'Size',
free: 'Free',
allFiles: 'All Files',
wrap: 'Wrap',
enableTextWrapping: 'Enable text wrapping',
disableTextWrapping: 'Disable text wrapping',
dragToResizeTooltip: 'Drag to resize, double-click to reset',
searchFiles: 'Search files...',
allTypes: 'All types',
prints: 'Prints',
ascending: 'Ascending',
descending: 'Descending',
resultsCount: '{{showing}} of {{total}} files',
selectAll: 'Select All',
deselectAll: 'Deselect All',
selected: '{{count}} selected',
adding: 'Adding...',
loadingFiles: 'Loading files...',
folderIsEmpty: 'Folder is empty',
noFilesYet: 'No files yet',
folderEmptyDescription: 'Upload files or move files into this folder to get started.',
noFilesDescription: 'Upload files to start organizing your print-related files.',
noMatchingFiles: 'No matching files',
noMatchingFilesDescription: 'No files match your current search or filter criteria.',
clearFilters: 'Clear filters',
printedCount: 'Printed {{count}}x',
uploadedBy: 'Uploaded By',
deleteFolder: 'Delete Folder',
deleteFile: 'Delete File',
deleteFilesCount: 'Delete {{count}} Files',
deleteFolderConfirm: 'Are you sure you want to delete this folder? All files inside will also be deleted.',
deleteFileConfirm: 'Are you sure you want to delete this file?',
deleteFilesConfirm: 'Are you sure you want to delete {{count}} selected files? This action cannot be undone.',
deleting: 'Deleting...',
noPermissionRenameFolder: 'You do not have permission to rename folders',
noPermissionLinkFolder: 'You do not have permission to link folders',
noPermissionDeleteFolder: 'You do not have permission to delete folders',
noPermissionPrint: 'You do not have permission to print',
noPermissionAddToQueue: 'You do not have permission to add to queue',
noPermissionDownload: 'You do not have permission to download files',
noPermissionRenameFile: 'You do not have permission to rename this file',
noPermissionGenerateThumbnail: 'You do not have permission to generate thumbnails',
noPermissionDeleteFile: 'You do not have permission to delete this file',
noPermissionCreateFolder: 'You do not have permission to create folders',
noPermissionUpload: 'You do not have permission to upload files',
noPermissionMoveFiles: 'You do not have permission to move files',
noPermissionDeleteFiles: 'You do not have permission to delete files',
toast: {
folderCreated: 'Folder created',
folderDeleted: 'Folder deleted',
fileDeleted: 'File deleted',
filesDeleted: 'Deleted {{count}} files',
filesMoved: 'Files moved',
folderLinked: 'Folder linked',
folderUnlinked: 'Folder unlinked',
addedToQueue: 'Added {{count}} file(s) to queue',
addedToQueuePartial: 'Added {{added}} file(s), {{failed}} failed',
failedToAddToQueue: 'Failed to add files: {{error}}',
fileRenamed: 'File renamed',
folderRenamed: 'Folder renamed',
thumbnailsGenerated: 'Generated {{count}} thumbnail(s)',
thumbnailsGeneratedPartial: 'Generated {{succeeded}} thumbnail(s), {{failed}} failed',
noStlMissingThumbnails: 'No STL files missing thumbnails',
failedToGenerateThumbnails: 'Failed to generate thumbnails: {{error}}',
thumbnailGenerated: 'Thumbnail generated',
failedToGenerateThumbnail: 'Failed to generate thumbnail: {{error}}',
},
},
// Projects
projects: {
title: 'Projects',
subtitle: 'Organize and track your 3D printing projects',
newProject: 'New Project',
editProject: 'Edit Project',
deleteProject: 'Delete Project',
projectName: 'Project Name',
description: 'Description',
noProjects: 'No projects yet',
noProjectsFiltered: 'No {{status}} projects',
noProjectsFilteredHelp: "You don't have any {{status}} projects. Projects will appear here when their status changes.",
createFirst: 'Create your first project to start organizing related prints, tracking progress, and managing your builds.',
createFirstButton: 'Create Your First Project',
create: 'Create',
files: 'Files',
prints: 'Prints',
plates: 'plates',
parts: 'parts',
lastModified: 'Last Modified',
deleteConfirm: 'Are you sure you want to delete this project? Archives and queue items will be unlinked but not deleted.',
addFiles: 'Add Files',
removeFile: 'Remove File',
viewDetails: 'View Details',
// Modal fields
namePlaceholder: 'e.g., Voron 2.4 Build',
descriptionPlaceholder: 'Optional description...',
color: 'Color',
targetPlates: 'Target Plates',
targetPlatesPlaceholder: 'e.g., 25',
targetPlatesHelp: 'Number of print jobs',
targetParts: 'Target Parts',
targetPartsPlaceholder: 'e.g., 150',
targetPartsHelp: 'Total objects needed',
tagsLabel: 'Tags (comma-separated)',
tagsPlaceholder: 'e.g., voron, functional, gift',
dueDate: 'Due Date',
priority: 'Priority',
priorityLow: 'Low',
priorityNormal: 'Normal',
priorityHigh: 'High',
priorityUrgent: 'Urgent',
// Status
statusActive: 'Active',
statusCompleted: 'Completed',
statusArchived: 'Archived',
done: 'Done',
completed: 'completed',
failed: 'failed',
inQueue: 'in queue',
noPrintsYet: 'No prints yet',
// Footer stats
printJobs: 'Print jobs (plates)',
partsPrinted: 'Parts printed',
failedParts: 'Failed parts',
// Actions
import: 'Import',
export: 'Export',
importProject: 'Import project',
exportAll: 'Export all projects',
loading: 'Loading projects...',
// Permissions
noEditPermission: 'You do not have permission to edit projects',
noDeletePermission: 'You do not have permission to delete projects',
noCreatePermission: 'You do not have permission to create projects',
noImportPermission: 'You do not have permission to import projects',
noExportPermission: 'You do not have permission to export projects',
// Toast
toast: {
created: 'Project created',
updated: 'Project updated',
deleted: 'Project deleted',
imported: 'Project imported',
multipleImported: '{{count}} projects imported',
importFailed: 'Import failed',
exported: 'Projects exported (metadata only)',
},
},
// Project detail page
projectDetail: {
notFound: 'Project not found',
backToProjects: 'Back to Projects',
export: 'Export',
exportProject: 'Export project',
noExportPermission: 'You do not have permission to export projects',
noEditPermission: 'You do not have permission to edit projects',
partOf: 'Part of:',
priorityLabel: 'Priority:',
noPrints: 'No prints in this project yet',
status: {
active: 'Active',
completed: 'Completed',
archived: 'Archived',
},
priority: {
low: 'Low',
normal: 'Normal',
high: 'High',
urgent: 'Urgent',
},
dueDate: {
overdue: 'Overdue',
today: 'Due today',
daysLeft: '{{count}} days left',
},
progress: {
platesProgress: 'Plates Progress',
partsProgress: 'Parts Progress',
printJobs: 'print jobs',
parts: 'parts',
percentComplete: '{{percent}}% complete',
remaining: '{{count}} remaining',
},
stats: {
printJobs: 'Print Jobs',
total: 'total',
failed: '{{count}} failed',
partsPrinted: '{{count}} parts printed',
printTime: 'Print Time',
filamentUsed: 'Filament Used',
},
cost: {
title: 'Cost Tracking',
filamentCost: 'Filament Cost',
energy: 'Energy',
budget: 'Budget',
remaining: 'Remaining',
},
subProjects: {
title: 'Sub-projects ({{count}})',
},
notes: {
title: 'Notes',
noEditPermission: 'You do not have permission to edit notes',
placeholder: 'Add notes about this project...',
empty: 'No notes yet. Click Edit to add notes.',
},
files: {
title: 'Files',
linkFolders: 'Link folders from the File Manager',
forQuickAccess: 'to this project for quick access.',
fileCount: '{{count}} file(s)',
empty: 'No folders linked. Go to File Manager and link a folder to this project.',
},
bom: {
title: 'Bill of Materials',
acquired: '{{completed}}/{{total}} acquired',
showAll: 'Show all',
hideDone: 'Hide done',
addPart: 'Add Part',
noAddPermission: 'You do not have permission to add parts',
partNamePlaceholder: 'Part name (e.g., M3x8 screws)',
partName: 'Part name',
qty: 'Qty',
price: 'Price ({{currency}})',
sourcingUrlPlaceholder: 'Sourcing URL (optional)',
remarksPlaceholder: 'Remarks (optional)',
deletePart: 'Delete Part',
deleteConfirm: 'Are you sure you want to delete "{{name}}"?',
noUpdatePermission: 'You do not have permission to update parts',
noEditPermission: 'You do not have permission to edit parts',
noDeletePermission: 'You do not have permission to delete parts',
totalCost: 'Total cost:',
empty: 'No parts in the bill of materials. Add hardware, electronics, or other components to track what needs to be sourced.',
},
timeline: {
title: 'Activity Timeline',
empty: 'No activity yet.',
},
template: {
saveAsTemplate: 'Save as Template',
noCreatePermission: 'You do not have permission to create templates',
},
queue: {
title: 'Queue',
viewAll: 'View all',
printing: '{{count}} printing',
queued: '{{count}} queued',
},
prints: {
title: 'Prints ({{count}})',
},
toast: {
projectUpdated: 'Project updated',
partAdded: 'Part added',
partRemoved: 'Part removed',
exportFailed: 'Export failed',
projectExported: 'Project exported',
templateCreated: 'Template created',
},
},
// System info
system: {
title: 'System Information',
version: 'Version',
uptime: 'Uptime',
cpuUsage: 'CPU Usage',
memoryUsage: 'Memory Usage',
diskUsage: 'Disk Usage',
networkInfo: 'Network Info',
logs: 'Logs',
debugMode: 'Debug Mode',
enableDebug: 'Enable Debug Logging',
disableDebug: 'Disable Debug Logging',
downloadLogs: 'Download Logs',
clearLogs: 'Clear Logs',
dockerInfo: 'Docker Info',
containerName: 'Container Name',
imageName: 'Image Name',
platform: 'Platform',
architecture: 'Architecture',
},
// Library (K Profiles)
library: {
title: 'Filament Library',
addFilament: 'Add Filament',
editFilament: 'Edit Filament',
deleteFilament: 'Delete Filament',
vendor: 'Vendor',
material: 'Material',
color: 'Color',
kFactor: 'K Factor',
temperature: 'Temperature',
noFilaments: 'No filaments in library',
deleteConfirm: 'Are you sure you want to delete this filament?',
importFromPrinter: 'Import from Printer',
exportToFile: 'Export to File',
},
// Spoolman
spoolman: {
title: 'Spoolman Integration',
enabled: 'Spoolman Enabled',
url: 'Spoolman URL',
connected: 'Connected',
disconnected: 'Not Connected',
testConnection: 'Test Connection',
sync: 'Sync',
syncing: 'Syncing...',
lastSync: 'Last Sync',
linkToSpoolman: 'Link to Spoolman',
openInSpoolman: 'Open in Spoolman',
unlinkSpool: 'Unlink Spool',
selectSpool: 'Select Spool',
noUnlinkedSpools: 'No unlinked spools available',
linkSuccess: 'Spool linked to Spoolman successfully',
linkFailed: 'Failed to link spool',
spoolId: 'Spool ID',
fillSourceLabel: '(Spoolman)',
weight: 'Weight',
remaining: 'Remaining',
disableWeightSync: 'Disable AMS Estimated Weight Sync',
disableWeightSyncDesc: "Don't update remaining capacity from AMS estimates. Use this if you prefer Spoolman's usage tracking over AMS percentage-based estimates. New spools will still use the AMS estimate as their initial weight.",
reportPartialUsage: 'Report Partial Usage for Failed Prints',
reportPartialUsageDesc: 'When a print fails or is cancelled, report the estimated filament used up to that point based on layer progress.',
},
// Timelapse
timelapse: {
title: 'Timelapse',
create: 'Create Timelapse',
download: 'Download',
delete: 'Delete',
preview: 'Preview',
frameRate: 'Frame Rate',
quality: 'Quality',
processing: 'Processing...',
noTimelapses: 'No timelapses available',
},
// AMS
ams: {
title: 'AMS',
slot: 'Slot',
empty: 'Empty',
emptySlot: 'Empty slot',
unknown: 'Unknown',
humidity: 'Humidity',
temperature: 'Temperature',
filamentType: 'Filament Type',
filamentColor: 'Color',
remaining: 'Remaining',
history: 'AMS History',
noHistory: 'No history available',
configureSlot: 'Configure Slot',
externalSpool: 'External Spool',
profile: 'Profile',
kFactor: 'K Factor',
fill: 'Fill',
configure: 'Configure',
},
// Print modal
printModal: {
title: 'Start Print',
selectPrinter: 'Select Printer',
selectPlate: 'Select Plate',
filamentMapping: 'Filament Mapping',
printSettings: 'Print Settings',
bedLeveling: 'Bed Leveling',
flowCalibration: 'Flow Calibration',
vibrationCalibration: 'Vibration Calibration',
layerInspection: 'First Layer Inspection',
timelapse: 'Timelapse',
startPrint: 'Start Print',
addToQueue: 'Add to Queue',
cancel: 'Cancel',
noPrintersAvailable: 'No printers available',
printerBusy: 'Printer is busy',
printerOffline: 'Printer is offline',
},
// Backup
backup: {
title: 'Backup & Restore',
createBackup: 'Create Backup',
restoreBackup: 'Restore Backup',
restoreDescription: 'Replace all data from a backup file',
downloadBackup: 'Download Backup',
uploadBackup: 'Upload Backup',
lastBackup: 'Last Backup',
autoBackup: 'Auto Backup',
backupNow: 'Backup Now',
restoreWarning: 'Warning: Restoring a backup will overwrite all current data.',
includeArchives: 'Include Archives',
includeSettings: 'Include Settings',
includeProfiles: 'Include Profiles',
backupSuccess: 'Backup created successfully',
restoreSuccess: 'Backup restored successfully',
backupFailed: 'Backup failed',
restoreFailed: 'Restore failed',
restoreNote: 'Virtual Printer will be stopped during restore',
},
// Tags
tags: {
title: 'Tags',
addTag: 'Add Tag',
editTag: 'Edit Tag',
deleteTag: 'Delete Tag',
tagName: 'Tag Name',
tagColor: 'Tag Color',
noTags: 'No tags',
deleteConfirm: 'Are you sure you want to delete this tag?',
manageTags: 'Manage Tags',
},
// Upload modal (archives)
uploadModal: {
title: 'Upload 3MF Files',
dragDrop: 'Drag & drop .3mf files here',
or: 'or',
browseFiles: 'Browse Files',
extractionInfo: 'The printer model will be automatically extracted from the 3MF file metadata.',
uploaded: 'uploaded',
failed: 'failed',
uploading: 'Uploading...',
upload: 'Upload',
uploadFailed: 'Upload failed',
},
// Edit archive modal
editArchive: {
title: 'Edit Archive',
name: 'Name',
namePlaceholder: 'Print name',
printer: 'Printer',
noPrinter: 'No printer',
project: 'Project',
noProject: 'No project',
itemsPrinted: 'Items Printed',
itemsPrintedHelp: 'Number of items produced in this print job',
notes: 'Notes',
notesPlaceholder: 'Add notes about this print...',
externalLink: 'External Link',
externalLinkPlaceholder: 'https://printables.com/model/...',
externalLinkHelp: 'Link to Printables, Thingiverse, or other source',
tags: 'Tags',
tagsPlaceholder: 'Add tags...',
addMoreTags: 'Add more tags...',
matchingTags: 'Matching "{{query}}"',
existingTags: 'Existing tags',
clickToAdd: '(click to add)',
status: 'Status',
failureReason: 'Failure Reason',
selectReason: 'Select reason...',
photos: 'Photos of Printed Result',
photosHelp: 'Click + to add photos of your printed result',
printResult: 'Print result',
saving: 'Saving...',
// Failure reasons
failureReasons: {
adhesionFailure: 'Adhesion failure',
spaghettiDetached: 'Spaghetti / Detached',
layerShift: 'Layer shift',
cloggedNozzle: 'Clogged nozzle',
filamentRunout: 'Filament runout',
warping: 'Warping',
stringing: 'Stringing',
underExtrusion: 'Under-extrusion',
powerFailure: 'Power failure',
userCancelled: 'User cancelled',
other: 'Other',
},
// Archive statuses
statuses: {
completed: 'Completed',
failed: 'Failed',
aborted: 'Cancelled',
printing: 'Printing',
},
},
// K-Profiles
kProfiles: {
title: 'K-Profiles',
noPrintersConfigured: 'No Printers Configured',
addPrinterInSettings: 'Add a printer in Settings to manage K-profiles',
noActivePrinters: 'No Active Printers',
enablePrinterConnection: 'Enable a printer connection to view its K-profiles',
loadingProfiles: 'Loading K-Profiles...',
printerOffline: 'Printer Offline',
printerOfflineDesc: 'The selected printer is not connected. Power it on to view K-profiles.',
noMatchingProfiles: 'No Matching Profiles',
noMatchingProfilesDesc: 'No profiles match your search criteria',
noKProfiles: 'No K-Profiles',
noKProfilesDesc: 'No pressure advance profiles found for {{diameter}}mm nozzle',
createFirstProfile: 'Create First Profile',
// Controls
printer: 'Printer',
nozzle: 'Nozzle',
refresh: 'Refresh',
addProfile: 'Add Profile',
export: 'Export',
import: 'Import',
select: 'Select',
selectAll: 'Select All',
delete: 'Delete',
// Filters
searchPlaceholder: 'Search by name or filament...',
allExtruders: 'All Extruders',
leftOnly: 'Left Only',
rightOnly: 'Right Only',
allFlow: 'All Flow',
hfOnly: 'HF Only',
sOnly: 'S Only',
sortName: 'Sort: Name',
sortKValue: 'Sort: K-Value',
sortFilament: 'Sort: Filament',
// Dual extruder labels
leftExtruder: 'Left Extruder',
rightExtruder: 'Right Extruder',
// Modal
modal: {
addTitle: 'Add K-Profile',
editTitle: 'Edit K-Profile',
profileName: 'Profile Name',
profileNamePlaceholder: 'My PLA Profile',
kValue: 'K-Value',
kValuePlaceholder: '0.020',
kValueHelp: 'Typical range: 0.01 - 0.06 for PLA, 0.02 - 0.10 for PETG',
filament: 'Filament',
selectFilament: 'Select filament...',
noFilamentsHelp: 'No filaments found. Create a K-profile in Bambu Studio first.',
flowType: 'Flow Type',
highFlow: 'High Flow',
standard: 'Standard',
nozzleSize: 'Nozzle Size',
extruder: 'Extruder',
extruders: 'Extruders',
left: 'Left',
right: 'Right',
notes: 'Notes (stored locally)',
notesPlaceholder: 'Add notes about this profile...',
notesHelp: 'Notes are saved in Bambuddy, not on the printer',
syncing: 'Syncing with printer...',
savingExtruder: 'Saving to extruder {{current}}/{{total}}...',
pleaseWait: 'Please wait',
},
// Delete confirmation
deleteConfirm: {
title: 'Delete Profile',
cannotUndo: 'This cannot be undone',
message: 'Are you sure you want to delete "{{name}}" from the printer?',
},
// Bulk delete
bulkDelete: {
title: 'Delete Profiles',
cannotUndo: 'This cannot be undone',
message: 'Are you sure you want to delete {{count}} selected profiles from the printer?',
},
// Toast
toast: {
profileSaved: 'K-profile saved',
profilesSaved: 'K-profile saved to {{count}} extruders',
selectAtLeastOneExtruder: 'Please select at least one extruder',
profileDeleted: 'K-profile deleted',
profilesDeleted: 'Deleted {{count}} profiles',
exportedProfiles: 'Exported {{count}} profiles',
importedProfiles: 'Imported {{count}} of {{total}} profiles',
noProfilesToExport: 'No profiles to export',
invalidFileFormat: 'Invalid file format',
failedToParseImport: 'Failed to parse import file',
failedToSaveBatch: 'Failed to save K-profiles',
noteSaved: 'Note saved',
failedToSaveNote: 'Failed to save note',
},
// Permissions
permission: {
noRead: 'You do not have permission to refresh profiles',
noCreate: 'You do not have permission to add profiles',
noUpdate: 'You do not have permission to update K-profiles',
noDelete: 'You do not have permission to delete K-profiles',
noExport: 'You do not have permission to export profiles',
noImport: 'You do not have permission to import profiles',
},
},
// Virtual Printer
virtualPrinter: {
title: 'Virtual Printer',
running: 'Running',
stopped: 'Stopped',
description: {
default: 'Enable a virtual printer that appears in Bambu Studio and OrcaSlicer. Files sent to this printer will be archived directly without printing.',
proxy: 'Enable a proxy that relays slicer traffic to a real printer, allowing remote printing over any network.',
},
enable: {
title: 'Enable Virtual Printer',
visibleInSlicer: 'Visible as "Bambuddy" in slicer discovery',
proxyingTo: 'Proxying to {{name}}',
notActive: 'Not active',
},
model: {
title: 'Printer Model',
description: 'Select which printer model to emulate.',
restartWarning: 'Changing the model will restart the virtual printer',
},
accessCode: {
title: 'Access Code',
isSet: 'Access code is set',
notSet: 'No access code set - required to enable',
placeholder: 'Enter 8-char code',
placeholderChange: 'Enter new code to change',
hint: 'Must be exactly 8 characters. Used by slicers to authenticate.',
charCount: '({{count}}/8)',
},
targetPrinter: {
title: 'Target Printer',
configured: 'Proxy target configured',
notConfigured: 'No target printer selected - required for proxy mode',
placeholder: 'Select a printer...',
hint: 'Select the printer to proxy slicer traffic to. The printer must be in LAN mode.',
noPrinters: 'No printers configured. Add a printer first to use proxy mode.',
},
remoteInterface: {
title: 'Slicer Network Interface',
configured: 'SSDP proxy enabled',
optional: 'Optional - for SSDP discovery across networks',
placeholder: 'Select interface for slicer network...',
hint: 'Select the network interface connected to the slicer. Enables automatic printer discovery in Bambu Studio.',
},
mode: {
title: 'Mode',
archive: 'Archive',
archiveDesc: 'Archive files immediately',
review: 'Review',
reviewDesc: 'Review before archiving',
queue: 'Queue',
queueDesc: 'Archive and add to queue',
proxy: 'Proxy',
proxyDesc: 'Relay to real printer',
},
setupRequired: {
title: 'Setup Required',
description: 'The virtual printer feature requires additional system configuration before it will work. This includes port forwarding, firewall rules, and platform-specific settings.',
readGuide: 'Read the setup guide before enabling',
},
howItWorks: {
title: 'How it works',
titleProxy: 'How it works (Proxy Mode)',
step1: 'Complete the setup guide for your platform',
step2: 'Enable the virtual printer and set an access code',
step3: 'In Bambu Studio or OrcaSlicer, go to "Add Printer"',
step4: 'The "Bambuddy" printer should appear in the discovery list',
step5: 'Connect using the access code you set',
step6: 'When you "print" to Bambuddy, the 3MF file is archived instead',
proxyStep1: 'Select the target printer (must be in LAN mode)',
proxyStep2: 'For cross-network: select the slicer network interface',
proxyStep3: 'Enable the proxy - printer appears in slicer discovery via SSDP',
proxyStep4: 'Connect using the printer\'s access code',
proxyStep5: 'Print as normal - traffic is relayed through Bambuddy',
proxyStep6: 'Camera streaming requires NAT/IP forwarding (see docs)',
},
status: {
title: 'Status Details',
printerName: 'Printer Name',
model: 'Model',
serialNumber: 'Serial Number',
mode: 'Mode',
pendingFiles: 'Pending Files',
targetPrinter: 'Target Printer',
ftpPort: 'FTP Port',
mqttPort: 'MQTT Port',
ftpConnections: 'FTP Connections',
mqttConnections: 'MQTT Connections',
},
toast: {
updated: 'Virtual printer settings updated',
failedToUpdate: 'Failed to update settings',
accessCodeRequired: 'Please set an access code first',
targetPrinterRequired: 'Please select a target printer first',
accessCodeEmpty: 'Access code cannot be empty',
accessCodeLength: 'Access code must be exactly 8 characters',
},
},
// Model Viewer
modelViewer: {
openInSlicer: 'Open in Slicer',
tabs: {
model: '3D Model',
gcode: 'G-code Preview',
},
notAvailable: 'not available',
notSliced: 'not sliced',
plates: 'Plates',
allPlates: 'All Plates',
plateNumber: 'Plate {{number}}',
plateCount: '{{count}} plate',
plateCount_other: '{{count}} plates',
objectCount: '{{count}} object',
objectCount_other: '{{count}} objects',
filamentCount: '{{count}} filament',
filamentCount_other: '{{count}} filaments',
eta: 'ETA {{minutes}} min',
noPreview: 'No preview available for this file',
pagination: {
pageOf: 'Page {{current}} of {{total}}',
prev: 'Prev',
next: 'Next',
},
errors: {
failedToLoad: 'Failed to load file',
noMeshes: 'No meshes found in 3MF file',
unsupportedFormat: 'Unsupported file format',
},
},
// Maintenance type descriptions (built-in)
maintenanceDescriptions: {
lubricateRails: 'Apply lubricant to linear rails for smooth motion',
cleanNozzle: 'Clean hotend and nozzle to prevent clogs',
checkBelts: 'Verify belt tension for accurate prints',
cleanBuildPlate: 'Clean build plate for better adhesion',
checkExtruder: 'Inspect extruder gears for wear',
checkCooling: 'Ensure cooling fans are working properly',
generalInspection: 'General printer inspection',
cleanCarbonRods: 'Clean carbon rods to reduce friction',
checkPtfeTube: 'Inspect PTFE tube for wear or damage',
replaceHepaFilter: 'Replace HEPA filter for air quality',
replaceCarbonFilter: 'Replace activated carbon filter',
lubricateLeftNozzleRail: 'Lubricate left nozzle rail (H2 series)',
},
};