{
  "product": "YSK Server",
  "tagline": "AI-centric, security-first Linux server management platform",
  "company": "YSK Limited",
  "agents": {
    "title": "AI Agent runtimes",
    "body": "OpenClaw / Hermes / IonClaw install and supervision; all tool calls go through Allowlist and approval.",
    "status": {
      "running": "Running",
      "activating": "Starting",
      "stuck": "Start stuck",
      "connected": "Online",
      "registered": "Registered only",
      "stale": "Stale",
      "disconnected": "Offline",
      "not_installed": "Not installed",
      "failed": "Failed",
      "error": "Error",
      "unknown": "Not probed",
      "fallback": "Unknown"
    },
    "cmdStatus": {
      "queued": "Queued",
      "acked": "Acked",
      "done": "Done",
      "error": "Error"
    },
    "activatingStuckHint": "Activating longer than 5 minutes — treated as failed. Check journal.",
    "noOnlineAgents": "No agents online",
    "journal": "journal",
    "writeUnit": "Write unit",
    "writeUnitConfirm": "Write the systemd unit for {{kind}} under /etc/systemd. The service is not started or enabled.",
    "liveN": "{{count}} online",
    "registeredOnly": "Registered only",
    "awaitProbe": "Awaiting probe",
    "runtimes": "Runtimes",
    "running": "Running",
    "liveAgents": "Online agents",
    "fleet": "Fleet",
    "aiTasks": "AI tasks",
    "expBanner": "Experimental.",
    "expBody": "Registration ≠ online. Real ops use the CLI:",
    "expDocs": "Repository file:",
    "expEdge": "On an edge:",
    "expPayload": "Command payload example:",
    "fleetCan": "What the fleet can do",
    "fleetCanDesc": "Not a hollow list — real control-plane capabilities for edge nodes",
    "capRegister": "Register",
    "capRegisterD": "Writes control-plane list (status “registered only”) — process may not be running",
    "capCommand": "Command",
    "capCommandD": "CLI presets (readiness / host / projects…) or custom; edge pulls, runs ysk-server, and acks",
    "capHistory": "Command history",
    "capHistoryD": "queued / done / error, exit code, pretty JSON result",
    "capDelete": "Delete",
    "capDeleteD": "Removes session and related messages",
    "capStatus": "Status",
    "capStatusD": "Registered only → online (heartbeat) → stale (>60s without heartbeat) → offline (disconnected / no further heartbeat)",
    "statusFlowTitle": "Status flow",
    "statusFlow": "Registered only → online → stale (>60s) → offline. Filter “Offline” means disconnected.",
    "colSession": "Session UUID",
    "copySession": "Copy session UUID for cluster / CLI --session",
    "staleFor": "Stale {{age}}",
    "commandTitle": "Queue a command for this session",
    "historyTitleShort": "Open command history (read-only)",
    "fleetTitle": "Fleet ({{count}})",
    "fleetDesc": "Control-plane registry · registered ≠ node online",
    "registerPlus": "+ Register agent",
    "colId": "ID",
    "colStatus": "Status",
    "colGroup": "Group",
    "colLastSeen": "Last seen",
    "command": "Command",
    "history": "History",
    "emptyAgents": "No agents registered",
    "emptyAgentsDesc": "Register from the list, or wait for edge processes to self-register",
    "historyTitle": "Command history · {{id}}",
    "historyDesc": "queued until node pulls;",
    "refreshHistory": "Refresh history",
    "colTime": "Time",
    "finishedAt": "Finished {{at}}",
    "colCommand": "Command",
    "colResult": "Result summary",
    "colExit": "Exit",
    "hasResult": "Has result",
    "emptyCmds": "No commands yet",
    "emptyCmdsDesc": "Queue with “Command”; stays queued until the edge agent is online",
    "edgeOnlineTitle": "How edge agents come online",
    "edgeOnlineDesc": "After panel registration, the node must run the outbound loop to heartbeat / pull commands",
    "controlPlaneApi": "Control-plane API:",
    "controlPlaneHint": "(must be reachable; use the real panel address in production)",
    "queueNote": "Without an edge process, “Command” still works: it queues until the agent comes online.",
    "runtimeTitle": "AI runtimes",
    "runtimeDesc": "Probe paths and units;",
    "emptyRuntime": "No probe results yet",
    "emptyRuntimeDesc": "Refresh to load runtimes, or probe individually",
    "pathExists": "Exists",
    "pathMissing": "Not installed",
    "unitUnknown": "{{unit}} · unknown",
    "unitFallback": "unit",
    "path": "Path",
    "probe": "Probe",
    "install": "Install",
    "recentOps": "Recent ops",
    "registerTitle": "Register agent",
    "registerDesc": "Writes control-plane list only; does not mean the node is online",
    "register": "Register",
    "agentId": "Agent ID",
    "agentIdHint": "Unique ID, e.g. edge-1 or office-gateway",
    "group": "Group",
    "groupHint": "For zoning / list filters",
    "registerNote": "Status shows “registered only” until the node runs the outbound agent and heartbeats.",
    "cmdTitle": "Command · {{id}}",
    "cmdTitlePlain": "Command",
    "cmdDesc": "Queued; edge agent pulls, runs, and acks (stays queued while offline)",
    "enqueue": "Enqueue",
    "cmdPreset": "Command (CLI first)",
    "cmdTypeAria": "Command type",
    "customCli": "Custom CLI",
    "cliArgs": "CLI arguments",
    "cliArgsHint": "Do not include ysk-server; e.g. logs journal --unit nginx.service",
    "cmdNote": "Edge ysk-server agent run executes CLI JSON locally (adds --json). Host changes still need YSK_EXECUTE=1 on the edge. See exit code and JSON in History.",
    "resultTitle": "Command result · exit {{code}}",
    "resultTitlePlain": "Command result",
    "codeComment": "# Concept: register → heartbeat loop → pull commands → ack\n# Library: ysk-server-core runOutboundAgent / agentCycle",
    "resultOuter": "Outer: edge ack (exitCode / stderr). Inner result:",
    "deleteTitle": "Delete {{id}}?",
    "deleteTitlePlain": "Delete agent?",
    "deleteDesc": "Related command history will also be removed.",
    "fact": {
      "kind": "Type",
      "name": "Name",
      "status": "Status",
      "unitActive": "Service",
      "unitName": "Unit",
      "pathExists": "Path exists",
      "installPath": "Install path"
    },
    "installBlocked": "Cannot complete install in the admin panel",
    "registeredMsg": "Registered {{id}} (control plane only; node must run outbound agent and heartbeat to go online)",
    "registerFailed": "Register failed",
    "removedFleet": "Fleet registration removed",
    "enqueuedMsg": "Queued command {{id}}… (runs after node pull)",
    "enqueueFailed": "Enqueue failed",
    "loadCommandsFailed": "Failed to load commands",
    "probedMsg": "Probed {{kind}}",
    "probeFailed": "Probe failed",
    "wroteUnitMsg": "Wrote {{kind}} unit settings",
    "writeFailed": "Write failed",
    "installedMsg": "Installed {{kind}}",
    "installIncomplete": "Install incomplete",
    "badgeDryRun": "dry-run",
    "badgeBlocked": "blocked",
    "labelStderr": "stderr",
    "labelAckCli": "ack + CLI JSON",
    "labelStdoutBody": "CLI stdout body",
    "resultOuterHint": "Outer result is CLI --json stdout.",
    "noteAllowlist": "Agent tool calls must pass the allowlist.",
    "noteRbacCap": "Agent role is capped at write-low."
  },
  "ai": {
    "status": {
      "completed": "Completed",
      "done": "Done",
      "executed": "Executed",
      "failed": "Failed",
      "error": "Error",
      "rejected": "Rejected",
      "pending": "Pending",
      "planned": "Planned",
      "approved": "Approved",
      "running": "Running",
      "cancelled": "Cancelled"
    },
    "activeCount": "{{count}} active",
    "taskCount": "{{count}} tasks",
    "tasks": "Tasks",
    "active": "Active",
    "tasksTab": "Tasks ({{count}})",
    "playbooksTab": "Playbooks ({{count}})",
    "queueTitle": "Task queue",
    "queueSub": "Select to view plan & steps · no extra actions on terminal state",
    "createTaskPlus": "+ Create task",
    "emptyTasks": "No tasks yet",
    "emptyTasksDesc": "Create a task from the list, or run a playbook",
    "browsePlaybooks": "Browse playbooks",
    "noPrompt": "(no prompt)",
    "stepsOf": "Steps {{done}}/{{total}}",
    "noPlanSummary": "(no plan summary)",
    "pipelineAria": "Task phases",
    "phase": {
      "plan": "Plan",
      "approve": "Review",
      "run": "Execute",
      "done": "Done"
    },
    "approveRun": "Approve & run",
    "cancelTask": "Cancel task",
    "terminalHint": "Task finished — create a new task or run a playbook",
    "stepsTitle": "Steps ({{count}})",
    "noSteps": "No steps yet",
    "needsApproval": "Needs approval",
    "noApproval": "No approval",
    "reject": "Reject",
    "selectTask": "Select a task",
    "selectTaskDesc": "Pick a task on the left to view plan and steps",
    "playbooksTitle": "Playbooks",
    "playbooksSub": "Preset ops · running creates a task and switches to Tasks",
    "countItems": "{{count}}",
    "searchPh": "Name / description",
    "noPlaybooks": "No matching playbooks",
    "noPlaybooksDesc": "Change keywords or clear search",
    "run": "Run",
    "createTitle": "Create AI task",
    "createDesc": "Planning ≠ executed. Tools stay on the allowlist.",
    "generatePlan": "Generate plan",
    "promptLabel": "Natural-language instruction",
    "promptHint": "e.g. check host load; or nginx status",
    "promptPh": "Describe what you want…",
    "createHint": "Next: Approve & run in the task detail, or reject individual steps."
  },
  "apache": {
    "pageDesc": "Apache sites (PHP projects + standalone)",
    "pillSites": "{{count}} sites",
    "pillSitesSplit": "{{n}} sites · {{leftover}} leftover",
    "listTitle": "Sites ({{count}})",
    "emptyTitle": "No sites",
    "createSite": "+ Create site",
    "createTitle": "Create site",
    "editTitle": "Edit site",
    "deleteTitle": "Delete site?",
    "deleteDesc": "Remove this Apache site?",
    "stopSites": "{{n}} site(s) will stop answering HTTP.",
    "colServerName": "Server name",
    "colSource": "Source",
    "colKind": "Type",
    "colTarget": "Target",
    "colStatus": "Status",
    "filterSource": "Source filter",
    "sourceAll": "All",
    "sourceProject": "Project",
    "sourceStandalone": "Standalone",
    "sourceArtifact": "On disk",
    "sourceOrphan": "Leftover",
    "orphanSite": "Project gone",
    "openProject": "Open project",
    "kindLabel": "Type",
    "kindProxy": "Proxy",
    "kindStatic": "Static",
    "kindPhp": "PHP",
    "upstreamLabel": "Upstream",
    "rootLabel": "Document root",
    "sslLabel": "SSL",
    "sslTerminatedUpstream": "TLS ends at front Nginx",
    "apply": "Apply",
    "notInstalled": "Apache not installed",
    "globalSettings": "Global settings",
    "siteSettings": "Site settings",
    "saveApply": "Save & apply",
    "settingsSaved": "Saved",
    "setGzip": "Gzip",
    "setShowVersion": "Show version",
    "setHttp2": "HTTP/2",
    "setBody": "Max body",
    "setKeepalive": "Keepalive",
    "setAccessLog": "Access log",
    "logOn": "On",
    "logOff": "Off",
    "setForceHttps": "Force HTTPS",
    "setHsts": "HSTS",
    "setIndexes": "Directory listing",
    "bodyInherit": "Global",
    "conflict": "Name conflict",
    "conflictHint": "Same ServerName has multiple sources. Keep the project/standalone row and remove disk orphans.",
    "removeArtifact": "Remove residual",
    "removeArtifactTitle": "Remove residual conf?",
    "removeArtifactDesc": "Delete this unclaimed Apache conf from the panel data directory and disable the system twin when possible. Does not delete the project.",
    "removeArtifactHint": "Deletes this leftover disk conf. Does not delete the project.",
    "previewConf": "Preview conf",
    "cleanupConflicts": "Clean conflict residuals",
    "cleanupConflictsTitle": "Clean all conflict residuals?",
    "cleanupConflictsDesc": "Remove every on-disk artifact conf that conflicts with a project or standalone ServerName. Project rows are kept.",
    "artifactRemovedOk": "Residual conf removed"
  },
  "applyStatus": {
    "draft": "Draft",
    "written": "Written (panel data)",
    "planned": "In progress",
    "applied": "Applied on host",
    "failed": "Failed",
    "pendingExecute": "Needs host execute",
    "uploaded": "Uploaded",
    "issued": "Issued",
    "missing": "File missing"
  },
  "audit": {
    "recent": "Recent audit",
    "lastN": "Last {{n}}",
    "actions": {
      "protection.change": "Protection settings changed",
      "auth.locale": "UI language changed",
      "auth.login": "Signed in",
      "auth.logout": "Signed out",
      "system.firewall.allow_port": "Firewall allow port",
      "system.firewall.deny": "Firewall deny IP",
      "system.firewall.apply": "Firewall apply",
      "project.deploy": "Project deploy",
      "project.create": "Project created",
      "project.delete": "Project deleted",
      "ssl.request": "SSL request",
      "ssl.upload": "SSL upload",
      "system.firewall.enable": "Firewall enable/disable",
      "system.firewall.delete_rule": "Delete firewall rule",
      "system.firewall.delete_deny": "Remove permanent deny IP",
      "db.adminer.apply": "DB browser project",
      "project.goLive": "Project go-live",
      "project.publish": "Publish Nginx",
      "project.suspend": "Suspend project",
      "software.install": "Install software",
      "software.update": "Update software",
      "backup.restore": "Backup restore",
      "backup.run": "Backup run",
      "backup.delete": "Backup deleted"
    }
  },
  "backups": {
    "settingsSaved": "Backup settings saved",
    "saveFailed": "Save failed",
    "downloadStarted": "Download started: {{name}}",
    "nothingToDo": "Nothing to do",
    "tarOkSideFail": "tar OK / side steps had issues",
    "success": "Success",
    "hasFailures": "Has failures",
    "notYet": "Not yet",
    "enabled": "Enabled",
    "needPassword": "Missing password",
    "off": "Off",
    "lastRun": "Last {{label}}",
    "backupFiles": "Backup files",
    "projects": "Projects",
    "lastAll": "Last all",
    "latestFile": "Latest archive",
    "remote": "Remote",
    "withBackups": "Projects with backups",
    "ops": "Actions",
    "remoteExclude": "Remote / exclude",
    "about": "About",
    "noBackups": "No backups yet",
    "noBackupsDesc": "Run “Backup all projects” or Backup on a project detail",
    "goOps": "Go to actions",
    "projectShort": "Project",
    "download": "Download",
    "preview": "Preview",
    "restoreWeb": "Restore web",
    "restoreFull": "Full restore",
    "restoreFullTitle": "Overwrite project files and databases from this archive — type the file name to confirm",
    "restoreWebTitle": "Restore website files only from this archive",
    "previewTitle": "Preview restore without writing",
    "partialSkipped": "Partial — some projects skipped",
    "delete": "Delete",
    "opsTitle": "Actions",
    "opsHint": "0 projects or all skipped = success;",
    "noProjects": "(no projects)",
    "successRatio": " · {{ok}}/{{total}} ok",
    "summary": "Summary{{extra}}",
    "backupFailed": "Backup failed",
    "backupDone": "Backup complete",
    "backupAll": "Backup all projects",
    "controlPlane": "Backup control plane",
    "controlPlaneDone": "Control-plane backup complete",
    "cronCmd": "Command: ysk-server backup all --data-dir …",
    "cronHint": "Schedule POST with install=true loads host crontab when EXECUTE is on;",
    "dailyCronRegistered": "Registered daily 03:00 schedule",
    "registerDailyCron": "Register daily schedule (+ install)",
    "resticNeedConfig": "Enable restic and set password under Remote / exclude first",
    "resticFailed": "restic failed",
    "resticDone": "restic incremental complete",
    "resticOnly": "Run restic only",
    "listSnapshots": "List restic snapshots",
    "lastAllDetail": "Last full backup detail",
    "time": "Time",
    "result": "Result",
    "nothingZero": "Nothing to do (0 projects)",
    "notes": "Notes",
    "status": "Status",
    "skipped": "Skipped",
    "failed": "Failed",
    "lastNoProjects": "No projects needed backup last time.",
    "noPerProject": "No per-project results.",
    "remoteSide": "Remote / restic side steps",
    "step": "Step",
    "remoteStep": "Remote",
    "restoreProjectId": "Restore projectId (empty = list all)",
    "needProjectOrTag": "Fill projectId or snapshot must have project: tag",
    "dryRunDone": "dry-run complete (no write)",
    "allSuccess": "All succeeded",
    "failOrSkip": "Failures / skips",
    "noteN": "Note {{n}}",
    "enableRemote": "Enable remote push",
    "targetKind": "Target type",
    "remoteKindAria": "Remote target type",
    "localPath": "Local path",
    "host": "Host",
    "port": "Port",
    "username": "Username",
    "password": "Password",
    "passwordSshHint": "Empty to use host SSH key",
    "savedLeaveEmpty": "Leave empty if already saved",
    "s3Bucket": "Bucket path",
    "region": "Region",
    "endpointOptional": "Endpoint (optional)",
    "localMirror": "Local mirror path",
    "remotePath": "Remote path",
    "remotePathHint": "Relative to the remote user’s home (or SFTP chroot). “.” is that home.",
    "resticTitle": "Restic incremental",
    "resticDesc": "Optional; restic on PATH. Password required when enabled (no default)",
    "enableRestic": "Enable restic",
    "repoPath": "Repo path",
    "repoPassword": "Repo password",
    "repoPassSaved": "Saved; empty = keep. Required when enabled.",
    "repoPassRequired": "Required when restic is enabled (no default password)",
    "savedPlaceholder": "Saved (empty = keep)",
    "required": "Required",
    "s3RepoUrl": "Or S3 repo URL",
    "excludeTitle": "Exclude rules",
    "excludeSub": "tar exclude paths, one glob per line",
    "excludeList": "Exclude list",
    "saveAll": "Save all settings",
    "restoreFailed": "Restore failed",
    "previewDone": "Preview complete",
    "restoreDone": "Restore complete",
    "previewQ": "Preview backup contents?",
    "restoreWebQ": "Selective restore (web)?",
    "restoreFullQ": "Full restore?",
    "previewDesc": "List {{name}} only — no file changes.",
    "restoreWebDesc": "Extract {{name}} into project home (safer).",
    "restoreFullDesc": "Full tar restore of {{name}}; may overwrite existing files.",
    "restore": "Restore",
    "cancel": "Cancel",
    "deleteFailed": "Delete failed",
    "deleted": "Deleted",
    "deleteTitle": "Move backup to recycle bin?",
    "deleteDesc": "Move {{name}} to the recycle bin. Permanent delete after 7 days.",
    "tabTrash": "Recycle bin",
    "trashTitle": "Recycle bin ({{count}})",
    "trashSub": "Deleted archives stay here for 7 days, then they are removed permanently.",
    "trashEmpty": "Recycle bin is empty",
    "trashEmptyDesc": "Deleted backup files appear here for 7 days.",
    "trashRestore": "Restore",
    "trashPurge": "Delete forever",
    "trashEmptyAll": "Empty recycle bin",
    "trashExpires": "Expires {{at}}",
    "trashPurgeTitle": "Permanently delete this backup?",
    "trashPurgeDesc": "Permanently delete {{name}}. This cannot be undone.",
    "trashEmptyTitle": "Empty recycle bin?",
    "trashEmptyDescConfirm": "Permanently delete {{count}} archive(s). Type the count to confirm.",
    "trashRestored": "Restored from recycle bin",
    "trashPurged": "Permanently deleted",
    "trashedOk": "Moved to recycle bin",
    "resticSafeTitle": "restic restore to safe directory?",
    "resticSafeDesc": "Restore {{snapshot}} to project {{project}} .restic-restore-* directory",
    "resticRestoreDone": "restic restore complete",
    "overwriteTitle": "Danger: overwrite home",
    "overwriteDesc": "Will overwrite home for project {{project}}. Type OVERWRITE to confirm.",
    "confirmString": "Confirm string",
    "overwriteHome": "Overwrite home",
    "resticOverwriteDone": "restic overwrite home complete",
    "opsResult": "Ops result",
    "filesTitle": "Backup files ({{count}})",
    "filesSub": "Archives live in the panel data directory. Download needs a login. Restore can preview, restore the site only, or restore everything.",
    "backupAllBtn": "Backup all",
    "yes": "Yes",
    "no": "No",
    "safeDir": "Safe directory",
    "remotePushTitle": "Remote push target",
    "remotePushSub": "After local tar succeeds, push to SFTP, local path, or S3",
    "accessKey": "Access Key",
    "secretKey": "Secret Key",
    "overwriteConfirmHint": "Type OVERWRITE to confirm overwrite",
    "testRemote": "Test destination",
    "testRemoteHint": "Connects to the remote host and writes a small probe file. Not read-only.",
    "testRemoteDone": "Remote probe finished",
    "testRemoteFailed": "Remote probe failed",
    "resticRepoPh": "Panel data directory / restic-repo",
    "testDisabledHint": "Turn on remote push before testing.",
    "identityId": "Outbound SSH identity",
    "identityHint": "Preferred. Same vault as /security SSH. Password needs sshpass.",
    "identityNone": "None — password or default key",
    "skippedListHint": "These projects were skipped:",
    "skippedPendingOs": "Skipped — OS user / home not provisioned",
    "goLogs": "Open logs",
    "goAbout": "Backup notes",
    "previewListingTitle": "Archive contents",
    "restoreNamedDesc": "Restore {{name}} into project {{project}}.",
    "overwriteNamedDesc": "Overwrite files of project {{project}} from snapshot {{snapshot}}.",
    "resticSafeNamed": "Restore snapshot {{snapshot}} of project {{project}} into a safe directory."
  },
  "btTracker": {
    "title": "BT Tracker",
    "sub": "BitTorrent / WebTorrent for file shares",
    "pageDesc": "BitTorrent / WebTorrent for file shares",
    "status": "Status",
    "running": "Running",
    "stopped": "Stopped",
    "installed": "Installed",
    "start": "Start",
    "stop": "Stop",
    "stopTitle": "Stop the tracker — seeding and downloads will interrupt",
    "stopDesc": "Running torrents stop announcing. Peers disconnect until you start the tracker again.",
    "fillPublicHost": "Use {{host}}",
    "fillPublicHostTitle": "Fill the current panel hostname as the public announce host",
    "refresh": "Refresh",
    "settings": "Settings",
    "httpPort": "HTTP / WS port",
    "udpPort": "UDP port",
    "listenHost": "Listen",
    "listenHostHint": "0.0.0.0 listens on every address. Prefer 127.0.0.1 unless peers must reach this host.",
    "listenAllWarn": "Tracker is bound to all addresses. With the firewall off this is public. Bind 127.0.0.1 for local-only, or restrict the port in the firewall.",
    "bindLoopback": "127.0.0.1 only",
    "bindAll": "0.0.0.0 (all)",
    "wsEnabled": "WebSocket",
    "wsEnabledHint": "",
    "autostart": "Autostart",
    "autostartHint": "",
    "publicAnnounceHost": "Public host",
    "publicAnnounceHostHint": "",
    "maxSeeds": "Max seeds",
    "seederPorts": "Peer ports",
    "seederPortMin": "Peer port start",
    "seederPortMax": "Peer port end",
    "seederPortsHint": "Inclusive range used by the local seeder (typically 6881–6889).",
    "saveSettings": "Save",
    "applyHint": "",
    "torrents": "Torrents",
    "torrentsEmpty": "No torrents",
    "torrentsEmptyHint": "Add a .torrent, or create a BT share in Files",
    "torrentsDesc": "",
    "colName": "Name",
    "colHash": "Hash",
    "colSeeds": "Seeds",
    "colLeechers": "Leechers",
    "colStatus": "Status",
    "announceUrls": "Announce",
    "announceDesc": "",
    "copy": "Copy",
    "copied": "Copied",
    "statsTorrents": "Torrents",
    "statsLibrary": "Library",
    "statsLibraryHint": "Torrents in the panel library / file shares",
    "statsTrackerLeftover": "Tracker hashes not in library",
    "statsTrackerLeftoverHint": "Info-hashes the local tracker has announced that are not torrent-library rows. Listed on the Tracker tab.",
    "leftoverHashesTitle": "Tracker leftover hashes",
    "publicHostMissingLive": "Tracker is listening but public announce host is not set. Off-host peers cannot find this seed.",
    "leftoverHashesHint": "Read-only. These announces are not library or share rows.",
    "statsPeers": "Peers",
    "statsAnnounces": "Announces",
    "statsAnnouncesHint": "Announce requests seen by the tracker process",
    "statsJobs": "Jobs",
    "openShares": "Shares",
    "needExecute": "YSK_EXECUTE required to bind ports",
    "guideTitle": "About",
    "guideBody": "BT shares build a .torrent and exchange peers via this tracker.",
    "restoreSeeds": "Re-seed",
    "restoreSeedsHint": "Restart local seeds",
    "bundledNote": "",
    "stackTitle": "Software",
    "jobs": "Jobs",
    "jobsEmpty": "No jobs",
    "jobsEmptyHint": "",
    "jobsDesc": "",
    "colJob": "Job",
    "colShare": "Share",
    "colJobStatus": "Status",
    "colEnqueued": "Time",
    "refreshJobs": "Refresh",
    "tabOverview": "Overview",
    "tabTorrents": "Torrents",
    "tabJobs": "Jobs",
    "tabSettings": "Settings",
    "tabAbout": "About",
    "heroRunning": "Running",
    "heroStopped": "Stopped",
    "heroRunningSub": "",
    "heroStoppedSub": "",
    "live": "Live",
    "liveOff": "Idle",
    "quickStart": "Steps",
    "quickStartDesc": "",
    "step1Title": "Public host",
    "step1Hint": "",
    "step2Title": "Start",
    "step2Hint": "",
    "step3Title": "BT share",
    "step3Hint": "",
    "stepDone": "Done",
    "stepTodo": "Todo",
    "networkCard": "Network",
    "networkCardDesc": "",
    "seederCard": "Seeder",
    "seederCardDesc": "",
    "lifecycleCard": "Lifecycle",
    "lifecycleCardDesc": "",
    "pid": "PID",
    "port": "Port",
    "announceHost": "Host",
    "goSettings": "Settings",
    "searchTorrents": "Search…",
    "filterAll": "All",
    "filterSeeding": "Seeding",
    "filterOther": "Other",
    "noMatch": "No matches",
    "seedStatusSeeding": "Seeding",
    "seedStatusPending": "Pending",
    "seedStatusError": "Error",
    "seedStatusStopped": "Stopped",
    "seedStatusNone": "None",
    "notesTitle": "Notes",
    "exposureTitle": "Access",
    "protoHttp": "HTTP",
    "protoWs": "WS",
    "protoUdp": "UDP",
    "saveOk": "Saved",
    "saveOkRestart": "Saved — restart tracker to apply ports",
    "startedOk": "Started",
    "stoppedOk": "Stopped",
    "restoredOk": "Re-seed done",
    "restoredCount": "Re-seeded {{seeded}} of {{attempted}} torrents",
    "portInvalid": "Enter a port from 1 to 65535.",
    "extraTrackerRequired": "Enter an announce URL.",
    "stopPort": "Tracker port {{port}} will stop listening.",
    "stopPid": "Process PID {{pid}} will exit.",
    "swarmLeftoverUnlisted": "{{count}} extra leftover announce(s) have no hash in this list.",
    "httpPortHint": "",
    "udpPortHint": "",
    "udpPortOff": "Off",
    "udpPortSameHttp": "Same HTTP ({{port}})",
    "udpPortClassic": "6969",
    "portSuggest8000": "8000",
    "announceHostUnset": "Not set",
    "tabTrackers": "Trackers",
    "addTorrent": "Add torrent",
    "addTorrentTitle": "Add torrent",
    "addTorrentHint": "Upload a .torrent or paste a magnet. After the file is read, pick where to save. WebTorrent downloads missing files and seeds when complete.",
    "dropTorrent": "Drop a .torrent here",
    "chooseFile": "or choose a file",
    "magnetLabel": "Magnet",
    "magnetPlaceholder": "magnet:?xt=urn:btih:…",
    "inspect": "Read",
    "extraTrackersPreview": "Will also announce to {{n}} extra tracker(s)",
    "saveLocation": "Save location",
    "saveRootPublic": "Public files",
    "newFolder": "New folder",
    "destPreview": "Will write to",
    "startDownload": "Start download",
    "filterDownloading": "Downloading",
    "filterPaused": "Paused",
    "filterError": "Error",
    "emptyDrop": "Drop a .torrent here, or choose a file",
    "emptyHint": "Drop a .torrent or paste a magnet. After it is read, the dialog asks where to save. Complete files seed on this host. Engine: WebTorrent.",
    "pause": "Pause",
    "resume": "Resume",
    "openFolder": "Open folder",
    "remove": "Remove",
    "removeKeep": "Remove, keep files",
    "removeDelete": "Remove and delete files",
    "removeConfirm": "Remove this torrent from the library?",
    "kindShare": "Share",
    "filesInTorrent": "files",
    "extraTrackersDesc": "Extra announce URLs. Library download/seed and file-share seeds use them in addition to the .torrent list. This does not open the local tracker to arbitrary swarms.",
    "extraTrackersEmpty": "No extra trackers. Add HTTP(S), UDP, or WS(S) announce URLs so this host can find peers.",
    "extraTrackerAdd": "Add",
    "extraTrackerUrl": "Announce URL",
    "extraTrackerApply": "Apply to current seeds",
    "extraTrackerApplyOk": "Applied extra trackers",
    "extraEnabled": "On",
    "extraTrackerBad": "URL must start with http://, https://, udp://, ws://, or wss://",
    "extraTrackerDup": "Already listed",
    "extraTrackerLimit": "Maximum 32 extra trackers",
    "addOk": "Added to library",
    "savedTo": "Save",
    "folderEmpty": "No subfolders",
    "needTorrentFile": "Choose a .torrent file",
    "torrentTooBig": ".torrent larger than 8 MiB",
    "seedStatusDownloading": "Downloading",
    "seedStatusChecking": "Checking",
    "seedStatusPaused": "Paused",
    "seedStatusQueued": "Queued",
    "swarmLeftover": "Tracker has {{count}} announce(s) not in the library",
    "addSourceSection": "Source",
    "addSourceFile": "File",
    "addSourceMagnet": "Magnet",
    "previewSection": "Preview",
    "saveRoot": "Root",
    "clearFile": "Clear file",
    "extraTrackersTitle": "Extra announce",
    "extraTrackersEmptyTitle": "No extra trackers yet",
    "extraEnabledCount": "{{count}} enabled",
    "extraApplyHint": "Enable at least one tracker to apply to current seeds",
    "destMode": "How to use this folder",
    "seedExisting": "Seed existing files",
    "downloadNewFolder": "Download into a new folder",
    "destFileConflict": "A file named {{name}} already exists here. Pick another folder, or seed the existing file if it matches.",
    "waitingPeers": "Waiting for peers. If the files are already on this host, add again and choose Seed existing files."
  },
  "catalog": {
    "sw": {
      "vsftpd": "vsftpd (FTPS)",
      "db_util": "db-util (FTP user DB)",
      "nginx": "Nginx",
      "certbot": "Certbot (Let's Encrypt)",
      "mysql_client": "MySQL/MariaDB client",
      "mysql_server": "MySQL server",
      "mariadb_server": "MariaDB server",
      "postgresql_client": "PostgreSQL client",
      "postgresql": "PostgreSQL server",
      "redis_tools": "Redis client",
      "redis_server": "Redis server",
      "ufw": "UFW firewall",
      "fail2ban": "fail2ban",
      "postfix": "Postfix",
      "dovecot": "Dovecot",
      "opendkim": "OpenDKIM",
      "pdns_server": "PowerDNS",
      "git": "Git",
      "node": "Node.js",
      "php": "PHP",
      "python": "Python",
      "go": "Go",
      "rust": "Rust",
      "chromium": "Chromium / Chrome"
    },
    "php": {
      "session": "Session",
      "opcache": "OPcache"
    }
  },
  "cdn": {
    "fromProjectOk": "CDN site created from project — apply edges / DNS",
    "fromProjectUpdated": "Updated project-bound CDN site",
    "fromProjectFailed": "from-project failed",
    "nodeUpdated": "Node updated",
    "nodeCreated": "Node created",
    "saveFailed": "Save failed",
    "geoMapInvalid": "Invalid geoMap JSON, e.g. {\"hkg\":[\"node-id\"]}",
    "siteUpdated": "Site updated",
    "siteCreated": "Site created",
    "probeOnline": "Probe OK (online)",
    "probeOffline": "Probe failed (offline)",
    "probeFailed": "Probe failed",
    "batchProbeOk": "All nodes probed",
    "batchProbePartial": "Some/all nodes unhealthy",
    "batchProbeFailed": "Batch probe failed",
    "drainingSet": "Set to draining",
    "drainCleared": "Drain cleared",
    "confirmDeleteNode": "Delete this CDN node?",
    "nodeDeleted": "Node deleted",
    "deleteFailed": "Delete failed",
    "confirmDeleteSite": "Delete this CDN site?",
    "siteDeleted": "Site deleted",
    "blocked": "Blocked (needs system-change permission)",
    "previewRender": "Preview render ({{status}}) hash={{hash}}",
    "fanoutDone": "Fan-out done ({{status}})",
    "purgeDone": "Purge done ({{status}})",
    "dnsSyncDone": "DNS sync done ({{status}})",
    "sslDone": "SSL done ({{status}})",
    "confWritten": "Conf written ({{status}})",
    "partialFail": "Not fully successful ({{status}}) — see notes",
    "statNodes": "Nodes",
    "hitNoStats": "No edge stats yet",
    "loopbackOriginBlocked": "Will not apply loopback origin {{url}} to a remote edge. Set a reachable origin first.",
    "applyFailedHint": "Apply failed",
    "applyFailedNoNote": "No stored reason. Re-apply to capture the error.",
    "applyStatus": {
      "draft": "Draft",
      "planned": "Planned",
      "applying": "Applying",
      "applied": "Applied",
      "failed": "Failed",
      "partial": "Partial"
    },
    "statSites": "Sites",
    "statSitesCount": "{{n}} sites",
    "cacheMethod": {
      "none": "No estimate",
      "access_log": "Access log",
      "cache_dir": "Cache directory",
      "log_format": "Need log format"
    },
    "geoMapLabel": "Geo map (JSON)",
    "statApplyFailed": "Apply failed",
    "pillNodesSites": "{{n}} nodes · {{s}} sites",
    "statOnline": "Online",
    "statHit": "Hit rate",
    "hitUnknown": "Unknown",
    "lastHealthHint": "Last probe {{at}} · {{ok}}",
    "lastHealthNever": "Not probed yet — run Probe",
    "lastHealthFail": "probe failed",
    "healthLoopNeedSites": "Add a site first",
    "nodeStatus": {
      "online": "online",
      "offline": "offline",
      "draining": "draining",
      "unknown": "unknown"
    },
    "recentNotes": "Recent notes",
    "previewOnlyNote": "Preview only — nothing was written to the edges.",
    "statByRegion": "Region: ",
    "statByApply": "Apply status: ",
    "col": {
      "origin": "Origin",
      "edges": "Edges",
      "apply": "Apply",
      "dns": "DNS",
      "edgesOnline": "Edges online / applied",
      "dnsRr": "CDN DNS records"
    },
    "mode": {
      "origin_pull": "Origin pull",
      "reverse_proxy": "Reverse proxy",
      "static_edge": "Static edge"
    },
    "dnsStrategy": {
      "multi_a": "Multiple A records",
      "cname": "CNAME",
      "geo": "Geo"
    },
    "edgesOnlineApplied": "{{online}}/{{total}} online · {{applied}} applied",
    "hitMiss": "Hits {{hits}} / misses {{misses}}",
    "cacheBytes": "Cache ≈ {{n}} B",
    "hitRateUnknown": "No access log with cache status and no cache directory, so hit rate cannot be estimated.",
    "edgeConfPreview": "Nginx edge conf preview",
    "tabs": {
      "nodes": "Nodes",
      "sites": "Sites",
      "dashboard": "Dashboard",
      "about": "About"
    },
    "nodesTitle": "CDN nodes ({{count}})",
    "nodesDesc": "Register control-plane, origin, edge, and DNS nodes. Probe refreshes status.",
    "offlineHint": "Offline — probe failed. Remove the node if it is leftover.",
    "colName": "Name",
    "colRole": "Role",
    "colStatus": "Status",
    "clearDrain": "Clear drain",
    "drain": "Drain",
    "drainTitle": "Stop sending new CDN traffic to this edge",
    "drainDesc": "Drain “{{name}}”? Existing connections stay until they finish.",
    "drainLastTitle": "This is the last edge — drain will leave every site without an edge",
    "drainLastDesc": "“{{name}}” is the only edge. Drain it and all sites have no edge.",
    "clearDrainTitle": "Accept new traffic on this edge again",
    "clearDrainDesc": "Clear drain on “{{name}}”?",
    "deleteNodeTitle": "Delete this CDN edge",
    "deleteLastNodeTitle": "Delete the last edge — all sites will have no edge",
    "purge": "Purge",
    "previewTitle": "Preview nginx config (no write)",
    "writeConfTitle": "Write edge nginx config files",
    "applyEdgesTitle": "Apply this site to edges (writes nginx)",
    "purgeTitle": "Purge cache on edges",
    "dnsSyncTitle": "Write CDN DNS records",
    "probeDnsTitle": "Probe edges and DNS (read-only)",
    "distSslTitle": "Copy TLS materials to edges",
    "leIssueTitle": "Issue a Let’s Encrypt certificate and distribute it",
    "deleteSiteTitle": "Delete this CDN site",
    "siteOpConfirmGeneric": "Run this action on “{{name}}”?",
    "siteOpConfirmDesc": "Site “{{name}}” · {{action}}. This can change nginx, DNS, or certificates.",
    "siteOpConfirm": {
      "apply": "Apply this site to edges?",
      "render": "Write nginx config for this site?",
      "purge": "Purge cache for this site?",
      "dns-sync": "Sync DNS for this site?",
      "dist": "Distribute TLS to edges?",
      "issue": "Issue Let’s Encrypt and distribute?"
    },
    "emptyNodesTitle": "No CDN nodes yet",
    "emptyNodesDesc": "Use “+ Add node” to register an edge, then create sites.",
    "sitesTitle": "CDN sites ({{count}})",
    "sitesDesc": "Domain + origin + edges + cache + multi-A DNS. Apply edges / DNS sync / purge.",
    "healthLoopOk": "Health loop finished for all sites",
    "healthLoopPartial": "Health loop partially failed",
    "healthLoopFailed": "health-loop failed",
    "colDomain": "Domain",
    "colMode": "Mode",
    "emptySitesTitle": "No CDN sites yet",
    "emptySitesDesc": "Use “+ Add site” in the table toolbar.",
    "emptySitesNoEdge": "No edges yet: register nodes on the Nodes tab first, then create a site.",
    "dashboardTitle": "CDN dashboard",
    "updatedAt": "Updated {{at}}",
    "dashboardEmpty": "Dashboard not loaded",
    "siteStatus": "Site status",
    "cacheHitEstimate": "Cache hit rate (estimate)",
    "dashboardNotes": "Dashboard notes",
    "editNode": "Edit CDN node",
    "addNode": "Add CDN node",
    "nodeAddrHint": "Fill at least one of IPv4 / IPv6 / healthUrl / baseUrl",
    "sshHostHint": "Empty = use IPv4; 127.0.0.1 = local apply",
    "sshHostPlaceholder": "Leave empty for public IPv4",
    "sshUser": "SSH user",
    "fleetHint": "Fleet only (no SSH): fan-out queues for agent;",
    "fleetPlaceholder": "Agents page session UUID",
    "editSite": "Edit CDN site",
    "addSite": "Add CDN site",
    "originHint": "Origin as URL for now; project binding later",
    "commaSeparated": "Comma-separated",
    "originUrl": "Edge origin URL",
    "edgeNodes": "Edge nodes",
    "cache": "Cache",
    "dnsPolicy": "DNS policy",
    "dnsPolicyHint": "multi_a = multi IP; failover = healthiest only",
    "zoneOptional": "Empty = auto-match zone by domain",
    "sslMode": "SSL mode",
    "sslModeHint": "upload = cert on SSL page; le_http01 = edge ACME",
    "leEmailOptional": "LE email (optional)",
    "leEmailHint": "Prefill for issuance",
    "shieldHint": "Non-shield edges origin via this node",
    "geoMapHint": "For strategy=geo, e.g. {\"hkg\":[\"id1\"],\"nrt\":[\"id2\"]}",
    "geoSubdomain": "Geo subdomain",
    "addNodeBtn": "+ Add node",
    "addSiteBtn": "+ Add site",
    "probeAll": "Probe all",
    "healthLoop": "Health loop",
    "setDraining": "Set draining",
    "fromProjectUpdatedAlt": "Updated project-bound CDN site",
    "refresh": "Refresh",
    "closePreview": "Close preview",
    "probe": "Probe",
    "preview": "Preview",
    "writeConf": "Write conf",
    "applyEdges": "Apply edges",
    "dnsSync": "DNS sync",
    "probeDns": "Probe+DNS",
    "distSsl": "Distribute SSL",
    "leIssue": "LE issue",
    "reaggregate": "Refresh aggregate",
    "createEdgeFirst": "Create an edge node first",
    "enableProxyCache": "Enable proxy_cache",
    "autoMatch": "(auto match)",
    "none": "(none)",
    "writeRegionDns": "Write region subdomain A/AAAA (e.g. hkg)",
    "workflowHint": "Flow: write conf → apply edges → probe+DNS → SSL",
    "healthLoopAll": "Health loop all sites",
    "deleteNodeDesc": "Deletes CDN node \"{{name}}\".",
    "deleteSiteDesc": "Deletes CDN site \"{{name}}\".",
    "deleteSiteC1": "Site policy and edge associations",
    "deleteSiteC2": "Applied nginx configs may need separate cleanup or re-apply",
    "statOnlineOf": "Online {{n}}/{{total}}",
    "colRegion": "Region",
    "statDraining": "Draining {{n}}",
    "statOffline": "Offline {{n}}",
    "localTest": "local / test",
    "statHitRate": "Hit rate {{v}}"
  },
  "cli": {
    "unknownCommand": "Unknown command: {{command}}\nRun `{{cli}} help`",
    "usagePrefix": "Usage:",
    "security": {
      "help": "Usage: ysk-server security status\n       ysk-server security sessions list|revoke|revoke-others [--user U]\n       ysk-server security api-keys list|create|delete …",
      "sessionsHelp": "Usage: ysk-server security sessions list [--user U]\n       ysk-server security sessions revoke --id PREFIX [--user U]\n       ysk-server security sessions revoke-others [--user U] [--keep-token T]",
      "apiKeysHelp": "Usage: ysk-server security api-keys list\n       ysk-server security api-keys create --name N [--user U] [--scope full|read]\n       ysk-server security api-keys delete --id KEY_ID",
      "noUser": "No user found. Create admin first or pass --user <name|id>",
      "tokenOnce": "token shown once — store securely",
      "sessionRevokeUsage": "Usage: ysk-server security sessions revoke --id <sessionIdPrefix> [--user U]",
      "apiKeyDeleteUsage": "Usage: ysk-server security api-keys delete --id KEY_ID"
    },
    "help": {
      "blurb": "Control plane CLI — prefer --json for AI agents.\nDocs: docs/agent/README.md · docs/cli/reference.md · docs/agent/commands.json",
      "main": "{{product}} ({{cli}}) v{{version}}\n\nControl plane CLI — prefer --json for AI agents.\nDocs: docs/agent/README.md · docs/cli/reference.md · docs/agent/commands.json\n\nUsage:\n  {{cli}} <command> [options]\n\nCommands:\n  setup                 Init dataDir + admin\n  update                Self-update check/apply\n  serve                 HTTP API + Web UI\n  system unit-install   Install ysk-server.service [--enable]\n  stack                 plans|bundles|status|install|uninstall\n  tools                 List tools; tools run --tool <name> [--dry-run]\n  ask                   NL → AI plan [--execute]\n  projects              list|get|create|deploy|stop|health|backup|template\n  users                 list|create|totp\n  packages              list\n  rbac                  list|show\n  audit                 list\n  backup                all|list|status|restore|delete|schedule|control-plane|settings|restic\n  templates             App templates\n  hosting               nginx|dns|db|firewall helpers\n  dns                   zone|zones|lookup|ddns\n  logs                  sources|query|journal|overview\n  host                  overview|metrics (read-only)\n  nginx                 status|list|test|sync\n  ssl                   list|get (certificates)\n  db-cluster            list|get|create|plan (HA plan-first)\n  ssh-key               list|create|import|public|export|install|delete (SSH identity vault)\n  ssh-2fa               list|enroll|confirm|install|pam|retire (SSH login TOTP ≠ panel 2FA)\n  services              Host service matrix (systemctl probe)\n  defense | protection  status|ban|unban|whitelist\n  security              status|sessions|api-keys (2FA flags · session revoke · API keys)\n  cdn                   nodes|sites|render|apply|purge|probe|dashboard|health-loop|from-project\n  agents                runtimes|fleet list|commands|register (panel + edge)\n  agent run             Outbound fleet poller (experimental)\n  store                 status|export|import|migrate (json|sqlite|postgres document backends)\n  files                 list|read|write|mkdir|rm|stat|rename|copy|move|chmod|trash|shares (sandbox)\n  cron                  list|create|update|delete|enable|disable|run|install|status|host\n  email                 domains|mailboxes|deliverability|bootstrap|dns (panel parity)\n  health                Local mode snapshot or --url http://host:port/health\n  notifications         list\n  readiness | doctor    Production readiness (honest)\n  migrate               inventory|host|post|status|resume|orphan-homes (full host migrate)\n  vpn                   WireGuard / OpenVPN\n  vnc                   accounts|clients|share\n  apache                sites|settings\n  network               ifaces|exposure|real-ip\n  real-ip               CDN Real IP\n  updates               inventory|apply\n  software              list|install|uninstall\n  db                    MySQL / MariaDB / PostgreSQL\n  redis                 status|keys|get|set\n  ftp                   accounts|status\n  runtimes              list|install\n  bt-tracker            status|settings\n  validators            list|chains|disk|get|checklist (Beta)\n  docker                status|ps|images|compose|prune (engine)\n  version | help\n\nGlobal:\n  --json                JSON stdout (AI)\n  --data-dir PATH       also --data-dir=PATH or YSK_DATA_DIR\n  --config PATH\n  --locale CODE         CLI language (default en). Also YSK_LOCALE.\n                        Codes: en zh-HK zh-CN ja ko hi es ar fr bn pt id ur\n  --limit N --offset N  Slice large JSON lists (software / updates / host metrics / rbac)\n  --help | --version\n\nExit: 0 ok · 1 error · 2 validation · 3 blocked · 4 not found · 5 host error\n\nSafety:\n  Dangerous ops default to dry-run (plan only).\n  Pass --execute (alias --apply) + env YSK_EXECUTE=1 to mutate host.\n  Command names and flags are always English. --locale only translates messages.\n\nExamples:\n  {{cli}} readiness --json\n  {{cli}} host --json\n  {{cli}} nginx status --json\n  {{cli}} ssl list --json\n  {{cli}} projects get --id UUID --json\n  {{cli}} defense ban --ip 1.2.3.4 --json          # dry-run plan\n  {{cli}} projects list --json\n  {{cli}} --locale=zh-HK help\n  {{cli}} logs query --source journal: --lines 100 --json\n  {{cli}} tools --json"
    },
    "usage": {
      "tools": {
        "run": {
          "--tool": {
            "name": {
              "--arg": {
                "cd327c": "Usage: ysk-server tools run --tool <name> [--arg key=val] [--dry-run]\n"
              }
            }
          }
        }
      },
      "email": {
        "domains": {
          "list": {
            "create": {
              "get": {
                "b94a62": "Usage: ysk-server email domains list|create|get …\n"
              }
            }
          },
          "create": {
            "--domain": {
              "example": {
                "bd4036": "Usage: ysk-server email domains create --domain example.com --ip A.B.C.D\n"
              }
            }
          }
        },
        "mailboxes": {
          "list": {
            "create": {
              "42b26c": "Usage: ysk-server email mailboxes list|create …\n"
            }
          },
          "create": {
            "--domain": {
              "example": {
                "7227f3": "Usage: ysk-server email mailboxes create --domain example.com --local user [--password P]\n"
              }
            }
          }
        },
        "dns": {
          "--domain": {
            "example": {
              "com": {
                "26b806": "Usage: ysk-server email dns --domain example.com\n"
              }
            }
          }
        },
        "sub": {
          "--data-dir": {
            "path": {
              "--json": {
                "73dad0": "Usage: ysk-server email <sub> [--data-dir PATH] [--json]\n  domains list|create|get [--q TEXT]\n    create --domain example.com --ip A.B.C.D\n    get --domain example.com | --id UUID\n  mailboxes list|create [--domain D | --id domainId]\n    create --domain D --local user [--password P]\n  deliverability --domain D | --id UUID\n  deliverability-overview\n  bootstrap --domain D --ip A.B.C.D [--install]\n  dns --domain D | --id UUID     # DNS bundle for panel\nAlso: hosting email-apply|email-mailbox|email-deliverability (aliases)\n"
              }
            }
          }
        },
        "deliverability": {
          "--domain": {
            "example": {
              "com": {
                "b0dff0": "Usage: ysk-server email deliverability --domain example.com\n"
              }
            }
          }
        },
        "bootstrap": {
          "--domain": {
            "example": {
              "com": {
                "affc8d": "Usage: ysk-server email bootstrap --domain example.com --ip 1.2.3.4 [--install]\n"
              }
            }
          }
        }
      },
      "cron": {
        "delete": {
          "--id": {
            "job": {
              "id": {
                "f6aafe": "Usage: ysk-server cron delete --id JOB_ID\n"
              }
            }
          }
        },
        "sub": {
          "--id": {
            "job": {
              "id": {
                "99cfdf": "Usage: ysk-server cron {{sub}} --id JOB_ID\n"
              }
            }
          },
          "--data-dir": {
            "path": {
              "--json": {
                "0349e6": "Usage: ysk-server cron <sub> [--data-dir PATH] [--json]\n  list [--project-id ID] [--q TEXT]\n  create --schedule \"0 3 * * *\" --command CMD [--project-id ID] [--user USER]\n  update --id JOB_ID [--schedule S] [--command CMD] [--user USER] [--project-id ID] [--enable|--disable]\n  delete --id JOB_ID\n  enable|disable --id JOB_ID\n  run --id JOB_ID              # run-now (needs YSK_EXECUTE=1)\n  install                     # load managed crontab (needs EXECUTE)\n  status                      # probe managed file vs host crontab\n  host [list] [--user USER] [--jobs-only]\n  host edit --user USER --old-schedule S --old-command C --schedule S --command C --execute\n  host disable|enable|delete|adopt --user USER --old-schedule S --old-command C --execute\n  host run --user USER --command C --execute\nHonesty: install / host write blocked without YSK_EXECUTE=1.\n"
              }
            }
          }
        },
        "run": {
          "--id": {
            "job": {
              "id": {
                "a0a97f": "Usage: ysk-server cron run --id JOB_ID\n"
              }
            }
          }
        },
        "create": {
          "--schedule": {
            "0": {
              "3": {
                "9a8328": "Usage: ysk-server cron create --schedule \"0 3 * * *\" --command CMD [--project-id ID] [--user USER]\n"
              }
            }
          }
        }
      },
      "files": {
        "stat": {
          "--path": {
            "rel": {
              "17c8f2": "Usage: ysk-server files stat --path REL\n"
            }
          }
        },
        "read": {
          "--path": {
            "rel": {
              "e35f8d": "Usage: ysk-server files read --path REL\n"
            }
          }
        },
        "mkdir": {
          "--path": {
            "rel": {
              "ae0438": "Usage: ysk-server files mkdir --path REL\n"
            }
          }
        },
        "rm": {
          "--path": {
            "rel": {
              "--permanent": {
                "fe2051": "Usage: ysk-server files rm --path REL [--permanent]\n"
              }
            }
          }
        },
        "rename": {
          "--from": {
            "rel": {
              "--to": {
                "35a260": "Usage: ysk-server files rename --from REL --to REL\n"
              }
            }
          }
        },
        "copy": {
          "--from": {
            "rel": {
              "--to": {
                "5337f4": "Usage: ysk-server files copy --from REL --to REL\n"
              }
            }
          }
        },
        "move": {
          "--from": {
            "rel": {
              "--to": {
                "75cf5d": "Usage: ysk-server files move --from REL --to REL\n"
              }
            }
          }
        },
        "chmod": {
          "--path": {
            "rel": {
              "--mode": {
                "39f983": "Usage: ysk-server files chmod --path REL --mode 644\n"
              }
            }
          }
        },
        "trash": {
          "restore": {
            "--id": {
              "trash": {
                "c89ce9": "Usage: ysk-server files trash restore --id TRASH_ID\n"
              }
            }
          },
          "list": {
            "restore": {
              "purge": {
                "ef063d": "Usage: ysk-server files trash list|restore|purge\n"
              }
            }
          }
        },
        "shares": {
          "list": {
            "ac342c": "Usage: ysk-server files shares list\n"
          }
        },
        "webdav": {
          "status": {
            "token": {
              "disable": {
                "f8e94b": "Usage: ysk-server files webdav status|token|disable\n"
              }
            }
          }
        },
        "sub": {
          "--root": {
            "public": {
              "project": {
                "42ebd4": "Usage: ysk-server files <sub> [--root public|project:ID] [--data-dir PATH] [--json]\n  list   [--path DIR] [--q TEXT] [--sort name|size|mtime] [--order asc|desc]\n  stat   --path REL\n  read   --path REL\n  write  --path REL --content TEXT | --file LOCAL\n  mkdir  --path REL\n  rm     --path REL [--permanent]\n  rename --from REL --to REL\n  copy   --from REL --to REL\n  move   --from REL --to REL\n  chmod  --path REL --mode 644\n  trash  list|restore|purge [--id TRASH_ID]\n  shares list\n  favorites list\n  upload --dir REL --file LOCAL [--file LOCAL2…]\n  webdav status|token|disable\nSandbox: only public files root or project home (path-constrained).\n"
              }
            }
          }
        },
        "write": {
          "--path": {
            "rel": {
              "--content": {
                "0addb1": "Usage: ysk-server files write --path REL --content TEXT | --file LOCAL\n"
              }
            }
          }
        },
        "upload": {
          "--dir": {
            "rel": {
              "--file": {
                "f8c3bf": "Usage: ysk-server files upload --dir REL --file LOCAL [--file LOCAL2…]\n"
              }
            }
          }
        }
      },
      "store": {
        "import": {
          "--in": {
            "file": {
              "json": {
                "5b6fdd": "Usage: ysk-server store import --in FILE.json\n"
              }
            }
          }
        },
        "sub": {
          "--data-dir": {
            "path": {
              "--json": {
                "d580e4": "Usage: ysk-server store <sub> [--data-dir PATH] [--json]\n  status                         Show backend kind + counts\n  export --out FILE.json         Dump document snapshot\n  import --in FILE.json          Overwrite snapshot from file\n  migrate --to sqlite|json [--out PATH]\n    Copy current store into another backend file\nEnv: YSK_STORE=json|sqlite|postgres  YSK_DATABASE_URL=postgres://…\nHonesty: document-blob backends (not full relational schema yet).\n"
              }
            }
          }
        },
        "migrate": {
          "--to": {
            "json": {
              "sqlite": {
                "1c52a3": "Usage: ysk-server store migrate --to json|sqlite [--out PATH]\n  (postgres: export JSON then import under YSK_DATABASE_URL)\n"
              }
            }
          }
        }
      },
      "cdn": {
        "nodes": {
          "delete": {
            "--id": {
              "node": {
                "0c6a1e": "Usage: ysk-server cdn nodes delete --id NODE_ID\n"
              }
            }
          },
          "drain": {
            "--id": {
              "node": {
                "a8aa81": "Usage: ysk-server cdn nodes drain --id NODE_ID [--off]\n"
              }
            }
          },
          "list": {
            "upsert": {
              "delete": {
                "52549e": "Usage: ysk-server cdn nodes list|upsert|delete|probe|drain …\n"
              }
            }
          },
          "upsert": {
            "--name": {
              "name": {
                "8f6f39": "Usage: ysk-server cdn nodes upsert --name NAME [--id ID] [--base-url U] [--fleet-agent-id S] [--ssh-host H] [--region R]\n"
              }
            }
          }
        },
        "sites": {
          "get": {
            "--id": {
              "site": {
                "3c3c35": "Usage: ysk-server cdn sites get --id SITE_ID\n"
              }
            }
          },
          "delete": {
            "--id": {
              "site": {
                "51ef8f": "Usage: ysk-server cdn sites delete --id SITE_ID\n"
              }
            }
          },
          "list": {
            "get": {
              "upsert": {
                "609da6": "Usage: ysk-server cdn sites list|get|upsert|delete …\n"
              }
            }
          },
          "upsert": {
            "--name": {
              "n": {
                "6ebb75": "Usage: ysk-server cdn sites upsert --name N --domains a.com,b.com [--edge-id ID]… [--origin-url U] [--origin-project ID]\n"
              }
            }
          }
        },
        "render": {
          "--site-id": {
            "id": {
              "--dry-run": {
                "2149eb": "Usage: ysk-server cdn render --site-id ID [--dry-run]\n"
              }
            }
          }
        },
        "apply": {
          "--site-id": {
            "id": {
              "--edge-id": {
                "a527b3": "Usage: ysk-server cdn apply --site-id ID [--edge-id EDGE]\n"
              }
            }
          }
        },
        "purge": {
          "--site-id": {
            "id": {
              "--edge-id": {
                "bc08ec": "Usage: ysk-server cdn purge --site-id ID [--edge-id EDGE]\n"
              }
            }
          }
        },
        "dns-sync": {
          "--site-id": {
            "id": {
              "--apply-zone": {
                "343068": "Usage: ysk-server cdn dns-sync --site-id ID [--apply-zone]\n"
              }
            }
          }
        },
        "sub": {
          "--data-dir": {
            "path": {
              "--json": {
                "092842": "Usage: ysk-server cdn <sub> [--data-dir PATH] [--json]\n  nodes list|upsert|delete|probe|drain\n  sites list|upsert|delete|get\n  render --site-id ID [--dry-run]\n  apply  --site-id ID [--edge-id ID]   # fan-out (fleet queue ok without EXECUTE)\n  purge  --site-id ID [--edge-id ID]\n  dns-sync --site-id ID [--apply-zone]\n  probe | dashboard | health-loop [--apply-zone]\n  from-project --project-id ID [--edge-id ID…]\nHonesty: apply_status written/queued ≠ edge nginx applied until agent ack / EXECUTE reload.\n"
              }
            }
          }
        },
        "from-project": {
          "--project-id": {
            "id": {
              "--edge-id": {
                "a96f42": "Usage: ysk-server cdn from-project --project-id ID [--edge-id ID]…\n"
              }
            }
          }
        }
      },
      "agents": {
        "fleet": {
          "remove": {
            "--session": {
              "session": {
                "1827fe": "Usage: ysk-server agents fleet remove --session SESSION_ID\n"
              }
            }
          },
          "register": {
            "--id": {
              "agent": {
                "209b2d": "Usage: ysk-server agents fleet register --id AGENT_ID [--group g] [--edge]\n"
              }
            }
          },
          "commands": {
            "--session": {
              "session": {
                "f8067c": "Usage: ysk-server agents fleet commands --session SESSION_ID\n"
              }
            }
          }
        },
        "register": {
          "--id": {
            "agent": {
              "id": {
                "3c4477": "Usage: ysk-server agents register --id AGENT_ID [--group g]\n"
              }
            }
          }
        },
        "commands": {
          "--session": {
            "session": {
              "id": {
                "e620d2": "Usage: ysk-server agents commands --session SESSION_ID\n"
              }
            }
          }
        },
        "runtimes": {
          "probe": {
            "fleet": {
              "list": {
                "261fa4": "Usage: ysk-server agents [runtimes|probe|fleet list|fleet register|fleet commands|register|commands]\n"
              }
            }
          }
        }
      },
      "agent": {
        "run": {
          "--control-plane": {
            "url": {
              "--id": {
                "cfefbe": "Usage: ysk-server agent run --control-plane URL --id AGENT_ID [--group g]\n"
              }
            }
          }
        }
      },
      "ask": {
        "check": {
          "system": {
            "info": {
              "b0c781": "Usage: ysk-server ask \"check system info\"\n"
            }
          }
        }
      },
      "backup": {
        "delete": {
          "--project-id": {
            "id": {
              "--name": {
                "d66c29": "Usage: ysk-server backup delete --project-id ID --name ARCHIVE\n"
              }
            }
          }
        },
        "restic": {
          "list": {
            "run": {
              "restore": {
                "10402b": "Usage: ysk-server backup restic list|run|restore …\n"
              }
            }
          },
          "restore": {
            "--project-id": {
              "id": {
                "a8f133": "Usage: ysk-server backup restic restore --project-id ID --snapshot SNAP [--dry-run] [--overwrite-home --confirm PHRASE]\n"
              }
            }
          }
        },
        "sub": {
          "--data-dir": {
            "path": {
              "--json": {
                "777243": "Usage: ysk-server backup <sub> [--data-dir PATH] [--json]\n  all                         Backup all project homes (+ remote/restic side when configured)\n  list [--project-id ID] [--q TEXT]\n  status                      Last run + schedule probe\n  restore --project-id ID --name ARCHIVE [--mode full|web|dry-run]\n  delete  --project-id ID --name ARCHIVE\n  schedule [--cron \"0 3 * * *\"] [--install]\n  control-plane               Snapshot ysk.json + config.json\n  control-plane-restore --name ARCHIVE [--mode dry-run|full] [--confirm RESTORE-CONTROL-PLANE]\n  settings [get|set]          Remote / exclusions / restic\n    set --remote-kind local|sftp|s3 --remote-path P [--remote-host H] …\n    set --exclude a,b,c | --exclusions-file FILE\n    set --restic-enable --restic-password P [--restic-repo PATH]\n    set --from-json FILE      # full patch {remote?,exclusions?,restic?}\n  restic list|run|restore     Incremental restic helpers\n"
              }
            }
          }
        },
        "control-plane-restore": {
          "--name": {
            "archive": {
              "--mode": {
                "316a76": "Usage: ysk-server backup control-plane-restore --name ARCHIVE [--mode dry-run|full] [--confirm RESTORE-CONTROL-PLANE]\n"
              }
            }
          }
        },
        "restore": {
          "--project-id": {
            "id": {
              "--name": {
                "bc7041": "Usage: ysk-server backup restore --project-id ID --name ARCHIVE [--mode full|web|dry-run]\n"
              }
            }
          }
        }
      },
      "packages": {
        "list": {
          "--q": {
            "text": {
              "b8e16b": "Usage: ysk-server packages list [--q text]\n"
            }
          }
        }
      },
      "projects": {
        "stop": {
          "--id": {
            "projectid": {
              "b15409": "Usage: ysk-server projects stop --id <projectId>\n"
            }
          }
        },
        "backup": {
          "--id": {
            "projectid": {
              "e62846": "Usage: ysk-server projects backup --id <projectId>\n"
            }
          }
        },
        "health": {
          "--id": {
            "projectid": {
              "e816ec": "Usage: ysk-server projects health --id <projectId>\n"
            }
          }
        },
        "isolation": {
          "provision": {
            "--id": {
              "projectid": {
                "5aff44": "Usage: ysk-server projects isolation provision --id <projectId>\n       ysk-server projects isolation provision-all [--limit 20]\n"
              }
            }
          },
          "backfill-owners": {
            "--owner-user-id": {
              "id": {
                "8691da": "Usage: ysk-server projects isolation backfill-owners --owner-user-id <id>\n"
              }
            }
          },
          "list": {
            "provision": {
              "provision-all": {
                "8e9da3": "Usage: ysk-server projects isolation list|provision|provision-all|backfill-owners\n"
              }
            }
          }
        },
        "get": {
          "--id": {
            "projectid": {
              "name": {
                "b0d532": "Usage: ysk-server projects get --id <projectId|name> [--json]\n"
              }
            }
          }
        },
        "create": {
          "--name": {
            "name": {
              "--domain": {
                "66e857": "Usage: ysk-server projects create --name <name> [--domain d] [--runtime node|php|static|python|go|rust] [--template id] [--git-url URL] [--branch B] [--create-dns] [--create-mail] [--server-ip A.B.C.D] [--server-ipv6 ADDR]\n"
              }
            }
          }
        },
        "deploy": {
          "--id": {
            "projectid": {
              "--entry": {
                "339111": "Usage: ysk-server projects deploy --id <projectId> [--entry f] [--port N] [--fpm|--builtin] [--reload]\n"
              }
            }
          }
        },
        "git-deploy": {
          "--id": {
            "id": {
              "--git-url": {
                "a513f5": "Usage: ysk-server projects git-deploy --id ID [--git-url URL] [--branch|--ref main] [--no-redeploy] [--depth 1] [--entry f]\n"
              }
            }
          }
        },
        "template": {
          "--id": {
            "projectid": {
              "--template": {
                "591ce4": "Usage: ysk-server projects template --id <projectId> --template <id> [--force]\n"
              }
            }
          }
        },
        "list": {
          "get": {
            "create": {
              "deploy": {
                "253b48": "Usage: ysk-server projects list|get|create|deploy|git-deploy|git|stop|backup|template|ftp|health [options]\n  deploy --id UUID [--entry f] [--port N] [--fpm|--builtin] [--reload]\n  git-deploy --id UUID [--git-url URL] [--branch|--ref B] [--no-redeploy]\n  git status|log|fetch|checkout|reset|auth|hook|deploy --id UUID [--ref R] [--unshallow] [--yes]\n  git auth --id UUID --token T|--deploy-key|--pin-host\n  git hook --id UUID --enable|--rotate|--disable\n  ftp --id UUID --password P [--user NAME] [--home app|root]\n"
              }
            }
          }
        }
      },
      "cli": {
        "name": {
          "db-cluster": {
            "get": {
              "--id": {
                "00f803": "Usage: {{CLI_NAME}} db-cluster get --id UUID [--json]\n"
              }
            },
            "plan": {
              "--id": {
                "483f52": "Usage: {{CLI_NAME}} db-cluster plan --id UUID [--json]\n"
              }
            },
            "artifacts": {
              "--id": {
                "6b33c4": "Usage: {{CLI_NAME}} db-cluster artifacts --id UUID [--json]\n"
              }
            },
            "bundle": {
              "--id": {
                "94ed27": "Usage: {{CLI_NAME}} db-cluster bundle --id UUID [--json]\n"
              }
            },
            "delete": {
              "--id": {
                "3de0e4": "Usage: {{CLI_NAME}} db-cluster delete --id UUID [--json]\n"
              }
            },
            "create": {
              "--name": {
                "e3b733": "Usage: {{CLI_NAME}} db-cluster create --name N --engine mariadb --kind mariadb-galera --member HOST=role[:access] ...\n"
              }
            },
            "apply": {
              "--id": {
                "4cddb8": "Usage: {{CLI_NAME}} db-cluster apply --id UUID [--execute] [--bootstrap] [--json]\n"
              }
            },
            "probe": {
              "--id": {
                "22870c": "Usage: {{CLI_NAME}} db-cluster probe --id UUID [--peers] [--json]\n"
              }
            },
            "install-peers": {
              "--id": {
                "600b02": "Usage: {{CLI_NAME}} db-cluster install-peers --id UUID [--execute] [--no-restart] [--identity ID] [--json]\n"
              }
            },
            "push": {
              "--id": {
                "697080": "Usage: {{CLI_NAME}} db-cluster push --id UUID [--member ID] [--identity ID] [--execute] [--json]\n"
              }
            },
            "fleet": {
              "--id": {
                "239462": "Usage: {{CLI_NAME}} db-cluster fleet --id UUID [--op apply|probe|plan] [--execute] [--edge-execute] [--json]\n"
              }
            },
            "list": {
              "get": {
                "3b9cfa": "Usage: {{CLI_NAME}} db-cluster list|get|create|plan|apply|probe|install-peers|artifacts|bundle|push|fleet|overview|delete [--peers] [--execute] [--json]\n"
              }
            }
          },
          "ssh-key": {
            "get": {
              "--id": {
                "292716": "Usage: {{CLI_NAME}} ssh-key get --id UUID [--json]\n"
              }
            },
            "public": {
              "--id": {
                "525d7d": "Usage: {{CLI_NAME}} ssh-key public --id UUID\n"
              }
            },
            "export": {
              "--id": {
                "0a6d81": "Usage: {{CLI_NAME}} ssh-key export --id UUID [--out PATH] [--json]\n"
              }
            },
            "delete": {
              "--id": {
                "a6e2f2": "Usage: {{CLI_NAME}} ssh-key delete --id UUID [--json]\n"
              }
            },
            "create": {
              "--name": {
                "8b1d79": "Usage: {{CLI_NAME}} ssh-key create --name N [--algo ed25519|rsa-4096] [--purpose user|panel|unbound] [--project ID] [--user U] [--home PATH] [--reveal] [--json]\n"
              }
            },
            "import": {
              "--name": {
                "6eb800": "Usage: {{CLI_NAME}} ssh-key import --name N --file PATH [--purpose panel|user] [--json]\n"
              }
            },
            "install": {
              "--id": {
                "b99c56": "Usage: {{CLI_NAME}} ssh-key install --id UUID [--execute] [--json]\n"
              }
            },
            "test": {
              "--id": {
                "e1aed3": "Usage: {{CLI_NAME}} ssh-key test --id UUID --target user@host[:port] [--execute] [--json]\n"
              }
            },
            "rotate": {
              "--id": {
                "9c3224": "Usage: {{CLI_NAME}} ssh-key rotate --id UUID [--reveal] [--json]\n"
              }
            },
            "authorize-self": {
              "--id": {
                "b7ea2e": "Usage: {{CLI_NAME}} ssh-key authorize-self --id UUID [--json]\n"
              }
            },
            "uninstall": {
              "--id": {
                "afcba0": "Usage: {{CLI_NAME}} ssh-key uninstall --id UUID [--execute] [--json]\n"
              }
            },
            "list": {
              "get": {
                "2c92c6": "Usage: {{CLI_NAME}} ssh-key list|get|create|import|public|export|install|test|rotate|authorize-self|uninstall|delete [--json]\n"
              }
            }
          },
          "ssh-2fa": {
            "reveal": {
              "--id": {
                "a6c27f": "Usage: {{CLI_NAME}} ssh-2fa reveal --id UUID [--json]\n"
              }
            },
            "retire": {
              "--id": {
                "6e1fa3": "Usage: {{CLI_NAME}} ssh-2fa retire --id UUID [--json]\n"
              }
            },
            "enroll": {
              "--user": {
                "081432": "Usage: {{CLI_NAME}} ssh-2fa enroll --user LINUX|--project ID [--home PATH] [--from-panel] [--json]\n"
              }
            },
            "confirm": {
              "--id": {
                "9ee8a2": "Usage: {{CLI_NAME}} ssh-2fa confirm --id UUID --code 123456 [--json]\n"
              }
            },
            "install": {
              "--id": {
                "dace06": "Usage: {{CLI_NAME}} ssh-2fa install --id UUID [--execute] [--json]\n"
              }
            },
            "uninstall": {
              "--id": {
                "0bb464": "Usage: {{CLI_NAME}} ssh-2fa uninstall --id UUID [--execute] [--json]\n"
              }
            },
            "list": {
              "enroll": {
                "802ed0": "Usage: {{CLI_NAME}} ssh-2fa list|enroll|confirm|install|uninstall|pam|reveal|retire [--json]\n"
              }
            }
          },
          "ssl": {
            "list": {
              "get": {
                "79c232": "Usage: {{CLI_NAME}} ssl list|get --domain X [--json]\n"
              }
            },
            "get": {
              "--domain": {
                "91c444": "Usage: {{CLI_NAME}} ssl get --domain example.com [--json]\n"
              }
            }
          },
          "dns": {
            "zone": {
              "--zone": {
                "ad30fa": "Usage: {{CLI_NAME}} dns zone --zone example.com --ip A.B.C.D [--ipv6 X:X::X] [--validate] [--reload]\n"
              }
            },
            "zones": {
              "zone": {
                "5b8bda": "Usage: {{CLI_NAME}} dns zones|zone --zone X --ip A.B.C.D [--ipv6 …] [--json]\n"
              }
            }
          },
          "nginx": {
            "status": {
              "list": {
                "d67a16": "Usage: {{CLI_NAME}} nginx status|list|test|sync [--execute] [--json]\n"
              }
            }
          },
          "host": {
            "overview": {
              "metrics": {
                "93c828": "Usage: {{CLI_NAME}} host overview|metrics|network [--path /] [--json]\n"
              }
            }
          },
          "logs": {
            "sources": {
              "overview": {
                "79058c": "Usage: {{CLI_NAME}} logs sources|overview|units|journal|query [--source id] [--json]\n"
              }
            }
          },
          "services": {
            "sub": {
              "--unit": {
                "4fe3fa": "Usage: {{CLI_NAME}} services {{sub}} --unit <systemd-unit> [--execute] [--json]\n"
              }
            },
            "matrix": {
              "start": {
                "4f3a35": "Usage: {{CLI_NAME}} services matrix|start|stop|restart|reload --unit NAME [--execute] [--json]\n"
              }
            }
          },
          "defense": {
            "ban": {
              "--ip": {
                "cc22de": "Usage: {{CLI_NAME}} defense ban --ip <ip> [--method fail2ban|ufw|both] [--reason t] [--execute]\n"
              }
            },
            "unban": {
              "--ip": {
                "46aa23": "Usage: {{CLI_NAME}} defense unban --ip <ip> [--method fail2ban|ufw|both] [--execute]\n"
              }
            },
            "whitelist": {
              "--action": {
                "c1cbdf": "Usage: {{CLI_NAME}} defense whitelist --action list|add|remove [--ip IP]\n"
              }
            },
            "status": {
              "bans": {
                "a8d96b": "Usage: {{CLI_NAME}} defense status|bans|suspects|ban|unban|whitelist|stack-apply|fail2ban|firewall|timeline|presets [--json]\n  bans [--q text] [--source fail2ban|panel|ufw|auto]\n  suspects [--q text]\n  stack-apply [--execute]   # UFW + fail2ban + current preset\n  fail2ban | firewall       # deep probes (honest)\n  timeline [--limit N] [--q text]\n  presets                   # list + activePreset\n"
              }
            }
          }
        }
      },
      "system": {
        "unit-install": {
          "--enable": {
            "--data-dir": {
              "path": {
                "33daa1": "Usage: ysk-server system unit-install [--enable] [--data-dir PATH]\n"
              }
            }
          }
        }
      },
      "users": {
        "create": {
          "--username": {
            "u": {
              "--password": {
                "7145c7": "Usage: ysk-server users create --username <u> --password <p> [--role operator|viewer|admin] [--package-id id] [--locale zh-HK]\n"
              }
            }
          }
        },
        "list": {
          "--q": {
            "text": {
              "--role": {
                "544685": "Usage: ysk-server users list [--q text] [--role admin|operator|viewer]\n       ysk-server users create --username u --password p [--role operator]\n"
              }
            }
          }
        }
      },
      "rbac": {
        "list": {
          "policies": {
            "330ade": "Usage: ysk-server rbac list|policies\n       ysk-server rbac show --role operator\n       ysk-server rbac audit   # route→cap sample matrix\n"
          }
        }
      },
      "hosting": {
        "postgres-provision": {
          "--db": {
            "name": {
              "--user": {
                "2c8889": "Usage: ysk-server hosting postgres-provision --db NAME --user U --password P(min8) [--execute]\n  Default dry-run (no host change). Pass --execute + YSK_EXECUTE=1 to apply.\n"
              }
            }
          }
        },
        "mysql-provision": {
          "--db": {
            "name": {
              "--user": {
                "fc25aa": "Usage: ysk-server hosting mysql-provision --db NAME --user U --password P(min8) [--execute]\n  Default dry-run (no host change). Pass --execute + YSK_EXECUTE=1 to apply.\n"
              }
            }
          }
        },
        "dns-zone": {
          "--zone": {
            "example": {
              "com": {
                "bdaa0d": "Usage: ysk-server hosting dns-zone --zone example.com --ip A.B.C.D [--ipv6 X:X::X] [--validate] [--reload]\n"
              }
            }
          }
        },
        "powerdns-load": {
          "--zone": {
            "example": {
              "com": {
                "dba49c": "Usage: ysk-server hosting powerdns-load --zone example.com --ip A.B.C.D [--ipv6 X:X::X] [--load|--execute]\n"
              }
            }
          }
        },
        "email-apply": {
          "--domain": {
            "example": {
              "com": {
                "37d350": "Usage: ysk-server hosting email-apply --domain example.com [--install|--execute]\n"
              }
            }
          }
        },
        "email-mailbox": {
          "--domain": {
            "x": {
              "--local": {
                "3d9be3": "Usage: ysk-server hosting email-mailbox --domain X --local user [--password P] [--ip A.B.C.D]\n"
              }
            }
          }
        },
        "ftps-apply": {
          "--domain": {
            "files": {
              "example": {
                "284a7c": "Usage: ysk-server hosting ftps-apply --domain files.example.com [--install|--execute]\n"
              }
            }
          }
        },
        "webmail-apply": {
          "--domain": {
            "webmail": {
              "example": {
                "2ad5b5": "Usage: ysk-server hosting webmail-apply --domain webmail.example.com [--download]\n"
              }
            }
          }
        },
        "public-files": {
          "--domain": {
            "files": {
              "example": {
                "0e9013": "Usage: ysk-server hosting public-files --domain files.example.com [--reload]\n"
              }
            }
          }
        },
        "email-deliverability": {
          "--domain": {
            "example": {
              "com": {
                "8774a4": "Usage: ysk-server hosting email-deliverability --domain example.com\n       ysk-server hosting email-deliverability --id <domainId>\n"
              }
            }
          }
        },
        "email-bootstrap": {
          "--domain": {
            "example": {
              "com": {
                "796da5": "Usage: ysk-server hosting email-bootstrap --domain example.com --ip 1.2.3.4 [--admin postmaster] [--password P] [--install]\n"
              }
            }
          }
        }
      },
      "migrate": {
        "post": {
          "--job": {
            "id": {
              "--data-dir": {
                "6a73cd": "Usage: ysk-server migrate post --job <id> --data-dir PATH --execute\n"
              }
            }
          }
        },
        "host": {
          "--target": {
            "root": {
              "new": {
                "3e94a2": "Usage: ysk-server migrate host --target root@NEW_IP [--identity-file PATH|--identity-id ID] [--password] --execute --data-dir PATH\n"
              }
            }
          }
        }
      },
      "x": {
        "972912": "Usage:\n  ysk-server migrate inventory [--data-dir PATH] --json\n  ysk-server migrate host --target root@IP [--identity-file PATH|--identity-id ID|--password PW] --execute [--maintenance] [--force-wipe-target]\n  ysk-server migrate post --job ID --data-dir PATH --execute   # on target\n  ysk-server migrate status [--job ID]\n  ysk-server migrate resume --job ID --execute\n  ysk-server migrate orphan-homes [--data-dir PATH] --json\n  ysk-server migrate orphan-homes --path /home/ysk-server-UUID --confirm PATH --execute\n"
      },
      "hostingHelp": "Usage: ysk-server hosting <sub>\n  Dangerous ops default dry-run; add --execute (+ YSK_EXECUTE=1) to apply\n  nginx | nginx-sync [--execute]\n  redis-provision | postgres-provision | mysql-provision [--execute]\n  dns-zone --zone X --ip A.B.C.D [--ipv6 X:X::X] [--validate] [--reload]\n  dns-zones | powerdns-status | powerdns-install [--install|--execute]\n  powerdns-load --zone X --ip A.B.C.D [--load|--execute]\n  email-apply --domain X [--install|--execute]\n  email-mailbox --domain X --local user [--password P] [--ip A.B.C.D] [--system]\n  ftps-apply --domain X [--install|--execute]\n  runtimes | runtime-install --kind node|php|python|go|rust --version V [--install|--execute]\n  dovecot-passdb --domain X | --all\n  webmail-apply --domain webmail.example.com [--download]\n  public-files --domain files.example.com [--reload]\n  email-bootstrap --domain example.com --ip A.B.C.D [--install|--execute]\n  email-deliverability --domain example.com   # PTR/DNSBL/warmup pack (honest)\n  firewall-apply [--smtp] [--execute]\n",
      "logsQuery": "Usage: {{CLI_NAME}} logs query --source <id> [--lines N] [--grep G] [--since 1h] [--priority err]\n  source examples: journal:  journal:nginx.service  file:syslog  project:<uuid>\n  {{CLI_NAME}} logs sources --json\n  {{CLI_NAME}} logs journal [--unit nginx.service] --json\n"
    },
    "msg": {
      "domain": {
        "missing": {
          "pass": {
            "5be09b": "Domain missing — pass --ip to create domain first\n"
          }
        }
      },
      "--root": {
        "must": {
          "be": {
            "a84834": "--root must be public or project:<id>\n"
          }
        }
      },
      "need": {
        "--content": {
          "or": {
            "4d7001": "Need --content or --file\n"
          }
        },
        "at": {
          "least": {
            "7d311a": "Need at least one --member HOST[=role][:access]\n"
          }
        }
      },
      "action": {
        "must": {
          "be": {
            "ba14c1": "action must be list|add|remove\n"
          }
        }
      },
      "use": {
        "ysk-server": {
          "backup": {
            "ca67f4": "Use: ysk-server backup control-plane-restore --name ARCHIVE (not restore --project-id control-plane)\n"
          }
        }
      },
      "new": {
        "domain": {
          "requires": {
            "986b78": "New domain requires --ip A.B.C.D (no placeholder defaults)\n"
          }
        }
      },
      "import-sync": {
        "prefers": {
          "fleet": {
            "4d7590": "import-sync prefers fleet clusterSync payload; or --file snapshot.json\n"
          }
        }
      },
      "security": {
        "control": {
          "plane": {
            "f59a63": "SECURITY: control plane bound publicly (0.0.0.0/::). Prefer 127.0.0.1 + reverse proxy / UFW.\n"
          }
        }
      }
    },
    "err": {
      "unknown": {
        "email": {
          "sub": {
            "sub": {
              "e37257": "Unknown email sub: {{sub}}\nRun: ysk-server email help\n"
            }
          }
        },
        "cron": {
          "sub": {
            "sub": {
              "e1a9ed": "Unknown cron sub: {{sub}}\nRun: ysk-server cron help\n"
            }
          }
        },
        "files": {
          "sub": {
            "sub": {
              "07ad7e": "Unknown files sub: {{sub}}\nRun: ysk-server files help\n"
            }
          }
        },
        "store": {
          "sub": {
            "sub": {
              "b7a083": "Unknown store sub: {{sub}}\nRun: ysk-server store help\n"
            }
          }
        },
        "cdn": {
          "subcommand": {
            "sub": {
              "76664f": "Unknown cdn subcommand: {{sub}}\nRun: ysk-server cdn help\n"
            }
          }
        },
        "backup": {
          "subcommand": {
            "sub": {
              "4092ad": "Unknown backup subcommand: {{sub}}\nRun: ysk-server backup help\n"
            }
          }
        }
      }
    },
    "setup": {
      "dryRunOk": "{{product}} setup dry-run OK",
      "dryRunNext": "Re-run without --dry-run to write config and initialize database",
      "weakPassword": "Admin password is weak or default. Pass a strong --admin-password (min 8, not \"admin\"/common defaults), or set YSK_ALLOW_INSECURE_DEFAULTS=1 for local dev only.",
      "weakPasswordShort": "Weak or default admin password rejected",
      "nextStart": "Start (API + Web UI): {{cli}} serve --config {{configPath}}",
      "nextOpen": "Open http://{{host}}:{{port}}/ and login as {{user}}",
      "nextUnit": "Systemd unit template: {{unitPath}}",
      "nextInstall": "Install unit (root + YSK_EXECUTE): {{cli}} system unit-install --enable --data-dir {{dataDir}}",
      "nextExecute": "Production host mutations require YSK_EXECUTE=1 and root",
      "nextGolive": "Go-live: docs/deploy/go-live.md + ysk-server readiness --json",
      "secPassword": "SECURITY: change admin password immediately (bootstrap used a weak/default password)",
      "sec2fa": "SECURITY: enable admin 2FA under Security → Account",
      "secListen": "SECURITY: listening on all interfaces — put behind firewall / reverse proxy; prefer 127.0.0.1 + SSH tunnel for admin",
      "ok": "{{product}} setup completed (database initialized)",
      "okInsecure": "{{product}} setup completed (database initialized) [INSECURE BOOTSTRAP — change password]"
    }
  },
  "common": {
    "all": "All",
    "cancel": "Cancel",
    "confirm": "Confirm",
    "refresh": "Refresh",
    "loading": "Loading…",
    "save": "Save",
    "apply": "Apply",
    "close": "Close",
    "copy": "Copy",
    "copied": "Copied",
    "expandAll": "Expand all",
    "collapseAll": "Collapse all",
    "empty": "Empty",
    "back": "Back",
    "showTechnical": "Show technical details",
    "hideTechnical": "Hide technical details",
    "needExecute": "Needs YSK_EXECUTE",
    "needRoot": "Needs root",
    "needExecuteRoot": "Needs YSK_EXECUTE and root",
    "writtenOnly": "Written to panel data; not applied on host",
    "applyToLive": "Apply to take effect",
    "saveDraft": "Save draft",
    "languageName": "English",
    "languageNative": "English",
    "language": "Language",
    "switchLanguage": "Switch language",
    "showPassword": "Show",
    "hidePassword": "Hide",
    "searchGlobal": "Search pages & resources…",
    "menu": "Menu",
    "processing": "Working…",
    "unavailable": "Not available right now",
    "retry": "Retry",
    "success": "Success",
    "ok": "OK",
    "failed": "Failed",
    "blocked": "Cannot run",
    "status": "Status",
    "port": "Port",
    "url": "URL",
    "actions": "Actions",
    "noData": "No data",
    "input": "Input",
    "pleaseEnter": "Enter {{value}}",
    "pleaseFill": "Please fill in this field",
    "required": "Required",
    "about": "About",
    "more": "More",
    "operation": "Actions",
    "delete": "Delete",
    "edit": "Edit",
    "create": "Create",
    "install": "Install",
    "installing": "Installing…",
    "reprobe": "Re-check",
    "search": "Search",
    "yes": "Yes",
    "no": "No",
    "on": "On",
    "off": "Off",
    "open": "Open",
    "enabled": "Enabled",
    "disabled": "Disabled",
    "installed": "Installed",
    "notInstalled": "Not installed",
    "running": "Running",
    "stopped": "Stopped",
    "ready": "Ready",
    "unknown": "Unknown",
    "normal": "OK",
    "degraded": "Degraded",
    "missing": "Missing",
    "available": "Available",
    "applied": "Applied",
    "notApplied": "Not applied",
    "completed": "Completed",
    "incomplete": "Incomplete",
    "probed": "Probed",
    "notProbed": "Not probed",
    "probe": "Probe",
    "name": "Name",
    "username": "Username",
    "password": "Password",
    "domain": "Domain",
    "host": "Host",
    "version": "Version",
    "type": "Type",
    "mode": "Mode",
    "notes": "Notes",
    "time": "Time",
    "steps": "Steps",
    "target": "Target",
    "package": "Package",
    "panel": "Panel",
    "system": "System",
    "user": "User",
    "project": "Project",
    "database": "Database",
    "mail": "Mail",
    "files": "Files",
    "memory": "Memory",
    "custom": "Custom",
    "static": "Static",
    "lifecycle": "Lifecycle",
    "loadFailed": "Failed to load",
    "saveFailed": "Failed to save",
    "opFailed": "Operation failed",
    "installFailed": "Install failed",
    "createFailed": "Create failed",
    "deleteFailed": "Delete failed",
    "applyFailed": "Apply failed",
    "startFailed": "Start failed",
    "statusLoadFailed": "Failed to load status",
    "downloadFailed": "Download failed",
    "uploadDone": "Uploaded {{count}} file(s)",
    "downloadStarted": "Download started: {{name}}",
    "savedOk": "Saved",
    "noneSelectedShort": "—",
    "unknownError": "Unknown error",
    "writtenSettings": "Settings written",
    "panelBlocked": "Cannot complete this action in the admin panel",
    "partialSuccess": "Operation did not fully succeed",
    "createdOk": "Created",
    "updatedOk": "Updated",
    "deletedOk": "Deleted",
    "applyDone": "Apply completed",
    "applyIncomplete": "Apply incomplete",
    "checking": "Checking…",
    "dismiss": "Close",
    "hide": "Hide",
    "show": "Show",
    "done": "Done",
    "next": "Next",
    "previous": "Previous",
    "redirectedTo": "Opened {{to}} (was {{from}})"
  },
  "cron": {
    "presetCdTrue": "cd app + true (test)",
    "presetCleanTmp": "Clean temp (sample)",
    "presetNpmCron": "npm run cron (if any)",
    "presetAppBin": "Run app binary",
    "presetRsync": "Sync static (sample rsync)",
    "noLinuxUser": "(no linux user) · {{name}}",
    "projectUser": "Project user",
    "panelUser": "ysk · panel / system",
    "system": "System",
    "rootCareful": "root · system (careful)",
    "customUser": "{{user}} · custom",
    "success": "Success",
    "failed": "Failed",
    "noProjects": "No projects yet",
    "noProjectsHint": "Create a project (and preferably a system user) before registering cron",
    "userSuffix": " · user ",
    "mon": "Mon",
    "tue": "Tue",
    "wed": "Wed",
    "thu": "Thu",
    "fri": "Fri",
    "sat": "Sat",
    "sun": "Sun",
    "everyNMin": "Every N minutes",
    "fixedInterval": "Fixed interval",
    "hourly": "Hourly",
    "atMinute": "At minute",
    "daily": "Daily",
    "atTime": "At time",
    "weekly": "Weekly",
    "weekdayTime": "Weekday + time",
    "monthly": "Monthly",
    "dayTime": "Day + time",
    "advanced": "Advanced",
    "customExpr": "Custom expression",
    "everyMinute": "Every minute",
    "everyMinutes": "Every {{n}} minutes",
    "hourlyAt": "Hourly at minute {{n}}",
    "dailyAt": "Daily {{time}}",
    "weeklyNone": "Weekly (no days) {{time}}",
    "weeklyAt": "Weekly {{days}} {{time}}",
    "monthlyAt": "Monthly day {{day}} {{time}}",
    "customAt": "Custom: {{expr}}",
    "frequency": "Schedule frequency",
    "interval": "Interval",
    "fromHour": "From top of hour",
    "intervalMinutes": "Interval minutes",
    "min1": "1 min",
    "minN": "{{n}} min",
    "minuteOfHour": "Minute of each hour",
    "minPad": "{{n}} min",
    "hour": "Hour",
    "minute": "Minute",
    "pickWeekdays": "Pick weekdays",
    "dayOfMonth": "Day of month",
    "dayOfMonthHint": "Skipped if month has no that day",
    "cronExpr": "Crontab expression",
    "cronExprHint": "Five fields: min hour day month weekday (0=Sun)",
    "cronExprPh": "crontab expression",
    "needLinuxUser": "Selected project has no Linux user — create one under project Resources first",
    "boundProject": "Bound to project; run as {{user}} (runuser isolation)",
    "systemJob": "System job; run as {{user}}",
    "writtenManage": "Written to managed crontab (not installed on host yet)",
    "needInstall": "Press Install to system crontab to take effect",
    "createdManageOnly": "Created (management only)",
    "installedSystem": "Installed to system",
    "hostSynced": "Host synced",
    "hostNotInstalled": "Not on host",
    "statusUnknown": "Unknown status",
    "systemCrontab": "System crontab",
    "synced": "Synced",
    "managedLines": "Managed lines",
    "jobsOnlyManage": "Jobs are management-only. System crontab ",
    "hostHasYsk": "includes YSK entries",
    "hostNoYsk": "not installed or no YSK entries",
    "pressInstall": "Registered jobs are not on the system crontab yet — click Install to system.",
    "jobsTab": "Jobs ({{count}})",
    "jobsTabPending": "Jobs ({{count}}) · pending {{pending}}",
    "registeredJobs": "Registered jobs ({{count}})",
    "jobsSub": "Management entries · Install to system after changes",
    "addJob": "+ Add job",
    "noCron": "No cron yet",
    "noCronDesc": "Add a job (top right of list), then install to system crontab",
    "onceInstalled": "Installed before",
    "manageOnly": "Manage only",
    "projectLabel": "Project",
    "systemLevel": "System",
    "runOnce": "Run now",
    "runOnceOk": "Ran once",
    "updatedManage": "Management updated; reinstall to system crontab",
    "updatedManageShort": "Management updated",
    "deletedManage": "Removed from management; reinstall to sync host",
    "installStatus": "Install status",
    "manageVsHost": "Management vs host",
    "hostYsk": "Host YSK",
    "lastInstall": "Last install",
    "installToSystem": "Install to system crontab",
    "installHint": "Install merges host crontab: keeps non-YSK lines and updates panel-managed jobs only",
    "hostPreview": "Host crontab preview",
    "cannotRead": "Cannot read or not installed (needs privileges)",
    "addJobTitle": "Add job",
    "addJobDesc": "Writes management; Install to system for crontab to run",
    "createManageOnly": "Create (management only)",
    "whenRun": "When to run",
    "whenRunHint": "Pick frequency below; advanced mode for raw crontab",
    "userPathHint": "User + command paths follow project home/runtime",
    "pickProject": "— select project —",
    "runAsUser": "Run as user",
    "runAsHint": "Project user syncs the project above; system user = system-level cron",
    "noProjectsYet": "(no projects yet)",
    "runInHome": "Run under project home ({{home}}); wrapped with runuser on save",
    "absPath": "Prefer absolute path",
    "commonCmds": "Common commands ({{runtime}})",
    "actualPreview": "Actual crontab line (preview)",
    "noLinuxName": "This project has no Linux username — create system user under Resources first.",
    "afterCreate": "After create: ",
    "projectParen": "(project {{name}})",
    "systemParen": "(system-level, unbound)",
    "weekLabel": "Weekday",
    "willRun": "Will run",
    "projectNoLinux": "(no linux user)",
    "createManageOnlyParen": "Create (management only)",
    "runAsHintFull": "Project user syncs project above; system user = system-level cron",
    "systemParenFull": "(system-level, unbound)",
    "hostOtherLines": "Host non-YSK lines",
    "hostOtherLinesVal": "{{other}} other ({{total}} host job lines)",
    "deleteTitle": "Delete cron job?",
    "deleteDesc": "Deletes \"{{name}}\". Only control-plane until applied to system crontab.",
    "hostJobs": "Host jobs",
    "hostJobsTitle": "Host crontabs ({{count}})",
    "usersScanned": "Users",
    "filterUser": "User",
    "filterAll": "All users",
    "sourceYsk": "Panel",
    "sourceHost": "Host",
    "noHostJobs": "No crontab jobs in this scope",
    "hostPartial": "Could not read every user crontab (root required)",
    "pendingInstall": "Pending install ({{count}})",
    "pendingStale": "Not written to system crontab for {{days}} day(s) — it will not run.",
    "willNotRun": "Not written to system crontab — will not run.",
    "hourRange": "Hour must be 0–23.",
    "minuteRange": "Minute must be 0–59.",
    "hoursCommon": "Common hours",
    "hoursAll": "All hours",
    "invalidExpr": "Not a valid 5-field cron expression.",
    "needCommand": "Command is required.",
    "needUser": "Choose a project or a system user.",
    "hostCounts": "Host lines",
    "hostCountsVal": "{{ysk}} · other {{other}} · total {{total}}",
    "hostYskYes": "panel lines present",
    "hostYskNo": "no panel lines",
    "emptyHostCrontab": "No crontab for {{user}}.",
    "writtenOnHost": "Written",
    "registeredJobsChip": "Registered",
    "registeredVsWritten": "Registered in the panel vs written to host crontab",
    "installPreviewTitle": "Preview before installing to system crontab",
    "installPreviewDesc": "This merges the YSK block into the host crontab. Existing non-YSK lines stay.",
    "installPreviewMerge": "Install writes a YSK Server crontab merge block. It does not replace the whole crontab.",
    "installPreviewEmpty": "No pending managed jobs — install still refreshes the YSK block.",
    "editJobTitle": "Edit job",
    "editJobDesc": "Changes stay in the panel until you install to the system crontab.",
    "saveJob": "Save (management only)",
    "panelLines": "Panel lines",
    "otherLines": "Other lines",
    "totalLines": "Total",
    "writtenOnHostHint": "Lines already written to the host crontab",
    "registeredJobsHint": "Jobs registered in the panel (including pending install)",
    "pendingInstallCount": "{{n}} pending install",
    "systemJobBadge": "No project · system user",
    "hostEdit": "Edit",
    "hostEditTitle": "Edit host crontab line",
    "hostEditDesc": "Writes this user’s live crontab now. Needs root and YSK_EXECUTE=1. Other lines stay.",
    "hostSave": "Write crontab",
    "hostSaveTitle": "Write this crontab line?",
    "hostSaveDesc": "Replaces the live line for {{user}}. Type EDIT to confirm.",
    "hostDisable": "Disable",
    "hostDisableTitle": "Disable host crontab line?",
    "hostDisableDesc": "Comments the line for {{user}}. Type DISABLE to confirm.",
    "hostEnable": "Enable",
    "hostEnableTitle": "Enable host crontab line?",
    "hostEnableDesc": "Removes the comment for {{user}}. Type ENABLE to confirm.",
    "hostRunTitle": "Run this host command once?",
    "hostRunDesc": "Runs as {{user}} now. Does not change crontab. Type RUN to confirm.",
    "hostAdopt": "Take into panel",
    "hostAdoptTitle": "Take this host line into the panel?",
    "hostAdoptDesc": "Tags the live line # ysk:id and registers it. Next install will not duplicate it. Type ADOPT to confirm.",
    "hostDeleteTitle": "Remove host crontab line?",
    "hostDeleteDesc": "Removes the live line for {{user}}. Type the command to confirm.",
    "hostUserLocked": "Crontab owner (cannot move between users here)",
    "hostLinePreview": "Line that will be written",
    "disabledJob": "Disabled",
    "confirmMismatch": "Confirm must match the command.",
    "writtenHost": "Wrote host crontab",
    "adoptedHost": "Taken into the panel",
    "keepDisabledHint": "This line is disabled. Save keeps it commented.",
    "currentLine": "Current",
    "nextLine": "Next"
  },
  "dashboard": {
    "serviceAria": "{{name}}: {{state}}",
    "sev": {
      "ok": "OK",
      "warn": "Warning",
      "bad": "Problem"
    },
    "title": "Dashboard",
    "health": "Health",
    "protection": "Protection mode",
    "welcome": "Welcome to YSK Server",
    "audit": "Recent audit",
    "needLogin": "Sign in to view audit events",
    "features": "Features",
    "featuresHint": "Badges: Ready = software installed;",
    "badge": {
      "panel": "Panel",
      "notInstalled": "Not installed",
      "ready": "Ready",
      "installed": "Installed",
      "prodReady": "Prod ready",
      "check": "Check",
      "needPerm": "Needs perm"
    },
    "status": {
      "healthy": "Healthy",
      "prodReady": "Prod ready",
      "needsCheck": "Needs check"
    },
    "stat": {
      "backups": "Backups",
      "notifications": "Alerts",
      "certExpiry": "Cert expiry"
    },
    "tabs": {
      "overview": "Overview",
      "wizard": "Quick create",
      "notifications": "Alerts",
      "features": "Features"
    },
    "serviceHealth": "Service health",
    "serviceHealthDesc": "Live systemctl probe",
    "fullServiceMatrix": "Full service matrix",
    "readinessCheck": "Readiness:",
    "prodOk": "Production ready",
    "notFullyReady": "Not fully ready",
    "readinessBlocked": "{{n}} blocker(s)",
    "modeScore": "Mode {{mode}} · score {{ready}}/{{total}}",
    "mode": {
      "degraded": "degraded",
      "production_capable": "EXECUTE + root",
      "blocked": "blocked",
      "normal": "normal"
    },
    "details": "Details",
    "certExpiryTitle": "Certificate expiry:",
    "certExpired": "expired",
    "certDays": "{{days}}d",
    "securityStrip": "Security & apply status",
    "securityStripDesc": "Live alerts + apply honesty audit (written ≠ applied)",
    "notifCount": "Alerts {{count}}",
    "criticalCount": " · critical {{count}}",
    "warnCount": " · warn {{count}}",
    "applyAuditBadge": "Apply audit · ok {{ok}} · warn {{warn}} · bad {{bad}}",
    "executeBadge": "EXECUTE {{state}}",
    "executeLabel": "System change",
    "publicNo2fa": "This panel listens on all interfaces and your admin account has no 2FA.",
    "go": "Open",
    "open": "Open",
    "noCriticalWarn": "No critical or warning alerts",
    "notifCenter": "Notification center",
    "noHealthYet": "Health status not available yet",
    "sysChange": "System changes",
    "opened": "On",
    "closed": "Off",
    "readinessLink": "Readiness →",
    "hostMetrics": "Host metrics",
    "loadAvg": "Load average (1 · 5 · 15 min)",
    "memoryDash": "Memory —",
    "metricsLink": "Metrics →",
    "runningOf": "Running {{running}}/{{total}}",
    "noProjects": "No projects yet",
    "wizardLink": "Quick create →",
    "allProjects": "All projects →",
    "recentN": "Last {{n}}",
    "runningCount": "Running {{n}}",
    "securityLink": "Security →",
    "wizardTitle": "Quick create",
    "wizardDesc": "Create a project and optionally draft DNS / mail / database (apply on each feature page)",
    "projectName": "Project name",
    "projectNameHint": "Display name; creates a matching directory",
    "nameRequired": "Enter a project name",
    "domainOptional": "Domain (optional)",
    "domainHint": "Required to enable DNS and mail options",
    "runtime": "Runtime",
    "runtimeHint": "Sets default runtime version and deploy style",
    "runtimeVersion": "Runtime version",
    "versionHint": "Writes the project runtime version setting",
    "serverIpv4": "Server IPv4",
    "serverIpv4Hint": "DNS A / mail SPF",
    "serverIpv4Ph": "This host public IPv4",
    "serverIpv6": "Server IPv6 (optional)",
    "serverIpv6Hint": "Writes AAAA / ip6: when set",
    "serverIpv6Ph": "Public IPv6 (optional)",
    "needDomainFirst": "Enter a domain first",
    "withDns": "Also create DNS zone",
    "withDnsDesc": "Needs domain; registration only — apply zone on DNS page",
    "withMail": "Also register mail domain",
    "withMailDesc": "Needs domain; install software & DNS on mail detail page",
    "withDb": "Also draft a database",
    "withDbDesc": "Control-plane registration; apply on the SQL engine page",
    "wizardHint": "Quick create does not go live automatically",
    "wizardSubmit": "Create",
    "wizardOk": "Created",
    "wizardPartial": "Partially failed",
    "notifCenterTitle": "Notifications ({{count}})",
    "notifCenterDesc": "Critical {{critical}} · warn {{warn}} · info {{info}}",
    "noNotifs": "No notifications. Recent audit events are on Overview.",
    "noNotifsDesc": "System alerts and todos appear here",
    "applyAuditTitle": "Apply status audit",
    "applyAuditDesc": "ok {{ok}} · warn {{warn}} · bad {{bad}}",
    "barTitle": "{{count}} host alert(s)",
    "levelCritical": "Critical",
    "levelWarn": "Warning",
    "levelInfo": "Info",
    "colTitle": "Alert",
    "colDetail": "Detail",
    "colSource": "Source",
    "notifSearch": "Search alerts",
    "notifAll": "All",
    "notifDismiss": "Hide",
    "goFix": "Fix"
  },
  "dataTable": {
    "empty": "No data",
    "actions": "Actions"
  },
  "db": {
    "serviceSettings": "Service settings",
    "installedOk": "{{engine}} installed",
    "startedOk": "{{engine}} started",
    "installFirst": "Install {{engine}} first",
    "softwareMissing": "{{engine}} software is not installed",
    "serviceOverview": "Service overview",
    "readonlyStatus": "Read-only status",
    "readonlyProbe": "Read-only probe",
    "systemChange": "System changes",
    "opened": "Enabled",
    "notOpened": "Disabled",
    "admin": "Admin",
    "client": "Client",
    "hasClient": "Yes",
    "noClient": "No",
    "canProvision": "Can create DBs",
    "dumpOk": "Dump complete",
    "dumpFailed": "Dump failed",
    "noDumpToImport": "No dump file to import",
    "expiredTempUsersProcessed": "Expired temporary users processed",
    "dumpFirstDb": "Dump first DB",
    "importLatestDump": "Import latest dump",
    "cleanupExpiredTempUsers": "Clean expired temp users",
    "adminerEntry": "DB browser project",
    "browserProjectTitle": "Create DB browser project",
    "browserTool": "Tool",
    "browserNameHint": "Creates a PHP project; name must be unique",
    "browserNameTaken": "Project name already exists: {{name}}",
    "browserProjectCreated": "DB browser project created",
    "createBrowserProject": "Create project and deploy",
    "downloadPhpMyAdmin": "Download phpMyAdmin (needs system-change + network)",
    "createDatabase": "Create database",
    "installBannerHint": "Use the banner above to install {{engine}}.",
    "exclusiveMariaHint": "This host runs MariaDB. Use the MariaDB page or one-click switch (type SWITCH).",
    "exclusiveMysqlHint": "This host runs MySQL. Use the MySQL page or one-click switch (type SWITCH).",
    "openMaria": "MariaDB",
    "openMysql": "MySQL",
    "openMariaService": "MariaDB service",
    "openMysqlService": "MySQL service",
    "startService": "Start service",
    "openServiceConsole": "Open service console",
    "opsResult": "Ops result",
    "tempPasswordOnce": "Temporary read-only password (shown once):",
    "tabDatabases": "Databases ({{count}})",
    "tabUsers": "Users ({{count}})",
    "tabTemp": "Temp read-only ({{count}})",
    "tabRemote": "Remote hosts ({{count}})",
    "dbList": "Database list",
    "charset": "Charset",
    "noDatabasesYet": "No databases yet",
    "emptyDbInstallFirst": "Install {{engine}} via the banner, then Create database",
    "emptyDbCannotProvision": "Cannot create databases on the server right now",
    "emptyDbCreateHint": "Use Create database, then Apply",
    "emptyDbHostHasRows": "The host already has databases that are not in this control-plane list.",
    "registeredVsHostHint": "Registered in the panel / found on the host",
    "registeredCount": "Registered",
    "hostCount": "On host",
    "registeredUsers": "Registered users",
    "registeredUsersHint": "Panel registrations only — not every MySQL account",
    "hostStillExists": "Still on host",
    "expiresLabel": "Expires",
    "dumpNeedRegistered": "Register a database in the panel first",
    "dumpFirstDbTitle": "Export the first registered database",
    "importNeedRegistered": "Register a database in the panel first",
    "importLatestNeedConfirm": "Needs confirmation — imports into the registered database",
    "hostHasUntracked": "{{count}} host databases are not registered in the panel",
    "hostInventoryHint": "The table is control-plane rows only. Live names come from SHOW DATABASES.",
    "userList": "Users",
    "userListDesc": "Grant users access to databases",
    "createUserBtn": "+ Create user",
    "noUsersYet": "No users yet",
    "tempReadonlyUsers": "Temporary read-only users",
    "tempReadonlyDesc": "Expired accounts are dropped from the server when this page loads (needs EXECUTE + root). Rows left below still exist on the host.",
    "dbName": "Database name",
    "ttlHours": "TTL (hours)",
    "ttlHoursHint": "Marked invalid after expiry",
    "createReadonlyUser": "Create read-only user",
    "tempUserCreated": "Temporary read-only user created",
    "expiresAt": "Expires",
    "revokeRegistration": "Revoke registration",
    "remoteDbHosts": "Remote database hosts",
    "remoteDbHostsDesc": "Register connection targets (password not echoed back). Saved ≠ reachable until Test connection.",
    "remoteTest": "Test connection",
    "remoteTestDone": "Remote host probe finished",
    "remoteTestOk": "reachable",
    "remoteTestFail": "unreachable",
    "remoteNotChecked": "not tested",
    "remoteDeleteTitle": "Remove this registration only",
    "remoteDeleteConfirm": "Remove registration {{name}}? The remote server is not changed.",
    "displayName": "Display name",
    "prodReplicaPlaceholder": "Production replica",
    "remoteHostSaved": "Remote host saved",
    "createDbTitle": "Create {{engine}} database",
    "createDbDesc": "After control-plane registration, Apply to write on the server",
    "dbNameHint": "Lowercase alnum and underscore; apply to system after create",
    "alsoCreateUser": "Also create user",
    "alsoCreateUserDesc": "Create a login that can connect to this database",
    "passwordMin8": "At least 8 characters",
    "passwordMin8chars": "At least 8 characters",
    "allowConnectHost": "Allowed host",
    "allowConnectHostHint": "Often % (any) or localhost",
    "allowConnectHostHintShort": "Often % or localhost",
    "createDbHint": "Writes control-plane only; Apply runs CREATE DATABASE on the server.",
    "createUserTitle": "Create {{engine}} user",
    "createUserDesc": "Apply after create",
    "bindDatabase": "Bind database",
    "bindDatabaseHint": "Optional; grant privileges on this DB",
    "noneOption": "— none —",
    "importDumpTitle": "Import dump?",
    "importDumpDesc": "Import {{dump}} into {{db}}",
    "import": "Import",
    "importOk": "Import complete",
    "importFailed": "Import failed",
    "deleteDbTitle": "Remove control-plane registration (does not DROP the server database)",
    "deleteDbDesc": "Removes control-plane record only; does not DROP the server database.",
    "deleteUserTitle": "Delete user registration?",
    "deleteUserDesc": "Removes control-plane record only.",
    "adminerTitle": "Adminer database browser",
    "adminerDesc": "Download Adminer + write Nginx conf; apply to system runs nginx -t + reload",
    "adminerWritten": "Adminer written to management files",
    "adminerApplied": "Adminer applied",
    "writeOnly": "Write only (written)",
    "applyToSystem": "Apply to system",
    "adminerRisk": "Public Adminer is risky — restrict source IPs or add HTTP auth. Needs PHP-FPM socket (default php8.2).",
    "vhostName": "Virtual host name",
    "vhostHint": "Point DNS A to this host for external access",
    "downloadAdminer": "Download Adminer PHP (needs YSK_EXECUTE + outbound net)",
    "downloadAdminerDesc": "Off = use already downloaded file only",
    "adminerWriteHint": "Write only = management written;",
    "pgInstallBanner": "Install PostgreSQL via the banner first",
    "pgEmptyCreateHint": "After create, Apply to system to write on the server",
    "pgNoDbs": "No PostgreSQL databases yet",
    "pgCreateTitle": "Create PostgreSQL database",
    "pgCreateDesc": "Control-plane registration; Apply to system runs CREATE DATABASE",
    "pgAlsoCreateRole": "Also create role",
    "pgAlsoCreateRoleDesc": "Create a login role and grant this database",
    "roleName": "Role name",
    "roleHint": "PostgreSQL role / login user",
    "pgDeleteDbDesc": "Removes control-plane record (does not auto DROP unless a revoke apply is run).",
    "update": "Update",
    "alsoCreateRole": "Also create role",
    "cluster": {
      "standaloneOtherEngines": "This engine is standalone. Other engines have clusters: {{names}}.",
      "roleUnassigned": "No role assigned",
      "title": "Cluster",
      "description": "Plan → write management files → apply → probe → distribute to peers / fleet. Default is dry-run (no host restart).",
      "redirectedFromCluster": "You were redirected here from /cluster. This is the database cluster tab.",
      "notApplied": "Not applied",
      "plannedAt": "Created {{when}}",
      "clearStalePlans": "Clear stale plans",
      "clearStalePlansTitle": "Delete stale planned clusters?",
      "clearStalePlansDesc": "Deletes {{n}} planned/draft registration(s) older than 7 days. Does not apply or push. System conf is not touched.",
      "landingTitle": "Database cluster",
      "landingDesc": "All planned and applied database clusters on this host. Open an engine to create or apply.",
      "landingNoneInstalled": "MySQL, MariaDB, PostgreSQL, and Redis are not installed. Install an engine first.",
      "openEngine": "Open {{engine}}",
      "overviewPill": "Clusters {{n}}",
      "enginesInstalled": "Engines",
      "plannedCount": "Planned",
      "overviewList": "Clusters ({{count}})",
      "overviewEmpty": "No cluster registrations yet.",
      "engine": "Engine",
      "kind": "Kind",
      "members": "Members",
      "kindGalera": "Simple Galera",
      "kindMysqlReplica": "MySQL primary/replica",
      "kindPgReplica": "PostgreSQL streaming replica",
      "kindRedisReplica": "Redis primary/replica",
      "createGalera": "Create simple Galera",
      "createMysqlReplica": "Create primary/replica",
      "createPgReplica": "Create streaming replica",
      "createSentinel": "Create Sentinel",
      "createRedisReplica": "Create Redis replica",
      "needRealIps": "Enter real local and peer IPs/hostnames",
      "hostInvalid": "Enter a valid IPv4, IPv6, or hostname.",
      "statusNote": "Status: {{status}} (plan success ≠ cluster health)",
      "artifactNote": "Artifacts: {{dir}}",
      "planGenerated": "Plan generated (dry-run)",
      "planUpdated": "Plan updated",
      "manageWritten": "Management files written (dry-run)",
      "bootstrapTried": "Bootstrap attempted",
      "applyTried": "System conf apply attempted",
      "localOk": "Local OK",
      "localProbeFail": "Local probe failed",
      "probedWithPeers": "Probed (incl. peers)",
      "probedLocal": "Probed local",
      "peerTarNote": "Peer bundle downloaded (.tar.gz) — extract and install conf on peer",
      "downloaded": "Downloaded",
      "peerPushed": "Pushed to peer",
      "pushPlanGenerated": "Push plan generated",
      "registrationDeleted": "Registration deleted",
      "nodes": "Nodes",
      "remoteInstallPlan": "Remote install plan",
      "fleetSession": "Fleet agent session id",
      "fleetSessionHint": "Optional. Pick a registered fleet session (uses fleet, not SSH). Leave empty for SSH scp.",
      "fleetSessionPh": "Agents page session UUID",
      "fleetSessionNone": "None — use SSH",
      "fleetSessionOpenAgents": "Open /agents to register a session",
      "createWizardTitle": "Opens the plan wizard. Needs a local IP and ≥1 peer. Writes panel artifacts only (dry-run). Does not restart the engine until you apply.",
      "bootstrap": "Bootstrap",
      "fleetApply": "Fleet apply",
      "planTitle": "Regenerate the cluster plan (no host change)",
      "writeFileTitle": "Write management files under the panel data dir (dry-run)",
      "probeLocalTitle": "Probe this host only",
      "probeAllTitle": "Probe every registered member",
      "bootstrapTitle": "Install local drop-in and bootstrap the first node",
      "remoteInstallPlanTitle": "Preview remote install (no execute)",
      "downloadBundleTitle": "Download peer conf bundle (.tar.gz)",
      "pushPlanTitle": "Preview push to peer (no scp)",
      "fleetSyncPlanTitle": "Preview fleet sync (no execute)",
      "fleetApplyTitle": "Enqueue apply on fleet members?",
      "status": {
        "healthy": "Healthy",
        "planned": "Planned",
        "partial": "Partial",
        "failed": "Failed",
        "draft": "Draft",
        "degraded": "Degraded",
        "applied": "Applied"
      },
      "fleetSyncPlan": "Fleet sync plan",
      "standaloneTitle": "Currently: standalone",
      "standaloneRepl": "No replica registered. Set primary/master + replica to generate conf and scripts.",
      "standaloneHa": "No HA registered. Add at least one peer, generate a conf plan, then bootstrap the first node and join the others.",
      "recentProbe": "Recent probe (local wsrep)",
      "probeRequired": "healthy requires a passing probe",
      "planPreview": "Plan preview",
      "planPreviewDesc": "dry-run · success only means steps/conf generated",
      "files": "Files",
      "systemChangeNeed": "Required on apply",
      "planModalDesc": "Pick nodes → generate plan (does not change peer systems)",
      "generatePlan": "Generate plan",
      "clusterName": "Cluster name",
      "localIp": "Local IP / host",
      "primaryIpHint": "Control-plane host (primary/master + access=local)",
      "localIpHint": "Control-plane host (access=local)",
      "ipExample1": "e.g. 10.0.0.1",
      "ipExample2": "e.g. 10.0.0.2",
      "ipExample3": "e.g. 10.0.0.3",
      "replicaIp": "Replica IP / host",
      "peerIp": "Peer IP / host",
      "replicaHint": "Replica node",
      "peerHint": "Second node (Galera prefers 3)",
      "thirdNode": "3rd node (optional)",
      "thirdNodeHint": "Recommended for Galera / multi-replica",
      "sstMethod": "SST method",
      "forbidDemoIp": "No demo IPs (203.0.113.x).",
      "fwGalera": "Open internal 3306 / 4567 / 4444 / 4568.",
      "fwPg": "Streaming needs internal 5432; change CHANGE_ME passwords in scripts.",
      "fwRedis": "Redis internal 6379 (sentinel 26379).",
      "fwRepl": "Replicas need matching internal ports; change CHANGE_ME passwords.",
      "needExecuteRoot": "Applying system conf needs YSK_EXECUTE=1 + root.",
      "topology": "Topology: {{kind}}",
      "applyLocalTitle": "Apply local system conf?",
      "applyBootstrapDesc": "Installs Galera drop-in and bootstrap (galera_new_cluster)",
      "applyJoinDesc": "Installs Galera drop-in and systemctl restart mariadb",
      "confirmApply": "Confirm apply",
      "deleteClusterTitle": "Delete cluster registration {{name}} ({{engine}})?",
      "remoteInstallTitle": "Remote-install peer?",
      "pushTitle": "Push to peer?",
      "fleetSyncTitle": "Fleet sync?",
      "confirmOp": "Confirm",
      "deleteClusterDesc": "Delete the {{engine}} cluster registration “{{name}}”. System conf is not auto-cleared (v1).",
      "remoteInstallDesc": "Install conf + restart on peer. Needs YSK_EXECUTE + SSH.",
      "pushDesc": "scp files to peer /tmp?",
      "fleetSyncDesc": "Sync cluster snapshot to fleet edge, then apply.",
      "fleetApplyDesc": "Enqueue apply to fleet members.",
      "remoteInstalled": "Remote installed",
      "fleetSynced": "Fleet sync queued",
      "fleetApplyQueued": "Fleet apply queued",
      "engineNotInstalled": "{{engine}} is not installed on this host — install it first, or open the engine that is actually running.",
      "plan": "Plan",
      "writeFile": "Write files",
      "applyLocal": "Apply local",
      "probeAll": "Probe all nodes",
      "remoteInstall": "Remote install",
      "downloadBundle": "Download bundle",
      "pushPlan": "Push plan",
      "pushExecute": "Push execute",
      "fleetSync": "Fleet sync",
      "localConfPreview": "Local conf preview",
      "refresh": "Refresh",
      "close": "Close",
      "cancel": "Cancel",
      "delete": "Delete",
      "probe": "Probe",
      "name": "Name",
      "type": "Type"
    },
    "console": {
      "dataBrowse": "Browse data",
      "dbManage": "Database admin",
      "realtime": "Live",
      "reload": "Reload",
      "needRestart": "Restart required",
      "affectsProjects": "Sites and services that use this engine will be interrupted.",
      "lifecycle": "Lifecycle",
      "overview": "Overview",
      "actionDone": "{{action}} done",
      "installDone": "Install complete",
      "noChanges": "Nothing to apply",
      "settingsApplied": "Settings applied",
      "notReadFromService": "Not read from service",
      "applyMode": "Apply mode: {{mode}}",
      "dirtyNotApplied": "Modified, not applied",
      "highRisk": "High-risk settings",
      "engine": "Engine",
      "bootEnabled": "Start on boot",
      "uptimeSec": "Uptime (s)",
      "currentConnections": "Connections",
      "changes": "Changes",
      "serviceTitle": "{{title}} service",
      "softwareMissing": "{{title}} software is not installed",
      "overviewDesc": "Read-only info from probe (not form fields)",
      "lifecycleDesc": "Install, start, stop, and enable on boot",
      "about": "About",
      "cluster": "Cluster",
      "noSettings": "No settings in this category (or unsupported in this version)",
      "applyHint": "Live can change online;",
      "applyCategory": "Apply category",
      "applyAll": "Apply all changes",
      "applyCatCount": "Apply category ({{n}})",
      "applyAllCount": "Apply all ({{n}})",
      "lifecycleNote": "On Settings, Live changes online; restart-required needs Lifecycle restart after apply.",
      "installEngine": "Use the banner above to install {{title}}.",
      "reloadConfig": "Reload config",
      "disableBoot": "Disable on boot",
      "disableBootConfirm": "The engine will not start after reboot until you enable it again.",
      "needRights": "Needs system-change rights and admin. Failures show reasons — never fake success.",
      "noneFetched": "— none —"
    },
    "importEntry": "Entry: {{url}}",
    "adminerRiskFull": "Public Adminer is risky — restrict source IPs or add HTTP auth. Needs PHP-FPM socket (default php8.2).",
    "adminerWriteHintFull": "Write only = management written;",
    "pgInstalled": "PostgreSQL installed",
    "pgStarted": "PostgreSQL started",
    "notInstalledShort": "Not installed",
    "serviceConsole": "Service console",
    "installPgFirst": "Install PostgreSQL first",
    "pgSoftwareMissing": "PostgreSQL software is not installed",
    "installPgBanner": "Use the banner above to install PostgreSQL.",
    "createPlus": "+ Create",
    "dbNameHintPg": "Lowercase alnum and underscore; apply after create",
    "deleteNotePg": "Deleting registration does not DROP the server DB; apply success means DDL ran on host.",
    "tabDatabasesSimple": "Databases ({{count}})",
    "frozenTitle": "Database service needs repair",
    "frozenBody": "Issues detected (freeze mode: {{mode}};",
    "unfreezeBtn": "Diagnose and repair",
    "unfreezeConfirmTitle": "Repair {{engine}}?",
    "unfreezeConfirmDesc": "Runs a generic repair plan from diagnostics (stop, clear freeze, sanitize config, init emp",
    "unfreezeConfirmBtn": "Confirm repair",
    "unfreezeOk": "{{engine}} repair complete",
    "startAfterUnfreeze": "Start service (auto-runs repair plan on failure)",
    "serviceDownTitle": "Database service is down",
    "serviceDownBody": "Service is unhealthy",
    "adoptHostDb": "Register in panel (no create): {{name}}",
    "adoptHostDbTitle": "Registers the name in the control plane only — does not change host data",
    "cleanupExpiredTempUsersTitle": "Drops panel-issued temporary users that have expired",
    "invalidSqlIdent": "Use a lowercase identifier: start with a letter, then letters, digits, or underscore.",
    "remoteHostRequired": "Enter a remote host.",
    "remoteTestUnsaved": "Save this host first, then Test connection. Or fill host and save.",
    "serverNotInstalled": "This engine is not installed on the server.",
    "dumpNeedEngine": "Install the engine before exporting a database.",
    "unboundDatabase": "Database registration removed",
    "userGoneRefresh": "That user is gone. The list was refreshed."
  },
  "dialogs": {
    "confirmDefault": "Confirm",
    "cancelDefault": "Cancel",
    "severity": {
      "consequencesTitle": "This will:",
      "typeToConfirm": "Type \"{{text}}\" to confirm"
    }
  },
  "dns": {
    "templates": {
      "minimal": "Minimal — apex A only",
      "web": "Web — apex + www",
      "mail": "Mail — apex + mail + MX + SPF",
      "full": "Full — web + mail + ftp + SPF",
      "cdn": "CDN — apex + www + cdn (multi-edge ready)"
    },
    "dnssecOk": "DNSSEC keys generated (written — zone not signed / not on registrar)",
    "dnssecNotOk": "DNSSEC keys not generated (notes only or tools unavailable — no false success)",
    "dnssecFailed": "DNSSEC failed",
    "blocked": "Blocked (needs system-change permission)",
    "clusterDone": "Done ({{status}})",
    "clusterPartial": "Not fully successful ({{status}}) — see details below",
    "clusterFailed": "Cluster operation failed",
    "validateFailed": "Record validation failed",
    "validateRequestFailed": "Validation request failed",
    "lookupFailed": "Lookup failed",
    "statRecords": "Records",
    "statSelected": "Selected",
    "notInstalled": "Required DNS software is not installed",
    "dsForRegistrar": "DS (for registrar; not auto-published):",
    "tabs": {
      "zones": "Zones",
      "records": "Records",
      "cluster": "Cluster",
      "dnssec": "DNSSEC",
      "tools": "Tools",
      "ddns": "DDNS",
      "about": "About"
    },
    "recentWrite": "Recent write result",
    "zonesTitle": "Zones ({{count}})",
    "zonesDesc": "After create, write/apply the zone",
    "createZone": "+ Create zone",
    "mailZonesMissing": "Email domains have no DNS zone here: {{domains}}.",
    "createMailZone": "Create mail zone",
    "colZoneName": "Zone name",
    "colServerIp": "Server IP",
    "colTemplate": "Template",
    "colStatus": "Status",
    "emptyZonesTitle": "No DNS zones yet",
    "emptyZonesDesc": "Use “Create zone” in the list toolbar",
    "applyZoneTitle": "Write zone file and register into PowerDNS named.conf + rediscover (write ≠ dig answers)",
    "applyZone": "Write / apply",
    "recordsFor": "Records — {{zone}}",
    "recordsNeedSelect": "Records (select a zone first)",
    "statusLabel": "Status",
    "addRecord": "+ Add record",
    "writeZoneFile": "Write & load zone",
    "healthLoaded": "Loaded",
    "stateLoaded": "Loaded",
    "healthPublicNs": "Public NS",
    "statePublicNs": "Public NS",
    "publicNsHere": "→ this host",
    "requestLeTitle": "Request Let’s Encrypt for {{zone}}",
    "requestZoneSsl": "Request SSL for zone",
    "soaTitle": "SOA / default TTL",
    "soaDesc": "SOA nameserver and $TTL when writing the zone file;",
    "soaBlockNs": "Nameservers",
    "soaBlockTiming": "TTL & timers",
    "recordsListTitle": "DNS records ({{count}})",
    "recordsListDesc": "After edits, use “Write zone file” above so named’s on-disk file updates.",
    "soaNsLabel": "SOA nameserver",
    "soaNsHint": "Leave empty → default ns1.zone.",
    "defaultTtl": "Default TTL (seconds)",
    "min1": "1 min",
    "min5": "5 min",
    "min10": "10 min",
    "hour1": "1 hour",
    "day1": "1 day",
    "customSeconds": "Custom seconds",
    "soaSaved": "SOA saved (control plane) — “Write zone file” to apply",
    "soaSaveFailed": "Failed to save SOA",
    "soaSavedAndWritten": "Saved and wrote zone file",
    "soaWriteFailed": "SOA write failed",
    "failed": "Failed",
    "colType": "Type",
    "colName": "Name",
    "colValue": "Value",
    "emptyRecords": "No records",
    "noZoneSelectedTitle": "No zone selected",
    "noZoneSelectedDesc": "Pick a zone on the Zones tab",
    "clusterTitle": "DNS cluster",
    "clusterDesc": "After SCP of zone files, remote reload (rndc / named / bind9 / pdns)",
    "peerHost": "Peer host",
    "peerHostHint": "Secondary NS hostname or IP (SSH key login)",
    "sshUser": "SSH user",
    "sshUserHint": "Needs write to target path and reload permission",
    "labelOptional": "Label (optional)",
    "labelPlaceholder": "e.g. ns2 / hkg-edge-dns",
    "opPerPeer": "This operation (per peer)",
    "registeredPeers": "Registered peers ({{count}})",
    "lastProbeHint": "lastProbe updates after probe or push",
    "noPeers": "No peers registered yet",
    "zoneDirMissing": "· zone directory missing",
    "generateKeys": "Generate keys; does not go live automatically",
    "selectZoneFirst": "Select a zone first",
    "lookupTitle": "DNS lookup (dig)",
    "lookupDesc": "Query public resolvers; verify multi-A / CDN. Does not invent answers.",
    "lookupNamePlaceholder": "e.g. example.com or www.example.com",
    "lookupType": "Query type",
    "lookupResults": "Results ({{count}})",
    "lookupNoAnswerFail": "No answers / failed",
    "digNotInstalled": "dig is not installed",
    "digNotInstalledHint": "This tab needs the dig binary (bind9-dnsutils). That is not NXDOMAIN. Install bind9-dnsutils from the host package manager; this page does not auto-install it.",
    "method": "Method: {{method}}",
    "noAnswers": "No answers",
    "noAnswersDesc": "NXDOMAIN, empty RRset, or resolve failure",
    "lookupOkHint": "Live query results",
    "lookupFailHint": "Lookup failed or empty. Check name, type, and upstream resolvers.",
    "validateTitle": "Record validation",
    "validateDesc": "Create/edit auto-validates (CNAME clashes, A/AAAA format, etc.).",
    "createZoneTitle": "Create DNS zone",
    "createZoneDesc": "Generate records from a template",
    "createZoneNeedValid": "Enter a valid zone name and IPv4 address",
    "zoneNameHint": "e.g. example.com (no trailing dot)",
    "invalidZone": "Invalid zone name. Use a real domain (e.g. example.com).",
    "invalidIpv4": "Invalid IPv4. Each octet must be 0–255.",
    "serverIpv4": "Server IPv4",
    "serverIpv4Hint": "Address used for template A records",
    "thisHostIpv4": "This host public IPv4",
    "serverIpv6Optional": "Server IPv6 (optional)",
    "serverIpv6Hint": "Writes AAAA when public v6 exists; can leave empty",
    "thisHostIpv6": "This host public IPv6 (optional)",
    "soaNsCreateHint": "Leave empty for ns1.zone-name",
    "defaultTtlLabel": "Default TTL",
    "defaultTtlHint": "Default for SOA and new records",
    "recordTemplate": "Record template",
    "editRecord": "Edit record",
    "addRecordTitle": "Add record",
    "recordModalDesc": "Zone {{zone}} · write zone file after save",
    "recordType": "DNS record type",
    "nameHint": "@ = apex; www = subdomain",
    "mxPlaceholder": "e.g. 10 mail.example.com.",
    "spfPlaceholder": "e.g. v=spf1 a mx ip4:… ip6:… ~all",
    "needIpv6": "Enter an IPv6 address",
    "needIpv4": "Enter an IPv4 address",
    "valueHint": "IP, hostname, or record content",
    "ipv6Address": "IPv6 address",
    "ipv4Address": "IPv4 address",
    "cacheTime": "Cache time",
    "deleteZoneTitle": "Delete zone?",
    "deleteZoneDesc": "Also removes its DNS record registrations.",
    "deleteRecordTitle": "Delete record?",
    "deleteRecordDesc": "Write the zone file after removal",
    "addPeer": "Add peer",
    "probe": "Probe",
    "pushZones": "Push zones",
    "reloadRemote": "Remote reload",
    "generateDnssec": "Generate DNSSEC keys",
    "lookup": "Lookup",
    "saveSoa": "Save SOA",
    "saveSoaAndWrite": "Save and write zone file",
    "saveSoaSettings": "Save SOA settings",
    "saveSoaAndWriteBtn": "Save and write zone file",
    "goToZones": "Go to zones",
    "refresh": "Refresh",
    "pushReload": "Push + reload",
    "pushOnly": "Push only (no reload)",
    "reloadOnly": "Remote reload only",
    "probePeers": "Probe peers",
    "clusterDefaultHint": "Default: push then reload DNS on peers; needs system-change rights.",
    "notProbed": "Not probed yet",
    "probeHealthy": "Probe: {{status}}",
    "pushReloadShort": "Push+reload",
    "dnssecCardDesc": "Generate keys/DS;",
    "currentZone": "Current zone:",
    "generateAndSign": "Generate keys and try signing zone",
    "lookupName": "Name",
    "fillCurrentZone": "Fill current zone",
    "lookupToolHint": "Prefers host dig;",
    "validateExtra": "Errors block save; warns (e.g. apex CNAME) only notify.",
    "createAfterHint": "After create, review on Records tab and write the zone file to disk.",
    "valueLabel": "Value",
    "ttlHint": "Cache time",
    "soaSavedControl": "SOA saved (control plane) — write zone file to apply",
    "soaNs2Label": "Secondary NS (optional)",
    "soaNs2Hint": "Second nameserver FQDN, e.g. ns2.example.com.",
    "soaHostmaster": "SOA hostmaster (RNAME)",
    "soaHostmasterHint": "Use dots instead of @, e.g. hostmaster.example.com.",
    "soaRefresh": "Refresh (seconds)",
    "soaRetry": "Retry (seconds)",
    "soaExpire": "Expire (seconds)",
    "soaMinimum": "Minimum / negative cache TTL (seconds)",
    "soaTimingHint": "SOA timing parameters in seconds.",
    "healthTitle": "DNS service health",
    "healthDesc": "Host truth: unit / port 53 / written zone files / local dig answers (written ≠ reloaded ≠",
    "healthPillOk": "DNS OK",
    "healthPillBad": "DNS issues",
    "healthService": "Service",
    "healthServiceDown": "down",
    "healthListen": "Port 53",
    "healthWritten": "Zone files",
    "healthAnswering": "Local answer",
    "healthAnsweringYes": "yes",
    "healthAnsweringNo": "no/refused",
    "healthRefresh": "Re-probe",
    "healthProbeLocal": "Probe health again",
    "healthOpen53": "Open firewall 53 (TCP+UDP)",
    "healthOpened53": "Requested open 53 TCP+UDP",
    "healthOpen53Failed": "Failed to open 53",
    "healthPortClosed": "not listening",
    "healthPortOpenAlready": "53 appears open",
    "healthHint": "If dig is refused, fix PowerDNS, open port 53, then write zones.",
    "stateService": "Service",
    "stateListen": "Listen",
    "stateWritten": "Written",
    "stateAnswering": "Local answering",
    "lookupServer": "Server (@)",
    "lookupServerHint": "127.0.0.1 = local auth; public IP tests external; empty = system resolver",
    "healthHealPdns": "Heal PowerDNS bind",
    "healNeedInstall": "PowerDNS is not installed — install it on the Software tab first",
    "applyNeedService": "DNS service is not running — start or install it before apply",
    "goStartService": "Start DNS service",
    "startBindHint": "If start returns to stopped, port 53 is often held by systemd-resolved. Use Heal bind below, then start again.",
    "deleteZoneNeedName": "Delete this zone — you will type the zone name to confirm",
    "healthHealPdnsHint": "Set local-address to public IP to avoid clashing with systemd-resolved on 0",
    "healthHealPdnsOk": "PowerDNS bound to {{ip}} and start attempted",
    "healthHealPdnsFailed": "PowerDNS heal failed",
    "startProbeFailed": "Could not re-check DNS health after start",
    "startNotListening": "PowerDNS start returned, but the unit is not answering on port 53",
    "aboutTitle": "DNS essentials",
    "aboutSub": "Zones first; records, cluster, and DNSSEC need a selected domain.",
    "aboutZonesTitle": "Zones and scope",
    "aboutZonesBody": "Pick a zone under Zones, then manage records, cluster, and DNSSEC for that domain.",
    "aboutHealthTitle": "Service health",
    "aboutHealthBody": "Use Tools to probe PowerDNS, heal bind, and open port 53.",
    "aboutStackTitle": "Software",
    "aboutStackBody": "Check/update the PowerDNS package under Software.",
    "aboutDdnsTitle": "DDNS",
    "aboutDdnsBody": "The DDNS tab updates named A/AAAA records when this host’s WAN address changes. It does not replace zone CRUD. Written is not the same as public resolver truth.",
    "ddns": {
      "honesty": "A successful write is not public DNS yet. Resolver caches and registrar NS still apply. Empty or private IPs are never published.",
      "needExecute": "Provider updates need root and YSK_EXECUTE=1. Detection still runs.",
      "lastRun": "Last run",
      "nextRun": "Next run",
      "wanRemembered": "Remembered WAN IPv4",
      "updateNow": "Update now",
      "updateTitle": "Publish detected WAN addresses?",
      "updateDesc": "Calls Cloudflare, nsupdate, or the local zone for each enabled record, even if the address is unchanged. Type UPDATE to confirm.",
      "updated": "DDNS update finished",
      "updateFailed": "DDNS update failed",
      "probe": "Probe WAN",
      "probed": "WAN probe finished",
      "probeFailedUi": "WAN probe failed",
      "forceHint": "Update now republishes even when the address is unchanged. Probe never calls a provider.",
      "saved": "Saved",
      "saveFailed": "Could not save",
      "deleted": "Record removed",
      "emptyTitle": "No DDNS records",
      "emptyDesc": "Add a hostname below. Cloudflare, RFC 2136, or this host’s PowerDNS zone (managedBy=ddns).",
      "colFqdn": "Hostname",
      "colProvider": "Provider",
      "colPublished": "Published",
      "colEnabled": "State",
      "colFrom": "From",
      "colTo": "To",
      "colWhen": "When",
      "colNote": "Note",
      "pauseRecord": "Pause",
      "resumeRecord": "Resume",
      "statusCard": "WAN status",
      "recordsCard": "Hostnames",
      "addCard": "Add hostname",
      "settingsCard": "Settings",
      "historyTitle": "Recent updates",
      "historyEmpty": "No DDNS history yet",
      "paused": "Scheduler paused",
      "pausedHint": "Scheduled updates are off. Probe and Update now still run.",
      "schedulerOn": "Scheduled updates",
      "schedulerOnHint": "In-process scheduler. Not crontab. Off means no automatic upsert.",
      "zone": "Zone",
      "zoneHint": "Leave empty to use the last two labels of the hostname. Local provider should pick a zone that already exists.",
      "zoneSelectHint": "Local zones on this host. Cloudflare and RFC 2136 can use any zone name.",
      "noLocalZones": "No local zones yet. Create one on the Zones tab first if you use Local PowerDNS.",
      "providerLocal": "Local PowerDNS",
      "proxied": "Cloudflare proxied",
      "proxiedHint": "Orange cloud. Leave off for VPN / WireGuard hostnames.",
      "proxiedWarnTitle": "Cloudflare orange cloud?",
      "proxiedWarnDesc": "A proxied record hides the origin IP. VPN and WireGuard hostnames should stay DNS only. Type PROXY to confirm.",
      "addRecord": "Add hostname",
      "interval": "Interval (seconds)",
      "intervalHint": "60–86400. In-process scheduler; not crontab.",
      "cfToken": "Cloudflare API token",
      "cfTokenHint": "Write-only. Env CF_API_TOKEN is used if set. Never shown again.",
      "tokenConfigured": "A Cloudflare token is stored. Leave blank to keep it.",
      "tokenMissing": "No Cloudflare token stored (env CF_API_TOKEN still applies).",
      "rfcServer": "RFC 2136 server",
      "rfcServerHint": "Remote servers need a TSIG key file under the data directory. Loopback may be unsigned. The secret is never passed on argv.",
      "rfcKeyFile": "TSIG key file",
      "rfcKeyFileHint": "Relative to the DDNS data directory, or an absolute path under the data directory.",
      "rfcKeyConfigured": "A key file path is stored. Leave blank to keep it.",
      "primaryFqdn": "Primary hostname",
      "primaryFqdnHint": "Used as a VPN endpoint hint. Does not rewrite existing peers.",
      "updateIdentity": "Remember WAN IPv4",
      "updateIdentityHint": "Store last public IPv4 in DDNS status for this host",
      "vpnHint": "VPN Endpoint can use a DDNS hostname (not rewritten automatically).",
      "sslHint": "Let’s Encrypt HTTP-01 needs the hostname to resolve here. Certificates are not reissued on IP change.",
      "deleteTitle": "Remove DDNS hostname?",
      "deleteDesc": "Type {{fqdn}} to confirm. Local managedBy=ddns rows are not deleted from the zone editor.",
      "err": {
        "requiresExecute": "Needs root and YSK_EXECUTE=1 to publish.",
        "missingToken": "Cloudflare API token is missing.",
        "rfc2136NeedKey": "Remote RFC 2136 needs a TSIG key file under the data directory.",
        "rfc2136KeyMissing": "TSIG key file is missing or outside the data directory.",
        "noPublicIpv4": "No public IPv4 detected.",
        "noPublicIpv6": "No public IPv6 detected.",
        "notPublicIpv4": "Detected IPv4 is not public.",
        "notPublicIpv6": "Detected IPv6 is not public.",
        "probeFailed": "Public IP probe failed.",
        "localNoZone": "No local DNS zone for this hostname.",
        "localNeedsDb": "Local provider needs the control-plane database.",
        "managedByClash": "That name is owned by another feature (not DDNS).",
        "unknownProvider": "Unknown DDNS provider.",
        "nsupdateFailed": "nsupdate failed.",
        "updateFailed": "Provider update failed.",
        "invalidFqdn": "Invalid hostname.",
        "invalidType": "Type must be A or AAAA.",
        "invalidProvider": "Unknown provider.",
        "notFound": "Record not found.",
        "confirmMismatch": "Confirm must match the hostname.",
        "schedulerDisabled": "Scheduled DDNS is paused.",
        "provider": "Provider returned an error."
      }
    },
    "createMailZoneNow": "Created mail zone {{domain}}",
    "toolsFirewallTitle": "Firewall (UFW)",
    "toolsFirewallHint": "Allow or deny port 53. This does not start or stop PowerDNS.",
    "toolsUnitTitle": "PowerDNS unit",
    "toolsUnitHint": "systemd unit pdns — start, stop, restart, reload.",
    "installConfirmTitle": "Install PowerDNS?",
    "installConfirmDesc": "Installs pdns-server and writes the managed authoritative config. Needs root and YSK_EXECUTE=1.",
    "installConfirmConsequence": "After install and start, PowerDNS will bind port 53.",
    "installPort53Busy": "Something already listens on port 53. PowerDNS may fail to bind until that listener is stopped or healed.",
    "installPort53BusyConsequence": "Heal bind or stop the other listener before expecting answers on port 53."
  },
  "docker": {
    "title": "Docker",
    "subtitle": "Install Docker Engine, then manage containers, images, volumes, and validator Compose stacks on this host.",
    "refresh": "Refresh",
    "notInstalled": "Docker Engine is not installed. Install docker.io and docker-compose-v2 from this page.",
    "protected": "Protected",
    "pruneConfirm": "Type PRUNE to confirm any prune",
    "needEngineTitle": "Install Docker Engine first",
    "stopEngineDesc": "This stops the Docker engine and all {{n}} container(s) on this host.",
    "notInstalledValue": "Not installed",
    "nameHint": "Letters, digits, underscore, dot, hyphen (max 128)",
    "volPlaceholder": "my-data",
    "netPlaceholder": "my-net",
    "runPorts": "Publish ports",
    "runPortsHint": "host:container per line, e.g. 8080:80",
    "runEnv": "Environment",
    "runEnvHint": "KEY=value per line",
    "runRestart": "Restart policy",
    "runNetwork": "Network",
    "runVolumes": "Volumes",
    "runVolumesHint": "volume:dest per line",
    "runAdvancedHint": "For multi-service stacks use validator nodes or Compose files already on this host.",
    "daemonConfirmTitle": "Apply daemon settings?",
    "daemonConfirmDesc": "Writes daemon.json and restarts docker.service. All containers will be interrupted.",
    "settingsHint": "Safe daemon.json subset only. Apply writes the file and restarts docker.service.",
    "cli": {
      "usage": "Usage: ysk-server docker status|ps|images|volumes|networks|df|logs|inspect|exec|start|stop|restart|rm|pull|run|prune|engine|compose [--image IMG] [--name N] [--preset version|help|hostname] [--bin BIN] [--project P] [--execute] [--json]"
    },
    "tab": {
      "overview": "Overview",
      "containers": "Containers",
      "images": "Images",
      "compose": "Compose",
      "volumes": "Volumes",
      "networks": "Networks",
      "prune": "Prune",
      "settings": "Settings",
      "about": "About"
    },
    "col": {
      "engine": "Engine",
      "containers": "Containers",
      "version": "Version",
      "dataRoot": "Data root",
      "disk": "Disk",
      "validators": "Validator stacks",
      "name": "Name",
      "image": "Image",
      "status": "Status",
      "ports": "Ports",
      "managed": "Managed",
      "size": "Size",
      "driver": "Driver",
      "type": "Type",
      "reclaimable": "Reclaimable"
    },
    "state": {
      "up": "Active",
      "down": "Stopped",
      "running": "Running",
      "exited": "Exited",
      "exitedCode": "Exited ({{n}})",
      "restarting": "Restarting",
      "restartingCount": "Restarting · {{n}} times",
      "paused": "Paused",
      "created": "Created",
      "dead": "Dead",
      "removing": "Removing",
      "unknown": "Unknown"
    },
    "df": {
      "images": "Images",
      "containers": "Containers",
      "volumes": "Local volumes",
      "builder": "Build cache",
      "other": "Other"
    },
    "actions": {
      "start": "Start",
      "stop": "Stop",
      "restart": "Restart",
      "remove": "Remove",
      "logs": "Logs",
      "inspect": "Inspect",
      "exec": "Exec (version)",
      "run": "Run image",
      "pull": "Pull",
      "up": "Up",
      "down": "Down",
      "createVolume": "Create volume",
      "createNetwork": "Create network",
      "pruneContainers": "Prune containers",
      "pruneImages": "Prune images",
      "pruneVolumes": "Prune volumes",
      "pruneSystem": "System prune",
      "startEngine": "Start engine",
      "stopEngine": "Stop engine",
      "restartEngine": "Restart engine",
      "applyDaemon": "Apply daemon settings"
    },
    "empty": {
      "containers": "No containers",
      "images": "No images",
      "compose": "No Compose projects",
      "composeDesc": "Projects come from validator nodes or Compose files already on this host. This page does not accept arbitrary YAML uploads.",
      "composeCta": "Open validator nodes",
      "volumes": "No volumes",
      "networks": "No networks"
    },
    "logs": {
      "empty": "No log output.",
      "follow": "Follow"
    },
    "deleteRunningWarn": "This container is still running or restarting. It will be force-removed.",
    "settings": {
      "logMaxSize": "Container log max size",
      "liveRestore": "Live restore (keep containers if the daemon restarts)",
      "mirrors": "Registry mirrors (one URL per line)",
      "insecure": "Insecure registries (one host per line)"
    },
    "about": {
      "body": "Docker is a first-class host service on YSK Server, like Nginx. Install via the panel (Ubuntu docker.io + docker-compose-v2). Validator nodes run as Compose projects named yskval-*.",
      "honesty": "Host changes need root and YSK_EXECUTE=1. Dry-run is the default. This page manages Docker on one host; use external Kubernetes for cluster orchestration.",
      "validators": "Open validator nodes"
    },
    "alerts": {
      "daemonTitle": "Docker daemon is down",
      "daemonBody": "The Docker engine is installed but docker.service is not active. Validator stacks cannot start."
    },
    "errors": {
      "notInstalled": "Docker is not installed",
      "daemonDown": "Docker daemon is not active",
      "needCompose": "docker compose (v2 plugin) is required",
      "badImage": "Invalid image reference",
      "badName": "Invalid name",
      "badPort": "Invalid port publish",
      "badEnv": "Invalid environment variable",
      "badVolume": "Invalid volume mount",
      "badNetwork": "Invalid network",
      "protectedNetwork": "Cannot remove a built-in Docker network",
      "badRestart": "Invalid restart policy",
      "badPrune": "Invalid prune scope",
      "needPruneConfirm": "Volume or system prune requires confirm=PRUNE",
      "badDaemon": "Invalid daemon setting",
      "composeMissing": "Compose file for this project was not found",
      "logsFailed": "Could not read container logs",
      "mutateFailed": "Docker command failed",
      "engineFailed": "Could not control docker.service",
      "badExec": "Exec is limited to allowlisted binaries and presets (no shell, no TTY)",
      "uninstallBusy": "Stop YSK-managed containers (including validator stacks) before uninstalling Docker",
      "badCommand": "Invalid command or entrypoint",
      "portBusy": "Host port {{bind}}:{{port}} is already in use",
      "nameInUse": "A container named {{name}} already exists. Remove it or pick another name.",
      "unpublished": "Container did not attach to a network or publish ports. Not treating this as started."
    },
    "notes": {
      "dryMutate": "Dry-run only. Pass --execute and YSK_EXECUTE=1 to change the host.",
      "dryPrune": "Prune preview (not applied).",
      "dryEngine": "Engine control is dry-run.",
      "dryDaemon": "Would write /etc/docker/daemon.json and restart docker.service.",
      "daemonWrote": "Wrote daemon.json",
      "start": "Container started",
      "stop": "Container stopped",
      "restart": "Container restarted",
      "remove": "Container removed",
      "ran": "Container started from image",
      "leftoverRemoved": "Removed leftover container {{name}} after bind failure",
      "pulled": "Image pulled",
      "exec": "Ran allowlisted exec",
      "imageRemoved": "Image removed",
      "volumeCreated": "Volume created",
      "volumeRemoved": "Volume removed",
      "networkCreated": "Network created",
      "networkRemoved": "Network removed",
      "pruned": "Prune finished",
      "compose": {
        "up": "Compose project started",
        "down": "Compose project stopped",
        "restart": "Compose project restarted",
        "rm": "Compose project removed"
      },
      "engine": {
        "start": "docker.service started",
        "stop": "docker.service stopped",
        "restart": "docker.service restarted"
      }
    },
    "ui": {
      "whatYouGet": "What this page does",
      "whatYouGetLead": "Install Docker Engine once. After that you can run a single container, pull images, and see validator Compose stacks that already live on this host.",
      "capEngine": "Engine",
      "capEngineDesc": "One-click install of docker.io and docker-compose-v2. Start and stop docker.service here.",
      "capWork": "Containers and images",
      "capWorkDesc": "Pick a common image, pull it, run it, then read logs or inspect the container.",
      "capStacks": "Validator stacks",
      "capStacksDesc": "Multi-service stacks are validator Compose projects (yskval-*). This page does not accept YAML uploads.",
      "cardEngine": "Engine",
      "cardDisk": "Disk",
      "cardWork": "On this host",
      "compose": "Compose",
      "cgroup": "cgroup",
      "used": "Used",
      "free": "Free",
      "running": "Running",
      "images": "Images",
      "volumes": "Volumes",
      "networks": "Networks",
      "goImages": "Images",
      "goValidators": "Validator nodes",
      "imagePickHint": "Choose a common image. Use Other only when you need a different reference.",
      "imageCustom": "Other",
      "driver": "Driver",
      "driverLocalOnly": "This panel creates local volumes only.",
      "netDefaultDriver": "New networks use Docker’s default bridge driver.",
      "pruneWhat": "What to remove",
      "pruneAck": "I understand unused data will be deleted and cannot be restored",
      "pruneAckDesc": "Volume and system prune cannot be undone. Stopped containers and unused images are removed for the selected scope.",
      "pruneNow": "Prune now",
      "useMirrors": "Use registry mirrors",
      "useInsecure": "Allow insecure registries",
      "publishPorts": "Publish ports to the host",
      "attachVolume": "Attach a volume",
      "setEnv": "Set environment variables",
      "defaultNet": "Default",
      "mountPath": "Mount path",
      "restartNo": "Never",
      "restartUnless": "Unless stopped",
      "restartAlways": "Always",
      "restartOnFail": "On failure",
      "needAck": "Confirm before pruning",
      "scopeContainers": "Stopped containers",
      "scopeImages": "Unused images",
      "scopeVolumes": "Unused volumes",
      "scopeBuilder": "Build cache",
      "scopeSystem": "Everything unused",
      "noVolumesYet": "No volumes yet — create one on the Volumes tab first.",
      "command": "Command",
      "commandHint": "Optional. Tokens after the image. Leave blank to use the image CMD.",
      "entrypoint": "Entrypoint",
      "entrypointHint": "Optional single binary. Leave blank to use the image ENTRYPOINT.",
      "portMap": "host:container",
      "portOccupied": "This host port is already in use",
      "validatorImage": "Managed by validator nodes",
      "newVolume": "New named volume",
      "loopbackUrl": "Local test URL",
      "nginxProxy": "Create Nginx reverse proxy",
      "intentPorts": "Requested (not published)",
      "customPort": "Another host port",
      "customPortHost": "Host port",
      "customPortContainer": "Container port",
      "pctUsed": "{{n}}% used",
      "customPortHint": "1–65535. Example: 9090 → 80.",
      "pickBridge": "Bridge network"
    },
    "deleteTitle": "Delete {{id}}",
    "deleteDesc": "This cannot be undone.",
    "deleteC1": "The resource is removed from this host.",
    "deleteComposeVal": "This is a validator stack — the validator instance is also deleted.",
    "pruneTitle": "Prune Docker resources",
    "pruneDesc": "Type PRUNE to confirm. Unused data cannot be restored.",
    "pruneC1": "Unused resources in the selected scope are deleted.",
    "pruneC2": "Volume and system prune permanently delete unused data volumes.",
    "pruneC3": "Stopped containers or unused images in this scope are removed."
  },
  "email": {
    "title": "Email",
    "subtitle": "Domains, DNS, mailboxes, and relay",
    "externalTodos": "Tasks you must handle outside the server",
    "ptr": "Reverse DNS (PTR) must be set by your VPS/cloud provider",
    "port25": "Outbound Port 25 may be blocked; request unblock or use a relay",
    "create": "Create mail domain",
    "createHint": "After create, review DNS, mailboxes, and health checks",
    "domains": "Registered domains",
    "empty": "No email domains yet",
    "emptyHint": "Create a domain to get DNS records and external todos",
    "searchPlaceholder": "Search domain…",
    "domain": "Domain",
    "serverIp": "Server IP",
    "notFound": "Email domain not found",
    "backToList": "Back to email domains",
    "softwareNeeded": "Required email software is not installed",
    "applyApplied": "Applied",
    "applyWritten": "Written",
    "applyFailed": "Failed",
    "applyDraft": "Draft",
    "queueMsgCount": "Queue {{count}} message(s)",
    "queueLoadFailed": "Failed to load queue",
    "queueFlushRequested": "Queue flush requested",
    "queueFlushFailed": "Flush failed",
    "queueDeleted": "Deleted {{id}}",
    "queueDeleteFailed": "Delete failed",
    "pillDomains": "{{count}} domain(s)",
    "pillNoDomain": "No domains",
    "statDomains": "Domains",
    "statHealthy80": "Health ≥80",
    "statApplied": "Applied",
    "statDraft": "Draft",
    "tabDomains": "Domains",
    "tabWebmail": "Webmail",
    "tabQueue": "Queue",
    "tabStack": "Software",
    "tabOps": "Roles",
    "webmailGlobalDesc": "One webmail app for the whole panel — every mail domain signs in through the same URL.",
    "webmailGlobalHint": "Needs system-change permission (YSK_EXECUTE) and outbound network to download Roundcube/SnappyMail. No half project is created without EXECUTE.",
    "webmailMovedHint": "Webmail is configured globally (not per domain).",
    "openGlobalWebmailSettings": "Open webmail settings",
    "domainsTitle": "Domains ({{filtered}}/{{total}})",
    "domainsListDesc": "Mail domains registered on this host",
    "emptyFilterHint": "No domains match the search",
    "emptyCreateHint": "Use Create in the toolbar to register a domain;",
    "queueLocalTitle": "Mail queue",
    "needExecute": "Needs YSK_EXECUTE",
    "viewQueue": "View queue",
    "flushQueue": "Flush queue",
    "flushQueueEmpty": "Queue is empty",
    "flushQueueNeedExecute": "Flushing the queue needs YSK_EXECUTE (host execute permission)",
    "queueHint": "Local Postfix queue. Viewing is a read probe; flush needs YSK_EXECUTE.",
    "deleteThisId": "Delete this ID",
    "queueEmpty": "No deferred mail",
    "queueEmptyHint": "No deferred messages",
    "mtaTitle": "MTA software",
    "mtaBody": "Probe and one-click install are driven by the banner above",
    "mtaSmtp": "SMTP outbound / inbound",
    "mtaImap": "IMAP / POP3 mailboxes",
    "mtaDkim": "Outbound DKIM signing",
    "mtaMissingHint": "When software is missing the banner shows install / re-probe",
    "pathTitle": "Domain setup path",
    "path1": "Register a domain (top-right)",
    "path2": "Open domain detail → one-click mail setup",
    "path3": "Add MX / SPF / DKIM / DMARC on DNS page or external checklist",
    "path4": "SSL for mail / webmail hostnames",
    "viewDomainList": "View domain list",
    "opsPanelTitle": "Panel vs external",
    "opsThisPage": "This page: domain registry, queue view, software probe",
    "opsDetail": "Domain detail: bootstrap, mailboxes, aliases, relay, webmail",
    "opsHost": "Host provider: PTR, Port 25 outbound policy",
    "opsRegistrar": "Registrar: publish MX / SPF / DKIM / DMARC",
    "statusTitle": "Status",
    "statusDraft": "Draft (panel only)",
    "deliverabilityChecks": "Checks",
    "statusWritten": "written: management files written, may not be live",
    "statusApplied": "applied: successfully applied before (still check service is-active)",
    "statusReputation": "Inbox reputation can never be 100% automated",
    "createModalDesc": "",
    "registerDomain": "Create",
    "domainApexHint": "No mail. prefix",
    "serverIpv4Hint": "MX/A/SPF",
    "serverIpv4Ph": "Public IPv4",
    "serverIpv6": "IPv6 (optional)",
    "serverIpv6Hint": "AAAA/SPF ip6",
    "serverIpv6Ph": "Optional",
    "registerNote": "",
    "flushConfirmTitle": "Flush entire mail queue?",
    "flushConfirmDesc": "Queued messages will be deleted. Cannot be undone.",
    "flushConfirm": "Flush",
    "tabMailbox": "Mailboxes",
    "tabAliases": "Aliases / forward",
    "tabHealth": "Health",
    "tabRelay": "Relay",
    "tabSieve": "Filter / SSO",
    "tabAdvanced": "Advanced",
    "pillApplied": "Applied",
    "pillManaged": "Managed files",
    "pillDraft": "Draft",
    "statHealth": "Health",
    "statApply": "Apply",
    "statDomain": "Domain",
    "pausedFlag": "Paused (flag)",
    "normal": "Normal",
    "statMailboxes": "Mailboxes",
    "statDnsRecords": "DNS records",
    "dnsTodosTitle": "DNS",
    "copyAllRecords": "Copy all records",
    "openDnsPage": "Open DNS page",
    "healthScore": "Health score",
    "healthUnchecked": "Not checked yet",
    "healthUncheckedHint": "Live DNS / PTR / port 25 have not been probed yet.",
    "healthPartialScore": "Partial {{n}}/100 (DNS only)",
    "healthPartialHint": "DNS checklist only — live and blacklist not probed.",
    "deliverabilityScore": "Deliverability pack",
    "opendkimNoReload": "OpenDKIM has no reload — use restart after key or table changes.",
    "opendkimNoReloadTitle": "systemctl reload opendkim is not supported on this stack",
    "healthChecklist": "Checklist {{score}}/100",
    "healthChecklistHint": "Checklist score — live DNS / PTR / port 25 not probed yet",
    "healthLiveHint": "Live probe score",
    "suggestedRecords": "Suggested records",
    "externalTodosCount": "External todos",
    "colType": "Type",
    "colName": "Name",
    "colValue": "Value",
    "colNote": "Note",
    "copy": "Copy",
    "noDnsRecords": "No DNS records",
    "externalTodosHeading": "External todos (panel cannot do these)",
    "externalTodosBody": "PTR, port 25, and registrar DNS are on you.",
    "copyExternalTodos": "Copy external todo list",
    "todoDone": "Done",
    "todoPending": "Todo",
    "refreshDnsHint": "Click Refresh to load DNS suggestions",
    "mailboxListTitle": "Mailboxes ({{count}})",
    "createMailbox": "+ Create mailbox",
    "writeDovecot": "Write Dovecot password DB",
    "noMailboxes": "No mailboxes yet — click Create mailbox",
    "mailboxOpsResult": "Mailbox operation result",
    "aliasesTitle": "Aliases / forward / catch-all",
    "aliasType": "Type",
    "aliasTypeAria": "Alias type",
    "typeForward": "Forward",
    "typeAlias": "Alias",
    "localPart": "Local part",
    "localPartHint": "e.g. sales",
    "targetMailbox": "Target mailbox",
    "targetMailboxHint": "Comma-separated for multiple",
    "addAlias": "Add alias",
    "noAliases": "No aliases / forwards yet",
    "aliasResult": "Alias result",
    "autoreplyTitle": "Autoreply / suspend",
    "autoreplyDesc": "Autoreply",
    "autoreplyBodyHint": "Optional apply to system",
    "enableAutoreply": "Enable autoreply",
    "enableAutoreplyDesc": "vacation.sieve; after system apply mounts .dovecot.sieve",
    "applyToSystem": "Apply to system (Postfix / Dovecot)",
    "applyToSystemDesc": "Needs YSK_EXECUTE=1 + root; failures are not faked as success",
    "subject": "Subject",
    "body": "Body",
    "saveApplyAutoreply": "Save and apply autoreply",
    "saveAutoreplyWritten": "Save autoreply",
    "suspendApply": "Suspend and apply REJECT",
    "suspendWritten": "Suspend domain (written)",
    "resumeApply": "Resume and update map",
    "resumeWritten": "Resume domain (written)",
    "flagsResult": "Flags / system apply result",
    "defaultAutoreplySubject": "Autoreply",
    "defaultAutoreplyBody": "We received your email and will reply later.",
    "healthLiveTitle": "Delivery health (live DNS / port probes)",
    "healthLiveDesc": "Live checks",
    "serverIpLabel": "Server IP",
    "liveCheck": "Live check",
    "liveOk": "Mostly OK",
    "liveBad": "Issues found",
    "notTested": "Not tested",
    "blacklist": "Blacklist",
    "healthExternalNote": "PTR and port 25 must be set at the host provider.",
    "runLiveCheck": "Run Live check",
    "dnsblThisIp": "DNSBL (this IP)",
    "multiIpRbl": "Multi-IP RBL",
    "warmupAdvice": "Warm-up tips",
    "probeMatrix": "Probe results",
    "colItem": "Item",
    "colStatus": "Status",
    "pass": "Pass",
    "fail": "Fail",
    "unknown": "Unknown",
    "colDetail": "Detail",
    "outboundPort25": "Outbound port 25",
    "noProbeResults": "No probe results yet",
    "noLiveYet": "Live check not run yet",
    "noLiveYetHint": "Run a live check first",
    "mailSslTitle": "Certificates & TLS",
    "mailSslHint": "Real issue is on SSL page; jump to mail / webmail / domain hostnames here",
    "openSslPage": "Open SSL page",
    "webmailSsoSkeleton": "Webmail SSO skeleton",
    "writeRoundcubeSso": "Write Roundcube SSO skeleton",
    "ssoSkeletonSymlink": "SSO skeleton + system symlink",
    "rateLimitTitle": "Outbound rate / antispam",
    "rateLimitDesc": "Writes Postfix anvil and Rspamd settings (applied only with YSK_EXECUTE + root)",
    "hourlyMsgCap": "Hourly message cap",
    "hourlyMsgCapHint": "Global uses the minimum across domains",
    "enableAntispam": "Enable antispam mark (Rspamd multimap)",
    "enableAntispamDesc": "Off keeps this domain out of the Rspamd antispam map. Write panel first, then apply to system.",
    "writeControlOnly": "Write panel only",
    "applyToSystemBtn": "Apply to system",
    "dnsblResult": "DNSBL result",
    "warmupResult": "Warm-up result",
    "policyResult": "Policy result",
    "relayTitle": "SMTP outbound relay",
    "relayHost": "Relay host",
    "applyRelaySystem": "Apply to system Postfix",
    "applyRelaySystemDesc": "Write system Postfix relay",
    "saveApplyRelay": "Save and apply to system",
    "saveOnly": "Save settings only",
    "relayResult": "Relay result",
    "webmailSsoTitle": "Webmail single sign-on",
    "webmailSsoDesc": "Issue one-time token;",
    "mailboxPasswordOptional": "Mailbox password (optional)",
    "mailboxPasswordHint": "Optional",
    "mailboxPasswordPh": "With password, token can auto-login Roundcube",
    "ssoTokenHint": "Issue a short-lived login token",
    "issueSsoToken": "Issue SSO token",
    "sieveTitle": "Sieve filters",
    "sieveDesc": "Filters",
    "sieveTemplateHint": "Default filter template",
    "writeDefaultSieve": "Write default Sieve",
    "listWrittenFiles": "List written files",
    "result": "Result",
    "domainSslTitle": "SSL for this domain",
    "domainSslDesc": "Mail host SSL",
    "requestCert": "Request cert for {{domain}}",
    "clientAutoTitle": "Client autoconfig",
    "clientAutoDesc": "Client autoconfig",
    "clientAutoHint": "Generate autodiscover/autoconfig",
    "generateCopyXml": "Generate and copy config XML",
    "queueTitle": "Mail queue",
    "queueDesc": "Local queue",
    "publicAutoconfig": "Public config",
    "bootstrapTitle": "One-click mail setup",
    "bootstrapDesc": "One-click setup",
    "adminPassword": "Admin password",
    "adminPasswordHint": "Admin mailbox password",
    "adminPasswordPh": "At least 8 characters",
    "adminPasswordRequired": "Set an admin password of at least 8 characters",
    "bootstrapBtn": "One-click mail setup",
    "webmailInstallDesc": "Download / apply Roundcube",
    "webmailHostname": "Webmail hostname",
    "webmailHostnameHint": "vhost server_name, e.g. webmail.example.com",
    "installWebmail": "Install / apply Webmail",
    "bootstrapResult": "Bootstrap / Webmail result",
    "createMailboxTitle": "Create mailbox",
    "createMailboxDesc": "Full address will be {{local}}@{{domain}}",
    "createMailboxBtn": "Create mailbox",
    "localPartLabel": "Local part",
    "localPartFullHint": "Full address will be {{local}}@{{domain}}",
    "passwordOptionalHint8": "Optional; if set, must be at least 8 characters",
    "live": {
      "noMx": "no MX",
      "mxLookupFailed": "MX lookup failed",
      "noSpf": "no SPF TXT",
      "spfLookupFailed": "SPF lookup failed",
      "noDkim": "no DKIM TXT",
      "dkimLookupFailed": "DKIM lookup failed",
      "noDmarc": "no DMARC",
      "dmarcLookupFailed": "DMARC lookup failed",
      "noPtr": "no PTR",
      "ptrLookupFailed": "PTR lookup failed",
      "port25Open": "Outbound TCP 25 appears open (probe to gmail-smtp-in.l.google.com)",
      "port25Blocked": "Outbound TCP 25 probe failed — may be blocked; request unblock or use relay",
      "dnsblListed": "LISTED: {{list}}",
      "dnsblClean": "clean on {{list}}"
    },
    "deliv": {
      "mx": "MX record",
      "mxFix": "Add MX at DNS provider pointing to mail host",
      "spf": "SPF TXT",
      "spfFix": "Publish v=spf1 including this IP",
      "dkim": "DKIM TXT",
      "dkimFix": "Publish selector._domainkey TXT from panel",
      "dmarc": "DMARC TXT",
      "dmarcFix": "Publish _dmarc policy (start with p=none)",
      "ptr": "Reverse DNS (PTR)",
      "ptrFix": "Set PTR at VPS/cloud console to match mail hostname — panel cannot set this",
      "port25": "Outbound Port 25",
      "port25Fix": "Request Port 25 unlock from hoster, or configure SMTP relay (submission 587)",
      "dnsbl": "DNSBL reputation",
      "dnsblFix": "Delist at listed services; stop sending until clean",
      "relay": "SMTP relay (when Port 25 blocked)",
      "relayOptional": "Port 25 probe open — relay optional",
      "relayPresent": "Relay config present under dataDir (apply may still need EXECUTE)",
      "relayMissing": "No relay configured — required if Port 25 stays blocked",
      "relayFix": "Panel Email → Relay, or ysk-server hosting email-bootstrap with relay",
      "warmup": "Warm-up plan",
      "warmupDetail": "{{phases}} phases · day1 max {{day1}} msgs",
      "warmupFix": "Follow phase limits; do not blast cold lists from a new IP",
      "honesty1": "Panel never guarantees worldwide inbox delivery (Gmail/Outlook filtering is external).",
      "honesty2": "PTR and Port 25 are owned by the VPS/network provider — not by YSK control plane.",
      "honesty3": "DNS MX/SPF/DKIM/DMARC must be published at the authoritative DNS provider.",
      "honestyPortBlocked": "Port 25 appears blocked — use relay or request unlock before high volume.",
      "honestyPortOk": "Port 25 probe succeeded — still monitor bounces and DNSBL."
    },
    "catchall": "Catch-all",
    "webmailRoundcube": "Webmail",
    "warmup": {
      "p1g1": "Send only transactional / known-good recipients",
      "p1g2": "Monitor bounces; keep complaint rate near zero",
      "p1g3": "Ensure SPF/DKIM/DMARC/PTR are live before volume",
      "p2g1": "Expand slowly to engaged contacts only",
      "p2g2": "Check DNSBL daily; pause if listed",
      "p2g3": "Prefer 587 submission over bulk on port 25 if restricted",
      "p3g1": "Double volume only if metrics stay clean",
      "p3g2": "Segment lists; remove hard bounces immediately",
      "p4g1": "Approach normal volume if no blocks",
      "p4g2": "Keep DMARC rua monitored",
      "c1": "PTR matches HELO/EHLO (mail hostname)",
      "c2": "SPF + DKIM + DMARC published and aligned",
      "c3": "DNSBL clean on Spamhaus / SpamCop / Barracuda",
      "c4": "Outbound port 25 open or relay configured",
      "c5": "No purchased “bulk email” IP ranges",
      "c6": "Domain age / history considered (new domains = slower ramp)",
      "noteNewIp": "Treat this IP as new — start at phase day 1–3 limits",
      "noteOldIp": "Existing IP still benefits from gradual ramp after config changes",
      "noteProcess": "Warm-up is operator process; YSK tracks tips + DNSBL, not marketing ESP volume"
    },
    "health": {
      "dnsUnconfirmed": "DNS records (MX/SPF/DKIM) not yet confirmed",
      "dmarcMissing": "DMARC missing — strongly recommended",
      "dmarcUnpublished": "DMARC is generated in the panel but not published in public DNS yet",
      "ptrBad": "PTR reverse DNS missing or incorrect — request at VPS provider",
      "port25Blocked": "Outbound Port 25 appears blocked — request unblock or use SMTP relay",
      "port25Unknown": "Port 25 status unknown — run connectivity check"
    },
    "stack": {
      "tlsNote": "TLS certs via Let’s Encrypt for SMTP/IMAP",
      "externalNote": "External DNS/PTR/Port25 still required for deliverability"
    },
    "test": {
      "defaultSubject": "YSK Server mail test",
      "needMta": "Requires local MTA (Postfix) installed and Port 25/relay configured",
      "checkSpam": "Check recipient spam folder and server mail logs after send",
      "hintDeferred": "If deferred: check Port 25 block or relay credentials",
      "hintSpam": "If accepted but spam: improve SPF/DKIM/DMARC/PTR and warm-up",
      "hintLogs": "Inspect /var/log/mail.log or journalctl -u postfix"
    },
    "leMailHost": "Request cert · {{host}}",
    "leWebmailHost": "Request cert · {{host}} (webmail)",
    "leApexHost": "Request cert · {{host}} (apex)",
    "applyMailTls": "Apply mail TLS paths",
    "applyMailTlsHint": "Certificate must exist; writes mail service paths and reloads.",
    "probeMx": "MX",
    "probeSpf": "SPF",
    "probeDkim": "DKIM",
    "probeDmarc": "DMARC",
    "probePtr": "PTR",
    "probeDnsbl": "DNSBL",
    "dnsAuthRepairTitle": "DNS auth needs fix",
    "dnsAuthRepairHint": "Copy records from the DNS tab and publish.",
    "fixHintSpf": "SPF failed: publish a v=spf1 TXT at @.",
    "fixHintDkim": "DKIM failed: publish selector._domainkey TXT.",
    "fixHintDmarc": "DMARC failed: publish _dmarc TXT.",
    "fixHintMx": "MX failed: point MX to mail.<domain>.",
    "mailTls": {
      "needRootExecute": "Applying mail TLS needs root and YSK_EXECUTE.",
      "certMissing": "No cert files for {{host}} ({{path}}).",
      "getCertFirst": "Issue a Let’s Encrypt cert for {{host}} on the SSL page first.",
      "certFound": "Found cert for {{host}}.",
      "postconfFailed": "postconf failed: {{detail}}",
      "postfixPathsSet": "Postfix TLS cert paths set.",
      "postfixReloaded": "Postfix reloaded.",
      "postfixReloadFailed": "Postfix reload failed: {{detail}}",
      "dovecotApplied": "Wrote Dovecot TLS snippet and attempted reload.",
      "dovecotSkipped": "Skipped Dovecot (not installed or doveconf unavailable).",
      "dovecotSslOmitted": "Mail certificate is missing; wrote ssl=no so Dovecot can start without the LE files."
    },
    "policyApplySystemHint": "Check “apply to system” to write Postfix/Rspamd maps and reload;",
    "rateLimitAppliedNote": "Hourly outbound rate and antispam flag applied (when system apply is on).",
    "bootstrapHonesty": "One-click writes panel files; apply to system needs rights. DNS/PTR/port 25 are manual.",
    "bootstrapAfterSteps": "Next: ① publish DNS (MX/SPF/DKIM/DMARC) ② issue mail SSL ③ Apply mail TLS paths.",
    "bootstrapThenSsl": "Next: issue mail SSL",
    "bootstrap": {
      "mtaOk": "MTA configs written ({{count}} files)",
      "mtaIncomplete": "MTA incomplete: {{detail}}",
      "seeNotes": "see notes",
      "mailboxOk": "Mailbox {{address}} (status {{status}})",
      "mailboxExists": "Mailbox already exists (skipped): {{detail}}",
      "passdbOk": "Dovecot passdb written ({{count}} mailboxes)",
      "webmailOk": "Webmail plan {{mode}} for {{host}}",
      "mailTlsTodo": "Mail TLS: issue a cert for {{mailHost}}, then use Apply mail TLS paths on the health tab.",
      "externalDns": "External (operator-owned): set MX/SPF/DKIM/DMARC at DNS; PTR at VPS; Port 25 or SMTP relay.",
      "healthScore": "Health score {{score}}/{{max}} (DNS/PTR/Port25 not auto-complete)",
      "webmailProjectOk": "Webmail project {{tool}} @ {{host}} ({{status}})",
      "dovecotApplyOk": "Dovecot virtual auth applied"
    },
    "tabDeliverability": "Delivery",
    "pendingCount": "Pending",
    "externalTodosOneLiner": "PTR, port 25, and registrar DNS must be done by you.",
    "runDeliverabilityPack": "Run delivery check",
    "deliverabilityTitle": "Delivery check",
    "deliverabilityEmpty": "Not checked yet",
    "deliverabilityEmptyDesc": "Run delivery check for DNS, PTR, and port 25.",
    "panelReady": "Panel-checkable",
    "gaps": "Gaps",
    "checkOk": "OK",
    "checkExternal": "External",
    "checkFail": "Fail",
    "mailboxListDesc": "Write password DB after create",
    "aliasesDesc": "Aliases and forwards",
    "relayDesc": "SMTP relay",
    "deliverabilityDesc": "PTR / DNS / port 25 checks",
    "dnsTodosDesc": "Copy then add at your DNS host",
    "deliverabilityHonesty": "Cannot set PTR or unlock port 25 for you",
    "warmupSuggest": "Warm-up suggestions",
    "writeSsoSkeleton": "Write Roundcube SSO skeleton",
    "rateLimitPerHour": "Hourly message cap",
    "rateLimitGlobalHint": "Global cap uses the lowest per-domain limit",
    "savePolicyWritten": "Written to the control plane only",
    "dnsblMultiIp": "Multi-IP RBL",
    "webmailTool": "Webmail software",
    "webmailToolRoundcube": "Roundcube (default)",
    "webmailToolSnappy": "SnappyMail (lightweight)",
    "webmailProjectName": "Project name",
    "installWebmailProject": "Create & go live",
    "openWebmail": "Open webmail",
    "webmailRisk": "Public webmail is risky — enable HTTPS soon.",
    "webmailForceHttps": "Force HTTPS (Roundcube; SSL required)",
    "reinstallWebmail": "Reinstall / upgrade",
    "installWebmailTitle": "Create the shared webmail project (first install)",
    "reinstallWebmailTitle": "Rebuild / upgrade the existing webmail project",
    "reinstallNeedInstall": "Install webmail first",
    "webmailSsoAdvanced": "Advanced · SSO plugin",
    "tlsRoleMail": "mail (IMAP/SMTP)",
    "tlsRoleMailHint": "Mail server hostname",
    "tlsRoleWebmail": "webmail",
    "tlsRoleWebmailHint": "Webmail virtual host",
    "tlsRoleApex": "Apex domain",
    "tlsRoleApexHint": "Web / apex certificate",
    "tlsRequestLe": "Request LE",
    "tlsRequestLeFor": "Request LE for {{host}}",
    "advancedToolsTitle": "Queue & clients",
    "flushQueueConfirm": "Flush the local MTA queue? This cannot be undone.",
    "mailSslTitleShort": "Certificates & TLS",
    "deleteDomain": "Delete domain",
    "deleteDomainConfirmTitle": "Delete email domain?",
    "deleteDomainConfirm": "Deletes {{domain}} and its mailboxes, aliases, and control-plane data. System Postfix/Dovecot config may still need cleanup.",
    "deleteDomainBtn": "Delete",
    "deleteMailbox": "Delete mailbox",
    "deleteMailboxTitle": "Delete mailbox?",
    "deleteMailboxDesc": "Deletes {{address}}, control-plane data, and local Maildir if present.",
    "deleteMailboxC1": "Mailbox login and mail files",
    "deleteMailboxC2": "Rewrite domain virtual map (control plane)",
    "deleteMailboxC3": "System Dovecot/Postfix may still need cleanup",
    "deleteAliasTitle": "Delete alias/forward?",
    "deleteAliasDesc": "Deletes {{source}}.",
    "deleteImpact": "{{mailboxes}} mailboxes · {{records}} DNS records · {{aliases}} aliases",
    "deleteDomainC1": "All mailboxes and aliases",
    "deleteDomainC2": "Control-plane DKIM, DNS suggestions, and flags",
    "deleteDomainC3": "Local dataDir/email directory if present",
    "deleteDomainC4": "System MTA maps may remain; clean separately if needed",
    "deleteDialogTitle": "Permanently delete mail domain",
    "deleteDialogDesc": "About to delete {{domain}}. This cannot be undone.",
    "deletePermanent": "Delete permanently",
    "deleteRemoveData": "Also remove local mail data",
    "deleteRemoveDataDesc": "Uncheck to remove from panel only; Maildir stays on disk",
    "deleteTypeName": "Type the domain to confirm",
    "deleteTypeNameHint": "Must match exactly: {{name}}",
    "deleteWillData": "Local dataDir/email directory if present",
    "deleteKeepData": "Keep local dataDir mail data",
    "deleteSystemWarn": "System Postfix/Dovecot maps are not auto-cleaned; clean separately if needed.",
    "hostIpPick": "Host IPv4",
    "hostIpPickV6": "Host IPv6",
    "editMailboxTitle": "Edit mailbox",
    "editMailboxDesc": "Change password or login settings for {{address}}",
    "editMailboxSave": "Save changes",
    "newPassword": "New password",
    "newPasswordHint": "Leave blank to keep the current password (min. 8 characters if set)",
    "confirmPassword": "Confirm password",
    "mailboxStatus": "Status",
    "mailboxStatusActive": "Active (login allowed)",
    "mailboxStatusDisabled": "Disabled (login blocked)",
    "mailboxStatusHint": "Disabled exports * to Dovecot passdb so login is denied",
    "colAddress": "Address",
    "colLocalPart": "Local part",
    "colPassword": "Password",
    "colCreated": "Created",
    "hasPassword": "Set",
    "noPassword": "Not set",
    "mailboxPager": "Mailbox pages",
    "prevPage": "Previous",
    "nextPage": "Next",
    "pageOf": "Page {{page}} / {{total}} · {{count}}",
    "mailboxEmptyTitle": "No mailboxes yet",
    "passwordMismatch": "Passwords do not match",
    "passwordTooShort": "Password must be at least 8 characters",
    "mailboxUpdateNeedField": "Set a new password or change status",
    "catchallHint": "Unknown local parts go to the target mailbox. Draft until mail apply.",
    "queueSearchPh": "Search ID, sender, or recipient…",
    "queueId": "Queue ID",
    "queueSender": "Sender",
    "queueRecipients": "Recipients",
    "queueSize": "Size",
    "queueReason": "Reason",
    "queueActive": "Active",
    "queueHeld": "Held",
    "queueDeferred": "Deferred",
    "deleteQueueTitle": "Delete this queued message?",
    "deleteQueueDesc": "Remove {{id}} from the local MTA queue. Needs YSK_EXECUTE.",
    "openQueuePage": "Open mail queue",
    "dovecotFailedHint": "Dovecot failed. Open the Software tab for the unit status.",
    "dovecotFailedStatus": "Dovecot is {{status}}. Open the Software tab for the unit summary.",
    "mailCertMissing": "No certificate for {{hosts}}. Issue it on the SSL page.",
    "mailCertPresent": "A mail certificate is already issued — this is not a missing-cert problem.",
    "webmailNeedCert": "No certificate for {{host}} — issue it on SSL before forcing HTTPS.",
    "domainRequired": "Enter a domain",
    "domainInvalid": "Enter a valid domain",
    "serverIpRequired": "Enter a server IP",
    "serverIpInvalid": "Enter a valid IP address",
    "serverIpv6Invalid": "Enter a valid IPv6 address",
    "localPartRequired": "Enter a local part",
    "localPartInvalid": "Local part may only use letters, digits, . _ + -",
    "aliasDestRequired": "Enter at least one destination address",
    "mailboxStatusManaged": "Managed",
    "mailboxStatusActiveShort": "Active",
    "mailboxStatusDisabledShort": "Disabled",
    "mailboxStatusSystem": "System provisioned",
    "mailboxStatusPending": "Pending system",
    "mailboxStatusFailed": "System failed",
    "dnsblCleanStatus": "Not listed",
    "dnsblListedStatus": "Listed",
    "deliverabilityDone": "Delivery check complete ({{score}}/100)",
    "sieveEmpty": "No written Sieve files",
    "sieveListed": "{{count}} written file(s)",
    "webmailHostnameRequired": "Enter a webmail hostname",
    "sieveFilesTitle": "Written files"
  },
  "errors": {
    "YSK_UNAUTHORIZED": "Unauthorized",
    "YSK_FORBIDDEN": "Forbidden",
    "YSK_NOT_FOUND": "Not found",
    "YSK_VALIDATION": "Invalid input",
    "YSK_ALLOWLIST_DENIED": "Not on allowlist",
    "YSK_APPROVAL_REQUIRED": "Approval required",
    "YSK_APPROVAL_PENDING": "Approval pending",
    "YSK_APPROVAL_REJECTED": "Approval rejected",
    "YSK_SANDBOX_VIOLATION": "Sandbox violation",
    "YSK_LLM_UNTRUSTED": "Untrusted LLM output",
    "YSK_CONFIG_INVALID": "Invalid configuration",
    "YSK_SETUP_INCOMPLETE": "Setup incomplete",
    "YSK_UPDATE_FAILED": "Update failed",
    "YSK_INTERNAL": "Internal error",
    "YSK_NEED_EXECUTE": "Host execute permission required",
    "YSK_NEED_ROOT": "Root required",
    "YSK_RATE_LIMITED": "Too many attempts; try again later",
    "YSK_TOTP_REQUIRED": "Authentication code required",
    "auth": {
      "needCredentials": "Enter username and password",
      "rateLimited": "Too many sign-in attempts; try again later",
      "badCredentials": "Incorrect username or password",
      "accountSuspended": "Account suspended",
      "adminTotpStrict": "Admins must enable 2FA (strict). Use an enrolled account or disable strict mode.",
      "totpReplay": "Code already used; wait for the next period",
      "totpRequired": "A valid authentication code is required",
      "mustEnrollTotp": "Policy: enable two-factor authentication now",
      "userNotFound": "User not found",
      "totpSetupNeedReauth": "Enabling 2FA requires your password (or a recent step-up code)",
      "totpBeginFirst": "Start 2FA setup first",
      "totpInvalid": "Invalid authentication code",
      "stepUpRequired": "This action requires a fresh authentication code",
      "missingCredential": "Missing credentials",
      "apiKeyUserMissing": "API key owner not found",
      "apiKeyInvalid": "Invalid API key",
      "sessionExpired": "Session expired; sign in again",
      "sessionIdle": "Idle timeout; sign in again",
      "totpNotEnabled": "2FA is not enabled",
      "totpSecretNoDataDir": "TOTP secret is encrypted but dataDir is not set",
      "mustChangePassword": "You must set a new password before continuing",
      "policyNeedsOwn2fa": "Turn on 2FA for this account and confirm with a TOTP code before requiring 2FA for others"
    },
    "http": {
      "notFoundRoute": "Not found: {{method}} {{path}}",
      "unauthorized": "Not signed in or session expired",
      "forbidden": "You do not have permission for this action",
      "notFound": "Resource not found",
      "unprocessable": "Request rejected by server",
      "requestFailed": "Request failed ({{status}})",
      "jsonInvalid": "Invalid JSON",
      "internal": "Internal error",
      "payloadTooLarge": "Request body is too large"
    },
    "YSK_HOST_BROWSE_SSRF": "Host browse blocked by security policy",
    "YSK_HOST_BROWSE_SESSION": "Host browse session not found or expired",
    "YSK_HOST_BROWSE_UPSTREAM": "Host browse upstream fetch failed",
    "YSK_HOST_BROWSE_NEED_CHROME": "Real browser engine requires Chrome/Chromium on the host"
  },
  "fail2ban": {
    "backToProtection": "Protection",
    "statCurrentBan": "Current bans",
    "statTotal": "Total banned",
    "statBanList": "Ban list",
    "statBoot": "On boot",
    "startedOk": "fail2ban started",
    "startService": "Start service",
    "notInstalled": "fail2ban is not installed",
    "toolHintPrefix": "Underlying tools:",
    "toolHintBody": "fail2ban temporarily bans after scanning logs. For attack response use",
    "toolHintTemp": "",
    "toolHintBody2": "",
    "toolHintUfw": "handles ports and permanent rules.",
    "tabs": {
      "bans": "Ban list",
      "whitelist": "Whitelist",
      "jails": "Jails",
      "policy": "Policy",
      "service": "Service",
      "about": "About"
    },
    "manualBanTitle": "Manual ban (temporary)",
    "ipPlaceholder": "IPv4 or IPv6",
    "banipOk": "banip done",
    "manualBanHint": "Temporary block;",
    "currentBans": "Currently banned",
    "bannedTableTitle": "Banned IPs (live fail2ban-client)",
    "bannedTableDesc": "Needs client access; unban needs YSK_EXECUTE",
    "unbanOk": "Unbanned",
    "unban": "Unban",
    "addWhitelistTitle": "Add to ignoreip whitelist",
    "whitelistAdded": "Added to whitelist",
    "addWhitelistShort": "+Whitelist",
    "emptyBansTitle": "No banned IPs",
    "emptyBansDesc": "Or no permission to read fail2ban-client",
    "ignoreipTitle": "ignoreip whitelist",
    "ignoreipDesc": "IPs never banned (panel file + optional live fail2ban-client)",
    "whitelistEmptyWarn": "Whitelist is empty while jails can ban you. Add your login IP before applying ignoreip.",
    "suggestIgnoreLogin": "Your login IP {{ip}}",
    "applyIgnoreEmptyWarn": "Applying with an empty whitelist clears ignoreip",
    "applyIgnoreNeedConfirm": "Rewrites jail ignoreip and reloads fail2ban",
    "addIp": "Add IP",
    "addWhitelist": "Add to whitelist",
    "applyPolicyIgnoreip": "Apply policy (incl. ignoreip)",
    "applyIgnoreipOk": "Wrote ignoreip into jail.local and applied",
    "ignoreipHint": "Without system-change permission only the panel file is written. Apply policy rebuilds jail.local ignoreip and reloads.",
    "whitelistTitle": "Whitelist ({{count}})",
    "whitelistRemoved": "Removed from whitelist",
    "remove": "Remove",
    "emptyWhitelistTitle": "No whitelist IPs yet",
    "emptyWhitelistDesc": "Add admin IPs so you are not banned",
    "activeJails": "Active jails",
    "colCurrent": "Current",
    "colTotal": "Total",
    "colDesc": "Description",
    "emptyJailsTitle": "No jails",
    "emptyJailsDesc": "Service not running or jail.local not applied",
    "policyTitle": "Jail policy",
    "policyDesc": "Writes panel jail.local; apply copies + reloads (not via UFW)",
    "bantimeHint": "Ban duration",
    "findtimeHint": "Counting window",
    "maxretryHint": "Max failures in window",
    "customExample2h": "Custom, e.g. 2h",
    "customExample15m": "Custom, e.g. 15m",
    "customMaxretry": "Custom 1–50",
    "min": "{{n}} min",
    "hour": "{{n}} h",
    "week": "{{n}} wk",
    "enableJailsHint": "Enable jails (check then apply):",
    "writtenOnlyMsg": "Wrote panel file (not applied on host)",
    "writeOnly": "Write panel file only",
    "appliedOk": "fail2ban applied",
    "applyToSystem": "Apply to system",
    "systemdTitle": "systemd control",
    "enableAndStart": "Enable and start",
    "serviceHint": "For attack response use",
    "serviceHintSuffix": "(calls this page’s jails + Nginx rate limits;",
    "actionOk": {
      "enable": "fail2ban enabled and started",
      "start": "fail2ban started",
      "reload": "fail2ban reloaded",
      "restart": "fail2ban restarted",
      "stop": "fail2ban stopped"
    },
    "statWhitelist": "Whitelist",
    "invalidIp": "Enter a valid IPv4, IPv6, or CIDR.",
    "whitelistPendingApply": "Saved to the panel list. Press Apply policy to write jail.local.",
    "ignoreipFile": "dataDir/fail2ban/ignoreip.txt",
    "jailsTabHint": "Status of active jails. Turn jails on or off in the Policy tab.",
    "colJail": "Jail",
    "colEnabled": "On",
    "serviceStateLine": "Unit {{unit}} · {{state}} · boot {{boot}}",
    "jail": {
      "sshd": "SSH brute-force",
      "nginxHttpAuth": "Nginx HTTP authentication",
      "nginxBotsearch": "Nginx scanner / bot probes",
      "nginxBadbots": "Nginx known bad bots",
      "nginxLimitReq": "Nginx rate-limit jail",
      "postfix": "Postfix mail brute-force",
      "dovecot": "Dovecot mail login",
      "recidive": "Repeat offenders"
    },
    "cannotBanSelf": "This is the host or your login IP — add it to ignoreip instead of banning",
    "suggestIgnoreHint": "Suggested admin IPs (panel file only until you apply policy):",
    "suggestIgnoreAdd": "Add {{ip}}"
  },
  "featurePage": {
    "back": "Back"
  },
  "files": {
    "pillFiles": "{{count}} files",
    "pillTrash": "{{count}} in trash",
    "pillSpace": "{{used}} used",
    "statFiles": "Files",
    "statFolders": "Folders",
    "statUsage": "Usage",
    "statSelected": "Selected",
    "statTrash": "Trash",
    "statShares": "Shares",
    "publicSiteSettings": "Public site settings",
    "opsResultTitle": "File operation result",
    "closeResult": "Close result",
    "tabBrowse": "Browse",
    "tabTrash": "Trash",
    "tabShares": "Shares",
    "spaceLabel": "Space",
    "publicFiles": "Public files",
    "viewLabel": "View",
    "allFiles": "All files",
    "favorites": "Favorites",
    "upload": "Upload",
    "newFolder": "New folder",
    "newTextFile": "New text file",
    "download": "Download",
    "copy": "Copy",
    "move": "Move",
    "zip": "Zip",
    "unzip": "Unzip",
    "unzipDone": "Unzipped {{path}}",
    "unzipFailed": "Unzip failed",
    "delete": "Delete",
    "searchName": "Search…",
    "sortAria": "Sort",
    "sortNameAsc": "Name↑",
    "sortNameDesc": "Name↓",
    "sortSizeAsc": "Small↑",
    "sortSizeDesc": "Large↓",
    "sortMtimeDesc": "Newest",
    "sortMtimeAsc": "Oldest",
    "viewList": "List",
    "viewIcons": "Icons",
    "viewAria": "View mode",
    "toolbarAria": "File actions",
    "pathAria": "Path",
    "rootPublic": "Public",
    "rootProject": "Project",
    "emptyFavorites": "No favorites yet",
    "emptyFolder": "This folder is empty",
    "emptyFolderHint": "Drop files or folders here to upload, or click Upload",
    "selectItem": "Select {{name}}",
    "colName": "Name",
    "colSize": "Size",
    "colMtime": "Modified",
    "rename": "Rename",
    "unfavorite": "Unfavorite",
    "favorite": "Favorite",
    "share": "Share",
    "versions": "Versions",
    "selectAllAria": "Select all",
    "selectAll": "Select all",
    "folder": "Folder",
    "dirNamedLikeFile": "(folder leftover; name looks like a file)",
    "dropToUpload": "Drop to upload",
    "trashTitle": "Trash ({{count}})",
    "trashDesc": "Deleted files can be restored or permanently removed",
    "emptyTrash": "Empty trash",
    "emptyTrashTitle": "Empty trash?",
    "emptyTrashDesc": "Every file in trash will be permanently deleted. This cannot be undone.",
    "purgeForeverDesc": "This file will be permanently deleted. This cannot be undone.",
    "emptyTrashDone": "Trash emptied",
    "colOrigPath": "Original path",
    "colDeletedAt": "Deleted at",
    "restore": "Restore",
    "restored": "Restored",
    "purgeForever": "Delete forever",
    "purged": "Permanently deleted",
    "trashEmpty": "Trash is empty",
    "sharesTitle": "Public share links ({{count}})",
    "colPath": "Path",
    "colLink": "Link",
    "colDownloads": "Downloads",
    "unshare": "Unshare",
    "unshareDone": "Share cancelled",
    "sharesEmpty": "No shares yet",
    "sharesEmptyHint": "Click Share on a file row",
    "webdavTitle": "WebDAV settings",
    "webdavDesc": "Mount the public files root via HTTP Basic in Finder, Windows, or rclone. Token is shown once.",
    "enableIssueToken": "Enable and issue token",
    "webdavReissueToken": "Re-issue token",
    "webdavReissueConfirm": "Re-issuing invalidates the old password immediately; mounted clients will disconnect. Continue?",
    "webdavDisableConfirm": "Disabling will reject all /webdav connections. Continue?",
    "tokenIssued": "Token issued",
    "status": "Status",
    "enabledMount": "Enabled · {{path}}",
    "notEnabled": "Not enabled",
    "disable": "Disable",
    "webdavAlreadyOff": "WebDAV is already off",
    "webdavDisabled": "WebDAV disabled",
    "webdavEnabledNoEcho": "Enabled (password will not be shown again; re-issue if needed)",
    "webdavDefaultOff": "Off by default — click Enable and issue token to start",
    "webdavAfterEnable": "Available after you enable WebDAV and issue a token.",
    "webdavOn": "Enabled",
    "webdavOff": "Disabled",
    "webdavOffNoToken": "Disabled (no active token)",
    "webdavTokenId": "Token #{{id}}",
    "webdavTokenInactive": "Disabled — token #{{id}} is not active",
    "webdavUpdated": "Updated {{at}}",
    "webdavTokenOnceTitle": "Copy the password now",
    "webdavTokenOnceHint": "This password is shown only once; it cannot be retrieved after you leave this page.",
    "webdavConnTitle": "Connection",
    "webdavConnDesc": "Use this URL with HTTP Basic credentials in your client",
    "webdavUrl": "Server URL",
    "webdavUsername": "Username",
    "webdavPassword": "Password (token)",
    "webdavPasswordHidden": "Issued earlier and not re-shown — re-issue or use a saved password",
    "webdavPasswordNone": "Not issued yet",
    "webdavRoot": "Mount root",
    "webdavRootValue": "Panel public files root",
    "webdavAuth": "Authentication",
    "webdavAuthValue": "HTTP Basic · user ysk · password = panel-issued token",
    "webdavConnBundle": "connection details",
    "webdavCopyAll": "Copy all connection details",
    "webdavClientsTitle": "Client setup",
    "webdavClientsDesc": "Common mount recipes (prefer HTTPS; trust self-signed certs in the client if needed)",
    "webdavClientFinder": "macOS Finder",
    "webdavClientFinderHint": "Go → Connect to Server… (⌘K), paste the URL, user ysk, password = token.",
    "webdavClientWin": "Windows",
    "webdavClientWinHint": "This PC → Map network drive → use different credentials; or Cyberduck / WinSCP (WebDAV).",
    "webdavNotesTitle": "Notes",
    "webdavNote1": "WebDAV maps the public files root only — not the whole host filesystem.",
    "webdavNote2": "Expose the panel port via reverse proxy/firewall; prefer HTTPS only.",
    "webdavNote3": "Re-issuing invalidates the old token immediately; disable rejects all /webdav requests.",
    "webdavNote4": "Supports OPTIONS / PROPFIND / GET / PUT; full LOCK suite may be incomplete.",
    "copiedLabel": "Copied “{{label}}”",
    "newFolderTitle": "New folder",
    "willCreateAt": "Will create under \"{{path}}\"",
    "nameRequired": "Enter a name",
    "folderCreated": "Folder created",
    "create": "Create",
    "folderName": "Folder name",
    "noPathSepHint": "Must not contain path separators",
    "newTextTitle": "New text file",
    "fileNameRequired": "Enter a file name",
    "textFileCreated": "Text file created",
    "fileName": "File name",
    "fileNameHint": "e.g. readme.md or notes.txt",
    "versionsTitle": "Version history",
    "versionsDesc": "",
    "noVersions": "No version history yet",
    "noVersionsHint": "",
    "versionRestored": "Restored",
    "restoreVersionConfirm": "Restore {{version}} over the current file {{file}}? This overwrites the file on disk.",
    "renameTitle": "Rename",
    "renameCurrent": "Current: {{name}}",
    "renamed": "Renamed",
    "newName": "New name",
    "newNameHint": "Renames only; stays in the same directory",
    "copyTo": "Copy to…",
    "moveTo": "Move to…",
    "copyMoveDesc": "{{action}} {{count}} item(s)",
    "actionCopy": "Copy",
    "actionMove": "Move",
    "copied": "Copied",
    "moved": "Moved",
    "targetFolderPath": "Target folder path",
    "targetFolderHint": "Relative to root, e.g. docs or docs/a; empty = root",
    "shareCreateTitle": "Share file",
    "shareCreateDesc": "Create a public download link. Optional password.",
    "createLink": "Create link",
    "sharePath": "Path: ",
    "passwordOptional": "Password (optional)",
    "passwordOptionalHint": "Leave empty for open access",
    "passwordPlaceholder": "Optional",
    "linkCreated": "Link created: ",
    "chmodTitle": "Change permissions (chmod)",
    "chmodDone": "chmod {{mode}} → {{count}} item(s)",
    "chmodDoneShort": "chmod {{mode}} done",
    "chmodFailed": "chmod failed",
    "apply": "Apply",
    "chmodApplyHint": "Apply to {{count}} selected item(s) (octal, e.g. 644 / 755)",
    "chmod644": "644 file",
    "chmod755": "755 executable",
    "chmod600": "600 private",
    "chmod700": "700 private dir",
    "chmod775": "775 group write",
    "chmodCustomPh": "Custom 0644…",
    "mode": "Mode",
    "zipTitle": "Compress to zip",
    "zipCreated": "Created {{path}}",
    "zipDone": "Zipped → {{path}}",
    "zipFailed": "zip failed",
    "compress": "Compress",
    "zipHint": "Zip {{count}} selected item(s) into current folder (needs zip on host)",
    "destFileName": "Destination file name",
    "destPathHint": "Path: {{path}}",
    "movedToTrash": "Moved to trash",
    "moveToTrashTitle": "Move to trash?",
    "moveToTrashDesc": "Delete {{count}} item(s) (restorable from trash)",
    "deleteMore": " and {{n}} more",
    "unshareTitle": "Revoke this share?",
    "unshareDesc": "Revoke the link for {{name}} ({{url}}). The link stops working immediately.",
    "preview": "Preview",
    "imagePreviewNeedLogin": "Image preview needs login; use download instead",
    "pdfDownloadHint": "Download PDF to open (needs auth headers)",
    "noEmbedPreview": "This type cannot be embedded; please download.",
    "uploadDone": "Uploaded {{count}} file(s)",
    "downloadFailedStatus": "Download failed ({{status}})",
    "downloadFailed": "Download failed",
    "uploadFolder": "Upload folder",
    "dropFolderOrFile": "Drop files or folders to upload",
    "uploadPanelTitle": "Uploads",
    "uploadPanelStats": "{{done}}/{{total}} done · {{err}} failed",
    "uploadClearDone": "Clear finished",
    "uploadInFolder": "Folder {{folder}}",
    "uploadStatusDone": "Done",
    "uploadStatusError": "Failed",
    "uploadStatusQueued": "Queued",
    "uploadNoFile": "No file data",
    "uploadSomeFailed": "{{count}} item(s) failed",
    "uploadTruncated": "Upload limited to {{max}} items ({{total}} selected; rest skipped)",
    "previewFailed": "Preview failed",
    "videoNotSupported": "Your browser cannot play this video.",
    "audioNotSupported": "Your browser cannot play this audio.",
    "edit": "Edit",
    "editorTitle": "Edit · {{name}}",
    "editorSave": "Save",
    "editorSavedIdle": "Saved",
    "editorSaved": "Saved {{name}}",
    "editorSaveFailed": "Save failed",
    "editorDirty": "Unsaved",
    "editorClean": "Saved",
    "editorChars": "{{count}} chars",
    "editorAria": "Editor for {{name}}",
    "editorDiscardConfirm": "Discard unsaved changes?",
    "shareReadyTitle": "Link ready",
    "shareReadyDesc": "Copy and send this link. Anyone with it can download.",
    "shareReadyBadge": "Created",
    "shareProtected": "Password protected",
    "shareOpenAccess": "No password",
    "shareLinkLabel": "Public link",
    "shareCopyHint": "Select the field or use Copy.",
    "shareAgain": "New link",
    "shareCreatedToast": "Share link created",
    "linkCopied": "Link copied",
    "linkCopyFailed": "Could not copy — select and copy manually",
    "shareExpireLabel": "Link expiry",
    "shareExpireHint": "After this time the link stops working",
    "shareExpireNever": "Never",
    "shareExpire1h": "1 hour",
    "shareExpire1d": "1 day",
    "shareExpire7d": "7 days",
    "shareExpire30d": "30 days",
    "shareExpireCustom": "Custom…",
    "shareExpireAt": "Expires at",
    "shareExpireInvalid": "Pick a future date and time",
    "shareExpiresAt": "Expires {{at}}",
    "colExpires": "Expires",
    "pdfInlineHint": "If the PDF does not display, download it.",
    "publicShareTitle": "Someone shared a file with you",
    "publicShareSub": "Download securely from this link — no account needed",
    "publicShareChecking": "Checking link…",
    "publicShareDownloading": "Downloading…",
    "publicShareWait": "Please wait",
    "publicShareNeedPassword": "This link requires a password to download",
    "publicSharePasswordPh": "Share password",
    "publicShareDownload": "Download",
    "publicShareDownloadAgain": "Download again",
    "publicShareDone": "Download started",
    "publicShareDoneHint": "Check your browser downloads; tap again if nothing appears",
    "publicShareNotFound": "Share not found or expired",
    "publicShareDenied": "Cannot access this share",
    "publicShareBadPassword": "Wrong password",
    "publicShareMissing": "Invalid share link",
    "publicShareFailed": "Download failed ({{status}})",
    "publicShareFailedGeneric": "Download failed",
    "publicShareDefaultName": "download",
    "publicSharePanelLogin": "Panel sign-in",
    "publicShareLang": "Language",
    "publicShareProgress": "{{loaded}} / {{total}} ({{pct}}%)",
    "publicShareProgressIndeterminate": "Received {{loaded}}…",
    "publicShareCancel": "Cancel",
    "publicShareCancelled": "Download cancelled",
    "publicSharePoweredBy": "Powered by {{company}}",
    "publicSharePoweredPrefix": "Powered by ",
    "publicSharePoweredSuffix": "",
    "publicShareHasAccount": "Have an account? Sign in",
    "password": "Password",
    "editorLines": "{{count}} lines",
    "editorLargeHint": "Large file — editing may feel slow. Prefer download for multi‑MB files (server cap ~2 MB).",
    "editorLnCol": "Ln {{line}}, Col {{col}}",
    "editorSpaces": "Spaces: {{n}}",
    "copyLink": "Copy link",
    "versionsTitleShort": "Version history",
    "versionsCount": "{{count}} / {{max}}",
    "versionN": "v{{n}}",
    "versionLatest": "Latest",
    "shareModeLabel": "Download method",
    "shareModeDirect": "Direct download",
    "shareModeBt": "BitTorrent (WebTorrent)",
    "shareModeBoth": "Direct + BitTorrent",
    "shareModeHint": "BT needs a running tracker (Files → BT Tracker). Magnet links can be used by anyone who has the link.",
    "shareModeBtBlocked": "Tracker is not running — start it before creating BT shares, or choose Direct only.",
    "shareMagnet": "Magnet link",
    "shareTorrentFile": "Download .torrent",
    "shareSeedStatus": "Seeding status",
    "shareBtStats": "BitTorrent status",
    "btSeeds": "Seeds",
    "btLeechers": "Leechers",
    "btPeers": "Peers",
    "btUploadSpeed": "Upload speed",
    "btDownloadSpeed": "Download speed",
    "btUploaded": "Uploaded",
    "btDownloaded": "Downloaded",
    "btRatio": "Ratio",
    "btUpdatedAt": "Updated",
    "btServerStats": "Server seeder",
    "btClientStats": "Your client",
    "btSeeding": "Seeding",
    "btPending": "Seeding pending",
    "btStopped": "Seed stopped",
    "btError": "Seed error",
    "publicShareMethod": "How do you want to download?",
    "publicShareDirect": "Direct download",
    "publicShareBt": "BitTorrent",
    "openBtTracker": "Open BT Tracker",
    "publicShareBtInBrowser": "Download in browser (WebTorrent)",
    "publicShareBtProgress": "Downloaded {{pct}}% · {{peers}} peers · ↓ {{down}} · ↑ {{up}}",
    "publicShareBtStarting": "Connecting to peers…",
    "publicShareBtFailed": "WebTorrent failed: {{detail}}",
    "publicShareBtNeedMagnet": "No magnet URI for this share",
    "publicShareBtUnsupported": "This browser cannot run WebTorrent; use magnet or .torrent instead",
    "btNone": "—",
    "uploadStatusSkipped": "Skipped",
    "uploadStatusCancelled": "Cancelled",
    "conflict": {
      "titleFile": "An item named “{{name}}” already exists",
      "titleFolder": "A folder named “{{name}}” already exists",
      "descFile": "Choose what to do. Nothing is overwritten until you pick Replace.",
      "descFolder": "Choose what to do. Merge keeps the existing folder and continues with its contents.",
      "incoming": "Incoming",
      "existing": "Already here",
      "kindFile": "File",
      "kindFolder": "Folder",
      "skip": "Skip",
      "skipHint": "Do not add this item",
      "keepBoth": "Keep both",
      "keepBothHint": "Save incoming as {{name}}",
      "replace": "Replace",
      "replaceHint": "Overwrite the existing file. A version snapshot is kept when possible.",
      "replaceFolderHint": "Overwrite files with the same names inside this folder. Other files stay.",
      "merge": "Merge",
      "mergeHint": "Keep the existing folder and add incoming files into it",
      "applyAll": "Apply to all remaining conflicts",
      "applyAllHint": "Use this action for the rest of this drop or transfer",
      "cancelRest": "Cancel remaining",
      "progress": "{{current}} of {{total}}",
      "typeMismatch": "A {{destKind}} named “{{name}}” is already here. Incoming is a {{incomingKind}}.",
      "skipped": "Skipped",
      "cancelled": "Cancelled"
    },
    "webdavReissueUnchanged": "Token id did not change after re-issue — the write may not have persisted. Try again.",
    "webdavDisableFailed": "WebDAV is still enabled after disable — the write may not have persisted. Try again."
  },
  "firewall": {
    "profiles": {
      "web": {
        "label": "Web host",
        "short": "SSH · 80 · 443"
      },
      "mail": {
        "label": "Web + mail",
        "short": "Also 25/465/587/993"
      },
      "ftps": {
        "label": "Web + FTPS",
        "short": "21 + PASV 30000–30100"
      }
    },
    "appliedProfile": "Applied profile: {{label}}",
    "backToProtection": "Protection",
    "statRules": "Rules",
    "statDenyIps": "Permanent deny IPs",
    "statAllow": "Allow",
    "statDeny": "Deny",
    "statDefaultIn": "Default incoming",
    "defaultNotApplied": "n/a (UFW off)",
    "ufwOffHint": "Default incoming is not applied while UFW is off",
    "executeOn": "On",
    "executeOff": "Off",
    "ufwDisabled": "UFW disabled",
    "ufwEnabled": "UFW enabled",
    "disableUfw": "Disable UFW",
    "enableUfw": "Enable UFW",
    "notInstalled": "UFW is not installed",
    "toolHintPrefix": "Underlying tools:",
    "toolHintBody": "UFW = ports / permanent rules · for attack response and auto-ban use",
    "toolHintfail2ban": "fail2ban = temporary log-based bans",
    "toolHintFail2ban": "fail2ban = temporary log-based bans",
    "executeOffHint": "System changes off — status is readable;",
    "tabs": {
      "rules": "Rules",
      "ports": "Open ports",
      "deny": "Permanent deny IP",
      "profiles": "Profiles",
      "about": "About",
      "services": "Services"
    },
    "currentRules": "Current rules",
    "rulesSourceHint": "UFW numbered rules (ufw status numbered)",
    "colAction": "Action",
    "colTo": "To",
    "colFrom": "From",
    "deleteShort": "Delete",
    "denyBadge": "DENY",
    "emptyRulesTitle": "No rules or no permission to read",
    "emptyRulesInstalled": "UFW inactive or needs root to read",
    "emptyRulesNotInstalled": "Install UFW then refresh",
    "allowPortTitle": "Allow port",
    "protocol": "Protocol",
    "protoBoth": "Both",
    "protoBothLabel": "TCP+UDP",
    "port": "Port",
    "portHint": "Pick a common port, or custom below",
    "portHintYsk": "All YSK service ports (Panel, Web, SSH, mail, FTP, DNS, DB, Redis);",
    "privatePortWarn": "{{service}} should usually stay private; public allow is risky. Prefer a source IP/CIDR.",
    "privatePortWarnWithFrom": "{{service}} will only allow the given source; double-check the IP/CIDR.",
    "allowFrom": "Source IP/CIDR (optional)",
    "allowFromHint": "Empty = anywhere; set an IP or CIDR to allow only that source on this port",
    "allowFromPlaceholder": "e.g. 203.0.113.10 or 10.0.0.0/8",
    "customPort": "Custom port (e.g. 8080 or 30000:30100)",
    "allowedPort": "Allowed {{proto}}/{{port}}",
    "allowedPortFrom": "Allowed {{proto}}/{{port}} from {{from}}",
    "allowThisPort": "Allow this port",
    "allowPortHint": "Keep 22/80/443 for a web host;",
    "denyTitle": "Permanent deny IP",
    "denySub": "UFW DENY · different from temporary fail2ban bans",
    "denyPlaceholder": "IPv4 or IPv6 to deny",
    "deniedOk": "Permanently denied",
    "removedDeny": "DENY removed",
    "remove": "Remove",
    "noDenyRules": "No permanent deny IP rules",
    "oneClickProfiles": "One-click profiles",
    "oneClickDesc": "Write panel script and apply UFW (does not install fail2ban — use the fail2ban page)",
    "customApply": "Custom apply",
    "allowSmtp": "Allow SMTP/IMAP ports",
    "extraTcp": "Extra TCP ports",
    "extraTcpHint": "Pick a preset; or custom comma/ranges",
    "noExtra": "None extra",
    "mailGroup": "Mail set",
    "customExtraPlaceholder": "Custom: 8080,9000:9010",
    "appliedCustom": "Custom rules applied",
    "applyToSystem": "Apply to system",
    "deletedRule": "Deleted #{{n}}",
    "deleteRuleTitle": "Delete rule #{{n}}?",
    "deleteRuleDesc": "Removes that UFW rule number (needs system-change permission).",
    "servicesTitle": "Managed services",
    "servicesHint": "Desired network exposure for YSK services. Opening a service syncs these rules automatically.",
    "servicesUfwOff": "UFW is off. This list is the desired exposure, not rules the host is enforcing.",
    "servicesEmpty": "No service exposure data yet",
    "servicesEmptyDesc": "Start a managed service (web, FTPS, VPN, DB…) to populate this list.",
    "servicesManualHint": "Manual port chips are under the Ports tab — prefer managing access here so rules stay tagged (ysk-svc).",
    "portsManualHint": "Advanced manual rules. Prefer the Services tab for managed software.",
    "colService": "Service",
    "colMode": "Mode",
    "colPorts": "Ports",
    "colSync": "Status",
    "synced": "Synced",
    "syncNow": "Sync",
    "disableConfirmTitle": "Disable UFW?",
    "disableConfirmDesc": "The host firewall will stop filtering traffic. SSH and the panel can be exposed if the host is on a public network.",
    "disableConfirmConsequence": "Existing allow/deny rules stay stored but are not enforced until UFW is enabled again.",
    "desiredOnlyUfwOff": "Desired: {{mode}} · UFW off (not applied)",
    "syncNotApplied": "UFW off · not applied"
  },
  "ftp": {
    "title": "FTPS accounts",
    "accountsCount": "{{count}} account(s)",
    "accounts": "Accounts",
    "applied": "Applied",
    "pendingApply": "Pending apply",
    "sftpKeys": "SFTP keys",
    "softwareMissing": "FTPS service software is not installed",
    "ftpAccounts": "FTP accounts",
    "sftpPubkeys": "SFTP public keys",
    "homeDir": "Home directory",
    "domain": "Domain",
    "user": "User",
    "keyFingerprint": "Key fingerprint (prefix)",
    "createHint": "Create an FTP account on the Accounts tab first, then return here to register keys.",
    "pubkeyHint": "Use “+ Add public key”, choose an FTP user, and paste a full ssh-ed25519 or ssh-rsa line.",
    "sftpKeyInvalid": "Need a username and a public key that starts with ssh-.",
    "quickSelect": "Quick-select account",
    "quickSelectHint": "Click a username to fill the new-key form",
    "editAccount": "Edit FTP account",
    "createAccount": "Create FTP account",
    "accountModalDesc": "Pick domain and home from lists, or type freely. Save then Apply to write vsftpd",
    "usernameHintCreate": "Alnum, dot, underscore, hyphen; immutable after create",
    "usernameHint": "Alnum, dot, underscore, hyphen",
    "newPasswordOptional": "New password (optional)",
    "passwordKeepHint": "Empty keeps current",
    "passwordMin8": "At least 8 characters",
    "domainHint": "Site or mail domain for grouping and path hints",
    "domainPh": "Create site/mail domain first, or type temporarily",
    "homeHint": "Root after login (chroot visible scope)",
    "addPubkey": "Add SFTP public key",
    "addPubkeyDesc": "Choose an account, optional note, and paste one full public key line. Writing the file does not prove login works.",
    "pubkeyAdded": "Public key added",
    "ftpUsername": "FTP username",
    "ftpUsernameHint": "Must match a registered FTP account",
    "ftpUsernamePh": "Same as FTP account",
    "note": "Note",
    "noteHint": "Device label, e.g. laptop / office",
    "notePh": "Laptop / office host",
    "sshPubkey": "SSH public key",
    "sshPubkeyHint": "Usually from ~/.ssh/id_ed25519.pub, paste whole line",
    "deleteAccountTitle": "Delete FTP account?",
    "deleteAccountNamed": "Delete FTP account {{name}}?",
    "deleteAccountDesc": "Apply again after remove",
    "deleteKeyTitle": "Delete SFTP public key?",
    "deleteKeyDesc": "Removes from management file; system authorized_keys may need reload.",
    "serviceTitle": "vsftpd service",
    "softwareMissingService": "FTPS software is not installed",
    "lifecycle": "Lifecycle",
    "overview": "Overview",
    "network": "Network",
    "security": "Security",
    "installStart": "Install and start",
    "listenPort": "Listen port",
    "accountCount": "Accounts",
    "loginBanner": "Login banner",
    "sslDomain": "SSL domain",
    "plaintextInsecure": "Cleartext FTP (no TLS) — insecure. Enable FTPS before exposing port 21.",
    "plaintextPublicLive": "vsftpd is listening on a public address without FTPS. Credentials travel in the clear. Enable FTPS, bind to this host only, or confirm PLAINTEXT to keep this posture.",
    "bindAddress": "Listen scope",
    "bindAddressHint": "New installs bind to this host only. Public listen without FTPS needs a typed confirmation.",
    "bindLocal": "This host only",
    "bindLocalHint": "127.0.0.1 — fine without TLS for local tests",
    "bindPublic": "Public",
    "bindPublicHint": "All interfaces — enable FTPS or confirm PLAINTEXT",
    "enableFtpsAndStart": "Enable FTPS and start",
    "publicPlainNeedConfirm": "Public cleartext FTP needs a PLAINTEXT confirmation",
    "plainConfirmTitle": "Start public FTP without FTPS?",
    "plainConfirmDesc": "Port 21 will accept logins and data in the clear on the public address.",
    "plainConfirmC1": "Usernames and passwords are visible on the network.",
    "plainConfirmC2": "PASV will advertise the configured public IP.",
    "plainConfirmC3": "Host firewall and cloud security group are not opened for you.",
    "plainConfirmAction": "Start cleartext FTP",
    "pasvRange": "PASV range",
    "forceTls": "Force TLS",
    "allowWrite": "Allow write",
    "networkTitle": "Network settings",
    "networkDesc": "Listen port and PASV;",
    "listenPortHint": "Default 21; open firewall if using another port",
    "customPort": "Custom port",
    "ipStack": "IP stack",
    "ipStackHint": "Most vsftpd builds: listen and listen_ipv6 are mutually exclusive.",
    "listenConflictLive": "Live vsftpd.conf has listen={{v4}} and listen_ipv6={{v6}} — both YES will fail to start.",
    "listenConflictNeedFix": "Fix listen / listen_ipv6 first (they cannot both be YES), then apply.",
    "fixListenIpv4": "Use IPv4 only (listen=YES, listen_ipv6=NO)",
    "liveFileValue": "File now: {{value}}",
    "startBlockedFailed": "Service is failed — apply a valid config before start",
    "ftpsNeedCert": "Pick a certificate domain first",
    "ipv4Only": "IPv4 only",
    "ipv6Mapped": "IPv6 (mapped OK)",
    "bannerHint": "Welcome string clients see after connect",
    "pasvStart": "PASV start port",
    "pasvStartHint": "Passive data channel start",
    "customStart": "Custom start",
    "pasvEnd": "PASV end port",
    "pasvEndHint": "Must be ≥ start; firewall must allow the range",
    "openFirewallPage": "Open firewall page",
    "customEnd": "Custom end",
    "pasvPublicIp": "PASV public IP",
    "detectPublicIp": "Detect public IP",
    "detectPublicIpTitle": "Fill the first non-loopback IPv4 from this host",
    "pasvPublicIpHint": "NAT/cloud: set public IP; local can leave empty",
    "pasvIpRequired": "Set a public PASV IP before apply (NAT/cloud). Detect or type an address.",
    "optionalEmpty": "(optional)",
    "securityTitle": "Security settings",
    "securityDesc": "TLS, write access, chroot; Apply and restart to take effect",
    "sslCertDomain": "SSL certificate domain",
    "sslCertDomainHint": "Pick an uploaded/issued cert domain",
    "enableFtps": "Enable FTPS (SSL/TLS)",
    "enableFtpsDesc": "TLS on control channel; recommended",
    "forceTlsLogin": "Force TLS login",
    "forceTlsLoginDesc": "Reject plain FTP; clients need FTPS",
    "allowWriteDesc": "Off = download/list only",
    "chrootUsers": "Chroot users",
    "chrootUsersDesc": "Jail to home after login",
    "writableChroot": "Allow writable chroot",
    "writableChrootDesc": "Keep chroot even when home is writable (common vsftpd need)",
    "settingsSaved": "Settings saved",
    "installIncomplete": "Install could not complete",
    "ftpsReady": "FTPS ready",
    "settingsApplied": "Settings applied",
    "opsResult": "Ops result",
    "saved": "Saved",
    "accountsList": "Account list",
    "accountsListDesc": "After create, Apply to sync vsftpd. If it is not installed, use the Software tab.",
    "startService": " start.",
    "createAccountPlus": "+ Create account",
    "noFtpAccounts": "No FTP accounts yet",
    "noFtpAccountsDesc": "Create account (list top-right); set home and domain, then apply.",
    "applyHint": "Note: Apply writes management only; listening needs vsftpd active.",
    "sshdMatchNote": "; system sshd Match must be configured to take effect.",
    "addPubkeyPlus": "+ Add public key",
    "noPubkeys": "No public keys registered",
    "pickDomain": "— pick domain —",
    "currentDomain": "{{domain}} (current)",
    "pickHome": "— pick home —",
    "currentHome": "{{path}} (current)",
    "fullPath": "Full path: ",
    "emptyHomes": "If the list is empty, create a project or site first for home options.",
    "pickAccount": "— pick account —",
    "installFtpsBanner": "Use the banner above to install FTPS, then start the service.",
    "applyRestart": "Apply and restart",
    "afterInstall": "After install you can log in with FTPS accounts. Admin rights needed to install.",
    "saveSettings": "Save settings",
    "saveApplyHint": "Save updates panel only; Apply and restart writes vsftpd.conf and reloads.",
    "installAndStart": "Install & start",
    "manageAccounts": "Accounts",
    "openFirewallPorts": "Open firewall ports",
    "firewallPortsApplied": "Firewall allowed TCP {{ports}}",
    "sftpTabDesc": "Register SSH public keys for FTP accounts so clients can use SFTP key login. Pick an account, paste one key line, then save.",
    "sftpNeedAccountTitle": "No FTP accounts yet",
    "sftpNeedAccount": "Create at least one FTP account first, then register a public key for that user.",
    "sftpFilterLabel": "Account",
    "sftpFilterAll": "All accounts",
    "sftpKeyCount": "{{count}} key(s)",
    "sftpEmptyFiltered": "No keys for this account",
    "sftpEmptyFilteredDesc": "“{{user}}” has no registered SSH public keys yet.",
    "sftpRegister": "Register key",
    "sftpAddedAt": "Added {{time}}",
    "sftpTechSummary": "Technical details (advanced)",
    "sftpTechNote": "Keys are written under the managed path",
    "filterProject": "Showing FTP accounts for this project",
    "clearProjectFilter": "Show all accounts",
    "vsftpdFailedHint": "vsftpd failed. Open the Service tab (listen and listen_ipv6 cannot both be YES).",
    "vsftpdFailedGeneric": "vsftpd failed. Open the Service tab for live settings and journal.",
    "stateFailed": "Failed to start",
    "tabService": "Service"
  },
  "geo": {
    "continents": {
      "AS": "Asia",
      "EU": "Europe",
      "NA": "North America",
      "SA": "South America",
      "AF": "Africa",
      "OC": "Oceania",
      "AN": "Antarctica"
    },
    "countries": {
      "CN": "China",
      "HK": "Hong Kong",
      "MO": "Macao",
      "TW": "Taiwan",
      "JP": "Japan",
      "KR": "South Korea",
      "KP": "North Korea",
      "SG": "Singapore",
      "MY": "Malaysia",
      "TH": "Thailand",
      "VN": "Vietnam",
      "PH": "Philippines",
      "ID": "Indonesia",
      "IN": "India",
      "AU": "Australia",
      "NZ": "New Zealand",
      "US": "United States",
      "CA": "Canada",
      "MX": "Mexico",
      "BR": "Brazil",
      "AR": "Argentina",
      "GB": "United Kingdom",
      "IE": "Ireland",
      "DE": "Germany",
      "FR": "France",
      "NL": "Netherlands",
      "BE": "Belgium",
      "CH": "Switzerland",
      "AT": "Austria",
      "SE": "Sweden",
      "NO": "Norway",
      "DK": "Denmark",
      "FI": "Finland",
      "PL": "Poland",
      "CZ": "Czechia",
      "ES": "Spain",
      "PT": "Portugal",
      "IT": "Italy",
      "RU": "Russia",
      "UA": "Ukraine",
      "TR": "Turkey",
      "IL": "Israel",
      "AE": "UAE",
      "SA": "Saudi Arabia",
      "EG": "Egypt",
      "ZA": "South Africa",
      "NG": "Nigeria",
      "PK": "Pakistan",
      "BD": "Bangladesh",
      "IR": "Iran",
      "IQ": "Iraq",
      "RO": "Romania",
      "BG": "Bulgaria",
      "HU": "Hungary",
      "GR": "Greece",
      "LT": "Lithuania",
      "LV": "Latvia",
      "EE": "Estonia",
      "BY": "Belarus",
      "KZ": "Kazakhstan",
      "UZ": "Uzbekistan",
      "CL": "Chile",
      "CO": "Colombia",
      "PE": "Peru",
      "VE": "Venezuela",
      "CU": "Cuba",
      "SC": "Seychelles",
      "PA": "Panama"
    },
    "regions": {
      "CN-BJ": "Beijing",
      "CN-SH": "Shanghai",
      "CN-TJ": "Tianjin",
      "CN-CQ": "Chongqing",
      "CN-GD": "Guangdong",
      "CN-ZJ": "Zhejiang",
      "CN-JS": "Jiangsu",
      "CN-SD": "Shandong",
      "CN-HN": "Henan",
      "CN-HB": "Hubei",
      "CN-HU": "Hunan",
      "CN-SC": "Sichuan",
      "CN-HE": "Hebei",
      "CN-FJ": "Fujian",
      "CN-AH": "Anhui",
      "CN-JX": "Jiangxi",
      "CN-LN": "Liaoning",
      "CN-JL": "Jilin",
      "CN-HL": "Heilongjiang",
      "CN-SX": "Shanxi",
      "CN-SN": "Shaanxi",
      "CN-GS": "Gansu",
      "CN-QH": "Qinghai",
      "CN-HA": "Hainan",
      "CN-YN": "Yunnan",
      "CN-GZ": "Guizhou",
      "CN-GX": "Guangxi",
      "CN-NX": "Ningxia",
      "CN-XJ": "Xinjiang",
      "CN-XZ": "Tibet",
      "CN-NM": "Inner Mongolia",
      "TW-TPE": "Taipei",
      "TW-TXG": "Taichung",
      "TW-KHH": "Kaohsiung",
      "HK-HK": "Hong Kong",
      "MO-MO": "Macao",
      "US-CA": "CA",
      "US-NY": "NY",
      "US-TX": "TX",
      "US-FL": "FL",
      "US-WA": "WA",
      "US-IL": "IL",
      "US-VA": "VA",
      "US-OR": "OR",
      "US-GA": "GA",
      "US-NJ": "NJ",
      "US-MA": "MA",
      "US-OH": "OH",
      "US-PA": "PA",
      "US-AZ": "AZ",
      "US-CO": "CO",
      "US-NC": "NC",
      "US-MI": "MI",
      "US-NV": "NV",
      "JP-13": "Tokyo",
      "JP-27": "Osaka",
      "JP-14": "Kanagawa",
      "JP-23": "Aichi",
      "KR-11": "Seoul",
      "KR-26": "Busan",
      "SG-01": "SG",
      "AU-NSW": "NSW",
      "AU-VIC": "VIC",
      "GB-ENG": "ENG",
      "DE-BE": "BE",
      "DE-BY": "BY",
      "RU-MOW": "MOW",
      "RU-SPE": "SPE"
    }
  },
  "hostBrowse": {
    "tabBrowse": "Browse",
    "subtitle": "Browse the internet or LAN via this host. Targets never see your desktop browser identity.",
    "modeInternet": "Internet",
    "modeIntranet": "Intranet",
    "modeHint": "Internet blocks private IPs; Intranet allows LAN targets. Both block cloud metadata.",
    "urlPlaceholder": "https://example.com or 192.168.1.1",
    "go": "Go",
    "back": "Back",
    "forward": "Forward",
    "reload": "Reload",
    "stop": "Stop",
    "clearCookies": "Clear cookies",
    "clearCookiesConfirm": "This clears cookies stored on the host for this browse session. Sites that were signed in will need to be signed in again.",
    "closeSession": "Close session",
    "copyUrl": "Copy URL",
    "newSession": "New session",
    "privacyOn": "Privacy on",
    "viaHost": "via host",
    "emptyTitle": "Host-mediated browse",
    "emptyBody": "Enter a URL. DNS, TLS, and egress use this server — not your browser. Cookies stay in a server-side jar.",
    "needUrl": "Enter a URL above to start a session.",
    "ssrfBlocked": "Blocked by security policy (SSRF / mode)",
    "loadFailed": "Fetch failed on host",
    "sessionReady": "Session ready",
    "noSession": "No session",
    "statusLine": "{{status}} · {{ms}}ms · {{type}} · via host",
    "cookies": "Cookies",
    "latency": "Latency",
    "locked": "HTTPS",
    "insecure": "HTTP",
    "loading": "Loading…",
    "modeSwitchHint": "Switching mode opens a new session and clears cookies.",
    "copied": "URL copied",
    "downloadHint": "Non-HTML response — open content frame or navigate again.",
    "engineLabel": "Engine",
    "engineProxy": "Proxy",
    "engineBrowser": "Real browser",
    "engineSwitchHint": "Switching engine opens a new session.",
    "needChrome": "Real browser needs system Chrome/Chromium (or set YSK_HOST_BROWSE_CHROME). Using proxy otherwise.",
    "engineBrowserNeedChrome": "Real browser (Chrome not installed)",
    "egressHint": "The target site sees this server’s outbound address ({{host}}), not your laptop. Cookies stay in the server session jar.",
    "needChromeFallback": "Chrome unavailable — switched to proxy engine.",
    "liveError": "Live stream failed",
    "liveWaiting": "Connecting host browser…",
    "tabSettings": "Settings",
    "softwareNeeded": "Chromium / Chrome required for real browser engine",
    "softwareHint": "One-click installs distro Chromium via apt. Google Chrome is also detected if already present. Needs superuser and system-change permission.",
    "closeNoSession": "No session yet",
    "goInstallChrome": "Open Software tab",
    "settingsIntro": "These panel settings override process environment variables for Host Browse.",
    "settingsEngine": "Default engine",
    "engineAuto": "Auto",
    "settingsChromePath": "Chrome / Chromium path",
    "settingsChromePathHint": "Empty = auto-detect. Example: /usr/bin/google-chrome",
    "settingsLoopback": "Allow loopback in intranet mode (127.0.0.1)",
    "settingsNoSandbox": "Chromium --no-sandbox (containers only)",
    "settingsSave": "Save settings",
    "settingsSaved": "Host Browse settings saved",
    "envHintsTitle": "Process env (read-only; panel settings take precedence when set)",
    "stream": {
      "label": "Quality",
      "smooth": "Smooth",
      "balanced": "Balanced",
      "sharp": "Sharp"
    },
    "zoom": {
      "label": "Zoom",
      "fit": "Fit",
      "fill": "Fill"
    },
    "retryNav": "Retry navigation",
    "retryLive": "Reconnect stream",
    "tryProxy": "Switch to proxy engine",
    "err": {
      "LIVE_NO_FRAME": "Stream timed out: no frames received. Reconnect or retry navigation.",
      "LIVE_WS_FAIL": "Live connection failed. Reconnect the stream.",
      "SSRF_BLOCKED": "Target blocked by security policy.",
      "BOT_CHALLENGE": "Target may require human verification or block automation. Complete the challenge on-screen if shown.",
      "TIMEOUT": "Load timed out. Please retry.",
      "DNS_FAIL": "DNS resolution failed.",
      "TLS_FAIL": "TLS/SSL connection failed.",
      "NAV_FAIL": "Navigation failed.",
      "CHROME_LAUNCH": "Could not start host Chromium. Check install and no-sandbox settings.",
      "SESSION_GONE": "Session expired. Navigate again.",
      "NEED_CHROME": "Chrome/Chromium is required."
    },
    "home": "Home",
    "bookmark": "Bookmark",
    "bookmarkAdd": "Add or remove bookmark",
    "bookmarkList": "Bookmark list",
    "bookmarks": "Bookmarks",
    "history": "History",
    "bookmarkToggled": "Bookmark updated",
    "newTab": "New tab",
    "fullscreen": "Fullscreen",
    "mediaNote": "Real browser: video is streamed into the panel. Enable audio bridge in Settings to hear page audio (requires user gesture).",
    "isolationNote": "Real browser creates an ephemeral Linux user for Chrome; leaving the page or idle timeout destroys that user.",
    "resumeHint": "Resume previous session ({{count}} tabs)",
    "resumeHintDetail": "Resume previous session ({{count}} tabs) · {{url}} · {{when}}",
    "resumeHintOwned": "Resume last browse for {{user}} ({{count}} tabs) · {{url}} · {{when}}",
    "clearSessionData": "Clear session data",
    "clearSessionConfirm": "This discards the resume snapshot for the previous browse session. You cannot restore those tabs afterwards.",
    "resume": "Resume",
    "resumeDismiss": "Dismiss",
    "resumeDone": "Session resumed",
    "settingsSafety": "Navigation safety",
    "settingsSafetyHint": "Strict blocks more risky hosts; Relaxed allows broader intranet targets. Does not disable SSRF protections for cloud metadata.",
    "safetyStrict": "Strict",
    "safetyStandard": "Standard",
    "safetyRelaxed": "Relaxed",
    "settingsBlockHosts": "Blocked host suffixes",
    "settingsBlockHostsHint": "One hostname or suffix per line (e.g. malware.test). Exact and suffix matches are blocked.",
    "settingsAllowDangerousDownloads": "Allow high-risk downloads (exe / scripts)",
    "settingsAudioBridge": "Bridge page audio to the panel",
    "settingsAudioBridgeHint": "Streams host Chrome audio into this browser. Some sites need a click to unlock playback.",
    "downloads": "Downloads",
    "downloadsEmpty": "No downloads in this session",
    "downloadReady": "Ready",
    "downloadBlocked": "Blocked",
    "downloadPending": "Pending",
    "downloadFailed": "Failed",
    "downloadSave": "Save",
    "audioUnlock": "Enable sound",
    "audioUnlockHint": "Click to unlock audio playback in this tab",
    "audioUnlocked": "Audio unlocked",
    "audioPlaying": "Audio playing",
    "audioNeedsUnlock": "Audio needs unlock",
    "audioBridgedHint": "Page audio is bridged from the host browser",
    "audioNotBridged": "Audio off",
    "audioNotBridgedHint": "Turn on audio bridge in Settings to hear the page",
    "mediaPolicyTitle": "Media in real browser",
    "mediaVideoLabel": "Video",
    "mediaVideoDesc": "Rendered on the host and streamed as frames into the panel.",
    "mediaAudioLabel": "Audio",
    "mediaAudioDesc": "Optional bridge from host Chrome; may require unlock click.",
    "mediaPolicyLabel": "Policy",
    "mediaPolicyDesc": "Downloads and autoplay follow the safety and download settings above.",
    "frameBlocked": "The page could not be shown in the panel frame.",
    "historyEmpty": "No history in this session.",
    "bookmarksEmpty": "No bookmarks yet.",
    "closeSessionHint": "Clears cookies for this browse session. Bookmarks stay.",
    "envUnset": "not set",
    "envPanelValue": "panel: {{value}}",
    "envColVar": "Variable",
    "envColHost": "Host process",
    "envColPanel": "Panel setting",
    "envColEffective": "Effective",
    "settingsNoSandboxWarn": "Disables Chromium sandbox. Use only inside a trusted container. Applies on next real-browser session.",
    "settingsDangerDlWarn": "Allows executable and script downloads through the host browser. Confirm you need this.",
    "settingsDangerConfirmTitle": "Enable a high-risk browse setting?"
  },
  "legal": {
    "hubTitle": "Legal",
    "hubSub": "Terms of Use, Privacy Policy, and Disclaimer for YSK Server",
    "terms": "Terms of Use",
    "privacy": "Privacy Policy",
    "disclaimer": "Disclaimer",
    "updated": "Last updated {{date}}",
    "englishPrevails": "Official languages: English and Hong Kong written Chinese. If they differ, the English version controls.",
    "notOfficialLocale": "Your display language is not an official legal language. The binding text below is English unless you switch it.",
    "officialLang": "Official text",
    "officialEn": "English",
    "officialZh": "繁體中文（香港）",
    "signIn": "Sign in",
    "mitNote": "Source code is licensed under MIT. These pages are additional conditions of use.",
    "backToIndex": "All legal documents"
  },
  "listToolbar": {
    "searchPlaceholder": "Search…",
    "searchAria": "Search list",
    "clearSearch": "Clear search",
    "clearAll": "Clear filters",
    "resultCount": "{{count}} results",
    "showingOf": "Showing {{shown}} of {{total}}",
    "activeFilters": "{{count}} filters active",
    "noResults": "No matches",
    "noResultsHint": "Try another keyword or clear filters.",
    "searching": "Searching…",
    "emptyChip": "No items in this filter"
  },
  "logViewer": {
    "banIpTitle": "Ban {{ip}} in Protection",
    "filter": "Filter",
    "filterPh": "Keyword",
    "levels": "Levels",
    "wrap": "Wrap",
    "follow": "Follow",
    "download": "Download",
    "nextError": "Next error",
    "prevError": "Previous error",
    "lines": "{{n}} lines",
    "shown": "{{n}} shown",
    "errors": "Err {{n}}",
    "warnings": "Warn {{n}}",
    "all": "All",
    "empty": "No log lines"
  },
  "login": {
    "title": "Sign in to YSK Server",
    "subtitle": "Server console",
    "username": "Username",
    "password": "Password",
    "submit": "Sign in",
    "failed": "Sign-in failed. Check username or password.",
    "footer": "A product of YSK Limited",
    "totpRequired": "2FA is enabled for this account. Enter the 6-digit code.",
    "totpLabel": "Authentication code",
    "totpHint": "6-digit code from your authenticator app",
    "submitting": "Signing in…",
    "sessionExpired": "Session expired; sign in again",
    "newPassword": "New password",
    "newPasswordAgain": "Confirm new password",
    "changePassword": "Change password",
    "passwordMismatch": "The two passwords do not match",
    "passwordChanged": "Password updated"
  },
  "logs": {
    "catSystem": "System files",
    "catMail": "Mail",
    "catSecurity": "Security",
    "catApp": "App",
    "catOther": "Other",
    "journalService": "Journal unit",
    "unavailable": "Unavailable",
    "compressed": " · compressed",
    "noLogFileYet": "(no log file yet)",
    "afterDeploy": "Appears after deploy",
    "logsLoaded": "Logs loaded",
    "sseFailed": "SSE failed, falling back to poll",
    "sseInterrupted": "SSE interrupted",
    "settingsSaved": "Settings saved",
    "exportedJsonl": "Exported JSONL",
    "exported": "Exported",
    "bookmarkSaved": "Bookmark saved",
    "title": "Log center",
    "fullAccess": "Full access",
    "nonRoot": "Non-root",
    "noExecute": "No EXECUTE",
    "error": "Error",
    "projectLog": "Project logs",
    "filesCount": "{{count}} file(s)",
    "tabExplore": "Explore",
    "tabMaint": "Maintenance",
    "tabSettings": "Settings",
    "tabAbout": "About",
    "sources": "Log sources",
    "filterPlaceholder": "Filter unit / file…",
    "filterSources": "Filter sources",
    "noProjectLogs": "No project logs — appear after deploy",
    "noMatchSources": "No matching sources",
    "projectPrefix": "Project · ",
    "timeRange": "Time range",
    "unlimited": "Unlimited",
    "priority": "Priority",
    "all": "All",
    "keywordIp": "Keyword / IP…",
    "custom": "Custom",
    "copied": "Copied",
    "truncated": " · truncated",
    "following": " · following",
    "followingSse": " · following (SSE)",
    "loadingSources": "Loading sources…",
    "pickSource": "Pick a source on the left, or a shortcut · then Query",
    "noRowsInWindow": "No records in this time window",
    "showInactiveUnits": "Show inactive units",
    "sseNeedFollow": "Turn on Follow first — SSE is only for live tail",
    "maintOverview": "Maintenance overview",
    "executable": "Executable",
    "restricted": "Restricted",
    "needRootExecute": "Needs root+EXECUTE",
    "retention": "Retention",
    "retentionHint": "e.g. 7d · 14d · 30d",
    "defaultLines": "Default lines",
    "followInterval": "Follow interval",
    "maxBytes": "Max bytes",
    "maskSecrets": "Mask secrets",
    "defaultVacuumDays": "Default vacuum days",
    "d7": "7 days",
    "d14": "14 days",
    "d30": "30 days",
    "d90": "90 days",
    "journalAlerts": "Journal alerts",
    "autoVacuum": "Auto vacuum",
    "deleted": "Deleted",
    "bookmarkDeleted": "Bookmark deleted",
    "opsResult": "Ops result",
    "saveBookmark": "Save bookmark",
    "bookmarkNamePrompt": "Name for current query",
    "query": "Query",
    "follow": "Follow",
    "export": "Export",
    "vacuum": "Vacuum",
    "loadFailed": "Failed to load",
    "projectLogsLink": "Project → Logs",
    "projectLogsDesc": " — per-site shortcut + deep link",
    "queryFollow": "Query and follow",
    "queryFollowDesc": "Default lines, follow interval, response cap on Explore",
    "retentionAlerts": "Retention and alerts",
    "retentionAlertsDesc": "vacuum defaults, journal disk alerts, auto-clean windows",
    "dailyNeedRoot": "Daily (needs root + EXECUTE)",
    "customAllow": "Custom allow paths",
    "customAllowDesc": "Only /var/log or /run/log · reject .ssh, keys, /etc",
    "pathsCount": "{{n}} path(s)",
    "noCustomPaths": "No custom paths yet",
    "bookmarks": "Bookmarks",
    "bookmarksDesc": "Common Explore filters; open switches to Explore and applies source",
    "noBookmarks": "No bookmarks — query on Explore then Save bookmark",
    "settingsWriteNote": "Settings write to panel DB; auto vacuum checks window every 15 minutes.",
    "saveSettings": "Save settings",
    "vacuumDaysQ": "Vacuum time {{days}}?",
    "vacuumSizeQ": "Vacuum size 500M?",
    "vacuumDesc": "journalctl vacuum deletes old logs permanently.",
    "vacuumRequested": "Vacuum requested",
    "vacuumSizeRequested": "Vacuum size requested",
    "scLogs": "Observe journal / files / projects",
    "scProtection": "Incident response, auto ban (click IP)",
    "shortcuts": "Shortcuts",
    "projectsOnly": "Projects only",
    "filesTitle": "{{n}} file(s)",
    "bookmarksLabel": "Bookmarks",
    "filter": "Filter",
    "followSec": "Follow {{sec}}s",
    "wrap": "Wrap",
    "bookmark": "Bookmark",
    "standby": "Idle",
    "partialFail": "Partial / failed",
    "lines": "{{n}} lines",
    "followingSseDyn": " · following{{sse}}",
    "ipBan": "IP → ban",
    "vacuumNote": "Reclaims systemd-journald disk. Without execute permission the action is blocked — it is not treated as success.",
    "vacuumTime": "Clean by retention",
    "vacuumNeedRetention": "Enter a retention window first (for example 14d)",
    "vacuumNeedConfirm": "Needs confirmation — deletes old journal logs",
    "vacuumSizeNeedConfirm": "Needs confirmation — caps journal disk use",
    "vacuumHint": "Keep ≥7 days recommended; re-probe disk after.",
    "logrotateStatus": "System logrotate status (read-only probe)",
    "logrotateMissing": "No status file or unreadable — check logrotate package in services matrix",
    "relatedOps": "Related ops",
    "relatedOpsDesc": "Log observation vs incident response",
    "scLogsLine": "Observe journal / files / projects",
    "scProtLine": "Incident response, auto ban (click IP)",
    "journalVacuumTitle": "Clean journald disk",
    "journalSection": "Journal",
    "sseLabel": "SSE",
    "logrotateLabel": "logrotate",
    "srcNginx": "nginx",
    "srcSsh": "ssh",
    "srcfail2ban": "fail2ban",
    "srcFail2ban": "fail2ban",
    "srcAuthLog": "auth.log",
    "srcNginxError": "nginx error",
    "srcLetsEncrypt": "letsencrypt",
    "groupJournal": "Journal",
    "groupVarLog": "/var/log",
    "prioErr": "err+",
    "prioWarn": "warn+",
    "prioInfo": "info+",
    "vacuumSize": "Limit to 500 MB",
    "logrotateNoStatus": "No logrotate status file yet (normal if it has never run).",
    "autoVacuumOff": "Automatic clean is off. Time is unused until you enable it.",
    "aboutAllowlist": "Explore can only read allowlisted journal units and /var/log paths. Arbitrary host paths are not offered.",
    "aboutCustomPath": "Add a custom path on Settings (only /var/log or /run/log). Then open it from Explore.",
    "vacuumSizeAlreadyBelow": "Current usage already below cap, this will no-op",
    "vacuumSizeNoopDesc": "Journal is already under 500 MB. This still runs vacuum --size=500M and typically deletes nothing.",
    "journalDiskHint": "Current systemd-journald usage (active journal). Rotated files under /var/log are not included.",
    "varLogDiskHint": "Estimated du of /var/log, including rotated files. Approximate.",
    "queryFirst": "Query first",
    "errorsWindowHint": "Recent errors from the last overview probe (not live-updating when you switch tabs)",
    "sourceCount": "{{shown}} shown",
    "sourceUnavailable": "This source has not produced a log yet",
    "sourceNoLog": "No log yet",
    "projectSourcesTitle": "{{n}} source(s) (files + journal)",
    "logrotatePath": "Path",
    "logrotateLast": "Last rotated",
    "exportJsonl": "JSONL export",
    "sseLive": " (live stream)",
    "logrotateExpand": "Show {{n}} more",
    "logrotateCollapse": "Show fewer",
    "logrotateVersion": "Status version {{v}}"
  },
  "metrics": {
    "alert": {
      "memory_high": "Memory high",
      "load_high": "Load high",
      "disk_high": "Disk high"
    },
    "loadFailed": "Failed to load metrics",
    "projectUsageFailed": "Failed to load project usage",
    "procListFailed": "Process list failed",
    "streamEnded": "Stream ended ({{reason}})",
    "streamOpenFailed": "Could not open stream",
    "signalFailed": "Signal failed",
    "detailFailed": "Could not load details",
    "alertCount": "{{count}} alert(s)",
    "attention": "Needs attention",
    "normal": "OK",
    "disk": "Disk",
    "alerts": "Alerts",
    "auto5s": "Auto 5s",
    "hostSettings": "Host settings",
    "loading": "Loading metrics…",
    "tabs": {
      "overview": "Overview",
      "live": "Live processes",
      "disk": "Disk",
      "projectUsage": "Project usage",
      "alerts": "Alerts"
    },
    "load": "Load",
    "load1m": "Load 1m",
    "uptime": "Uptime",
    "filterCpu5": "≥5% CPU",
    "filterMem5": "≥5% memory",
    "signalHint": "Select a process, then send TERM or KILL.",
    "signalFromRow": "Select this process for TERM / KILL",
    "selectForSignal": "Select",
    "forceKillTitleNamed": "KILL PID {{pid}} ({{cmd}})?",
    "sendSigTitleNamed": "Send TERM to PID {{pid}} ({{cmd}})?",
    "min1": "1m",
    "min5": "5m",
    "min15": "15m",
    "loadHint": "Relative to {{cpus}} CPUs; above 1.0× may queue.",
    "memory": "Memory",
    "total": "Total",
    "available": "Available",
    "mainDisk": "Root disk",
    "path": "Path",
    "diskReadFail": "Could not read disk",
    "viewAllMounts": "View all {{count}} mounts →",
    "nAlerts": "{{count}} alerts",
    "details": "Details",
    "noThresholdAlerts": "No memory / load / disk threshold alerts",
    "projectDisk": "Project disk (real du)",
    "viewAllProjectUsage": "View all project usage →",
    "loadProjectDisk": "Load project disk usage (real du) →",
    "followSse": "Follow (SSE)",
    "interval": "Interval",
    "sort": "Sort",
    "rows": "Rows",
    "onceQuery": "One-shot query",
    "procSearchPh": "Search PID / USER / COMMAND",
    "procSearchAria": "Search processes",
    "filterAll": "All",
    "filterMine": "Non-system",
    "selectedN": "{{count}} selected",
    "showOf": " · showing {{shown}}/{{total}}",
    "topLoading": "Loading top summary… (/proc/stat dual sample)",
    "topAria": "top summary",
    "perCore": "Per-core",
    "noPerCore": "No per-core data",
    "uptimeDays": "{{d}} days, {{h}}:{{m}}",
    "used": "Used",
    "free": "Free",
    "signal": "Signal",
    "kill": "Kill",
    "send": "Send",
    "procDetail": "Process detail",
    "refreshProc": "Refresh processes",
    "noProcs": "No processes",
    "noProcsFilter": "No processes match filters",
    "mounts": "Mounts",
    "fs": "Filesystem",
    "mount": "Mount",
    "size": "Size",
    "usage": "Usage",
    "project": "Project",
    "quota": "Quota",
    "ratio": "Share",
    "unlimited": "Unlimited",
    "noProjects": "No projects yet",
    "noProjectsDesc": "Create a project to see real home usage here",
    "usageNote": "Usage from local du (not estimated). Quota is a control-plane soft limit; hard setquota needs apply-to-host.",
    "thresholdAlerts": "Threshold alerts",
    "alertsBuiltinOnly": "Built-in CPU / memory / disk thresholds only. No email, webhook, or Slack channel.",
    "lastEvaluated": "Last checked",
    "alertsOkTitle": "All clear",
    "alertsOkDesc": "No memory / load / disk threshold alerts.",
    "cpu": "CPU",
    "command": "Command",
    "user": "User",
    "clearSelection": "Clear selection",
    "batchSignal": "Batch signal",
    "liveHint": "Live process list (SSE or poll). Signals need root + YSK_EXECUTE.",
    "signalTo": "Signal {{sig}} → PID {{pid}}",
    "procAlive": "Process still alive (kill -0 ok)",
    "procGone": "Process ended",
    "procTable": "Processes ({{count}}{{more}})",
    "procTableDesc": "ps list · select for TERM/KILL (needs YSK_EXECUTE)",
    "selectAllAria": "Select all filtered",
    "selectPidAria": "Select PID {{pid}}",
    "controlPlane": "Control plane",
    "controlPlaneNoSignal": "The control-plane process cannot be signalled",
    "protectedPid": "PID 1 / init / systemd cannot be signalled from the panel",
    "sigTermTitle": "Send SIGTERM (ask process to exit)",
    "sigKillTitle": "Send SIGKILL (force kill — cannot be caught)",
    "batchTerm": "TERM",
    "batchKill": "KILL",
    "rawTopLabel": "Raw top (untranslated)",
    "followSseLabel": "Follow (live stream)",
    "alertsReadOnly": "Built-in CPU / memory / disk thresholds only. No email, webhook, or Slack channel.",
    "alertsGoNotifications": "Open notification centre",
    "lastCheck": "Last check",
    "rawTopHint": "Untranslated top(1) output",
    "detailShort": "Info",
    "procUnavailable": "Could not get processes",
    "noProcData": "No process data yet",
    "noProcFilter": "No processes match filters",
    "clickOnceOrFollow": "Run one-shot query or enable follow",
    "liveFootnote": "Like SSH top: /proc/stat dual sample for %Cpu (per-core = top “1”), Mem/Swap, Tasks; process table from ps. Not an interactive PTY. Kill needs YSK_EXECUTE; PID 1 and control plane are protected by default.",
    "forceKillTitle": "Force kill PID {{pid}} (SIGKILL)",
    "sendSigTitle": "Send SIG{{sig}} to PID {{pid}}",
    "forceKillDesc": "Cannot be caught; may lose data. Command: {{cmd}}",
    "termDesc": "Process may clean up and exit. Command: {{cmd}}",
    "forceKillBtn": "Force KILL",
    "sendTermBtn": "Send TERM",
    "procPidTitle": "Process PID {{pid}}",
    "readingProc": "Reading /proc…",
    "applyRenice": "Apply renice",
    "reniceHint": "-20 highest · 19 lowest (needs EXECUTE)",
    "noData": "No data",
    "shareOfMeasured": "{{pct}}% of measured",
    "mountsTitle": "Disk mounts ({{count}})",
    "mountsDesc": "Real disk usage (temporary filesystems filtered)",
    "noMounts": "No mount list",
    "noMountsDesc": "df unavailable or filtered. Root disk still on Overview.",
    "seeProjectUsage": "Project home usage is on the Project usage tab (real du · {{size}})",
    "measuringDu": "Measuring project homes (du)…",
    "projectUsageTitle": "Project disk usage ({{count}})",
    "projectUsageDesc": "Real du · total {{total}} · {{at}}",
    "projectUsageDescEmpty": "Run du on each project home_dir",
    "remeasure": "Re-measure",
    "usageNoteFull": "Usage from local du (not estimated). Quota is a control-plane soft limit; hard setquota needs apply-to-host.",
    "sseNeedLogin": "Not logged in; cannot open SSE",
    "sseSessionExpired": "Not logged in or session expired; cannot open SSE",
    "sseHttpError": "stream HTTP {{status}}",
    "colFilesystem": "Filesystem",
    "colMount": "Mount",
    "colSize": "Size",
    "colUsed": "Used",
    "colAvail": "Available",
    "colUsePct": "Used %",
    "colHome": "Home",
    "usageNoteLink": "Control-plane soft quota. Apply hard limits on the project Isolation tab.",
    "shareNoQuotaHint": "No quota set, so share is not a percentage. Set a quota on the project Isolation tab.",
    "setQuotaLink": "Set quota",
    "unusualHome": "Unusual path",
    "unusualHomeHint": "Not a /home/… project home. Canonical isolation is /home/ysk-server-{id}."
  },
  "migrate": {
    "tabInventory": "Inventory",
    "tabTarget": "Target",
    "tabRun": "Run",
    "tabDone": "Done",
    "refreshFailed": "Refresh failed",
    "migrateIncomplete": "Migration incomplete",
    "requestFailed": "Migration request failed",
    "title": "Full-host migration",
    "subtitle": "Source control plane → full copy to new host. Afterward only change public IP/DNS; accounts, paths, and projects stay the same.",
    "inventorying": "Inventorying",
    "inventoried": "Inventoried",
    "inventoriedWarn": "Inventoried · {{n}} warnings",
    "inventoriedOrphans": "Inventoried · {{n}} leftover homes",
    "inventoriedWarnAndOrphans": "Inventoried · {{w}} warnings · {{n}} leftover",
    "inventoryFailed": "Inventory failed",
    "pendingInventory": "Pending inventory",
    "projects": "Projects",
    "mailboxes": "Mailboxes",
    "users": "Users",
    "software": "Software",
    "jobs": "Jobs",
    "notFound": "Not found",
    "wizard": "Migration wizard",
    "jobLog": "Job history",
    "about": "About",
    "steps": "Migration steps",
    "sourceInventory": "Source inventory",
    "sourceInventoryDesc": "Read-only scan of control plane and project paths; does not modify the system",
    "inventoryRunning": "Inventorying this host…",
    "host": "Host",
    "projectHome": "Projects / home",
    "needSoftware": "Software to install",
    "noInventory": "No inventory yet",
    "noInventoryHint": "Use Refresh (top right) to scan host state and jobs",
    "targetHost": "Target host",
    "targetHostDesc": "Root SSH only; password is for this request only and is not stored",
    "sshTarget": "SSH target",
    "sshPort": "SSH port",
    "targetDataDir": "Target dataDir",
    "authMethod": "Auth method",
    "rootPassword": "Root password",
    "notPersisted": "Not persisted",
    "passwordNotStored": "Password is used for this SSH session only and is not saved on disk.",
    "overwriteDanger": "Overwrite will replace existing YSK data on the target. This cannot be undone from the panel.",
    "outboundIdentity": "Outbound identity in vault",
    "dryRun": "Dry-run precheck",
    "startMigrate": "Start full-host migration",
    "needSshTarget": "Enter SSH target",
    "needMaintWindow": "Check maintenance window",
    "needRootPassword": "Enter root password",
    "needRequired": "Complete required fields",
    "result": "Migration result",
    "blocked": "Blocked",
    "failed": "Failed",
    "detail": "Details",
    "jobsTitle": "Migration jobs ({{count}})",
    "jobsDesc": "State under dataDir/migrate/;",
    "phase": "Phase",
    "jobPhase": "Job {{id}} · {{phase}}",
    "phaseName": {
      "failed": "Failed",
      "done": "Done",
      "running": "Running",
      "queued": "Queued",
      "cancelled": "Cancelled"
    },
    "target": "Target",
    "updated": "Updated",
    "notes": "Notes",
    "noJobs": "No migration jobs yet",
    "noJobsHint": "Jobs appear after a dry-run or full migration in the wizard.",
    "confirmTitle": "Confirm full-host migration",
    "confirmDesc": "Will rsync and bootstrap {{target}}",
    "confirmStart": "Confirm start",
    "cancel": "Cancel",
    "success": "Success",
    "unfilledTarget": "(no target)",
    "restartApiHint": "If you just deployed a new version, restart the API (",
    "afterRestart": ") then Refresh.",
    "inventoryWarnings": "Inventory warnings ({{count}})",
    "orphanHomesHint": "Leftover project homes (not in the store). Remove only after you confirm they are unused.",
    "orphanHomesTitle": "Leftover project homes ({{count}})",
    "orphanHomesSummary": "{{count}} path(s) on disk are not in the store. Back up first if unsure, then remove unused paths.",
    "orphanColHome": "Home",
    "orphanColModified": "Modified",
    "orphanColEntries": "Entries",
    "orphanEntries": "{{n}} top-level entries in the directory",
    "orphanKpi": "Leftover",
    "sourceOs": "OS",
    "sourceDataDir": "dataDir",
    "sourceDbRedis": "Databases / Redis",
    "sourceDbRedisValue": "{{db}} databases · {{redis}} Redis",
    "orphanRemove": "Remove",
    "orphanRemoveTitle": "Delete leftover project home?",
    "orphanRemoveDesc": "Permanently delete {{path}} from disk. This is not a store project. Needs superuser and system-change permission.",
    "orphanRemovePhrase": "Type DELETE to confirm.",
    "orphanRemoveNeedConfirm": "Needs confirmation",
    "orphanBackupFirst": "Back up first (open Backups)",
    "orphanMtime": "Last modified {{at}}",
    "expandAllWarnings": "Show all {{n}} warnings",
    "collapseWarnings": "Show fewer",
    "moreWarnings": "…and {{n}} more",
    "authPassword": "root password (switch to key after temp key install)",
    "authIdentity": "SSH identity vault identityId",
    "authAgent": "Local default agent / key",
    "confirmMaint": "Confirm maintenance window",
    "confirmMaintDesc": "· Source briefly pauses for consistent dump (required for real migrate)",
    "allowOverwrite": "Allow overwrite of existing YSK data on target",
    "allowOverwriteDesc": "· Required if target already has ysk.json",
    "dryRunOnly": "Dry-run only",
    "dryRunOnlyDesc": "· Inventory + precheck only; no rsync or target writes",
    "executeNote": "Host needs system-change permission and a superuser API. After migrate, update DNS A/AAAA and check cloud firewall + mail PTR.",
    "dnsCutover": "DNS cutover (manual)",
    "dnsCutoverDesc": "Point A/AAAA for these names to the new public IP;"
  },
  "multiCheck": {
    "customPlaceholder": "Custom code",
    "searchPlaceholder": "Search…",
    "emptyText": "No matching items",
    "removeTitle": "Click to remove",
    "noneSelected": "Nothing selected",
    "optionsAria": "Options",
    "showingCapped": "Showing first {{shown}} of {{total}} — use search to narrow",
    "add": "Add",
    "bulkAria": "Bulk selection",
    "selectAll": "Select all",
    "selectAllTitle": "Select all {{n}} items",
    "selectFiltered": "Select filtered ({{n}})",
    "selectFilteredTitle": "Select all {{n}} search results",
    "clearAll": "Clear all",
    "clearFiltered": "Clear filtered",
    "selectedCount": "{{n}} / {{total}} selected",
    "chipsCollapsed": "{{n}} selected — expand",
    "chipsCollapse": "Collapse"
  },
  "nav": {
    "dashboard": "Dashboard",
    "ai": "AI Tasks",
    "projects": "Projects",
    "security": "Account security",
    "email": "Email",
    "files": "Files",
    "system": "System apply",
    "updates": "Updates",
    "agents": "AI Agents (exp.)",
    "login": "Login",
    "logout": "Log out",
    "publicFiles": "Public files",
    "ftp": "FTPS",
    "ftpService": "FTPS",
    "mysql": "MySQL",
    "mysqlService": "MySQL service",
    "mariadb": "MariaDB",
    "mariadbService": "MariaDB service",
    "postgres": "PostgreSQL",
    "postgresService": "PostgreSQL service",
    "redis": "Redis",
    "redisService": "Redis service",
    "cluster": "Clusters",
    "dns": "DNS",
    "ssl": "SSL certificates",
    "nginx": "Nginx",
    "node": "Node.js",
    "php": "PHP",
    "python": "Python",
    "go": "Go",
    "rust": "Rust",
    "protection": "Defense Center",
    "firewall": "Firewall",
    "fail2ban": "fail2ban",
    "users": "Users & packages",
    "services": "Services",
    "metrics": "Metrics",
    "network": "Network",
    "logs": "Log center",
    "cron": "Cron",
    "backups": "Backups",
    "migrate": "Host migrate",
    "systemd": "systemd",
    "readiness": "Readiness",
    "systemIndex": "System tools",
    "sections": {
      "overview": "Overview",
      "sites": "Account & sites",
      "mail": "Email",
      "files": "Files & FTP",
      "databases": "Databases",
      "dnsSsl": "DNS & SSL",
      "runtimes": "Runtimes",
      "security": "Security",
      "system": "System",
      "ai": "AI",
      "validators": "Validators",
      "containers": "Containers"
    },
    "java": "Java",
    "kotlin": "Kotlin",
    "bun": "Bun",
    "software": "Software",
    "terminal": "Terminal",
    "hostBrowse": "Host Browse",
    "cdn": "CDN",
    "vpn": "VPN",
    "vnc": "VNC",
    "apache": "Apache",
    "bookmarkedProjects": "Bookmarked projects",
    "bookmarkedEmailDomains": "Bookmarked domains",
    "bookmark": "Pin to sidebar",
    "unbookmark": "Unpin from sidebar",
    "bookmarkPinned": "Pinned",
    "bookmarkAdded": "Pinned to sidebar",
    "bookmarkRemoved": "Removed from sidebar",
    "btTracker": "BT Tracker",
    "support": "Support",
    "noAccessTitle": "No access",
    "noAccessDesc": "Your role does not include this page. Ask an admin if you need it.",
    "backToDashboard": "Back to dashboard",
    "validators": "Validators (Beta)",
    "docker": "Docker"
  },
  "network": {
    "title": "Network interfaces",
    "canMutate": "Mutable",
    "readOnlyBlocked": "Read-only / blocked",
    "statIfaces": "Interfaces",
    "statUp": "Up",
    "oper": {
      "up": "Up",
      "down": "Down",
      "unknown": "Unknown",
      "loopback": "Always on",
      "loopbackHint": "Loopback is always available and cannot be changed.",
      "other": "Other"
    },
    "statGateway": "Gateway",
    "pageActions": "Page actions",
    "loadingSnap": "Loading network snapshot…",
    "mutateHint": "Changes apply live; may reset on reboot.",
    "cannotMutate": "Cannot change: needs EXECUTE and root.",
    "tabs": {
      "ifaces": "Interfaces",
      "routes": "Routes",
      "dns": "DNS",
      "advanced": "Advanced",
      "about": "About",
      "realip": "Real IP / CDN"
    },
    "ifaceSummary": "{{count}} interface(s) · {{up}} UP",
    "noIfaces": "No interfaces",
    "noIfacesDesc": "ip unavailable or no permission",
    "colName": "Name",
    "colStatus": "Status",
    "ifaceOps": "{{name}} actions",
    "routeTable": "Route table",
    "defaultGw": "Default gateway {{gw}}",
    "liveIpRoute": "Live ip route",
    "noRoutes": "No routes",
    "colDest": "Destination",
    "addRoute": "Add route",
    "persistNm": "Save to NetworkManager connection (survives reboot)",
    "ephemeralRoute": "Live ip route only (may vanish on reboot)",
    "destPlaceholder": "default or 10.0.0.0/8",
    "devOptional": "Dev (optional)",
    "defaultDev": "Default egress: {{dev}}",
    "saveNm": "Save (NetworkManager, survives reboot)",
    "ephemeralHint": "Unchecked = live ip route add only",
    "nmUnavailable": "NetworkManager is not running — only a live route can be added",
    "defaultRouteDownNeedName": "This is the default route egress. Type the interface name to confirm — the panel may disconnect.",
    "saveRoute": "Save route",
    "dnsSettings": "DNS settings",
    "dnsNmHint": "Writes NM connection “{{conn}}” and reconnects (persistent)",
    "dnsCannotApply": "Cannot apply: needs active NM connection + EXECUTE + root",
    "mode": "Mode",
    "connection": "Connection",
    "source": "Source",
    "ignoreAutoDns": "Current ignore-auto-dns",
    "ignoreYes": "yes (ignore DHCP DNS)",
    "ignoreNo": "no (follow DHCP)",
    "nameserverEditHint": "Add/remove servers; apply writes NetworkManager and reconnects",
    "routerDns": "Router {{dns}}",
    "current": "Current",
    "serverList": "Server list",
    "emptyDnsTitle": "No DNS servers yet",
    "emptyDnsDesc": "Click “Add server” to start",
    "keepOneRow": "Keep at least one row (clear then delete)",
    "removeServer": "Remove this server",
    "searchDomainsPlaceholder": "Optional, space-separated",
    "ignoreDhcpDns": "Ignore DHCP auto DNS (ipv4.ignore-auto-dns=yes)",
    "restoreDhcpHint": "“Restore DHCP DNS” hands back to router",
    "noNmConnection": "No NM connection — will not blindly edit /etc/resolv.conf (no false success).",
    "needExecuteRoot": "Needs YSK_EXECUTE=1 and root for real writes.",
    "resolveTest": "Resolve test",
    "resolveTestDesc": "getent ahosts (actual local resolution)",
    "hostname": "Hostname",
    "testFailed": "Test failed",
    "stackDetect": "Local network stack detection",
    "available": "Available",
    "unavailable": "Unavailable",
    "persistNmCap": "Persistable (NM)",
    "ifaceDetail": "Interface {{name}}",
    "type": "Type",
    "addresses": "Addresses",
    "noAddresses": "No addresses",
    "ifaceAdjust": "Interface adjust",
    "addIpTitle": "Add IP · {{name}}",
    "saveIp": "Save IP",
    "add": "Add",
    "cidrPlaceholder": "e.g. 10.0.0.5/24 or 2001:db8::5/64",
    "saveIpHint": "Write connection +ipv4/ipv6.addresses and connection up",
    "confirmIfaceName": "Type interface name “{{name}}” to confirm",
    "deleteRouteTitle": "Delete route?",
    "deleteRouteNamed": "Delete route {{dst}}?",
    "deleteRouteBody": "Remove {{dst}}{{via}}{{dev}} from the live routing table.",
    "viaGw": " via {{gw}}",
    "onDev": " on {{dev}}",
    "deleteDefaultWarn": "— deleting default may drop connectivity.",
    "alsoRemoveNm": "Also remove from NetworkManager connection (gone after reboot)",
    "loadFailed": "Load failed",
    "loadNetworkFailed": "Failed to load network",
    "on": "On",
    "off": "Off",
    "addServer": "Add server",
    "applyDns": "Apply DNS",
    "restoreDhcpDns": "Restore DHCP DNS",
    "test": "Test",
    "refresh": "Refresh",
    "hostSettings": "Host settings",
    "protection": "Protection",
    "defaultEgressBadge": "Default",
    "opsAria": "{{name}} actions",
    "details": "Details",
    "addIp": "Add IP",
    "reset": "Reset",
    "ephemeralOnly": "Live only",
    "saveRouteHint": "Save writes NM connection + connection up;",
    "deleteShort": "Del",
    "resetForm": "Reset form",
    "applyDnsNotes": "Apply runs nmcli connection modify + up; brief disconnect is normal. Stub 127.0.0.53 is not written (local resolved).",
    "testResolve": "Test resolve",
    "loadRaw": "Load raw output",
    "hideRaw": "Hide raw output",
    "rawLoadedAt": "Loaded {{time}}",
    "confirmDown": "Confirm Down",
    "linkDownTitle": "Take {{name}} offline",
    "linkDownNeedConfirm": "Type the interface name to confirm",
    "defaultRouteDownWarn": "This interface is the default route egress; down may cut panel access.",
    "deleteDefaultMayDrop": " — deleting default may drop connectivity.",
    "deleteDefaultPanelWarn": "Deleting the default route can drop this panel session. Type DEFAULT to confirm.",
    "deleteDefaultNeedConfirm": "Needs confirmation — type DEFAULT (may drop this panel)",
    "deleteRouteNeedConfirm": "Needs confirmation",
    "typeDefaultToConfirm": "Type DEFAULT to confirm",
    "gateway": "Gateway",
    "nameservers": "Nameservers",
    "searchDomains": "Search domains",
    "backend": "Backend",
    "cidr": "CIDR",
    "realip": {
      "title": "CDN / Real client IP",
      "desc": "Restore visitor IP behind CDN; trust edge CIDRs only.",
      "provider": "Default provider",
      "providerHint": "none = direct origin; pick CDN when behind edge.",
      "mode": "Trust mode",
      "modeSingle": "Single provider header (recommended)",
      "modeXff": "X-Forwarded-For + merged CDN CIDRs",
      "customCidrs": "Extra trusted CIDRs",
      "customCidrsHint": "One CIDR per line.",
      "lastRefresh": "Last CIDR refresh",
      "active": "Active default",
      "republishHint": "Re-publish project Nginx after save.",
      "refresh": "Refresh CDN IP lists",
      "refreshOk": "CIDR lists refreshed",
      "providers": {
        "none": "None (direct origin)",
        "cloudflare": "Cloudflare",
        "fastly": "Fastly",
        "bunny": "Bunny CDN",
        "cloudfront": "AWS CloudFront",
        "azure_frontdoor": "Azure Front Door",
        "gcore": "Gcore CDN",
        "custom": "Custom proxies"
      },
      "needProvider": "Choose a CDN provider before fetching its IP list.",
      "spoofWarn": "Trusting the wrong CIDR lets clients spoof X-Forwarded-For / CDN headers as their IP."
    },
    "linkUp": "Up",
    "linkDown": "Down",
    "linkDownDefault": "Down default route",
    "loopbackImmutable": "Loopback cannot be changed",
    "operUnknownHint": "Kernel did not report UP/DOWN (common for lo). The interface is still usable.",
    "persistNmHint": "Persistable means changes can survive reboot via NetworkManager."
  },
  "nginx": {
    "pillSites": "{{count}} site(s)",
    "statSites": "Sites",
    "statSslFlag": "SSL flag",
    "purgeOk": "Purged",
    "projectSitesHint": "Project sites (managed conf) and standalone sites are listed separately. Edit project Nginx under Projects → Network.",
    "purgeCache": "Purge cache + reload",
    "purgeCacheTitle": "Purge Nginx cache and reload?",
    "purgeCacheDesc": "Clears the on-disk cache and reloads Nginx. Live sites stay up.",
    "notInstalled": "Nginx is not installed",
    "listTitle": "Sites ({{count}})",
    "listDesc": "After create, click Apply to sync to the system",
    "createSite": "+ Create site",
    "colServerName": "Server name",
    "colKind": "Type",
    "kindProxy": "Reverse proxy",
    "kindStatic": "Static",
    "kindPhp": "PHP-FPM",
    "colTarget": "Upstream / root",
    "colStatus": "Status",
    "emptyTitle": "No sites",
    "emptyDesc": "Use “Create site” in the list toolbar; then Apply",
    "applyTitle": "Write panel data and try sync + nginx -t + reload",
    "applyToSystem": "Sync to system",
    "createTitle": "Create Nginx site",
    "createDesc": "Apply required after create",
    "editTitle": "Edit Nginx site",
    "editDesc": "Apply required after save",
    "deleteTitle": "Delete site?",
    "deleteDesc": "Delete this site?",
    "deleteTitleNamed": "Delete site {{name}}?",
    "deleteDescNamed": "Remove {{name}} from the panel. Applied sites will also drop their managed nginx conf.",
    "invalidServerName": "Enter a valid hostname (e.g. app.example.com).",
    "needUpstream": "Upstream is required for reverse proxy sites.",
    "needRoot": "Document root is required for static and PHP sites.",
    "serverNameHint": "server_name, e.g. app.example.com",
    "kindLabel": "Site type",
    "upstreamLabel": "Upstream",
    "upstreamHint": "e.g. 127.0.0.1:3000 or http://backend:8080",
    "rootLabel": "Document root",
    "rootHintPhp": "PHP project document root, e.g. /var/www/app/public",
    "rootHintStatic": "Absolute path to static files",
    "sslLabel": "Enable SSL block",
    "sslDesc": "Emits listen 443 ssl; bind certs from the SSL page when ready",
    "saveThenApply": "After save, click Apply to write nginx config",
    "statProjectSites": "Projects",
    "projectListTitle": "Project sites ({{count}})",
    "projectListDesc": "Panel-managed conf from project publish / goLive — open the project Network tab to change.",
    "colProject": "Project",
    "colRuntime": "Runtime",
    "colConf": "Conf",
    "confWritten": "Written",
    "confMissing": "No path",
    "projectEmptyTitle": "No project Nginx yet",
    "projectEmptyDesc": "Publish Nginx from a project Network tab after deploy",
    "preview": "Preview",
    "openProject": "Open project",
    "projectPager": "Project site pages",
    "prevPage": "Previous",
    "nextPage": "Next",
    "pageOf": "Page {{page}} / {{total}} · {{count}}",
    "projectConfEmpty": "(empty conf file)",
    "projectConfReadFail": "Failed to read project conf",
    "projectPreviewPath": "{{path}}",
    "pageDesc": "Nginx sites",
    "filterSource": "Source",
    "sourceAll": "All",
    "sourceProject": "Project",
    "sourceStandalone": "Standalone",
    "colSource": "Source",
    "filterProject": "Filtered by project",
    "globalSettings": "Global settings",
    "siteSettings": "Site settings",
    "saveApply": "Save & apply",
    "settingsSaved": "Saved",
    "setGzip": "Gzip",
    "setShowVersion": "Show server version",
    "setShowVersionDesc": "Checked = server_tokens on (nginx version in response headers)",
    "setHttp2": "HTTP/2 (SSL)",
    "setBody": "Max body",
    "setKeepalive": "Keepalive",
    "setAccessLog": "Access log",
    "logOn": "On",
    "logBuffered": "Buffered",
    "logOff": "Off",
    "setForceHttps": "Force HTTPS",
    "setHsts": "HSTS",
    "setCfRealIp": "Cloudflare Real IP",
    "setIndexes": "Directory listing",
    "bodyInherit": "Global",
    "stopSites": "{{n}} site(s) will stop answering HTTP."
  },
  "notFound": {
    "title": "Page not found",
    "body": "No panel page at {{path}}.",
    "hint": "Unknown URLs no longer send you to the dashboard.",
    "home": "Dashboard"
  },
  "notes": {
    "agents": {
      "sessionNotFound": "Session not found: {{sessionId}}"
    },
    "notFound": "Not found",
    "needPath": "Specify a path",
    "needName": "Enter a name",
    "needHost": "Enter a host",
    "needDomain": "Enter a domain",
    "needProjectName": "Enter a project name",
    "needServerIp": "Specify a server IP",
    "passwordMin8": "Password must be at least 8 characters",
    "invalidPath": "Invalid path",
    "invalidIp": "Invalid IP",
    "invalidIp46": "Invalid IPv4/IPv6",
    "invalidPackageName": "Invalid package name",
    "fileMissing": "File does not exist",
    "notRegularFile": "Not a regular file",
    "readFailed": "Read failed",
    "pathResolveFailed": "Failed to resolve path",
    "fieldInvalid": "Invalid field {{field}}: {{value}}",
    "apt": {
      "updateIndex": "Update package index"
    },
    "state": {
      "closed": "Closed",
      "active": "Active"
    },
    "cat": {
      "security": "Security",
      "mail": "Mail",
      "database": "Database",
      "runtime": "Runtimes"
    },
    "ssh": {
      "identityNotFound": "Identity not found",
      "registrationNotFound": "Registration not found",
      "keyOkNologin": "Key accepted. Account is nologin or SFTP-only (no SSH shell). Treated as PASS.",
      "keyOkSftp": "SFTP pwd succeeded after SSH shell was refused."
    },
    "cdn": {
      "siteNotFound": "CDN site not found",
      "nodeMissing": "Node does not exist",
      "loopbackOriginRemote": "Origin is 127.0.0.1 — that is this host, not a remote edge. Set a reachable origin IP or bind_ip.",
      "originRemoteRewrite": "Remote edges will use reachable origin {{url}} instead of loopback.",
      "originRemoteUnknown": "Origin is loopback and no public/LAN IP or bind_ip is known — apply will refuse remote edges until one is set.",
      "needSshOrFleet": "Remote edge needs an outbound SSH identity (or username) or a /agents fleet session. Health URL alone is not apply transport.",
      "probe": {
        "timeout": "Connect timeout after {{ms}}ms ({{detail}}). Peer may be firewalled.",
        "dns": "DNS lookup failed ({{detail}}).",
        "refused": "Connection refused after {{ms}}ms ({{detail}}). Port closed or one-way block.",
        "tls": "TLS verify failed ({{detail}}).",
        "unreach": "Host unreachable after {{ms}}ms ({{detail}}).",
        "http": "HTTP probe failed after {{ms}}ms ({{detail}})."
      }
    },
    "backup": {
      "testUnsaved": "Testing unsaved form values (not written to settings).",
      "testIdentity": "sftp (identity) to {{spec}} ok",
      "sshAuthFailed": "SSH key or password rejected (publickey). Pick an outbound identity or install sshpass.",
      "remotePathIsFile": "Remote path {{path}} is a file. Use a directory.",
      "remoteMkdirFailed": "Could not create remote directory: {{detail}}",
      "sidecarPushed": "Also pushed SQL sidecar {{name}}",
      "fileNotFound": "Backup file not found",
      "resticNoPassword": "restic is enabled but password is not set",
      "resticNotInPath": "restic not in PATH",
      "dbEnvUnreadable": "Could not read .db.env; skipped SQL dump.",
      "dbEnvNoName": ".db.env has no database name; skipped SQL dump.",
      "targetOutside": "Restore target must be inside the project home or the public files root.",
      "controlPlaneDryRun": "Preview only — nothing written. In the panel, use Restore and confirm the phrase to write.",
      "controlPlaneNeedConfirm": "Full control-plane restore needs the confirm phrase RESTORE-CONTROL-PLANE.",
      "controlPlaneRestartAfter": "Restart the API after a successful restore.",
      "movedToTrash": "Moved {{name}} to the recycle bin. Permanent delete after {{days}} days.",
      "restoreNameExists": "Cannot restore {{name}} — a live archive with that name already exists.",
      "restoredFromTrash": "Restored {{name}} from the recycle bin.",
      "trashEmptied": "Permanently deleted {{n}} archive(s) from the recycle bin.",
      "partialOk": "Partial success — {{n}} project(s) skipped"
    },
    "health": {
      "portListening": "Port {{port}} is listening",
      "portNotListening": "Port {{port}} is not listening",
      "httpOk": "HTTP OK {{status}}",
      "httpFail": "HTTP failed: {{detail}}"
    },
    "redis": {
      "cliMissing": "redis-cli is not installed",
      "requirepassAlreadySet": "Redis already has requirepass — not overwritten.",
      "requirepassApplied": "requirepass applied at runtime",
      "requirepassApplyFailed": "Could not CONFIG SET requirepass (will rely on restart + conf)",
      "generatedRequirepass": "Generated Redis password (shown once): {{password}}"
    },
    "nginx": {
      "reloaded": "nginx reloaded",
      "configOk": "Nginx config check passed",
      "reloadExit": "Nginx reload exit code={{code}}",
      "managedDir": "Managed config dir: {{path}}",
      "includeHint": "In nginx: include {{path}}/*.conf;",
      "removedOrphan": "Removed orphan nginx conf {{path}}",
      "keptLiveSsl": "Kept live HTTPS block in {{path}} (managed template had no listen 443)",
      "orphanCleanupFailed": "Orphan nginx cleanup failed: {{detail}}",
      "settingsWritten": "Nginx global snippet written",
      "settingsNeedExecute": "Apply needs YSK_EXECUTE",
      "reloadFailed": "nginx reload failed"
    },
    "ssl": {
      "requestCert": "Request certificate"
    },
    "ftp": {
      "startVsftpd": "Start vsftpd",
      "writeVsftpd": "Write vsftpd config",
      "vsftpdStarted": "vsftpd started",
      "openPortsStep": "Firewall ports (manual)",
      "openPortsReminder": "Open TCP ports on host firewall and cloud security group: {{ports}}. FTPS apply does not open ports for you.",
      "openPortsPasvHint": "If login works but directory LIST times out, the PASV data range is blocked — open the ful",
      "publicPlaintextBlocked": "Refusing to start public FTP without FTPS. Bind to this host only, enable FTPS with a certificate, or confirm PLAINTEXT to expose cleartext on the public address."
    },
    "deploy": {
      "nodeMissingIsolated": "Node binary missing for isolated deploy: {{path}} — install Node {{version}} toolchain then redeploy. Refusing to write a unit that would 203/EXEC.",
      "nodeMissing": "Node binary missing: {{path}} — install toolchain (Node {{version}}) then redeploy",
      "nodeRejectedPath": "Node binary rejected for project user: {{path}} — use {{planned}}",
      "unitUnhealthy": "systemd unit not healthy ({{detail}}). journalctl -u {{unit}} — 203/EXEC often means binary not executable by project user",
      "skippedPanelNode": "Skipped panel Node at {{path}} (not executable by project user; would cause systemd 203/EXEC)",
      "usingFallback": "Node binary: using {{path}} (planned {{planned}} not found)",
      "usingPanelExec": "Node binary: fallback to panel execPath {{path}}",
      "usingPanelDegraded": "Node binary: degraded deploy using panel {{path}} (not for systemd User=ysks_*)",
      "nodeNotFoundPlanned": "Node {{version}} binary not found on host — unit will use {{planned}}; install toolchain then redeploy"
    },
    "files": {
      "needSrcDst": "Specify source and destination paths",
      "pathOutsideSandbox": "Path outside sandbox: {{target}}",
      "notFoundRel": "Not found: {{relPath}}",
      "fileNotFoundRel": "File not found: {{relPath}}",
      "notFoundFrom": "Not found: {{fromPath}}",
      "alreadyExists": "Already exists: {{name}}"
    },
    "dns": {
      "needZoneServerIp": "Enter zone and server IP",
      "noClusterPeer": "No cluster peer registered",
      "planOnly": "Plan only — set apply=true (root + YSK_EXECUTE) to install into /etc/powerdns and rediscover",
      "needRootNamed": "Need root + EXECUTE to update /etc/powerdns/named.conf and rediscover zones",
      "noManagedZonesClear": "No managed zone files under dataDir/dns/zones — will clear PowerDNS YSK include",
      "bindRegistered": "PowerDNS BIND: registered {{count}} zone(s) (list-zones confirmed)",
      "listZonesIncomplete": "named.conf/runtime zones updated but list-zones did not confirm all zones — not marking loaded (check pdns logs / bind-config)",
      "noLaunchDefaultBind": "no launch= found — defaulting to bind path",
      "writeNotAnswerDig": "Writing zone file alone does not answer dig — load into PowerDNS (bind named.conf + rediscover)",
      "bindDigFailed": "Zone listed but dig SOA failed — not claiming loaded",
      "bindLoadedOk": "Zone {{zone}} registered via PowerDNS BIND named.conf + dig OK",
      "bindSyncFailed": "BIND named.conf sync failed or dig not answering",
      "bindSkipPdnsutil": "Skipping BIND path (backend prefers pdnsutil)",
      "pdnsCtlNoConfirm": "pdns_control present but zone not confirmed; check /etc/powerdns/named.conf or use pdnsutil backend",
      "usingExistingZone": "Using existing zone file: {{path}}",
      "healNeedRoot": "Need root + EXECUTE to rewrite pdns local-address",
      "pdnsUnitActive": "pdns unit: active",
      "pdnsUnitInactive": "pdns unit: not active",
      "udp53Listening": "UDP/53: listening",
      "udp53NotListening": "UDP/53: still not listening",
      "healResyncOk": "Healed listener + re-synced managed zones into PowerDNS BIND",
      "healResyncPartial": "Listener healed but zone re-sync incomplete — click Write & load zone / powerdns load",
      "installAfterLoad": "After install, apply DNS zones (writes named.conf + rediscover) or POST powerdns/load",
      "bindFileNotEnough": "BIND backend: zone files alone do not answer dig until named.conf includes them",
      "zeroDomainsHint": "PowerDNS list-zones: 0 — zone files on disk are not loaded (named",
      "localAFailed": "local A probe failed for www/ftp/@ under {{zone}}",
      "publicNsCloudflare": "public NS is a third-party DNS/CDN (e.g. Cloudflare) — public dig will NOT use this host zone",
      "publicNsOther": "public NS is not this host — worldwide checks ignore local PowerDNS until registrar NS change",
      "publicNsHere": "public NS looks like in-zone nameservers (ns1/ns2.zone) — world may query you",
      "firewall53Hint": "UDP/53 not listening from ss — open firewall 53 both (TCP+UDP) if external dig fails",
      "applyDigOk": "PowerDNS BIND: list-zones + dig OK",
      "applyDigFail": "Zone registered in conf but dig still empty/REFUSED — not marking applied",
      "applySyncIncomplete": "PowerDNS bind sync incomplete — zone file on disk only (not applied). Fix EXECUTE/root or pdns logs.",
      "writeOnlyHint": "Zone file written only — PowerDNS will not answer until load/apply registers named",
      "noActiveUnit": "No active named/bind9/pdns unit",
      "pdnsUnitRestarts": "pdns unit state/restarts: {{detail}}",
      "port53LoopbackOnly": "Port 53 is only on loopback (systemd-resolved 127.0.0.53) — not a product authoritative nameserver",
      "port53Closed": "Port 53 is not listening (UDP/TCP)",
      "udp53NotPublic": "UDP/53 is not listening on a public address",
      "tcp53NotPublic": "TCP/53 is not listening on a public address",
      "noManagedZones": "No managed zone files under dataDir/dns/zones",
      "pdnsListZones": "PowerDNS list-zones: {{n}}",
      "lookupIgnoredAt": "dig is unavailable — @{{server}} was ignored. Not using the system resolver as that server’s answer.",
      "digNotInstalled": "dig is not installed",
      "digEmpty": "dig: no answer",
      "localAOk": "local A {{name}} → {{ip}}"
    },
    "db": {
      "needExecuteCreate": "Host execute is off; cannot create database from the panel",
      "dryRunMysql": "dry-run: database not created. Use --execute with YSK_EXECUTE=1 to provision",
      "remoteNoCreds": "No username/password stored — TCP only (registration is not a login).",
      "remoteReachable": "TCP {{host}}:{{port}} open ({{ms}}ms).",
      "remoteUnreachable": "TCP {{host}}:{{port}} closed or filtered ({{ms}}ms)."
    },
    "net": {
      "invalidIface": "Invalid interface name",
      "invalidDev": "Invalid device name",
      "needNmActive": "Cannot persist: need an active NetworkManager connection"
    },
    "project": {
      "notFound": "Project not found: {{id}}",
      "docRootMustBeRelative": "Document root must be relative to the project home (not an absolute path).",
      "docRootInvalid": "Invalid document root (no .. or illegal characters).",
      "domainInvalid": "Invalid domain name: {{domain}}",
      "domainInUse": "Domain {{domain}} is already used by project “{{other}}”."
    },
    "email": {
      "domainNotFound": "Mail domain not found: {{id}}",
      "wroteNginx": "Wrote Nginx config: {{nginxPath}}",
      "wrotePath": "Wrote {{path}}",
      "domainDeleted": "Deleted domain {{domain}} ({{mailboxes}} mailboxes, {{aliases}} aliases)",
      "domainDataDirRemoved": "Removed local data directory {{path}}",
      "domainDataDirRemoveFailed": "Could not remove data directory {{path}}: {{detail}}",
      "domainDeleteSystemHint": "Control plane removed; re-apply remaining domains or clean system MTA maps if needed",
      "mailboxDeleted": "Deleted mailbox {{address}}",
      "mailboxNotFound": "Mailbox not found",
      "mailboxDataRemoved": "Removed local path {{path}}",
      "domainDeleteConfirmMismatch": "Confirm name does not match domain; delete refused",
      "domainDataKept": "Kept local dataDir mail data (removeData=false)",
      "mailboxPasswordUpdated": "Password updated for {{address}}",
      "mailboxStatusUpdated": "Status for {{address}} set to {{status}}",
      "mailboxUpdateEmpty": "Nothing to update — provide password and/or status",
      "mailboxStatusInvalid": "Invalid mailbox status",
      "mailboxNoChanges": "No changes applied",
      "dovecotApplyNeedRoot": "Dovecot virtual auth apply needs root + YSK_EXECUTE",
      "dovecotNotInstalled": "Dovecot is not installed on this host",
      "dovecotNoPassdbSnippets": "No domain passdb snippets found under dataDir/email",
      "dovecotApplyFailed": "Dovecot virtual auth apply failed: {{detail}}",
      "dovecotApplyOk": "Dovecot virtual auth installed ({{conf}}, {{count}} domain snippet(s))",
      "dovecotPassdbWrittenNeedApply": "Passwd-file written under dataDir — run apply (EXECUTE+root) so Dovecot loads it",
      "postqueueSetgidBroken": "Postfix queue tools failed: setgid_group is empty in main.cf. Set setgid_group=postdrop (panel tries to fix when YSK_EXECUTE is on).",
      "postqueueMailDown": "Postfix is not running (showq unavailable). Panel tried to start it when YSK_EXECUTE is on — check the Software tab / systemctl status postfix.",
      "postqueueSpoolMissing": "Postfix queue directories are missing (e.g. hold/). Panel tried to create the spool tree and start Postfix when YSK_EXECUTE is on.",
      "invalidDomain": "Enter a valid mail domain",
      "invalidServerIp": "Enter a valid server IP",
      "mailboxLocalPartInvalid": "Mailbox local-part may only use letters, digits, . _ + -",
      "passwordTooShort": "Password must be at least 8 characters"
    },
    "software": {
      "startUnit": "Start {{u}}",
      "installedSpec": "Installed {{title}}",
      "installPkg": "Install {{p}}",
      "npmGlobal": "npm install -g {{pkgs}}",
      "needNodeForNpm": "node/npm not found — install Node.js before {{title}}",
      "uninstallNoTargets": "No software selected for uninstall",
      "uninstallNothingInstalled": "Nothing installed for the selected scope",
      "uninstallProtected": "Skipped protected components: {{ids}}",
      "uninstallConfirmMismatch": "Confirmation phrase does not match",
      "uninstallOk": "Uninstalled {{n}} component(s)",
      "uninstallPartial": "Uninstall finished with errors — check steps"
    },
    "php": {
      "aptPackages": "Will install {{count}} packages: {{list}}"
    },
    "runtime": {
      "plugins": "Companion tools: {{list}}",
      "pluginsOk": "Companion tools installed",
      "pluginsFailed": "Some tools failed or were skipped: {{list}}",
      "pluginsUninstall": "Uninstall tools: {{list}}",
      "pluginsUninstallOk": "Companion tools uninstalled",
      "pluginsUninstallFailed": "Some tools failed to uninstall or were skipped: {{list}}",
      "pluginsNoneToUninstall": "No tools to uninstall (already gone or required)"
    },
    "approval": {
      "notFound": "Approval not found: {{id}}"
    },
    "readiness": {
      "core": "Control plane",
      "security": "Permissions & security",
      "binaries": "Binaries / packages",
      "hosting": "Hosting",
      "dns": "DNS",
      "email": "Email",
      "isolation": "Project isolation",
      "ops": "Operations",
      "runtimesNode": "Node.js",
      "runtimesPhp": "PHP",
      "runtimesPython": "Python",
      "runtimesGo": "Go",
      "pm2": "PM2",
      "runtimesNodeFix": "Install Node from /runtimes/node",
      "runtimesPhpFix": "Install PHP from /runtimes/php",
      "runtimesPythonFix": "Install Python from /runtimes/python",
      "runtimesGoFix": "Install Go from /runtimes/go",
      "pm2Fix": "Install PM2 from the Node runtime page"
    },
    "needAdmin": "Administrator permission required",
    "notInstalled": "Not installed",
    "unknown": "Unknown",
    "failed": "Failed",
    "running": "Running",
    "stopped": "Stopped",
    "probe": "Probe",
    "install": "Install",
    "port": "Port",
    "git": {
      "missingBin": "git is not on PATH",
      "auth": "Authentication failed. Add a deploy key or HTTPS token.",
      "hostkey": "SSH host key verification failed. Confirm and pin the host key.",
      "dirty": "Working tree has {{count}} local change(s). Pull is blocked.",
      "diverged": "Cannot fast-forward. Reset to the remote ref if you intend to discard local Git history.",
      "missingRef": "That branch, tag, or commit is not on the remote.",
      "shallow": "This clone is shallow. Fetch full history before pinning an old commit.",
      "notRepo": "app/ is not a Git repository yet.",
      "diffEmpty": "No unstaged diff (protected .env is excluded).",
      "unrelated": "Unrelated histories. Reclone only after confirm — custom files will be lost.",
      "lock": "Git index.lock is present. Remove it only if no git process is running.",
      "disk": "Disk full or quota exceeded.",
      "timeout": "Git timed out.",
      "network": "Network error talking to the remote.",
      "lfs": "This repo uses Git LFS and git-lfs is not available.",
      "submodule": "Submodule update failed.",
      "unknown": "Git failed. See the command output.",
      "fetchOk": "Fetched from origin.",
      "checkoutOk": "Checked out {{ref}}.",
      "resetOk": "Reset hard to {{ref}}.",
      "envRestored": "Restored app/.env from the control plane.",
      "needPinHost": "SSH host key is not pinned. Scan and pin it before clone or fetch.",
      "tokenSaved": "HTTPS token stored (never shown again).",
      "tokenCleared": "HTTPS token removed.",
      "tokenInvalid": "Token must be at least 8 characters.",
      "deployKeyCreated": "Deploy key created. Add the public key on the Git host.",
      "deployKeyCleared": "Deploy key detached from this project.",
      "hostPinned": "Pinned SSH host keys for {{host}}.",
      "hostUnpinned": "Cleared pinned SSH host keys.",
      "hostScanFailed": "ssh-keyscan returned no keys for that host.",
      "hookEnabled": "Inbound Git hook is on. Paste the URL into GitHub, Gitea, or GitLab yourself.",
      "hookDisabled": "Inbound Git hook is off. The URL will not sync.",
      "hookSecretOnce": "Copy this hook secret now. It is not shown again.",
      "refsNeedUrl": "Enter a Git URL first.",
      "refsOk": "Loaded {{branches}} branch(es) and {{tags}} tag(s).",
      "refsEmpty": "Remote advertised no branches or tags."
    },
    "auto": {
      "n0001": "Status: applied",
      "n0002": "User not found",
      "n0003": "blocked: requires YSK_EXECUTE=1",
      "n0004": "Resource not found",
      "n0005": "Cannot apply on host: needs YSK_EXECUTE + root",
      "n0006": "Host execute required",
      "n0007": "Status: written",
      "n0008": "Root privileges are required to complete this",
      "n0009": "createdatabase",
      "n0010": "done",
      "n0011": "Not found",
      "n0012": "Status: failed",
      "n0013": "not running",
      "n0014": "start",
      "n0015": "Not installed mysql",
      "n0016": "Not installed psql",
      "n0017": "UFW firewall",
      "n0018": "Runtimes",
      "n0019": "Not found cron",
      "n0020": "",
      "n0021": "Policy not enforced: 0/1 admin has 2FA enabled",
      "n0022": "Admin two-factor authentication",
      "n0023": "Binary log (replication)",
      "n0024": "Not found",
      "n0025": "System changes disabled",
      "n0026": "Auto-ban circuit breaker tripped",
      "n0027": "Please specify agentId",
      "n0028": "Project not found",
      "n0029": "requires name",
      "n0030": "Emergency",
      "n0031": "ban not enable",
      "n0032": "dry-run: thisnot system",
      "n0033": "dry-run: not system",
      "n0034": "1 replica",
      "n0035": "node probe Success",
      "n0036": "serverHost execute is not enabled, cannot rsync",
      "n0037": "reapply key stepsFailed",
      "n0038": "cannot bootstrap: not enable YSK_EXECUTE",
      "n0039": "bootstrap Requires YSK_EXECUTE=1",
      "n0040": "Max connections",
      "n0041": "Bind address",
      "n0042": "domain",
      "n0043": "draining",
      "n0044": "Not found CDN node",
      "n0045": "(GitHub Releases latest)",
      "n0046": "execute ( YSK_EXECUTE systemdirectory)",
      "n0047": "dry-run: add --execute first to system nginx",
      "n0048": "requiresadmin",
      "n0049": "projectId and name",
      "n0050": "^.*account or password.*$",
      "n0051": "^.*requires verify.*$",
      "n0052": "echo \"pdnsutil Not found: \" >&2",
      "n0053": ": ''}(May not persist across reboot; use Save to persist)",
      "n0054": "# rsa_cert_file= (not certificate)",
      "n0055": "$_GET / $_POST / $_COOKIE",
      "n0056": "--password, or YSK_MIGRATE_SSH_PASSWORD",
      "n0057": "-1 disable; 0",
      "n0058": "/proc/meminfo can",
      "n0059": "/proc/stat can — CPU% cannot",
      "n0060": "0 = limits; can 256mb",
      "n0061": "0 = use all CPUs",
      "n0062": "0 (off)",
      "n0063": "1-minute load exceeds CPU × 2",
      "n0064": "1. panelcreate MySQL database",
      "n0065": "1 = safest; 2 = better performance",
      "n0066": "2. WordPress to app/public",
      "n0067": "3. settings wp-config.php",
      "n0068": "4. PHP + Nginx/SSL",
      "n0069": "A IPv4",
      "n0070": "A IPv4",
      "n0071": "AAAA IPv6",
      "n0072": "AAAA IPv6",
      "n0073": "AOF persist",
      "n0074": "Adminer File does not exist; please download:true",
      "n0075": "Agent cannot write",
      "n0076": "Agent running",
      "n0077": "Allowlist",
      "n0078": "Axum + Tokio; cargo build crates ()",
      "n0079": "Axum: cargo build --release crates.io",
      "n0080": "Skip name resolve",
      "n0081": "Collation server",
      "n0082": "Character set server",
      "n0083": "Bootstrap node ()",
      "n0084": "Bot scan",
      "n0085": "CLI OPcache",
      "n0086": "CONFIG SET databases not Success (can restart)",
      "n0087": "CPU for 1–10000",
      "n0088": "Cloudflare UA not Success",
      "n0089": "Cloudflare Under Attack please",
      "n0090": "Cookie Secure ( HTTPS)",
      "n0091": "DB index for 0–15",
      "n0092": "System user not created for this project",
      "n0093": "DB id User not found — please createsystemuser",
      "n0094": "DB_PASSWORD for — please page create MySQL or WP_DB_*",
      "n0095": "DDoS",
      "n0096": "DKIM",
      "n0097": "DMARC",
      "n0098": "DNS written ≠ resolver ( TTL/)",
      "n0099": "DS registrar, please.",
      "n0100": "Django: pip install django/gunicorn",
      "n0101": "Down confirmName etcinterface",
      "n0102": "EmailService dataDir — database ( dataDir Maildir)",
      "n0103": "FPM reloadFailed",
      "n0104": "FTPS requiresdomain",
      "n0105": "FastAPI + uvicorn; requirements.txt; / and /health",
      "n0106": "Flask app.py; requirements.txt; / and /health",
      "n0107": "GTID: conf gtid_mode=ON",
      "n0108": "Galera Supports mariadb",
      "n0109": "Git URL Invalid",
      "n0110": "GitHub package.json Missing version",
      "n0111": "GitHub release Missing tag",
      "n0112": "Go runtime",
      "n0113": "certbot",
      "n0114": "HTTP conf with ACME webroot (not TLS)",
      "n0115": "HTTP Failed",
      "n0116": "HTTPS enable",
      "n0117": "IMAP/POP Failed",
      "n0118": "IP not (/enrich)",
      "n0119": "IP Invalid",
      "n0120": "IPv4 0–32",
      "n0121": "IPv6 0–128",
      "n0122": "InnoDB flush log at trx commit",
      "n0123": "InnoDB log file size",
      "n0124": "InnoDB buffer pool size",
      "n0125": "Install and publish via admin panel (Webmail install).",
      "n0126": "L7 flood / abnormal traffic",
      "n0127": "LLM Abnormal (Missing)",
      "n0128": "Let’s Encrypt HTTP-01 requires 80 can; DNS-01 API token.",
      "n0129": "LimitNOFILE for 64–10000000",
      "n0130": "MTU 68–65535",
      "n0131": "MX mailhost",
      "n0132": "MX: first host ( 10 mail.example.com.)",
      "n0133": "MariaDB server",
      "n0134": "Require clients to use TLS",
      "n0135": "MySQL server",
      "n0136": "MySQL/MariaDB client",
      "n0137": "NetworkManager unavailable, cannotwrite DNS",
      "n0138": "Nginx tighter rate limit (~8 req/s)",
      "n0139": "Nginx strict rate limit (~3 req/s)",
      "n0140": "Nginx gentle rate limit (~20 req/s)",
      "n0141": "fail2ban",
      "n0142": "Node Install failed",
      "n0143": "Node.js",
      "n0144": "OPcache (MB)",
      "n0145": "PHP docroot + wp-config ()",
      "n0146": "firewall (UFW)",
      "n0147": "PHP processstartnot process",
      "n0148": "PHP degraded — not with project Linux user (Requires root + createsystemuser)",
      "n0149": "PID for",
      "n0150": "PID Invalid",
      "n0151": "PING succeeded",
      "n0152": "PM2 Start failed — pidfile start",
      "n0153": "postfix",
      "n0154": "POST",
      "n0155": "Per-sender: envelope sender domain msgs/hour; DEFER_IF_PERMIT",
      "n0156": "Postfix suspend map Applied (check_recipient_access REJECT)",
      "n0157": "PostgreSQL server",
      "n0158": "PostgreSQL serverNot installed",
      "n0159": "PostgreSQL client",
      "n0160": "PostgreSQL servicenot running",
      "n0161": "PowerDNS tools",
      "n0162": "Primary: create replication user (SQL )",
      "n0163": "Python Django ()",
      "n0164": "redis-server",
      "n0165": "Python behavior",
      "n0166": "RDB rule",
      "n0167": "RDB",
      "n0168": "RUSTFLAGS (build)",
      "n0169": "Redis dbIndex for 0–15",
      "n0170": "Redis dump Requires YSK_EXECUTE=1",
      "n0171": "Redis server",
      "n0172": "Redis serverNot installed or cannotconnection",
      "n0173": "Redis startcannot PING",
      "n0174": "Redis client",
      "n0175": "Redis start",
      "n0176": "Redis restorerequires YSK_EXECUTE",
      "n0177": "Renewal via certbot.timer (dns-01 )",
      "n0178": "Rust build / run",
      "n0179": "S3 bucket/path not settings",
      "n0180": "SFTP.ssh chown Requires root + YSK_EXECUTE",
      "n0181": "SIGKILL confirmKill: true",
      "n0182": "SMTP /",
      "n0183": "SPF",
      "n0184": "SRV: priority weight port target",
      "n0185": "SSH",
      "n0186": "SSH connectionFailed",
      "n0187": "SSH Requires YSK_EXECUTE=1",
      "n0188": "SSO verify ()· password",
      "n0189": "SSO verify ()· password",
      "n0190": "SST=mariabackup: node mariadb-backup",
      "n0191": "Session",
      "n0192": "Session",
      "n0193": "Session",
      "n0194": "TCP (inuse)",
      "n0195": "TOTP Success",
      "n0196": "TasksMax for 1–1000000",
      "n0197": "UFW Not installed",
      "n0198": "UFW StatusRead failed",
      "n0199": "VACUUM",
      "n0200": "WAL etc",
      "n0201": "Web + mail",
      "n0202": "Web UI: Not found: (build apps/web or set YSK_WEB_ROOT)\\n",
      "n0203": "Web host",
      "n0204": "Web interface",
      "n0205": "WebAuthn verifyFailed",
      "n0206": "WebDAV not",
      "n0207": "Webmail Invalid domain",
      "n0208": "Wildcard/dns-01: certbot TXT; panelwillstart DS/TXT DNS done",
      "n0209": "WordPress (PHP )",
      "n0210": "YSK PHP OK — WordPress Not installed\\\\n",
      "n0211": "YSK_EXECUTE is on but the process is not root — some systemctl/nginx reloads will be blocked",
      "n0212": "YSK_EXECUTE enable",
      "n0213": "YSK_EXECUTE is off — written ≠ applied",
      "n0214": "YSK_EXECUTE is off — host mutations stay written/draft until you set YSK_EXECUTE=1",
      "n0215": "access log Failed",
      "n0216": "access=fleet requires fleetAgentId",
      "n0217": "action for reboot | poweroff | cancel",
      "n0218": "apex + www ( edge )+ cdn host",
      "n0219": "apex CNAME server/",
      "n0220": "app.py — skipped",
      "n0221": "applied ≠ healthy — please probe wsrep",
      "n0222": "apply reload sshd; Error Match can — first dry-run",
      "n0223": "applySystem suspend/autoreply change",
      "n0224": "apply_status=written (Success ≠ system MTA; add applySystem:true firstapply)",
      "n0225": "apps/web/dist exists",
      "n0226": "apt list --upgradable: (can update or apt not Ready)",
      "n0227": "apt Install failed",
      "n0228": "apt-get Available",
      "n0229": "auto vacuum disable",
      "n0230": "blocked: requires HostExecutor + YSK_EXECUTE=1",
      "n0231": "bootstrap: Node Failed",
      "n0232": "bootstrap: apt Failed",
      "n0233": "bootstrap key stepsFailed",
      "n0234": "candidateVersion not",
      "n0235": "cargo / rustc",
      "n0236": "certbot exit 0 — check /etc/letsencrypt/live/",
      "n0237": "chown requires YSK_EXECUTE + root",
      "n0238": "clone (YSK scaffold / stub)",
      "n0239": "cluster_size Unknown or 0",
      "n0240": "command ysk-server / ysk-server",
      "n0241": "control plane filecomplete",
      "n0242": "cwd can",
      "n0243": "dataDir",
      "n0244": "dataDir ysk.json — Statuscomplete",
      "n0245": "dataDir/email exists",
      "n0246": "dataDir/web exists",
      "n0247": "database Not found:",
      "n0248": "db-util (FTP user database)",
      "n0249": "deployNode Node project",
      "n0250": "df Available mount ( or )",
      "n0251": "dig unavailable, node dns",
      "n0252": "dig: no answer (NXDOMAIN or empty)",
      "n0253": "dns-01: panel TXT — done\" SSL\"",
      "n0254": "dnssec-dsfromkey not DS",
      "n0255": "dnssec-keygen PATH (apt install bind9-dnsutils)",
      "n0256": "dnssec-keygen failed",
      "n0257": "dnssec-signzone unavailable — keptkey/DS",
      "n0258": "dnssec-signzone not.signed",
      "n0259": "domain",
      "n0260": "domain Not found:",
      "n0261": "dovecot reload failed or servicenot (sieve Wrote; reload Success)",
      "n0262": "dry-run fleet dispatch (not queued)",
      "n0263": "dry-run peer push (not scp)",
      "n0264": "dry-run remote install (not ssh)",
      "n0265": "dry-run transfer done ( full bootstrap)",
      "n0266": "dry-run — pass apply/execute home",
      "n0267": "dry-run — pass apply/execute really ssh",
      "n0268": "dry-run — not write /etc",
      "n0269": "dry-run: add --execute firstapply ufw",
      "n0270": "dry-run: inventory + preflight passed, not package/transfer",
      "n0271": "Dry-run: probe/plan only. Pass --execute with YSK_EXECUTE=1 to actually provision.",
      "n0272": "Dry-run: wrote the managed file (dataDir). Pass --execute with YSK_EXECUTE=1 as root to install the system drop-in.",
      "n0273": "Dry-run: not banned. Pass --execute with YSK_EXECUTE=1 to actually ban.",
      "n0274": "Dry-run: not unbanned. Pass --execute with YSK_EXECUTE=1 to actually unban.",
      "n0275": "dryRun=true — change API",
      "n0276": "dryRun: not write",
      "n0277": "dump Wrote dataDir, not transfer",
      "n0278": "enable failed",
      "n0279": "execute ( YSK_EXECUTE=1 + root)",
      "n0280": "execute requires enqueue",
      "n0281": "export admin",
      "n0282": "fail2ban applyFailed",
      "n0283": "fail2ban service",
      "n0284": "fail2ban not active",
      "n0285": "fail2ban not",
      "n0286": "fail2ban",
      "n0287": "fail2ban StatusRead failed",
      "n0288": "fail2ban: sshd, nginx-http-auth and standard jails",
      "n0289": "fd unavailable",
      "n0290": "files (file)",
      "n0291": "fleet purge blocked — enqueue or SSH",
      "n0292": "fleet please db-cluster fleet --op probe --execute",
      "n0293": "fromPanel admin",
      "n0294": "fromPanel requires step-up: POST /api/v1/auth/totp/step-up",
      "n0295": "fullchain PEM certificate",
      "n0296": "gateway for IP",
      "n0297": "geo apex: EDNS write geo edge multi-A (·user Anycast)",
      "n0298": "geoMap edge — edge",
      "n0299": "geo: not settings geoMap — etc multi_a ( edge). please dns.geoMap region→nodeIds",
      "n0300": "git binary Not found: on PATH",
      "n0301": "git binary",
      "n0302": "go binary",
      "n0303": "healthUrl http(s) URL",
      "n0304": "http-01 webroot — 80 can ACME conf fan-out",
      "n0305": "identity not linuxUser/project — cannot authorized_keys",
      "n0306": "ignoreip: dataDir/fail2ban/ignoreip.txt",
      "n0307": "index.html + CSS, Nginx root or",
      "n0308": "install conf → systemctl restart mariadb (not bootstrap node)",
      "n0309": "ip -j addr interface",
      "n0310": "job manifest",
      "n0311": "journal; can permission",
      "n0312": "journalctl can requires root or user systemd-journal/adm",
      "n0313": "key",
      "n0314": "Key missing or not deleted",
      "n0315": "kill -0 Success: can for zombie or permission",
      "n0316": "kill -0 failed",
      "n0317": "Apply failed on host",
      "n0318": "Apply blocked on host",
      "n0319": "local cache directory/",
      "n0320": "localhost or *",
      "n0321": "logical DB 0... N-1; restart",
      "n0322": "logrotate Installed",
      "n0323": "logrotate Not installed or PATH",
      "n0324": "main.py — skipped",
      "n0325": "manage.py + minimal settings/urls/wsgi; pip install django",
      "n0326": "manifest dumpRelPath — not ？",
      "n0327": "manifest rdbRelPath",
      "n0328": "memoryMax 512M or 1G",
      "n0329": "migrate host --execute + YSK_EXECUTE=1, or --dry-run ( inventory+preflight)",
      "n0330": "migrate post --execute YSK_EXECUTE=1 ( target)",
      "n0331": "migrate post Requires YSK_EXECUTE=1",
      "n0332": "migrate post Requires YSK_EXECUTE=1 ( target)",
      "n0333": "minimal bootstrap failed",
      "n0334": "mysql / mariadb client",
      "n0335": "mysql-replica Supports mysql",
      "n0336": "mysql_databases name",
      "n0337": "named-checkzone PATH — Wrote, not verify",
      "n0338": "nginx -t or reload failed",
      "n0339": "nginx -t not passed, not reload",
      "n0340": "nginx reload ok · Status: applied",
      "n0341": "nginx reload failed",
      "n0342": "nginx binary",
      "n0343": "nginx not found",
      "n0344": "nginx service",
      "n0345": "Binary not on PATH; service cannot become ready",
      "n0346": "node can",
      "n0347": "npm latest Missingversion",
      "n0348": "npm exit 0 Not found binary — packagecan not CLI or PATH not update",
      "n0349": "nullok not user",
      "n0350": "nullok:.google_authenticator userAvailable key",
      "n0351": "open_basedir path",
      "n0352": "openssl unavailable, YSK-SCRYPT hash",
      "n0353": "openssl binary",
      "n0354": "optionalEtc Failed transfer (can targetcertificate)",
      "n0355": "origin shield: thisnode for shield, origin",
      "n0356": "origin.kind project or url",
      "n0357": "origin.project requires projectId",
      "n0358": "origin.url http(s) URL",
      "n0359": "originShieldNodeId edgeNodeIds",
      "n0360": "package dump Incomplete — transfer",
      "n0361": "package Failed — transfer",
      "n0362": "package Requires YSK_EXECUTE=1",
      "n0363": "pam.d/sshd not pam_google_authenticator (not enforce)",
      "n0364": "panel not settings 2FA or secret — please first \"\" TOTP",
      "n0365": "panel TOTP secret — first Web 2FA or --from-panel",
      "n0366": "panel login Failedwritecan fail2ban log (journal or )",
      "n0367": "passkey",
      "n0368": "passkey Failed",
      "n0369": "passkey Success",
      "n0370": "pdnsutil Not found: — install PowerDNS tools or run helper script as root after install",
      "n0371": "peer SSH probe YSK_EXECUTE=1 (local)",
      "n0372": "peer Not probed ( probe local)",
      "n0373": "peer nodeapply conf and join",
      "n0374": "php binary Not found: — install php-cli",
      "n0375": "php binary",
      "n0376": "php not PATH",
      "n0377": "pidfile with userstart(degraded)",
      "n0378": "pidfile startnot pid",
      "n0379": "pm2 PATH (Available pidfile/systemd)",
      "n0380": "pm2 Not found: on PATH — install: npm i -g pm2",
      "n0381": "post-transfer reapply",
      "n0382": "post-transfer restore",
      "n0383": "postconf not message_rate_limit (complete applied)",
      "n0384": "kind postgres-replica needs --engine postgres",
      "n0385": "postgres_databases name",
      "n0386": "postqueue unavailable or mailNot installed",
      "n0387": "Install nginx on the host, or use panel software / runtime install",
      "n0388": "Install nginx on the system, or use panel software / runtime install",
      "n0389": "privkey PEM",
      "n0390": "productionReady not (datacan )",
      "n0391": "ps",
      "n0392": "ps Degraded: --sort/",
      "n0393": "ps Degraded: pri/vsz/stat etc",
      "n0394": "psql client",
      "n0395": "purge Failed or target",
      "n0396": "python3 binary",
      "n0397": "queued ≠ edge purge",
      "n0398": "queued ≠ edge reload — agent and cdn.edge.apply",
      "n0399": "queued ≠ edge — Agents exit/JSON",
      "n0400": "realpath",
      "n0401": "realpath",
      "n0402": "reapply Requires YSK_EXECUTE=1",
      "n0403": "redis clusterSupports redis",
      "n0404": "registry shasum not sha256 (npm sha1)— with npm integrity for",
      "n0405": "reload/restart failed",
      "n0406": "remote post Failed — can target migrate post",
      "n0407": "restic backupdone (written/applied restic exit)",
      "n0408": "restic is enabled but password is not set — denypassword (please backupsettings)",
      "n0409": "restic not",
      "n0410": "restic not — cannot snapshots",
      "n0411": "restic not — please first \"/\"enable and settings password",
      "n0412": "restic disabled (tar only)",
      "n0413": "restic not (skipped)",
      "n0414": "restic Not installed ( PATH), please systeminstall restic",
      "n0415": "restore ok; reapply/verify",
      "n0416": "restore done",
      "n0417": "restore Failed",
      "n0418": "restore not Success",
      "n0419": "restore Requires YSK_EXECUTE=1",
      "n0420": "restore+reapply ok; verify",
      "n0421": "rsync dataDir failed",
      "n0422": "rsync Requires YSK_EXECUTE=1",
      "n0423": "scp Wrotecannot reload: rndc/named/bind9/pdns",
      "n0424": "scp Success ≠ peer restart / join",
      "n0425": "secrets key Available",
      "n0426": "secrets master key",
      "n0427": "sentinel not sentinel",
      "n0428": "sentinel: INFO replication; please sentinel masters",
      "n0429": "server IP IPv4",
      "n0430": "server IPv6 Invalid",
      "n0431": "setquota PATH — (deploy du )",
      "n0432": "shell pathinvalid",
      "n0433": "signal for TERM | KILL | HUP | USR1",
      "n0434": "ssh true succeeded → verified",
      "n0435": "sshd keyboard-interactive / challenge-response enable",
      "n0436": "sshd can not KbdInteractiveAuthentication — TOTP cannot SSH",
      "n0437": "sshpass Available (password)",
      "n0438": "strict Match Wroteuser (password off)",
      "n0439": "symlink path",
      "n0440": "symlink log directory",
      "n0441": "symlink project home",
      "n0442": "systemctl Failed",
      "n0443": "systemd Failed — PM2/pidfile",
      "n0444": "systemd not: Host execute permission required and admin",
      "n0445": "target: user@host or user@host:port",
      "n0446": "token",
      "n0447": "token",
      "n0448": "top -b unavailable ( with ps for )",
      "n0449": "transfer: dataDir rsync Failed",
      "n0450": "transfer: cannotcreatedirectory",
      "n0451": "transfer done ( full bootstrap)",
      "n0452": "transfer Completed, target restore/reapply/verify Failed",
      "n0453": "transfer Failed",
      "n0454": "transfer Failed",
      "n0455": "transfer Requires YSK_EXECUTE=1",
      "n0456": "transfer/bootstrap failed",
      "n0457": "ufw Failed",
      "n0458": "unit and action",
      "n0459": "useradd requires YSK_EXECUTE + root",
      "n0460": "value ( 256KB)",
      "n0461": "verify off",
      "n0462": "verify not passed — for done",
      "n0463": "verify passed — job=done",
      "n0464": "vsftpd Start failed",
      "n0465": "vsftpd not Successstart",
      "n0466": "weighted: edge",
      "n0467": "wp-config.php — skipped",
      "n0468": "written ≠ Dovecot Pigeonhole — ManageSieve or symlink to user sieve",
      "n0469": "written ≠ Roundcube — enableSystem or symlink",
      "n0470": "Written ≠ applied: sync to system conf.d, run nginx -t, then reload",
      "n0471": "written ≠ can — reverse proxy to panel /webdav",
      "n0472": "written ≠ processreload",
      "n0473": "ysk-server CLI Install failed — can npm i -g ysk-server",
      "n0474": "ysk-web Nginx/www-data (not world-readable)",
      "n0475": "ysk-web YSK_EXECUTE + root ( Nginx can cannot 750 home)",
      "n0476": "ysk.json fingerprint (can reapply )local≠source",
      "n0477": "ysk.json fingerprint and",
      "n0478": "ysk.json fingerprint and ( bind_ip )",
      "n0479": "ysk.json",
      "n0480": "ysk.json Failed",
      "n0481": "zone apply blocked ( EXECUTE)— update",
      "n0482": "zone rectify done",
      "n0483": "zone invalid",
      "n0484": "zone Not found:",
      "n0485": "zone Failed",
      "n0486": "Binlog format",
      "n0487": "install",
      "n0488": "createdone (draft please to page \"apply\")",
      "n0489": "and POST",
      "n0490": "Last full backup had failures",
      "n0491": ": write conf → apply edges → DNS ( and can SSL)",
      "n0492": ": PAM /etc/pam.d/sshd (nullok)",
      "n0493": ": systeminstall libpam-google-authenticator + PAM ()",
      "n0494": "can deletedirectory",
      "n0495": "can deletedirectory or path",
      "n0496": "",
      "n0497": "thisoperation",
      "n0498": "Supports (allow TERM / KILL / HUP / USR1)",
      "n0499": "data",
      "n0500": "delete admin",
      "n0501": "portinvalid",
      "n0502": "Applied to system",
      "n0503": "settingsWrote dataDir (apply to systemenablesystemchange)",
      "n0504": "Host memory usage is over 90%",
      "n0505": "Host metrics",
      "n0506": "Main InnoDB data cache",
      "n0507": "Binary is not on PATH; the service cannot become ready",
      "n0508": "Binlog expire (seconds)",
      "n0509": "Interactive timeout",
      "n0510": ": firewall, mail PTR/rDNS, kept",
      "n0511": "vacuum",
      "n0512": "to Cron page \"install to system crontab\"willreally",
      "n0513": "with Nginx root or \"\" public/",
      "n0514": "Start the ysk-server service as root (systemctl / control-plane unit)",
      "n0515": "Start as root and set YSK_EXECUTE=1 (see host settings / deploy docs)",
      "n0516": "with user (degraded — not project Linux user)",
      "n0517": "shell — deny",
      "n0518": "Slow query log",
      "n0519": "serverNot installed (command -v )",
      "n0520": "Long query time (seconds)",
      "n0521": "serverNot installed MySQL",
      "n0522": "serverNot installed PostgreSQL",
      "n0523": "serverNot installed Redis",
      "n0524": "serverNot installed, Cannot complete this from the management panel",
      "n0525": "servernot enable YSK_EXECUTE",
      "n0526": "serverHost execute is not enabled or Missing root, cannot paneldoneinstall",
      "n0527": "serverHost execute is not enabled, cannot Redis",
      "n0528": "serverHost execute is not enabled, cannot panelinstall Webmail",
      "n0529": "serverHost execute is not enabled, cannotdoneapply",
      "n0530": "serverHost execute is not enabled, cannotcreate SSH connection",
      "n0531": "serverHost execute is not enabled, cannot dump",
      "n0532": "Host execute is off; the panel cannot finish system-level operations",
      "n0533": "serverHost execute is not enabled: Wrote managed file, cannot named-checkzone / reload",
      "n0534": "TCP port the server listens on",
      "n0535": "for",
      "n0536": "",
      "n0537": "YSK-SCRYPT hash ( for openssl hash)",
      "n0538": "YSK_SECRETS_KEY",
      "n0539": "baseUrl/.ysk-cdn-health path (C2 can health location)",
      "n0540": "version (latestOverride)",
      "n0541": "YSK_LATEST_VERSION (/)",
      "n0542": "unavailable",
      "n0543": "mysqldump — package cannot MySQL",
      "n0544": "pg_dump — package cannot Postgres",
      "n0545": "redis-cli — package cannot Redis RDB",
      "n0546": "sshpass",
      "n0547": "requires rsync (Not installed)",
      "n0548": "not passed",
      "n0549": "passed",
      "n0550": "128M, 256M, 512M, -1 ()",
      "n0551": "e.g. 512MiB; leave empty to unset",
      "n0552": "900 1 300 10; disable",
      "n0553": "Paste a session UUID from /agents on the cluster form, or CLI --member 10.0.0.3=replica:fleet:SESSION_UUID",
      "n0554": "= ASN (system), not",
      "n0555": "22/80/443; can offnot port",
      "n0556": "kept: 10",
      "n0557": "ysk-server process.pid",
      "n0558": "",
      "n0559": "detect to pam_google_authenticator",
      "n0560": "Backup tar succeeded but remote/restic had issues",
      "n0561": "admin",
      "n0562": "admin impersonate",
      "n0563": "admin can operation",
      "n0564": "apex A",
      "n0565": "Listed managed confs (not written to system)",
      "n0566": "write PM2 settings, not start",
      "n0567": "writemanaged file (not reload)",
      "n0568": "writemanagesettings — Ready and reload",
      "n0569": "write (not enable)",
      "n0570": "(apply:false); password",
      "n0571": "Supports postgres + postgres-replica",
      "n0572": "Supports redis + redis-replica|redis-sentinel",
      "n0573": ", HIT",
      "n0574": "stub resolv (127.0.0.53); DNS please resolvectl",
      "n0575": "Warning, can",
      "n0576": "for; / CDN edge access log cache status",
      "n0577": "willwrite systemd Environment / process env",
      "n0578": "allow URL include",
      "n0579": "allow URL file",
      "n0580": "allowfile",
      "n0581": ": + / + (enrich)+ ASN; city policyoff",
      "n0582": "edge fan-out applied",
      "n0583": "edge fan-out Failed",
      "n0584": "edge purge Success",
      "n0585": "peer nameserver reload",
      "n0586": "peer reload failed — filecan not",
      "n0587": "peer Failed",
      "n0588": "peer: zone and remote reload Success",
      "n0589": "All succeeded",
      "n0590": "All skipped (no backupable home) — not treated as failure",
      "n0591": "",
      "n0592": "RDB, restore",
      "n0593": "Other runtime variables",
      "n0594": "",
      "n0595": "or",
      "n0596": "— manualapply\"\" (Never automatic)",
      "n0597": "Score is very high — emergency preset needs manual confirmation (never automatic)",
      "n0598": "directory",
      "n0599": "process",
      "n0600": "delete default confirmDefault: true",
      "n0601": "deletefile or directory",
      "n0602": "deletesystemuser — deny",
      "n0603": "delete: Host execute is not enabled, path managedata directory",
      "n0604": "to fail2ban apply and enable service",
      "n0605": "to page enable (soft/normal)",
      "n0606": "Hardened",
      "n0607": "or",
      "n0608": "Under attack",
      "n0609": "21 and PASV",
      "n0610": "Write panel file only",
      "n0611": "Can apply to system",
      "n0612": "can dataDir/clusters/<id>/",
      "n0613": "You can view settings; install, restart, and writing system settings need host execute permission",
      "n0614": "can \"\" or \"add\"",
      "n0615": "Install and configure Postfix from Email",
      "n0616": "can: SSL, WP-CLI,",
      "n0617": "",
      "n0618": "allowrestore to.restic-restore-* directory",
      "n0619": "Start, stop, restart, enable on boot",
      "n0620": "startprocessnot process",
      "n0621": "OPcache",
      "n0622": "SSL",
      "n0623": "Active",
      "n0624": "file",
      "n0625": "file",
      "n0626": "node wsrep, HA ≥2 node",
      "n0627": "\"\"create MySQL ( or DB) and WP_DB_*",
      "n0628": "domain — kept domain-level vacation",
      "n0629": "Invalid domain",
      "n0630": "domainStatus: active ()",
      "n0631": "domainStatus: suspended (; etc Postfix )",
      "n0632": "Port, bind address, connection limits",
      "n0633": "portcheckAbnormal",
      "n0634": "Runtime",
      "n0635": "Require secure transport (TLS)",
      "n0636": "(.gz etc)",
      "n0637": "Bot",
      "n0638": "probe",
      "n0639": "Last resort when out of control",
      "n0640": "package",
      "n0641": "packageinstallnot: Host execute permission required",
      "n0642": "packageupdaterequiressystemadminpermission",
      "n0643": "apply to vsftpd",
      "n0644": "apply to system",
      "n0645": "applywillmanaged file; YSK_EXECUTE=1 + root applied",
      "n0646": "",
      "n0647": "intern (MB)",
      "n0648": "password",
      "n0649": "Error, please apply",
      "n0650": "Enable admin 2FA under Security → My security, then add a backup admin on Users.",
      "n0651": "and path",
      "n0652": "install PAM",
      "n0653": "install vsftpd",
      "n0654": "Install failed",
      "n0655": "installpackage",
      "n0656": "installdone",
      "n0657": "install",
      "n0658": "installsystemsettings",
      "n0659": "",
      "n0660": "",
      "n0661": "password",
      "n0662": "password SQL CHANGE_ME",
      "n0663": "Password stored as crypt hash (not plaintext)",
      "n0664": "password for",
      "n0665": "passwordrequires sshpass",
      "n0666": "passwordrequireslocalinstall sshpass",
      "n0667": "passwordrequires 8",
      "n0668": "password ( 8 )— createnot writehash",
      "n0669": "passwordsettings",
      "n0670": "etc",
      "n0671": "and please",
      "n0672": "deny",
      "n0673": "Writes NODE_OPTIONS=--max-old-space-size=N",
      "n0674": "write Nginx drop-in",
      "n0675": "write home ≠ PAM",
      "n0676": "Write failed",
      "n0677": "write",
      "n0678": "writefile",
      "n0679": "",
      "n0680": "Include to sshd_config, or POST /api/v1/sftp/sshd-snippet/apply install",
      "n0681": "Project Linux user isolation",
      "n0682": "project id",
      "n0683": "project id invalid, cannot home",
      "n0684": "project id, cannotsystemuser",
      "n0685": "project internal-sftp Match user interactive shell — TOTP SSH shell/scp",
      "n0686": "project managed log invalid",
      "n0687": "project",
      "n0688": "project or not settings home",
      "n0689": "projectcannotsystemuser",
      "n0690": "project",
      "n0691": "project (503)",
      "n0692": "projectCreate failed,",
      "n0693": "project domain — please firstsettingsdomain",
      "n0694": "project linux_user",
      "n0695": "project purge host nginx cache directory (not per-vhost zone)",
      "n0696": "projectMissing linuxUser — cannotcreate FTP",
      "n0697": "projectMissing linux_user",
      "n0698": "project; ＝",
      "n0699": "Project detail → Resources → create system user / migrate to /home/ysk-server-{id} (needs YSK_EXECUTE + root)",
      "n0700": "jail",
      "n0701": "Home directory missing or not under project isolation layout",
      "n0702": "not GeoIP — please \"IP \"update",
      "n0703": "not port, please firstproject",
      "n0704": "not to system Nginx (managed file)",
      "n0705": "not servercreate Redis, please redis-cli, TCP and YSK_EXECUTE=1",
      "n0706": "Not applied to vsftpd service — please \"apply\" or vsftpd servicepage donestart",
      "n0707": "Not appliedmaildomain",
      "n0708": "not Web interface — API",
      "n0709": "not GeoIP — please update",
      "n0710": "not DNSSEC key",
      "n0711": "not CDN node",
      "n0712": "not passkey",
      "n0713": "not (package will)",
      "n0714": "not settings LLM connection",
      "n0715": "not zone: please panel",
      "n0716": "CDN",
      "n0717": "No managed Nginx conf yet",
      "n0718": "Available HIT/MISS — overall hit-rate Unknown",
      "n0719": "No projects yet",
      "n0720": "— please first plan",
      "n0721": "Ready",
      "n0722": "and cookie",
      "n0723": "enable --now fail2ban",
      "n0724": "galera_new_cluster (bootstrap)",
      "n0725": "Reloaded fail2ban",
      "n0726": "reload nginx",
      "n0727": "Restarted fail2ban",
      "n0728": "scp zone (written on peer ≠ named reloaded)",
      "n0729": "scp to peer /tmp (written on peer ≠ service restarted)",
      "n0730": "systemctl reload nginx",
      "n0731": "and Roundcube",
      "n0732": "Disabled UFW (Warning: hostport)",
      "n0733": "project php.ini; apply FPM/",
      "n0734": "managesettings (Not applied to systemservice)",
      "n0735": "settings (not applysystem)",
      "n0736": "Deleted",
      "n0737": "Deleted key · authorized_keys",
      "n0738": "Deletedcluster; system conf manual (v1 )",
      "n0739": "Deletedlocalkey",
      "n0740": "ip addr add (settingsWrote, reboot )",
      "n0741": "apply databases (restart)",
      "n0742": "off/restart",
      "n0743": "to system and reload",
      "n0744": "start",
      "n0745": "Enabled HSTS",
      "n0746": "NTP synchronization enabled",
      "n0747": "Enabled UFW",
      "n0748": "Enabled WebDAV · Basic user ysk · password for token ()",
      "n0749": "Enabled systemd service",
      "n0750": "stop redis",
      "n0751": "nginx cache directory and reload (hostnot proxy_cache can )",
      "n0752": "serverdonecertificateplease",
      "n0753": "Applied CF-only UFW (origin CF + keptport)",
      "n0754": "Applied fail2ban",
      "n0755": "Appliedsettings to system Postfix",
      "n0756": "Applied to system Nginx",
      "n0757": "Appliedfirewallrule",
      "n0758": "Installed and ysk-server.service",
      "n0759": "Installed to user system crontab",
      "n0760": "Wrote.google_authenticator ( 5 scratch codes)",
      "n0761": "Wrote rspamd multimap + postfix snippet",
      "n0762": "Wroteinstall",
      "n0763": "Wrote; please \"applylimits to OS\" or Deploy write unit",
      "n0764": "Wrote management jail.local (not applied to system)",
      "n0765": "Written to managed files; not yet applied to system conf.d",
      "n0766": "Wrote settings (not package)",
      "n0767": "Wrote; projectwillprocess",
      "n0768": "Wrotemanaged file, Not appliedsystem conf: YSK_EXECUTE=1",
      "n0769": "Wrotemanaged file, Not appliedsystem conf: requires root",
      "n0770": "block: candidateVersion",
      "n0771": "block: update",
      "n0772": "block: Administrator permission required",
      "n0773": "create DNSSEC directory ()",
      "n0774": "from",
      "n0775": "from (disk install not; uninstall --purge)",
      "n0776": "from; systemaccount DROP USER (: not drop)",
      "n0777": "from connection",
      "n0778": "deny",
      "n0779": "deny by allowlist",
      "n0780": "deny: raisetarget",
      "n0781": "scan nginx access log",
      "n0782": "MySQL/MariaDB createuser",
      "n0783": "PostgreSQL create",
      "n0784": "version ()",
      "n0785": "",
      "n0786": "",
      "n0787": "catch-all",
      "n0788": "DS (please registrar — panelwill)",
      "n0789": "addbackup ( dataDir master key can )",
      "n0790": "SHA512-CRYPT hashpassword (Dovecot)",
      "n0791": "skipped Nginx settingscheck (Not installed or not systemchangepermission)",
      "n0792": "certificatepath (file /etc/ysk-server/certs)",
      "n0793": "UA",
      "n0794": "",
      "n0795": "",
      "n0796": "Removed",
      "n0797": "Removed",
      "n0798": ",",
      "n0799": "version = apt Candidate, Availableraise",
      "n0800": "Copied to /etc/fail2ban/jail.local",
      "n0801": "(filenot; can uninstall)",
      "n0802": "restart",
      "n0803": "off",
      "n0804": "restart postgresql",
      "n0805": "restart redis-server",
      "n0806": "restart redis-server with applyrestart",
      "n0807": "restart (reload)",
      "n0808": "Connection re-enabled (persists after reboot)",
      "n0809": "TLS edge conf ()",
      "n0810": "Nginx reloaded (static site live if DNS points here)",
      "n0811": "Nginx reloaded",
      "n0812": "System change permission is on (YSK_EXECUTE)",
      "n0813": "password — Roundcube can login",
      "n0814": "manage; systempermission FTP service",
      "n0815": "account (usermod -U)",
      "n0816": "account (usermod -L)",
      "n0817": "pathscan",
      "n0818": "this IP",
      "n0819": "createsystemuserrequiressystemadminpermission",
      "n0820": "createmaildomain and page apply",
      "n0821": "done",
      "n0822": "\"\"",
      "n0823": "Review SSH and non-essential ports",
      "n0824": "",
      "n0825": "1 replica; can primary conf",
      "n0826": "2 node ( 3); can",
      "n0827": "Consider CDN Under Attack mode",
      "n0828": "enable ban",
      "n0829": "HTTPS (HTTP→301)",
      "n0830": "Default authentication plugin",
      "n0831": "",
      "n0832": ": status=active",
      "n0833": "Error log path",
      "n0834": "(ms)",
      "n0835": "General log",
      "n0836": "certificateplease Failed",
      "n0837": "≥ file",
      "n0838": "settingskeptbackup",
      "n0839": "Success means this target accepts BatchMode SSH (non-interactive). It is not a grant of global access.",
      "n0840": "or 32767",
      "n0841": "softwareInstalled",
      "n0842": "permission/",
      "n0843": "",
      "n0844": "Not found CLI binary — systemd will enable silent placeholder",
      "n0845": "Not found DNS zone — please dns.zoneId, or firstcreatedomain zone",
      "n0846": "Not found PowerDNS — please install pdns-server / pdns-tools",
      "n0847": "Not found Roundcube plugins directory — Wrote; please install Roundcube or roundcubePluginsDir",
      "n0848": "Not found SQL",
      "n0849": "Not found Sieve",
      "n0850": "Not found config.inc.php — please: $config[\\'plugins\\'][] = \\'ysk_sso\\';",
      "n0851": "Not found edge.conf — please first",
      "n0852": "Not found: key",
      "n0853": "Not found: migrate job",
      "n0854": "Not found pm2 — cannot with PM2 stop",
      "n0855": "Not found",
      "n0856": "Cluster not found",
      "n0857": "Not foundcan reload local nameserver (rndc/named/bind9/pdns)",
      "n0858": "Not foundAvailablecertificate — please first SSL page, or LE",
      "n0859": "Not foundAvailable NetworkManager connection",
      "n0860": "Not found",
      "n0861": "Not found",
      "n0862": "Project not found access log — please nginx access_log path or log",
      "n0863": "Not found",
      "n0864": "Not found",
      "n0865": "Not foundversion",
      "n0866": "Not foundnode",
      "n0867": "Not founddatabase",
      "n0868": "deny",
      "n0869": "deny down loopback",
      "n0870": "deny renice",
      "n0871": "deny systemctl enable: Not installed agent CLI ( placeholder running)",
      "n0872": "deny loopback ()",
      "n0873": "denydelete loopback",
      "n0874": "deny homeDir — please overwriteHome + confirmPhrase or targetdirectory",
      "n0875": "deny PID 1 (init/systemd )",
      "n0876": "deny ysk; can forceControlPlane",
      "n0877": "deny (ysk-server); requiresplease forceSelf",
      "n0878": "denyreadpath",
      "n0879": "denypath or not",
      "n0880": "persist default requires Gateway",
      "n0881": "Persistence",
      "n0882": "for",
      "n0883": "Command blocked: host change requires system-change permission (YSK_EXECUTE)",
      "n0884": "scan",
      "n0885": "scanpath",
      "n0886": "probe INFO replication",
      "n0887": "probe SHOW MASTER / REPLICA STATUS",
      "n0888": "probe pg_is_in_recovery / pg_stat_replication",
      "n0889": "probe wsrep (SHOW STATUS LIKE 'wsrep%')",
      "n0890": "Control plane wrote config but it is not applied on the host — use Apply on each feature page",
      "n0891": "Control plane stays in normal mode",
      "n0892": "Control-plane emergency degrade (local ops)",
      "n0893": "Control-plane data directory",
      "n0894": "Control plane enters ddos-protection hint",
      "n0895": "complete (partial/failed)",
      "n0896": "Faster auth when clients use IPs only",
      "n0897": ": Cloudflare zones + CF_API_TOKEN firstcan Under Attack API",
      "n0898": "cannotdone",
      "n0899": "Nginx and fail2ban",
      "n0900": "Performance & resources",
      "n0901": "IP/domain. please check Spamhaus etc, and.",
      "n0902": "A/AAAA (apex and www)",
      "n0903": "DMARC TXT",
      "n0904": "MX/SPF/DKIM DNS",
      "n0905": "_dmarc TXT with and.",
      "n0906": "Method + thresholds",
      "n0907": "DNS MX, SPF (TXT) and DKIM (TXT). Cloudflare: mailoffplease DNS ().",
      "n0908": "Install PowerDNS tools from DNS page",
      "n0909": "Install certbot from SSL page",
      "n0910": "Install fail2ban from Defense Center or the software banner",
      "n0911": "Install and enable UFW from Defense Center",
      "n0912": "Install Redis from the Redis page",
      "n0913": "Install required packages for this check",
      "n0914": "Daily",
      "n0915": "Logs",
      "n0916": "logwriteproject logs directory",
      "n0917": "log",
      "n0918": "log",
      "n0919": "logpathallow",
      "n0920": "log etc",
      "n0921": "logpathinvalid",
      "n0922": "",
      "n0923": "and",
      "n0924": "Table open cache",
      "n0925": "PHP version",
      "n0926": "More fail2ban jails, faster bans",
      "n0927": "please Redis",
      "n0928": "update fail2ban jail (managed file)",
      "n0929": "updateIncomplete",
      "n0930": "Strictest Nginx limits (~1 req/s)",
      "n0931": "12 directory",
      "n0932": "8 nameserver",
      "n0933": "file",
      "n0934": "",
      "n0935": "WAL",
      "n0936": "",
      "n0937": "",
      "n0938": "Max connect errors",
      "n0939": "",
      "n0940": "HTTP server (/health)+ public directory",
      "n0941": "",
      "n0942": "",
      "n0943": "Availableraise",
      "n0944": "When scans / brute-force appear",
      "n0945": "",
      "n0946": "database/Redis dump Failed, (will transfer)",
      "n0947": "serviceinvalid",
      "n0948": "not WordPress (/)— WORDPRESS_INSTALL.txt",
      "n0949": "not with system unit start (Requires root + )— pidfile",
      "n0950": "not to pam_google_authenticator — apt install libpam-google-authenticator",
      "n0951": "not 2FA",
      "n0952": "Control-plane summary exported only (Nginx not synced)",
      "n0953": "Not applied to system nginx ( YSK_EXECUTE + root)— Status: written",
      "n0954": "Not applied to system: YSK_EXECUTE + root",
      "n0955": "redis-cli is not installed",
      "n0956": "not writefile",
      "n0957": "not systemcan verifychange — will ok",
      "n0958": "not to postgresql conf.d — conf dataDir; willAppliedsystem",
      "n0959": "not to secrets/ssh/.master.key YSK_SECRETS_KEY — targetcan cannot vault/2FA",
      "n0960": "not",
      "n0961": "Not probed",
      "n0962": "not certbot/LE cron (Availablesystem certbot.timer)",
      "n0963": "not nginx conf",
      "n0964": "Unknown passkey",
      "n0965": "Unknown source (journal:... / file:... / project:...)",
      "n0966": "Unknown",
      "n0967": "Unknownsoftware",
      "n0968": "Unknownsoftware ID",
      "n0969": "Unknownsoftware",
      "n0970": "Unknown",
      "n0971": "not, deny ( dump )",
      "n0972": "not project home — write ftps/ssh; sshd Match",
      "n0973": "not applyupdate: please YSK_SOURCE_ROOT git directory, or publish npm package YSK_NPM_PACKAGE",
      "n0974": "not — will\"\"",
      "n0975": "not — will",
      "n0976": "not City Lite — /ASN; updatecan DB-IP ( CC BY)",
      "n0977": "not City Lite — /; please update ( DB-IP)",
      "n0978": "not to /etc/nginx (not root or not EXECUTE)— managed conf dataDir",
      "n0979": "not settings CF_API_TOKEN — cannot Cloudflare API",
      "n0980": "not settings Cloudflare API Token — dry-run",
      "n0981": "not settings (disable)",
      "n0982": "Done",
      "n0983": "not please install to system (installSystem=false)",
      "n0984": "YSK_EXECUTE is not enabled",
      "n0985": "System change is off (control plane can write settings only)",
      "n0986": "not enablesystemchange: cannot dnssec-keygen",
      "n0987": "not password — verify email ()",
      "n0988": "not verify/reload: serverHost execute is not enabled (writemanaged file)",
      "n0989": "conf, please first plan",
      "n0990": "backup",
      "n0991": "zone",
      "n0992": "certificate ( or from not )",
      "n0993": "invalid",
      "n0994": "Ban rate limit reached this hour — check Defense Center",
      "n0995": "local ip can Supports -j; please raise iproute2 ( notes)",
      "n0996": "local nginx -t OK ( managed conf, ≠ edge applied)",
      "n0997": "local wsrep can, size not node",
      "n0998": "local ysk.json cannotread / fingerprint",
      "n0999": "Local node is OK; a complete healthy status needs a peer probe (not done).",
      "n1000": "local nginx — conf Wrote, not reload",
      "n1001": "localAvailable NM connection; willSuccess. can \"\" or NetworkManager.",
      "n1002": "localAvailable ps — cannot ()",
      "n1003": "local NM connection; willSuccess. can \"\" or NetworkManager.",
      "n1004": "can ban",
      "n1005": "invalid",
      "n1006": "serviceStatus",
      "n1007": "Root filesystem usage is over 90%",
      "n1008": "directoryinvalid",
      "n1009": "Root disk space",
      "n1010": "Overview",
      "n1011": "TcpListener ( crate); Cargo.toml",
      "n1012": "net/http; go.mod; / and /health",
      "n1013": "Mode: production ready",
      "modeProductionCapable": "production ready",
      "modeDegraded": "degraded",
      "n1014": ": not",
      "n1015": "Dry-run finished — nothing copied or reloaded (turn off dry-run for real sync)",
      "n1016": "Dry-run finished — real sync needs root and YSK_EXECUTE",
      "n1017": "with.conf",
      "n1018": "with.sieve",
      "n1019": "Files",
      "n1020": "file and POST",
      "n1021": "File does not exist or can",
      "n1022": "File does not exist or Deleted",
      "n1023": "checkprocess; host",
      "n1024": "checkfile",
      "n1025": "check ()",
      "n1026": "check",
      "n1027": "for, cannotwrite",
      "n1028": "permission for 3–4",
      "n1029": "permission and",
      "n1030": "OK",
      "n1031": "Day-to-day operations",
      "n1032": "please SECRET_KEY/DEBUG and configdatabase",
      "n1033": "planner Supports mariadb + mariadb-galera",
      "n1034": "planner Supports mysql + mysql-replica",
      "n1035": "thishost systemd servicemanage",
      "n1036": "thisproject Node runtime, please Node",
      "n1037": "thisproject Node runtime, please Node ( or runtime for static)",
      "n1038": "thisupdate (/). please apply.",
      "n1039": "this for (DNS /IP ); cannot PTR/ 25",
      "n1040": "thisapply to system",
      "n1041": "thissoftware apt package",
      "n1042": "settings;,, limits",
      "n1043": "project with Linux user/active",
      "n1044": "Hourly auto-ban cap",
      "n1045": "(IPinfo Lite)",
      "n1046": "Permanent ban",
      "n1047": "edge node — please first CDN page edge",
      "n1048": "can apply raise ( candidate or and version)",
      "n1049": "projectcan restic",
      "n1050": "projectcan backup (0 )— for Failed",
      "n1051": "can for",
      "n1052": "log/backup; hostsettings",
      "n1053": "firewallrule — deny",
      "n1054": "requires and",
      "n1055": "createsystemuser...",
      "n1056": "browserenabledone WP install",
      "n1057": ".zone can",
      "n1058": "HostExecutor — please chown file",
      "n1059": "HostExecutor — chown (please chown)",
      "n1060": "IP write DNS",
      "n1061": "NM connectioncan;",
      "n1062": "NM connectioncan;",
      "n1063": "Redis dump",
      "n1064": "SQL database dump",
      "n1065": "SSH target",
      "n1066": "SSH/fleet target",
      "n1067": "access log cache status, cache directory — hit-rate Unknown (please log_format or first apply edge)",
      "n1068": "access=fleet fleetAgentId",
      "n1069": "access=ssh — please create:ssh or members",
      "n1070": "Written on control plane; not applied on host",
      "n1071": "apt-get",
      "n1072": "authentication challenge",
      "n1073": "bind_ip",
      "n1074": "dataDir — updatedatabase",
      "n1075": "domain vacation.sieve — skipped per-mailbox",
      "n1076": "edge can apply ( skip/drain)— conf written",
      "n1077": "galera_new_cluster; restart mariadb",
      "n1078": "home_dir",
      "n1079": "install — Status for stored",
      "n1080": "linuxUser",
      "n1081": "master key / YSK_SECRETS_KEY",
      "n1082": "nameserver (can not config)",
      "n1083": "rdbRelPath",
      "n1084": "registration challenge",
      "n1085": "ssh peer",
      "n1086": "ssh peer can",
      "n1087": "sshpass ( key/agent )",
      "n1088": "vacation.sieve can",
      "n1089": "vhost requiresupdate ( or conf server )",
      "n1090": "wsrep Status (can not Galera or servicenot )",
      "n1091": "active jail or fail2ban not running",
      "n1092": "log",
      "n1093": "can system ( written)",
      "n1094": "can target ( healthUrl / baseUrl / publicIpv4)",
      "n1095": "Available access log ( or )",
      "n1096": "Available access log (Available / ban)",
      "n1097": "Available access/auth log",
      "n1098": "Available edge IP — DNS (kept managed )",
      "n1099": "Available strict user ( or not )",
      "n1100": "invalid conf",
      "n1101": "Invalid export id",
      "n1102": "invalid export",
      "n1103": "Invalid linux_user",
      "n1104": "Invalid public key",
      "n1105": "Invalid snapshot id",
      "n1106": "Invalid token",
      "n1107": "Invalid unit",
      "n1108": "invalid unit",
      "n1109": "invalid vacuum-size (: 500M)",
      "n1110": "invalid vacuum-time (: 7d)",
      "n1111": "invalidbackup",
      "n1112": "invalidbackup",
      "n1113": "invalidport",
      "n1114": "invalid key",
      "n1115": "invalid projectId",
      "n1116": "invalid backup",
      "n1117": "invalid pattern",
      "n1118": "invalidrule",
      "n1119": "invaliddatabase",
      "n1120": "domain — map for (systemapplywill postmap )",
      "n1121": "IP",
      "n1122": "Available auto-ban enrich",
      "n1123": "Cannot ban on the host: YSK_EXECUTE is off. The panel list was not changed.",
      "n1124": "cannot dump Redis: redis-cli",
      "n1125": "cannot dump: serverHost execute is not enabled",
      "n1126": "cannot fan-out: Host execute is not enabled",
      "n1127": "cannot import: serverHost execute is not enabled",
      "n1128": "cannot list: Host execute is not enabled",
      "n1129": "cannot probe DNS cluster: Host execute is not enabled",
      "n1130": "cannot probe: Host execute is not enabled (SSH EXECUTE)",
      "n1131": "cannot purge cache: Host execute is not enabled (YSK_EXECUTE)",
      "n1132": "cannot purge: Host execute is not enabled",
      "n1133": "cannot remote reload: Host execute is not enabled",
      "n1134": "cannot restic: Host execute is not enabled",
      "n1135": "cannot restore: Host execute is not enabled",
      "n1136": "cannot scp: YSK_EXECUTE=1",
      "n1137": "cannot stat home",
      "n1138": "cannot symlink: Host execute is not enabled",
      "n1139": "cannot unban: Host execute is not enabled",
      "n1140": "cannot unban: YSK_EXECUTE",
      "n1141": "cannot Adminer: Host execute is not enabled",
      "n1142": "cannot WordPress: serverHost execute is not enabled",
      "n1143": "cannot PM2, localprocessmanage",
      "n1144": "cannot: not enable YSK_EXECUTE",
      "n1145": "cannotstop PM2: serverHost execute is not enabled",
      "n1146": "cannot SSL: Host execute is not enabled",
      "n1147": "Sync blocked: needs YSK_EXECUTE",
      "n1148": "cannot to system Nginx: Host execute permission required",
      "n1149": "cannotstart PM2: serverHost execute is not enabled",
      "n1150": "cannot Apache: Host execute permission required",
      "n1151": "cannot NTP: Host execute permission required and root",
      "n1152": "cannot PHP-FPM: requiressystemadminpermission",
      "n1153": "cannot systemd service (please permission)",
      "n1154": "cannot systemd service: requiressystemadminpermission",
      "n1155": "cannotservice: requiressystemadminpermission",
      "n1156": "cannot targetinstall rsync, target rsync",
      "n1157": "cannot systemcreateaccount: requires YSK_EXECUTE + root; (written/blocked)",
      "n1158": "cannot certbot: Host execute is not enabled",
      "n1159": "cannotoperation: Host execute permission required (YSK_EXECUTE) and root",
      "n1160": "cannotapply to system: requires YSK_EXECUTE + root",
      "n1161": "cannotapplysystemsettings: Host execute permission required",
      "n1162": "cannotapply: Failed",
      "n1163": "cannotinstall PowerDNS: requiressystemadminpermission",
      "n1164": "cannotinstall to /etc/ssh: requires YSK_EXECUTE + root",
      "n1165": "cannotinstall to system: serverHost execute is not enabled (writemanaged file)",
      "n1166": "cannot: serverHost execute is not enabled or Not installedmailservice",
      "n1167": "cannotcreate virtual user database ( db_load)",
      "n1168": "cannotcreatedatabase, can Failed",
      "n1169": "cannotcreatesystemmailuser: requiressystemadminpermission",
      "n1170": "cannot from npm or GitHub version (not )",
      "n1171": "cannotprobe systemctl",
      "n1172": "cannot DNS cluster: Host execute is not enabled",
      "n1173": "Host execute is off. Live SFTP/S3/local probe needs YSK_EXECUTE=1.",
      "n1174": "cannot metrics",
      "n1175": "cannot: serverHost execute is not enabled",
      "n1176": "cannot ACME: Host execute is not enabled",
      "n1177": "cannot crypt passwordhash (requires openssl passwd)",
      "n1178": "cannot: serverHost execute is not enabled",
      "n1179": "cannot Tasks (ps state Failed)",
      "n1180": "cannot zone to dnssec directory",
      "n1181": "cannot ysk.json fingerprint",
      "n1182": "cannot /etc/resolv.conf",
      "n1183": "cannotread cmdline (can or permission)",
      "n1184": "cannotread numbered rule",
      "n1185": "cannotread statfs",
      "n1186": "cannotread: serverHost execute is not enabled",
      "n1187": "cannotreaduser with check 2FA",
      "n1188": "cannotreadtarget",
      "n1189": "cannotchange UFW: YSK_EXECUTE=1",
      "n1190": "cannotchangehost/: Host execute permission required and root",
      "n1191": "cannotchange: Host execute permission required (YSK_EXECUTE) and root",
      "n1192": "cannot PowerDNS zone: serverHost execute is not enabled",
      "n1193": "cannot IPv4/IPv6",
      "n1194": "cannotconnection 127.0.0.1:6379",
      "n1195": "cannotconnectiontarget",
      "n1196": "",
      "n1197": "No hard blockers in this probe",
      "n1198": "keydirectory",
      "n1199": "user",
      "n1200": "— system sieve",
      "n1201": "createdirectory",
      "n1202": "Circuit breaker",
      "n1203": "Wrote dataDir/security/fail2ban (not to /etc)",
      "n1204": "; please reload",
      "n1205": "Status draft — please to FTP servicepage \"apply\"willwrite vsftpd",
      "n1206": "Status and version",
      "n1207": "Status:",
      "n1208": "Status: applied (anvil + per-sender policy + maps)",
      "n1209": "Status: applied (symlink + config plugins[] Enabled)",
      "n1210": "Status: applied (directory)",
      "n1211": "Status: applied ( homeDir)",
      "n1212": "Status: applied (systemSuccess)",
      "n1213": "Status: applied (key+ zone; not registrar )",
      "n1214": "Status: blocked — managed fileWrote; not Postfix/Dovecot",
      "n1215": "Status: blocked (placeholder written)",
      "n1216": "Status: blocked (policy daemon; systemapply EXECUTE+root)",
      "n1217": "Status: executed ≠, to certbot done reload",
      "n1218": "Status: failed (nginx -t or reload failed)",
      "n1219": "Status: partial — will applied (Success)",
      "n1220": "Status: partial — systemFailed",
      "n1221": "Status: partial (symlink Success; config add plugins)— willcomplete applied",
      "n1222": "Status: preview only",
      "n1223": "Status: written/partial (system/reload/verifynot Success)",
      "n1224": "Status: written/partial (key stepsFailed — applied)",
      "n1225": "Status: written (apply=false; Not applied to system)",
      "n1226": "Status: written (blocked system apply)",
      "n1227": "Status: written (conf Wrote; reload blocked)",
      "n1228": "Status: written ()— edge Not applied; PR-C3 fan-out + nginx -t/reload",
      "n1229": "Status: written (Not applied to system Postfix/Rspamd)",
      "n1230": "Status: written (not to system Nginx; applySystem will try reload)",
      "n1231": "Status: written (manage; live fail2ban-client YSK_EXECUTE, or \"→apply to system\" jail.local)",
      "n1232": "Status: written (key/DS; zone not or not zone )",
      "n1233": "Status: written (not SSO)",
      "n1234": "Status: written (not /not )— Success",
      "n1235": "Status: written (/managed file)",
      "n1236": "Status: Wrote and Success reload nameserver",
      "n1237": "Status: Wrotemanage zone (not for DNS, not reload nameserver)",
      "n1238": "Status: Wrote managed file (Not applied to system)",
      "n1239": "Status: data (not )",
      "n1240": "TOTP ( and panel operator 2FA )",
      "n1241": "panel operator 2FA",
      "n1242": "Lifecycle",
      "n1243": "can off and reload",
      "n1244": "please disable",
      "n1245": "Production gate: not fully met — review the items below",
      "n1246": "Production gate: passed (permissions, Nginx, Node ready)",
      "n1247": "Production isolation: open the project Resources tab to create a Linux user and home",
      "n1248": "user 2–32 [a-z0-9._-]",
      "n1249": "please SSL requiresdomain and",
      "n1250": "limits; path:",
      "n1251": "system; can path",
      "n1252": "",
      "n1253": "Skip DNS name resolve",
      "n1254": "skipped chown (not with root )",
      "n1255": "skipped chown ( YSK_EXECUTE + root)— filecan for user",
      "n1256": "draining node",
      "n1257": "skipped reload: zone verifyFailed",
      "n1258": "remote reload (reload=false)— written ≠ applied",
      "n1259": "usermod (not os_provisioned)",
      "n1260": "skipped zone apply (applyZone=false)— update records",
      "n1261": "Skipped invalid username",
      "n1262": "DDoS — Degradedactive",
      "n1263": "IP: deny",
      "n1264": ": skipped",
      "n1265": "IP/domain and",
      "n1266": "Addresses to bind (0.0.0.0 = all)",
      "n1267": "",
      "n1268": "with localprocess",
      "n1269": "with PHP",
      "n1270": "permission to firewallStatus (not )",
      "n1271": "Not running as root; some system settings cannot be applied",
      "n1272": "target ysk.json Failed",
      "n1273": "target ysk-server CLI — please bootstrap or npm i -g ysk-server",
      "n1274": "target YSK data, forceWipeTarget",
      "n1275": "target rsync",
      "n1276": "for root",
      "n1277": "targetuser",
      "n1278": "target rsync ( bootstrap install)",
      "n1279": "targetrequires sshpass (Not installed)",
      "n1280": "targetFailed",
      "n1281": "targetnot passed",
      "n1282": "targetpassed",
      "n1283": "with.zip",
      "n1284": "really execute + YSK_EXECUTE=1",
      "n1285": "<?",
      "n1286": "skipped: not os_provisioned",
      "n1287": "guest user",
      "n1288": "80/443 can from to (LE HTTP-01)",
      "n1289": "PHP runtime and FPM Ready",
      "n1290": "Port 25",
      "n1291": "Disk, backups, AOF/WAL",
      "n1292": "Low disk space",
      "n1293": "",
      "n1294": "/local, apply geo",
      "n1295": "",
      "n1296": "; 0 = (CLI)",
      "n1297": "; please",
      "n1298": "package",
      "n1299": "How long to keep binary logs",
      "n1300": "invalid",
      "n1301": "edge node",
      "n1302": "hostversion",
      "n1303": "node host invalid",
      "n1304": "nodeinvalid",
      "n1305": "node draining —, Status draining",
      "n1306": "systemapply YSK_EXECUTE + root",
      "n1307": "systemuser (not provision or )",
      "n1308": "System administrator (root)",
      "n1309": "Not root — useradd / systemd / nginx system paths are restricted",
      "n1310": "System change permission",
      "n1311": "System load",
      "n1312": "System software",
      "n1313": "",
      "n1314": "",
      "n1315": "",
      "n1316": "(verifyportcannot)",
      "n1317": "cannotconnection",
      "n1318": "Web",
      "n1319": "rsync",
      "n1320": "ssh",
      "n1321": "ysk.json",
      "n1322": "Missing conf, please first plan",
      "n1323": "Missing dataDir, cannotinstall runtime",
      "n1324": "Missing linuxUser/homeDir",
      "n1325": "Temporary ban",
      "n1326": "keyFailed",
      "n1327": "keyInstall failed",
      "n1328": "VACUUM",
      "n1329": "ban → off ()",
      "n1330": "ban: not enablesystemchange (YSK_EXECUTE)",
      "n1331": "ban",
      "n1332": "Auto switch or manual",
      "n1333": "offdisable",
      "n1334": "IP: deny",
      "n1335": "",
      "n1336": ": Status written — not Dovecot/Pigeonhole ( ManageSieve or symlink)",
      "n1337": "auto-escalated",
      "n1338": "allow path",
      "n1339": "target",
      "n1340": "edge node",
      "n1341": "requiresdomain",
      "n1342": "requiresnode",
      "n1343": "requires (control/origin/edge/dns)",
      "n1344": "and panel operator 2FA",
      "n1345": "remote authorized_keys, update or authorize-self",
      "n1346": "Invalid domain",
      "n1347": "Tmp table size",
      "n1348": "filter/jail systemctl reload fail2ban",
      "n1349": "jail.local Failed",
      "n1350": "See audit log",
      "n1351": "Success (secret )",
      "n1352": "limit_req",
      "n1353": "invalid",
      "n1354": "Sum signals 0–100 → threat level",
      "n1355": "Memory, buffers, concurrency",
      "n1356": "",
      "n1357": "High memory use",
      "n1358": "Memory pressure",
      "n1359": "",
      "n1360": "Memory & V8",
      "n1361": "Max heap table size",
      "n1362": "can for",
      "n1363": "",
      "n1364": "Error to log",
      "n1365": "",
      "n1366": "settings DNS (PTR)",
      "n1367": "settingsmanage; system conf/restartpermission",
      "n1368": "settingsWroteApply failed",
      "n1369": "settingsWroteconnectionRestart failed; please nmcli connection up",
      "n1370": "settingsWroteconnectionFailed, please nmcli connection up",
      "n1371": "settings product ysk-server",
      "n1372": "settingsError ( for )",
      "n1373": "settingsMissing dataDir",
      "n1374": "block TCP 25. please, or SMTP.",
      "n1375": "Score",
      "n1376": ": create, etc CDN",
      "n1377": ": resolver will A —; edge IP or Anycast",
      "n1378": "please CIDR, 192.168.1.10/24",
      "n1379": "please POST /api/v1/ssl/upload or POST /api/v1/ssl/letsencrypt",
      "n1380": "please first CDN node (PR-C1)",
      "n1381": "please first maintenanceAccepted",
      "n1382": "Open Backup ops and check sideResults",
      "n1383": "Open the Backups page for details",
      "n1384": "Open Alerts → apply-status audit",
      "n1385": "Open Defense Center to review signals and switch the protection preset",
      "n1386": "please peer install conf and restart / join",
      "n1387": "Please enter serverName",
      "n1388": "please serverName and upstream",
      "n1389": "please serverName and directory",
      "n1390": "please serverName, directory and FPM socket",
      "n1391": "Please enter zone",
      "n1392": "please zone",
      "n1393": "please host",
      "n1394": "please cluster (≤64)",
      "n1395": "please",
      "n1396": "please user, and",
      "n1397": "please node (unavailable IP)",
      "n1398": "please DNS A/AAAA IP; checkfirewall and mail PTR",
      "n1399": "please XML to hostname, or to DNS host",
      "n1400": "Please specify IP",
      "n1401": "please action or mtu",
      "n1402": "Please specify dataDir",
      "n1403": "Please specify listenHost",
      "n1404": "please zip path",
      "n1405": "please backup",
      "n1406": "please Status (/)",
      "n1407": "please",
      "n1408": "please",
      "n1409": "please settingspath",
      "n1410": "Specify a path and permission",
      "n1411": "Specify a path and version",
      "n1412": "Specify a path and",
      "n1413": "please DKIM",
      "n1414": "please Git URL ( or first projectsettings)",
      "n1415": "please IP",
      "n1416": "please package",
      "n1417": "please package and version",
      "n1418": "please password ( 8 )",
      "n1419": "please",
      "n1420": "please",
      "n1421": "please — Enabled",
      "n1422": "please \"apply to system\" or PHP project (pool php_admin_*)",
      "n1423": "please /etc/default/ufw IPV6=yes",
      "n1424": "Ensure dataDir exists and the process can write to it",
      "n1425": "please nameserver, or \"restore DHCP DNS\"",
      "n1426": "please publicIpv4 / publicIpv6 / healthUrl / baseUrl",
      "n1427": "please",
      "n1428": "please file",
      "n1429": "please limits IP or HTTP auth",
      "n1430": "Warning: manifest packagedAt — DB please first package",
      "n1431": "Warning: unit for active Not found CLI binary (can placeholder unit)",
      "n1432": "Warning: target YSK data",
      "n1433": "Warning: thisinterface for, down can panel",
      "n1434": "Warning: secrets/ssh/.master.key YSK_SECRETS_KEY (vault/2FA can cannot)",
      "n1435": "Warning: config.json (can setup )",
      "n1436": "read banned Failed",
      "n1437": "read banned can permission; unban/ban YSK_EXECUTE",
      "n1438": "read banned Failed (permission or service)",
      "n1439": "read fail2ban bans Failed",
      "n1440": "readFailed",
      "n1441": "readlogFailed",
      "n1442": "readfile",
      "n1443": "readsystem",
      "n1444": "change default confirmDefault: true",
      "n1445": "changewillwritemanaged file; \"apply to system\"will /etc/php/.../conf.d and reload FPM",
      "n1446": "High load",
      "n1447": "datacan; install/restartserviceHost execute permission required",
      "n1448": "databasecan (>7 )— update",
      "n1449": "databasenot create. please mysql and YSK_EXECUTE=1.",
      "n1450": "databasenot create. please psql, TCP and YSK_EXECUTE=1.",
      "n1451": "database",
      "n1452": "database name",
      "n1453": "database",
      "n1454": "data directory",
      "n1455": "Open the project Resources tab to create the system user",
      "n1456": "limits",
      "n1457": "",
      "n1458": "pathallow",
      "n1459": "path allow log directory",
      "n1460": "pathdeny",
      "n1461": "",
      "n1462": "home: target canonical complete",
      "n1463": "; setquota please \"applylimits to OS\"",
      "n1464": "",
      "n1465": "datainvalid",
      "n1466": "; can package",
      "n1467": "for RAM 25%",
      "n1468": "Connections & network",
      "n1469": "(can KILL)",
      "n1470": "(kill -0 Failed)",
      "n1471": "Advanced",
      "n1472": ": secret panel ( and operator 2FA — )",
      "n1473": "Operations",
      "n1474": "SFTP settingscomplete (host/username/path)",
      "n1475": "applied ≠ cluster healthy — please probe --peers",
      "n1476": "migrate post Failed",
      "n1477": "mkdir Failed",
      "n1478": "post ok=false",
      "n1479": "backupnot (skipped)",
      "n1480": "install YSK_EXECUTE=1",
      "n1481": "Not found rndc / active named|bind9|pdns",
      "n1482": "Remote push or restic failed — local tar may have succeeded; see sideResults",
      "n1483": "file,,",
      "n1484": "active named/bind9/pdns (can scp file)",
      "n1485": "nginx — conf scp (written on peer)",
      "n1486": "Remote / restic steps processed",
      "n1487": "requires YSK_EXECUTE + root",
      "n1488": "restorenot chown (Requires root + YSK_EXECUTE)",
      "n1489": "DNSBL not completeSupports IPv6;",
      "n1490": "peer applied; written or Failed — cluster reload",
      "n1491": "peer reload Success (partial)",
      "n1492": "Some or all backups failed — see results",
      "n1493": "or Not applied to system ( YSK_EXECUTE)",
      "n1494": "Failed — check SSH key / firewall",
      "n1495": "Failed — steps",
      "n1496": "systemFailed",
      "n1497": "",
      "n1498": "PHP + Nginx ( app/public)",
      "n1499": "Can be overridden at deploy time",
      "n1500": "will go build -o app.; hostInstalled Go toolchain",
      "n1501": "will venv + pip; ExecStart uvicorn main:app",
      "n1502": "will venv + pip; entry app.py (not ASGI)",
      "n1503": "/apply FPM pool write php_admin_value",
      "n1504": ": panel\"\"willstart server.js; written ≠",
      "n1505": "mailhost A",
      "n1506": "mailhost AAAA (IPv6)",
      "n1507": "Mail management settings directory",
      "n1508": "ID invalid",
      "n1509": "invalid",
      "n1510": "for 1–1000000 MiB",
      "n1511": "1 MiB",
      "n1512": "restartsystemservice",
      "n1513": "ban add",
      "n1514": "reload vsftpd",
      "n1515": "reloadservice",
      "n1516": "Error etc",
      "n1517": "Error log, slow query log",
      "n1518": "Error and log",
      "n1519": "Threshold numbers",
      "n1520": "ROW recommended for replication",
      "n1521": "Wait timeout",
      "n1522": "Off",
      "n1523": "firewall ( UFW not applysystem)",
      "n1524": "firewall (): TCP 3306, 4567, 4444, 4568",
      "n1525": "Preset writes nginx limit_req",
      "n1526": "(hold), lower",
      "n1527": "Defense: critical",
      "n1528": "Defense: emergency preset suggested",
      "n1529": "Defense: possible attack",
      "n1530": "limitsWrote; apply to OS YSK_EXECUTE + root",
      "n1531": "Rate limit",
      "n1532": "",
      "n1533": "/ DB; Postfix/Rspamd please \"apply/ to system\"",
      "n1534": ": degraded — build/processcan with user; please createsystemuser",
      "n1535": ": degraded — processcan with user; please root + YSK_EXECUTE and createsystemuser",
      "n1536": "save; TOTP secret. Authenticator can.",
      "n1537": "EXECUTE + root firstcan vacuum",
      "n1538": "NetworkManager active persist DNS (will /etc/resolv.conf)",
      "n1539": "YSK_EXECUTE firstcan ufw apply",
      "n1540": "YSK_EXECUTE willreally auto-ban",
      "n1541": "YSK_EXECUTE banip",
      "n1542": "YSK_EXECUTE fail2ban service",
      "n1543": "YSK_EXECUTE=1 firstcan vacuum journal",
      "n1544": "execute:true or dryRun:true",
      "n1545": "nginx log_format $upstream_cache_status ( or X-YSK-Cache)first HIT/MISS",
      "n1546": "Requires root + YSK_EXECUTE willreally useradd; willSuccess",
      "n1547": "Requires root journalctl --vacuum",
      "n1548": "Requires root firstcan UFW",
      "n1549": "hostInstalled cargo/rustc",
      "n1550": "host Python and pip",
      "n1551": "host Python and pip (installwillFailed)",
      "n1552": "install bind9-dnsutils and enablesystemchangepermission, can really dnssec-keygen.",
      "n1553": "Requires confirm string EMERGENCY; avoid locking yourself out",
      "n1554": "system sshd Match/User settingswillreally",
      "n1555": "requires --target or resume --job",
      "n1556": "requires MySQL/MariaDB adminpermission",
      "n1557": "requires YSK_EXECUTE",
      "n1558": "requires YSK_EXECUTE Adminer",
      "n1559": "requires admin",
      "n1560": "requires aws CLI ( or restic s3 repo)",
      "n1561": "requires id or all",
      "n1562": "requires ip",
      "n1563": "requires jobId",
      "n1564": "requires linuxUser or projectId",
      "n1565": "requires master node",
      "n1566": "requires nginx geoip2 (libnginx-mod-http-geoip2)firstwill HTTP",
      "n1567": "requires primary node",
      "n1568": "requires privateKey",
      "n1569": "requires projectId",
      "n1570": "requires root",
      "n1571": "requires source",
      "n1572": "requires sshpass, YSK key (identityId), or local SSH key",
      "n1573": "requires target (root@host) or jobId with resume",
      "n1574": "requires target, or target jobId",
      "n1575": "requires username and ssh-",
      "n1576": "requires zone domain",
      "n1577": "requirespassword",
      "n1578": "requires email",
      "n1579": "requires email and domain",
      "n1580": "requiresversion and version",
      "n1581": "requires candidateVersion (can etc current or )",
      "n1582": "requiressystemadminpermissiondoneinstall",
      "n1583": "Root is required for lifecycle and system writes",
      "n1584": "Host execute permission required/reload",
      "n1585": "Host execute permission required to system and reload Nginx",
      "n1586": "Host execute permission required check_policy_service",
      "n1587": "Host execute permission required nginx conf and reload",
      "n1588": "Sync blocked: needs root",
      "n1589": "requires primary node",
      "n1590": "",
      "n1591": "Not root — useradd / systemd / nginx system paths are restricted",
      "n1592": "not seccomp requires runAsUser",
      "n1593": "Public requests / min",
      "n1594": "panelconnection; Available\"\" ( )",
      "n1595": "Panel is not running as root",
      "n1596": "Available apply:false",
      "n1597": "— not writefile",
      "n1598": "Default uvicorn workers",
      "n1599": "with Redis DB",
      "n1600": "",
      "n1601": "Local infile",
      "n1602": "logpathinvalid",
      "n1603": "startError",
      "n1604": "Error, and etc",
      "n1605": "Error ()",
      "n1606": "build can; Failed notes/log",
      "n1607": "",
      "n1608": "verifyinvalid",
      "n1609": "passed",
      "n1610": "Package index not refreshed (YSK_EXECUTE off) — showing apt list only; enable execute to run apt-get update",
      "n1611": "UFW is inactive: {{n}} permanent deny rule(s) are stored in user.rules but the kernel is not enforcing them.",
      "n1612": "UFW is inactive. A deny rule would be written to user.rules only — the kernel would not drop packets. Enable UFW first. Not enabling automatically.",
      "t0001": "listenPort invalid: {{v0}}",
      "t0002": "restoreversion {{v0}}",
      "t0003": "file (>{{v0}} bytes)",
      "t0004": ": {{v0}}",
      "t0005": "target: {{v0}}",
      "t0006": "not found: {{v0}}",
      "t0007": "Failed: {{v0}}",
      "t0008": "{{v0}} → {{v1}}",
      "t0009": "not found: {{v0}}",
      "t0010": "Failed: {{v0}}",
      "t0011": "{{v0}} → {{v1}}",
      "t0012": "cannot from Status {{v0}} for",
      "t0013": "thisoperationrequires: {{v0}}",
      "t0014": "Statusinvalid: {{v0}}",
      "t0015": "{{v0}}",
      "t0016": "Unknown: {{v0}}",
      "t0017": "{{v0}} cannot {{v1}} ( {{v2}})",
      "t0018": "{{v0}} not readoperationrequires id",
      "t0019": "host: {{v0}}",
      "t0020": "allow: {{v0}}",
      "t0021": "deny: {{v0}}",
      "t0022": "not found Playbook: {{v0}}",
      "t0023": "ip -j addr failed: {{v0}}",
      "t0024": "ip -j route failed: {{v0}}",
      "t0025": "nmcli writeFailed: {{v0}}",
      "t0026": "{{v0}} → connection\"{{v1}}\"",
      "t0027": "connection up warning: {{v0}}",
      "t0028": "Connection re-enabled (persists after reboot)",
      "t0029": "{{v0}} → {{v1}} (; rebootcan disappear)",
      "t0030": "from connection\"{{v0}}\" {{v1}}",
      "t0031": "NM: {{v0}}",
      "t0032": "Deleted {{v0}} ← {{v1}}",
      "t0033": "link down failed: {{v0}}",
      "t0034": "did down {{v0}}",
      "t0035": "link up failed: {{v0}}",
      "t0036": "did up {{v0}}",
      "t0037": "MTU Failed: {{v0}}",
      "t0038": "nmcli write gateway Failed: {{v0}}",
      "t0039": "save default gateway {{v0}} → connection\"{{v1}}\" (reboot )",
      "t0040": "nmcli write routes Failed: {{v0}}",
      "t0041": "save {{v0}} →\"{{v1}}\" (reboot )",
      "t0042": "ip route add failed: {{v0}}",
      "t0043": "add {{v0}}${gw?",
      "t0044": ": ''}(May not persist across reboot; use Save to persist)",
      "t0045": "from connection\"{{v0}}\" ipv4.gateway",
      "t0046": "NM gateway: {{v0}}",
      "t0047": "from \"{{v0}}\" {{v1}}",
      "t0048": "NM routes: {{v0}}",
      "t0049": "ip route del failed: {{v0}}",
      "t0050": "{{v0}}",
      "t0051": "{{v0}}",
      "t0052": "DNS invalid: {{v0}}",
      "t0053": "DNS IP: {{v0}}",
      "t0054": "nmcli modify failed: {{v0}}",
      "t0055": "restore {{v0}} DHCP DNS (ignore-auto-dns=no)",
      "t0056": "nmcli modify failed: {{v0}}",
      "t0057": "Wrote {{v0}}: DNS {{v1}}${search.length?",
      "t0058": "Failed: {{v0}}",
      "t0059": "{{v0}} → {{v1}}",
      "t0060": "{{v0}}",
      "t0061": "SSO token ({{v0}} )",
      "t0062": "Webmail Install failed: {{v0}}",
      "t0063": "{{v0}}",
      "t0064": "systemFailed: {{v0}}",
      "t0065": "vacation to {{v0}} sieve directory (written)",
      "t0066": "sieve +.dovecot.sieve → {{v0}}@{{v1}}",
      "t0067": "Disabled active sieve link → {{v0}}@{{v1}}",
      "t0068": "{{v0}}@{{v1}} sieve Failed: {{v2}}",
      "t0069": "Wrote per-sender policy daemon ({{v0}} domains)",
      "t0070": "{{v0}} failed (exit {{v1}}): {{v2}}",
      "t0071": "Wrote plugin {{v0}}",
      "t0072": "symlink failed: {{v0}}",
      "t0073": "did symlink {{v0}} → {{v1}}",
      "t0074": "config Failed: {{v0}}",
      "t0075": "config plugin {{v0}}: {{v1}}",
      "t0076": "Wrote {{v0}}: {{v1}}",
      "t0077": "{{v0}} and www.{{v1}} to server IP. CDN (Cloudflare)can or.",
      "t0078": "PTR VPS/ IP settings, and and HELO/EHLO ({{v0}}). please (AWS/GCP ).",
      "t0079": "{{v0}}",
      "t0080": "postsuper failed: {{v0}}",
      "t0081": "domain: {{v0}}",
      "t0082": ": {{v0}}",
      "t0083": "create Maildir: {{v0}}",
      "t0084": "createsystemuser {{v0}}",
      "t0085": "createsystemuserFailed: {{v0}}",
      "t0086": ": {{v0}}",
      "t0087": "write passdb Failed: {{v0}}",
      "t0088": ": {{v0}}",
      "t0089": "create {{v0}}: {{v1}} → {{v2}}",
      "t0090": "Mail domain not found: {{v0}}",
      "t0091": "Wrote vacation {{v0}}",
      "t0092": "Wrote {{v0}}",
      "t0093": "virtual_alias: {{v0}} ({{v1}} )",
      "t0094": "Postfix anvil: smtpd_client_message_rate_limit={{v0}} / 3600s (; domain rate )",
      "t0095": "postconf: {{v0}}",
      "t0096": "Wrote rspamd ratelimit.conf (~{{v0}}/h)",
      "t0097": "map ({{v0}} domains)",
      "t0098": "{{v0}}: block (allowlocal LLM)",
      "t0099": "LLM please Failed: {{v0}}",
      "t0100": "{{v0}}–{{v1}} Not foundAvailableport",
      "t0101": "please confirm: {{v0}}",
      "t0102": "{{v0}}s will with 1 (shutdown +N with )",
      "t0103": "restart ( {{v0}} )",
      "t0104": "off ( {{v0}} )",
      "t0105": "Read failed: {{v0}}",
      "t0106": "Failed: {{v0}}",
      "t0107": "serviceinvalid: {{v0}}",
      "t0108": "path allowwrite: {{v0}}",
      "t0109": "purge/reload failed: {{v0}}",
      "t0110": "DB {{v0}}: {{v1}} key",
      "t0111": "(type {{v0}} — )",
      "t0112": "Wrote {{v0}}",
      "t0113": "Write failed: {{v0}}",
      "t0114": "Key missing or not deleted",
      "t0115": "home: {{v0}}",
      "t0116": "cannot snapshots JSON: {{v0}}",
      "t0117": "{{v0}} restic",
      "t0118": "home confirmPhrase=\"{{v0}}\" ()",
      "t0119": "dry-run: snapshot {{v0}} {{v1}} path ( 100)",
      "t0120": "dry-run failed: {{v0}}",
      "t0121": "restore snapshot {{v0}} → {{v1}}",
      "t0122": "restore failed exit={{v0}}",
      "t0123": "Wrotemanage: {{v0}}",
      "t0124": "project Linux user {{v0}} (Match User ysks_*,ysk_*)",
      "t0125": "please: cp {{v0}} /etc/ssh/sshd_config.d/ && systemctl reload sshd",
      "t0126": "sshd -t Failed, not reload: {{v0}}",
      "t0127": "Installed {{v0}} and reload sshd",
      "t0128": "Installed reload failed: {{v0}}",
      "t0129": "Wrote {{v0}} ({{v1}} bytes)",
      "t0130": "Managed Nginx confs: {{v0}} (panel dataDir nginx/conf.d)",
      "t0131": "Unknown: {{v0}}",
      "t0132": "{{v0}}: {{v1}}",
      "t0133": "{{v0}} — skipped (force can )",
      "t0134": "WordPress install — {{v0}}",
      "t0135": "domain: {{v0}}",
      "t0136": "entry {{v0}}.wsgi:application (gunicorn)",
      "t0137": "will cargo build --release;./target/release/{{v0}}",
      "t0138": "Axum: cargo build --release crates.io",
      "t0139": "./target/release/{{v0}}",
      "t0140": "create {{v0}}, {{v1}}, Error {{v2}}",
      "t0141": "{{v0}}doneproject Linux user (page → createsystemuser).",
      "t0142": "home: /home/ysk-server-{{v0}} · user: {{v1}}",
      "t0143": "did chown {{v0}}:{{v1}} → {{v2}}",
      "t0144": "with projectuser {{v0}}",
      "t0145": "pidfile with runuser -u {{v0}} start",
      "t0146": "Wrote FPM pool: {{v0}}",
      "t0147": "Enabled pool: {{v0}}",
      "t0148": "/etc/php/{{v0}}/fpm not found — install php{{v1}}-fpm",
      "t0149": "{{v0}} Installed",
      "t0150": "install {{v0}}",
      "t0151": "not install {{v0}}",
      "t0152": "SSH probe failed: {{v0}}",
      "t0153": "nameserver: {{v0}}",
      "t0154": "zone directory ({{v0}}.zone)",
      "t0155": "zone directory: {{v0}}",
      "t0156": "remote reload failed: {{v0}}",
      "t0157": "{{v0}}: scp failed {{v1}}",
      "t0158": "scp {{v0}} OK → {{v1}}",
      "t0159": "scp /Failed (ok={{v0}} fail={{v1}})",
      "t0160": "enable failed: {{v0}}",
      "t0161": "disable failed: {{v0}}",
      "t0162": "UFW DENY from {{v0}} (rule, )",
      "t0163": "deny failed: {{v0}}",
      "t0164": "UFW DENY {{v0}}",
      "t0165": "delete failed: {{v0}}",
      "t0166": "rule #{{v0}}",
      "t0167": "#{{v0}} Failed: {{v1}}",
      "t0168": "allow {{v0}}/{{v1}}",
      "t0169": "allow failed: {{v0}}",
      "t0170": "reload Failed ({{v0}}): {{v1}}",
      "t0171": ": with projectuser {{v0}} active",
      "t0172": "Node: {{v0}}",
      "t0173": "port: {{v0}}",
      "t0174": "Appliedpanel Node ({{v0}})",
      "t0175": "applyNot found: {{v0}}",
      "t0176": "with systemd unit: {{v0}}",
      "t0177": "with PM2: {{v0}}",
      "t0178": "startprocessFailed: {{v0}}",
      "t0179": "start pid={{v0}}, pidfile={{v1}}",
      "t0180": "Nginx settings (managed file): {{v0}}",
      "t0181": "createpage: {{v0}}",
      "t0182": ": {{v0}}",
      "t0183": "Nginx settings: {{v0}}",
      "t0184": "directory: {{v0}}",
      "t0185": "HTTP: {{v0}} ({{v1}})",
      "t0186": ": {{v0}}",
      "t0187": "→ {{v0}}",
      "t0188": "certificate: {{v0}}",
      "t0189": "Enabled SSL ( Let’s Encrypt path; or SSL page {{v0}} certificate)",
      "t0190": "reload Nginx Failed: {{v0}}",
      "t0191": "Wrotehost: {{v0}}",
      "t0192": "Runtime {{v0}} — Git, restartprocess",
      "t0193": "Wrote {{v0}} ({{v1}} )",
      "t0194": "PHP-FPM pool user: {{v0}} (project)",
      "t0195": "runtime version → {{v0}}",
      "t0196": "panel php.ini ({{v0}} php_admin_*)",
      "t0197": "PHP-FPM Nginx settings: {{v0}}",
      "t0198": "Nginx reload ={{v0}}: {{v1}}",
      "t0199": "PHP server pid={{v0}} @ 127.0.0.1:{{v1}}",
      "t0200": "SIGTERM {{v0}}",
      "t0201": "SIGKILL {{v0}}",
      "t0202": "pid {{v0}}",
      "t0203": "deployProcess runtime\"{{v0}}\"",
      "t0204": ": with projectuser {{v0}} and start",
      "t0205": "Runtime: {{v0}} · port {{v1}} · entry {{v2}}",
      "t0206": ": {{v0}}",
      "t0207": "Failed: {{v0}}",
      "t0208": "Appliedpanel {{v0}} ({{v1}})",
      "t0209": "Wrote systemd: {{v0}}",
      "t0210": "enable --now project unit (User={{v0}})",
      "t0211": "systemctl Start failed: {{v0}}",
      "t0212": "writesystem unit Failed: {{v0}}",
      "t0213": "pidfile start pid={{v0}}${mode === 'isolated'?",
      "t0214": "pidfile Start failed: {{v0}}",
      "t0215": "checknot passed ({{v0}}ms): {{v1}}",
      "t0216": "checkpassed ({{v0}}ms)",
      "t0217": "Wrote Nginx: {{v0}}",
      "t0218": "{{v0}} banned IP",
      "t0219": "did unban {{v0}} @ {{v1}}",
      "t0220": "unban failed: {{v0}}",
      "t0221": "manage: {{v0}} ({{v1}} )",
      "t0222": "sshd ignoreip {{v0}} {{v1}} · Status: applied",
      "t0223": "fail2ban-client ignoreip Failed: {{v0}} (managed fileWrote; applied)",
      "t0224": "fail2ban jails: {{v0}}",
      "t0225": "Wrote unit {{v0}}",
      "t0226": "Status is still {{v0}} (not applied)",
      "t0227": "Unexpected apply_status: {{v0}}",
      "t0228": "database: {{v0}} ( 0–{{v1}})",
      "t0229": "to {{v0}}",
      "t0230": "cannot to system conf directory: {{v0}}",
      "t0231": "conf Failed: {{v0}}",
      "t0232": "restart {{v0}}",
      "t0233": "to {{v0}} Failed: {{v1}}",
      "t0234": "denydirectory: {{v0}}",
      "t0235": "directory: {{v0}}",
      "t0236": "skippeddirectory (scan): {{v0}}",
      "t0237": "{{v0}} (not )",
      "t0238": "journal php{{v0}}-fpm (pool log not )",
      "t0239": "grep\"{{v0}}\": {{v1}} (scan {{v2}} bytes)",
      "t0240": "{{v0}} (file {{v1}} bytes, )",
      "t0241": "{{v0}} (file {{v1}} bytes)",
      "t0242": "to {{v0}} log (not off)",
      "t0243": "cannotread: {{v0}}",
      "t0244": "\"{{v0}}\": {{v1}}, {{v2}} ()",
      "t0245": "{{v0}} serverNot installed",
      "t0246": "{{v0}} servicenot running",
      "t0247": "{{v0}} Not installed",
      "t0248": ": {{v0}}",
      "t0249": "server: {{v0}}",
      "t0250": "{{v0}} Ready",
      "t0251": "{{v0}} Install incomplete",
      "t0252": "{{v0}} servicestart",
      "t0253": "Start failed: {{v0}}",
      "t0254": "Supports Node.js version {{v0}}; available versions: {{v1}}",
      "t0255": "Supports PHP version {{v0}}; Available: {{v1}}",
      "t0256": "Supports Python version {{v0}}; Available: {{v1}}",
      "t0257": "Supports Go version {{v0}}; Available: {{v1}}",
      "t0258": "Unknown runtime: {{v0}}",
      "t0259": "dig: no answer (NXDOMAIN or empty)",
      "t0260": "{{v0}}",
      "t0261": "PostgreSQL failed: {{v0}}",
      "t0262": "MySQL failed: {{v0}}",
      "t0263": "{{v0}}: cannot DROP — EXECUTE+root ( expired)",
      "t0264": "{{v0}}: DROP failed {{v1}}",
      "t0265": "{{v0}}: DROP failed {{v1}}",
      "t0266": "{{v0}}: expired (not DROP systemaccount)",
      "t0267": "FTP user: {{v0}}",
      "t0268": "create FTP {{v0}}",
      "t0269": "Jail path: {{v0}}",
      "t0270": "Password stored as crypt hash (not plaintext)",
      "t0271": "with project Linux user: {{v0}} (apply vsftpd )",
      "t0272": "Skipped invalid username",
      "t0273": "{{v0}}: password → crypt hash",
      "t0274": "{{v0}} hashnot crypt (openssl unavailable)— can Failed",
      "t0275": "{{v0}} passwordhash, cannot",
      "t0276": "{{v0}} project linuxUser — guest\"{{v1}}\" (please FTP )",
      "t0277": "Wrote {{v0}} settings",
      "t0278": "{{v0}}",
      "t0279": "{{v0}} Applied, vsftpd Running",
      "t0280": "skipped chown {{v0}}: systemuser\"{{v1}}\" (please firstcreateprojectsystemuser)",
      "t0281": "chown failed {{v0}}: {{v1}}",
      "t0282": "FTP directory ({{v0}})",
      "t0283": "project {{v0}} directory",
      "t0284": "project {{v0}} public",
      "t0285": "mail {{v0}}",
      "t0286": "not createsystemuser (requiressystemadminpermission). home: {{v0}}; directory.",
      "t0287": "{{v0}}; home {{v1}}",
      "t0288": "stop {{v0}}",
      "t0289": "Removed home: {{v0}}",
      "t0290": "home not (can ): {{v0}} — {{v1}}",
      "t0291": "denydelete home path: {{v0}}",
      "t0292": "not OS home (Requires root): {{v0}}; systemuser {{v1}} can",
      "t0293": "pdnsutil load-zone failed: {{v0}}",
      "t0294": "pdnsutil zone {{v0}}",
      "t0295": "systemctl {{v0}} fail2ban ok",
      "t0296": "{{v0}} failed: {{v1}}",
      "t0297": "fail2ban ban {{v0}} @ {{v1}} (, bantime limits)",
      "t0298": "banip failed: {{v0}}",
      "t0299": "jails: {{v0}}",
      "t0300": "ignoreip: dataDir/fail2ban/ignoreip.txt",
      "t0301": "installcheck: {{v0}}",
      "t0302": "project {{v0}} (package: {{v1}})",
      "t0303": "{{v0}} (package: {{v1}})",
      "t0304": "database {{v0}} (package: {{v1}})",
      "t0305": "Wrote {{v0}} (DB {{v1}}@{{v2}}; Available)",
      "t0306": "pm2 start failed: {{v0}}",
      "t0307": "pm2 start {{v0}}",
      "t0308": "{{v0}} is not installed",
      "t0309": "{{v0}}",
      "t0310": "Applied {{v0}}",
      "t0311": "with can restart: {{v0}}",
      "t0312": "apply {{v0}}",
      "t0313": "restart (please restart): {{v0}}",
      "t0314": "ALTER SYSTEM {{v0}} and reload",
      "t0315": "restart: {{v0}}",
      "t0316": "did {{v0}} {{v1}}",
      "t0317": "ini: {{v0}}",
      "t0318": "/etc/php/{{v0}}/fpm — please firstinstall php{{v1}}-fpm",
      "t0319": "Applied {{v0}} and reload php{{v1}}-fpm",
      "t0320": "ini; reload failed: {{v0}}",
      "t0321": "DNS zone draft {{v0}} ( to DNS write/apply)",
      "t0322": "IPv6 {{v0}}",
      "t0323": "maildomain {{v0}}",
      "t0324": "MySQL DB draft {{v0}} ( to databaseapply)",
      "t0325": "skipped: directory {{v0}}",
      "t0326": "Backed up {{v0}}/{{v1}} project(s)",
      "t0327": " (skipped {{v0}} without a home dir)",
      "t0328": "projectdirectory: {{v0}}",
      "t0329": "tar failed: {{v0}}",
      "t0330": "Wrote backup {{v0}}",
      "t0331": "Preview: {{v0}} files in the archive (showing {{v1}})",
      "t0332": "cannot: {{v0}}",
      "t0333": "restore (web) to {{v0}}",
      "t0334": "web restoreFailed: {{v0}}",
      "t0335": "restoreFailed: {{v0}}",
      "t0336": "from {{v0}} restore to projectdirectory",
      "t0337": "did chown {{v0}}:{{v1}} → {{v2}}",
      "t0338": ": {{v0}}",
      "t0339": "manage crontab: {{v0}}",
      "t0340": "crontab failed: {{v0}}",
      "t0341": "pg_dump failed: {{v0}}",
      "t0342": "dump failed: {{v0}}",
      "t0343": "psql failed: {{v0}}",
      "t0344": "import failed: {{v0}}",
      "t0345": "target {{v0}} not git — deny clone with data (.ysk-scaffold )",
      "t0346": "did clone {{v0}} → {{v1}}",
      "t0347": "pull update: {{v0}}",
      "t0348": "linuxUser invalid: {{v0}}",
      "t0349": "Applied {{v0}}: {{v1}} + www-data/nginx; home 750, public g+rX",
      "t0350": "ysk-web applyFailed: {{v0}}",
      "t0351": "path {{v0}}",
      "t0352": "nginx conf: {{v0}}",
      "t0353": "Download failed: {{v0}}",
      "t0354": "Adminer → {{v0}}",
      "t0355": "{{v0}}",
      "t0356": "nginx conf: {{v0}}",
      "t0357": "→ {{v0}}",
      "t0358": "portinvalid: {{v0}}",
      "t0359": "with user {{v0}} install crontab",
      "t0360": "key {{v0}}",
      "t0361": "zone → {{v0}} ( reload DNS; DS manual registrar)",
      "t0362": "not to managed zone ( dns/zones/{{v0}}.zone)—",
      "t0363": "{{v0}} file under {{v1}}",
      "t0364": "TCP {{v0}}:{{v1}} OK ({{v2}}ms)",
      "t0365": "TCP {{v0}}:{{v1}} failed: {{v2}}",
      "t0366": "PING failed: {{v0}}",
      "t0367": ": {{v0}}MB > {{v1}}MB",
      "t0368": "({{v0}} / {{v1}} MiB), cannot{{v2}}",
      "t0369": "Home path is not ready ({{v0}})",
      "t0370": "Linux user {{v0}} not provisioned",
      "t0371": "Ready {{v0}} / degraded {{v1}} / not isolated {{v2}} ({{v3}} total)",
      "t0372": " · Pending: {{v0}}{{v1}}",
      "t0373": "Project \"{{v0}}\" isolation",
      "t0374": "to localpath {{v0}}",
      "t0375": "identity {{v0}}: {{v1}}",
      "t0376": "sftp (identity) to {{v0}} ok",
      "t0377": "sftp (identity) failed: {{v0}}",
      "t0378": "sftp to {{v0}} ok",
      "t0379": "sftp failed: {{v0}}",
      "t0380": "sftp to {{v0}} ok",
      "t0381": "sftp failed: {{v0}} (set backup remote identityId)",
      "t0382": "S3 {{v0}}",
      "t0383": "S3 failed: {{v0}}",
      "t0384": ": {{v0}}/{{v1}} admin Enabled 2FA",
      "t0385": "Policy not enforced: {{v0}}/{{v1}} admin(s) have 2FA. If there is a single admin without 2FA, enable 2FA then add a backup admin.",
      "t0386": "{{v0}} PATH",
      "t0387": "{{v0}} not found",
      "t0388": "Install {{v0}} or add it to PATH",
      "t0389": "Available versions: {{v0}}",
      "t0390": "{{v0}}% ( {{v1}} MB)",
      "t0391": "{{v0}}% ({{v1}})",
      "t0392": "servicestart {{v0}}",
      "t0393": "Mode: {{v0}}",
      "t0394": "Ready {{v0}} / Degraded {{v1}} / Missing {{v2}} ({{v3}} total)",
      "t0395": "Not found ( {{v0}})",
      "t0396": "host node: {{v0}}",
      "t0397": "host php: {{v0}}",
      "t0398": "host python: {{v0}}",
      "t0399": "host go: {{v0}}",
      "t0400": "host cargo: {{v0}}",
      "t0401": "Node Available: {{v0}}",
      "t0402": "PHP Available: {{v0}}",
      "t0403": "Python Available: {{v0}}",
      "t0404": "Go Available: {{v0}}",
      "t0405": "Rust Available: {{v0}}",
      "t0406": "install Node {{v0}}",
      "t0407": "install PHP {{v0}}",
      "t0408": "install Python {{v0}}",
      "t0409": "install Go {{v0}} to /usr/local/ysk/go",
      "t0410": "install Rust ({{v0}}) to /usr/local/ysk/rust",
      "t0411": "Install failed: {{v0}}",
      "t0412": "Prepared OpenJDK {{v0}} install script",
      "t0413": "Prepared Kotlin {{v0}} install script (needs JDK)",
      "t0414": "Prepared Bun ({{v0}}) install script",
      "t0415": "project home: {{v0}}",
      "t0416": "targetuser {{v0}} (project home); please.ssh chown (API will)",
      "t0417": "did chown {{v0}} → {{v1}}",
      "t0418": "chown.ssh failed: {{v0}}",
      "t0419": "Deleted key · authorized_keys",
      "t0420": "Supports: {{v0}}",
      "t0421": "TTL {{v0}} 30–604800",
      "t0422": "{{v0}} CNAME and ()",
      "t0423": "{{v0}} CNAME target",
      "t0424": "settingsFailed: {{v0}}",
      "t0425": "{{v0}} Wrotemanagesettings",
      "t0426": "cannotfile: {{v0}}",
      "t0427": "{{v0}} settings to systemdirectory",
      "t0428": "{{v0}} invalid",
      "t0429": "home not path ( {{v0}})",
      "t0430": "usermod -s failed: {{v0}}",
      "t0431": "Failed: {{v0}}",
      "t0432": "Failed: {{v0}}",
      "t0433": "set-property Failed: {{v0}} ( deploy willwrite unit)",
      "t0434": "unit {{v0}} not active — limits DB, deploy write unit",
      "t0435": "setquota not Success (filesystemcan not user_xattr/quota): {{v0}}",
      "t0436": "home: {{v0}}",
      "t0437": "did chown {{v0}} → {{v1}}",
      "t0438": "top header failed: {{v0}}",
      "t0439": "ps completeFailed: {{v0}}",
      "t0440": "NI={{v0}}",
      "t0441": "PID {{v0}} (process.pid)",
      "t0442": "or probe (kill -0 exit {{v0}})",
      "t0443": "kill -s {{v0}} failed: ${err ||",
      "t0444": "{{v0}} → PID {{v1}}",
      "t0445": "{{v0}} project(s) suspended",
      "t0446": "{{v0}} project(s) missing system users",
      "t0447": "{{v0}} pending approval(s)",
      "t0448": "Certificate expired: {{v0}}",
      "t0449": "Certificate expires in {{v0}} day(s): {{v1}}",
      "t0450": "Time: {{v0}}",
      "t0451": "DNSBL listing: {{v0}}",
      "t0452": "{{v0}} apply failure(s)/blocked",
      "t0453": "{{v0}} item(s) still written/draft",
      "t0454": "Auto defense preset: {{v0}}",
      "t0455": "Operation failed: {{v0}}",
      "t0456": "Journal disk use high: ≈{{v0}} MB",
      "t0457": "Threshold {{v0}} MB — vacuum in Log center or adjust retention",
      "t0458": "df failed: {{v0}}",
      "t0459": "{{v0}} project ( {{v1}})",
      "t0460": "version {{v0}} → {{v1}}",
      "t0461": "raise {{v0}}",
      "t0462": "Failed exit={{v0}}",
      "t0463": "apt list --upgradable: {{v0}} can raise",
      "t0464": "apt list --upgradable unavailable (exit {{v0}}); apt-cache policy",
      "t0465": "dpkg+apt-cache policy: {{v0}} package",
      "t0466": "dpkg/apt-cache policy Failed or (exit {{v0}})— can apt or permission",
      "t0467": "Node {{v0}} (not apt nodejs packagecan raise)",
      "t0468": "can raise (candidate ≠ current): {{v0}}",
      "t0469": "npm registry HTTP {{v0}}",
      "t0470": "GitHub releases HTTP {{v0}}",
      "t0471": "GitHub package.json HTTP {{v0}}",
      "t0472": "npm: {{v0}}@{{v1}}",
      "t0473": "npm {{v0}} unavailable: {{v1}}",
      "t0474": "GitHub releases unavailable: {{v0}}",
      "t0475": "GitHub package.json ({{v0}}): {{v1}}",
      "t0476": "GitHub package.json unavailable: {{v0}}",
      "t0477": "update: {{v0}} → {{v1}}",
      "t0478": "directory {{v0}} git repo — can YSK_SOURCE_ROOT, or npm (YSK_NPM_PACKAGE)",
      "t0479": "GitHub tarball Download failed: {{v0}}",
      "t0480": "to {{v0}} (staging only)— not Runninginstall; please /git directorydone",
      "t0481": "git: {{v0}}",
      "t0482": "git apply {{v0}} Failed (exit {{v1}}): {{v2}}",
      "t0483": "updatetarget {{v0}} and build — please restart ysk-server version",
      "t0484": "Installed {{v0}}",
      "t0485": "npm Update failed: {{v0}}",
      "t0486": "YSK_NPM_PACKAGE install {{v0}}",
      "t0487": "YSK_NPM_PACKAGE Install failed: {{v0}}",
      "t0488": "can raise {{v0}} → {{v1}} (CRITICAL CVE, )",
      "t0489": "can raise {{v0}} → {{v1}} (HIGH CVE, )",
      "t0490": "can raise {{v0}} → {{v1}} (can, )",
      "t0491": "can raise {{v0}} → {{v1}} ()",
      "t0492": "can raise {{v0}} → {{v1}} (apt Candidate)",
      "t0493": "Availableraise, OSV {{v0}}",
      "t0494": "serviceStatus: {{v0}}",
      "t0495": "detect to can: {{v0}}",
      "t0496": "Unknown Agent running: {{v0}}",
      "t0497": "Supports Agent: {{v0}}",
      "t0498": "installFailed (willSuccess): {{v0}}",
      "t0499": "Agent not found session: {{v0}}",
      "t0500": "Not found: {{v0}}",
      "t0501": "user: {{v0}}",
      "t0502": "user: {{v0}}",
      "t0503": "project SFTP user (ysks_/ysk_, internal-sftp kbd-interactive): {{v0}}",
      "t0504": "from strict user: {{v0}}",
      "t0505": "{{v0}} user publickey+TOTP, disable password",
      "t0506": "managed file: {{v0}}",
      "t0507": "Installed {{v0}} and reload sshd",
      "t0508": "install/sshd -t Failed: {{v0}}",
      "t0509": "PAM willmanaged file: {{v0}}",
      "t0510": "chown Failed: {{v0}}",
      "t0511": "Warning: mode 400 (stat: {{v0}})",
      "t0512": "PAM (managed file): {{v0}}",
      "t0513": "sshd (managed file): {{v0}}",
      "t0514": "scratch (this): {{v0}} — please save",
      "t0515": "pam.d/sshd: {{v0}}",
      "t0516": "user {{v0}} SSH 2FA ({{v1}}). disable/retire.",
      "t0517": "secrets master key: {{v0}}",
      "t0518": "chown Failed: {{v0}}",
      "t0519": "ssh failed: {{v0}}",
      "t0520": "master key: {{v0}} (please backup)",
      "t0521": "master key: {{v0}}",
      "t0522": "fingerprint: {{v0}} ({{v1}})",
      "t0523": "Wrote CF-only UFW: {{v0}}",
      "t0524": "port: {{v0}}",
      "t0525": "CF IPv4: {{v0}}",
      "t0526": "CF IPv6: {{v0}}",
      "t0527": "ufw Failed: {{v0}}",
      "t0528": "auth failed IP: {{v0}}",
      "t0529": "Top IP {{v0}}",
      "t0530": "{{v0}} · {{v1}}",
      "t0531": "Auto-switched defense preset → {{v0}}{{v1}}",
      "t0532": "Auto-switched defense preset: {{v0}}",
      "t0533": "SSH failed×{{v0}}",
      "t0534": "auth Failed {{v0}} IP",
      "t0535": "please ×{{v0}}",
      "t0536": "scan×{{v0}}",
      "t0537": "{{v0}}/{{v1}}",
      "t0538": "done {{v0}} IP: Success {{v1}}",
      "t0539": ": auto-ban {{v0}}",
      "t0540": ": {{v0}}",
      "t0541": "ban {{v0}} IP",
      "t0542": "cannot zone {{v0}} (HTTP {{v1}})",
      "t0543": ": {{v0}} security_level → {{v1}}",
      "t0544": ": {{v0}} → security_level={{v1}}",
      "t0545": "({{v0}})",
      "t0546": "{{v0}}",
      "t0547": "confirm=\"{{v0}}\"",
      "t0548": "Wrote Nginx rate limits: {{v0}}",
      "t0549": "Injected rate-limit markers into {{v0}} vhost(s)",
      "t0550": "Active defense preset → {{v0}}",
      "t0551": "ban → {{v0}} ({{v1}} / {{v2}})",
      "t0552": "Applied defense preset: {{v0}}",
      "t0553": "fail2ban failed: {{v0}}",
      "t0554": "ufw failed: {{v0}}",
      "t0555": "{{v0}}",
      "t0556": "ufw delete failed: {{v0}}",
      "t0557": "{{v0}}",
      "t0558": "{{v0}}: {{v1}}",
      "t0559": "to {{v0}} vhost",
      "t0560": "cluster_size={{v0}} < node {{v1}}",
      "t0561": "{{v0}} node cluster",
      "t0562": "probe Supports {{v0}}",
      "t0563": "mysql/mariadb Failed: {{v0}}",
      "t0564": "SHOW REPLICA/SLAVE failed: {{v0}}",
      "t0565": "SHOW MASTER failed: {{v0}}",
      "t0566": "replica for recovery, ={{v0}}",
      "t0567": "primary recovery, ={{v0}}",
      "t0568": "replica Abnormal role={{v0}}",
      "t0569": "master, role={{v0}}",
      "t0570": "{{v0}} · {{v1}}",
      "t0571": "tar failed: {{v0}}",
      "t0572": "{{v0}} ({{v1}} bytes)",
      "t0573": "{{v0}} peer target",
      "t0574": "{{v0}}: identity {{v1}} unavailable — key",
      "t0575": "{{v0}}: ssh mkdir failed {{v1}}",
      "t0576": "{{v0}}: {{v1}}",
      "t0577": "{{v0}}/{{v1}}: scp failed {{v2}}",
      "t0578": "{{v0}} agent · op={{v1}}",
      "t0579": "{{v0}}: enqueue failed {{v1}}",
      "t0580": "Unknown {{v0}}",
      "t0581": "Galera conf ({{v0}})",
      "t0582": "{{v0}} install conf and join ( / SSH / fleet)",
      "t0583": "install conf → systemctl restart mariadb (not bootstrap node)",
      "t0584": "Not found conf: {{v0}}",
      "t0585": "local apply Supports {{v0}}",
      "t0586": "Installedsystem drop-in: {{v0}}",
      "t0587": "writesystem conf Failed: {{v0}}",
      "t0588": "galera_new_cluster failed: {{v0}}",
      "t0589": "systemctl restart {{v0}} ( from /slot/sentinel scripts/)",
      "t0590": "did systemctl restart {{v0}}",
      "t0591": "ssh probe failed: {{v0}}",
      "t0592": "replica probe failed: {{v0}}",
      "t0593": "primary probe failed: {{v0}}",
      "t0594": "{{v0}} node probe OK · size={{v1}}",
      "t0595": "{{v0}} node probe OK",
      "t0596": "install to {{v0}} and {{v1}}",
      "t0597": "scp failed {{v0}}",
      "t0598": "install conf failed: {{v0}}",
      "t0599": "conf Wrote restart {{v0}} Failed",
      "t0600": "Wrote {{v0}}${restart?",
      "t0601": "Supports: {{v0}}",
      "t0602": "Supports cluster: {{v0}}",
      "t0603": "stop {{v0}} project unit (ok-ish {{v1}})",
      "t0604": "stop not exit ( {{v0}})— dump",
      "t0605": "and {{v0}} RDB (skipped dump)",
      "t0606": "done → {{v0}}",
      "t0607": "createuser {{v0}} uid={{v1}}",
      "t0608": "user {{v0}}",
      "t0609": "useradd failed: {{v0}}",
      "t0610": "chown failed: {{v0}}",
      "t0611": "home, skipped chown: {{v0}}",
      "t0612": "dump or: {{v0}}",
      "t0613": "RDB: {{v0}}",
      "t0614": "restore RDB → {{v0}}",
      "t0615": "RDB Failed: {{v0}}",
      "t0616": "redis start/ping: {{v0}}",
      "t0617": ": {{v0}} — dump dataDir rsync to (dumpRelPath)",
      "t0618": "cannottarget sha256: {{v0}}",
      "t0619": "ysk.json sha256 {{v0}}...",
      "t0620": "ysk.json local={{v0}} remote={{v1}}",
      "t0621": "local dataDir: {{v0}}",
      "t0622": "dataDir: {{v0}}",
      "t0623": "skipped home: {{v0}}",
      "t0624": "home dataDir, dataDir: {{v0}}",
      "t0625": "rsync home failed {{v0}}",
      "t0626": "transfer: home rsync Failed {{v0}}",
      "t0627": "skipped: {{v0}}",
      "t0628": "transfer done → {{v0}}:{{v1}}",
      "t0629": "Project {{v0}} has no system user yet (home missing: {{v1}}). Finish isolation on the project page.",
      "t0630": "project {{v0}} bind_ip={{v1}} — can ( IP )",
      "t0631": "project {{v0}} home not path: {{v1}}",
      "t0632": "Orphan home on disk (no matching store project): {{v0}}",
      "t0633": "Maildir: {{v0}}",
      "t0634": "{{v0}} — cannot to target",
      "t0635": "cannotprobe {{v0}}",
      "t0636": "{{v0}} · {{v1}}",
      "t0637": "project {{v0}} · {{v1}} · DB {{v2}} · Redis {{v3}}",
      "t0638": "Install software {{v0}} · homes {{v1}}",
      "t0639": "cutover host {{v0}}",
      "t0640": "{{v0}} warning(s) — review before cutover.",
      "t0641": "key {{v0}}",
      "t0642": "cannotkey: {{v0}}",
      "t0643": "targetnot write authorized_keys: {{v0}}",
      "t0644": "{{v0}} install ( key )",
      "t0645": "deletekeyFailed: {{v0}}",
      "t0646": "{{v0}} Available",
      "t0647": "dataDir: {{v0}}",
      "t0648": "~{{v0}}",
      "t0649": "Available {{v0}} (dump )",
      "t0650": ": Available {{v0}}, ≥ {{v1}}",
      "t0651": "Warning {{v0}} (not )",
      "t0652": "SSH connection {{v0}}",
      "t0653": "user {{v0}} not root (MVP requires root)",
      "t0654": "Supports OS ({{v0}}); requires Debian/Ubuntu",
      "t0655": "targetAvailable {{v0}} ≥ {{v1}}",
      "t0656": "target: Available {{v0}}, requires {{v1}}",
      "t0657": "target {{v0}}/ysk.json — deny ( forceWipeTarget)",
      "t0658": "targetdirectory ysk.json: {{v0}}",
      "t0659": "targetdirectorycreate: {{v0}}",
      "t0660": "{{v0}}s",
      "t0661": "{{v0}}s ≥ 120s ( TLS/TOTP)",
      "t0662": "project {{v0}} bind_ip={{v1}} — for (interface)",
      "t0663": "{{v0}} project.bind_ip",
      "t0664": "cannot persist bind_ip: {{v0}}",
      "t0665": "nginx sync: {{v0}}",
      "t0666": ": {{v0}}",
      "t0667": "identity {{v0}} unavailable",
      "t0668": "SSH failed exit={{v0}}: {{v1}}",
      "t0669": "path: {{v0}}",
      "t0670": "rsync failed exit={{v0}}: {{v1}}",
      "t0671": "Redis RDB Wrote {{v0}} (--rdb)",
      "t0672": "--rdb failed: {{v0}}",
      "t0673": "BGSAVE failed: {{v0}}",
      "t0674": "Redis RDB {{v0}} → {{v1}} (BGSAVE)",
      "t0675": "cannot Redis RDB (src={{v0}})",
      "t0676": "{{v0}} {{v1}} {{v2}}",
      "t0677": "home, skipped: {{v0}}",
      "t0678": "home {{v0}}",
      "t0679": "Maildir: {{v0}}",
      "t0680": "maildir {{v0}}",
      "t0681": "ysk.json fingerprint (can reapply )local≠source",
      "t0682": "readiness Error: {{v0}}",
      "t0683": "DNS cutover: with A/AAAA IP → {{v0}}{{v1}}",
      "t0684": "verify Failed: {{v0}} mismatch",
      "t0685": "verify passed (mismatches={{v0}})",
      "t0686": "invalid target: {{v0}} (requires root@host or host)",
      "t0687": "not found job {{v0}}",
      "t0688": ": target YSK_EXECUTE=1 ysk-server migrate post --job {{v0}} --data-dir {{v1}}",
      "t0689": "done → {{v0}}",
      "t0690": "cutover host: {{v0}}",
      "t0691": "post done @ {{v0}}",
      "t0692": "Not found job {{v0}} ( dataDir rsync)",
      "t0693": "not Success ({{v0}})",
      "t0694": "bootstrap done → {{v0}}",
      "t0695": "not Failed: {{v0}}",
      "t0696": "Supports mode: {{v0}}",
      "t0697": "Not found edge node: {{v0}}",
      "t0698": "node {{v0}} edge ( or origin)",
      "t0699": "Supports DNS: {{v0}}",
      "t0700": "Supports SSL mode: {{v0}}",
      "t0701": "CDN {{v0}}",
      "t0702": "origin shield Node does not exist: {{v0}}",
      "t0703": "edges: {{v0}}",
      "t0704": "Origin URL (from project bind): {{v0}}",
      "t0705": "update CDN {{v0}}",
      "t0706": "create CDN {{v0}}",
      "t0707": "origin shield: edge shield {{v0}} → {{v1}}",
      "t0708": "origin.kind=project not projectOriginUrl — {{v0}}",
      "t0709": "edge {{v0}} ({{v1}}): planned (not fan-out — PR-C3)",
      "t0710": "edge {{v0}}: node",
      "t0711": "Wrote managed nginx: {{v0}}",
      "t0712": "Wrote edge: {{v0}}",
      "t0713": "local nginx -t failed (proxy_cache_path can http{}): {{v0}}",
      "t0714": "certId={{v0}} domain={{v1}}",
      "t0715": "certId={{v0}} File does not exist: {{v1}}",
      "t0716": "not found certId={{v0}}",
      "t0717": "dataDir certificate {{v0}}",
      "t0718": "local Let’s Encrypt {{v0}}",
      "t0719": "scp failed {{v0}}",
      "t0720": "mkdir failed {{v0}}",
      "t0721": "certbot failed: {{v0}}",
      "t0722": "originShieldNodeId={{v0}} — shield",
      "t0723": "{{v0}}: SSH target — SSH apply (skipped fleet )",
      "t0724": "fleet cannot (blocked={{v0}})— enqueue or SSH",
      "t0725": "fleet {{v0}} edge — queued ≠ agent nginx reload; Agents",
      "t0726": "fleetAgentId={{v0}} — requires fleet enqueue (API will); or SSH apply",
      "t0727": "not found conf: {{v0}}",
      "t0728": "conf Failed: {{v0}}",
      "t0729": "fleet enqueue failed: {{v0}}",
      "t0730": "nginx -t failed: {{v0}}",
      "t0731": "SSH mkdir failed: {{v0}}",
      "t0732": "scp failed: {{v0}}",
      "t0733": "remote reload failed: {{v0}}",
      "t0734": "fleetAgentId={{v0}} — purge fleet enqueue or SSH",
      "t0735": "enqueue failed: {{v0}}",
      "t0736": "purge failed: {{v0}}",
      "t0737": "remote purge failed: {{v0}}",
      "t0738": "fleet purge {{v0}} — queued ≠ edge purge",
      "t0739": "geo {{v0}}: Unknownnode {{v1}}",
      "t0740": "weighted maxRr={{v0}} ( {{v1}})",
      "t0741": "minHealthyEdges={{v0}} {{v1}} edge —: IP edge ( offline)",
      "t0742": "edge {{v0}} — skipped",
      "t0743": "probe {{v0}}: {{v1}}",
      "t0744": "zoneId={{v0}} ({{v1}})",
      "t0745": "{{v0}} user manage {{v1}} — CDN write managedBy=cdn (can and; please check zone)",
      "t0746": "geo subdomain {{v0}}: IP — skipped",
      "t0747": "access_log {{v0}} ({{v1}} cache status token)",
      "t0748": "read log {{v0}}",
      "t0749": "cache directory {{v0}} ≈ {{v1}} bytes (not )",
      "t0750": "cache {{v0}}/{{v1}}",
      "t0751": "IPv4 invalid: {{v0}}",
      "t0752": "IPv6 invalid: {{v0}}",
      "t0753": "CDN node {{v0}}",
      "t0754": "HTTP {{v0}} ( for ){{v1}}",
      "t0755": "HTTP Failed: {{v0}}",
      "t0756": "TCP {{v0}}:443/80 cannotconnection",
      "t0757": "{{v0}}/{{v1}}",
      "t0758": "list-units failed: {{v0}}",
      "t0759": "{{v0}} service units",
      "t0760": "unit {{v0}}",
      "t0761": "{{v0}} bytes",
      "t0762": "journalctl · {{v0}}",
      "t0763": "did vacuum: {{v0}}",
      "t0764": "vacuum failed: {{v0}}",
      "t0765": "filter: {{v0}}",
      "t0766": "file {{v0}} · {{v1}} bytes · {{v2}}",
      "t0767": "path allowlist: {{v0}}",
      "t0768": "Journal: ≈{{v0}} MB ( {{v1}} MB)",
      "t0769": "project {{v0}} · {{v1}} log (directory)",
      "t0770": "Exported {{v0}} ({{v1}})",
      "t0771": "not to {{v0}}",
      "t0772": "(DB-IP City Lite {{v0}}; Failed)",
      "t0773": "fallback {{v0}}",
      "t0774": ": {{v0}} · {{v1}} · {{v2}} · {{v3}}{{v4}} · ASN {{v5}}",
      "t0775": "file ({{v0}} B), can Download failed",
      "t0776": "{{v0}} fallback (Success)",
      "t0777": "update {{v0}} ({{v1}} B)",
      "t0778": "Update failed {{v0}}: {{v1}}{{v2}}",
      "t0779": "Not foundsettings: {{v0}}",
      "t0780": "cannotsettings: {{v0}}",
      "t0781": "Not foundcertificate: {{v0}}",
      "t0782": "dry-run: not systemctl {{v0}}. add --execute YSK_EXECUTE=1 + root firstreally",
      "t0783": "not found job {{v0}}",
      "t0784": "Web UI: Not found (build apps/web or set YSK_WEB_ROOT)\\n",
      "t0785": "DNS zone create (draft): {{v0}}",
      "t0786": "DNS zone Create failed: {{v0}}",
      "t0787": "maildomain: {{v0}}",
      "t0788": "maildomainCreate failed: {{v0}}",
      "t0789": "to {{v0}} can off cron",
      "t0790": "restic {{v0}}/{{v1}} ok",
      "t0791": ": {{v0}} {{v1}}",
      "t0792": "settings {{v0}}. --force.",
      "t0793": "settings {{v0}}",
      "t0794": "Not foundinterface {{v0}}",
      "t0795": "hostname failed: {{v0}}",
      "t0796": "pretty hostname failed: {{v0}}",
      "t0797": "timezone failed: {{v0}}",
      "tScoreFrom": "score={{score}} from={{from}}",
      "appliedTag": " (applied)",
      "writtenTag": " (written only)",
      "selfDestMissing": "Cannot find the running install directory (systemd ExecStart or cli.js)",
      "selfDestUnwritable": "Cannot write to the running install directory {{v0}}",
      "selfApplied": "Applied {{v0}} onto {{v1}}",
      "selfVerifyFail": "Version file after overlay does not contain {{v0}}",
      "selfDownloadFail": "Cannot download or unpack official package {{v0}}: {{v1}}",
      "selfOverlayFail": "Could not overlay the official package onto the running install: {{v0}}",
      "selfUpgradeHint": "Panel apply failed. As root run: curl -fsSL https://raw.githubusercontent.com/yanshekki/ysk-server/main/install.sh | bash -s -- --upgrade"
    },
    "tpl": {
      "deleted": "Deleted {{name}}",
      "removed": "Removed {{name}}",
      "failedDetail": "Failed: {{detail}}",
      "failedColon": "Failed: {{detail}}",
      "actionFailed": "{{action}} failed: {{detail}}",
      "restartFailed": "Restart failed: {{detail}}",
      "chownFailed": "chown failed: {{detail}}",
      "available": "Available: {{detail}}",
      "supportedNotProbed": "Supports {{name}} — not probed yet",
      "wrote": "Wrote {{path}}",
      "wroteSettings": "Wrote settings {{path}}",
      "wroteManaged": "Wrote managed file {{path}}",
      "copyFailed": "Copy failed: {{detail}}",
      "copyFailed2": "Copy failed: {{detail}}",
      "reloadFailed": "Reload failed: {{detail}}",
      "reloadFailed2": "Reload failed: {{detail}}",
      "nginxReloadFailed": "nginx reload failed: {{detail}}",
      "nginxTestFailed": "nginx -t failed: {{detail}}",
      "nginxConfigFailed": "Nginx config check failed: {{detail}}",
      "psqlFailed": "psql failed: {{detail}}",
      "redisCliFailed": "redis-cli failed: {{detail}}",
      "restartFailed2": "restart failed: {{detail}}",
      "missing": "Missing {{name}}",
      "project": "Project {{name}}",
      "logNotFound": "Log not found: {{path}}",
      "clusterNotFound": "Cluster not found: {{id}}",
      "domainInvalid": "Invalid domain: {{domain}}",
      "exported": "Exported {{path}}",
      "reenabledLink": "Re-enabled connection {{name}}",
      "installed": "Installed",
      "missingDataDir": "Missing dataDir",
      "installIncomplete": "Install incomplete",
      "noPackages": "No packages",
      "recentlyUpdated": "Recently updated",
      "needRootRead": "Requires root to read",
      "reenabledPersist": "Connection re-enabled (survives reboot)",
      "runtimeOnlyHint": "(May not persist across reboot; use Save to persist)",
      "statusWrittenPartial": "Status: written/partial",
      "keyMissingOrNotDeleted": "Key missing or not deleted",
      "passwordCryptStored": "Password stored as crypt hash (not plaintext)",
      "skipInvalidUsername": "Skipped invalid username",
      "digNoAnswer": "dig: no answer (NXDOMAIN or empty)",
      "ipAddrAddFailed": "ip addr add failed: {{detail}}",
      "ipAddrDelFailed": "ip addr del failed: {{detail}}",
      "connUpWarn": "connection up warning: {{detail}}",
      "ntpEnableFailed": "Enable NTP failed: {{detail}}",
      "cancelFailed": "Cancel failed: {{detail}}",
      "powerCmdFailed": "Power command failed: {{detail}}",
      "reniceFailed": "renice failed: {{detail}}",
      "pgIncludeHint": "Include this file in postgresql.conf, or copy it when applying",
      "none": "none",
      "success": "Success",
      "on": "on",
      "off": "off",
      "continueOp": "continue",
      "unavailable": "unavailable",
      "unknownError": "unknown error",
      "noParen": "(none)",
      "keepOldDb": "(kept old DB)",
      "ufwNotDetected": "UFW not detected on this host",
      "fail2banStartHint": "Start it on the fail2ban page",
      "hasExecuteNotRoot": "EXECUTE is on but process is not root",
      "notRootTarget": "Not root (target useradd/apt will be blocked)",
      "reapplyDone": "reapply key steps completed",
      "someFailed": "Some failed — see results",
      "securityDesc": "Passwords, TLS, local limits",
      "yskControlPlane": "YSK control plane",
      "sslDistributeNote": "SSL distribute: cert on edge ≠ full browser trust chain; verify with dig / curl -vI https://",
      "autoNever": "Never automatic",
      "autoManualEmergency": "Manual EMERGENCY only",
      "probeMech": "Public TCP, panel req/min, TCP inuse, fail2ban, UFW",
      "probeTunable": "Raise / lower thresholds",
      "priorityBlockers": "Address {{count}} blocker(s) first: {{list}}",
      "readinessNotProduction": "Readiness is not production-ready: {{list}}",
      "noRestart": "no restart",
      "cityPolicyOff": "(city policy off)",
      "pidStarted": "Process started pid={{pid}} {{extra}}",
      "pidUser": "(user={{user}})",
      "pidDegraded": "(degraded)",
      "killFailed": "kill -s {{sig}} failed: {{detail}}",
      "routeAdded": "Added route {{dst}}{{via}}{{dev}}",
      "dnsWritten": "Wrote {{conn}}: DNS {{dns}}{{search}}",
      "peerInstalled": "Installed to {{dest}}{{restart}}"
    },
    "installedTool": "Installed (tool)",
    "cron": {
      "preserveHostLines": "Preserved {{count}} non-YSK host crontab line(s) (not a full wipe).",
      "noHostLinesOrEmpty": "No extra non-YSK host crontab lines (or empty).",
      "installReplacesYskOnly": "Install updates YSK-marked jobs only; other host jobs were merged and kept.",
      "hostScanNeedRoot": "Reading other users’ crontabs requires the control plane as root; only the process user’s crontab is listed.",
      "hostScanSkipUser": "Skipped user {{user}} (no permission)",
      "hostUserInvalid": "Invalid crontab user.",
      "hostScheduleInvalid": "Invalid host cron schedule.",
      "hostLineNotJob": "That crontab line is not a job.",
      "hostLineMissing": "No matching crontab line (host crontab may have changed).",
      "hostLineDuplicate": "That job line appears {{count}} times; edit one unique line first.",
      "hostReadFailed": "Could not read crontab: {{detail}}",
      "hostWriteFailed": "crontab write failed: {{detail}}",
      "hostRewriteNeedExecute": "Writing a host crontab line needs root and YSK_EXECUTE=1. Preview only.",
      "hostRewriteNeedRoot": "Editing another user’s crontab needs the control plane as root.",
      "hostPreview": "Next line: {{line}}",
      "hostPreviewDelete": "Next: remove that line.",
      "hostRewritten": "Wrote crontab for {{user}}.",
      "hostRunNeedExecute": "Running a host cron command needs YSK_EXECUTE=1.",
      "hostRan": "Ran host cron command as {{user}}.",
      "hostAdoptNeedExecute": "Adopting a host line into the panel needs YSK_EXECUTE=1 (otherwise install would duplicate it).",
      "hostAdopted": "Host line tagged # ysk:{{id}} and registered in the panel.",
      "hostConfirmMismatch": "Confirm must match the command.",
      "hostAdoptOnlyInstallUser": "Take into panel only for the crontab Install writes (root / this process user). Other users would be duplicated on install.",
      "hostAdoptEnableFirst": "Enable the host line before taking it into the panel.",
      "hostPercentNewline": "crontab treats unescaped % as a newline. Write date formats as \\%Y (or avoid %)."
    },
    "dbBrowser": {
      "pmaInstalled": "phpMyAdmin installed at {{path}}",
      "pmaConfigWritten": "phpMyAdmin config and tmp written (cookie auth; HTTPS recommended)",
      "pmaExtractFailed": "phpMyAdmin download/extract failed: {{detail}}",
      "projectCreated": "Project created {{id}} ({{name}})"
    },
    "firewallAllow": {
      "already": "{{port}}/{{proto}}{{from}}: already allowed",
      "partial": "Partial: {{ok}} ok, {{fail}} failed",
      "fromLabel": " from {{from}}"
    },
    "firewallDeleteByComment": {
      "removed": "Removed {{n}} firewall rule(s) matching {{prefix}}",
      "none": "No firewall rules matched {{prefix}}"
    },
    "serviceExposure": {
      "needsDecision": "{{service}}: confirm whether to expose this service on the network",
      "private": "{{service}}: kept private (no public firewall allow)",
      "restrictedEmpty": "Restricted mode needs at least one allowed IP/CIDR",
      "badCountry": "Invalid country code: {{cc}}",
      "zoneDownloadFail": "Country zone download failed for {{cc}}: {{detail}}",
      "zoneEmpty": "Country zone for {{cc}} is empty",
      "zoneDownloaded": "Downloaded {{n}} CIDRs for {{cc}}",
      "zoneMissing": "No zone file for {{cc}} — place under geoip/country-zones or allow download",
      "zoneCidrCap": "Country CIDR list capped at {{n}} entries",
      "geoNeedExecute": "Country allowlist needs YSK_EXECUTE",
      "geoNeedRoot": "Country allowlist needs root",
      "geoNoCidrs": "No country CIDRs loaded — cannot apply geo allowlist",
      "ipsetMissing": "ipset not installed — country allowlist skipped",
      "ipsetApplyFail": "ipset/iptables apply failed: {{detail}}",
      "ipsetApplied": "Country allowlist set {{set}} ({{countries}}, {{n}} CIDRs)",
      "ipsetCleared": "Cleared country ipset {{set}}",
      "geoBestEffort": "Country filtering is best-effort (ipset); cloud security groups are separate"
    },
    "goLive": {
      "deployIncomplete": "goLive: deploy incomplete",
      "deployFailed": "goLive deploy failed: {{detail}}",
      "publishIncomplete": "goLive: publish incomplete",
      "publishFailed": "goLive publish failed: {{detail}}"
    },
    "ops": {
      "projectNameExists": "Project name already exists: {{name}}",
      "sslNotReady": "SSL not ready: no certificate for {{domain}}.",
      "sslNotReadyDetail": "SSL not ready: no certificate for {{domain}} (panel SSL or Let’s Encrypt live path).",
      "sslGoToPage": "Issue or upload a certificate on SSL, then publish + SSL.",
      "sslRejectWrite": "Refused to write SSL nginx conf to avoid nginx -t failure.",
      "installAborted": "Install aborted (client disconnected or cancelled)",
      "phpPackagesPartialFail": "Some PHP packages failed: {{list}} (core CLI may still work)",
      "pdnsBindConflict": "PowerDNS cannot bind 0.0.0.0:53 (in use); often conflicts with systemd-resolved. Bind the public IP (panel: Fix PowerDNS)."
    },
    "webmail": {
      "notInstalled": "Webmail is not installed; enable download and re-run",
      "needExecute": "Downloading webmail needs system-change permission (YSK_EXECUTE) and outbound network",
      "needExecuteBeforeCreate": "Will not create a half project until EXECUTE is enabled",
      "notRoundcubeTree": "Document root is not a full Roundcube tree (may still be php-hello)",
      "notSnappyTree": "Document root is not a full SnappyMail tree",
      "installIncompleteHint": "Project exists but webmail is incomplete — enable EXECUTE then Reinstall/Upgrade",
      "extractFailed": "{{tool}} download or extract failed: {{detail}}",
      "roundcubeInstalled": "Installed Roundcube {{version}} → {{path}}",
      "roundcubeReuse": "Reusing installed Roundcube → {{path}}",
      "roundcubeConfigWritten": "Wrote Roundcube config (SQLite, IMAP 993, SMTP 587)",
      "snappyInstalled": "Installed SnappyMail {{version}} → {{path}}",
      "snappyReuse": "Reusing installed SnappyMail → {{path}}",
      "snappyAdminHint": "On first open, finish SnappyMail admin setup and add the local IMAP domain",
      "imapSmtpHint": "IMAP {{imap}}:993 · SMTP {{smtp}}:587 (login with full mailbox address and password)",
      "projectCreated": "Created PHP project {{name}} ({{tool}}, {{id}})",
      "domainRequired": "Webmail hostname is required",
      "openHint": "Sign in with mailbox address and password; open the URL from Projects or this page after go-live",
      "sslHint": "Recommend Let’s Encrypt for {{domain}} (SSL page)",
      "bootstrapLegacyHint": "Bootstrap had no project service — wrote dataDir skeleton; use Create & go live in the panel for PHP project path",
      "ssoPluginInstalled": "Installed SSO plugin → {{path}}",
      "forceHttpsOn": "Roundcube force_https enabled (HTTPS required)",
      "forceHttpsOff": "force_https off — after SSL, reinstall with force HTTPS checked",
      "reinstallHint": "Project exists — use Reinstall/Upgrade or reinstall:true",
      "reinstalling": "Reinstalling webmail into project {{name}} ({{id}})",
      "reinstallStart": "Starting reinstall/upgrade (version pin {{version}}, project {{id}})",
      "projectNotFound": "Webmail project not found",
      "snappyAdminOnce": "SnappyMail admin {{user}} — password shown once (see result / ONCE file)",
      "snappyAdminPassword": "SnappyMail admin password (copy now): {{password}}",
      "publicHtmlStub": "Document root still has the SnappyMail/RainLoop package stub. HTTP must serve the public_html app tree — reinstall webmail after this fix.",
      "goLiveFailed": "Webmail files installed, but project go-live / deploy health failed — expand details.",
      "forceHttpsNeedsSsl": "Roundcube force_https is on: bind SSL for this hostname before relying on public HTTPS, or uncheck force HTTPS until then.",
      "roundcubePublicHtmlDocRoot": "HTTP doc root set to Roundcube public_html ({{path}})",
      "docRootUpdated": "Project document root updated to {{path}}",
      "docRootUpdateFailed": "Could not update project document root: {{detail}}",
      "sqliteSchemaReady": "Roundcube SQLite schema initialized",
      "sqliteSchemaFailed": "Roundcube SQLite schema init failed: {{detail}}",
      "snappyFullEmailLogin": "Mailbox login must use full email (user@domain); short local-part is disabled",
      "removedBogusPublicHtml": "Removed leftover public_html (php-hello) so webmail is not served from the wrong tree",
      "snappyDocRoot": "SnappyMail HTTP doc root: {{path}}",
      "phpHelloStillPresent": "Install left php-hello (YSK PHP OK) as the site root — webmail extract did not replace it"
    },
    "vpn": {
      "needInstall": "Install {{engine}}",
      "openvpnComing": "OpenVPN full path is staged for the next release.",
      "outlineComing": "Outline / Shadowsocks is staged for a later release.",
      "needExecuteServer": "VPN server setup requires root and YSK_EXECUTE=1.",
      "serverStopped": "{{engine}} server stopped.",
      "serverStopFailed": "Could not stop {{engine}} server: {{detail}}",
      "needExecuteClient": "VPN client connect requires root and YSK_EXECUTE=1.",
      "keygenFailed": "WireGuard key generation failed (is wg installed?).",
      "serverKeysCreated": "WireGuard server keys created.",
      "applyFailed": "Failed to apply WireGuard config: {{detail}}",
      "serverActive": "WireGuard server applied (UDP {{port}}).",
      "serverMissing": "WireGuard server not initialized — run Start server first.",
      "peerCreated": "Client «{{name}}» created.",
      "peerNotFound": "Client not found.",
      "peerRemoved": "Removed {{name}}.",
      "peersSynced": "Peer list reloaded on the running WireGuard interface.",
      "setEndpointHint": "Set public endpoint (host:port) so mobile clients can reach this server.",
      "invalidConf": "This file is not a valid VPN client conf. Use a WireGuard or OpenVPN client profile.",
      "clientImported": "Profile «{{name}}» imported.",
      "profileNotFound": "Client profile not found.",
      "clientUpFailed": "Connect failed: {{detail}}",
      "clientUp": "Connected: {{name}}",
      "clientDown": "Disconnected: {{name}}",
      "clientDeleted": "Deleted profile: {{name}}",
      "autostartOn": "Autostart on: {{name}}",
      "autostartOff": "Autostart off: {{name}}",
      "ovpnPkiStart": "Generating OpenVPN PKI (may take a minute for DH params)…",
      "ovpnPkiDone": "OpenVPN PKI ready.",
      "ovpnServerActive": "OpenVPN server applied ({{proto}} {{port}}).",
      "invalidOvpn": "OpenVPN conf should include client/remote directives.",
      "ssHonest": "Uses shadowsocks-libev ss-server — not full Outline Manager.",
      "ssKeysCreated": "Shadowsocks server password generated.",
      "ssServerActive": "Shadowsocks server applied (port {{port}}).",
      "ssSharedPassword": "All ss:// labels share one server password (rotate by re-ensuring server).",
      "ssPackageYielded": "Stopped/masked Debian shadowsocks-libev default unit so YSK can bind public {{port}} on this host.",
      "ssEndpointAutofilled": "Public endpoint set to {{endpoint}}.",
      "ssClientsRewritten": "Regenerated {{n}} client ss:// URI(s) for current endpoint/password.",
      "ssUfwOpened": "Opened UFW {{port}}/tcp+udp for Shadowsocks (if ufw installed).",
      "endpointAutofilled": "Public endpoint set to {{endpoint}}.",
      "ovpnClientsRewritten": "Updated remote= in {{n}} OpenVPN client profile(s) for download/QR.",
      "accessFullNat": "Full internet enabled (IP forward + NAT)",
      "accessLanOnly": "LAN-only mode (no internet NAT)",
      "accessReconnectHint": "Already-connected clients must reconnect to pick up new routes",
      "ovpnNatDurable": "OpenVPN NAT/forward installed for reboot (systemd ExecStartPost).",
      "clientFullTunnelProtect": "Full-tunnel client detected (AllowedIPs 0.0.0.0/0). Applied host protect so panel/SSH replies stay on the LAN NIC.",
      "clientFullTunnelHint": "Tip: for split access only, set AllowedIPs to VPN/LAN CIDRs (not 0.0.0.0/0) in the conf, then reconnect."
    },
    "vnc": {
      "needInstall": "Install {{stack}}",
      "needExecute": "YSK_EXECUTE is disabled — cannot install packages or provision Linux users.",
      "needRoot": "Not running as root — system useradd and vncserver apply are blocked.",
      "hostnameResolves": "Hostname {{hostname}} resolves.",
      "hostnameUnresolvable": "This host cannot resolve its own hostname ({{hostname}}). VNC session start will fail until /etc/hosts is fixed.",
      "hostnameAlreadyResolves": "Hostname {{hostname}} already resolves — /etc/hosts unchanged.",
      "hostnameWouldAppend": "Would append to /etc/hosts: {{line}}",
      "hostnameAppended": "Appended to /etc/hosts: {{line}}",
      "hostnameAppendFailed": "Could not write /etc/hosts: {{detail}}",
      "hostnameAliasPresent": "Hostname {{hostname}} is already an exact /etc/hosts alias — not appended again.",
      "hostnameStillUnresolvable": "Wrote /etc/hosts but {{hostname}} still does not resolve. Confirm nsswitch hosts includes files.",
      "skipStartHostname": "Did not start the display — fix hostname resolution first.",
      "novncAssetsOnly": "noVNC web assets found; websockify binary still missing.",
      "viewerNeedExecute": "Starting a local VNC desktop for browser view needs root + YSK_EXECUTE",
      "browserSessionReady": "Browser VNC session ready: {{name}}",
      "clientPathUserReachable": "Path: user-reachable endpoint — {{name}} → {{target}} (browser via panel)",
      "clientPathServerProxy": "Path: server proxy — {{name}} → {{target}} (egress via this server)",
      "clientOpenInBrowserHint": "Use “Open in browser” on the client list for the embedded VNC client",
      "probeOk": "Reachability OK: control plane can open TCP to {{target}}",
      "probeRefused": "Nothing is listening on {{target}} (connection refused). Is VNC running on that host?",
      "probeTimeout": "Timed out connecting to {{target}} from this server. Check firewall / routing.",
      "probeDns": "Cannot resolve host name «{{host}}».",
      "probeNet": "Network unreachable for {{target}} from this server.",
      "probeFailed": "Cannot reach {{target}}: {{detail}}",
      "probeInvalid": "Invalid VNC target {{host}}:{{port}}",
      "probeHintUserReachable": "Path is “user-reachable”: this panel must still open TCP to the public host (browser cannot speak RFB alone).",
      "probeHintServerProxy": "Path is “server proxy”: the target must be reachable from this control-plane host’s network.",
      "connectHostOverride": "Server proxy: display host {{display}}, TCP connects to {{connect}}",
      "probeConnectHostHint": "Display target {{display}}, probe/connect address {{connect}} (connect-host override).",
      "accountNotFound": "VNC account not found",
      "accountExists": "A VNC account with this name or Linux user already exists",
      "accountCreated": "Created VNC account {{name}} ({{user}}, display :{{display}})",
      "accountUpdated": "Updated VNC account {{name}}",
      "accountDeleted": "Deleted VNC account {{name}}",
      "invalidName": "Invalid account name",
      "invalidGeometry": "Invalid resolution (use e.g. 1920x1080)",
      "displayBusy": "Display number is invalid or already in use",
      "displayExhausted": "No free VNC display numbers left in range",
      "userWrittenOnly": "Linux user {{user}} recorded in control plane only (need root + YSK_EXECUTE to useradd)",
      "userExists": "Linux user {{user}} already exists",
      "userCreated": "Created Linux user {{user}}",
      "useraddFailed": "useradd failed for {{user}}: {{detail}}",
      "userdelBlocked": "Cannot remove Linux user {{user}} without root + YSK_EXECUTE",
      "userAlreadyGone": "Linux user {{user}} already absent",
      "userdelFailed": "userdel failed for {{user}}: {{detail}}",
      "userdelLeftover": "Panel account removed, but Linux user {{user}} is still on the host. Remove it from Users or the host.",
      "userDeleted": "Removed Linux user {{user}}",
      "passwordTooShort": "VNC password must be at least 6 characters",
      "passwordWrittenOnly": "Password marked in control plane only (need root + YSK_EXECUTE for vncpasswd)",
      "passwordFailed": "Failed to write VNC password: {{detail}}",
      "passwordNeedTiger": "vncpasswd not found. Install TigerVNC (tigervnc-standalone-server) before setting a password.",
      "passwordSet": "VNC password set for {{user}}",
      "passwordUpdated": "Password updated for {{name}}",
      "passwordMetaOnly": "Password stored as meta only until system apply",
      "xstartupWrittenOnly": "xstartup not written to home (need root + YSK_EXECUTE)",
      "xstartupWriteFailed": "Failed to write ~/.vnc/xstartup ({{detail}}). Need root + YSK_EXECUTE.",
      "xstartupFailed": "VNC xstartup/desktop failed on display :{{display}} ({{detail}}). Prefer XFCE profile or install a terminal.",
      "xstartupWritten": "Wrote {{path}}",
      "sessionStartBlocked": "Cannot start VNC session without root + YSK_EXECUTE",
      "sessionStartFailed": "Failed to start display :{{display}}: {{detail}}",
      "sessionStartHostname": "Failed to start display :{{display}}: this host cannot resolve its own hostname. Add the hostname to /etc/hosts (or fix DNS) then start the session again.",
      "sessionStarted": "Started VNC for {{user}} on :{{display}} (port {{port}})",
      "sessionStartUnverified": "Start command returned OK but RFB port not yet listening",
      "sessionAlreadyRunning": "VNC already running for {{user}} on :{{display}} (port {{port}})",
      "vncserverMissing": "TigerVNC server wrapper (tigervncserver/vncserver) is not installed — use the Install tab",
      "vncserverWrapperMissing": "Found {{found}} but no tigervncserver/vncserver wrapper — reinstall tigervnc-standalone-server",
      "vncPackageWithoutBin": "Package tigervnc-standalone-server is installed but the start script is missing — reinstall the package",
      "needPasswordBeforeStart": "Set a VNC password (≥6 chars) before starting",
      "displayPortBusy": "Display :{{display}} → port {{port}} is already in use — stop the other session or pick another display",
      "sessionStartPermission": "Permission denied starting display :{{display}}",
      "staleLockCleared": "Cleared stale lock for display :{{display}}, retrying",
      "sessionStopBlocked": "Cannot stop VNC session without root + YSK_EXECUTE",
      "sessionStopped": "Stopped VNC for {{user}} display :{{display}}",
      "linuxUserKept": "Kept Linux user {{user}} on the system",
      "novncStartBlocked": "Cannot start noVNC without root + YSK_EXECUTE",
      "novncAlreadyRunning": "noVNC already running on port {{port}}",
      "novncStartFailed": "Failed to start websockify: {{detail}}",
      "novncStarted": "noVNC listening on 127.0.0.1:{{httpPort}} → RFB {{rfbPort}}",
      "novncNotRunning": "noVNC was not running",
      "novncStopBlocked": "Cannot stop noVNC without root + YSK_EXECUTE",
      "novncStopped": "Stopped noVNC on port {{httpPort}}",
      "directNeedsAllBind": "RFB bind is localhost — direct clients cannot reach from outside without tunnel",
      "directOpenFirewall": "Open TCP {{port}} in the firewall for direct clients",
      "viaServerReady": "noVNC is up — open the local URL or use an SSH tunnel",
      "viaServerStartFirst": "Start noVNC to enable browser access via the server",
      "viewTicketIssued": "Issued a short-lived view ticket",
      "invalidPort": "Invalid port number",
      "firewallNeedExecute": "Opening UFW ports requires YSK_EXECUTE",
      "firewallNeedRoot": "Opening UFW ports requires root",
      "firewallFailed": "ufw allow failed: {{detail}}",
      "firewallOpened": "UFW allowed TCP {{port}}",
      "clientInvalid": "Client name and host are required",
      "clientNotFound": "Client profile not found",
      "clientUpBlocked": "Cannot connect VNC client without root + YSK_EXECUTE",
      "clientUpFailed": "Client connect failed: {{detail}}",
      "clientViaServerUp": "Client {{name}} ready for browser VNC via panel (legacy websockify note retired). Target remains reachable through Open in browser.",
      "clientDirectUp": "Client {{name}} uses in-browser VNC only (host vncviewer path removed). Open in browser → {{target}}.",
      "clientNeedViewer": "Desktop vncviewer is optional. Use Open in browser for the embedded VNC client.",
      "clientDownBlocked": "Cannot disconnect without root + YSK_EXECUTE",
      "clientDown": "Disconnected client {{name}}",
      "clientDeleted": "Client profile deleted",
      "sessionStartCwd": "VNC start failed: working directory not accessible to the session user (display :{{display}}). Fixed by starting from HOME.",
      "desktopRestarted": "Desktop profile applied and session restarted ({{desktop}}). Reconnect VNC/noVNC.",
      "desktopNeedsStart": "Desktop profile {{desktop}} written to xstartup. Start the session to apply.",
      "linuxUserRolledBack": "Removed leftover Linux user {{user}} after VNC password failed.",
      "linuxUserOrphan": "Could not remove leftover Linux user {{user}} after VNC password failed."
    },
    "apache": {
      "needServerName": "Server name required",
      "siteExists": "Site already exists",
      "siteNotFound": "Site not found",
      "wroteConf": "Wrote {{path}}",
      "needExecute": "Needs YSK_EXECUTE",
      "settingsWritten": "Apache defaults written",
      "managedDir": "Managed dir {{path}}",
      "dryRun": "Dry run",
      "copyFailed": "Copy failed: {{file}}",
      "configOk": "configtest OK",
      "configFailed": "configtest failed: {{detail}}",
      "reloaded": "Apache reloaded",
      "reloadFailed": "Reload failed",
      "skippedOrphans": "Skipped {{count}} orphan conf(s) (not owned)",
      "artifactInvalid": "Invalid artifact conf name",
      "artifactOwned": "Conf {{file}} is owned by a project or standalone site",
      "artifactNotFound": "Artifact conf not found: {{file}}",
      "artifactRemoveFailed": "Failed to remove {{file}}: {{detail}}",
      "artifactRemoved": "Removed orphan conf {{file}}",
      "artifactSystemPending": "DataDir cleaned; system Apache twin needs YSK_EXECUTE/root to disable",
      "artifactSystemDisabled": "Disabled system site {{site}}",
      "artifactSystemFailed": "System disable failed: {{detail}}",
      "conflictProjectsOnly": "Domain {{name}} is claimed by multiple projects — change a project domain",
      "cleanupNothing": "No conflicting artifact confs to remove",
      "conflictOwnedKeep": "Kept owned conf {{file}} (also ServerName {{domain}})",
      "retiredOrphan": "Retired orphan conf {{file}} (ServerName clash with {{domain}})"
    },
    "btTracker": {
      "needExecute": "YSK_EXECUTE is off — tracker install/start and public ports need system-change permission.",
      "startWithoutExecute": "Starting tracker without YSK_EXECUTE — listen may work; host firewall will not be opened.",
      "alreadyRunning": "BitTorrent tracker is already running in this process.",
      "notRunning": "BitTorrent tracker is not running.",
      "started": "BitTorrent tracker listening on port {{port}}.",
      "startFailed": "Failed to start tracker: {{detail}}",
      "stopped": "BitTorrent tracker stopped.",
      "maxSeeds": "Maximum concurrent seeds reached ({{n}}).",
      "seedStarted": "Seeding share {{id}}.",
      "seedStopped": "Stopped seeding share.",
      "seedPending": "Seeding not ready yet — start the tracker and ensure YSK_EXECUTE when required.",
      "notSeeding": "This share is not currently seeded by the control plane.",
      "btNeedsTracker": "BT share needs a running tracker. Open Files → BT Tracker and start it.",
      "restoreTrackerFailed": "BT tracker failed to start during boot restore",
      "restoreDone": "BT restore: seeded {{seeded}}/{{attempted}} (failed {{failed}})",
      "workerMissing": "Detached worker script missing; started in-process (dies with this process)",
      "startedDetached": "BT tracker detached worker started (pid {{pid}}, port {{port}})",
      "runningDetached": "Tracker running as detached worker (pid {{pid}})",
      "jobQueued": "BT torrent creation queued (large share)",
      "jobRunning": "BT torrent creation running",
      "libraryAdded": "Added {{name}} to the WebTorrent library",
      "libraryInspectFailed": "Could not read that .torrent or magnet",
      "libraryDup": "That torrent is already in the library",
      "libraryDestBad": "Save folder is not a valid Files path",
      "libraryTorrentTooBig": ".torrent file is larger than 8 MiB",
      "libraryNotFound": "Library item not found",
      "libraryPaused": "Paused",
      "libraryResumed": "Resumed",
      "libraryRemoved": "Removed from library",
      "libraryFilesRemoved": "Deleted downloaded files",
      "libraryRestoreDone": "Library restore: started {{started}}/{{attempted}} (failed {{failed}})",
      "applyTrackersDone": "Applied extra trackers to {{n}} live announce slots",
      "libraryNeedServe": "Saved. Open the panel (ysk-server serve) so WebTorrent can download or seed.",
      "libraryDestIsFile": "Cannot create a folder named {{name}} — a file with that name already exists.",
      "librarySeedMissing": "No matching files in that folder to seed.",
      "libraryWaitingPeers": "Waiting for peers. If the files are already on this host, add again and choose seed-existing."
    },
    "migrate": {
      "orphanConfirm": "Type the exact leftover home path to confirm delete.",
      "orphanStillInStore": "That home still belongs to a project in the store.",
      "orphanMissing": "Path not on disk: {{path}}",
      "orphanNeedExecute": "Would remove leftover {{path}}. Needs YSK_EXECUTE=1.",
      "orphanRmFailed": "Could not remove leftover home: {{detail}}",
      "orphanRemoved": "Removed leftover project home {{path}}."
    },
    "publicFiles": {
      "liveConf": "Live Nginx conf: {{path}}",
      "publicRoot": "Public root: {{path}}",
      "confNameStale": "Conf file {{file}} does not match current server_name {{serverName}}. Re-apply public files to rewrite the name."
    },
    "leftover": {
      "staleCliTitle": "Stale leftover CLI",
      "staleCli": "Leftover CLI still present: {{path}} (running product {{version}}). PATH may prefer it. Remove with: rm -f {{path}}",
      "apacheDefaultTitle": "Apache leftover default site",
      "apacheDefault": "Apache 000-default is still enabled. That is the stock site file — it does not mean Apache is listening on public :80 (YSK Apache is expected on 127.0.0.1:8080). Overlay does not disable it. Apply Apache from the panel or hosting apache apply --execute.",
      "nginxCatchAllTitle": "Nginx catch-all missing",
      "nginxCatchAll": "ysk-000-default.conf is not in /etc/nginx/conf.d. Unknown SNI can fall through. Run projects nginx-sync --execute.",
      "vsftpdTitle": "vsftpd unit failed",
      "vsftpd": "vsftpd is failed. Overlay does not rewrite listen/listen_ipv6. Apply FTP from the panel.",
      "dovecotTitle": "Dovecot TLS points at missing cert",
      "dovecot": "Dovecot ssl_cert points at missing {{path}}. Overlay does not rewrite ssl=no. Apply mail TLS after issuing the cert, or apply email stack.",
      "overlayDoesNotHeal": "Product overlay does not rewrite nginx, Apache, vsftpd, or Dovecot. Use the listed apply commands (root + YSK_EXECUTE=1).",
      "executeStaleCli": "Pass --execute (root + YSK_EXECUTE=1) to remove stale CLI bins.",
      "executeMissingTls": "Pass --execute (root + YSK_EXECUTE=1) to disable missing-cert TLS so vsftpd/Dovecot can start.",
      "executeGeneric": "Pass --execute (root + YSK_EXECUTE=1) to apply leftover cleanup for the findings above.",
      "staleCliRemoved": "Removed leftover CLI {{path}}.",
      "staleCliRemoveFailed": "Could not remove leftover CLI {{path}}: {{detail}}",
      "vsftpdSslOff": "Set vsftpd ssl_enable=NO because the FTPS certificate file is missing, then restarted vsftpd.",
      "dovecotSslOff": "Set Dovecot ssl=no because {{path}} is missing, then restarted Dovecot.",
      "readinessTitle": "Host leftovers after overlay",
      "readinessClean": "No leftover Apache default, missing nginx catch-all, failed vsftpd, or stale CLI detected.",
      "nginxRemoved": "Removed leftover nginx conf {{path}}.",
      "nginxNotLeftover": "Not a leftover public-files conf — refuse delete.",
      "nginxUnusedKeep": "000-default is unused, not leftover — not deleted.",
      "nginxSystemCopy": "System copy still present: {{path}}. Needs YSK_EXECUTE + root to remove.",
      "nginxReloadFailed": "nginx -t or reload failed after removing {{path}}."
    },
    "defense": {
      "panelReqLabel": "Panel requests / min",
      "panelReqExcluded": "Authenticated panel traffic — shown here, not counted in threat score",
      "tcpOk": "TCP {{target}} reachable",
      "tcpFail": "TCP {{target}} failed",
      "dnsDegraded": "DNS path degraded",
      "reqRateHigh": "Public request rate {{reqs}}/min ≥ {{threshold}}",
      "ddosHeuristic": "High public request rate plus edge probe failure"
    }
  },
  "ops": {
    "blocked": {
      "needExecute": "Host execute is off; this action cannot finish from the panel",
      "needExecuteShort": "Host execute is not enabled",
      "needExecuteBlocked": "Blocked: host execute is off",
      "needRoot": "Root privileges required",
      "needExecuteRoot": "Requires YSK_EXECUTE=1 and root",
      "needExecuteYsk": "Requires YSK_EXECUTE=1",
      "writeOutsideDataDir": "Write blocked: host execute is off and the path is outside the panel data directory",
      "nginxReload": "Cannot reload Nginx: host execute required",
      "signal": "Cannot send signal: host execute required (YSK_EXECUTE)",
      "signalNote": "YSK_EXECUTE=1 is required for a real kill",
      "renice": "Cannot renice: host execute required (YSK_EXECUTE)",
      "install": "Host execute is off; install cannot finish from the panel",
      "update": "Host execute is off; update cannot finish from the panel",
      "panel": "Cannot complete this from the management panel"
    },
    "honesty": {
      "blockedNotOk": "Honesty fix: blocked cannot be ok=true",
      "blockedNotApplied": "Honesty fix: blocked cannot be apply_status=applied",
      "okFalseNotApplied": "Honesty fix: ok=false cannot be apply_status=applied"
    },
    "status": {
      "applied": "Status: applied",
      "failed": "Status: failed",
      "written": "Status: written",
      "blocked": "Status: blocked"
    },
    "notes": {
      "writtenSettings": "Settings written",
      "completed": "Completed",
      "partialSuccess": "Operation only partially succeeded",
      "notInstalled": "Not installed",
      "running": "Running",
      "stopped": "Stopped",
      "unknown": "Unknown"
    }
  },
  "opsResult": {
    "title": "Result",
    "status": "Status",
    "port": "Port",
    "url": "URL",
    "pid": "PID",
    "blocked": "Cannot run",
    "success": "Success",
    "failed": "Failed",
    "retry": "Retry",
    "showDetails": "Details ({{count}})",
    "hideDetails": "Hide details",
    "stepBuildOk": "Build completed",
    "stepHealthOk": "Health check passed",
    "stepProcessStarted": "Process started",
    "stepSystemdFallback": "Systemd unit not ready — process started via pidfile",
    "stepNginxWritten": "Nginx config written",
    "stepConfigsSynced": "Configs synced to system",
    "stepStoppedOld": "Stopped previous process",
    "stepTuningApplied": "Runtime tuning applied",
    "stepUnitWritten": "Service unit written",
    "stepSystemdStartFailed": "Systemd start failed — using process fallback",
    "portListening": "Port {{port}} is listening",
    "portNotListening": "Port {{port}} is not listening",
    "httpOk": "HTTP OK {{status}}",
    "httpFail": "HTTP failed: {{detail}}"
  },
  "pageGuide": {
    "missing": "No help content is available for this page yet.",
    "missingTitle": "No guide",
    "eyebrow": "About",
    "canDoTitle": "What you can do",
    "workflowTitle": "Suggested flow",
    "notesTitle": "Notes",
    "cliTitle": "CLI quick reference",
    "cliFoot": "For full flags run ysk-server <command> --help or see the docs.",
    "relatedTitle": "Related"
  },
  "playbooks": {
    "discover-host": {
      "name": "Host discovery",
      "description": "Read-only host inventory"
    },
    "nginx-health": {
      "name": "Nginx health check",
      "description": "Check nginx service status"
    },
    "nginx-restart": {
      "name": "Nginx restart (high risk)",
      "description": "Restart nginx after approval"
    },
    "local-llm-ops-only": {
      "name": "Local LLM ops only",
      "description": "Emergency discovery under protection mode"
    },
    "disk-pressure": {
      "name": "Disk pressure check",
      "description": "Read-only disk usage via df"
    },
    "mail-stack-status": {
      "name": "Mail stack status",
      "description": "Check postfix + dovecot units"
    },
    "security-units": {
      "name": "Security units",
      "description": "fail2ban + sshd status (read-only)"
    },
    "web-stack-status": {
      "name": "Web stack status",
      "description": "nginx + php-fpm probe"
    },
    "emergency-read-only": {
      "name": "Emergency read-only sweep",
      "description": "Protection-safe facts only"
    },
    "backup-health": {
      "name": "Backup readiness",
      "description": "Check disk + list processes before backup window"
    },
    "db-stack-status": {
      "name": "Database stack status",
      "description": "mysql/mariadb/redis/postgres units"
    },
    "ssl-nginx-check": {
      "name": "SSL + Nginx check",
      "description": "nginx status before cert ops"
    }
  },
  "presetChips": {
    "customPlaceholder": "Custom…"
  },
  "projects": {
    "title": "Projects",
    "subtitle": "",
    "create": "Create project",
    "createHint": "After create, open detail to deploy, publish, and tune resources",
    "empty": "No projects yet",
    "emptyHint": "Create your first project, then deploy and publish Nginx",
    "emptyFilter": "No matching projects",
    "emptyFilterHint": "Clear search or change the runtime filter",
    "name": "Name",
    "domain": "Domain (optional)",
    "detail": "Project detail",
    "deploy": "Deploy",
    "deployPhp": "Deploy PHP",
    "stop": "Stop",
    "health": "Health check",
    "publishNginx": "Publish Nginx",
    "publishNginxSsl": "Publish Nginx + SSL",
    "opsResult": "Ops result",
    "runtime": "Runtime",
    "template": "Template (optional)",
    "templateNone": "— none —",
    "searchPlaceholder": "Search name, domain, or ID…",
    "listDesc": "Manage sites on this host.",
    "filterAll": "All runtimes",
    "statTotal": "Total",
    "statRunning": "Running",
    "statDegraded": "Degraded",
    "statUnhealthy": "Unhealthy",
    "statStopped": "Stopped / ready",
    "statStoppedOnly": "Stopped",
    "statReadyOnly": "Ready",
    "statPendingOs": "OS user pending",
    "status": {
      "failed": "Failed",
      "failedHint": "Deploy or health check failed — check logs",
      "unhealthy": "Unhealthy",
      "unhealthyHint": "Process is up but health check failed",
      "pendingOs": "OS user pending",
      "pendingOsHint": "System user not provisioned",
      "degraded": "Running (degraded)",
      "degradedHint": "Process is up but not full production mode (e.g. non-root / pidfile)",
      "deploying": "Deploying",
      "published": "Published",
      "publishedHint": "Nginx config written; process may be separate",
      "running": "Running",
      "stopped": "Stopped",
      "ready": "Ready",
      "readyHint": "Created — deploy to start",
      "unknown": "Unknown"
    },
    "checklist": {
      "title": "Launch path",
      "desc": "Complete these steps to serve traffic",
      "created": "Created",
      "os": "OS user",
      "deploy": "Deploy",
      "nginx": "Nginx",
      "health": "Health"
    },
    "next": {
      "pendingOsTitle": "System user not provisioned",
      "provisionOsAction": "Create system user",
      "pendingOsBody": "This project has no isolated system user yet.",
      "pendingOsActions": "You can still deploy; full isolation needs admin privileges on the host.",
      "deployTitle": "Next: Deploy",
      "deployBody": "Use Deploy in the header, or the Deploy tab for Git.",
      "nginxTitle": "Next: Publish Nginx",
      "nginxBody": "Open the Network tab to publish Nginx (optional SSL)."
    },
    "healthDetail": {
      "none": "No health check yet",
      "overall": "Result",
      "nginxStatus": "Nginx status",
      "nginxReloaded": "Nginx reload",
      "httpStatus": "HTTP",
      "latency": "Latency",
      "error": "Error",
      "at": "Checked at",
      "deployMode": "Deploy mode",
      "edgeKind": "Edge",
      "goLiveOk": "Go-live",
      "goLiveAt": "Go-live at",
      "degraded": "Degraded"
    },
    "railPhp": "PHP / site",
    "railStatic": "Static site",
    "sectionPhpDeploy": "PHP deploy",
    "sectionPhpDeployDesc": "Write PHP site / pool and apply when allowed",
    "sectionStaticDeploy": "Static content",
    "sectionStaticDeployDesc": "Static sites use files + Nginx — no Node process",
    "staticDeployHint": "Pull content via Git, then Publish Nginx under Network.",
    "noDomain": "No domain",
    "lastDeploy": "Last deploy",
    "neverDeployed": "Never deployed",
    "created": "Created {{name}}",
    "backToList": "Back to projects",
    "openUrl": "Open site",
    "openUrlNeedDomain": "Set a domain first — do not open 127.0.0.1 in your browser",
    "needOsUser": "Create the system user on the Isolation tab first",
    "goIsolation": "Open Isolation tab",
    "homeMissing": "Home directory does not exist",
    "homeMissingHint": "Same live probe as migrate inventory — create the system user on Isolation",
    "stopTitle": "Stop this project (systemd unit and public site)",
    "deployTitle": "Deploy this project",
    "httpStatsHint": "From this project’s access log (last sample)",
    "httpStatsNone": "No project access log yet",
    "notFound": "Project not found",
    "home": "Home directory",
    "env": "Environment",
    "backup": "Backup",
    "resources": "Resources",
    "quotaUnlimited": "No quota",
    "lastHealth": "Last health",
    "tabOverview": "Overview",
    "tabDeploy": "Deploy",
    "tabApp": "App",
    "tabNetwork": "Network",
    "tabResources": "Resources",
    "tabIsolation": "Isolation",
    "tabLogs": "Logs",
    "tabAdvanced": "Advanced",
    "tabMore": "More",
    "createGoLive": "Deploy and publish Nginx after create",
    "createPreferredPort": "Fixed port (optional)",
    "goLiveOk": "Deployed and published",
    "goLivePartial": "Created; deploy/publish incomplete",
    "nginxLive": "Live",
    "nginxWritten": "Written",
    "nginxNeedsDeploy": "Needs deploy",
    "nginxFailed": "Publish failed",
    "netEdgeStatus": "Edge status",
    "netUpstream": "Upstream",
    "netPortTitle": "Process port",
    "netCurrentPort": "Current port",
    "netPublishTitle": "Publish",
    "netConfPreview": "Conf",
    "savePublishSsl": "Save and publish + SSL",
    "retryLiveTitle": "Go-live incomplete",
    "retryLiveBody": "Deploy or Nginx publish did not finish. Retry below.",
    "retryDeploy": "Retry deploy",
    "retryPublish": "Retry publish Nginx",
    "preferredPortRedeployHint": "Save, then redeploy for the process to use this port",
    "railProcess": "Process",
    "railNginx": "Nginx",
    "railOs": "OS user",
    "railHealth": "Health",
    "nginxPublished": "Config published",
    "nginxNone": "Not published",
    "osProvisioned": "System user provisioned",
    "osPending": "OS isolation pending",
    "healthOk": "Healthy",
    "healthBad": "Failed",
    "healthUnknown": "Not checked",
    "sectionRuntimeDeploy": "Runtime deploy",
    "sectionRuntimeDeployDesc": "Start the process for this project runtime (Node / PHP)",
    "sectionGit": "Git",
    "sectionGitDesc": "Clone, sync, and inbound push",
    "sectionEnv": "Environment variables",
    "sectionEnvDesc": "Write KEY=value lines to the project .env",
    "gitUrl": "Git URL",
    "gitDeploy": "Git deploy",
    "envFile": "Env (.env)",
    "saveEnv": "Save env",
    "sectionNginx": "Nginx & SSL",
    "sectionNginxDesc": "Write and apply site config",
    "domainHint": "Set a domain at create time for cleaner publish",
    "sectionQuota": "Disk quota",
    "sectionQuotaDesc": "Limit home directory size (MiB)",
    "sectionLimits": "CPU / memory",
    "sectionLimitsDesc": "systemd limits; redeploy to apply the unit",
    "quotaMb": "Quota (MiB)",
    "memoryMax": "MemoryMax",
    "cpuQuota": "CPU quota %",
    "setQuota": "Set quota",
    "setResources": "Save resource limits",
    "sectionLogs": "Application logs",
    "sectionLogsDesc": "Tail recent log files under the project home",
    "viewLogs": "Load logs",
    "logsEmpty": "No logs loaded yet",
    "logsNoFiles": "(no log files yet — deploy first)",
    "sectionAdvanced": "Other actions",
    "sectionAdvancedDesc": "Backups and template content",
    "downloadWp": "Download WordPress",
    "dangerZone": "Danger zone",
    "dangerZoneDesc": "Delete removes project records and related resources",
    "delete": "Delete project",
    "confirmStopTitle": "Stop this project?",
    "confirmStopDesc": "This will stop the running process for “{{name}}”.",
    "confirmDeleteTitle": "Delete this project?",
    "confirmDeleteDesc": "Delete “{{name}}”? This cannot be undone from the UI.",
    "close": "Close",
    "statProjects": "{{count}} projects",
    "noProjectsShort": "No projects yet",
    "runtimeStatic": "Static",
    "logsLoadFailed": "Failed to load logs",
    "deleteFailed": "Delete failed",
    "tabAbout": "About",
    "statusLabel": "Status",
    "userLabel": "User",
    "nginxValuePublished": "Published",
    "nginxValueNone": "Not published",
    "osValueReady": "Ready",
    "osValuePending": "OS user pending",
    "openFiles": "Files",
    "enableCdn": "Enable CDN",
    "openLogs": "Logs",
    "osUserReadyMsg": "System user ready. {{detail}}",
    "osUserNeedRoot": "Cannot create system user: needs YSK_EXECUTE + root. {{detail}}",
    "osUserIncomplete": "System user provisioning incomplete",
    "saveLogDirsFailed": "Failed to save log directories",
    "createName": "Project name",
    "noPathSepHint": "The name cannot contain / or \\.",
    "createRuntime": "Runtime",
    "createRuntimeHint": "You can change deploy options later in detail",
    "createVersion": "Version",
    "createVersionHint": "Writes the project runtime version setting; deploy / FPM uses it",
    "createVersionAria": "Runtime version",
    "createPrimaryDomain": "Primary domain",
    "createPrimaryDomainHint": "Optional for now",
    "createAliases": "Aliases",
    "createAliasesHint": "Comma or newline separated",
    "createTemplate": "Template",
    "createTemplateHint": "One Hello World! demo per runtime; picking a template sets that runtime",
    "createTemplateNote": "Templates only write a skeleton; deploy to build/start.",
    "createRuntimeNow": "Current runtime: ",
    "createTemplateFooter": ". Optional template to start faster, or leave empty.",
    "createDraftResources": "Also create draft resources with the domain",
    "createNeedDomainFirst": "Enter primary domain first so draft options apply together.",
    "createDnsZone": "Also create DNS zone",
    "createDnsZoneDesc": "Writes management draft only — not live authoritative DNS",
    "createMailDomain": "Also register mail domain",
    "createMailDomainDesc": "Finish mailboxes and apply on the mail page later",
    "createServerIpv4": "Server IPv4",
    "createServerIpv4Hint": "For DNS / mail templates",
    "createServerIpv4Ph": "This host public IPv4",
    "createServerIpv6": "Server IPv6 (optional)",
    "createServerIpv6Ph": "Public IPv6 (optional)",
    "sshCardDesc": "Login keys decide who can enter;",
    "sshLoginKeys": "Login public keys allowed",
    "sshKeyCount": "{{count}} key(s)",
    "sshOutbound": "Outbound identity",
    "sshOutboundNone": "Not created",
    "sshOutboundCreated": "Outbound identity created (private key encrypted)",
    "sshCreateFailed": "Create failed",
    "sshWriteTried": "Tried writing to disk",
    "sshOutboundHint": "After create, this project user can use git/scripts outbound.",
    "sshCreateOutbound": "Create outbound identity",
    "sshWriteHome": "Write home/.ssh",
    "sshOpenWorkspace": "Open SSH workspace",
    "sshManageLoginKeys": "Manage login keys",
    "logsSectionDesc": "Scan logs/, log/ and extra dirs; search by name or content keyword",
    "logsNameSearch": "Filename search",
    "logsNameSearchHint": "Match relative path, e.g. error, app.out",
    "logsContentKw": "Content keyword",
    "logsContentKwHint": "Search file tails (not full-file)",
    "logsSearch": "Search",
    "logsRescan": "Rescan",
    "logsRefreshFile": "Refresh this file",
    "logsCopy": "Copy content",
    "logsDownloadTail": "Download tail",
    "logsCenter": "Log center",
    "logsHitsTitle": "{{count}} file(s) with hits — click to open tail (with keyword filter)",
    "logsLinesHit": "{{count}} line hit(s)",
    "logsFileCount": "Log files {{count}}",
    "logsNameFilter": "(name contains “{{q}}”)",
    "logsScanning": "Scanning logs…",
    "logsNoneYet": "No log files yet — appear after deploy/run; extra dirs also work.",
    "logsNoContent": "No content yet",
    "logsRelated": "Related sources",
    "logsRelatedDesc": "journal / nginx / PHP-FPM (see log center)",
    "logsAvailable": "Available",
    "logsMissing": "Missing",
    "logsOpenInCenter": "Open in log center",
    "logsExtraDirs": "Extra log directories",
    "logsExtraDirsDesc": "Paths relative to project home (besides logs/ and log/)",
    "logsDirList": "Directory list",
    "logsDirListHint": "One per line; home-relative paths only",
    "logsReset": "Reset",
    "logsSaveScan": "Save and scan",
    "logsDefaultNote": "Always scans logs/ and log/. Extra dirs only include *.log / *.out / *.err.",
    "resOsTitle": "System user isolation",
    "resOsDesc": "Each project has its own Linux user;",
    "resLinuxUser": "Linux user",
    "resOsIsolation": "OS isolation",
    "resOsReady": "Ready",
    "resOsNotCreated": "Not created (needs admin)",
    "resHomeDir": "Home directory",
    "resCanonical": "Intended path",
    "resUserMissing": "User missing",
    "resShellLive": "Live shell / lock",
    "resLocked": "Locked",
    "resUnlocked": "Unlocked",
    "resHomeMode": "home mode",
    "resHomeExists": "Exists · mode {{mode}}",
    "resHomeMissing": "Missing",
    "resIsolationOn": "Isolated",
    "resIsolationPending": "Pending isolation",
    "resOsHint": "Processes run as the project user",
    "resProvisionUser": "Create / repair system user",
    "resRefreshStatus": "Refresh status",
    "resFixHome": "Fix home ownership",
    "resMigrateHome": "Migrate to /home/ysk-server-…",
    "resQuotaDesc": "Soft quota (du before deploy) + hard enforce when setquota exists",
    "resQuotaHint": "e.g. 1024 = 1 GiB",
    "resSetSoftQuota": "Save soft quota",
    "resLimitsTitle": "Process and account limits",
    "resLimitsDesc": "systemd MemoryMax / CPUQuota / TasksMax / NOFILE + shell / lock",
    "resLimitsDescSystemd": "systemd cgroup: MemoryMax / CPUQuota / TasksMax / NOFILE + shell / lock",
    "resLimitsDescPm2": "PM2: memory maps to max_memory_restart; other limits use systemd.",
    "resRunnerSystemd": "Process manager: systemd",
    "resRunnerPm2": "Process manager: PM2",
    "resMemMax": "Memory max",
    "resMemHint": "e.g. 512M or 1G",
    "resMemHintSystemd": "systemd MemoryMax (cgroup hard cap, e.g. 512M or 1G)",
    "resMemHintPm2": "Writes ecosystem max_memory_restart (restart threshold, not cgroup kill);",
    "resFieldSystemdOnly": "systemd cgroup only; still saved to DB for when you switch back to systemd",
    "resCpuHint": "100 = one CPU",
    "resCustomPct": "Custom %",
    "resTasksHint": "Max tasks",
    "resNofileHint": "Open files limit",
    "resShellHint": "Default nologin",
    "resShellBashRisk": "bash · risk",
    "resLockAccount": "Lock Linux account",
    "resLockDesc": "usermod -L; uncheck to unlock",
    "resLimitsHint": "Save & apply writes DB and tries usermod / setquota / systemctl set-property",
    "resLimitsHintSystemd": "Save & apply writes panel state and OS/systemd limits when allowed.",
    "resLimitsHintPm2": "Save & apply writes panel state and PM2 memory limit.",
    "resSaveApply": "Save and apply limits to OS",
    "resSaveControlOnly": "Save Mem/CPU to control plane only",
    "resReapply": "Re-apply once (no form change)",
    "resMigrateDone": "Migration complete",
    "resMigrateIncomplete": "Migration incomplete",
    "resMigrateTitle": "Migrate system user home?",
    "resMigrateDesc": "Migrates to /home/ysk-server-{id} and creates/repairs the system user",
    "resMigrate": "Migrate",
    "resWrittenOnly": "Written to control plane; OS not applied (needs root). {{notes}}",
    "resAppliedOs": "Limits applied to OS. {{notes}}",
    "resSaved": "Saved",
    "resIncomplete": "Incomplete",
    "resApplyLimitsFailed": "Failed to apply limits",
    "resApplied": "Applied",
    "resApplyFailed": "Apply failed",
    "resChownOk": "chown complete",
    "resChownFailed": "chown failed",
    "netSavedPublished": "Network saved and Nginx published",
    "netSavedOnly": "Network settings saved (not published)",
    "netSaveFailed": "Save failed",
    "netSuspended": "Project suspended — visitors get 503. Unsuspend then publish.",
    "netDomainTitle": "Domain",
    "netDomainDesc": "Primary domain and aliases; save can also write Nginx management config",
    "netPrimaryDomain": "Primary domain",
    "netPrimaryHint": "Visitor domain, e.g. app.example.com",
    "netAliases": "Aliases",
    "netAliasesHint": "One per line, e.g. www or blog subdomain",
    "netNeedPrimary": "Enter primary domain first",
    "netHttpsTitle": "HTTPS and site redirect",
    "netHttpsDesc": "Publish Nginx after save. Full-site 301 overrides proxy/PHP/static content",
    "netForceHttps": "Force HTTPS",
    "netForceHttpsDesc": "HTTP → HTTPS (301); needs SSL cert and SSL publish",
    "netForceHttpsOn": "HTTP will redirect to HTTPS after you publish the edge.",
    "netForceHttpsOff": "No forced redirect is stored.",
    "netBoundCert": "Bound certificate",
    "netBoundCertExpiry": "expires {{at}}",
    "netNoBoundCert": "No certificate on disk for this hostname",
    "netForceHttpsNeedCert": "Issue a certificate on /ssl for this domain before forcing HTTPS.",
    "netHttpsLiveNotForced": "An edge file exists; HTTPS may already work. This box only forces HTTP→HTTPS.",
    "netHsts": "Enable HSTS",
    "netHstsDesc": "Browsers stick to HTTPS (recommended after force HTTPS)",
    "netHstsNeedHttps": "Turn on force HTTPS first",
    "netRedirectUrl": "Full-site redirect URL",
    "netRedirectHint": "Optional. Full-site 301 to this URL (move / apex→www)",
    "netBasicAuthTitle": "HTTP basic auth (browser login)",
    "netBasicAuthDesc": "Writes htpasswd on publish; empty username = off. Empty password = keep stored",
    "netAuthUserHint": "Empty disables auth",
    "netAuthPassHint": "Required first time; leave empty later to keep",
    "netAuthPassSet": "Set or update password",
    "netCacheNote": "Static/PHP static Cache-Control 7d by default; purge clears host nginx cache dir (needs YSK_EXECUTE)",
    "netPurgeOk": "Tried purge cache",
    "netPurgeFailed": "purge failed",
    "netDocrootTitle": "Site directory (docroot)",
    "netDocrootDesc": "Relative to project home; used as Nginx root on publish (default app/public)",
    "netDocrootLabel": "Document root",
    "netDocrootFull": "Full path: {{path}}",
    "netDocrootCustom": "Custom relative path…",
    "netAdvancedTitle": "Advanced & publish",
    "netAdvancedDesc": "Bind IP, publish to system Nginx",
    "netCollapseBind": "Collapse bind IP",
    "netExpandBind": "Expand bind IP",
    "netBindIp": "Bind IP",
    "netBindHint": "Empty = all interfaces",
    "netBindPh": "Empty = all; or bind IP",
    "netNeedDomainSave": "Enter and save primary domain first",
    "ovUsed": "Used",
    "ovQuota": "Quota",
    "ovQuotaUnset": "Unset",
    "ovQuotaStatus": "Quota status",
    "ovOverQuota": "Over quota",
    "ovQuotaOk": "OK",
    "ovDocroot": "Document root",
    "ovAccessSample": "Access sample",
    "ovLines": "{{count}} lines",
    "ovDailyDays": "Daily stats days",
    "ovDailyTitle": "Daily visit stats (max 60 days)",
    "ovDailyDesc": "Rolling from access log samples",
    "ovQuickTitle": "Site shortcuts",
    "ovQuickDesc": "Publish and backup (main deploy via header or Deploy tab)",
    "ovNeedNetworkDomain": "Set domain on Network tab first",
    "ovPublishNginx": "Publish Nginx",
    "ovPublishSsl": "Publish Nginx + SSL",
    "ovBackupProject": "Backup this project",
    "ovOpenFiles": "Open project files",
    "ovNoDomainHint": "No domain — set it on Network tab before publishing.",
    "ovPublishNote": "Publish writes management config; live Nginx reload needs system change rights.",
    "ovStatic": "Static",
    "ovAliases": "Aliases",
    "ovForceOn": "Forced",
    "ovForceOff": "Not forced",
    "advFtpCreated": "FTP {{user}} created (draft — apply on FTPS page)",
    "advCreateFailed": "Create failed",
    "advFtpFailed": "FTP create failed",
    "advMaintTitle": "Maintenance",
    "advMaintDesc": "Backup, suspend/resume, optional tools",
    "advBackupProject": "Backup this project",
    "advOneClickWp": "One-click WordPress (download + setup)",
    "advSuspendedHint": "Suspended: process stopped, visitors get 503.",
    "advSuspendHint": "Suspend stops the process and shows a 503 maintenance page.",
    "advFtpTitle": "Project FTP (path jail)",
    "advFtpDesc": "Account jailed to project app dir; apply on FTPS service page after create",
    "advFtpUserHint": "Optional; system can generate",
    "advFtpPassHint": "At least 8 characters",
    "advDangerTitle": "Danger zone",
    "advDangerDesc": "Delete cannot be undone from the UI — backup first.",
    "advDelete": "Delete project",
    "deployPyHint": "Default: venv + pip; ASGI via uvicorn, Django via gunicorn.",
    "deployGoHint": "Default: go build -o app . then ./app; skip build if binary exists.",
    "deployRustHint": "Default: cargo build --release then target/release/{crate}; skip build optional.",
    "deployNodeHint": "Start Node process (entry default server.js); systemd recommended in prod.",
    "deployDefaultHint": "Start by runtime; external only after apply.",
    "deployOsStep": "Isolated Linux user + /home/ysk-server-{project id} (Resources tab can create)",
    "deployPyReady": "Python runtime ready",
    "deployPipNet": "requirements.txt needs outbound pip",
    "deployCheckPort": "After deploy check port and /health",
    "deployPublishProxy": "Publish Nginx reverse proxy",
    "deployToolchainReady": "{{runtime}} toolchain ready",
    "deployFirstBuild": "First deploy builds (may take a while)",
    "deployNeedBinary": "Binary only after successful build",
    "deployPhpFpmOk": "PHP-FPM version OK",
    "deployPhpPool": "Deploy PHP / apply pool",
    "deployNginxSsl": "Publish Nginx + optional SSL",
    "deployPublicContent": "Confirm public/ has content",
    "deployNetPublish": "Publish Nginx on Network tab",
    "deployConfirmToolchain": "Confirm runtime page installed toolchain (or host has it)",
    "deployConfirmCode": "Confirm app/ has code (template or Git)",
    "deployPressDeploy": "Press Deploy; then publish Nginx on Network",
    "deployVersionSaved": "Saved {{runtime}} version {{version}} (used on deploy)",
    "deployVersionSaveFailed": "Failed to save runtime version",
    "deployInstallingToolchain": "Installing / confirming toolchain…",
    "deployToolchainIncomplete": "Toolchain install incomplete (permission or network); try Runtime page",
    "deployToolchainDone": "Toolchain step done, starting deploy…",
    "deployToolchainFailed": "Toolchain install failed",
    "deployChecklistTitle": "Created — deploy checklist",
    "deployChecklistDesc": "{{runtime}} skeleton ready; finish steps to serve traffic",
    "deploySectionTitle": "{{runtime}} deploy",
    "deploySectionDesc": "Start {{runtime}} process (port / systemd or pidfile)",
    "deployPhpVersion": "PHP version",
    "deployPhpVersionHint": "PHP version for this site (matching FPM must be installed)",
    "deployRuntimeVersion": "{{runtime}} version",
    "deployRuntimeVersionHint": "Saved on project; used on deploy. Install on Runtime page",
    "deployRuntimeVersionCreateHint": "Written at create; referenced on deploy",
    "deployRuntimeVersionGeneric": "Runtime version",
    "deployEntry": "Start entry",
    "deployEntryHint": "Empty = default ({{hint}}); synced to server",
    "deploySkipBuild": "Skip build",
    "deploySkipBuildHint": "If venv/binary exists; speeds restart (local preference)",
    "deployPort": "· port {{port}}",
    "deployFpmApplied": "PHP-FPM pool applied",
    "deployFpmIncomplete": "FPM incomplete",
    "deployFpmNote": "Writes site/pool config; live reload needs system change rights.",
    "deployBuildNote": "Build/start failures show in ops result. Entry writes to server; skip-build is local preference.",
    "deployPhpIniTitle": "Project php.ini overrides",
    "deployPhpIniDesc": "Only keys to change;",
    "deployPhpIniExample": "e.g. 256M; empty = global",
    "deployGlobal": "Global",
    "deployCustom": "Custom",
    "deployOff": "Off",
    "deployOnCareful": "On · careful",
    "deployPhpIniSaved": "Project php.ini overrides saved; deploy or apply FPM again",
    "deployHistory": "Deploy history ({{count}})",
    "deployHistoryDesc": "From audit; newest first",
    "deployGitUrlHint": "HTTPS or git@host:org/repo.git",
    "deployEnvHint": "One KEY=value per line; # comments",
    "resume": "Resume project",
    "suspend": "Suspend project",
    "goFtpsApply": "Go apply on FTPS service",
    "toolchainNote": "Installing toolchain ≠ project is live; deploy success ≠ public Nginx (publish on Network).",
    "installToolchainDeploy": "Install toolchain and deploy",
    "deployOnly": "Deploy only",
    "openRuntime": "Open {{runtime}} runtime",
    "later": "Later",
    "installToolchainDeployShort": "Toolchain + deploy",
    "runtimeEnv": "{{runtime}} env",
    "applyFpmPool": "Apply FPM pool",
    "staticNginxHint": "Static sites rely on Publish Nginx — use Network or Overview shortcuts.",
    "fullIniLink": "Full catalog and opcache/session etc. at",
    "phpIniLink": "PHP runtime → php.ini",
    "savePhpIniOverride": "Save php.ini overrides",
    "scaffoldNote": "If app/ is a YSK scaffold (.ysk-scaffold), it is cleared before clone; custom content refuses overwrite.",
    "saveOnly": "Save only",
    "savePublishNginx": "Save and publish Nginx",
    "needDomainToPublish": "Enter primary domain before publishing.",
    "savePublish": "Save and publish",
    "saveAuth": "Save auth",
    "cacheZoneNote": "Full FastCGI/proxy_cache zones need keys_zone in host nginx.conf; panel offers best-effort purge.",
    "purgeNginxCache": "Purge Nginx cache",
    "nginxManageFile": "Nginx management file: ",
    "publishRuntimeNote": "Publish writes proxy/PHP-FPM/static conf by runtime (auth, redirects, docroot)",
    "publishStored": "Publish with saved settings",
    "publishStoredSsl": "Publish saved + SSL",
    "publishNote": "Publish writes management conf; sync to /etc/nginx and reload needs system-change rights.",
    "hitsFiles": "{{count}} file(s) with hits — click to open tail (keyword filter)",
    "logFilesCount": "Log files {{count}}",
    "defaultScanNote": "Always scans logs/ and log/. Extra dirs only include *.log / *.out / *.err.",
    "opsOk": "{{label}} completed{{url}}",
    "opsOkWithNote": "{{label}} completed: {{note}}{{url}}",
    "opsFail": "{{label}} failed: {{reason}}",
    "railPython": "Python process",
    "railGo": "Go process",
    "railRust": "Rust process",
    "railNode": "Node process",
    "runtimeName": {
      "php": "PHP",
      "node": "Node.js",
      "static": "Static",
      "python": "Python",
      "go": "Go",
      "rust": "Rust",
      "java": "Java",
      "kotlin": "Kotlin",
      "bun": "Bun"
    },
    "netCacheTitle": "Cache",
    "logsDeepAccess": "Log center · access",
    "logsDeepError": "Log center · error",
    "logsDeepNginxUnit": "Nginx unit logs",
    "logsPresetAccess": "Filter access.log",
    "logsPresetError": "Filter error.log",
    "railJava": "Java process",
    "railKotlin": "Kotlin process",
    "railBun": "Bun process",
    "deployProcessManager": "Process manager",
    "deployProcessManagerSystemd": "systemd (recommended)",
    "deployProcessManagerPm2": "PM2",
    "proc_restart": "Restart",
    "proc_stop": "Stop",
    "proc_reload": "Reload",
    "procControlsHint": "Process controls ({{manager}})",
    "procActionOk": "{{action}} ok · {{notes}}",
    "procActionFail": "{{action}} failed · {{notes}}",
    "procActionFailShort": "Process action failed",
    "procMissingUser": "Project has no Linux user — cannot target PM2 app",
    "deploySystemdHint": "Production default: unit ysk-project-*",
    "deployPm2Hint": "Starts via pm2 (ecosystem",
    "deleteDialogTitle": "Permanently delete project",
    "deletePermanent": "Delete permanently",
    "deleteRemoveFiles": "Delete disk home and Linux user",
    "deleteTypeName": "Type the project name to confirm",
    "deletedOk": "Project deleted",
    "sslRequiredFirst": "No SSL certificate for this domain yet. Create or upload one under SSL Certificates before Publish + SSL.",
    "sslGateHint": "SSL actions locked — go to",
    "sslGateHint2": "to issue/upload a cert for this domain first.",
    "netPublishPrimary": "Basic",
    "netPublishSsl": "HTTPS / SSL",
    "netPublishMaint": "Maintenance",
    "sslNeedDomain": "Set a domain before publishing Nginx / SSL.",
    "createTemplateMissing": "{{v0}} ；「— —」。",
    "deleteDialogDesc": "This permanently deletes “{{name}}”. It cannot be undone.",
    "deleteWillStop": "systemd / PM2 /",
    "deleteWillWeb": "Nginx conf、PHP-FPM pool、Apache vhost（）",
    "deleteWillOs": "Linux home （）",
    "deleteKeepOs": "home Linux （）",
    "deleteWillDb": "…",
    "deleteRemoveFilesDesc": "Cancel，",
    "deleteTypeNameHint": "「{{name}}」",
    "deleteDnsWarn": "DNS zone / domain 。",
    "manageInNginx": "Manage in Nginx",
    "advFtpHomeApp": "Site app directory",
    "advFtpHomeRoot": "Project home (full)",
    "advFtpManage": "Open FTP page",
    "resShell": "Login shell",
    "resSaveHint": "Save and apply changes the live OS. Control-plane only stores the form. Re-apply uses the last saved values.",
    "resBashConfirmTitle": "Allow interactive bash?",
    "resBashConfirmDesc": "This grants an interactive login shell to the project user. Confirm only if you need SSH or PTY as that user.",
    "createGitHint": "Optional. Stored on the project; clone from the Deploy tab (does not clone on create).",
    "gitTokenLaterHint": "HTTPS token and clone depth are set on the project Deploy tab after create.",
    "gitBranch": "Branch",
    "gitBranchHint": "Pick a remote branch or tag.",
    "gitBranchAfterUrl": "Enter a Git URL first. Empty uses the remote default branch.",
    "gitLastRef": "Last sync: {{branch}} @ {{commit}}",
    "gitConfirmTitle": "Clone into this project?",
    "gitConfirmBody": "If app/ is still the Hello World placeholder it will be cleared, then cloned. Custom files that are not a YSK scaffold are refused.",
    "gitConfirmRemoteBody": "This points origin at the new URL and pulls. Unrelated histories fail; custom files are not wiped.",
    "runtimeActual": "Actual binary {{path}}",
    "runtimeFallback": "Chosen {{version}} is not on this host. Process uses {{path}}.",
    "gitSync": "Sync",
    "gitFetch": "Fetch",
    "gitCheckout": "Checkout",
    "gitReset": "Reset to remote",
    "gitResetNeedConfirm": "Needs confirmation — discards local commits",
    "gitDeepen": "Fetch full history",
    "gitLogTitle": "Recent commits",
    "gitDirtyTitle": "Local changes block pull",
    "gitDirtyBody": "{{count}} file(s) differ from Git (Files edits or the app). Discard them or abort.",
    "gitSyncBlockedDirty": "Sync is disabled until local changes are discarded (Reset) or the files match Git.",
    "gitViewDiff": "View diff",
    "gitDiscard": "Discard local files",
    "gitOpenFiles": "Open in Files",
    "gitNotCloned": "Not cloned",
    "gitClean": "Clean",
    "gitDirty": "Dirty",
    "gitBehind": "Behind {{count}}",
    "gitAhead": "Ahead {{count}}",
    "gitDetached": "Pinned",
    "gitShallow": "Shallow",
    "gitMissing": "git missing",
    "gitResetConfirmTitle": "Reset hard to remote?",
    "gitResetConfirmBody": "This discards local Git history and untracked files except .env, then restores .env from the control plane.",
    "gitHeads": "Remote branches",
    "gitToken": "HTTPS token",
    "gitTokenHint": "Encrypted at rest. Never stored in the remote URL.",
    "gitTokenPlaceholder": "ghp_… or glpat-…",
    "gitTokenSet": "Token set",
    "gitSaveToken": "Save token",
    "gitClearToken": "Clear token",
    "gitDeployKey": "Deploy public key",
    "gitDeployKeyHint": "Add this as a read-only deploy key on the Git host.",
    "gitDeployKeyOn": "Deploy key",
    "gitMakeKey": "Create deploy key",
    "gitCopyPub": "Copy public key",
    "gitClearKey": "Clear deploy key",
    "gitKeyCopied": "Public key copied",
    "gitPinHost": "Pin host key",
    "gitPinHostBody": "{{host}} is not pinned. Confirm the fingerprints, then pin before SSH clone.",
    "gitHostUnpinned": "Host key not pinned",
    "gitHookTitle": "Push hook",
    "gitHookHint": "Paste the URL into GitHub / Gitea / GitLab (push only). Not Slack.",
    "gitHookOn": "On",
    "gitHookOff": "Off",
    "gitHookEnable": "Enable",
    "gitHookRotate": "Rotate secret",
    "gitHookDisable": "Disable",
    "gitHookSecretOnce": "Copy this secret now — it will not be shown again.",
    "gitHookCopyUrl": "Copy",
    "gitHookCopySecret": "Copy secret",
    "gitHookCopied": "Copied",
    "gitHookSetup": "Payload URL = the URL above. Content type application/json. Events: push only. Secret = the one-time value.",
    "gitHookGithub": "Settings → Webhooks → Add webhook. Content type application/json. Events: Just the push event. GitHub.com needs HTTPS.",
    "gitHookGitea": "Settings → Webhooks → Add Webhook → Gitea. Method POST. Event: Push.",
    "gitHookGitlab": "Settings → Webhooks. Trigger: Push events. Secret token = hook secret (X-Gitlab-Token).",
    "gitHookHonesty": "Host unit needs YSK_EXECUTE=1 or the hook only returns a plan.",
    "gitHookSkipOther": "Other branches are ignored.",
    "gitAuthHttps": "HTTPS token",
    "gitAuthSsh": "SSH deploy key",
    "gitLoadRefs": "Load branches",
    "gitRefDefault": "Remote default",
    "gitRefBranches": "Branches",
    "gitRefTags": "Tags",
    "gitRefOther": "Other ref…",
    "gitRefCustom": "Commit or ref",
    "gitRefsNeedUrl": "Enter a URL first.",
    "gitRefsNeedAuth": "Save a token or deploy key, then load branches.",
    "gitRefsHint": "Loaded from the remote. Choose one — do not type.",
    "gitHookSetupToggle": "How to paste this",
    "gitHookOneLiner": "HMAC or X-YSK-Git-Hook. Only this project’s ref.",
    "gitHookExecuteHint": "Needs YSK_EXECUTE=1 to clone or deploy.",
    "gitShowKey": "Show key",
    "gitHideKey": "Hide",
    "gitBehindShort": "↓{{count}}",
    "gitAheadShort": "↑{{count}}",
    "gitDirtyShort": "Dirty · {{count}}",
    "gitFilesLink": "Files",
    "nameInvalid": "Use a lowercase name: start with a letter, then letters, digits, or hyphen (max 31).",
    "deployVersionMissing": "Node {{version}} is not installed on this host. Pick an installed version, or install this version first.",
    "deployUsedBinary": "Deploy used {{path}}"
  },
  "protection": {
    "levels": {
      "low": {
        "label": "OK",
        "verb": "System steady",
        "hint": "Keep daily protection"
      },
      "elevated": {
        "label": "Elevated",
        "verb": "Anomalies seen",
        "hint": "Switch to hardened and watch suspect IPs"
      },
      "under_attack": {
        "label": "Under attack",
        "verb": "Likely under attack",
        "hint": "Apply under-attack preset + bulk ban"
      },
      "critical": {
        "label": "Critical",
        "verb": "Severe threat",
        "hint": "Consider emergency; ensure you are whitelisted"
      }
    },
    "presetsWhen": {
      "daily": "Day-to-day",
      "hardened": "Scan / brute",
      "under_attack": "L7 flood",
      "emergency": "Last resort"
    },
    "note": {
      "notApplied": "Not applied on host (needs root + YSK_EXECUTE=1) — saved to panel settings",
      "nginxWritten": "Wrote Nginx rate-limit panel file",
      "f2bWritten": "Wrote fail2ban panel settings",
      "hintDropped": "Internal protection hint omitted",
      "nginxLimits": "Will write Nginx rate-limit snippet"
    },
    "rel": {
      "justNow": "Just now",
      "minutesAgo": "{{n}} min ago",
      "hoursAgo": "{{n}} h ago"
    },
    "apiUnreachable": "Cannot reach API (web proxy/backend may be down)",
    "geoipLoadFailed": "Failed to load GeoIP",
    "loadFailed": "Load failed",
    "previewDone": "Preview done (not written)",
    "presetApplied": "Protection preset applied",
    "manualBan": "Manual ban",
    "banSent": "Ban sent for {{ip}}",
    "quickSelectBan": "Quick-select ban",
    "bulkBan": "Bulk ban {{count}}",
    "autoBanStatus": "Auto-ban: {{onOff}} · {{mode}} · {{method}}",
    "autoBanUpdated": "Auto-ban updated",
    "automationMaster": "Automation master: {{onOff}}",
    "autoPresetStatus": "Auto preset: {{onOff}}",
    "autoBanAutomation": "Auto-ban: {{onOff}} ({{mode}})",
    "automationSaved": "Automation settings saved",
    "statFirewall": "Firewall",
    "statSuspects": "Suspect IPs",
    "statSuspectsSplit": "{{actionable}} actionable / {{total}} listed",
    "suspectActionableCount": "Actionable IPs {{count}}",
    "scoreBasisHint": "Listed suspects vs IPs you can still ban (excludes already banned / whitelist).",
    "statAutoBan": "Auto-ban",
    "statApply": "System apply",
    "statActiveBans": "Active bans",
    "statPreset": "Preset",
    "threatPill": "Threat {{label}} · score {{score}}",
    "reprobed": "Re-probed",
    "loadingStatus": "Loading protection status…",
    "tabs": {
      "command": "Response",
      "automation": "Automation",
      "bans": "Bans",
      "geo": "IP access",
      "stack": "Stack",
      "intel": "Intel",
      "about": "About"
    },
    "reapply": "Re-apply",
    "nginxLimits": "Nginx rate limits",
    "notWritten": "Not written",
    "modeValue": {
      "normal": "Normal",
      "degraded": "Degraded",
      "ddos-protection": "DDoS protection",
      "offline": "Offline"
    },
    "mode": "Mode",
    "controlPlane": "Control plane",
    "canApply": "Can apply",
    "needRoot": "Needs root",
    "writeOnly": "Write file only",
    "autoRunning": "Running · every {{sec}}s · bans this hour {{n}}",
    "autoOffManual": "Off — manual only",
    "lastTick": "· last {{t}}",
    "nextTick": "· next {{t}}",
    "on": "On",
    "off": "Off",
    "open": "Open",
    "ranAutomationTick": "Ran one automation tick",
    "escalateHardened": "Hardened ≥ score",
    "escalateAttack": "Under attack ≥ score",
    "deescalateDaily": "Back to daily < score",
    "zeroOff": "0 off",
    "holdAfterEscalate": "Min hold after escalate",
    "min5": "5 min",
    "min15": "15 min",
    "min30": "30 min",
    "hour1": "1 h",
    "hour2": "2 h",
    "hour6": "6 h",
    "presetOrCustom": "Preset / custom",
    "autoBanMode": "Auto-ban mode",
    "soft": "Soft",
    "normal": "Normal",
    "aggressive": "Aggressive",
    "custom": "Custom",
    "method": "Method",
    "banMethod": "Ban method",
    "both": "Both",
    "scoreGte": "Score ≥",
    "hitsGte": "Request hits ≥",
    "hits429Gte": "429-related hits ≥",
    "scanHitsGte": "Scan-path hits ≥",
    "cooldown": "Cooldown",
    "maxPerHour": "Max per hour",
    "scanInterval": "Scan interval",
    "schedulerDefault": "scheduler default 120s",
    "collapse": "Collapse",
    "expand": "Expand",
    "step": "Step",
    "mechanism": "Mechanism",
    "youCanTune": "You can tune",
    "probe": "Probe",
    "probeSignals": "WAN / req rate / TCP / f2b / UFW",
    "escalateThreshold": "Escalate threshold",
    "emergency": "Emergency",
    "neverAuto": "Never auto",
    "manualEmergency": "Manual EMERGENCY",
    "signalNetworkDown": "WAN down",
    "signalHighReq": "High request rate",
    "signalDdos": "DDoS heuristic",
    "signalTcp": "TCP connections",
    "signalUfwOff": "UFW off",
    "signalF2bBans": "fail2ban ban count",
    "weightHint": "{{label}} weight 0–3",
    "detected": "(detected)",
    "notSet": "(not set)",
    "zonesComma": "Zones (comma-separated)",
    "underAttackRequested": "Under Attack requested",
    "underAttackCleared": "Clear UA requested",
    "autoBanOpen": "On · {{mode}} · this hour {{n}}/{{max}}",
    "autoBanClosed": "Off — manual/list only",
    "pausedNoExecute": "· paused (no EXECUTE)",
    "circuitOpen": "· circuit open",
    "autoBanModeLabel": "Auto-ban mode",
    "scanned": "Scanned",
    "bulkOps": "Bulk actions",
    "fromAccessLog": "From access log · one-click or bulk ban",
    "noSuspectIps": "No suspect IPs for now",
    "noSuspectDesc": "Appears when scan/429 traffic is seen. Expand for manual ban.",
    "whitelistPlus": "Whitelist + {{ip}}",
    "whitelistAdded": "Added to whitelist",
    "activeBansTitle": "Active bans ({{count}})",
    "activeBansDesc": "Protection aggregate · unban via defense API (same as fail2ban-client)",
    "source": "Source",
    "unbanned": "Unbanned",
    "noBans": "No bans",
    "noBansDesc": "Bans show here",
    "collapseQuickAdd": "Collapse quick-add",
    "quickAddOne": "Quick-add one",
    "removeItem": "Remove {{w}}",
    "updated": "Updated",
    "ipOrCidr": "IPv4/IPv6 or CIDR",
    "autoBanWhitelistAdded": "Added to auto-ban whitelist",
    "added": "Added",
    "banIpPlaceholder": "IPv4 or IPv6 to ban",
    "reason": "Reason",
    "scanBrute": "Scan / brute",
    "noSignals": "No signals yet",
    "pressReprobe": "Press re-probe",
    "points": "pts",
    "noTopIps": "No top IPs yet",
    "topIpsAfterLog": "Shows after logs exist",
    "noManagedVhost": "No managed vhost",
    "afterPresetMarker": "Preset apply injects marker",
    "injected": "YSK_DEFENSE injected",
    "notInjected": "Not injected",
    "noEvents": "No events yet",
    "eventsAfterOps": "Appear after apply/ban",
    "geoipUpdated": "GeoIP DB updated",
    "dbReady": "DB ready",
    "stale": "Stale",
    "older7d": ">7 days",
    "freshnessNa": "n/a",
    "freshnessMissing": "No database",
    "freshnessStale": "Stale",
    "freshnessFresh": "Current",
    "lastSuccess": "Last success",
    "downloaded": "Downloaded",
    "missing": "Missing",
    "geoMode": "Geo access mode",
    "denyList": "Deny list",
    "allowListHighRisk": "Allow list · high risk",
    "autoUpdateDb": "Auto-update DB",
    "countriesSelected": "Countries ({{n}} selected)",
    "searchCountry": "Search Chinese name or ISO",
    "countryPlaceholder": "China / CN",
    "regionsSelected": "Regions ({{n}} selected)",
    "regionsHint": "From selected countries; custom CN-GD OK",
    "pickCountryFirst": "Pick countries first to narrow list",
    "customRegion": "Custom, e.g. CN-GD",
    "regionPlaceholder": "Guangdong / CA / Tokyo",
    "continentsSelected": "Continents ({{n}} selected)",
    "continentsHint": "Optional continents",
    "continentPlaceholder": "Asia / EU",
    "asnsSelected": "Provider ASN ({{n}} selected)",
    "asnsHint": "Cloud/ISP; custom ASN OK",
    "customAsn": "Custom ASN, e.g. 13335",
    "asnPlaceholder": "Cloudflare / ISP",
    "cityExample": "e.g. CN|Shenzhen or US|Ashburn",
    "policySaved": "Policy saved · countries {{c}} · regions {{r}} · ASN {{a}}",
    "ipPolicySaved": "IP access policy saved",
    "nginxGeoWritten": "Wrote nginx geo snippet",
    "ipAddress": "IP address",
    "lookupPlaceholder": "IPv4 or IPv6 to look up",
    "wouldBlock": "Would block · {{reason}} · {{matched}}",
    "wouldAllow": "Allow · {{reason}}",
    "lookupDone": "Lookup done",
    "item": "Field",
    "value": "Value",
    "country": "Country",
    "region": "Region",
    "city": "City",
    "continent": "Continent",
    "coords": "Coords",
    "provider": "Provider",
    "policy": "Policy",
    "block": "Block",
    "allow": "Allow",
    "matched": "Matched",
    "applyStricterTitle": "Apply {{name}}?",
    "applyStricterDesc": "May enable auto-ban. Confirm your IP is whitelisted. Review the profile changes below.",
    "confirmEmergencyTitle": "Confirm emergency preset",
    "confirmEmergencyDesc": "Emergency extremely rate-limits. Confirm whitelist and type EMERGENCY.",
    "confirmString": "Confirm string",
    "applyEmergency": "Apply emergency",
    "sectionPreset": "Presets",
    "sectionAutoPreset": "① Auto preset",
    "sectionAutoBan": "② Auto-ban",
    "unban": "Unban",
    "ban": "Ban",
    "banConfirmTitle": "Ban {{ip}}?",
    "banConfirmMethod": "Method: {{method}}",
    "banConfirmUntilUnban": "Stays banned until you unban it (or fail2ban expiry).",
    "banConfirmDesc": "This IP will be blocked on the host. Confirm it is not a current panel or session address.",
    "wlRemovedUndo": "Removed {{ip}} from the allow list. Undo within 5 seconds.",
    "undo": "Undo",
    "banSelectedConfirmTitle": "Ban {{count}} selected IPs?",
    "banSelectedConfirmDesc": "These addresses will be blocked on the host: {{ips}}",
    "save": "Save",
    "yes": "Yes",
    "no": "No",
    "oneClickSuggested": "Apply suggested preset",
    "stackApply": "Apply protection stack (UFW, fail2ban, preset)",
    "stackApplyDone": "Protection stack apply requested",
    "stackApplyHint": "This enables UFW and applies fail2ban plus the suggested preset. Confirm you will not lock yourself out of a remote panel.",
    "viewPresets": "View presets",
    "suspectIpsCount": "Suspect IPs {{count}}",
    "goBans": "Go to bans",
    "singleEntryPrefix": "Single entry:",
    "singleEntryBody": " ",
    "emergencyNeverAuto": "emergency never auto",
    "writeOnlyBanner": "Write-only: system apply needs EXECUTE=1 and root.",
    "readiness": "Readiness",
    "goTo": "Open",
    "presetGuide": "",
    "active": "Active",
    "recommended": "Suggested",
    "useCarefully": "Caution",
    "preview": "Preview",
    "stackToolsSee": "Stack tools on Stack tab ·",
    "readinessCheck": "Readiness check",
    "automationMasterLabel": "Automation master switch",
    "runOneTick": "Run one tick now",
    "suggestEmergencyBanner": "Score very high — system suggests emergency but will not auto-apply. Confirm on Response tab.",
    "autoPresetDesc": "Auto-switch daily/hardened/under-attack by score. Emergency never auto.",
    "allowDeescalate": "Allow auto de-escalate",
    "autoBanThresholdHint": "soft/normal/aggressive fill thresholds;",
    "sectionMechanism": "③ How it works",
    "lastNotes": "Last: {{notes}}",
    "sectionWeights": "④ Signal weights (0–3)",
    "weightsDesc": "Default 1;",
    "needCfToken": "Needs env CF_API_TOKEN",
    "cfOnEscalate": ". Can call API when escalating to under-attack or manual apply.",
    "ufwOnlyCf": "Under attack: UFW allow only CF ranges (+SSH)",
    "ufwOnlyCfHint": "Resets UFW to Cloudflare IPs only; needs system-change rights.",
    "saveZones": "Save zones",
    "uaNow": "Under Attack now",
    "uaClear": "Clear (→ high)",
    "stackRoleNote": "UFW and fail2ban are tool pages under Protection (not top-level nav). Sidebar keeps this page only.",
    "fwUfwTitle": "Firewall UFW",
    "fwStats": "Port policy · permanent DENY · allow {{allow}} · deny {{deny}}",
    "fwRulesProfiles": "UFW rules & profiles",
    "f2bStats": "Log temp bans · {{jails}} jails · banned {{banned}}",
    "jailsWhitelistPolicy": "Jails · whitelist · policy",
    "divisionTitle": "Division of labour",
    "divisionUfw": "UFW = which ports open, permanent IP deny",
    "divisionF2b": "fail2ban = temp ban after log scan",
    "divisionDefense": "This page = attack orchestration (rate presets + auto-ban + suspects)",
    "autoBanLabel": "Auto-ban",
    "scanOnce": "Scan once",
    "selectedIps": "{{count}} IP(s) selected",
    "banSelected": "Ban selected",
    "suspectIps": "Suspect IPs",
    "selectAll": "Select all",
    "alreadyBanned": "Banned",
    "whitelist": "Whitelist",
    "bansWorkflow": "Response: suspect list → ban/unban. Jail policy, ignoreip, service lifecycle:",
    "f2bTool": "fail2ban tool",
    "noSecondJail": "(no second jail editor here).",
    "autoBanWhitelistTitle": "Auto-ban whitelist",
    "autoBanWhitelistDesc": "Protection auto-ban exemptions (syncs fail2ban ignoreip).",
    "ufwOff": "UFW (off)",
    "ufwOffHint": "UFW is not active — fail2ban is the usable target.",
    "whitelistSyncHint": "{{n}} panel entries · fail2ban ignoreip sync: {{sync}}",
    "whitelistSyncOn": "on",
    "whitelistSyncOff": "off (lists may differ)",
    "ignoreipWhitelist": "ignoreip whitelist",
    "notSetSuggestAdmin": "Not set (add your admin IP)",
    "moreItems": "… {{n}} more · see fail2ban whitelist",
    "add": "Add",
    "manualBanTitle": "Manual ban",
    "methodFollows": "Method follows selection above (fail2ban / UFW)",
    "preferSuspectList": "Usually the suspect list is enough.",
    "threatSignals": "Threat signals",
    "scoreSource": "Score sources · weights tunable",
    "accessAuthSample": "access + auth samples",
    "fullLogsAt": "Full nginx/auth logs:",
    "logCenter": "Log center",
    "colScore": "Score",
    "colHits": "Hits",
    "col429": "429",
    "topIpsTitle": "Top IPs",
    "hitsCount": "{{n}} hits",
    "sampleWindowHint": "Counts are from the current access + auth sample window, not the full log file.",
    "banShort": "Ban",
    "vhostLimits": "Vhost rate limits",
    "eventStream": "Event stream",
    "eventKind": {
      "preset": "Preset",
      "auto_preset": "Auto preset",
      "cloudflare_ua": "Cloudflare",
      "ban": "Ban",
      "unban": "Unban"
    },
    "hours48": "48 hours",
    "geoipDb": "GeoIP database",
    "refreshStatus": "Refresh status",
    "updateDbNow": "Update DB now",
    "geoipSourceHint": "Uses local GeoIP DB by default; optional IPinfo token.",
    "retry": "Retry",
    "loadingGeoip": "Loading GeoIP status…",
    "nextScheduledUpdate": "Next scheduled update: {{at}}",
    "statusNotLoaded": "Status not loaded",
    "load": "Load",
    "accessPolicy": "Access policy",
    "enable": "Enable",
    "freeGranularity": "Free max: country + region + ASN; city optional (default off, lower accuracy). Provider = ASN. Whitelist always exempt. Click chip to remove.",
    "allowListDanger": "Allow-list mode is high risk: public IPs not listed (incl. unknown geo) are blocked. Ensure admin IP is on ban-page whitelist.",
    "dailySchedule": "Daily schedule",
    "cityPolicy": "City policy (low confidence · optional)",
    "useCityAccess": "Use city for access",
    "cityPolicyHint": "Free DB city accuracy is limited",
    "noCitiesYet": "No cities yet",
    "savePolicy": "Save policy",
    "applyNginxSnippet": "Apply Nginx snippet",
    "nginxSnippetHint": "HTTP blocking needs the nginx geoip2 module.",
    "testIp": "Test IP",
    "lookup": "Lookup",
    "plusCountry": "+ country {{v}}",
    "plusRegion": "+ region {{v}}",
    "plusCity": "+ city {{v}}",
    "lastTickPrefix": "· last {{t}}",
    "nextTickPrefix": "· next {{t}}",
    "cannotBanSelf": "Cannot ban {{ip}} — this is the host, your login, or ignoreip",
    "selfIp": "This host",
    "selfHostIp": "Host IP",
    "selfLoginIp": "Your login IP",
    "showZeroScore": "Show 0-score",
    "hideZeroScore": "Hide 0-score",
    "geoDraftOnly": "Policy is off — Save stores a draft only. Nginx will not enforce until you enable it.",
    "geoNeedDb": "GeoIP databases are missing — update the MMDB files first",
    "uaNeedZones": "Set a Cloudflare zone first",
    "selectAllCountriesWarn": "Select all countries in block-list mode? That can lock out this host and your login country.",
    "badgeRecommendPreset": "A stronger preset is recommended for the current threat",
    "badgeAutomationOn": "Automation is on",
    "badgeBanCount": "Active bans",
    "badgeGeoOn": "Geo access policy is on",
    "badgeGeoNotReady": "GeoIP database is not ready",
    "badgeIntelSignals": "Signals that currently add score",
    "signalActive": "Active",
    "signalInactive": "Inactive",
    "signalJails": "{{n}} jail(s)",
    "dbReadyHint": "MMDB files are present",
    "dbNotReadyHint": "Download a GeoIP database first",
    "staleHint": "Whether the last successful update is older than 7 days",
    "draftBadge": "Draft",
    "banIsSelf": "This IP matches the current panel source or this host.",
    "banNotSelf": "This IP is not the current panel source.",
    "geoSourceLocal": "Local GeoIP library (sapics + DB-IP)",
    "nginxPreviewHint": "Nginx snippet this preset would write (preview only):"
  },
  "publicFiles": {
    "notSet": "Not set",
    "quota": "Quota",
    "reloadOnApply": "On apply",
    "path": "Path",
    "fileManager": "File manager",
    "overview": "Overview",
    "overviewDesc": "Settings to apply (read-only summary)",
    "serverName": "Server name",
    "reloadNginx": "Reload Nginx",
    "reloadTry": "Try on apply",
    "siteSettings": "Site settings",
    "siteSettingsDesc": "Writes managed conf; may reload Nginx on apply (reachable only after apply)",
    "serverNameHint": "Nginx server_name, e.g. files.example.com",
    "notes": {
      "noManagedConf": "No managed Nginx conf yet — click Apply",
      "notSynced": "Managed conf exists but is not under /etc/nginx/conf.d — apply again as root with YSK_EXECUTE"
    },
    "quotaMiB": "Quota (MiB)",
    "quotaHint": "Optional; caps public directory size. Unlimited disables the MiB field.",
    "unlimited": "Unlimited",
    "quotaInvalid": "Enter a whole number of MiB, or choose Unlimited.",
    "serverNameRequired": "Enter a server name.",
    "serverNameInvalid": "Use a hostname, wildcard, or IP — no spaces or punctuation.",
    "applyHint": "Apply only writes config;",
    "appliedOk": "Public files site applied",
    "applyReload": "Apply and reload Nginx",
    "statusLive": "Live on nginx",
    "statusDraft": "Draft / not applied",
    "statusManagedOnly": "Managed only",
    "statusNotApplied": "Not applied",
    "nginxLive": "in conf.d",
    "nginxNotLive": "not in conf.d",
    "openSite": "Open site",
    "notLiveHint": "Domain 404 usually means conf is only under dataDir, not copied to /etc/nginx/conf.d, or nginx was not reloaded. Re-apply with root + YSK_EXECUTE. Use http:// until SSL is issued for this hostname.",
    "diskRoot": "Disk root",
    "executeFlag": "Execute",
    "asRoot": "Root",
    "filesInRoot": "Entries",
    "managedConf": "Managed conf",
    "systemConf": "System conf.d",
    "autoindex": "Directory listing (autoindex)",
    "liveSystemConf": "Live system conf: {{path}}",
    "publicRootNote": "Public root: {{path}}",
    "applyConfirmTitle": "Apply public-files site?",
    "applyConfirmDesc": "Write Nginx server_name {{name}} and reload Nginx.",
    "serverNameMismatch": "Live conf uses {{live}}; the form has {{draft}}. Apply to replace.",
    "liveName": "Live name",
    "draftName": "Draft name",
    "draftUnapplied": "This draft is not applied. Nginx still serves the live name.",
    "discardDraft": "Discard draft"
  },
  "rbac": {
    "permissions": "Permissions",
    "permissionsDesc": "Add or remove capabilities per role. Factory defaults with one-click restore.",
    "rolePolicy": "Role policy",
    "dirty": "Customized",
    "factory": "Factory default",
    "maxLevel": "Max level",
    "save": "Save policy",
    "saved": "Saved {{role}} policy",
    "restoreRole": "Restore this role",
    "restoreAll": "Restore all roles",
    "restoreRoleTitle": "Restore {{role}} to factory defaults?",
    "restoreRoleDesc": "Custom capabilities for this role will be cleared.",
    "restoreAllTitle": "Restore all roles to factory defaults?",
    "restoreAllDesc": "All custom role policies will be cleared.",
    "restoredRole": "Restored {{role}}",
    "restoredAll": "Restored all role defaults",
    "bandAllOn": "Enable all",
    "bandAllOff": "Disable all",
    "diffFromFactory": "Differs from default",
    "effectivePreview": "Effective capabilities",
    "userOverrides": "User overrides",
    "extraGrants": "Extra grants",
    "extraRevokes": "Extra revokes",
    "restoreUserOverrides": "Clear user overrides",
    "restoreUserOverridesTitle": "Clear overrides for {{name}}?",
    "restoreUserOverridesDesc": "Only extra grants/revokes are cleared; role policy is unchanged.",
    "overridesBadge": "Overrides",
    "promoteAdminTitle": "Promote to Admin?",
    "promoteAdminDesc": "Admin can manage users, change RBAC, impersonate, restore backups, and more.",
    "level": {
      "read": "Read",
      "write-low": "Write (low)",
      "write-high": "Write (high)",
      "destructive": "Destructive",
      "privilege": "Privilege"
    },
    "cap": {
      "dashboardRead": "Dashboard",
      "logsRead": "Logs",
      "metricsRead": "Metrics",
      "projectsRead": "Projects (read)",
      "mailRead": "Mail (read)",
      "dnsRead": "DNS (read)",
      "sslRead": "SSL (read)",
      "backupsRead": "Backups (read)",
      "updatesRead": "Updates (read)",
      "servicesRead": "Services (read)",
      "firewallRead": "Firewall (read)",
      "approvalsView": "Approvals (view)",
      "usersSelf": "Self profile / 2FA",
      "projectsWrite": "Projects create/edit",
      "mailWrite": "Mailboxes / aliases",
      "dbWrite": "Create databases",
      "sslUpload": "Upload certificates",
      "filesProject": "Project files",
      "approvalsRespond": "Respond to approvals",
      "cronManage": "Cron management",
      "servicesControl": "Service control",
      "updatesApply": "Apply package updates",
      "dnsApply": "Apply DNS",
      "sslIssue": "Issue SSL",
      "publishApply": "Publish / Nginx",
      "firewallEdit": "Edit firewall",
      "mailApply": "Apply mail maps",
      "runtimeTuning": "Runtime tuning",
      "mysqlConsoleWrite": "MySQL write console",
      "projectsDelete": "Delete projects",
      "dbDrop": "Drop databases",
      "backupsRun": "Run backups",
      "backupsRestore": "Restore backups",
      "firewallFlush": "Flush firewall",
      "logsPurge": "Purge logs",
      "usersManage": "Manage users",
      "packagesManage": "Manage packages",
      "usersImpersonate": "Impersonate",
      "securityPolicy": "Security policy",
      "rbacPolicy": "RBAC policy",
      "settingsSystem": "System settings",
      "auditExport": "Audit export",
      "securityApiKeysAdmin": "API keys admin",
      "networkBrowse": "Host-mediated web browse",
      "networkVnc": "VNC remote desktop",
      "validatorsRead": "Validators (read)",
      "validatorsManage": "Validators manage",
      "validatorsWipe": "Validators wipe data",
      "dockerRead": "Docker (read)",
      "dockerManage": "Docker manage",
      "dockerWipe": "Docker wipe / prune"
    },
    "aboutRoles": "Roles (factory defaults)",
    "aboutRolesBody": "Roles set default capabilities; users can override individual ones.",
    "aboutQuota": "Quotas",
    "aboutQuotaBody": "Package quotas are primarily host/panel totals, not hard multi-tenant isolation",
    "dangerPolicyTitle": "Grant destructive / privilege capabilities?",
    "dangerPolicyDesc": "You are adding destructive or privilege caps, or raising maxLevel for this role",
    "needRbacPolicy": "rbac.policy is required to edit role policies.",
    "adminLockedFull": "Admin full-open (locked)",
    "adminLockedHint": "The admin system role is always fully open and cannot be reduced",
    "maxLevelHint": "Capability groups above this level stay locked.",
    "capabilities": "Capabilities",
    "capabilitiesHint": "Toggle what this role may do",
    "enabledCount": "{{enabled}} of {{total}} enabled",
    "bandAboveMax": "Above max level",
    "roleUnavailable": "Not available for this role",
    "dirtyHint": "Customized (differs from factory)",
    "unsaved": "Unsaved",
    "unsavedHint": "Unsaved edits on this role",
    "nothingToSave": "Nothing to save",
    "saveRole": "Save {{role}} policy",
    "discardTitle": "Discard unsaved changes?",
    "discardDesc": "Unsaved permission edits will be discarded."
  },
  "readiness": {
    "cat": {
      "core": "Control plane",
      "security": "Permissions & security",
      "binaries": "System software",
      "hosting": "Runtimes",
      "dns": "DNS",
      "email": "Email",
      "isolation": "Project isolation",
      "ops": "Ops"
    },
    "level": {
      "ready": "Ready",
      "degraded": "Degraded",
      "missing": "Missing",
      "unknown": "Unknown"
    },
    "severity": {
      "critical": "Critical",
      "recommended": "Recommended",
      "optional": "Optional"
    },
    "fix": "Fix",
    "passed": "Pass",
    "checkFailed": "Readiness check failed",
    "gatePass": "Gate passed · {{pct}}%",
    "gateFail": "Not ready · {{pct}}%",
    "gateBlocked": "Not passed · {{n}} missing",
    "executeOn": "On",
    "executeOff": "Off",
    "blockers": "Blockers",
    "blockersHint": "Blockers are the critical subset of Missing — not extra checks.",
    "requireAdminTotp": "require admin 2FA policy",
    "listenBind": "listen address",
    "item": {
      "admin2fa": "Admin two-factor"
    },
    "dataDirPerms": "panel data-directory permissions",
    "mode750": "mode 750",
    "totalChecks": "All checks",
    "totalChecksHint": "Ready + degraded + missing = this total. Blockers are the critical missing subset.",
    "probing": "Probing…",
    "reprobe": "Re-probe",
    "exportReport": "Export report",
    "exportStarted": "Downloading {{name}}",
    "firstBlocker": "Fix first blocker",
    "viewRecommended": "View recommended",
    "loadingProbe": "Probing host capabilities…",
    "priorityTab": "Priority fixes",
    "checklistTab": "Full checklist",
    "summaryTab": "Summary & shortcuts",
    "priorityTitle": "Priority fixes",
    "prioritySub": "Handle in order; re-probe after clearing blockers",
    "nItems": "{{count}} items",
    "noHardBlockers": "No hard blockers",
    "noHardBlockersTitle": "No hard blockers",
    "prodGate": "Production gate",
    "gatePassed": "passed",
    "gateMaybePerm": "may still fail due to permissions",
    "viewDegradedHint": "Review degraded recommendations (mail, DNS, optional runtimes).",
    "viewDegraded": "View degraded",
    "fullChecklist": "Full checklist",
    "showing": "Showing {{shown}} / {{total}}",
    "filterAria": "Status filter",
    "all": "All",
    "category": "Category",
    "allCategories": "All categories",
    "searchPh": "Title, detail, id, fix hint…",
    "quickCatAria": "Quick categories",
    "noMatchTitle": "No matching items",
    "noMatchDesc": "Clear search or change filters.",
    "resetFilters": "Reset filters",
    "summary": "Summary",
    "shortcuts": "Shortcuts",
    "opsShortcutsAria": "Ops shortcuts",
    "scHost": "Host settings",
    "scHostD": "hostname · power · NTP",
    "scUnit": "Control-plane unit",
    "scUnitD": "systemd install / enable",
    "scServices": "Service matrix",
    "scServicesD": "nginx · DB · lifecycle",
    "scMetrics": "Host metrics",
    "scMetricsD": "load · memory · alerts",
    "scProtection": "Defense center",
    "scProtectionD": "response · UFW · fail2ban",
    "policyNote": "Policy: mail PTR / port 25 / registrar DNS are never auto-claimed complete. HTTP 503 = not ready but full report (not a fake success).",
    "notProbedTitle": "Not probed yet",
    "notProbedDesc": "Click “Re-probe” to start a read-only readiness check.",
    "runCheck": "Run readiness check",
    "reportFormatError": "Invalid readiness report format",
    "checkFailedHttp": "Readiness check failed ({{status}})",
    "itemAdminPassword": "Admin password strength",
    "itemAdminPasswordWeak": "{{count}} admin(s) flagged must_change_password / insecure bootstrap — change before production",
    "itemAdminPasswordOk": "No bootstrap/weak-password flag on admin accounts",
    "itemAdminPasswordFix": "Change admin password (Security / Users)",
    "itemListenBind": "Control plane listen bind",
    "itemListenBindPublic": "Listen may be public (0.0.0.0/::). Prefer 127.0.0.1 + reverse proxy / firewall.",
    "itemListenBindLoopback": "Prefer loopback bind (default 127.0.0.1)",
    "itemDataDirPerms": "dataDir permissions",
    "itemDataDirWorldW": "chmod 750 (or 700) dataDir; chown to panel user",
    "itemDataDirOtherR": "Prefer chmod 750 dataDir so other users cannot read control-plane JSON",
    "itemRustToolchain": "Rust toolchain",
    "itemWebBuildFix": "Click “Fix now” to build the Web UI (requires monorepo on this host), or run: pnpm --filter ysk-server-web build",
    "itemWebBuildManual": "No monorepo or packaged SPA on this host — one-click fix is unavailable. On a machine with source: pnpm --filter ysk-server-web build, then copy apps/web/dist/* into dataDir/web (e.g. /var/lib/ysk-server/web), or set YSK_WEB_ROOT and restart.",
    "itemStateStore": "Control-plane state store",
    "itemStateStoreSqliteHint": "Optional: YSK_STORE=sqlite for WAL document store",
    "itemBackupFreshness": "Last full backup run",
    "itemBackupNone": "No last_backup_run recorded — run backup all or schedule",
    "itemBackupFix": "ysk-server backup all · backup schedule --install",
    "itemFleetSessions": "Fleet agent sessions",
    "itemFleetNone": "Optional for single-host; multi-edge needs agent run + heartbeat",
    "itemFleetNoHb": "Sessions registered but not heartbeating — start edge agent",
    "itemPdnsutil": "pdnsutil (PowerDNS)",
    "apachePort80Title": "Apache vs public :80",
    "apachePort80Detail": "Apache is listening on :80 and Nginx is not on public HTTP — conflicts with Nginx-as-edge topology.",
    "apachePort80Both": "Both Apache and Nginx appear on :80 — rebind Apache to 127.0.0.1:8080.",
    "apachePort80Ok": "Apache is running but not solely owning public :80 (topology OK).",
    "apachePort80Fix": "Install rebind helpers exist; disable Apache vhosts on 80 or verify with ss -lntp after reload.",
    "fixNow": "Fix now",
    "fixFailed": "Fix failed",
    "fixDone": "dataDir permissions hardened (chmod 750)",
    "fixDoneWebUi": "Web UI built / installed",
    "rootLabel": "Superuser",
    "techDetails": "Technical details",
    "missingOwner": "No panel owner assigned (package quota attribution)",
    "notOsProvisioned": "OS user pending (home not provisioned)",
    "isolationPendingOs": "Same as project status: OS user pending. Open Isolation to provision the system user and home.",
    "ondrejNone": "No ondrej Launchpad PHP sources detected",
    "ondrejFound": "Found legacy ondrej/php sources that conflict with packages.sury.org: {{paths}}",
    "ondrejTitle": "PHP apt source (ondrej residual)",
    "systemctlActive": "Service is running",
    "systemctlStatus": "Service status: {{status}}",
    "binInPath": "{{bin}} in PATH",
    "leftoverApache": "Apache leftover default site",
    "leftoverVsftpd": "vsftpd unit failed",
    "leftoverCli": "Stale leftover CLI",
    "leftoverNginx": "Nginx catch-all missing",
    "leftoverDovecot": "Dovecot TLS points at missing cert",
    "leftoverOther": "Host leftover",
    "leftoverApply": "Leftover apply",
    "isolationOwnerDegrades": "Missing owner_user_id affects package quota attribution — status is degraded, not ready."
  },
  "redis": {
    "neverExpire": "Never expires",
    "ttlSeconds": "{{ttl}}s",
    "ttlMinutes": "{{n}} min",
    "ttlHours": "{{n}} h",
    "ttlDays": "{{n}} d",
    "typeString": "String",
    "typeHash": "Hash",
    "typeList": "List",
    "typeSet": "Set",
    "typeZset": "Sorted set",
    "keysLoadFailed": "Failed to load keys",
    "writeFailed": "Write failed",
    "saved": "Saved",
    "deleted": "Deleted",
    "offline": "Offline",
    "connections": "Connections",
    "totalKeys": "Total keys",
    "writable": "Writable",
    "connected": "Connected",
    "notConnected": "Not connected",
    "keys": "Keys",
    "selected": "Selected",
    "softwareMissing": "Redis software is not installed",
    "notConnectedTitle": "Not connected to Redis",
    "installThenStart": "Install Redis via the banner, then start the service.",
    "installedNotConnected": "Installed but not connected — start the service to browse keys.",
    "keysCountSuffix": " · {{n}} key(s)",
    "searchPlaceholder": "Search keys, e.g. user:* or *",
    "searchKeys": "Search keys",
    "scanHint": "Uses SCAN, not KEYS. Returns at most {{n}} keys — avoid * on huge databases.",
    "scanCapped": "Showing the first {{n}} matches.",
    "rows": "{{n}} row(s)",
    "content": "Content",
    "noMatchingKeys": "No matching keys",
    "dbEmpty": "Database {{db}} is empty.",
    "noMatchPattern": "No keys matching “{{pattern}}”.",
    "opsResult": "Ops result",
    "addStringKey": "Add string key",
    "writeToDb": "Write to Redis DB {{db}} (live — be careful)",
    "keyName": "Key",
    "keyNameHint": "Use colon namespaces, e.g. session:user:1",
    "ttlLabel": "TTL (seconds)",
    "ttlHint": "Empty = never expire",
    "m1": "1m",
    "m5": "5m",
    "h1": "1h",
    "d1": "1d",
    "d7": "7d",
    "customSeconds": "Custom seconds",
    "stringValue": "String value via SET",
    "stringContent": "String content",
    "deleteKeyTitle": "Delete this key?",
    "deleteKeyDesc": "Delete “{{key}}” from DB {{db}}? This cannot be undone.",
    "installedOk": "Redis installed",
    "startedOk": "Redis started",
    "memory": "Memory",
    "addKey": "Add key",
    "dbLabel": "DB {{i}}",
    "keysInDb": " · {{n}} key(s)",
    "dbOptionKeys": "DB {{i}} · {{n}} keys",
    "dbOptionEmpty": "DB {{i}} · empty",
    "dbRange": "{{n}} databases (0–{{max}}).",
    "serviceLink": "Change count in service settings",
    "dbsWithData": "DBs with data (quick)",
    "keysShort": "{{k}} keys",
    "keyList": "Key list",
    "pickKey": "Select a key on the left to view content.",
    "ttlPrefix": "TTL: {{ttl}}",
    "writeLiveHint": "Writes live Redis; cannot undo from the panel in one click.",
    "refPath": "Ref: {{path}}",
    "dbEmptyMark": " · empty",
    "noRequirepass": "Protected mode is on, but requirepass is empty or unread — no password.",
    "insecureShort": "No password",
    "setRequirepass": "Set password",
    "generateRequirepass": "Generate and apply password",
    "generateRequirepassTitle": "Generate a Redis password?",
    "generateRequirepassDesc": "Writes requirepass and restarts Redis. The password is shown once. Host change needs EXECUTE.",
    "generateRequirepassDone": "Redis password applied",
    "generatedOnce": "Generated password (shown once): {{password}}",
    "rdbOnlyLossHint": "AOF is off and RDB is on. A restart or crash can lose recent writes.",
    "dirDataContainer": "/data (container)",
    "dirHostDefault": "/var/lib/redis",
    "dirDefaultInstance": "/var/lib/redis/default",
    "dirDataWarn": "/data is usually a container path; this panel cannot confirm it exists.",
    "saveOff": "Disable snapshots (not recommended)",
    "saveOffWarn": "Empty save string turns RDB snapshots off. A crash can lose all data if AOF is also off.",
    "dirMoveWarn": "Changing dir does not move dump.rdb / AOF. The next start uses the new path as-is.",
    "passwordUnset": "Not set on the service",
    "passwordSetHidden": "Set (not shown)"
  },
  "resources": {
    "created": "Created",
    "updated": "Updated",
    "deleted": "Deleted",
    "applyDone": "Apply completed",
    "applyIncomplete": "Apply incomplete"
  },
  "roles": {
    "admin": "Admin",
    "operator": "Operator",
    "viewer": "Viewer",
    "agent": "Agent"
  },
  "runtime": {
    "probed": "Probed",
    "notProbed": "Not probed",
    "probe": "Probe",
    "read": "Read",
    "targetVersion": "Target version",
    "nodeMissing": "Node.js is not installed",
    "probeResult": "Probe result",
    "readonly": "Read-only",
    "installNode": "Install Node.js",
    "needExecuteAdmin": "Needs system-change rights and admin",
    "nodeMajor": "Node major version",
    "nodeMajorHint": "LTS often 20 or 22; align with project runtime",
    "installedNode": "Installed Node {{version}}",
    "installPm2": "Install PM2",
    "installPm2Desc": "One-click npm install -g pm2 (process manager). Requires Node.js first.",
    "installPm2Btn": "Install PM2",
    "reinstallPm2": "Reinstall PM2",
    "installedPm2": "PM2 installed",
    "pm2Status": "PM2 status",
    "pm2Ready": "Ready",
    "pm2MissingShort": "Not installed",
    "pm2NeedNodeFirst": "Install Node.js first, then PM2.",
    "pm2InstallHint": "Runs npm -g as root with system-change rights;",
    "pm2ReadyHint": "PM2 is on PATH; projects can use PM2 process mode.",
    "opsResult": "Ops result",
    "unlimited": "Unlimited",
    "zeroUnlimited": "0 = unlimited",
    "m24": "24m",
    "h1": "1h",
    "d1": "1d",
    "d7": "7d",
    "phpIniLoadFailed": "Failed to load php.ini",
    "loaded": "Loaded",
    "default": "Default",
    "phpMissing": "PHP is not installed",
    "overview": "Overview",
    "fpmSites": "FPM / sites",
    "tools": "Tools",
    "about": "About",
    "installPhp": "Install PHP",
    "versionAlreadyInstalled": "Version {{version}} is already on the host",
    "installedVersionBtn": "Installed {{version}}",
    "newerVersionAvailable": "Current {{current}}; newer supported: {{newer}} (select to install)",
    "switchToNewer": "Select {{version}}",
    "installedVersionsHint": "Detected: {{list}}",
    "phpInstallHint": "Needs system-change rights and admin;",
    "phpVersion": "PHP version",
    "phpExtHint": "Choose extensions to install",
    "phpExtSelect": "PHP extensions",
    "phpExtSelectHint": "Packages install as php{{version}}-…;",
    "phpExtRequired": "Required (core)",
    "phpExtRecommended": "Recommended set",
    "phpExtSelectAll": "Select all extensions",
    "phpExtCoreOnly": "Core only",
    "phpExtSearch": "Search extensions (mysql, gd, redis…)",
    "phpExtEmpty": "No matching extensions",
    "pluginsSelect": "Common tools / plugins",
    "pluginsSelectHint": "Select to install with the runtime (e.g. PM2 for Node, Poetry for Python)",
    "pluginsSearch": "Search tools (pm2, poetry, maven…)",
    "pluginsEmpty": "No matching tools",
    "pluginsRecommended": "Recommended set",
    "pluginsSelectAll": "Select all available",
    "pluginsNone": "No companion tools",
    "pluginsInstallNote": "Select tools then Install selected. First-time runtime install can include tools; if runtime is present, only use the button above.",
    "installPluginsOnly": "Install selected tools ({{version}} already present)",
    "installExtOnly": "Install selected extensions (PHP {{version}} present)",
    "pluginAlreadyOnHost": "already on host",
    "installAddonsOnly": "Install selected add-ons ({{version}} present)",
    "remoteNewerHint": "Installed {{current}} · upstream latest {{remote}}{{source}}",
    "installedPhp": "Installed PHP {{version}}",
    "nextSteps": "Next",
    "suggestedFlow": "Suggested flow",
    "globalPhpIni": "Global php.ini",
    "globalPhpIniDesc": "One setting per row",
    "managePath": "Management path",
    "loading": "Loading",
    "probing": "Probing…",
    "noBinaryPath": "No binary path",
    "hostDefaultError": "Host default unavailable",
    "pm2Tick": "{{at}} · projects {{projects}} · PM2 {{pm2}} · running {{run}}",
    "cannotLoadSettings": "Cannot load settings table",
    "reloadFailed": "Reload failed",
    "sensitive": "Sensitive setting — careful",
    "on": "On",
    "off": "Off",
    "customNumber": "Custom number",
    "customExample": "Custom, e.g. 768M",
    "advancedExtra": "Advanced: extra keys and raw",
    "advancedExtraDesc": "Directives not in catalog; one key=value per line; raw appends to ini tail",
    "extraDirectives": "Extra directives",
    "extraDirectivesHint": "One key=value per line (keys not already above)",
    "rawAppend": "Append raw to end of ini",
    "phpIniSaved": "php.ini saved",
    "appliedSystem": "Applied to system",
    "demoVhost": "System tools: demo vhost / pool",
    "demoVhostDesc": "Advanced/debug; daily sites use Projects → Deploy",
    "domain": "Domain",
    "domainRequired": "Enter a valid domain before applying the vhost.",
    "vhostServerName": "Virtual host server_name",
    "poolName": "Pool name",
    "poolNameHint": "Hand-typed id (demo); project paths use ysks_* users",
    "enableReload": "Enable and reload services",
    "enableReloadHint": "Needs system-change rights; off = write management only",
    "applyFailed": "Apply failed",
    "phpVhostApplied": "PHP vhost / pool applied",
    "composerTools": "Composer / WP-CLI / modules",
    "composerToolsDesc": "Live probe of PATH tools and php -m (read-only)",
    "toolsProbed": "Tools probed",
    "notFound": "Not found",
    "available": "Available",
    "moduleCount": "Modules",
    "installNodeV": "Install Node {{v}}",
    "installPhpV": "Install PHP {{v}}",
    "installPythonV": "Install Python {{v}}",
    "installGoV": "Install Go {{v}}",
    "installRustV": "Install Rust {{v}}",
    "pythonMissing": "Python is not installed",
    "goMissing": "Go is not installed",
    "rustMissing": "Rust/cargo is not installed",
    "tuneLoadFailed": "Failed to load tuning",
    "availableCount": "{{n}} available",
    "notDetected": "Not detected",
    "binaryPath": "Binary path",
    "targetMissing": "Target not installed",
    "targetMissingHint": "Target {{version}} is not on this host. Bind an installed version or install this pin.",
    "target": "Target",
    "tune": "Tune",
    "loadedShort": "Loaded",
    "host": "Host",
    "tabOverviewInstall": "Overview",
    "tabTune": "Tuning",
    "probeReadonlyInstall": "Read-only · probe again after install",
    "hostDefault": "Host default",
    "panelSupport": "Panel support",
    "ready": "Ready",
    "notDetectedYet": "Not detected yet",
    "install": "Install",
    "installHint": "Needs system-change rights and admin; installing toolchain ≠ project is public",
    "panelTune": "Panel tuning",
    "panelTuneDesc": "Write management; inject env on deploy",
    "bindVersion": "Pin version",
    "onePerRow": "One setting per row",
    "zeroAll": "0 = all",
    "custom": "Custom",
    "extraEnv": "Extra environment variables",
    "extraEnvHint": "One KEY=value per line",
    "customEnv": "Custom env",
    "envPreview": "Env preview",
    "envPreviewDesc": "Merged result after save / last load",
    "unsupported": "Unsupported",
    "tuneSaved": "Tuning saved",
    "nodeDetectedHint": "Node detected on host; reinstall follows privileges and may overwrite.",
    "nodeProbeAfter": "After install, re-probe to confirm PATH and version.",
    "installNodeVBtn": "Install Node {{version}}",
    "installPhpVBtn": "Install PHP {{version}}",
    "phpIniSteps1": "Design global values on the php.ini tab and save",
    "phpIniSteps2": "Optional: Apply to system (writes /etc/php/…/conf.d, needs root)",
    "phpIniSteps3": "Project deploy injects merged ini as php_admin_* on the FPM pool",
    "phpIniSteps4": "Projects can override individual keys (Project → Deploy)",
    "phpIniNote": "Changes save to panel dataDir first; Apply to system copies to /etc/php and reloads FPM. Project pools inject php_admin_value on deploy.",
    "phpIniLoading": "Loading php.ini form…",
    "phpIniEmpty": "Empty catalog — reload or ensure API is up.",
    "reloadForm": "Reload form",
    "savePhpIni": "Save php.ini",
    "prodUseProjects": "Production should use Projects",
    "prodPathDesc": ": create PHP project → deploy/apply FPM (pool = project Linux user + isolated home)",
    "systemDemo": "system-level demo/tools",
    "demoNotBind": "(hand-typed pool name) and does not auto-bind project isolation. Global php.ini is on the php.ini tab.",
    "applyOkWritten": "Apply success = files written. Prefer project deploy so User=project Linux user.",
    "applyPhpVhost": "Apply PHP vhost / pool",
    "applyPhpVhostTitle": "Needs confirm — writes pool/vhost files",
    "applyPhpVhostDesc": "Will write the {{pool}} pool and {{domain}} vhost. Reload services: {{reload}}.",
    "reprobeTools": "Re-probe tools",
    "pressReprobe": "Press Re-probe tools to load",
    "installNodeLabel": "Install Node {{v}}",
    "installPhpLabel": "Install PHP {{v}}",
    "installPythonLabel": "Install Python {{v}}",
    "installGoLabel": "Install Go {{v}}",
    "installRustLabel": "Install Rust {{v}}",
    "readShort": "Read",
    "pressReprobeHost": "Press Re-probe to load host version matrix",
    "installScriptNote": "Writes install script; runs only with privileges. Tuning is on the Tuning tab; redeploy projects for process changes.",
    "envNote": "Node: max-old-space-size merges into NODE_OPTIONS. Go/Python/Rust use official env vars.",
    "saveTune": "Save tuning",
    "pressReprobeLoad": "Press Re-probe tools to load",
    "installJavaLabel": "Install / update OpenJDK",
    "installKotlinLabel": "Install / update Kotlin",
    "installBunLabel": "Install / update Bun",
    "javaMissing": "Java (OpenJDK) not detected",
    "kotlinMissing": "Kotlin compiler not detected",
    "bunMissing": "Bun not detected",
    "phpIniCatalog": {
      "groups": {
        "resource": {
          "title": "Resource limits",
          "description": "Memory, execution time, and input limits"
        },
        "upload": {
          "title": "Upload & POST",
          "description": "File uploads and POST body size"
        },
        "session": {
          "title": "Session",
          "description": "Session storage and cookies"
        },
        "error": {
          "title": "Errors & logging",
          "description": "Display errors, logging, and reporting level"
        },
        "opcache": {
          "title": "OPcache",
          "description": "Bytecode cache"
        },
        "security": {
          "title": "Security & paths",
          "description": "Remote files, exposure, and disabled functions"
        },
        "locale": {
          "title": "Timezone & charset"
        },
        "misc": {
          "title": "Other common settings"
        }
      },
      "fields": {
        "memory_limit": {
          "label": "Memory limit",
          "hint": "e.g. 128M, 256M, 512M, -1 (unlimited)"
        },
        "max_execution_time": {
          "label": "Max execution time",
          "hint": "Seconds; 0 = unlimited (CLI)"
        },
        "max_input_time": {
          "label": "Max input time",
          "hint": "Seconds; max time to parse the request"
        },
        "max_input_vars": {
          "label": "Max input variables",
          "hint": "Limit for $_GET / $_POST / $_COOKIE variables"
        },
        "max_input_nesting_level": {
          "label": "Max input nesting level"
        },
        "file_uploads": {
          "label": "Allow file uploads"
        },
        "upload_max_filesize": {
          "label": "Max upload file size"
        },
        "post_max_size": {
          "label": "Max POST size",
          "hint": "Should be ≥ max upload file size"
        },
        "max_file_uploads": {
          "label": "Max files per request"
        },
        "session_save_handler": {
          "label": "Session save handler"
        },
        "session_gc_maxlifetime": {
          "label": "Session lifetime (seconds)",
          "hint": "Seconds"
        },
        "session_cookie_httponly": {
          "label": "Cookie HttpOnly"
        },
        "session_cookie_secure": {
          "label": "Cookie Secure (HTTPS only)",
          "hint": "Recommended for HTTPS sites"
        },
        "session_use_strict_mode": {
          "label": "Session strict mode"
        },
        "display_errors": {
          "label": "Display errors (on page)",
          "hint": "Disable in production"
        },
        "display_startup_errors": {
          "label": "Display startup errors"
        },
        "log_errors": {
          "label": "Log errors"
        },
        "error_reporting": {
          "label": "Error reporting level",
          "hint": "Or an integer such as 32767"
        },
        "error_log": {
          "label": "Error log path",
          "hint": "Empty = system default; absolute path allowed"
        },
        "opcache_enable": {
          "label": "Enable OPcache"
        },
        "opcache_enable_cli": {
          "label": "Enable OPcache for CLI"
        },
        "opcache_memory_consumption": {
          "label": "OPcache memory (MB)",
          "hint": "Unit: MB"
        },
        "opcache_interned_strings_buffer": {
          "label": "Interned strings buffer (MB)"
        },
        "opcache_max_accelerated_files": {
          "label": "Max accelerated files"
        },
        "opcache_validate_timestamps": {
          "label": "Validate timestamps",
          "hint": "In production you may disable and reload manually"
        },
        "opcache_revalidate_freq": {
          "label": "Revalidate frequency (seconds)"
        },
        "allow_url_fopen": {
          "label": "Allow URL fopen"
        },
        "allow_url_include": {
          "label": "Allow URL include"
        },
        "expose_php": {
          "label": "Expose PHP version header"
        },
        "open_basedir": {
          "label": "open_basedir path restriction",
          "hint": "Empty = no limit; separate paths with :"
        },
        "disable_functions": {
          "label": "Disabled functions",
          "hint": "Comma-separated; too strict may break packages"
        },
        "date_timezone": {
          "label": "Timezone"
        },
        "default_charset": {
          "label": "Default charset"
        },
        "short_open_tag": {
          "label": "Allow short open tags (<?)"
        },
        "realpath_cache_size": {
          "label": "Realpath cache size"
        },
        "realpath_cache_ttl": {
          "label": "Realpath cache TTL (seconds)"
        },
        "cgi_fix_redirect": {
          "label": "CGI fix path redirect"
        }
      },
      "options": {
        "sessionFiles": "Files",
        "sessionRedis": "Redis",
        "sessionMemcached": "Memcached",
        "errorReportingProd": "Production (E_ALL minus deprecated/strict)",
        "errorReportingAll": "Everything (E_ALL)",
        "errorReportingQuiet": "Quieter (no NOTICE/DEPRECATED)",
        "errorReportingMinimal": "Errors / warnings / parse only",
        "errorReportingOff": "Off (0)",
        "openBasedirNone": "No restriction (empty)",
        "openBasedirVarWww": "/var/www",
        "openBasedirHome": "/home",
        "openBasedirWwwTmp": "/var/www and /tmp",
        "errorLogDefault": "System default (empty)",
        "errorLogPhp": "/var/log/php/error.log",
        "errorLogFpm": "FPM log path",
        "errorLogSyslog": "syslog"
      },
      "disableFn": {
        "groups": {
          "process": "Process execution",
          "dynamic": "Dynamic loading",
          "info": "Information disclosure",
          "filesystem": "Filesystem",
          "network": "Network / other"
        },
        "extraHint": "Not in catalog (host existing)",
        "customPlaceholder": "Other function name…",
        "searchPlaceholder": "Search functions…",
        "emptyText": "No matches"
      }
    },
    "pluginsAvailableTitle": "Available to install",
    "pluginsInstalledTitle": "Installed on host",
    "pluginsInstalledHint": "Detected on PATH; excluded from install selection. Uninstall is best-effort.",
    "pluginsAllInstalled": "All catalog tools are already on this host.",
    "pluginStatusInstalled": "Installed",
    "pluginUninstall": "Uninstall",
    "pluginUninstallConfirmTitle": "Uninstall tool?",
    "pluginUninstallConfirm": "Remove \"{{name}}\" from this host (via npm/apt/pip as applicable). Stop services that depend on it first.",
    "pluginUninstalled": "Uninstalled {{name}}",
    "pluginUninstallFailed": "Failed to uninstall {{name}}",
    "pluginUninstallBlocked": "Panel cannot uninstall (needs root + EXECUTE)",
    "phpExtAlreadyOnHost": "Installed extensions",
    "pluginsInstallSelected": "Install selected ({{n}})",
    "pluginInstallOk": "Installed {{n}} tool(s)",
    "pluginInstallFailed": "Tool install failed",
    "phpExtUninstallHint": "Uninstall optional extensions (apt remove; never FPM/CLI)",
    "phpExtUninstallConfirmTitle": "Uninstall PHP extension?",
    "phpExtUninstallConfirm": "Will apt remove “{{pkg}}” ({{name}}). Core FPM/CLI is never removed.",
    "phpExtOpsTitle": "Extension ops result",
    "pluginsOpsTitle": "Tools ops result",
    "pluginBatchUninstall": "Uninstall selected ({{n}})",
    "pluginBatchUninstallConfirm": "Uninstall {{n}} selected tools?",
    "pluginBatchUninstalled": "Uninstalled {{n}} tool(s)",
    "pluginBatchLabel": "selected tools",
    "addonsInstallAbove": "Use “Install selected…” above for tools/extensions. This button only installs/confirms the runtime version.",
    "phpExtInstallSelected": "Install selected extensions ({{n}})",
    "phpExtInstallNote": "Select extensions then Install selected. First-time PHP uses Install PHP below (core+ext); when installed only the extensions button is shown.",
    "phpExtInstallNoteInstalled": "Select extensions then Install selected. This version is already on the host — no runtime reinstall.",
    "phpExtInstallNoteFirst": "PHP {{version}} is not installed: select extensions then use Install PHP {{version}} below (one install button, core+extensions).",
    "installPhpWithExt": "Install PHP {{version}} (with selected extensions)",
    "installLogTitle": "Install log (live)",
    "installLogStreaming": "Streaming…",
    "installLogDone": "Finished",
    "installLogWaiting": "Waiting for server output…",
    "activeDefault": "default",
    "switchDefaultBtn": "Set host default to {{version}}",
    "switchDefaultHint": "This version is installed but not the active default",
    "installedNotActive": "{{version}} installed (not default)",
    "multiVersionHint": "Go/Rust keep multiple versions: Install missing ones, then Switch default for PATH",
    "tabProcesses": "Processes",
    "pm2": {
      "title": "PM2 fleet",
      "desc": "PM2 is a process manager. This tab lists the panel user’s processes (read-only). Live updates use SSE (server-sent events) about every 2 seconds.",
      "glossary": "PM2 = process manager; SSE = live stream.",
      "live": "Live",
      "installed": "PM2 installed",
      "version": "pm2 version",
      "path": "pm2 path",
      "counts": "Processes",
      "countsValue": "{{n}} total · {{run}} online · {{stop}} stopped · {{err}} errored",
      "updatedAt": "Last refresh",
      "notInstalled": "PM2 is not on PATH.",
      "installHint": "Install companion plugin on Overview",
      "tableTitle": "Process list",
      "yskOnly": "YSK apps only (ysk-*)",
      "filterPh": "Filter name / script / pid…",
      "emptyTitle": "PM2 not available",
      "emptyDesc": "Install the pm2 plugin for Node, then refresh.",
      "noApps": "No processes",
      "noAppsDesc": "No PM2 apps for the panel user",
      "streamLog": "Live tick log",
      "streamLogDesc": "One line per SSE tick (not process stdout).",
      "col": {
        "name": "Name",
        "status": "Status",
        "mem": "Memory",
        "restarts": "Restarts",
        "uptime": "Uptime",
        "mode": "Mode",
        "script": "Script",
        "interpreter": "Interpreter",
        "user": "User",
        "unit": "Unit",
        "runtime": "Runtime",
        "pid": "PID"
      },
      "projectsTitle": "YSK project processes",
      "projectsDesc": "systemd units for panel projects (default deploy path — not PM2).",
      "projectsCount": "YSK projects",
      "noProjects": "No projects",
      "noProjectsDesc": "No node/bun projects in the panel, or OS user not provisioned.",
      "pm2OnlyDesc": "Only apps started with PM2 under the panel user. systemd deploys appear above.",
      "startupTitle": "Start on boot",
      "startupDesc": "Register PM2 so processes come back after reboot.",
      "systemdActionsHint": "systemd actions need root and YSK_EXECUTE.",
      "startupOk": "Startup registered. {{notes}}",
      "startupFail": "Could not register startup. {{notes}}",
      "actionOk": "{{action}} {{name}} — {{notes}}",
      "actionFail": "Could not {{action}} {{name}}. {{notes}}",
      "startupReady": "Ready",
      "startupReadyYes": "Yes",
      "startupReadyNo": "No",
      "startupUnit": "Unit",
      "startupDump": "Dump",
      "startupInstall": "Install startup",
      "startupSave": "Save process list",
      "actRestart": "Restart",
      "actStop": "Stop",
      "actReload": "Reload",
      "pm2ActionsHint": "PM2 actions apply to the panel user’s process list only.",
      "noteUnparsed": "PM2 list could not be parsed (empty or unexpected output).",
      "notePanelUserOnly": "PM2 list is for the panel process user only.",
      "noteProjectUnits": "{{n}} YSK project unit(s) listed"
    },
    "recordedInstalled": "Recorded {{v}}",
    "remoteSourceSuffix": " ({{source}})",
    "nodePathYskMissingTitle": "Managed Node path not ready",
    "nodePathYskMissing": "YSK-managed Node for version {{version}} is not ready. Re-probe or reinstall.",
    "managedPathMissingTitle": "Managed {{name}} path not ready",
    "managedPathMissing": "YSK-managed {{name}} for version {{version}} is not ready. Re-probe or reinstall.",
    "nodePathUnsafeTitle": "Node path is unsafe",
    "nodePathUnsafe": "Path {{path}} is outside the managed tree; project deploys may fail.",
    "recordedButProbeEmpty": "Panel recorded install {{v}}, but the host probe found no binary. Not installed — re-probe or reinstall.",
    "installedLabel": "Installed",
    "installedHint": "Host probe result — not the control-plane record",
    "targetHint": "Version this page will install or pin",
    "panelDefaultHint": "New projects prefer panel default {{version}} (host CLI may differ).",
    "rebuildFromHost": "Rebuild record from host",
    "rebuiltFromHost": "Record refreshed from host probe",
    "tabTuning": "Tuning",
    "versionPlaceholder": "Latest，",
    "pluginsBundleWithRuntime": "Tools「Install runtime」Install（Install）。",
    "tabSoftware": "Software",
    "overviewSoftwareHint": "Install versions, set host default, and uninstall from the",
    "versionReadyTitle": "{{name}} {{version}} is ready",
    "versionReadyHint": "You can set host default or uninstall from this tab.",
    "softwareVersionTitle": "Version {{version}}",
    "setHostDefault": "Set as host default",
    "alreadyHostDefault": "{{version}} is the host default",
    "setHostDefaultConfirmTitle": "Set host default to {{version}}?",
    "setHostDefaultConfirm": "System CLI (node/go/…) will point at {{version}}. Projects that pin a version are unchanged.",
    "hostDefaultUnsupported": "This runtime does not support switching host default in the panel. Use install or project-level pin.",
    "versionInventory": "Version inventory",
    "versionInventoryDesc": "All panel-supported versions. Select a row to install or set as default.",
    "selectToInstall": "Select",
    "advancedFeatureUninstall": "Advanced: remove entire {{name}} stack…",
    "advancedFeatureUninstallHint": "Removes all {{name}} versions managed by the panel (and companions like PM2 for Node), with impact preview and double confirm. Prefer removing single versions above when possible.",
    "probeReadonly": "Read-only probe of the host",
    "uninstallVersion": "Uninstall {{version}}",
    "uninstallVersionTitle": "Uninstall {{version}}?",
    "uninstallVersionConfirm": "Remove managed {{name}} {{version}} from this host (YSK install path or rustup toolchain). If it was the host default, CLI symlinks for that runtime will be cleared. Projects that pin another version are unchanged.",
    "uninstallVersionDone": "Uninstalled {{version}}",
    "uninstallVersionUnsupported": "Per-version uninstall is not available for this runtime yet.",
    "setPanelDefault": "Set as panel default",
    "alreadyPanelDefault": "Panel default · {{version}}",
    "panelDefaultSaved": "Panel default set to {{version}}",
    "panelDefaultExplain": "Panel default = preferred version for new sites/projects. Host default = system CLI (php/python/node…).",
    "stackReadyTitle": "{{name}} stack ready",
    "softwareIntro": "Manage installed versions, host CLI default, and the version preferred for new projects.",
    "panelDefaultLabel": "Panel default",
    "panelDefaultNone": "Not set",
    "versionsTitle": "Versions",
    "versionsDesc": "Select a version. Install, set host CLI, or set panel default from the row.",
    "roleHost": "Host",
    "rolePanel": "Panel",
    "rowUninstall": "Remove this version",
    "moreActions": "More actions",
    "selectedVersion": "Selected · {{version}}",
    "selectedInstalledDesc": "Companion tools below. Remove this version only if you no longer need it.",
    "selectedMissingDesc": "Install this version on the host. Companion tools can be added after install.",
    "path": "Path",
    "fullVersion": "Full version",
    "useListForDefaults": "To change host or panel default, or remove this version, use the list above.",
    "alreadyHostDefaultShort": "Host default",
    "installRecordedCta": "Install recorded {{v}}",
    "needsInstall": "needs install",
    "needsInstallHint": "Not on this host. Install it first, or pick an installed version.",
    "unitBytes": "bytes",
    "headerSizeKb": "{{n}} KB",
    "phpIniChipEmpty": "Not loaded — open the php.ini tab",
    "phpFpmService": "PHP-FPM",
    "phpFpmServiceDesc": "Start, stop, reload, or restart the PHP-FPM unit",
    "rustupDefaultMissingTitle": "No rustup default toolchain",
    "rustupDefaultMissing": "rustup has no default toolchain. Set one (stable) on the Software tab.",
    "rustupDefaultMissingShort": "No default toolchain",
    "rustupSetDefaultHint": "Set default toolchain",
    "uninstalledCountHint": "{{n}} version(s) not on this host"
  },
  "search": {
    "placeholder": "Search pages & resources…",
    "aria": "Global search",
    "results": "Search results",
    "loading": "Searching…",
    "noResults": "No matches",
    "kinds": {
      "page": "Pages",
      "project": "Projects",
      "email": "Email",
      "mailbox": "Mailboxes",
      "ssl": "SSL",
      "dns": "DNS",
      "nginx": "Nginx",
      "share": "Shares",
      "ftp": "FTP",
      "mysql": "MySQL",
      "postgres": "PostgreSQL",
      "redis": "Redis",
      "cron": "Cron",
      "user": "Users",
      "other": "Other"
    },
    "alias": {
      "ssl": "cert certificate certs",
      "projects": "project sites"
    }
  },
  "security": {
    "title": "Security & Approvals",
    "allowlist": "Tool Allowlist (read-only default; high-risk needs human approval)",
    "llmUntrusted": "LLM output is always untrusted and must never execute directly",
    "pending": "Pending approvals",
    "runSysInfo": "Run sys.info",
    "none": "No pending approvals",
    "pillPending": "{{count}} pending",
    "pillReady": "Ready",
    "pill2faOff": "2FA off",
    "stat2fa": "2FA",
    "statApi": "API keys",
    "statApiSessions": "API sessions",
    "revokeOtherTitle": "Sign out {{n}} other session(s)",
    "statSsh": "SSH",
    "statSshValue": "{{keys}} keys · {{auth}} authorized",
    "statSshHint": "Outbound identities / authorized login keys",
    "statPending": "Pending",
    "on": "On",
    "off": "Off",
    "output": "Output",
    "tabAccount": "My security",
    "tabApiKeys": "API keys",
    "tabSsh": "SSH",
    "tabApprovals": "Approvals",
    "tabAllowlist": "Agent tools",
    "apiTokenOnce": "API token (shown once):",
    "copiedToken": "Token copied",
    "totpTitle": "Two-factor (TOTP)",
    "totpStatus": "Status: ",
    "totpEnabled": "Enabled",
    "totpEnrolledUnconfirmed": "In progress — scan & confirm",
    "totpNotSet": "Not set",
    "totpLead": "Login requires a 6-digit app code.",
    "totpWhy1": "Stolen passwords alone cannot sign in without the app code",
    "totpWhy2": "Sensitive actions can re-prompt for TOTP (step-up)",
    "totpWhy3": "Works with Google Authenticator, Authy, NordPass, 1Password, and more",
    "totpAppsHint": "Suggested apps: Google Authenticator, Authy, Microsoft Authenticator, NordPass, 1Password",
    "totpStepsLabel": "Setup steps",
    "totpStepReauth": "Verify password",
    "totpStepScan": "Scan QR / enter key",
    "totpStepConfirm": "Confirm 6-digit code",
    "totpStepBackup": "Save recovery codes",
    "totpScanTitle": "Scan QR code",
    "totpScanHint": "Open your authenticator app → Add account → Scan this QR.",
    "totpManualTitle": "Or enter the key manually",
    "totpManualHint": "If you cannot scan, choose manual entry in the app and paste this Base32 secret.",
    "totpShowOtpauth": "Show otpauth:// URL (advanced)",
    "totpQrAlt": "TOTP setup QR code",
    "totpQrFailed": "Could not render QR — use the secret key below",
    "totpSecretCopied": "Secret copied",
    "hideSecret": "Hide secret",
    "showSecret": "Show secret",
    "totpEnabledDesc": "Enabled.",
    "totpRecoveryRemaining": "{{n}} recovery codes left",
    "totpResetSummary": "Reset or turn off 2FA…",
    "totpResetHint": "Reset issues a new QR/secret (old app entries stop working)",
    "totpDisableCodeHint": "App 6-digit code or recovery code",
    "disable2fa": "Turn off 2FA",
    "totpDisabledOk": "Two-factor auth turned off",
    "reauthPassword": "Re-enter password",
    "reauthPasswordHint": "Start/reset 2FA requires password again (stolen session protection)",
    "reauthPasswordRequired": "Enter your login password first",
    "needCurrentPassword": "Enter the current password first",
    "passwordMin8": "New password must be at least 8 characters",
    "totpSecretGenerated": "Secret ready — scan the QR or copy the key, then enter the app’s 6-digit code",
    "reset2fa": "Reset 2FA",
    "start2fa": "Set up 2FA",
    "secretLabel": "Secret: ",
    "confirmCode": "6-digit code from app",
    "confirmCodeHint": "After scanning, enter the 6 digits currently shown in your authenticator.",
    "confirmCodeInvalid": "Enter a 6-digit verification code",
    "totpEnabledSaveCodes": "2FA enabled — save the recovery codes below now (shown once)",
    "confirmEnable": "Confirm & enable",
    "recoveryCodesHint": "Recovery codes are shown once only",
    "copiedRecoveryCodes": "Recovery codes copied",
    "downloadRecovery": "Download .txt",
    "recoveryDownloaded": "Recovery codes file downloaded",
    "copyAll": "Copy all",
    "savedClose": "I've saved them — done",
    "sessionsTitle": "Sessions",
    "sessionsDesc": "",
    "revokeOtherSessions": "Sign out other devices",
    "revokedOtherSessions": "Signed out {{count}} other session(s)",
    "noSessions": "No active sessions",
    "currentSession": "This device",
    "revoke": "Sign out",
    "passkeyTitle": "Passkey / WebAuthn",
    "passkeyDesc": "",
    "passkeyRegistered": "Passkey registered",
    "webauthnFailed": "WebAuthn failed",
    "webauthnUnsupported": "This page has no WebAuthn API. In Brave/Chrome/Firefox avoid restricted modes; use a password manager if needed, and open the panel on a domain over HTTPS.",
    "webauthnInsecureContext": "This page is not a secure context ({{origin}}). Browsers require HTTPS or localhost for Passkeys — unrelated to Brave/NordPass. Open https://your-domain instead.",
    "webauthnIpHost": "You opened the panel via IP ({{origin}}). WebAuthn forbids IP as RP ID, so Brave/NordPass will fail. Bind a domain + HTTPS (e.g. https://panel.example.com) and retry.",
    "webauthnEnvOk": "Passkey ready ({{origin}})",
    "webauthnEnvCurrent": "Current page: {{origin}}",
    "webauthnCancelled": "Cancelled or timed out. Try again.",
    "webauthnUnavailableHint": "Passkey needs HTTPS + domain.",
    "registerPasskey": "Register passkey",
    "noPasskey": "No passkey",
    "passkeyVerifyOk": "Passkey verified (step-up done)",
    "verifyFailed": "Verification failed",
    "verifyWithPasskey": "Verify with passkey (step-up)",
    "passkeyHint": "For high-risk step-up; needs HTTPS + domain.",
    "devicesTitle": "Devices / backup",
    "devicesDesc": "",
    "viewTrustedDevices": "View trusted devices",
    "trustedDevicesCount": "Trusted devices: {{count}}",
    "revokeAllDevices": "Revoke all devices",
    "revokedAllDevices": "All trusted devices revoked",
    "export2faBackup": "Export 2FA encrypted backup",
    "fail2banSnippetMsg": "fail2ban snippets: {{written}} — {{notes}}",
    "generatefail2ban": "Generate fail2ban snippets",
    "generateFail2ban": "Generate fail2ban snippets",
    "adminPolicyTitle": "Admin 2FA policy",
    "adminPolicyDesc": "",
    "requireAdmin2fa": "Require admin 2FA",
    "strictAdmin2fa": "Strict: block login without 2FA",
    "confirmTotpPolicy": "Confirm TOTP (when changing policy)",
    "confirmTotpPolicyHint": "Enabling policy needs step-up",
    "totp6digitPlaceholder": "6-digit code",
    "policyUpdated": "Security policy updated",
    "savePolicy": "Save policy",
    "recentProbe": "Recent probe",
    "apiKeysTitle": "API access keys",
    "apiKeysDesc": "",
    "createKey": "+ Create key",
    "colName": "Name",
    "colPrefix": "Prefix",
    "colCreated": "Created",
    "apiKeysEmpty": "No API keys yet",
    "apiKeysEmptyHint": "Create from the toolbar; then call API with Bearer token",
    "approve": "Approve",
    "allowlistTitle": "Agent tools ({{count}})",
    "allowlistEmpty": "No agent tools in the catalog",
    "totpStatusLoadFailed": "Could not load 2FA status",
    "createApiKeyTitle": "Create API key",
    "createApiKeyDesc": "Full token is shown only once after create",
    "createKeyBtn": "Create key",
    "apiKeyNameHint": "Easy to recognize, e.g. CI / backup script",
    "apiKeyScope": "Scope",
    "apiKeyScopeHint": "read = read-only (no full mutate)",
    "scopeFull": "full (full API)",
    "scopeRead": "read (read-only)",
    "apiKey2faHint": "If 2FA is on, creating a key requires a verification code (step-up).",
    "apiKeyCreated": "API key created",
    "export2faBackupTitle": "Export 2FA backup",
    "createApiKeyStepUp": "Create API key · step-up",
    "enterTotpCode": "Enter current TOTP code",
    "export": "Export",
    "backupCopied": "Encrypted backup copied to clipboard (store offline)",
    "digit6Placeholder": "6-digit code",
    "ssh": {
      "workspaceTitle": "SSH workspace",
      "workspaceDesc": "Pick a job first",
      "subOutbound": "Outbound IDs",
      "subOutboundHint": "Private keys for panel/project outbound",
      "subLogin": "Login auth",
      "subLoginHint": "Who can SFTP/SSH in",
      "sub2fa": "Login 2FA",
      "sub2faHint": "SSH TOTP (≠ panel 2FA)",
      "subSshd": "System sshd",
      "subSshdHint": "Project user SFTP settings",
      "jobOutboundTitle": "Connect outbound",
      "jobOutboundDesc": "Create outbound identity keys · panel peer / project git",
      "jobLoginTitle": "Allow inbound login",
      "jobLoginDesc": "Register public keys to project home · authorized_keys",
      "job2faTitle": "SSH login needs 2FA",
      "job2faDesc": "Linux user TOTP (separate from panel 2FA)",
      "jobSshdTitle": "Enable system SFTP",
      "jobSshdDesc": "Install sshd Match snippets (project users)",
      "purposePanel": "Panel to other hosts",
      "purposeUser": "Project user outbound",
      "purposeUnbound": "Purpose not set",
      "purposePanelHint": "Cluster peer, backup scp, remote probes",
      "purposeUserHint": "Project Linux user git / scp / scripts",
      "purposeDefaultHint": "Bind later",
      "statusStored": "Stored",
      "statusInstalled": "On disk",
      "statusVerified": "Verified",
      "statusMissing": "Missing on disk",
      "statusRetired": "Retired",
      "statusError": "Error",
      "actionInstall": "Write to disk",
      "actionTest": "Test connection",
      "actionCopyPub": "Copy public key",
      "pipelineStored": "Stored",
      "pipelineInstalled": "On disk",
      "pipelineVerified": "Verified",
      "progressAria": "Progress",
      "loginTitle": "Login authorization (public keys)",
      "loginDesc": "Who can come in",
      "loginAdd": "Add login public key",
      "loginEmpty": "No login public keys yet",
      "loginEmptyHint": "Paste a laptop or CI public key, bind to a project user for SFTP/SSH (needs sshd snippet)",
      "loginAddFirst": "Add first login public key",
      "boundProject": "Project",
      "unboundProject": "No project",
      "loginRemoved": "Public key removed",
      "remove": "Remove",
      "loginModalTitle": "Authorize a public key",
      "loginModalDesc": "After selecting a project, the key is written to that Linux user home/",
      "addAuth": "Add authorization",
      "selectOption": "— Select —",
      "publicKey": "Public key",
      "publicKeyHint": "Paste full line, e.g. ssh-ed25519 AAAA… comment",
      "commentOptional": "Comment (optional)",
      "commentPlaceholder": "laptop / CI",
      "loginNeedProject": "Create a project first. Binding works best when the system user is ready.",
      "loginNeedPub": "Select a project or Linux user, and paste a public key starting with ssh-",
      "loginNoProjects": "No projects. Authorize an existing Linux user (root / tester) below. Writing /root/.ssh needs YSK_EXECUTE=1.",
      "loginLinuxHint": "Used when no project. Example: root or tester.",
      "loginAdded": "Added",
      "sshdTitle": "Project user SFTP (sshd)",
      "sshdDesc": "Let ysks_* / ysk_* project users SFTP with public keys",
      "sshdStep1": "Add public keys under Login auth for projects",
      "sshdStep2": "Preview and install system Match snippets here",
      "sshdStep3": "Install needs system execute rights; will try to reload sshd",
      "sshdPreview": "Config preview",
      "loadingSnippet": "(Loading…)",
      "reloadedCopied": "Reloaded; snippet copied to clipboard",
      "reloadAndCopy": "Reload and copy",
      "installedOk": "Installed",
      "installToSystem": "Install to system",
      "sshdManualHint": "If execute is blocked, run the control plane with privileges, or place the snippet under",
      "outboundTitle": "Outbound identity keys",
      "outboundDesc": "Private keys encrypted in control plane",
      "outboundAdd": "Add outbound identity",
      "filterActive": "Active",
      "filterPanel": "Panel",
      "filterUser": "Project user",
      "filterRetired": "Retired",
      "filterAll": "All",
      "searchIdentity": "Search name or fingerprint…",
      "searchIdentityAria": "Search identities",
      "identityCount": "{{count}} identities",
      "identityList": "Identities",
      "outboundEmpty": "No outbound identities yet",
      "outboundEmptyFilter": "No matching items",
      "outboundEmptyHint": "Create a key in ~30s: pick purpose → name → done. Use for peer / backup / git.",
      "outboundEmptyFilterHint": "Try changing filters or clear search",
      "outboundAddFirst": "Add first outbound identity",
      "userPrefix": "User {{user}}",
      "createFailed": "Create failed",
      "identityCreatedOnce": "Identity created (private key shown once)",
      "writtenToDisk": "Written to disk",
      "cannotWriteNeedExecute": "Cannot write to system: enable execute (YSK_EXECUTE)",
      "notDone": "Not completed",
      "installFailed": "Install failed",
      "testPassed": "Connection OK",
      "testFailed": "Connection failed",
      "testError": "Test failed",
      "copiedPubPaste": "Public key copied — paste into peer authorized_keys or Git deploy key",
      "deletedNamed": "Deleted \"{{name}}\"",
      "rotated": "Rotated: old key retired, new key created",
      "detailStatus": "Status",
      "detailPurpose": "Purpose",
      "detailLinuxUser": "Linux user",
      "detailDiskPath": "Disk path",
      "detailLastTest": "Last test",
      "suggestFlow": "Suggested: store → write disk → put public key on peer → test connection",
      "suggestFlowPrefix": "Suggested: store → write disk → put ",
      "suggestFlowSuffix": " on peer → test connection",
      "publicKeyStrong": "public key",
      "copiedPub": "Public key copied",
      "allowLocalLogin": "Allow local login with this key",
      "localLoginOk": "Public key added to local login authorization",
      "testingConnection": "Testing connection…",
      "rotateKey": "Rotate key",
      "wizStepPurpose": "What is this key for?",
      "wizStepProject": "Which project?",
      "wizStepPanelConfirm": "Confirm panel outbound",
      "wizStepName": "Name and options",
      "wizStepPurposeDesc": "Pick purpose so list and install path align",
      "wizStepProjectDesc": "Key binds to that project's Linux user and home",
      "wizStepPanelDesc": "Private key stays in control-plane secrets for scp/ssh to other hosts",
      "wizStepNameDesc": "Name for recognition; advanced options can wait",
      "prevStep": "Back",
      "nextStep": "Next",
      "createIdentity": "Create identity",
      "purposePanelTitle": "Panel to other hosts",
      "purposePanelSub": "Cluster peer, remote backup, probes",
      "purposePanelRec": "Recommended for most admin ops",
      "purposeUserTitle": "Project user outbound",
      "purposeUserSub": "git pull, project script scp",
      "purposeUserPath": "Writes project home/.ssh",
      "selectProject": "— Select project —",
      "noProjectsHint": "No projects yet — create a project and system user first",
      "afterCreatePub": "After create, put the ",
      "afterCreatePubMid": " on the target host's ",
      "afterCreatePubEnd": ", then use Test connection.",
      "privKeyStayLocal": "Private key stays on this control plane; never in lists or logs.",
      "displayName": "Display name",
      "displayNameHint": "e.g. peer-prod, myapp-git",
      "algorithm": "Algorithm",
      "algoSuggested": "Recommended",
      "algoLegacy": "Legacy systems",
      "installImmediately": "Write to disk immediately after create",
      "installImmediatelyHint": "(needs system execute; otherwise you will be told it cannot apply)",
      "savePrivTitle": "Save private key now",
      "savePrivDesc": "After close, full private key will not be shown again",
      "copiedPriv": "Private key copied",
      "copyPriv": "Copy private key",
      "nextInstallDisk": "Next: write to disk",
      "savedCloseBtn": "Saved — close",
      "privKeyOnce": "Private key (this time only)",
      "privSavedConfirm": "I stored the private key safely (password manager / offline backup)",
      "testConnTitle": "Test connection",
      "testConnDesc": "Try ssh … true with this identity. Success only means this target is reachable.",
      "startTest": "Start test",
      "testTarget": "Target",
      "testTargetHint": "Format user@host or user@host:port",
      "deleteIdentityTitle": "Delete identity?",
      "rotateKeyTitle": "Rotate key?",
      "deleteIdentityDesc": "Delete \"{{name}}\" and try to remove the private key file on disk",
      "rotateKeyDesc": "\"{{name}}\" will be retired and a new key created. Update peer authorized_keys.",
      "rotate": "Rotate",
      "enrollStatusSecret": "Secret generated",
      "enrollStatusConfirmed": "App confirmed",
      "enrollStatusWritten": "Written to home",
      "enrollStatusRetired": "Retired",
      "needProjectOrUser": "Select a project or enter a Linux username",
      "enrollFailed": "Enrollment failed",
      "totpGenerated": "SSH-only TOTP generated (separate from panel 2FA unless you sync)",
      "confirmed": "Confirmed",
      "codeWrong": "Wrong code",
      "gaWritten": "Wrote .google_authenticator",
      "needExecute": "Needs system execute enabled",
      "ssh2faTitle": "SSH login second factor",
      "ssh2faDesc": "Protects ssh login for Linux users",
      "ssh2faStep1": "Enroll TOTP for a Linux user (scan QR)",
      "ssh2faStep2": "Confirm App 6-digit code",
      "ssh2faStep3": "Write home file",
      "ssh2faStep4": "Install PAM module and merge snippets (below)",
      "pkgLabel": "Package {{name}}",
      "pkgStatus": "Package {{status}}",
      "pamStatus": "PAM {{status}}",
      "kbdStatus": "sshd keyboard-interactive {{status}}",
      "light": {
        "green": "ok",
        "yellow": "check",
        "red": "missing"
      },
      "enrollForUser": "Enroll SSH 2FA for user",
      "ssh2faEmpty": "No Linux user has SSH 2FA yet",
      "ssh2faEmptyHint": "Prefer key login first;",
      "startEnroll": "Start enrollment",
      "fromPanelBadge": "Same as panel",
      "enterCode": "Enter code",
      "rewriteHome": "Rewrite home file",
      "writeHome": "Write home",
      "retiredOk": "Retired",
      "retire": "Retire",
      "pamTitle": "System: PAM / sshd (manual or apply when permitted)",
      "pamDesc": "nullok avoids locking users without files. File written ≠ TOTP required.",
      "pamSnippet": "PAM snippet (merge into /etc/pam.d/sshd)",
      "sshdHint": "sshd hints",
      "rescueUsers": "Rescue users (comma-separated, never in strict Match)",
      "strictPreview": "Strict Match preview (publickey+TOTP, password off)",
      "copiedPam": "PAM snippet copied",
      "copyPam": "Copy PAM",
      "applyStrict": "Apply Strict to system",
      "pamPkgHint": "Package: ",
      "pamRescueHint": ". Keep at least one rescue admin without a 2FA file (default root).",
      "enrollModalTitle": "Enroll SSH 2FA",
      "enrollModalDesc": "Default: independent secret (not shared with panel)",
      "generateShowSecret": "Generate and show secret",
      "projectSuggested": "Project (recommended)",
      "orManualUser": "— or enter user manually —",
      "linuxUser": "Linux user",
      "advancedSharePanel": "Advanced: use current panel operator TOTP secret (type SHARED to confirm)",
      "setupAuthTitle": "Set up authenticator",
      "setupAuthDesc": "Scan or enter secret, then confirm with App 6-digit code",
      "later": "Later",
      "confirmCodeBtn": "Confirm code",
      "secretBase32": "Secret (base32)",
      "copiedSecret": "Secret copied",
      "copySecret": "Copy secret",
      "scanThenCode": "If already scanned, enter the current 6-digit code.",
      "verifyCode": "Verification code",
      "applyStrictStepUp": "Apply Strict · step-up",
      "enterPanelTotp": "Enter current panel TOTP code",
      "applyBtn": "Apply",
      "appliedOk": "Applied",
      "sharePanelTitle": "Share panel TOTP secret?",
      "sharePanelDesc": "High risk. Type SHARED to confirm.",
      "confirmString": "Confirmation string",
      "enableShare": "Enable sharing",
      "invalidPub": "Paste a full OpenSSH public key line (ssh-ed25519 / ssh-rsa / ecdsa…).",
      "dryRunOk": "Dry-run finished. Review the preview below.",
      "strictDryRun": "Strict preview (dry-run)",
      "errorNoDetail": "Test failed (no details)",
      "strictBlocked": "Package or PAM is not ready; Strict apply is disabled.",
      "privCloseWithoutAck": "Closed. The private key will not be shown again; generate a new one if you did not save it."
    },
    "sessionsActive": "Active sessions",
    "sessionsOther": "Other devices",
    "sessionsHint": "",
    "noSessionsHint": "When you sign in again, this device will appear here.",
    "sessionOtherBadge": "Other",
    "sessionThisDevice": "You’re here",
    "sessionDeviceOn": "{{browser}} on {{os}}",
    "sessionIpUnknown": "IP unknown",
    "sessionLastActive": "Last active {{when}}",
    "sessionStarted": "Signed in {{when}}",
    "sessionIdShort": "ID {{id}}…",
    "sessionJustNow": "just now",
    "sessionMinAgo": "{{n}} min ago",
    "sessionHourAgo": "{{n}} h ago",
    "sessionDayAgo": "{{n}} d ago",
    "revokeSessionTitle": "Sign out this device?",
    "revokeSessionDesc": "End session for {{device}} ({{ip}}). That device will need to sign in again.",
    "revokeOthersTitle": "Sign out all other devices?",
    "revokeOthersDesc": "This will end {{count}} other session(s). Your current browser stays signed in.",
    "sessionRevoked": "Session signed out",
    "mySecurityHint": "",
    "policyTotpHint": "Site policy: each admin must enable their own 2FA (individual QR)",
    "requireUser2fa": "Require 2FA for all panel users",
    "changePasswordTitle": "Change sign-in password",
    "currentPassword": "Current password",
    "newPassword": "New password",
    "confirmNewPassword": "Confirm new password",
    "passwordMismatch": "New passwords do not match.",
    "changePassword": "Change password",
    "passwordChanged": "Password updated.",
    "strictNeedsEnrolled": "Enable 2FA on this admin account before turning on Strict.",
    "policyTotpNeedSelf": "Enable 2FA on this account first; the confirm code cannot be filled otherwise.",
    "policyNoTotpHint": "This account has no 2FA yet. Turn on 2FA above before requiring it for admins or all users — otherwise you can lock everyone out.",
    "policyNeedSelf2fa": "Enable 2FA on this account first, then confirm with a TOTP code",
    "revokeAllDevicesTitle": "Revoke every remembered device — you and other admins must verify 2FA again",
    "sessionCli": "CLI",
    "sessionApi": "API",
    "fail2banSnippetTitle": "fail2ban snippet",
    "fail2banSnippetEmpty": "No snippet was written.",
    "trustedDevicesTitle": "Trusted devices",
    "noTrustedDevices": "No trusted devices.",
    "strictConfirmTitle": "Turn on Strict 2FA?",
    "strictConfirmDesc": "Users without 2FA will be refused sign-in. Confirm you already have a working TOTP or passkey.",
    "revokeDevicesTitle": "Revoke trusted devices?",
    "revokeDevicesDesc": "Remembered browsers will need 2FA again.",
    "approvalsHint": "Approvals appear when a high-risk tool needs a second operator. Grant Review approvals and Handle approvals on Users → Permissions.",
    "allowlistReadonly": "Read-only catalog of agent tools. Capability grants are configured on Users → Permissions.",
    "colTool": "Tool",
    "colAllowed": "Allowed",
    "colRisk": "Risk",
    "colApproval": "Approval",
    "risk": {
      "low": "Low",
      "medium": "Medium",
      "high": "High",
      "critical": "Critical"
    },
    "confirmDeleteApiKey": "Delete this API key?",
    "confirmDeleteApiKeyDesc": "“{{name}}” will stop authenticating. This cannot be undone."
  },
  "serviceExposure": {
    "title": "Network access",
    "manage": "Manage access",
    "manageTitle": "Service network access",
    "manageDesc": "Control how {{service}} is reachable on the host firewall.",
    "mode": "Access mode",
    "modePrivate": "Local only",
    "modePublic": "Public",
    "modeRestricted": "Restricted",
    "modeUndecided": "Not set",
    "modePublicLive": "Public (live bind)",
    "summaryPublicLive": "Listening on {{bind}} — reachable on all interfaces. Confirm access mode; this is not private.",
    "modeLoading": "Loading",
    "summaryPrivate": "Not open on the public firewall.",
    "summaryPublic": "Open · {{ports}}",
    "summaryUndecided": "Access mode not confirmed (catalog default: {{suggested}}).",
    "summaryNotEnforced": "Firewall is off — the panel is not opening or blocking these ports.",
    "roleSmtp": "SMTP submission",
    "roleImap": "IMAP / POP3 mailbox",
    "summaryRestricted": "Restricted · {{count}} source(s)",
    "summaryFirewallOff": "Host firewall: {{detail}} — rules not enforced until UFW is active.",
    "summaryFirewallOffOnly": "Host firewall is not enabled, so port rules are not enforced.",
    "outOfSync": "Out of sync",
    "openButStopped": "Ports open — service not running",
    "openNoTenants": "Public ports with no tenants",
    "firewallOff": "Firewall off",
    "ufwMissing": "UFW not installed",
    "ufwInactive": "inactive",
    "firewallLink": "Firewall",
    "portsLabel": "Ports",
    "allowFrom": "Allowed sources (IP / CIDR)",
    "allowCountries": "Allowed countries (ISO)",
    "hintPrivate": "Service may still listen on localhost; no public UFW allow rules.",
    "hintPublic": "Warning: opens this port to the whole Internet. Prefer restricted for databases.",
    "hintRestricted": "Comma-separated IPs or CIDRs. Only these sources may connect.",
    "hintCountries": "L2 best-effort via ipset + country zone CIDRs. Requires root, EXECUTE, and ipset. Cloud security groups are separate.",
    "restrictedNeedIp": "Add at least one IP or CIDR for restricted mode.",
    "restrictedNeedSource": "Add at least one IP/CIDR or country code for restricted mode.",
    "privateStartTitle": "Expose {{service}} on the network?",
    "confirmAndStart": "Confirm and start",
    "cloudSgNote": "Host firewall only — cloud security groups (AWS/GCP/Azure) are not changed.",
    "serviceNotInstalled": "This service is not installed, so firewall rules do not apply."
  },
  "services": {
    "enabledBoot": "On boot",
    "unitNotFound": "Not installed",
    "bootNa": "Not applicable",
    "unitNa": "Not applicable",
    "permLabel": "Permission",
    "permCanChange": "Can change the system (superuser)",
    "permBlocked": "Cannot change the system",
    "permHint": "System change {{exec}} · Superuser {{root}}",
    "clusterLegend": "Planned = saved in the panel, not applied on the host.",
    "active": {
      "active": "Running",
      "inactive": "Stopped",
      "not-found": "Not installed",
      "failed": "Failed",
      "tool": "Tool",
      "activating": "Starting"
    },
    "unitStatic": "static",
    "unitIndirect": "indirect",
    "action": {
      "start": "Start",
      "stop": "Stop",
      "restart": "Restart",
      "reload": "Reload",
      "enable": "Enable on boot",
      "disable": "Disable on boot"
    },
    "enabledOk": "{{label}} enabled on boot",
    "bootDisabledWarn": "{{label}} is running but will not start at boot. Enable it to persist across reboot.",
    "bootDisabledShort": "Not on boot",
    "sshdBootOffWarn": "sshd is not enabled on boot. After reboot this host will have no SSH rescue path.",
    "mariadbNotInstalled": "MariaDB is not installed",
    "mariadbNotInstalledMysqlOk": "Not installed: MariaDB (MySQL is installed)",
    "lifecycleTitle": "{{label}} service control",
    "startedOk": "{{label}} started",
    "stoppedOk": "{{label}} stopped",
    "needRunning": "{{label}} is not running",
    "restartedOk": "{{label}} restarted",
    "reloadedOk": "{{label}} reloaded",
    "reloadTitle": "Reload {{label}} configuration without a full restart",
    "stopNeedConfirm": "Needs confirmation",
    "stopNeedConfirmPhrase": "Needs confirmation phrase",
    "stopNeedConfirmImpact": "Stop {{label}}? Active connections to this service will drop.",
    "stopConfirmTitle": "Stop {{label}}?",
    "stopConfirmDesc": "{{label}} will stop listening. Start it again from this page when needed.",
    "stopConfirmEdgeDesc": "Stopping {{label}} takes sites and reverse-proxy traffic offline until it is started again.",
    "stopConfirmEdgeConsequence": "HTTP/HTTPS on this host will not be served while {{label}} is stopped.",
    "stopConfirmSshdTitle": "Stop sshd?",
    "stopConfirmSshdDesc": "Stopping sshd closes remote SSH. Confirm you still have a console or another login path.",
    "stopConfirmSshdToken": "stop sshd",
    "stopConfirmSshdConsequence": "New SSH sessions will fail until sshd is started from the host console.",
    "stopConfirmPanelTitle": "Stop YSK Server?",
    "stopConfirmPanelDesc": "The panel and API will go offline until the unit is started on the host.",
    "stopConfirmPanelSshdOffDesc": "The panel and API will go offline. sshd is not enabled on boot, so SSH may not be a rescue path after reboot.",
    "stopConfirmPanelSshdOffConsequence": "sshd is not enabled on boot. After reboot you may have no SSH rescue path.",
    "ufwNoLifecycle": "UFW is not started or stopped from this matrix.",
    "restartConfirmPanelTitle": "Restart YSK Server?",
    "restartConfirmPanelDesc": "The panel and API will drop briefly while the unit restarts.",
    "restartConfirmTitle": "Restart {{label}}?",
    "restartConfirmDesc": "Restart {{label}} now. Active connections may drop.",
    "restartConfirmConsequence": "{{label}} will briefly interrupt connections, then keep serving HTTP/HTTPS.",
    "reloadConfirmTitle": "Reload {{label}}?",
    "reloadConfirmDesc": "Reload {{label}} configuration. Existing sessions should stay up.",
    "enableConfirmTitle": "Enable {{label}} at boot?",
    "enableConfirmDesc": "Enable {{label}} so it starts on boot.",
    "startVerifyFailed": "{{label}} start did not stay healthy.",
    "stopConfirmPanelToken": "stop ysk-server",
    "stopConfirmPanelConsequence": "This browser session will disconnect. Start the unit from SSH or the host console.",
    "stopConfirmFail2banTitle": "Stop fail2ban?",
    "stopConfirmFail2banDesc": "Stopping fail2ban turns off automatic IP bans. Websites and SSH keep running.",
    "stopConfirmFail2banConsequence": "New attackers are not banned until fail2ban is started again.",
    "actionDone": "{{action}} done",
    "runningOf": "{{running}}/{{total}} running",
    "statusFilter": {
      "all": "All states",
      "running": "Running",
      "failed": "Failed",
      "missing": "Not installed"
    },
    "canMutate": "Mutable",
    "locked": "Locked",
    "controlUnit": "Control-plane unit",
    "logs": "Logs",
    "dbHa": "Database HA",
    "clusterCount": "{{count}} cluster(s)",
    "mariadbCluster": "MariaDB cluster",
    "probing": "Probing service matrix…",
    "lifecycleLocked": "Lifecycle actions locked: need root + YSK_EXECUTE. Probes still work. See",
    "hostSettings": "Host settings",
    "matrixTab": "Service matrix ({{count}})",
    "stackTab": "Software stack",
    "stackTitle": "Host software stack",
    "stackHint": "Software plans install OS packages. The service matrix tab lists systemd units — the two counts are not the same set.",
    "protectionTab": "Protection probe",
    "knownServices": "Known services",
    "showing": "Showing {{shown}} / {{total}}",
    "all": "All",
    "searchPh": "Name / unit / category",
    "noMatch": "No matching services",
    "bootPrefix": "Boot {{state}}",
    "controlPage": "Control page",
    "manageRuntime": "Install / update",
    "installOrOpen": "Install / open",
    "protectionTitle": "Protection probe",
    "protectionSub": "Read-only; does not change firewall / fail2ban",
    "protectionDoneNote": "Protection probe finished",
    "probeDone": "Probe complete",
    "runProtection": "Run protection probe",
    "notProbedYet": "Not probed yet",
    "cat": {
      "web": "Web",
      "db": "Databases",
      "mail": "Mail",
      "dns": "DNS",
      "ftp": "FTP",
      "cache": "Cache",
      "panel": "Panel",
      "ssh": "SSH",
      "other": "Other",
      "runtime": "Runtimes"
    }
  },
  "software": {
    "title": "Software",
    "desc": "All managed software: install status, service health, newer versions, and links to use in projects.",
    "tabs": {
      "overview": "Overview",
      "runtimes": "Runtimes",
      "databases": "Databases",
      "edge": "Domains & edge",
      "mailFiles": "Mail & files",
      "host": "Host services"
    },
    "stat": {
      "catalog": "Catalog items",
      "runtimesInstalled": "Runtimes installed",
      "updates": "Updates / expandable",
      "attention": "Needs attention"
    },
    "quickTitle": "Shortcuts",
    "quickDesc": "Jump to a section or host tools",
    "updatesTitle": "Updates & installable versions",
    "updatesDesc": "Newer upstream or panel pins. Install, then select the runtime on a project.",
    "allSoftware": "All software",
    "status": {
      "unknown": "—",
      "installed": "Installed",
      "notInstalled": "Not installed",
      "running": "Running",
      "missing": "Not detected",
      "failed": "Failed",
      "stopped": "Stopped"
    },
    "badge": {
      "update": "Update available",
      "upToDate": "Up to date"
    },
    "meta": {
      "installed": "Installed: {{list}}",
      "default": "Default {{v}}",
      "remote": "Upstream ~{{v}}",
      "openManage": "Open manage page to install or configure",
      "aptCurrentLatest": "Installed {{v}} · repo is latest",
      "aptVersion": "Installed {{v}}",
      "aptUpgrade": "{{from}} → {{to}} available",
      "aptUpgradeMulti": "{{n}} packages upgradable: {{list}}",
      "aptNotInstalled": "Package not installed (open manage page to install)",
      "hostUpgradable": "~{{n}} upgradable packages on host",
      "checking": "Checking versions… or open manage page"
    },
    "action": {
      "manage": "Manage",
      "useInProject": "Use in project",
      "useInProjectTitle": "Open projects to set this runtime",
      "update": "Update",
      "updateTitle": "Install or switch to {{v}}",
      "updateTo": "Update to {{v}}",
      "installVersion": "Install {{v}}",
      "applyAptTitle": "Confirm update {{pkg}}",
      "updateN": "Update {{n}} items",
      "installTitle": "Install {{list}}",
      "install": "Install",
      "updateAptTitle": "Open Updates for {{pkg}}"
    },
    "apply": {
      "blockedShort": "Blocked",
      "failedShort": "Failed",
      "failed": "Update failed",
      "blocked": "Blocked",
      "confirm": "Confirm update",
      "confirmTitle": "Confirm software update?",
      "confirmBody": "Update {{pkg}}: {{from}} → {{to}}. Needs system-change rights.",
      "ok": "Applied {{pkg}}",
      "progress": "Updating {{n}}/{{total}}: {{pkg}}",
      "okMulti": "Updated: {{list}}",
      "okMultiTitle": "{{label}} updated",
      "partial": "Partial success",
      "partialTitle": "Some updates failed",
      "failedTitle": "{{label}} update failed",
      "progressDetail": "{{from}} → {{to}}",
      "confirmBodyMulti": "Update {{label}}: {{list}}"
    },
    "version": {
      "loading": "Loading versions…",
      "installed": "Installed",
      "latest": "Latest",
      "upToDate": "Up to date / repo latest",
      "refresh": "Recheck latest",
      "refreshHasUpdate": "Newer version available",
      "refreshLatest": "Already the latest recorded version",
      "pick": "Pick version",
      "noTarget": "No update target",
      "needRuntimePage": "Install this version on the runtime page",
      "noAptCandidate": "No apt candidate version",
      "sourceLabel": "Source"
    },
    "install": {
      "progress": "Installing: {{list}}…",
      "progressHint": "May take a minute or two",
      "blockedTitle": "{{label}} could not install",
      "ok": "Install queued: {{list}}",
      "okTitle": "{{label}} installed / queued",
      "failedTitle": "{{label}} install failed",
      "confirmTitle": "Confirm software install?",
      "confirmBody": "Install {{label}}: {{list}}. Needs system-change rights.",
      "confirm": "Confirm install"
    },
    "runtime": {
      "installing": "Installing/updating {{kind}} {{v}}…",
      "installingHint": "May take a minute or two",
      "blockedTitle": "{{kind}} {{v}} could not install",
      "installed": "Installed/updated {{kind}} {{v}}",
      "installedDetail": "Select this version on a project",
      "failedTitle": "{{kind}} {{v}} install failed",
      "installingShort": "Installing…"
    },
    "aptSummaryTitle": "Repo upgrades available",
    "aptSummaryDesc": "Catalog and host package counts are separate; apply from Updates or a card.",
    "aptSummary": {
      "catalog": "Catalog {{n}}",
      "host": "Host packages {{n}}",
      "openUpdates": "Open updates"
    },
    "navBadgeTitle": "Catalog upgrades: {{n}}",
    "projectHint": "Runtime {{runtime}} prefilled — create a project",
    "projectHintWithVersion": "Runtime {{runtime}} {{version}} prefilled — create a project"
  },
  "softwareBanner": {
    "titleDefault": "Required software is not installed",
    "missing": "Missing: {{names}}",
    "nameSep": ", ",
    "installOneClick": "Install now",
    "installing": "Installing…",
    "reprobe": "Re-check",
    "close": "Close",
    "resultTitle": "Install result",
    "probeFailed": "Probe failed",
    "installIncomplete": "Install incomplete",
    "installedOne": "Installed {{name}}",
    "allInstalled": "Required software installed"
  },
  "softwareLifecycle": {
    "kindInstall": "Install",
    "kindUninstall": "Uninstall",
    "dockBusy": "{{kind}} · {{title}}",
    "dockFail": "Failed · {{title}}",
    "dockDone": "Done · {{title}}",
    "minimize": "Minimize",
    "maximize": "Maximize",
    "restore": "Restore",
    "liveLog": "Live log",
    "uninstall": "Uninstall…",
    "uninstallTitle": "Uninstall {{name}}",
    "impactIntro": "These components and services will be affected. Review carefully before continuing.",
    "nothingInstalled": "Nothing installed for this feature.",
    "packagesList": "Packages: {{list}}",
    "noPackages": "No apt packages listed",
    "unitsList": "Services: {{list}}",
    "dataPolicy": "Data policy",
    "policyKeep": "Keep config & data",
    "policyPurge": "Purge config & data (dangerous)",
    "purgeWarning": "Purge permanently deletes configuration and data directories. This cannot be undone easily.",
    "keepHint": "Packages will be removed; configuration and data directories are kept on disk.",
    "summaryLine": "{{packages}} package(s), {{units}} service unit(s) will be processed.",
    "doubleConfirmIntro": "Double confirmation is required for uninstall.",
    "ackLabel": "I understand services may stop and I have read the impact list.",
    "typePhrase": "Type {{phrase}} to confirm",
    "confirmUninstall": "Confirm uninstall",
    "protected": "Protected",
    "readyHint": "Required software is installed. You can uninstall from here if needed.",
    "readyTitle": "Software ready",
    "jobInProgress": "Another install/uninstall is already running",
    "uninstallDone": "Uninstall finished",
    "uninstallFailed": "Uninstall failed",
    "impact": {
      "sitesDown": "Public sites may go offline",
      "reverseProxy": "Reverse proxy will stop",
      "phpBackend": "PHP backend may stop",
      "mailOutbound": "Outbound mail will stop",
      "mailInbound": "Inbound mail will stop",
      "mailQueue": "Mail queue tools unavailable",
      "mailDkim": "DKIM signing will stop",
      "database": "Database service will stop",
      "dataLossPurge": "Purge deletes data directories",
      "cache": "Cache service will stop",
      "firewall": "Host firewall will be removed",
      "intrusion": "Intrusion blocking will stop",
      "ftp": "FTPS service will stop",
      "dns": "DNS server will stop",
      "vpn": "VPN services will stop",
      "vnc": "VNC services will stop",
      "controlPlane": "Control plane runtime (protected)",
      "generic": "Related services may stop",
      "containers": "Running containers will stop",
      "validators": "Validator node stacks that use Docker Compose will stop",
      "purgeData": "Data paths will be deleted",
      "protectedSkipped": "Protected components are skipped",
      "runtimeStack": "All panel-managed versions of this runtime will be removed"
    },
    "requestCancel": "Request cancel",
    "cancelling": "Cancelling…",
    "dockCancelling": "Cancelling · {{title}}",
    "dockCancelled": "Cancelled · {{title}}",
    "cancelHint": "Cancel requested. The client stopped listening; the host may finish the current apt/step. Re-probe status after a moment.",
    "cancelledToast": "Operation cancelled (client stopped streaming)",
    "kindApply": "Apply",
    "kindScan": "Scan",
    "kindDeploy": "Deploy",
    "kindRuntime": "Runtime",
    "jobDone": "Finished · {{title}}",
    "jobFailed": "Failed · {{title}}",
    "uninstallUfwWarn": "Removing UFW leaves this host without its panel-managed port firewall.",
    "uninstallFail2banWarn": "Removing fail2ban stops jails and releases current bans. Add your login IP to ignoreip first if you keep it."
  },
  "sqlEngineHealth": {
    "finding": {
      "package_missing": "Server package for {{flavor}} is not installed.",
      "client_missing": "SQL client tools are not installed.",
      "frozen_marker": "Debian freeze marker present (mode: {{mode}}). Daemon start is blocked until released.",
      "datadir_uninitialized": "Data directory has no system catalog — needs initialization.",
      "config_flavor_mismatch": "my.cnf points at the wrong engine for {{flavor}} ({{path}}).",
      "residual_foreign_plugins": "Residual config/plugins from the other SQL engine can crash this daemon.",
      "unit_failed": "Service unit {{unit}} is failed.",
      "unit_not_active": "Service unit {{unit}} is {{active}} (not active).",
      "port_conflict": "Port 3306 is in use while this engine is down (possible conflict)."
    },
    "action": {
      "stop_unit": "Stop service unit",
      "clear_frozen": "Clear freeze marker",
      "sanitize_config": "Align my.cnf and disable foreign engine plugins",
      "init_datadir": "Initialize empty data directory",
      "reset_failed": "Reset failed unit state",
      "enable_unit": "Enable service at boot",
      "start_unit": "Start service",
      "verify_active": "Verify service is active"
    },
    "note": {
      "alreadyHealthy": "SQL engine already healthy — no repair needed.",
      "needsConfirm": "Repair needs confirmation ({{count}} steps: {{findings}}).",
      "installPackageFirst": "Install {{flavor}} server package first, then repair.",
      "stepFailed": "Repair step {{action}} failed: {{detail}}",
      "repairOk": "Repair complete — {{unit}} is active.",
      "repairIncomplete": "Repair finished but unit is still {{active}}."
    }
  },
  "sqlEngineSwitch": {
    "title": "Switch to {{target}}",
    "subtitle": "Replace {{from}} with {{to}}. Only one SQL server is allowed on this host.",
    "confirm": "Confirm switch and migrate",
    "success": "SQL engine switched and data migrated",
    "bannerHint": "If the other engine is already installed, you must confirm an exclusive switch (uninstall",
    "flowAria": "SQL engine switch direction",
    "from": "Current",
    "to": "Target",
    "calloutTitle": "Hard to undo without backups",
    "calloutBody": "{{from}} packages are removed only after a successful export",
    "sectionImpact": "What will happen",
    "sectionLimits": "Limitations and risks",
    "dbListTitle": "Databases to migrate ({{count}})",
    "dbMigrateBadge": "{{count}} user database(s)",
    "dbEmptyBadge": "No user databases",
    "noUserDbs": "No user databases detected (system schemas only). The server engine will still be replaced.",
    "tableCount": "{{count}} table(s)",
    "ackLabel": "I understand the engines are exclusive. Uninstall {{from}} and migrate data to {{to}}.",
    "phraseLabel": "Type {{phrase}} to confirm",
    "phraseMismatch": "Phrase does not match. Type SWITCH exactly.",
    "warn": {
      "replace_engine": "Uninstall {{from}} and install {{to}}.",
      "exclusive": "MySQL and MariaDB cannot run together as servers on one host (exclusive).",
      "uninstall_packages": "Current SQL server packages will be removed from the system.",
      "logical_dump": "User databases are logical-exported then imported. System schemas are not copied as files.",
      "dialect_risk": "MariaDB- or MySQL-specific SQL may fail on import.",
      "no_replication": "Replication settings, plugins, and binary logs are not migrated.",
      "root_auth": "Root socket or password authentication may need reconfiguration after the switch.",
      "no_user_dbs": "No user databases detected — only engine packages will change.",
      "has_user_dbs": "{{count}} user database(s) will be exported and imported."
    },
    "note": {
      "needsSwitch": "This host already runs {{other}}. MySQL and MariaDB are exclusive — confirm switch (export → uninstall other → install → import).",
      "invalidTarget": "Invalid target (mysql or mariadb only).",
      "badConfirmPhrase": "Confirm phrase must be exactly SWITCH.",
      "needAck": "You must acknowledge exclusive switch (MySQL or MariaDB, not both).",
      "switchNotNeeded": "Switch not needed — use normal install.",
      "migrateDataRequired": "Data migration must be enabled when user databases exist.",
      "dumpFailed": "Export failed — source {{source}} left running. {{detail}}",
      "datadirBackupFailed": "Datadir backup failed — aborted before uninstall. Try starting the source service manually.",
      "waitFailed": "Target service did not become ready. Backup: {{dumpPath}}. Old datadir: {{datadir}}. Manual recovery required.",
      "incomplete": "Switch incomplete. Export retained at {{dumpPath}}. Old datadir at {{datadir}}. Do not purge again blindly.",
      "switched": "Switched {{from}} → {{to}}. Imported {{imported}}/{{total}} database(s).",
      "dumpPath": "Logical export path: {{path}}",
      "datadirBackup": "Old datadir backup: {{path}} (remove when satisfied: rm -rf {{path}})",
      "grantsExported": "Grants exported ({{detail}})",
      "frozenDetected": "MySQL/MariaDB is FROZEN (not an apt failure). Path {{path}} (mode: {{mode}}). The package may be installed but the daemon refuses to start after an engine switch or downgrade. Clear freeze and re-init empty datadir if safe. Snippet: {{snippet}}",
      "frozenCleared": "Removed freeze marker {{path}}.",
      "frozenClearFailed": "Could not remove freeze marker {{path}} — remove manually as root.",
      "datadirNotEmptySkipInit": "Data directory already has system tables — skipped re-initialize.",
      "datadirInitialized": "Initialized empty data directory for {{flavor}}.",
      "datadirInitFailed": "Failed to initialize data directory: {{detail}}",
      "unitNotActive": "Unit {{unit}} is {{active}} (expected active).",
      "nginxPortConflict": "Nginx unit not active — Apache may still bind public :80; rebind Apache to 127.0.0.1:8080, then restart Nginx.",
      "nginxConfigFailed": "nginx -t failed: {{detail}}",
      "frozenShort": "FROZEN ({{mode}}) — daemon blocked; unfreeze and repair required.",
      "unfreezeNeedsConfirm": "Confirm required to unfreeze (frozen={{frozen}}, emptyDatadir={{empty}}). POST with confirm:true.",
      "unfreezeOk": "Service {{unit}} is active after unfreeze repair.",
      "unfreezeStartFailed": "Still not active after unfreeze: {{detail}}",
      "unfreezePrompt": "Click “Unfreeze and repair” to clear FROZEN and re-init empty datadir.",
      "configSanitized": "SQL config aligned for {{flavor}} (my.cnf → {{target}}). MariaDB plugin remnants disabled when targeting MySQL.",
      "configSanitizeFailed": "Failed to sanitize SQL config: {{detail}}"
    },
    "step": {
      "dump": "Export {{db}}",
      "exportGrants": "Export grants",
      "stop": "Stop {{unit}}",
      "backupDatadir": "Backup datadir",
      "purge": "Uninstall {{pkg}}",
      "wait": "Wait for {{unit}}",
      "importDb": "Import {{db}}",
      "importGrants": "Import grants",
      "verify": "Verify",
      "preflight": "Preflight",
      "confirm": "Confirm",
      "clearFrozen": "Clear MySQL FROZEN",
      "initDatadir": "Initialize empty datadir",
      "startUnit": "Start {{unit}}",
      "sanitizeConfig": "Sanitize my.cnf / residual plugins"
    }
  },
  "ssl": {
    "status": {
      "uploaded": "Uploaded",
      "issued": "Issued",
      "planned": "In progress",
      "failed": "Failed",
      "missing": "Files missing",
      "ready": "Ready",
      "processing": "In progress"
    },
    "step": {
      "ok": "Done",
      "blocked": "Cannot run",
      "failed": "Failed",
      "skipped": "Skipped"
    },
    "pillCount": "{{count}} cert(s)",
    "statCerts": "Certificates",
    "panelCertHint": "Panel HTTPS uses {{path}} (expires {{exp}}). It is not listed as a site certificate.",
    "openPanelTls": "Open panel HTTPS",
    "statWithFiles": "With files",
    "statBindings": "Bindings",
    "statFailed": "Failed",
    "requestLe": "Request Let’s Encrypt",
    "openLetsEncryptLog": "Open letsencrypt.log in Log Center",
    "uploadCert": "+ Upload certificate",
    "certbotNotInstalled": "Certbot is not installed",
    "leFailNxdomain": "DNS has no record for {{domain}} (NXDOMAIN) — Let's Encrypt cannot validate without a public A/AAAA.",
    "leFailNxdomainHint": "Add an A record for {{domain}} to this server’s public IP in DNS, write the zone, confirm",
    "leFailDns": "DNS error resolving {{domain}} (SERVFAIL or similar).",
    "leFailDnsHint": "Check nameservers and that the zone is published to the public internet.",
    "leFailHttp01": "{{domain}} resolves, but HTTP-01 failed (port 80 unreachable or wrong response).",
    "leFailHttp01Hint": "Open port 80, ensure nginx listens on 80, and that {{domain}} points at this host",
    "leFailRateLimit": "Let's Encrypt rate limit hit.",
    "leFailRateLimitHint": "Wait and retry, or avoid repeated requests for the same name.",
    "leFailCaa": "CAA records block Let's Encrypt for {{domain}}.",
    "leFailCaaHint": "Add a CAA allowing letsencrypt.org, or remove the blocking CAA.",
    "leFailChallenge": "Let's Encrypt domain validation failed ({{domain}}).",
    "leFailChallengeHint": "Confirm DNS A record and port 80 reachability, then retry; see letsencrypt.log.",
    "leFailUnknown": "Let's Encrypt request failed ({{domain}}).",
    "leFailUnknownHint": "Open letsencrypt.log for details.",
    "leFailRawTail": "Technical detail (excerpt): {{snippet}}",
    "requestFailedWhy": "Why it failed",
    "requestFailedNext": "Next steps",
    "retryRequest": "Retry request",
    "retryRequestFor": "Retry request for {{domain}}",
    "retryInTableHint": "Retry from the failed domain row in the list below",
    "bindingsTitle": "Bindings & renewal",
    "autoRenewLabel": "Auto-renewal",
    "autoRenewYes": "Enabled",
    "autoRenewNo": "Not enabled / unconfirmed",
    "autoRenewYesDetail": "Renewal mechanism detected: {{source}}. Let's Encrypt certs should renew before expiry when certbot is healthy.",
    "autoRenewNoDetail": "No enabled certbot.timer or renew cron found. Enable certbot.timer or certs will expire unless you renew manually.",
    "renewSourceCron": "panel/system cron",
    "renewTimerEnabled": "systemd timer enabled: {{unit}}",
    "renewTimerDisabled": "Found {{unit}} but it is not enabled (systemctl enable --now {{unit}})",
    "renewTimerInstalledUnknown": "Host has {{unit}} unit file; confirm systemctl enable --now",
    "renewTimerActive": "{{unit}} is active",
    "renewViaCron": "Found {{count}} cron job(s) mentioning certbot/renew",
    "renewNone": "No certbot.timer or LE renew cron registered",
    "expiresUnknown": "Unknown",
    "expiresUnknownHint": "Certificate file unreadable (permissions/path);",
    "expiresInDays": "in {{n}} days",
    "expiresAt": " · Expires {{date}}",
    "projectsAt": " · Projects: {{names}}",
    "mailAt": " · Mail: {{domains}}",
    "noBindings": "No project/mail bindings detected",
    "certsTitle": "Certificates ({{count}})",
    "colDomain": "Domain",
    "colProvider": "Source",
    "providerUpload": "Upload",
    "colLocalFiles": "Local files",
    "filesYes": "Yes",
    "filesNo": "No",
    "colExpires": "Expires",
    "renew": "Renew",
    "renewFor": "Renew {{domain}}",
    "deleteDomain": "Delete {{domain}}",
    "colStatus": "Status",
    "emptyTitle": "No certificates yet",
    "emptyDesc": "Use “Upload certificate” or “Request Let’s Encrypt” above",
    "uploadTitle": "Upload certificate",
    "uploadDesc": "Paste PEM content; the panel writes files on the server",
    "domainHint": "Primary domain for this cert, e.g. example.com",
    "fullchainLabel": "Certificate chain (fullchain)",
    "fullchainHint": "PEM with server cert and intermediate CA",
    "privkeyLabel": "Private key (privkey)",
    "privkeyHint": "Private key PEM matching the certificate — keep it secret",
    "uploadHint": "Upload only writes files;",
    "leTitle": "Request Let’s Encrypt",
    "leDesc": "The panel requests the cert on the server — no manual certbot",
    "requestCert": "Request certificate",
    "domainLeHint": "Apex/domain or *.example.com wildcard",
    "domainLePlaceholder": "example.com or *.example.com",
    "emailLabel": "Contact email",
    "emailHint": "For Let’s Encrypt expiry notices; leave empty to use admin@domain",
    "leDns01Hint": "Wildcards use dns-01: the panel starts a certbot manual challenge — complete the TXT recor",
    "leHttp01Hint": "Normal domains use http-01 (nginx plugin)",
    "deleteTitle": "Delete certificate?",
    "deleteDesc": "Removes cert files and registration for {{domain}}.",
    "deleteNeedDomain": "Delete this certificate — type the domain name to confirm",
    "savedCert": "Saved certificate for {{domain}}",
    "uploadFailed": "Upload failed",
    "requestBlocked": "Cannot complete certificate request in the admin panel",
    "requestDone": "Certificate request completed",
    "requestFailed": "Certificate request did not succeed",
    "applyFailed": "Request failed",
    "deletedCert": "Deleted {{domain}}",
    "uninstallCertbotWarn": "Removing certbot stops automatic renewal of existing Let's Encrypt certificates.",
    "uninstallCertbot": "Uninstall certbot (loses auto-renew)",
    "domainRequired": "Please enter a domain.",
    "domainInvalid": "Domain format is not valid.",
    "domainKnownHint": "Pick a known project, DNS, or mail domain, or type a custom name."
  },
  "stackWizard": {
    "purgeConfirm": "Confirm purge? Registered data paths (databases/mail) will be deleted permanently.",
    "installedCount": "Packages installed {{installed}} · missing {{missing}}",
    "countHint": "These counts are OS packages in the software plan — not the service-matrix units on the other tab.",
    "executeRoot": "System changes {{execute}} · administrator {{root}}",
    "manifestPlan": "Plan {{plan}} ({{bundles}})",
    "manifestHint": "Last chosen software plan and bundles",
    "needRootExecute": "Live install/remove needs administrator rights and system-change permission. You can still dry-run.",
    "modeInstall": "Install plan",
    "modeUninstall": "Uninstall",
    "plan": "Plan",
    "customBundles": "Custom bundles",
    "sqlExclusive": "SQL server (exclusive)",
    "clamavOptional": "optional, large",
    "componentsTitle": "Components to install",
    "dryRun": "Dry-run preview",
    "installNow": "Install now",
    "uninstallHint": "Select bundles to remove",
    "dataPolicy": "Data policy",
    "keepData": "Keep data",
    "purgeData": "Purge data",
    "uninstallNow": "Uninstall now",
    "uninstallNeedSelect": "Select at least one bundle. Empty selection no longer means remove all.",
    "uninstallConfirmTitle": "Remove selected bundles?",
    "uninstallConfirmDesc": "{{count}} bundle(s) will be removed. Type REMOVE to confirm.",
    "bundle": {
      "control-plane": "Control plane",
      "web": "Web hosting",
      "database": "Databases",
      "email": "Mail stack",
      "dns": "DNS",
      "ftp": "FTP / FTPS",
      "defense": "Host defense",
      "runtimes": "Language runtimes"
    },
    "planTitle": {
      "minimal": "Control plane only",
      "recommended": "Recommended hosting",
      "full": "All software"
    }
  },
  "support": {
    "title": "Support",
    "sub": "Creator, donate, and YSK Limited — free product, real help",
    "creatorTitle": "Creator",
    "creatorBody": "YSK Server is built as a free, honest single-host control plane for operators who want to own their stack. The project is maintained in the open; feedback and bug reports keep it sharp.",
    "donateTitle": "Support / Donate",
    "donateBody": "If YSK Server saves you time, consider sponsoring development. Every contribution helps keep the product free for everyone.",
    "donateGithub": "GitHub Sponsors",
    "donateOther": "Other ways to give",
    "yskTitle": "YSK Limited",
    "yskIntro": "Need hands-on help beyond the free panel? YSK Limited can assist with:",
    "yskSvc1": "Server setup, hardening, and ongoing ops",
    "yskSvc2": "Hosting stack design (web, mail, DNS, databases)",
    "yskSvc3": "Migration, automation, and custom integration",
    "yskSvc4": "Incident response and production readiness reviews",
    "yskNoPrice": "No prices listed here — contact us for a conversation that fits your environment.",
    "yskWebsite": "ysk.hk",
    "helpTitle": "Having a problem?",
    "helpBody": "Email us with your OS, install log path, and what you expected vs what happened. We read every message.",
    "docsHint": "Full documentation lives in the repository under",
    "donateLinktree": "Linktree",
    "cryptoTitle": "Crypto / web3 handles",
    "cryptoHint": "Send on the matching network only. Double-check the address before sending.",
    "cryptoNetwork": "Network",
    "cryptoAddress": "Address",
    "copy": "Copy",
    "copied": "Copied",
    "copyTitle": "Copy {{address}}",
    "docsLink": "Documentation",
    "diagTitle": "Diagnostic summary",
    "diagBody": "Copy version, system-change, superuser, and host facts to paste into an email. This is not a full log bundle.",
    "diagCopy": "Copy diagnostic summary",
    "diagCopied": "Diagnostic summary copied",
    "diagCopyTitle": "Copy version, system-change, and host facts",
    "diagPreview": "Preview what will be copied",
    "diagLoading": "Loading diagnostic…",
    "diagLoadFailed": "Could not load diagnostic",
    "copiedAddr": "Copied {{addr}}",
    "diagStatus": "Status",
    "diagMode": "Mode",
    "diagProtection": "Protection",
    "diagHostname": "Hostname",
    "diagOs": "OS"
  },
  "system": {
    "exportLoadFailed": "Failed to load export data",
    "dryRunDone": "Dry-run complete (system unchanged)",
    "rebuildDone": "Rebuild request finished — see ops result",
    "exportWritten": "Export written / managed conf listed",
    "rebuildFailed": "Rebuild failed",
    "hostFallback": "Host",
    "mem": "Memory",
    "diskPeak": "Disk peak",
    "exportRebuild": "Export / Rebuild",
    "dnsCerts": "DNS / certs",
    "editIdentity": "Edit identity",
    "power": "Power",
    "metrics": "Metrics",
    "writeExports": "Write export directory",
    "dryRunSync": "Dry-run sync",
    "hostConsole": "Host console",
    "loadingHost": "Loading host overview…",
    "identity": "Identity",
    "identityReadonly": "Read-only — needs YSK_EXECUTE + root to apply",
    "identityTools": "Set hostname and timezone via system tools",
    "hostnameHint": "System hostname",
    "writable": "Writable",
    "locked": "Locked",
    "hostname": "Hostname",
    "prettyName": "Pretty name",
    "optional": "Optional",
    "prettyPh": "Friendly display name",
    "timezone": "Timezone",
    "timezoneHint": "IANA zone from timedatectl (e.g. Asia/Hong_Kong). This is the host clock — cron and vsftpd local time follow it. Stored timestamps stay UTC.",
    "timezoneNow": "Host time now: {{time}} ({{tz}})",
    "timezoneBrowserDiff": "This host uses {{host}}; your browser uses {{browser}}. Changing timezone here changes the host clock, not the browser.",
    "timezoneSelect": "Select timezone",
    "notExported": "Not exported yet",
    "dns": "DNS",
    "updated": "Updated",
    "applyIdentity": "Apply identity",
    "identitySetHostname": "Hostname set to {{name}}",
    "identitySetPretty": "Pretty hostname set to {{name}}",
    "identityClearPretty": "Pretty hostname cleared",
    "identitySetTimezone": "Timezone set to {{tz}}",
    "panelSsl": "Panel SSL",
    "panelTls": {
      "title": "Panel HTTPS",
      "sub": "Control plane (ysk-server) serves TLS on the configured port; WebAuthn/Passkeys need HTTPS",
      "domain": "Panel domain",
      "domainHint": "Used for certificate issue/bind, e.g. {{host}}",
      "email": "Let’s Encrypt email",
      "status": "Status",
      "enabled": "TLS enabled in config",
      "disabled": "TLS off (HTTP)",
      "serving": "This connection: HTTPS",
      "servingHttp": "This connection: HTTP",
      "expires": "Certificate expires",
      "certPath": "Certificate path",
      "issueEnable": "Issue cert & enable HTTPS",
      "enableExisting": "Enable with existing cert",
      "disable": "Disable panel HTTPS",
      "disableNeedConfirm": "Needs confirmation — type DISABLE-HTTPS",
      "needDomain": "Enter hostname / domain first",
      "needFqdn": "Need a FQDN (example.com), not a bare hostname",
      "urlHint": "After restart open {{url}}",
      "certMissing": "TLS enabled but cert/key files missing",
      "restartToApply": "Restart ysk-server to apply HTTPS",
      "noConfig": "config.json not found (start with --config)",
      "usingExisting": "Using existing local certificate",
      "usingLe": "Using Let’s Encrypt live paths",
      "needCertFirst": "No certificate for {{domain}}; issue or upload first",
      "configWritten": "Panel TLS settings written",
      "disabledNote": "Panel TLS disabled",
      "certAlreadyPresent": "Certificate already present; skipped re-issue",
      "restartManual": "Restart manually: systemctl restart ysk-server",
      "restarted": "ysk-server restarted",
      "restartFailed": "Restart failed: {{detail}}",
      "firewallHint": "If reaching from the internet, allow the panel port (default 9287/tcp)",
      "restartNow": "Restart ysk-server immediately after",
      "restartNowHint": "Drops this session;",
      "restartConfirm": "Restart the panel service now? This connection may drop — reopen over HTTPS.",
      "manualRestart": "Restart manually, then open {{url}}",
      "reconnectHttps": "Service may have restarted. Reconnect at {{url}}.",
      "leStrategies": "Panel cert: try webroot → nginx certonly → standalone (no --redirect)",
      "leOk": "Let’s Encrypt certificate obtained for {{domain}}",
      "leFailed": "Certificate request failed: {{detail}}",
      "leHint": "Ensure DNS A points here and port 80 is reachable (or nginx serves the domain)",
      "openFirewall": "If public: allow panel port {{port}}/tcp (Firewall → open port → 9287 Panel)",
      "disableConfirmTitle": "Disable panel HTTPS?",
      "disableConfirmDesc": "The panel will serve HTTP. WebAuthn / Passkey will stop working until HTTPS is on again.",
      "disablePasskeyWarn": "Registered passkeys need HTTPS — they will fail on HTTP.",
      "listenPublic": "Panel is listening on a public address (0.0.0.0/::). Restrict with a firewall or bind to 127.0.0.1.",
      "bootstrapCert": "This is the self-signed bootstrap certificate — browsers will warn. Issue a trusted certificate for the panel domain.",
      "cliNoSocket": "CLI has no live HTTP socket; servingHttps is inferred from config and listen sockets (ss).",
      "listenHost": "Listen address",
      "currentHost": "This session",
      "replaceCert": "Replace with a trusted certificate"
    },
    "timeNtp": "Time & NTP",
    "clockStatus": "System clock status",
    "local": "Local",
    "utc": "UTC",
    "source": "Source",
    "ntpService": "NTP service",
    "ntpServiceActive": "Running",
    "ntpServiceInactive": "Stopped",
    "ntpServiceNa": "N/A",
    "ntpSync": "Clock sync",
    "ntpSyncedYes": "Synchronized",
    "ntpSyncedNo": "Not synchronized",
    "ntpSyncedUnknown": "Unknown",
    "ntpRequested": "NTP sync enable requested",
    "ntpFailed": "Failed to enable NTP",
    "enableNtp": "Enable NTP sync",
    "network": "Network",
    "networkSub": "Read-only · full netplan is not on this page",
    "noIp": "Could not read IPs",
    "storage": "Storage",
    "metricsDetail": "Metrics detail",
    "noDisk": "Could not read disks",
    "avail": "Avail {{v}}",
    "shortcuts": "Ops shortcuts",
    "shortcutsAria": "Ops shortcuts",
    "scServices": "Service matrix",
    "scServicesD": "unit lifecycle",
    "scUnit": "Control-plane unit",
    "scUnitD": "Panel systemd unit",
    "scReadiness": "Readiness",
    "scReadinessD": "Production gate",
    "scUpdates": "System updates",
    "scUpdatesD": "Packages / CVE",
    "scMetrics": "Host metrics",
    "scMetricsD": "Load alerts",
    "scLogs": "Log center",
    "scLogsD": "journal / files",
    "powerTitle": "Power (danger zone)",
    "powerWarn": "Reboot/poweroff interrupts all services and the panel. The panel cannot power the host on — needs physical access or hypervisor.",
    "unlocked": "Unlocked",
    "powerUnlock": "Unlock danger zone",
    "powerLock": "Lock danger zone",
    "noScheduledPower": "No reboot or poweroff is scheduled",
    "powerCaps": "Needs YSK_EXECUTE=1 and root. Now EXECUTE={{exec}}, root={{root}}.",
    "scheduledPower": "Scheduled poweroff/reboot detected",
    "cancelScheduleHint": ". Use “Cancel schedule” to withdraw.",
    "rebootHost": "Reboot host…",
    "poweroffHost": "Power off…",
    "cancelled": "Cancelled",
    "cancelFailed": "Cancel failed",
    "cancelSchedule": "Cancel schedule",
    "confirmStrings": "Confirm with REBOOT / POWEROFF. Default delay ~1 min for poweroff and reboot (shutdown +N). Written to audit.",
    "confirmReboot": "Confirm host reboot?",
    "confirmPoweroff": "Confirm power off?",
    "confirmRebootDesc": "All services and panel sessions will drop. Type REBOOT to confirm.",
    "confirmPoweroffDesc": "Host will power off; panel cannot remote power-on. Type POWEROFF to confirm.",
    "typeToUnlock": "Type {{need}} to unlock",
    "confirmRebootBtn": "Confirm reboot",
    "confirmPoweroffBtn": "Confirm power off",
    "sentDisconnect": "Sent — connection will drop",
    "powerFailed": "Power action failed",
    "exportExplain": "Export = panel DB summary JSON. Rebuild = managed conf → /etc/nginx/conf.d + reload. Sync needs root + EXECUTE.",
    "controlSummary": "Control-plane summary",
    "controlSummarySub": "Live DB snapshot · preview / download / write to server",
    "snapshotLoaded": "Summary loaded · {{at}}",
    "previewSummary": "Preview summary",
    "downloadedJson": "JSON downloaded to browser",
    "downloadJson": "Download JSON",
    "snapshotMeta": "Generated {{at}} · users {{users}} · packages {{packages}}",
    "previewHint": "Click “Preview summary” to load the control-plane snapshot.",
    "managedNotEtc": "dataDir/nginx/conf.d — not the same as applied under /etc",
    "nFiles": "{{count}} files",
    "noManaged": "No managed conf yet",
    "noManagedDesc": "Appears after publishing project Nginx",
    "readFailed": "Read failed",
    "preview": "Preview",
    "previewModalDesc": "Managed conf content (dataDir)",
    "prevPage": "Previous",
    "nextPage": "Next",
    "pageOf": "Page {{page}} / {{total}} · {{count}} files",
    "managedPager": "Managed conf pages",
    "syncToSystem": "Sync to system",
    "syncSub": "Copy to /etc/nginx/conf.d and reload — needs root + EXECUTE",
    "syncReload": "Sync + reload",
    "syncReloadNeedConfirm": "Needs confirmation — writes /etc/nginx/conf.d and reloads Nginx",
    "exportOnly": "Export only + list conf",
    "dryRun": "Dry-run",
    "dryRunNote": "Dry-run does not change the system.",
    "exportHistory": "Server export history",
    "exportHistorySub": "dataDir/exports · authenticated download",
    "noExports": "No server export files yet",
    "noExportsDesc": "Click “Write export directory” to create",
    "downloaded": "Downloaded {{name}}",
    "download": "Download",
    "syncConfirmTitle": "Sync Nginx to system?",
    "syncConfirmDesc": "Sync managed Nginx conf to /etc/nginx/conf",
    "uptime": "Uptime",
    "load1m": "Load 1m",
    "executeLabel": "System change",
    "rootLabel": "Superuser",
    "managedLabel": "Managed",
    "managedCount": "Managed",
    "exportsCount": "Exports",
    "managedNginxTitle": "Managed Nginx",
    "exportPath": "Export path",
    "mode": "Mode",
    "managedConf": "Managed conf",
    "dryRunFlag": "Dry-run",
    "timezoneSearch": "Filter timezones…",
    "resyncNtp": "Re-sync NTP",
    "storageSub": "Disk usage",
    "nginxLeftover": "Leftover",
    "nginxUnused": "Unused",
    "nginxLeftoverHint": "Stale public-files or leftover conf. Still included in sync until you remove or replace it.",
    "nginxUnusedHint": "Stock / catch-all conf (000-default). Still included in sync until you act.",
    "nginxRemoveLeftover": "Remove leftover",
    "nginxRemoveLeftoverTitle": "Remove leftover nginx conf?",
    "nginxRemoveLeftoverDesc": "Deletes {{name}} from the panel inventory. The live /etc/nginx copy is removed only with YSK_EXECUTE + root. 000-default is not leftover and cannot be deleted here.",
    "needExecuteRoot": "Needs YSK_EXECUTE + root"
  },
  "systemd": {
    "enabled": "Enabled",
    "disabled": "Disabled",
    "notInstalled": "Not installed",
    "running": "Running",
    "notRunning": "Not running",
    "failed": "Failed",
    "activating": "Activating",
    "unitMissing": "Unit missing",
    "loadFailed": "Failed to load",
    "opFailed": "Operation failed",
    "installedEnabled": "Installed and tried to enable",
    "unitTemplateWritten": "Unit template written",
    "writeTemplate": "Write management-dir template",
    "writeTemplateDesc": "Creates ysk-server.service under dataDir/systemd (does not change /etc)",
    "templateExists": "Management template already exists",
    "installEnable": "Install to /etc/systemd and enable",
    "installEnableDesc": "Copy unit → daemon-reload → enable --now",
    "needExecuteRoot": "Needs YSK_EXECUTE and root",
    "serviceNotRunning": "Service not running",
    "serviceNotRunningHint": "Unit may be installed but inactive — try Install & enable or the services matrix",
    "controlRunning": "Control-plane service running",
    "unlockApply": "Unlock system apply capability",
    "startAsRoot": "Start as root with YSK_EXECUTE=1",
    "status": "Status",
    "bootEnabled": "Start on boot",
    "on": "On",
    "off": "Off",
    "yes": "Yes",
    "no": "No",
    "canInstall": "Installable",
    "copyEnable": "Copy to /etc/systemd and enable --now",
    "needExecuteRootShort": "Needs EXECUTE + root",
    "probing": "Probing systemd status…",
    "suggestedSteps": "Suggested steps",
    "install": "Install",
    "policy": "Policy",
    "about": "About",
    "exists": "Exists",
    "missing": "Missing",
    "notWritten": "Not written yet",
    "related": "Related",
    "opsResult": "Ops result",
    "writeTemplateOnly": "Write template only",
    "installAndEnable": "Install and enable",
    "stepReport": "Step report",
    "installEnableShort": "Install enable",
    "cannotInstall": "Cannot install to system yet: needs ",
    "andRoot": " and root. Write template still creates management files. See ",
    "probeDetail": "Probe detail",
    "probeDetailSub": "Live systemd state and unit files on disk",
    "unit": "Unit",
    "manageTemplate": "Management template",
    "installOps": "Install actions",
    "twoModes": "Two modes for different needs — pick by environment",
    "writeOnlyTitle": "Write template only",
    "writeOnlyBody": "Creates management-dir unit file. Good for review or prep without root.",
    "willNotEnable": "Does not enable the service.",
    "writeTemplateBtn": "Write template",
    "installEnableTitle": "Install and enable",
    "installEnableBody": "Copy to /etc/systemd/system, daemon-reload, enable --now. Needs root + EXECUTE.",
    "policyWrite": "Write template only — dataDir only, not /etc",
    "policyInstall": "Install and enable — cp + daemon-reload + enable",
    "policyBlocked": "No EXECUTE or non-root → clearly blocked, no fake success",
    "policyNotEqual": "Write template ≠ service enabled ≠ listening",
    "shortcutPower": "EXECUTE / power",
    "shortcutOther": "Other units",
    "cannotInstallFull": "Cannot install to system yet: needs YSK_EXECUTE=1 and root. Write template still creates management files. See ",
    "policyWriteFull": "Write template only — dataDir only, not /etc",
    "policyNotEqualFull": "Write template ≠ service enabled ≠ listening",
    "controlPlaneUnit": "Control-plane unit",
    "kpiRuntime": "Runtime",
    "rawStateHint": "Raw unit state in tooltip",
    "bootHint": "Whether the unit starts at boot",
    "kpiBoot": "Boot enable",
    "kpiCaps": "Apply capability",
    "capsReady": "Can install to system",
    "capsBlocked": "Cannot apply",
    "unitFiles": "Unit files",
    "unitFilesSub": "System path vs panel-managed template (different roles)",
    "systemUnitFile": "System unit (/etc)",
    "systemUnitHint": "Unit systemd loads; appears after install & enable.",
    "managedUnitFile": "Managed template (dataDir)",
    "managedUnitHint": "Panel-written template — not the same as installed in /etc.",
    "managedPathHint": "dataDir/systemd/ysk-server.service",
    "fragmentPath": "Fragment path",
    "fromSystemd": "From systemd",
    "pid": "PID {{pid}}",
    "nextAction": "Suggested next step",
    "controlRunningHint": "systemctl is-active = active",
    "aboutPolicyTitle": "Apply policy",
    "aboutPolicySub": "Template write and system install are separate steps. Re-running after install is normal ops, not a missing step.",
    "policyInstallFull": "Install & enable: copy to /etc/systemd/system, daemon-reload, enable --now. Needs root + EXECUTE.",
    "policyBlockedTitle": "Blocked without privilege",
    "policyNotEqualTitle": "States are not equivalent"
  },
  "tabs": {
    "scrollLeft": "Scroll tabs left",
    "scrollRight": "Scroll tabs right",
    "about": "About",
    "main": "Actions",
    "stack": "Software",
    "unknown": "No such tab",
    "unknownHint": "This page has no tab named {{tab}}."
  },
  "terminal": {
    "tabSession": "Session",
    "target": "Login as",
    "connect": "Connect",
    "disconnect": "Disconnect",
    "user": "User",
    "size": "Size",
    "stateConnected": "Connected",
    "stateConnecting": "Connecting",
    "stateIdle": "Idle",
    "connecting": "Opening session…",
    "connectedAs": "Logged in as {{user}}",
    "disconnected": "Disconnected",
    "error": "Terminal error",
    "wsError": "WebSocket failed",
    "exitCode": "Exit code {{code}}",
    "needRootExecute": "System shells need superuser and system-change permission.",
    "groupSystem": "System",
    "groupProject": "Project",
    "unavailable": "unavailable",
    "copyAll": "Copy all",
    "copyAllNeedConn": "Connect first — the buffer is empty while disconnected",
    "placeholder": "Pick an identity, then Connect",
    "aboutTitle": "About terminal",
    "aboutSub": "Interactive OS shell in the browser (local users). Not an arbitrary remote SSH client.",
    "aboutWhat": "What it is",
    "aboutWhatBody": "Real PTY login shell (bash -l). Project users via runuser; root via root shell.",
    "aboutReq": "Requirements",
    "aboutReqBody": "Control plane must run as root with YSK_EXECUTE enabled.",
    "aboutUsers": "Identities",
    "aboutUsersBody": "Root, or OS-provisioned project Linux users.",
    "stepUpRequired": "Root shell needs a TOTP / recovery code",
    "stepUpHint": "Root login requires 2FA step-up when your account has TOTP enabled.",
    "stepUpTitle": "Confirm root shell",
    "stepUpDesc": "Enter your authenticator code or a recovery code.",
    "totpLabel": "TOTP / recovery code",
    "sessionStillOpen": "A live shell is still connected while you read this page.",
    "rootConfirmTitle": "Open a root shell?",
    "rootConfirmDesc": "This session is an unrestricted root PTY on the host. Commands are audited.",
    "rootConfirmBody": "Only continue if you intend to run privileged host commands."
  },
  "uiInline": {
    "s27d9daa5": "runtime {{v0}} {{v1}}，",
    "sb8eaefa3": "runtime {{v0}}，",
    "s7d540128": " · {{v0}}",
    "s814bcc7c": " · {{v0}}",
    "s3f7c3eae": "Update",
    "s92e48065": "Skip",
    "sdff0f697": "Watch",
    "s012f2d7e": "Update",
    "s20455064": "…",
    "s9b34f8c3": "…",
    "s8e3824cb": "Update 0/{{v0}}：…",
    "sc2570ff7": "Update {{v0}}/{{v1}}：{{v2}}",
    "s0bd0c471": "： {{v0}}，Failed {{v1}}",
    "s2980553a": "…",
    "s303ee0f7": "Cancel…（）",
    "s21858fe5": "Cancel",
    "sddc05404": "Close",
    "saf251c2a": "Update（）",
    "s5929623c": "…",
    "s18b08919": "…",
    "se2b088fc": "Update ({{v0}})",
    "sb2848bc7": "Update？",
    "sc1910cf2": "{{v0}} 。 root EXECUTE。",
    "sc13bb38c": "／；。",
    "sea4ba90a": "Loaded",
    "sdd78429a": "Written",
    "s9b6c1b03": "About",
    "s858f4eca": "…",
    "s090aa1a7": "Manage。 Nginx Projects → → 。",
    "sac96ec39": "Panel recorded install {{v0}}, but the host probe found no binary. Not installed — re-probe or reinstall.",
    "sf7f7807b": "Default",
    "sc9530028": "Latest，",
    "s9602769e": "Installed {{v0}} · upstream latest {{v1}}",
    "sb8b5a353": "Go／Rust ：「Install」，「Default」 PATH 。",
    "sac155c20": "Removable non-core extensions (apt remove; keeps FPM/CLI)",
    "s23379974": "「Install」。， runtime。",
    "s7b6d4414": "Not installed PHP {{v0}}：「Install PHP {{v0}}」+（Install）。",
    "s2e9a1b03": "Install PHP {{v0}}（）",
    "s62b73dd7": "…",
    "se23513e5": "PHP ？",
    "sf8c8ff4b": "Will apt remove \"{{v0}}\". Core FPM/CLI will not be removed.",
    "s7aa09150": "Installed",
    "sbcbdbc49": "Not installed",
    "sae7738d0": "Running",
    "sf3af7c5e": "Not detected",
    "sa1d77833": "Failed",
    "s75dddf52": "Stopped",
    "s4e7f6152": "Update… {{v0}}/{{v1}}：{{v2}}",
    "s72cac69e": "{{v0}}: {{v1}}",
    "sd1c15b6d": "{{v0}}: {{v1}}",
    "s7a90f74c": "Update：{{v0}}",
    "s0aa24093": "{{v0}} Update",
    "s5d92ffc3": "：{{v0}}；Failed：{{v1}}",
    "sa15a291f": "UpdateFailed",
    "sbb823c06": "Failed",
    "s68db1348": "{{v0}} UpdateFailed",
    "s84a4e7c6": "Install：{{v0}}…",
    "s2ca8a4f5": "root + EXECUTE；。",
    "sd9419dc9": "Install（ root+EXECUTE）",
    "s3ec3d449": "{{v0}} Install",
    "sbb8dfdeb": "Install：{{v0}}",
    "s18bb4b62": "{{v0}} Install／",
    "se9a47def": "Install",
    "sdc0528a2": "{{v0}} InstallFailed",
    "s69e60fb5": "No update target",
    "s3f50fa6e": "Install／Update {{v0}} {{v1}}…（）",
    "s1f5eef17": "Show server ，Close。",
    "s2bf6b642": "Update（ root YSK_EXECUTE=1）",
    "s9b4a58e8": "{{v0}} {{v1}} Install",
    "s6dc82720": "Installed／Update {{v0}} {{v1}}",
    "s94a1f025": "。Show，。",
    "s73cae5a0": "{{v0}} {{v1}} InstallFailed",
    "se1050a28": "Overview",
    "s8c29cb38": "…",
    "s583f0654": "…",
    "s4344c486": "…",
    "sed2550e1": "…",
    "scb435db5": "Service",
    "s97bbc1b7": "…",
    "s60a23151": "Manage：Install、Service、；Manage。",
    "s5387b55b": "…",
    "s0b582c70": "…",
    "s4be2a3a4": "Installed",
    "s259e6f0e": "／",
    "s13b3f970": "Needs attention",
    "sdd33adf9": "…",
    "sdfaaf946": "；Update。",
    "s78f03e20": "{{v0}}",
    "sbf368054": "{{v0}}",
    "s235a7426": "Update",
    "s14249f75": "Quick",
    "saff76d0a": "Service",
    "s24f12f4f": "Update／Install",
    "s43a9fd7a": "：Upstream／；Service：。Update。",
    "sc45743bd": "…",
    "s00338fde": "Update？",
    "s0e05f4b7": "Update",
    "s4d0b4688": "Cancel",
    "s92b8bf67": "Install？",
    "s9af27043": "Install {{v0}}：{{v1}}。 root YSK_EXECUTE=1。",
    "s28263d85": "Install",
    "s2e37cbfa": "Installed：{{v0}}",
    "s7d52bb0c": "Default {{v0}}",
    "s9f898b85": "Upstream {{v0}}",
    "s93dde991": "{{v0}} → {{v1}}",
    "s9071dcb7": "Installed {{v0}} · repo is latest",
    "s0b09f444": "{{v0}}",
    "sf6cc774f": "Not installed（ManageInstall）",
    "s42f9c88b": "{{v0}}",
    "sb72e8ebc": "Checking versions… or open manage page",
    "sabac942e": "Open manage page to install or configure",
    "sbd26894e": "Update available",
    "s5985ee9a": "Up to date",
    "s090e6a43": "Pick version",
    "s8253535d": "Install／Update {{v0}}",
    "s1723f1d7": "Install……",
    "sd9db02d0": "Update",
    "sba60558e": "Update {{v0}}",
    "s706de938": "Update {{v0}}",
    "s0f9ddc70": "Install {{v0}}",
    "sef864639": "Install",
    "s59f613d5": "Install／ {{v0}}",
    "s78b1688f": "Update {{v0}}",
    "s4989b5cf": "Manage",
    "s72203f17": "Service",
    "s75817a35": "， runtime",
    "s6d449473": "…",
    "s777e90e0": "Manage",
    "sd8bc8ab3": "Name：{{name}}",
    "s09877be5": "Manage",
    "sd95910ce": "…",
    "sa72ef18d": "Tools",
    "s4b2bec80": "Name",
    "sd00c0d39": "PHP ；Name",
    "sd7c669ac": "phpMyAdmin（）",
    "s9e5d3a97": "： {{v0}}，Failed {{v1}}",
    "s1f0a4bf9": "Cancel（）",
    "s7193f51b": "： {{v0}}，Failed 0",
    "sd93b8620": "{{v0}} Tools",
    "sd0ef129c": "({{v0}})",
    "se6d47d0b": "Tools",
    "se6436711": "InstallTools ({{v0}})",
    "s1a27a3c4": "Tools「Install runtime」Install（Install）。",
    "s32add03e": "{{v0}} Tools。",
    "s3bca33b2": "Tools",
    "s8072fa0d": "{{v0}} Install（Default）",
    "s2bf2b4c4": "InstallDefault。「Default」；Install。",
    "s42f3d613": "Default {{v0}}",
    "sdcdc5029": "Go-live incomplete",
    "s55cc91e0": "Nginx Publish，。",
    "s303f6113": "Retry deploy",
    "s3265f9ed": "Publish Nginx",
    "s99cc48c1": "{{v0}} ；「— —」。",
    "sa87ceeff": "Publish Nginx",
    "s38a63bcb": "Fixed port（）",
    "s5ac95c29": "Not published",
    "sc8f34a0d": "Written（ reload）",
    "s07fb5671": "Deploy first",
    "sa5f994e3": "Publish failed",
    "s32dd17d9": "SSL 。「SSL 」／，Publish + SSL。",
    "s5516cb5b": "Site status",
    "sed38f4ea": "Upstream",
    "sadb6ef47": "Process port",
    "se7a422dd": "Fixed port",
    "s2eff57b7": "Process port",
    "s110671e6": "Current port",
    "s549ea65e": "Publish",
    "s9dc5c003": "Basic",
    "s04a32a1e": "SSL ：",
    "s564d50b7": "／Publish + SSL。",
    "sbb6c72f1": " ({{v0}})",
    "sd9b695a5": "，Publish Nginx / SSL。",
    "scb85cfff": "SSL",
    "s18c1af46": "Publish + SSL",
    "s6a284cb0": "Publish Nginx + SSL",
    "s85483ffb": "Maintenance",
    "s6993c6ba": "Hide",
    "s15671929": "Show",
    "s56f99a6b": "Permanently delete project",
    "sa0f2f5c6": "「{{v0}}」。。",
    "sa6710b42": "Delete permanently",
    "s06569331": "systemd / PM2 /",
    "sd20a5b0c": "Nginx conf、PHP-FPM pool、Apache vhost（）",
    "s4ff53acc": "Linux home （）",
    "s50dda2df": "home Linux （）",
    "sa7f90a4a": "…",
    "se0d24557": "Name",
    "s9a9e4e32": "home Linux",
    "s1cf2a97b": "Cancel，",
    "s51af87fd": "Name",
    "s8b04d62f": "「{{v0}}」",
    "s49d55c8f": "DNS zone / domain 。",
    "s239f6551": "：{{v0}}",
    "sa00380bd": "：{{v0}}",
    "sb4e3bb0b": "Install",
    "sae926193": "…",
    "s52573ef8": "Update（ root+EXECUTE）",
    "s872d2fe0": "{{v0}} Update",
    "s6a93c0ec": "Loading versions…",
    "s378e49b6": "Installed",
    "s7e805a12": "Latest",
    "s74b39712": "Up to date / repo latest",
    "s03a87d5d": "Recheck latest",
    "s53c07a48": "Update {{v0}}",
    "s425e8381": "Install {{v0}}",
    "s5bd1242f": "{{v0}}：{{v1}} → {{v2}}。 root EXECUTE。",
    "s296817b1": "Install（）",
    "s3568a3da": "…",
    "s28256229": "Finished",
    "s3971290f": "server …"
  },
  "updates": {
    "title": "Intelligent updates",
    "body": "",
    "risk": {
      "critical": "Critical",
      "high": "High",
      "medium": "Medium",
      "low": "Low"
    },
    "justNow": "Just now",
    "secAgo": "{{n}}s ago",
    "minAgo": "{{n}}m ago",
    "hourAgo": "{{n}}h ago",
    "highRiskN": "{{count}} high-risk",
    "panelUpdate": "Panel update available",
    "footerNewVersion": "New version {{version}}",
    "riskOk": "Risk manageable",
    "riskUnevaluated": "Not evaluated — run Scan + OSV",
    "pendingScan": "Awaiting scan",
    "packages": "Packages",
    "highRisk": "High risk",
    "needApproval": "Needs approval",
    "hasCve": "Has CVE",
    "panel": "Panel",
    "schedule": "Schedule",
    "reload": "Reload",
    "osvTitle": "Query OSV for top 12 suggested packages (needs network)",
    "scanOsv": "Scan + OSV",
    "cveNotChecked": "Not checked",
    "scanPkgs": "Scan packages",
    "tabInventory": "Package inventory",
    "tabSelf": "Panel self",
    "badgeUpdate": "Update",
    "tabSchedule": "Schedule",
    "tabPolicy": "Policy",
    "scanning": "Scanning…",
    "inventoryTitle": "Package inventory",
    "inventoryDesc": "Showing {{shown}} / {{total}} · inventoried {{when}}",
    "riskFilterAria": "Risk filter",
    "all": "All",
    "upgradable": "Upgradable",
    "mediumFilter": "Medium",
    "lowUnmarked": "Low / unmarked",
    "searchPh": "Package / advice / CVE…",
    "searchAria": "Search packages",
    "colPackage": "Package",
    "colVersion": "Version (installed → apt Candidate)",
    "installedTitle": "Installed",
    "noUpgrade": "(no upgrade available)",
    "colAdvice": "Advice",
    "upgradeTo": "Upgrade to {{v}}",
    "sameVersion": "apt Candidate matches installed version",
    "noNeedUpgrade": "No upgrade needed",
    "emptyInventory": "No package data yet",
    "emptyInventoryDesc": "Use “Scan packages” in the page header to inventory this host",
    "emptyFilter": "No packages match filters",
    "emptyFilterDesc": "Change risk filters or clear search",
    "resetFilters": "Reset filters",
    "selfLoading": "Loading self-update status…",
    "selfTitle": "Panel self-update",
    "selfCheckFailed": "Check failed",
    "selfUpToDate": "Up to date",
    "selfAvailable": "Update available",
    "selfCurrent": "Current version",
    "selfLatest": "Latest version",
    "selfChannel": "Channel",
    "checkSelf": "Check for updates",
    "applySelf": "Apply self-update",
    "scheduleTitle": "Auto-scan schedule",
    "scheduleDesc": "Periodic inventory; does not auto-upgrade",
    "enabled": "Enabled",
    "disabled": "Disabled",
    "cron": "Cron expression",
    "saveSchedule": "Save schedule",
    "policyTitle": "Update policy",
    "policyBody": "High-risk and CVE packages require approval before apply",
    "applyPkg": "Apply package upgrade",
    "rebootNeeded": "reboot",
    "kernelRebootHint": "Kernel packages need a reboot after apply",
    "applyPkgConfirm": "Upgrade {{name}}?",
    "applyPkgDesc": "Runs apt upgrade for this package on the host. Needs root + YSK_EXECUTE.",
    "lastScan": "Last scan",
    "never": "Never",
    "cve": "CVE",
    "riskCol": "Risk",
    "selfUpdatable": "Updatable",
    "selfCurrentShort": "Current",
    "selfLatestShort": "Latest",
    "applyPanelUpdate": "Apply panel update",
    "applySelfConfirmTitle": "Apply panel update?",
    "applySelfConfirmDesc": "Install {{from}} → {{to}} and restart the panel service. There is no dry-run.",
    "applyPanelAlreadyLatest": "Already the latest panel version",
    "recheck": "Recheck",
    "aboutScope": "Scope",
    "aboutScopeV": "ysk-server panel + catalog services + runtimes + remaining apt packages",
    "aboutChannel": "Channel",
    "aboutChannelV": "npm package ysk-server → GitHub release → apps/server/package.json; apply: npm i -g ysk-server@version or git (YSK_SOURCE_ROOT)",
    "aboutFail": "Failures",
    "aboutFailV": "Unavailable channels are not reported as up-to-date; apply needs EXECUTE; git apply needs service restart",
    "jobsTitle": "Scheduled jobs",
    "jobsSub": "Control-plane scheduler (read-only) · {{count}}",
    "noJobs": "No visible schedules",
    "noJobsDesc": "Disabled or no scheduler jobs yet",
    "lastRun": "last {{when}}",
    "scanPolicy": "Scan",
    "scanPolicyV": "Scan ≠ upgraded; apply changes the system",
    "highRiskPolicy": "High risk",
    "highRiskPolicyV": "Needs approval: the Apply button opens a confirm dialog before anything is sent",
    "needApprovalHint": "Open Available and filter to packages that need approval",
    "applyNeedConfirm": "Opens a confirm dialog before applying",
    "probeFailed": "Probe failed",
    "notViaApt": "Not managed by apt — no candidate",
    "noCandidate": "No candidate from package manager",
    "cveLabel": "CVE",
    "jobOpenGeo": "GeoIP page",
    "job": {
      "protection_probe": {
        "name": "Protection probe",
        "hint": "Periodic defense signals"
      },
      "updates_scan": {
        "name": "Updates scan",
        "hint": "Refresh package inventory"
      },
      "daily_backup": {
        "name": "Daily backup",
        "hint": "Scheduled backup all"
      },
      "db_temp_expire": {
        "name": "Expire temp DB users",
        "hint": "Drop expired temporary database users"
      },
      "defense_auto_ban": {
        "name": "Defense auto-ban",
        "hint": "Apply auto-ban tick"
      },
      "defense_geoip_update": {
        "name": "GeoIP update",
        "hint": "Download GeoIP databases"
      },
      "log_auto_vacuum": {
        "name": "Log vacuum",
        "hint": "journald retention"
      },
      "email_dnsbl": {
        "name": "Email DNSBL",
        "hint": "Mail DNSBL check"
      },
      "validators_upgrade_scan": {
        "name": "Validators upgrade scan",
        "hint": "Check validator image / binary updates"
      }
    },
    "permPolicy": "Permissions",
    "permPolicyV": "Without EXECUTE/root → blocked (no fake success)",
    "osvPolicyV": "Needs network; enriches top 12 suggestions only",
    "relatedAria": "Related",
    "scHost": "Host settings",
    "scReadiness": "Readiness",
    "scReadinessD": "Production gate",
    "scSystemd": "systemd unit",
    "scSystemdD": "Control-plane service",
    "scSecurity": "Security center",
    "scSecurityD": "Approval / tools",
    "applyHighRisk": "Apply high-risk update {{name}}?",
    "highRiskUpdate": "High-risk update",
    "remoteUnknown": "Remote unknown",
    "hasUpdate": "Update available",
    "scanned": "Scanned {{count}} package(s)",
    "scannedWithOsv": "Scanned {{count}} package(s) (with OSV)",
    "realUpgradeable": "{{count}} truly upgradable",
    "panelCheckFailed": "Panel version check failed",
    "applyIncomplete": "Apply incomplete",
    "appliedPackage": "Package update applied",
    "updateFailed": "Update failed",
    "updateIncomplete": "Update incomplete",
    "appliedUpdate": "Update applied",
    "panelRestarting": "Panel is restarting to load the new version…",
    "panelRestarted": "Panel is back · {{version}}",
    "panelRestartWait": "Panel apply finished. If this page does not refresh, reload after a few seconds.",
    "reloadUi": "Reload UI",
    "reloadUiTitle": "Reload the panel UI?",
    "reloadUiDesc": "The panel service is {{version}}. This tab still has the previous frontend until you reload. Unsaved fields on this page will be lost.",
    "aptCandidate": "apt Candidate",
    "advice": {
      "update": "Update recommended",
      "skip": "Skip",
      "watch": "Watch",
      "urgent": "Urgent update"
    },
    "selectCol": "Select",
    "selectAllUpgradable": "Select all upgradable",
    "clearSelection": "Clear selection",
    "updateSelected": "Update selected ({{n}})",
    "batchConfirmTitle": "Confirm bulk package update?",
    "batchConfirmBody": "Will upgrade {{n}} package(s) in order. Requires root and EXECUTE.",
    "batchConfirmHighRisk": "Selection includes high-risk / approval packages; I have reviewed and approve apply.",
    "batchProgress": "Bulk update {{n}}/{{total}}: {{pkg}}",
    "batchDone": "Bulk done: {{ok}} ok, {{fail}} failed",
    "batchPartialFail": "Some failed: {{list}}",
    "batchEmpty": "Select upgradable packages first",
    "batchNoneUpgradable": "No upgradable packages in current filter",
    "batchCancel": "Cancel bulk",
    "batchCancelling": "Cancelling… (stops after current package)",
    "batchCancelled": "Cancelled (remaining skipped)",
    "batchRescanned": "Host package state re-scanned",
    "applyLogTitle": "Update（）",
    "navBadgeTitle": "Updates pending: {{n}}",
    "aboutPolicySub": "Scan, apply, privilege, and OSV boundaries. Scan is not the same as upgraded.",
    "tabOverview": "Overview",
    "overviewHint": "Server scans packages on a schedule. Install software on each feature page; this page only checks and applies upgrades.",
    "overviewStale": "Scan data is outdated. Run a scan or wait for the next automatic check.",
    "nextScan": "Next scan",
    "autoScan": "Auto scan",
    "autoScanEnable": "Enable automatic package scan",
    "scanInterval": "Scan interval",
    "interval6h": "Every 6 hours",
    "interval12h": "Every 12 hours",
    "interval24h": "Every 24 hours",
    "interval48h": "Every 48 hours",
    "scheduleSaved": "Scan schedule saved",
    "scanNow": "Scan now",
    "viewUpgradable": "View upgradable",
    "installElsewhere": "To install packages (Nginx, PHP, databases…), open the matching feature page — not this hub.",
    "status": "Status",
    "groupService": "Services",
    "groupRuntime": "Runtimes",
    "groupOs": "System packages",
    "notInstalled": "Not installed",
    "goToPage": "Open page",
    "hubHint": "Catalog software and runtimes on this host. Scan to refresh.",
    "intervalDay": "every day",
    "intervalDays": "every {{n}} days",
    "intervalHour": "every hour",
    "intervalHours": "every {{n}} hours",
    "intervalMinutes": "every {{n}} minutes",
    "intervalSeconds": "every {{n}} seconds",
    "availableHint": "Packages with a newer candidate from the package manager.",
    "servicesHint": "Catalog services on this host. Open the service page to install.",
    "runtimeHint": "Runtimes on this host. Version upgrades are done on each runtime page.",
    "needsReboot": "Reboot needed",
    "kernelRebootWarn": "Installing a new kernel usually needs a reboot before it is used.",
    "neverRun": "not run yet",
    "scanOsvN": "Scan + OSV (first {{n}})"
  },
  "users": {
    "userCount": "{{count}} users",
    "users": "Users",
    "packages": "Packages",
    "suspended": "Suspended",
    "securityCenter": "Security center",
    "singleAdminNo2fa": "This host has a single admin and 2FA is off. Enable admin 2FA under Security, then add a backup admin on this page.",
    "enableAdmin2fa": "Enable admin 2FA",
    "addBackupAdmin": "Add a backup admin",
    "loading": "Loading users & packages…",
    "userList": "Users ({{count}})",
    "userListDesc": "Open detail to edit role, password, package, overrides",
    "createUser": "Create user",
    "operatorHighRiskHint": "The factory operator role includes high-risk writes (services, firewall, package apply, MySQL, Nginx publish). Narrow it only if you intend to change every existing operator.",
    "createUserPlus": "+ Create user",
    "searchPh": "Username / role / package",
    "searchPkgPh": "Package name",
    "searchUsersAria": "Search users",
    "user": "User",
    "roles": "Roles",
    "package": "Package",
    "packageAria": "{{name}} package",
    "noneOption": "— none —",
    "resume": "Resume",
    "suspend": "Suspend",
    "impersonate": "Impersonate",
    "impersonateHint": "Opens a session as this user. Use the account menu to leave impersonation.",
    "cannotDeleteSelf": "You cannot delete the signed-in account",
    "cannotImpersonateSelf": "You are already signed in as this account",
    "openDetail": "Details",
    "edit": "Edit",
    "resetPassword": "Reset password",
    "newPassword": "New password",
    "saveUser": "Save user",
    "userSaved": "Updated {{name}}",
    "filterAll": "All",
    "filterAdmin": "Admin",
    "filterOperator": "Operator",
    "filterViewer": "Viewer",
    "filterSuspended": "Suspended",
    "filterNoPkg": "No package",
    "filter2faOff": "2FA off",
    "filterOverrides": "Has overrides",
    "subscribers": "Subscribers",
    "subscribersN": "{{count}} users",
    "ftp": "FTP",
    "ssh": "SSH",
    "databases": "Databases",
    "bandwidth": "Bandwidth MiB",
    "notes": "Notes",
    "editPkg": "Edit package",
    "pkgUpdated": "Updated package {{name}}",
    "pkgList": "Packages ({{count}})",
    "pkgListDesc": "Edit quotas; delete blocked while subscribers remain",
    "createPkg": "Create package",
    "createPkgPlus": "+ Create package",
    "mailboxes": "Mailboxes",
    "diskMiB": "Disk MiB",
    "noPackages": "No packages yet",
    "noPackagesHint": "Create a plan from the toolbar, then bind it to users.",
    "createUserDesc": "Password min 8 chars; edit role and permissions in detail later",
    "username": "Username",
    "passwordHint": "At least 8 characters",
    "role": "Role",
    "roleAria": "User role",
    "createPkgDesc": "Quota template; bind to users later",
    "maxProjects": "Max projects",
    "diskQuota": "Disk MiB",
    "custom": "Custom",
    "createdUser": "Created user {{name}}",
    "createdPkg": "Created package {{name}}",
    "impersonateTitle": "Impersonate {{name}}?",
    "deleteUserTitle": "Delete {{name}}?",
    "deletePkgTitle": "Delete package {{name}}?",
    "impersonateDesc": "Your current session will be replaced (~2 hours).",
    "deleteUserDesc": "This cannot be undone.",
    "deletePkgDesc": "Delete is refused while users still use this package.",
    "lastSeen": "Last seen",
    "neverSeen": "Never",
    "hostUsage": "Host usage",
    "hostUsageHint": "Machine-wide (host) totals, not hard per-user isolation",
    "hostTotalsBadge": "host totals",
    "opsChecklist": "Ops checklist",
    "opsCheck1": "Give Admin only to people who need privilege; use Operator day-to-day.",
    "opsCheck2": "Save after editing Permissions; one-click restore returns factory defaults.",
    "opsCheck3": "Do not delete packages with subscribers; unassign first.",
    "opsCheck4": "Backup restore is destructive—Admin by default; confirm before granting to Operator.",
    "detailDesc": "Account, access preview, and advanced overrides",
    "tabAccount": "Account",
    "tabAccess": "Access",
    "tabAdvanced": "Advanced",
    "rolePickHint": "Pick the right job role; Admin stays fully open",
    "accountSection": "Account settings",
    "packageHint": "Hosting package template (optional)",
    "resetPasswordOptional": "Leave blank to keep password",
    "accountStatus": "Account status",
    "suspendedHint": "Suspended: cannot sign in",
    "activeHint": "Active: can sign in and work",
    "accessHint": "Effective capabilities from role policy (readable labels)",
    "noCapsInBand": "No capabilities in this level",
    "overridesHint": "Affects this user only; role defaults stay unchanged",
    "adminNoOverrides": "Admin users are always fully open; personal revokes are not applied.",
    "grantsHint": "Extra capabilities beyond the role pack",
    "revokesHint": "Turn off inherited capabilities (not for Admin)",
    "searchCaps": "Search capabilities…",
    "noCapMatch": "No matching capability",
    "no2fa": "2FA off",
    "lastSeenValue": "Last active {{time}}",
    "roleName": {
      "admin": "Admin",
      "operator": "Operator",
      "viewer": "Viewer",
      "agent": "Agent"
    },
    "roleDesc": {
      "admin": "Full control: users, permissions, destructive ops. Always full-open.",
      "operator": "Day-to-day ops: services, updates, DNS/SSL, sites.",
      "viewer": "Read-only: status, logs, lists — no changes.",
      "agent": "Automation agent: low-risk writes with scope limits."
    },
    "securityTitle": "Two-factor auth (this user)",
    "securityPerUserHint": "TOTP/Passkey is per user",
    "securityStatusOn": "2FA enabled",
    "securityStatusOff": "2FA not set",
    "securitySessions": "Active sessions",
    "securityClearTotp": "Force-clear this user's 2FA",
    "securityClearTotpHint": "Requires step-up",
    "securityClearConfirm": "Type the username to confirm clearing 2FA",
    "securityClearOk": "Cleared 2FA for {{name}}",
    "securitySelfNote": "To set up your own 2FA, open Security → My security.",
    "cannotModifySelf": "You cannot suspend or demote the signed-in account",
    "cannotDeleteLastAdmin": "Cannot delete the last admin",
    "cannotDemoteLastAdmin": "Cannot suspend or demote the last admin",
    "lockSelfHint": "This is the signed-in account. Delete, suspend, and role change are blocked to prevent lock-out.",
    "lockLastAdminHint": "This is the last admin. Delete, suspend, and demotion are blocked.",
    "demoteAdminTitle": "Demote this admin?",
    "demoteAdminDesc": "This user will lose full admin access. Confirm only if another admin remains.",
    "quotaNonNeg": "Counts and quotas cannot be negative.",
    "diskQuotaHint": "Presets are GiB; custom box is MiB.",
    "bandwidthHint": "0 means unlimited."
  },
  "validators": {
    "title": "Validators (Beta)",
    "subtitle": "Install and manage L1 nodes on this host. Non-custodial — you keep the keys.",
    "beta": "Beta",
    "tab": {
      "nodes": "Nodes",
      "disk": "Disk",
      "stack": "Software",
      "about": "About"
    },
    "empty": {
      "title": "No validator nodes yet",
      "desc": "Create a testnet node in a few clicks."
    },
    "refresh": "Refresh",
    "software": {
      "engine": "Docker Engine",
      "engineDesc": "Validator nodes run as Compose projects. Install Docker here if it is missing. Image prune stays on the Docker page.",
      "client": "Client",
      "image": "Image",
      "present": "Local",
      "local": "Pulled",
      "missing": "Not pulled",
      "size": "Size",
      "usedBy": "Used by",
      "unused": "No instance",
      "pull": "Pull pin",
      "pulled": "On this host",
      "pulling": "Pull {{ref}}",
      "empty": "No pinned client images",
      "emptyDesc": "The catalog is empty. This should not happen.",
      "daemonDown": "Docker Engine is not running",
      "source": "Source",
      "official": "Official latest",
      "officialNewer": "Official newer",
      "stale": "Behind pin",
      "staleItem": "{{id}} ({{tag}})",
      "pin": "Panel pin",
      "openRelease": "Release notes",
      "chooseOnInstance": "Change the version on the instance page. Pulling an image does not retag a running node."
    },
    "disk": {
      "title": "Validator disk",
      "root": "Data directory",
      "free": "Free",
      "used": "Validator data",
      "fsUsed": "Filesystem used",
      "leftoverTitle": "Leftover data ({{count}})",
      "leftoverEmpty": "No leftover instance directories",
      "leftoverDesc": "Directories under the validators root that are not a store instance. Remove only after you confirm they are unused.",
      "leftoverRemove": "Remove",
      "leftoverRemoveTitle": "Delete leftover validator data?",
      "leftoverRemoveDesc": "Permanently delete {{path}} from disk. This is not a listed node.",
      "browseRoot": "Open in file browser",
      "none": "No instance data yet",
      "warn": "Disk usage is high (70%+)",
      "danger": "Disk usage is critical (85%+)",
      "autoClear": "Auto-clear the largest stopped instance when disk is critical (off by default)",
      "autoClearRisk": "Destructive: the largest stopped instance is deleted without a further prompt. Default is off. Check audit / logs after it fires.",
      "autoClearConfirmTitle": "Enable auto-clear?",
      "autoClearC1": "When disk is critical, the largest stopped instance is deleted without asking again.",
      "autoClearThreshold": "Trigger: filesystem use at or above 85%.",
      "autoClearCandidate": "Current candidate: {{id}}",
      "autoClearCandidates": "Stopped candidates (largest with data first): {{list}}",
      "autoClearNone": "No stopped instance is a candidate right now."
    },
    "chain": {
      "eth": "Ethereum",
      "avax": "Avalanche",
      "near": "NEAR",
      "ada": "Cardano",
      "btc": "Bitcoin",
      "cosmos": "Cosmos Hub",
      "sui": "Sui",
      "aptos": "Aptos",
      "dot": "Polkadot",
      "sol": "Solana"
    },
    "network": {
      "hoodi": "Hoodi",
      "sepolia": "Sepolia",
      "mainnet": "Mainnet",
      "fuji": "Fuji",
      "testnet": "Testnet",
      "preview": "Preview",
      "preprod": "Preprod",
      "westend": "Westend"
    },
    "networkKind": {
      "testnet": "Testnet",
      "mainnet": "Mainnet",
      "mixed": "Mainnet + testnet"
    },
    "profile": {
      "minimal": "Minimal",
      "pruned": "Pruned",
      "validator-ready": "Validator-ready",
      "rpc": "RPC"
    },
    "profileHelp": {
      "title": "The four profiles",
      "desc": "Wizard step 3 offers Minimal, Pruned, Validator-ready, and RPC. They differ by disk and role. The wizard shows the size for the chain you picked. The panel never holds staking keys.",
      "colName": "Profile",
      "colUse": "Use for",
      "colDisk": "Disk",
      "colStake": "Staking validator",
      "useMinimal": "Testnet or a first install. Not a full history.",
      "usePruned": "Follow the chain tip long-term. Keeps recent data only (Pruned).",
      "useValidatorReady": "Sized so you can later attest or propose. Generate keys offline yourself.",
      "useRpc": "Let this host or other services query the chain. Listens on 127.0.0.1 by default.",
      "diskMinimal": "Smallest",
      "diskPruned": "Medium (more than Minimal)",
      "diskValidatorReady": "Largest of the four",
      "diskRpc": "Depends on the chain",
      "stakeNo": "Not suitable",
      "stakeYes": "Yes — offline or misconfigured can lose stake",
      "stakeRpc": "Not a validator",
      "minimal": "Smallest disk. Use for testnets or a first install. Not a full history, and not for a live staking validator.",
      "pruned": "Keeps recent chain state and drops older blocks (Pruned). More disk than Minimal, less than a full node. Use to follow the tip long-term.",
      "validatorReady": "Reserves more disk so you can later attest or propose as a validator. Generate keys offline yourself. Being offline or misconfigured can lose stake.",
      "rpc": "For this host or other services to query the chain. RPC listens on 127.0.0.1 by default and is not published to the internet."
    },
    "col": {
      "id": "ID",
      "chain": "Chain",
      "network": "Network",
      "profile": "Profile",
      "status": "Status",
      "traffic": "Traffic",
      "disk": "Disk"
    },
    "cli": {
      "usage": "Usage: ysk-server validators list|chains|disk|get|status|checklist|logs|create|start|stop|restart|clear|upgrade|set-version|versions|policy|mithril|prune|switch-network|snapshot|compose|compose-write|rewrite-compose|software|pull|leftover-remove|stats|settings|producer-keys|producer-detach|near-account [--chain C] [--network N] [--profile P] [--el EL] [--cl CL] [--el-tag T] [--cl-tag T] [--node-tag T] [--client ID] [--tag T] [--data-path P] [--rpc-port N] [--id ID] [--path PATH] [--file PATH] [--image REF] [--upgrade POLICY] [--confirm TOKEN] [--kes-file P] [--vrf-file P] [--opcert-file P] [--accept-low-disk] [--accept-low-mem] [--accept-mainnet] [--refresh] [--execute] [--json]"
    },
    "clients": {
      "el": "Execution client",
      "cl": "Consensus client",
      "version": "Version",
      "pin": "Panel pin",
      "officialNewer": "Official newer",
      "olderThanPin": "Older than the panel pin",
      "prerelease": "Prerelease",
      "current": "Running now",
      "source": "Image source"
    },
    "mithril": {
      "label": "After the node is up, restore from a Mithril snapshot",
      "hint": "This is a one-time restore after install. It is not written into compose. You can also run it later from the instance page.",
      "action": "Restore with Mithril"
    },
    "errors": {
      "notFound": "Validator instance not found",
      "invalidId": "Invalid instance id",
      "diskLow": "Not enough free disk for this chain, network, and profile",
      "memLow": "Not enough free RAM for this chain's memory cap",
      "diskUnknownMainnet": "Cannot measure free disk; refusing mainnet create",
      "needDocker": "Docker Compose is required and was not found",
      "composeFailed": "docker compose failed",
      "containerNotUp": "Compose started, but the container did not stay running",
      "probeFailed": "The node is not answering RPC yet. Check logs on this page.",
      "oom": "Out of memory. Set a memory limit or add RAM, then restart.",
      "nofile": "The process hit the open-files (nofile) limit. Raise ulimits.nofile and restart.",
      "noContainer": "No compose container exists for this instance.",
      "restarting": "Container is restarting. Check logs on this page.",
      "restartingCount": "Container is restarting ({{n}}). Check logs on this page.",
      "needConfirm": "Clear requires confirm=instance id or CLEAR",
      "mithrilAdaOnly": "Mithril restore is only available for Cardano",
      "needMithrilConfirm": "Mithril requires confirm=instance id or MITHRIL",
      "mithrilBlocked": "Mithril docker run was blocked by the allowlist",
      "mithrilKey": "Could not load the Mithril genesis verification key",
      "mithrilFailed": "Mithril snapshot download failed",
      "pruneFailed": "Prune failed",
      "switchNeedStop": "Stop the node before switching network",
      "switchNeedClear": "Switching network clears chain data. Confirm with instance id or CLEAR",
      "composeMissing": "Compose file not found",
      "composeNotManaged": "Refusing to write a compose file that is not YSK-managed",
      "badDataPath": "Data path must be an absolute directory outside system paths",
      "portInUse": "That RPC port is already used by another validator instance",
      "badTag": "That client version is not an official tag for this image",
      "needVersionConfirm": "Changing version requires confirm=instance id",
      "needMainnetVersionAck": "Mainnet version changes require acceptMainnet",
      "snapshotUnsupported": "No allowlisted snapshot source for this chain",
      "snapshotLookup": "Could not resolve the official snapshot pointer",
      "needSnapshotConfirm": "Snapshot restore requires confirm=instance id or SNAPSHOT",
      "snapshotBlocked": "Snapshot docker run was blocked by the allowlist",
      "snapshotFailed": "Snapshot download or extract failed",
      "producerAdaOnly": "Producer keys are only for Cardano",
      "needProducerConfirm": "Attaching producer keys requires confirm=instance id or PRODUCER",
      "needMainnetProducerAck": "Mainnet producer attach requires acceptMainnet",
      "producerColdRejected": "Cold or pool-owner signing keys are refused. Keep cold keys offline.",
      "producerTooLarge": "That key file is larger than 64 KiB",
      "producerBadType": "That file is not a KES key, VRF key, or operational certificate",
      "producerEmpty": "Provide at least one of kes, vrf, or opcert",
      "switchNeedDetachProducer": "Detach producer keys before switching network",
      "nearAccountInvalid": "Pool name must be a short slug (or the full {pool}{factory} account).",
      "nearKeyMissing": "validator_key.json is missing or has no public_key. Start the node and wait for neard init."
    },
    "notes": {
      "beta": "This feature is Beta. Host changes need root and YSK_EXECUTE=1.",
      "noKeys": "YSK Server never generates or stores staking keys.",
      "dockerSoon": "Install and start from this page wizard. Host changes need root and YSK_EXECUTE=1.",
      "dryCreate": "Wrote instance spec and compose (dry-run). Pass --execute and YSK_EXECUTE=1 to start containers.",
      "dryStart": "Start is dry-run. Pass --execute and YSK_EXECUTE=1.",
      "dryStop": "Stop is dry-run. Pass --execute and YSK_EXECUTE=1.",
      "dryClear": "Clear is dry-run. Pass --execute and YSK_EXECUTE=1.",
      "created": "Node created and compose started",
      "started": "Node started",
      "stopped": "Node stopped",
      "cleared": "Chain data cleared",
      "dryMithril": "Mithril restore is dry-run. Pass --execute and YSK_EXECUTE=1.",
      "mithril": "Mithril snapshot restored; node restarted",
      "dryPrune": "Prune is dry-run. Pass --execute and YSK_EXECUTE=1.",
      "pruned": "Unused project images pruned",
      "pruneProfile": "Client-native prune is the pruned/minimal profile. Recreate to change it.",
      "sameNetwork": "Already on that network",
      "drySwitch": "Network switch is dry-run.",
      "switched": "Network switched and chain data cleared",
      "dryCompose": "Would write compose.yml",
      "composeWrote": "Wrote compose.yml",
      "statsEmpty": "No running containers to measure",
      "autoClearNone": "No stopped instance to auto-clear",
      "drySnapshot": "Snapshot restore is dry-run. Pass --execute and YSK_EXECUTE=1.",
      "snapshotEthEl": "Restored ethPandaOps EL archive and reset CL for checkpoint sync",
      "snapshotEthCl": "Reset CL data for official checkpoint sync",
      "snapshotNear": "Wiped NEAR data; compose will re-init official genesis and epoch sync",
      "nativePrune": "Ran the client-native prune command",
      "dryProducer": "Producer keys are dry-run. Add --execute and YSK_EXECUTE=1.",
      "dryProducerDetach": "Producer detach is dry-run. Add --execute and YSK_EXECUTE=1.",
      "producerPartial": "Wrote hot keys. Attach KES, VRF, and opcert before the node starts as a block producer.",
      "producerAttached": "Hot keys attached; compose rewritten as block producer",
      "producerDetached": "Hot keys removed; compose rewritten as relay",
      "dryDelete": "Delete is dry-run. Pass --execute and YSK_EXECUTE=1.",
      "deleted": "Node deleted",
      "leftoverRemoved": "Removed leftover {{path}}",
      "dryNearAccount": "Would set account_id to {{account}} (pass --execute). Secret is never changed.",
      "nearAccountWrote": "Set account_id to {{account}}. Secret was not changed. Restart the node if it is running."
    },
    "create": "Create node",
    "wizard": {
      "title": "Create node",
      "stepOf": "Step {{n}} / {{total}}",
      "stepChain": "Chain",
      "stepNetwork": "Network",
      "stepProfile": "Profile",
      "stepSummary": "Summary",
      "needDocker": "Docker Engine is not installed. Install it first — this button stays disabled.",
      "diskNeed": "This profile needs about {{need}} · free {{free}}",
      "diskNeedNetwork": "Default (Minimal) for this network needs about {{need}} · free {{free}}",
      "profileHint": {
        "minimal": "Smallest sync — light disk, not for staking.",
        "pruned": "Keeps recent history only (Pruned). Smaller than archive, still usable for RPC.",
        "validator-ready": "Sized for a staking validator. Needs more disk than Minimal.",
        "rpc": "Public RPC node — not a staking validator."
      },
      "diskShort": "Not enough free disk for this chain / network / profile",
      "diskShortDetail": "Need {{need}} · free {{free}} · short {{short}}",
      "memShort": "Not enough free RAM for this chain's memory cap",
      "memShortDetail": "Need {{need}} · free {{free}} · short {{short}}",
      "needCustomPath": "Enter an absolute data path",
      "previewId": "Node id",
      "previewCompose": "Compose project",
      "profileSeeAbout": "How the four profiles differ is on the About tab.",
      "back": "Back",
      "next": "Next",
      "install": "Install",
      "mainnetWarn": "Mainnet needs a lot of free disk (ETH often 800 GiB+). Testnet is recommended.",
      "mainnetAck": "Create the mainnet node. I understand it needs a lot of disk, and a staking validator can lose stake if it is offline or misconfigured.",
      "lowDiskAcked": "Free disk is below the recommended size. You confirmed create anyway; sync may stop if the disk fills.",
      "lowMemAcked": "Free RAM is below this chain's memory cap plus 1 GiB headroom. You confirmed create anyway; the node may OOM or stall.",
      "heavyWarn": "This chain is heavy (large disk and high IOPS). Mainnet Solana typically needs 2 TiB+.",
      "memory": "Memory limit",
      "cpus": "CPU limit",
      "dataPath": "Data path",
      "rpcPort": "RPC port",
      "limitNone": "No limit",
      "rpcDefault": "Default",
      "customPath": "Use a custom data path",
      "installConfirmTitle": "Install this node?",
      "installConfirmDesc": "{{chain}} · {{network}} · {{profile}}. About {{disk}} of disk. The image pull can take a long time.",
      "installC1": "Several gigabytes of images may be downloaded.",
      "installC2": "You can cancel the panel task; already-pulled images are not deleted automatically.",
      "installC3": "Mainnet uses a lot of disk. A staking validator can lose stake if it is offline or misconfigured. Type the node id to confirm.",
      "dockerAbout": "Docker Engine is required to install and start nodes.",
      "dockerAboutOk": "Docker Engine is installed.",
      "dockerAboutMissing": "Docker Engine is not installed. Open Docker to install it.",
      "rewriteCompose": "Rewrite compose",
      "rewriteComposeTitle": "Rewrite compose.yml from the current adapter?",
      "rewriteComposeDesc": "Overwrites the generated compose for {{id}} using the shipped flags for this chain.",
      "chainMeta": "{{disk}} min · {{clients}} clients"
    },
    "actions": {
      "detail": "Details",
      "start": "Start",
      "stop": "Stop",
      "restart": "Restart",
      "clear": "Clear",
      "upgrade": "Upgrade",
      "setVersion": "Change version",
      "clearConfirm": "Type instance id or CLEAR",
      "prune": "Prune",
      "switchNetwork": "Switch network",
      "removeUnit": "Also remove compose / instance record",
      "restoreAfter": "Restore snapshot after clear",
      "delete": "Delete",
      "deleteTitle": "Delete {{id}}",
      "deleteDesc": "This removes the node from the panel.",
      "deleteC1": "Docker Compose is stopped and removed",
      "deleteC2": "Chain data on disk is deleted",
      "deleteC3": "The instance record is removed",
      "pruneTitle": "Prune unused images",
      "pruneDesc": "Type the instance id to prune unused Compose images for this node.",
      "pruneC1": "Unused images labelled for this Compose project are deleted.",
      "clearTitle": "Clear {{id}}",
      "clearC1": "Chain data on disk is deleted.",
      "clearC2": "The instance stays in the panel, stopped and empty.",
      "switchTitle": "Switch network",
      "switchC1": "The node is stopped and chain data is wiped before the new network is written."
    },
    "policy": {
      "label": "Upgrade policy",
      "manual": "Manual",
      "notify": "Notify",
      "auto-safe": "Auto (safe)",
      "auto-all": "Auto (all)"
    },
    "logs": {
      "empty": "No logs yet",
      "follow": "Follow logs"
    },
    "compose": {
      "label": "Compose file",
      "save": "Save compose"
    },
    "snapshot": {
      "action": "Restore snapshot",
      "mithril": "Cardano uses Mithril for certified snapshot restore.",
      "eth": "Ethereum mainnet uses official checkpoint sync on the consensus client. EL continues snap sync.",
      "ethEl": "Hoodi/Sepolia can restore an ethPandaOps EL archive, then checkpoint-sync the CL.",
      "avax": "Avalanche uses state-sync in the compose profile.",
      "near": "Official free NEAR tarball snapshots were retired. Restore wipes data and uses official genesis plus epoch sync.",
      "none": "No snapshot source is configured for this chain."
    },
    "producer": {
      "title": "Block producer hot keys",
      "hint": "This is not an IP address. Upload the KES key, VRF key, and operational certificate from an offline machine. Keep cold keys off this host.",
      "warn": "The same node with a public P2P port will sign blocks. Official topology keeps the producer off the public internet. These three files are hot keys.",
      "kes": "KES",
      "vrf": "VRF",
      "opcert": "opcert",
      "missing": "Not attached",
      "present": "Attached {{fp}}",
      "presentShort": "On host",
      "queuedShort": "Ready",
      "queued": "Selected · {{name}}",
      "fileHint": "Typical name {{file}}",
      "dropOrBrowse": "Drop {{file}} here or browse",
      "dropping": "Drop to attach {{label}}",
      "browse": "Browse",
      "clearFile": "Remove",
      "choose": "Choose file",
      "apply": "Apply and restart as block producer",
      "detach": "Detach and run as relay",
      "applyTitle": "Attach hot keys to {{id}}?",
      "applyDesc": "KES, VRF, and opcert are written under the instance keys directory. Compose is rewritten. The container restarts as a block producer.",
      "applyC1": "Cold keys must stay offline. Do not upload cold.skey.",
      "applyC2": "The running node can sign blocks if these files are valid.",
      "applyC3": "Mainnet: an offline or misconfigured producer misses blocks.",
      "detachTitle": "Detach producer keys from {{id}}?",
      "detachDesc": "Hot keys are deleted from this host. Compose goes back to relay.",
      "detachC1": "The node will no longer produce blocks.",
      "mainnet": "Mainnet: I understand this host will hold hot keys and sign blocks."
    },
    "stake": {
      "title": "Prepare for staking (you keep the keys)",
      "offlineKeys": "Generate keys offline. The panel never stores them.",
      "deposit": "Complete deposit / registration on the official launchpad.",
      "withdrawal": "Set withdrawal credentials yourself.",
      "monitor": "Watch disk, peers, and upgrade badges on this page."
    },
    "playbook": {
      "overviewTitle": "How staking works on each chain",
      "overviewDesc": "This panel runs the node. Your wallet and keys stay with you. Official links only — never share a seed phrase here.",
      "colChain": "Chain",
      "colModel": "How you register",
      "colMin": "Typical minimum",
      "colWallet": "Your wallet",
      "colPanel": "What this panel does",
      "yskDoes": "This panel does",
      "youDo": "You do",
      "steps": "Steps",
      "never": "Do not",
      "official": "Official links",
      "seeAbout": "Full steps are on the About tab.",
      "nodeIdReady": "NodeID (from this node)",
      "nodeIdPending": "NodeID appears after the node is synced and answering RPC.",
      "blsReady": "BLS public key",
      "blsProof": "BLS proof of possession",
      "blsPending": "BLS credentials appear after the node answers RPC.",
      "copyAll": "Copy all",
      "copyNamed": "Copy {{label}}",
      "nearStakeKey": "Stake public key",
      "nearStakeKeyPending": "Appears after first start (neard init). RPC not ready does not mean the key is missing.",
      "nearAccountId": "Key file account_id",
      "nearAccountIdPending": "Often empty until you set it to {{pool}}{{suffix}} after the pool exists. The panel writes only this field — never secret_key.",
      "nearFactory": "Staking-pool factory",
      "nearPublicAddr": "Public P2P (peers)",
      "nearPublicAddrPending": "Appears after first start writes WAN:{{port}} into config.json.",
      "nearCreateCommand": "create_staking_pool command",
      "nearPointing": "The pool contract does not take this server’s IP. It stores this node’s stake public key. Peers use the Public P2P row above (host port {{port}}). RPC stays on localhost.",
      "nearAccountIdHint": "After the pool exists, set account_id here (do not edit the file by hand). The panel never writes secret_key.",
      "cosmosPubkey": "Consensus public key",
      "cosmosPubkeyPending": "Appears after gaiad init writes priv_validator_key.json. RPC not ready does not mean the key is missing.",
      "cosmosChainId": "chain-id",
      "cosmosP2p": "Public P2P (external_address)",
      "cosmosP2pPending": "Appears after first start writes tcp://WAN:{{port}} into config.toml.",
      "ethBeacon": "Beacon API (localhost)",
      "ethBeaconPending": "Beacon HTTP on this host. Point a validator client you run yourself at this URL — this compose has no VC.",
      "cosmosCreateCommand": "create-validator command",
      "cosmosCreateJson": "validator.json (gaiad v28)",
      "copyFailed": "Copy failed",
      "solIdentity": "Identity pubkey",
      "solIdentityPending": "Appears after RPC answers getIdentity. This process is --no-voting until you add a vote account yourself.",
      "adaP2pPort": "Relay P2P port",
      "adaP2pPending": "Advertise this host’s public IPv4 (or DNS) and this port in the pool registration certificate. topology.json localRoots is for your own block producer. This panel does not probe WAN.",
      "notPosTitle": "Not proof-of-stake",
      "notPosBody": "Bitcoin here is a full or pruned node. There is no staking wallet on this page.",
      "eth": {
        "model": "This compose runs execution + beacon only — not a validator client. Deposit 32 ETH on the official launchpad.",
        "min": "32 ETH + gas",
        "wallets": "MetaMask, Ledger, Trezor — only on the official launchpad",
        "panel": "Runs EL + beacon. RPC and beacon API on localhost. No validator client in compose.",
        "honesty": "This instance is execution + beacon only. There is no validator client in the compose file. Copying a keystore into the beacon data directory will not start attesting. The deposit contract does not take this server’s IP.",
        "yskDoes": [
          "Install and start the execution and beacon clients.",
          "Show disk, peers, and upgrade status.",
          "Does not run a validator client and does not load a signing keystore."
        ],
        "youDo": [
          "Create the keystore and withdrawal address yourself on the official launchpad or with staking-deposit-cli.",
          "Deposit 32 ETH on the launchpad for this network.",
          "Run a validator client yourself (not this compose) against this instance’s localhost beacon API."
        ],
        "steps": [
          "Wait until execution and beacon are synced.",
          "Open the official launchpad for this network (Hoodi or Mainnet on this page). Sepolia has no launchpad button here.",
          "Offline, generate the keystore (staking-deposit-cli). Set the withdrawal address to your own ETH wallet.",
          "Deposit 32 ETH on the launchpad (keep extra for gas).",
          "Run a validator client yourself against the beacon URL on this card (example: lighthouse vc --beacon-nodes). This compose has no VC — putting a keystore in the beacon datadir does not attest."
        ],
        "never": [
          "Never give your seed phrase or withdrawal key to anyone, including this panel.",
          "Never upload a signing keystore to a hosted cloud.",
          "Do not expect this page to attest after you copy a keystore into the beacon datadir."
        ]
      },
      "avax": {
        "model": "Register the running NodeID and BLS proof on the P-Chain from Core or Ledger.",
        "min": "2,000 AVAX + fee (1 AVAX on Fuji); at least 14 days",
        "wallets": "Core, Ledger",
        "panel": "Runs avalanchego and can show NodeID and BLS after RPC answers",
        "yskDoes": [
          "Run avalanchego and keep RPC on localhost.",
          "Show NodeID and BLS credentials once the node answers RPC."
        ],
        "youDo": [
          "Hold AVAX in Core or Ledger.",
          "Add the validator from Core using this node’s NodeID and BLS proof."
        ],
        "steps": [
          "Wait until this node is synced and the NodeID / BLS rows appear (RPC).",
          "Copy NodeID, BLS public key, and BLS proof of possession.",
          "In Core web (Staking → Validate), or with Ledger via Core, register on the P-Chain. The transaction does not take a server IP.",
          "Mainnet needs at least 2,000 AVAX, a 14-day minimum period, and a fee reserve. Fuji is 1 AVAX."
        ],
        "never": [
          "Do not send AVAX to this panel.",
          "Do not share your Core or Ledger recovery phrase."
        ]
      },
      "ada": {
        "model": "Operate a stake pool with offline cold / KES / VRF keys — not a browser wallet tap.",
        "min": "Pledge is your choice (see official docs)",
        "wallets": "Official stake-pool tooling (cold keys stay offline)",
        "panel": "Runs cardano-node as a relay first; hot keys can be attached on this page.",
        "honesty": "This instance starts as a relay. On-chain pool registration uses cold keys you keep offline. Peers and topology use this host’s public IPv4 and the P2P port shown here — the panel does not probe WAN.",
        "yskDoes": [
          "Run cardano-node and Mithril snapshot restore where offered.",
          "Attach KES, VRF, and opcert when you provide them. Cold keys are refused."
        ],
        "youDo": [
          "Generate pool keys offline.",
          "Register the pool with the official Cardano CLI. Put this host’s public IPv4 or DNS and the relay P2P port into the pool registration certificate.",
          "Attach KES, VRF, and opcert on this page. Do not upload cold keys."
        ],
        "steps": [
          "Read the official operate-a-stake-pool guide.",
          "Generate cold, KES, and VRF keys on an offline machine.",
          "Register the pool on-chain. Advertise the relay in that certificate (--pool-relay-ipv4 or DNS + the P2P port on this card). Public discovery is the certificate, not topology.json.",
          "On this instance page, attach KES, VRF, and the operational certificate. Cold keys are refused.",
          "topology.json localRoots is for your own block producer (advertise: false). This panel does not look up the WAN address."
        ],
        "never": [
          "Do not treat this as a MetaMask one-click stake.",
          "Do not store cold keys on the validator host.",
          "Do not expect editing topology.json alone to register the relay on-chain."
        ]
      },
      "near": {
        "model": "Create a staking-pool contract at the official factory. The contract stores this node’s public key — not the server IP.",
        "min": "See official validator docs (30 NEAR to create the pool, plus stake)",
        "wallets": "Official NEAR wallet / lockup",
        "panel": "Runs neard; form fills create_staking_pool; after the pool exists, writes account_id only.",
        "yskDoes": [
          "Run neard with RPC on localhost and P2P on 24567.",
          "After init, show the stake public key, public P2P address, and factory.",
          "Fill create_staking_pool from pool name + owner + public key. After the pool exists, write account_id only — never secret_key, never the transaction."
        ],
        "youDo": [
          "Start the node and wait for the public key on this page.",
          "Enter pool name and owner, then copy the command.",
          "Sign create_staking_pool from your own NEAR wallet or near-cli.",
          "Return here and set account_id. Stake from your wallet into that pool."
        ],
        "steps": [
          "Start the node and wait for neard init so the public key appears (RPC not ready is not the same as missing keys).",
          "Enter the pool short name and owner account. Copy the filled create_staking_pool command.",
          "From your wallet, call the factory (testnet pool.f863973.m0 / mainnet poolv1.near) with 30 NEAR for storage. The command uses --accountId; if your near CLI expects --account_id, follow that CLI’s --help.",
          "After the pool exists, use Set account_id on this page (confirm = instance id). Do not edit validator_key.json by hand.",
          "Restart if the node is already running. Wait until RPC answers and the node is synced before staking large amounts. Peers use Public P2P — the contract does not take an IP."
        ],
        "never": [
          "Do not paste a seed phrase into this panel.",
          "Do not put this server’s IP into the contract.",
          "Do not expect the panel to send the create_staking_pool transaction."
        ]
      },
      "cosmos": {
        "model": "create-validator from your operator wallet using this node’s consensus public key — not the server IP.",
        "min": "See official Cosmos Hub docs (self-delegation in uatom)",
        "wallets": "Keplr or another Cosmos wallet you control",
        "panel": "Runs gaiad v28; shows consensus pubkey; form fills validator.json + create-validator. Never writes priv_validator_key.json or broadcasts.",
        "honesty": "This gaiad is v28 (JSON file). Hub docs still show flags — those fail here. The transaction stores this node’s consensus public key, not the server IP. Peers use Public P2P. RPC stays on localhost. This panel does not broadcast or read priv_key.",
        "yskDoes": [
          "Run gaiad with RPC on localhost and P2P on 26656. minimum-gas-prices is 0.005uatom.",
          "After init, show the consensus public key, chain-id, and public P2P.",
          "Fill validator.json and the gaiad v28 command from amount, moniker, and --from plus the consensus pubkey. Never write priv_validator_key.json or broadcast the transaction."
        ],
        "youDo": [
          "Start the node and wait for the consensus public key on this page.",
          "Enter amount, moniker, and --from. Copy validator.json, then the gaiad command.",
          "Sign from Keplr or gaiad keys you control. Do not mix that mnemonic with the consensus key on this host."
        ],
        "steps": [
          "Start the node and wait for gaiad init so the consensus public key appears (RPC not ready is not the same as missing keys).",
          "Enter self-delegation (1atom = 1 ATOM, or uatom), moniker, and --from. Copy validator.json then the gaiad command. This node is gaiad v28: JSON file, not the Hub docs’ flag form. chain-id is cosmoshub-4 on mainnet, provider on testnet.",
          "The copied --gas-prices is 0.005uatom to match this node. Do not paste the Hub docs’ 0.0025uatom example or the flag-based create-validator.",
          "Save validator.json and broadcast from your operator wallet. The transaction does not take a server IP. Peers use tcp://WAN:{{port}}.",
          "Wait until RPC answers and the node is synced before bonding large amounts."
        ],
        "never": [
          "Do not mix the operator wallet mnemonic with the consensus key.",
          "Do not enter wallet mnemonics here.",
          "Do not put this server’s IP into create-validator.",
          "Do not paste the Hub docs’ --amount/--pubkey flags — this gaiad is v28 (validator.json).",
          "Do not use 0.0025uatom gas on this node — the compose minimum is 0.005uatom."
        ]
      },
      "sol": {
        "model": "This compose runs Agave with --no-voting. Vote account and withdrawer are created with official Solana tools — not this panel.",
        "min": "See official operations docs (hardware and disk are heavy)",
        "wallets": "Official Solana CLI / wallet you control",
        "panel": "Runs Agave as a catch-up node (--no-voting). Can show identity pubkey after RPC answers.",
        "honesty": "This process is --no-voting. It will not vote or earn stake until you create a vote account with official Agave CLI and change how the process is started. This panel does not remove --no-voting.",
        "yskDoes": [
          "Run the Agave client and warn about disk.",
          "Show the identity pubkey once RPC answers getIdentity.",
          "Does not create a vote account and does not start voting."
        ],
        "youDo": [
          "Create vote and authorized-withdrawer keys with official Solana tools on a machine you control.",
          "Create the vote account with the official CLI, using this identity pubkey.",
          "Only then run a voting validator — this compose stays --no-voting."
        ],
        "steps": [
          "Confirm this host has enough disk and IOPS (mainnet is typically 2 TiB+).",
          "Wait until RPC answers, then copy the identity pubkey shown here.",
          "Create vote and authorized-withdrawer keys with official Solana tools on a machine you control, then solana create-vote-account.",
          "This compose keeps --no-voting. Creating a vote account does not make this process vote."
        ],
        "never": [
          "Do not expect a browser wallet button in this panel.",
          "Do not paste identity or vote keypairs into this panel.",
          "Do not expect this page to start voting after you create a vote account."
        ]
      },
      "dot": {
        "model": "This compose is a full node (no --validator). Session keys and setKeys are official Polkadot.js steps — not this panel.",
        "min": "See the official wiki",
        "wallets": "Polkadot.js",
        "panel": "Runs polkadot as a full node. RPC on localhost. No --validator flag.",
        "honesty": "This process is not started with --validator. The panel does not call author_rotateKeys (that would change the keystore). Becoming a validator needs the official node flag and a rotateKeys call you make against localhost RPC.",
        "yskDoes": [
          "Run polkadot and expose RPC on localhost.",
          "Does not pass --validator and does not rotate session keys."
        ],
        "youDo": [
          "Follow the official set-up-a-validator guide.",
          "If you add --validator yourself, call rotateKeys on localhost RPC and bind the result in Polkadot.js from your stash."
        ],
        "steps": [
          "Sync this full node.",
          "Read the official validate guide. This compose is not a validator process.",
          "Do not paste the stash mnemonic here. If you later run with --validator, rotate keys yourself on http://127.0.0.1 (RPC port on this instance).",
          "In Polkadot.js, set those session keys on your stash / controller, then follow official bonding steps."
        ],
        "never": [
          "Do not paste the stash mnemonic into this panel.",
          "Do not expect this page to generate session keys or to have started --validator."
        ]
      },
      "sui": {
        "model": "This compose is a Sui fullnode (fullnode.yaml), not a validator node.",
        "min": "See official Sui docs",
        "wallets": "Official Sui operator wallet",
        "panel": "Runs sui-node as a fullnode. RPC on localhost.",
        "honesty": "This process cannot sign as a Sui validator. Validator setup uses a different config and keys. Official validator docs are linked; this panel does not switch the node to validator mode.",
        "yskDoes": [
          "Run the shipped sui-node image as a fullnode."
        ],
        "youDo": [
          "Use this instance as a fullnode.",
          "To become a validator, follow official Sui validator docs on a validator config — not this compose."
        ],
        "steps": [
          "Sync this fullnode.",
          "Treat it as a fullnode: it re-executes checkpoints but does not sign consensus.",
          "Open the official validator operator guide only if you are building a separate validator process."
        ],
        "never": [
          "Do not send SUI to this panel.",
          "Do not expect this fullnode process to register as a validator."
        ]
      },
      "aptos": {
        "model": "This compose is an Aptos public fullnode (role full_node), not a validator.",
        "min": "See official Aptos docs",
        "wallets": "Official Aptos operator wallet",
        "panel": "Runs aptos-node as a public fullnode. RPC on localhost.",
        "honesty": "Public fullnodes do not participate in consensus. A validator needs a different role, keys, and usually a validator fullnode. This panel does not switch the node to validator mode.",
        "yskDoes": [
          "Run the shipped Aptos image as a public fullnode."
        ],
        "youDo": [
          "Use this instance as a public fullnode.",
          "To run a validator, follow official Aptos validator-node docs — not this compose."
        ],
        "steps": [
          "Sync this public fullnode.",
          "Treat it as a PFN: it serves ledger data, it does not vote.",
          "Open official validator docs only if you are building a separate validator + VFN pair."
        ],
        "never": [
          "Do not enter operator keys in this panel.",
          "Do not expect this fullnode process to register as a validator."
        ]
      },
      "btc": {
        "model": "Not proof-of-stake. This is a Bitcoin full or pruned node.",
        "min": "—",
        "wallets": "Not applicable",
        "panel": "Runs bitcoind",
        "yskDoes": [
          "Run a Bitcoin full or pruned node."
        ],
        "youDo": [
          "Use any Bitcoin wallet separately. Mining and Lightning are out of scope."
        ],
        "steps": [
          "Treat this instance as a Bitcoin node only.",
          "There is no staking deposit and no validator keystore."
        ],
        "never": [
          "Do not look for a staking wallet on this page."
        ]
      },
      "nearPoolSlug": "Pool name",
      "nearPoolSlugHint": "Short name only. The factory adds {{suffix}}.",
      "nearOwner": "Owner account",
      "nearOwnerHint": "NEAR account that signs create_staking_pool in your wallet. Not the node key.",
      "nearPreview": "Command preview",
      "nearWriteAccount": "Set account_id",
      "nearWriteTitle": "Set validator_key.json account_id for {{id}}?",
      "nearWriteDesc": "Writes only account_id on the existing key file. Does not send create_staking_pool. Does not touch secret_key.",
      "nearWriteC1": "account_id becomes {{pool}}{{suffix}}",
      "nearWriteC2": "The panel never signs the factory transaction",
      "nearRestart": "Restart the node after writing",
      "nearNeedKey": "Wait until the stake public key appears (neard init), then fill this form.",
      "nearNeedSlug": "Enter a pool name to set account_id.",
      "nearNeedOwner": "Enter the owner account to fill the command. Set account_id only needs the pool name.",
      "cosmosPointing": "This gaiad is v28: copy validator.json, then create-validator validator.json. Hub docs still show flags — those fail here. The transaction uses this node’s consensus public key, not the server IP. Peers use Public P2P (host port {{port}}). Gas is 0.005uatom — not the Hub docs’ 0.0025uatom example.",
      "avaxPointing": "P-Chain registration uses this NodeID and BLS proof, not the server IP. RPC stays on localhost. Register in Core (Staking → Validate).",
      "ethVcCommand": "Validator client example (not in this compose)",
      "ethVcHint": "Run a validator client yourself against this beacon URL. Importing a keystore into the beacon data directory does not attest.",
      "cosmosAmount": "Self-delegation",
      "cosmosAmountHint": "uatom, or 1atom for 1 ATOM. A bare 1 is 1 uatom — not 1 ATOM.",
      "cosmosAmountParsed": "{{amount}} = {{atom}}",
      "cosmosMoniker": "Moniker",
      "cosmosFromKey": "--from key name",
      "cosmosFromHint": "Local gaiad key name, or sign with Keplr. Not the consensus key on this host.",
      "cosmosNeedPubkey": "Wait until the consensus public key appears (gaiad init), then fill this form.",
      "cosmosNeedFields": "Enter amount, moniker, and --from to fill the command."
    },
    "alerts": {
      "diskTitle": "Validator disk critical",
      "diskBody": "Free space on the validator data volume is critically low.",
      "upgradeTitle": "Validator upgrade available",
      "upgradeBody": "One or more node clients have a newer pinned version.",
      "syncTitle": "Validator node needs attention",
      "syncBody": "A node has been syncing for more than 6 hours or reported an error.",
      "rollbackTitle": "Validator upgrade rolled back",
      "rollbackBody": "Upgrade of {{id}} failed the health check and was rolled back."
    },
    "upgrade": {
      "changelog": "Changelog"
    },
    "readiness": {
      "dockerTitle": "Docker for validator nodes",
      "dockerOk": "{{count}} validator instance(s); Docker is installed",
      "dockerMissing": "Validator instances exist but the docker binary was not found"
    },
    "detail": {
      "status": "Status",
      "sync": "Sync",
      "peers": "Peers",
      "traffic": "Traffic",
      "version": "Version",
      "access": "Access",
      "upgrade": "Updates",
      "upgradeHint": "How this node tracks client versions.",
      "setVersion": "Change version",
      "setVersionHint": "Pick an official Docker tag for a client on this node. Compose is rewritten, then pulled and restarted.",
      "setVersionConfirmTitle": "Change {{id}} to {{tag}}?",
      "setVersionConfirmDesc": "Rewrites compose, pulls {{ref}}, and restarts the node.",
      "setVersionC1": "The running container is replaced with the selected tag.",
      "setVersionC2": "Type the instance id to confirm.",
      "setVersionMainnet": "Mainnet: a bad version can take the node offline. I understand.",
      "releaseNotes": "Release notes",
      "network": "Network",
      "networkHint": "Switching network stops the node and clears chain data. Confirm under Clear data first.",
      "maintain": "Maintenance",
      "danger": "Clear data",
      "dangerHint": "Type the instance id or CLEAR. This deletes chain data on disk.",
      "compose": "Compose",
      "logs": "Logs"
    },
    "state": {
      "unknown": "Unknown",
      "stopped": "Stopped",
      "created": "Created (never started)",
      "missing": "No container",
      "starting": "Starting",
      "rpc_wait": "Running — RPC not ready",
      "running": "Running",
      "syncing": "Syncing",
      "error": "Error"
    }
  },
  "vnc": {
    "pageDesc": "VNC server & client",
    "result": "VNC operation result",
    "installed": "Installed",
    "notInstalled": "Not installed",
    "stackBins": "{{bins}}",
    "stackMissing": "Missing tools",
    "executeOn": "YSK_EXECUTE on",
    "executeOff": "YSK_EXECUTE off",
    "statAccounts": "Accounts",
    "statRunning": "Running",
    "statClients": "Client profiles",
    "statEndpoint": "Host",
    "goAccounts": "Accounts",
    "goClient": "Client",
    "goInstall": "Install",
    "accountsEmptyTitle": "No accounts",
    "accountsEmptyDesc": "Create an account to start",
    "clientPathHint": "Both paths open VNC in the browser. They differ by target semantics and copy (both still TCP-proxy via the panel).",
    "clientPathCompare": "“User-reachable”: public hostnames (e.g. hermes.example.com:5901). “Server proxy”: LAN / DC targets only this host can reach. TCP is probed from this server before connect.",
    "clientEmptyTitle": "No clients",
    "clientEmptyDesc": "Add remote host:port",
    "openInBrowser": "Open in browser",
    "pathUserReachable": "User-reachable endpoint",
    "pathServerProxy": "Via server proxy",
    "pathUserReachableShort": "User-reachable",
    "pathServerProxyShort": "Server proxy",
    "pathUserReachableHint": "For public hostnames or targets as configured (e.g. example.com:5901). Browser goes through the panel; this host must open TCP to that address.",
    "pathServerProxyHint": "For LAN or targets only the control-plane server can reach. Traffic is proxied via this server’s network. Optional connect host overrides the TCP address (e.g. display name vs 10.x).",
    "connectHost": "Connect host (optional, server proxy)",
    "connectHostHint": "TCP address the control plane opens (LAN IP). Leave empty to use Remote host above.",
    "pathBrowser": "User-reachable endpoint",
    "pathHostViewer": "Via server proxy",
    "hostViewer": "Via server proxy",
    "needViewerOptional": "TigerVNC Viewer (optional, not for browser path)",
    "viewerStackOptional": "In-browser VNC does not need desktop vncviewer. The Viewer package below is optional system maintenance only.",
    "viewer": {
      "minting": "Preparing session…",
      "connecting": "Connecting…",
      "connected": "Connected",
      "disconnected": "Disconnected",
      "error": "Connection failed",
      "idle": "Idle",
      "closed": "Closed",
      "minting_state": "Preparing",
      "reconnect": "Reconnect",
      "disconnect": "Disconnect",
      "fullscreen": "Fullscreen",
      "fit": "Fit window",
      "oneToOne": "1:1",
      "cad": "Ctrl+Alt+Del",
      "password": "VNC password",
      "passwordPrompt": "Password required",
      "sendPassword": "Send password",
      "securityFailure": "Authentication failed",
      "canvasLabel": "VNC desktop: {{name}}",
      "clipboardPaste": "Paste → remote",
      "clipboardPanel": "Clipboard",
      "clipboardHint": "Sync text between this browser and the remote desktop.",
      "clipboardLocal": "Send to remote",
      "clipboardLocalPh": "Paste or type text to send into the VNC session",
      "clipboardRemote": "From remote",
      "clipboardRemotePh": "Text copied on the remote desktop appears here",
      "clipboardSend": "Send to remote",
      "clipboardCopy": "Copy locally",
      "clipboardToRemote": "Clipboard sent to remote",
      "clipboardToRemoteHint": "Paste browser clipboard into the remote session",
      "clipboardFromRemote": "Remote clipboard copied to this browser",
      "clipboardFromRemoteManual": "Remote clipboard updated — open Clipboard panel to copy",
      "clipboardEmpty": "Nothing to paste — copy text first or type below",
      "clipboardReadDenied": "Browser blocked clipboard read — paste into the panel and Send",
      "clipboardNoRemote": "No text received from remote yet",
      "clipboardCopiedLocal": "Copied to this browser",
      "quality": "Quality",
      "qualityHint": "Image quality vs bandwidth (JPEG / compression)",
      "qualityLow": "Low (save data)",
      "qualityBalanced": "Balanced",
      "qualityHigh": "High",
      "qualityMax": "Max quality",
      "passwordPromptHint": "This desktop requires a VNC password — enter it below.",
      "errNeedExecute": "Cannot start the desktop: server needs root and YSK_EXECUTE enabled.",
      "errTicket": "Session ticket expired or invalid — press Reconnect.",
      "errBusy": "Too many VNC sessions on this panel — close another and retry.",
      "errRefused": "Nothing is listening on {{host}}:{{port}} (connection refused). Is VNC running and reachable from this server?",
      "errRefusedGeneric": "Connection refused — check that VNC is running and the port is correct.",
      "errTimeout": "Timed out connecting to {{host}}:{{port}}. Check firewall / network path from this server.",
      "errTimeoutGeneric": "Connection timed out — check network and firewall.",
      "errDns": "Cannot resolve host name «{{host}}».",
      "errDnsGeneric": "Host name could not be resolved.",
      "errNet": "Network unreachable for {{host}}:{{port}}.",
      "reconnecting": "Connection dropped — reconnecting ({{n}}/{{max}})…",
      "idleHint": "Session has been idle for a while. The remote desktop may lock; move the mouse or reconnect if needed.",
      "idleDismiss": "Still here",
      "sessions": "Open VNC sessions",
      "sessionCount": "{{n}} / {{max}} sessions",
      "sessionLimit": "At most {{max}} VNC sessions at once — close one first.",
      "closeSession": "Close session {{name}}",
      "shareLink": "Share link",
      "shareCopied": "View-only share link copied (valid ~1 hour)",
      "shareFailed": "Could not create share link",
      "shareTitle": "Shared VNC view",
      "shareGuest": "Shared desktop",
      "shareMissing": "Missing share token",
      "shareExpired": "This share link is invalid or has expired",
      "viewOnlyBadge": "View only",
      "screenshot": "Screenshot",
      "screenshotSaved": "Screenshot downloaded",
      "screenshotFailed": "Could not capture screenshot",
      "screenshotNoCanvas": "Display not ready for screenshot",
      "record": "Record",
      "recordStop": "Stop rec",
      "recordHint": "Record desktop to WebM (max 60s)",
      "recordStarted": "Recording… click Stop rec or wait 60s",
      "recordSaved": "Recording downloaded",
      "recordFailed": "Could not record",
      "recordUnsupported": "This browser cannot record the canvas",
      "connectingHint": "Opening a secure tunnel to the desktop…",
      "reconnectHint": "Press Reconnect to try again, or check the remote host and port."
    },
    "installHint": "TigerVNC → noVNC; XFCE optional",
    "needTigerVnc": "TigerVNC required",
    "needXfceFirst": "Install XFCE first",
    "needSessionRunning": "Session is not running — start it first",
    "needNovnc": "noVNC required",
    "needXfce": "XFCE (optional)",
    "needViewer": "Viewer (optional)",
    "needViewerOrNovnc": "Viewer or noVNC",
    "settingsHint": "Defaults for new accounts",
    "settingsNeedStack": "These defaults apply when TigerVNC (and XFCE if selected) are installed. Install them on the Install tab first.",
    "clientNeedNovnc": "Open in browser needs noVNC. Install it on the Install tab before adding remotes you expect to open here.",
    "defaultDesktop": "Default desktop",
    "defaultGeometry": "Default resolution",
    "defaultDepth": "Colour depth",
    "defaultRfbBind": "VNC (RFB) listen range",
    "defaultAutostart": "Autostart sessions",
    "autostartLabel": "Start on boot",
    "settingsSaved": "VNC defaults saved",
    "tab": {
      "overview": "Overview",
      "accounts": "Accounts",
      "client": "Client",
      "install": "Install",
      "settings": "Settings",
      "about": "About"
    },
    "desktop": {
      "xfce": "XFCE (full desktop)",
      "terminal": "Terminal"
    },
    "bind": {
      "localhost": "Localhost only (noVNC / tunnel)",
      "all": "All interfaces (direct RFB — open firewall)",
      "localhostShort": "localhost",
      "allShort": "0.0.0.0"
    },
    "accountListTitle": "VNC accounts ({{count}})",
    "accountListDesc": "One Linux user per account",
    "createAccount": "+ Create account",
    "createAccountTitle": "Create VNC account",
    "createAccountDesc": "Dedicated yskvnc_* user",
    "createAccountBtn": "Create account",
    "editAccountTitle": "Edit VNC account",
    "editAccountDesc": "Linux user {{user}} · display :{{display}}",
    "setPassword": "Password",
    "setPasswordTitle": "Set VNC password",
    "setPasswordDesc": "Update VNC login password for {{address}}",
    "newPassword": "New password",
    "confirmPassword": "Confirm password",
    "passwordHint": "Min 6 chars",
    "passwordMismatch": "Passwords do not match",
    "passwordTooShort": "Password must be at least 6 characters",
    "needName": "Enter a display name",
    "start": "Start",
    "stop": "Stop",
    "startAfterCreate": "Start after create",
    "hostnameBroken": "This host cannot resolve its own hostname ({{hostname}}). Session start will fail.",
    "hostnameBrokenIdle": "No VNC sessions yet. Hostname {{hostname}} does not resolve — you can write /etc/hosts later if you create a session.",
    "hostnameFix": "Write hostname to /etc/hosts",
    "hostnameFixTitle": "Append this line to /etc/hosts?",
    "hostnameFixDesc": "{{line}}",
    "hostnameFixDone": "Hostname /etc/hosts updated",
    "startAfterCreateBlocked": "Disabled until the hostname resolves",
    "startHostnameBlocked": "Cannot start until this host can resolve its hostname. Use “Write hostname to /etc/hosts”.",
    "colName": "Name",
    "colLinuxUser": "Linux user",
    "colDisplay": "Display / port",
    "colStatus": "Status",
    "colDesktop": "Desktop",
    "colBind": "RFB bind",
    "accountStatus": {
      "running": "Running",
      "stopped": "Stopped",
      "failed": "Failed",
      "written": "Written",
      "unknown": "Unknown"
    },
    "clientStatus": {
      "up": "Connected",
      "down": "Disconnected",
      "unknown": "Unknown",
      "error": "Error",
      "viewing": "Viewing in browser"
    },
    "accountPager": "Account pages",
    "prevPage": "Previous",
    "nextPage": "Next",
    "pageOf": "Page {{page}} / {{total}} · {{count}}",
    "deleteAccountTitle": "Delete VNC account?",
    "deleteAccountDesc": "Remove control-plane account “{{name}}” (Linux user {{user}}). The VNC session for this display stops first.",
    "deleteAccountC1": "The VNC session for this account will be stopped first.",
    "deleteAccountC2": "The panel VNC account record will be removed.",
    "deleteAccountC3User": "The Linux user and home directory will also be removed. If the host refuses, the panel reports failure and the user stays.",
    "deleteAccountC3Keep": "The Linux user stays on the host; only the panel account is removed.",
    "removeLinuxUser": "Also remove Linux user and home directory",
    "deleteKeepUserWarn": "The Linux user will stay on the host as an orphan. You must clean it up later.",
    "bindRfbLine": "RFB {{bind}} :{{port}}",
    "bindNovncLine": "noVNC 127.0.0.1:{{port}}",
    "bindNovncHint": "noVNC listens on localhost. The desktop is reached through this panel, not the public internet, unless RFB bind is all interfaces.",
    "connection": "Connect",
    "connectionTitle": "Connection materials",
    "connectionDesc": "How clients reach {{name}}",
    "connectionPathsHint": "Prefer open in browser; advanced options for legacy noVNC / direct RFB",
    "connectionBrowserHint": "Recommended: open the desktop inside this panel (no SSH tunnel, works from any browser that can reach the panel).",
    "connectionBrowserDesc": "Starts the VNC session if needed and opens the in-panel viewer with keyboard, mouse, and clipboard.",
    "connectionAdvanced": "Advanced: legacy noVNC URL & direct RFB",
    "pathViaServer": "Via server (noVNC)",
    "pathViaServerLegacy": "Legacy noVNC on server (127.0.0.1)",
    "pathViaServerLegacyHint": "Only works on the server host or via SSH tunnel — prefer “Open in browser”.",
    "pathDirect": "Direct RFB",
    "recommended": "Recommended",
    "startNovnc": "Start noVNC",
    "stopNovnc": "Stop noVNC",
    "copyNovncUrl": "Copy noVNC URL",
    "copyAddress": "Copy host:port",
    "openFirewall": "Open UFW port",
    "directAddress": "Address",
    "ticketPath": "View ticket API",
    "directLocalhostWarn": "RFB is localhost-only",
    "copied": "Copied to clipboard",
    "clientListTitle": "Client profiles ({{count}})",
    "clientListDesc": "Outbound VNC",
    "addClient": "+ Add remote",
    "addClientTitle": "Add remote VNC",
    "addClientDesc": "Remote host:port",
    "clientTarget": "Target",
    "clientPath": "Connect path",
    "clientHost": "Remote host",
    "pathViaServerShort": "Browser",
    "pathDirectShort": "Host viewer",
    "disconnect": "Disconnect",
    "connect": "Connect",
    "clientNeedFields": "Name and host are required",
    "clientCreated": "Client profile created",
    "clientPasswordOptional": "VNC password (optional)",
    "clientPasswordHint": "Used when you open the browser viewer. Leave empty to type it each time.",
    "clientRememberPassword": "Store password on this server for next open",
    "clientRememberPasswordWarn": "Password is stored in panel dataDir (readable by root). Prefer typing each time on shared hosts.",
    "stackMissingShort": "Not installed",
    "editClientTitle": "Edit remote client",
    "editClientDesc": "Update path, hosts, and optional stored password.",
    "clientUpdated": "Client profile updated",
    "rememberNeedPassword": "Enter a password first."
  },
  "vpn": {
    "pageDesc": "VPN server & client",
    "eyebrow": "VPN",
    "tab": {
      "wireguard": "WireGuard",
      "openvpn": "OpenVPN",
      "outline": "Shadowsocks",
      "client": "Local client",
      "software": "Software",
      "monitor": "Monitor",
      "about": "About",
      "server": "Server",
      "install": "Install",
      "overview": "Overview"
    },
    "softwareIntro": "Install or update VPN engines here. Server tabs stay focused on config.",
    "monitor": {
      "needLive": "Live metrics need root + YSK_EXECUTE on the server.",
      "autoRefresh": "Auto 3s",
      "filterEngine": "Engine filter",
      "filterPresence": "Presence filter",
      "engineAll": "All engines",
      "presenceAll": "All",
      "presenceOnline": "Online",
      "presenceOffline": "Offline",
      "onlineOf": "Online {{online}} / {{total}}",
      "peersTitle": "Peers ({{count}})",
      "localTitle": "Local outbound",
      "colEndpoint": "Remote",
      "colLastSeen": "Last seen",
      "colRx": "↓ Total",
      "colTx": "↑ Total",
      "colRxRate": "↓ Rate",
      "colTxRate": "↑ Rate",
      "sampledAt": "Sampled {{when}}",
      "emptyPeers": "No peers to show",
      "emptyPeersHint": "Add peers on engine tabs, or clear filters",
      "presence": {
        "online": "Online",
        "idle": "Idle",
        "offline": "Offline",
        "never": "Never",
        "unknown": "Unknown"
      }
    },
    "installed": "Installed",
    "notInstalled": "Not installed",
    "serverUp": "Running",
    "serverDown": "Stopped",
    "engineSummary": "port {{port}} · {{peers}} peers",
    "engineSummaryClient": "{{count}} profiles · {{up}} up",
    "needWireGuard": "WireGuard required",
    "needOpenVpn": "OpenVPN required",
    "needSs": "ss-server required",
    "ssHonestUi": "ss:// access keys (not full Outline Manager)",
    "listenPort": "Listen port",
    "listenPortUdp": "Listen port (UDP)",
    "listenPortTcp": "Listen port (TCP)",
    "endpoint": "Public endpoint",
    "endpointHint": "Public host:port clients use to connect",
    "ddnsFill": "Use DDNS hostname",
    "ddnsFilled": "Filled endpoint host from DDNS. Peers are unchanged.",
    "ddnsFillEmpty": "No DDNS primary hostname yet. Add one on the DNS DDNS tab.",
    "ensureServer": "Apply server",
    "openFirewall": "Open {{port}}/{{proto}}",
    "presets": "Port presets",
    "portHint": {
      "51820": "Default WireGuard listen port",
      "51821": "Alternate WireGuard listen port",
      "51822": "Second alternate WireGuard listen port"
    },
    "proto": "Protocol",
    "protoUdp": "UDP",
    "protoTcp": "TCP",
    "statusLine": "{{state}} · {{port}}/{{proto}} · {{peers}} peers",
    "peersTitle": "Peers / keys",
    "peersTitleWg": "Peers",
    "peersTitleOvpn": "Client configs",
    "peersTitleSs": "Access keys",
    "peerName": "Name",
    "peerNamePlaceholder": "office-laptop",
    "peerNameHint": "Letters, digits, . _ - — no spaces, / or !",
    "peerNameInvalid": "Spaces, / and ! are not allowed. Use {{preview}} or change the name.",
    "addPeer": "+ Add",
    "installEngineFirst": "Install the VPN engine first",
    "needServerRunning": "{{engine}} is not running — apply the server first",
    "engineSummarySoftware": "{{installed}} installed · {{running}} running",
    "privateKeyOnce": "The client private key is shown only here. Download or copy it now — it cannot be recovered later.",
    "showPrivateKey": "Show private key",
    "hidePrivateKey": "Hide private key",
    "deletePeerTitle": "Delete peer {{name}}?",
    "deletePeerDesc": "Remove {{name}} ({{address}}). The client disconnects immediately and the config cannot be restored. The WireGuard server stays up.",
    "deleteClientTitle": "Delete OpenVPN client {{name}}?",
    "deleteClientDesc": "Remove {{name}} ({{address}}). The client disconnects immediately and the profile cannot be restored. The OpenVPN server stays up.",
    "deleteKeyTitle": "Delete Shadowsocks key {{name}}?",
    "deleteKeyDesc": "Remove access key {{name}} ({{address}}). Clients using this key disconnect. The Shadowsocks server stays up.",
    "deleteResult": "Removed {{name}}.",
    "portInvalid": "Listen port must be an integer from 1 to 65535.",
    "portRequired": "Listen port is required.",
    "importInvalid": "Could not detect a WireGuard or OpenVPN client conf.",
    "qrFailed": "Could not generate a QR code for this config. Download or copy the text instead.",
    "cfgTitle": "Config — {{name}}",
    "addPeerWg": "+ Add peer",
    "addPeerOvpn": "+ Add client",
    "addPeerSs": "+ Add key",
    "noPeers": "None yet",
    "noPeersHint": "Add one to download config",
    "colName": "Name",
    "colAddress": "Address",
    "colCreated": "Created",
    "colActions": "Actions",
    "colEngine": "Engine",
    "colStatus": "Status",
    "colIface": "Interface",
    "downloadKey": "Download",
    "showQr": "QR",
    "copyConf": "Copy",
    "copied": "Copied",
    "downloaded": "Config downloaded",
    "qrReady": "QR ready",
    "qrTitle": "QR — {{name}}",
    "qrHintWg": "Scan in WireGuard app",
    "qrHintSs": "Scan ss:// in a Shadowsocks client",
    "showConf": "Config text",
    "close": "Close",
    "clientIntro": "Import a conf file to connect this host out",
    "profileName": "Profile name",
    "pasteConf": "Paste conf",
    "importProfile": "Import",
    "importOpen": "+ Import conf",
    "noProfiles": "No local profiles",
    "noProfilesHint": "Import WireGuard or OpenVPN client conf",
    "connect": "Connect",
    "disconnect": "Disconnect",
    "clientStatus": {
      "up": "Connected",
      "down": "Disconnected",
      "unknown": "Unknown",
      "error": "Error"
    },
    "result": "Result",
    "clientEngine": "Type",
    "engineAuto": "Auto-detect",
    "refresh": "Refresh",
    "dnsOptional": "DNS (optional)",
    "serverSettings": "Server settings",
    "access": {
      "label": "Client traffic",
      "full": "Full internet",
      "lan": "LAN only",
      "custom": "Custom routes",
      "fullHint": "All client traffic goes via this server (enables NAT). Reconnect clients after apply.",
      "lanHint": "Only VPN + selected private nets; client keeps its own internet. Reconnect after apply.",
      "customHint": "Only the CIDRs you list enter the tunnel. Reconnect after apply.",
      "lanCidrs": "LAN networks",
      "customCidr": "CIDR",
      "addCidr": "Add",
      "cidrRequired": "Enter a CIDR (for example 192.168.1.0/24).",
      "cidrInvalid": "Enter a valid CIDR, for example 192.168.1.0/24."
    },
    "engineNotInstalled": "This VPN engine is not installed on the host.",
    "serverNotListening": "Server unit is not active. UDP/TCP {{port}} may be closed."
  }
}
