import officialJson from "../data/official-locales.json" with { type: "json" };
import { displayName } from "./factorio-data.ts";
import type { ItemGroupId, Locale, QualityId } from "./types.ts";

type Sections = Record<string, Record<string, string>>;
const official = officialJson as Record<Locale, Sections>;

export const LOCALE_OPTIONS: Array<{ id: Locale; label: string }> = [
  { id: "en", label: "English" },
  { id: "de", label: "Deutsch" },
  { id: "es-ES", label: "Español" },
  { id: "fr", label: "Français" },
  { id: "it", label: "Italiano" },
  { id: "ja", label: "日本語" },
  { id: "ru", label: "Русский" },
  { id: "zh-CN", label: "简体中文" },
  { id: "zh-TW", label: "繁體中文" },
];

const en = {
  title: "Factorio Production Calculator",
  subtitle: "Product-first · official 2.1.17 data · offline-ready",
  production: "Production",
  quality: "Quality",
  science: "Science",
  energy: "Energy",
  help: "Help",
  recycling: "Recycling",
  qualityRecycling: "Quality recycling",
  language: "Language",
  productRoute: "Product & route",
  product: "Product",
  recipeRoute: "Recipe route",
  productionMachine: "Production machine",
  targetRate: "Target rate",
  amount: "Amount",
  unit: "Unit",
  desiredOutput: "Desired output",
  inputLimited: "Input-limited",
  targetQuality: "Target quality",
  ingredientQuality: "Ingredient quality",
  machineQuality: "Machine quality",
  maximumQuality: "Maximum researched quality",
  modules: "Modules",
  machineModules: "Machine modules",
  beaconModules: "Beacon modules",
  beacons: "Beacons",
  enabled: "Enabled",
  disabled: "Disabled",
  activePerMachine: "Active per machine",
  beaconQuality: "Beacon quality",
  automatic: "Automatic",
  manual: "Manual",
  tier: "Tier",
  moduleQuality: "Module quality",
  slots: "slots",
  addProduct: "Add product",
  remove: "Remove",
  allQualities: "All qualities",
  selectProduct: "Select a product",
  searchProducts: "Search products and fluids…",
  noMatch: "No matching product.",
  available: "available",
  route: "Route",
  machine: "Machine",
  ingredients: "Ingredients",
  outputs: "Outputs",
  machinesRequired: "Machines required",
  theoretical: "theoretical",
  build: "build",
  utilization: "Utilization",
  power: "Power",
  directPower: "Direct setup",
  chainPower: "Upstream chain",
  includeEnergy: "Include in Energy calculator",
  productionChain: "Production chain",
  chainMaster: "Chain-wide setup",
  applyEntireChain: "Applied to every upstream recipe unless a node override is set.",
  globalChainMaster: "All-products chain-wide setup",
  applyAllActiveChains:
    "Changes overwrite that setting in every active product chain; later local changes remain local.",
  subprocessMachines: "Machines by sub-process",
  subprocessMachineHint:
    "Choose the recipe and machine used for each repeated upstream product.",
  machineResearchAndPriority: "Research status & automatic machine hierarchy",
  machineResearchAndPriorityHint:
    "Only enabled machines are used automatically. The first compatible machine in each recipe family wins.",
  unlockedMachines: "Unlocked machines",
  machineHierarchy: "Priority by recipe family",
  machineGroupCrafting: "Assembly & electronics",
  machineGroupSmelting: "Smelting & metallurgy",
  machineGroupFluids: "Fluids & chemistry",
  machineGroupBiology: "Biological production",
  machineGroupProcessing: "Special processing",
  movePriorityUp: "Move up in priority",
  movePriorityDown: "Move down in priority",
  machinePriority: "Preferred machine",
  miningDrill: "Raw-resource mining drill",
  miningDrillHint:
    "Sizes mineable raw-resource sources with this drill. If it cannot mine a resource, the next capable drill is used.",
  miningAndRawQuality: "Mining & raw-resource quality",
  miningModules: "Mining-drill modules",
  qualityMiningHint:
    "Quality chains begin at extraction: the selected modules fill every available mining-drill slot and their expected quality output feeds all upstream recipes.",
  miningQualityChance: "Quality chance",
  occupiedSlots: "occupied slots",
  slotsPerBeacon: "slots per beacon",
  modulePriority: "Module priority",
  showChain: "Show full production chain",
  hideChain: "Hide production chain",
  includeProductionChain: "Include full production chain",
  includeProductionChainHint:
    "On by default; disable to use only this recipe's direct ingredients.",
  nodeSetup: "Recipe & machine",
  nodeModules: "Modules & beacons",
  rawSource: "Raw source",
  logistics: "Machine logistics",
  inserter: "Inserter",
  inserterQuality: "Inserter quality",
  capacityResearch: "Capacity research",
  handoff: "Handoff",
  chainInserterHint:
    "Default inserter setup for every upstream production machine.",
  inputLoad: "Input load",
  outputLoad: "Output load",
  perMachine: "per machine",
  insertersRequired: "Required inserters",
  geometryCheck: "Geometry check",
  beaconDesign: "Beacon design",
  zoom: "Zoom",
  actualSpm: "Actual science rate",
  effectiveSpm: "Effective science rate",
  scienceSupplyMode: "Supplied science packs",
  scienceTargetMode: "Target effective research",
  researchPerPack: "Research per supplied pack",
  perLab: "per lab",
  scienceSpeedNote:
    "Speed modules, beacons and lab quality change processing capacity and therefore the required lab count. They do not create more research from a fixed pack stream; pack quality, productivity and the Biolab's 50% drain do.",
  lab: "Lab",
  biolab: "Biolab",
  labType: "Research building",
  packQuality: "Science pack quality",
  beaconsOff: "Beacons off",
  forcedRing: "Full 16-beacon ring",
  manualMw: "Manual demand",
  importedLoads: "Selected calculator loads",
  targetDemand: "Target demand",
  reserve: "Reserve",
  technology: "Power technology",
  planet: "Planet / orbit",
  steam: "Steam power",
  solar: "Solar & accumulators",
  nuclear: "Nuclear power",
  heatingTower: "Heating tower",
  fusion: "Fusion power",
  demandSizing: "Size for demand",
  fixedBlock: "Inspect fixed reactor block",
  reactorBlock: "Reactors per block",
  grossOutput: "Gross output",
  netOutput: "Net supported output",
  internalDemand: "Internal demand",
  entities: "Entities",
  fuelAndFluids: "Fuel & fluids",
  recycleProduct: "Product to recycle",
  recyclerQuality: "Recycler quality",
  expectedOutputs: "Expected returns",
  recycleTime: "Recycle time",
  throughput: "Throughput",
  lostFluids: "Fluid ingredients lost",
  warnings: "Notes & warnings",
  noQualityFluids: "Fluids themselves cannot have quality.",
  normalModeQualityNotice:
    "Manual quality modules affect speed and power here. Open Quality Production to see quality output splitting.",
  qualitySafeBeacon:
    "Quality default limits speed support to one beacon with one occupied slot because speed effects reduce quality. Manual controls can override it.",
  qualityBeaconMode: "Quality-safe · 1 beacon / 1 slot",
  passiveSpoilage: "Passive spoilage",
  clickIngredient: "Calculate this ingredient",
  reset: "Reset setup",
  addInput: "Add input constraint",
  fluid: "Fluid",
  item: "Item",
  recipeCount: "player recipes",
  productCount: "products",
  fullChain: "Full chain",
  actual: "Actual",
  effective: "Effective",
  imported: "Imported",
  sourceSelection: "Energy load selection",
  normalQuality: "Normal production",
  qualityProduction: "Quality production",
  invalidSetup: "This setup cannot be calculated",
  craftingSpeed: "Crafting speed",
  width: "Width",
  height: "Height",
  blocks: "blocks",
  previewCapped: "The preview is limited; totals include every machine.",
  solidRecycleReturn:
    "Expected return is 25% of solid recipe ingredients; fluid ingredients are destroyed.",
  steamFuelNote:
    "Fuel demand uses coal at 4 MJ/item; other fuels scale by energy value.",
  solarAverageNote:
    "The displayed result is sustained average power; peak output is higher.",
  solarScalingNote:
    "Solar intensity and quality are applied before day/night averaging.",
  nuclearNeighborNote:
    "Each cardinally adjacent fueled reactor adds 100% of its base heat output.",
  heatingEfficiencyNote:
    "A normal heating tower turns 16 MW of fuel into 40 MW of heat at 250% efficiency.",
  fusionDemandNote: "Fusion-cell consumption follows actual grid demand.",
  fusionCoolantNote:
    "Cold fluoroketone is a closed-loop circulation rate, not continuous consumption.",
  rocket: "Rocket freight",
  currentProducts: "Current products",
  moveProductToTop: "Move this product and its results to the top",
  noProductSelected: "No product selected yet",
  resetCurrent: "Reset this calculator",
  clickMaterial: "Use this material as the current target",
  optimizedLayout: "Optimized shared layout",
  manualBeaconLayout: "Manual beacon selection",
  energyBlueprint: "Compact ratio blueprint",
  orientation: "Orientation & setup",
  reactorGrid: "Reactor grid",
  neighborLinks: "Cardinal neighbour links",
  rocketCargo: "Rocket cargo",
  sourcePlanet: "Origin",
  destinationPlanet: "Destination",
  cargoPerTransit: "Cargo per transit",
  rocketCapacity: "Rocket capacity",
  launchesPerTransit: "Launches per transit",
  rocketPartResearch: "Rocket-part productivity research",
  platformSpeed: "Platform speed",
  manualSpeed: "Manual speed",
  deriveFromThrusters: "Derive from thrusters",
  thrusterCount: "Thrusters",
  thrusterQuality: "Thruster quality",
  throttle: "Thruster fluid level",
  platformMass: "Platform mass",
  platformWidth: "Platform width",
  cargoBays: "Cargo bays",
  cargoBayQuality: "Cargo bay quality",
  flightTime: "One-way flight",
  roundTrip: "Round trip",
  loadingTime: "Rocket loading",
  landingTime: "Cargo landing",
  platformsRequired: "Freight platforms",
  sustainedSilos: "Sustained silos",
  waveSilos: "Preloaded wave silos",
  rocketParts: "Rocket-part materials",
  launchesPerMinute: "Launches per minute",
  landingWaves: "Landing waves",
  tiles: "tiles",
  rocketSelectionError:
    "Select a launchable item and two different connected locations.",
  rocketSilosToPlace: "Rocket silos to place",
  siloLoading: "Silo cargo loading",
  logisticRobots: "Logistic robots",
  inserters: "Inserters",
  ignoreInsertion: "Ignore insertion",
  experimental: "Experimental",
  experimentalInserterLoading:
    "Experimental: one inserter loads each silo through the bottom-centre tile. That tile cannot hold a beacon, so the physical maximum is 15.",
  experimentalRobotLoading:
    "Experimental: each silo uses a full Buffer chest, one inserter and the displayed local Roboport. Robot flight is estimated only for this compact local leg; the physical maximum is 15 beacons.",
  ignoreInsertionWarning:
    "Insertion is ignored. Rockets are assumed to be filled instantaneously or preloaded; chest, inserter and robot time and power are excluded. This permits the full 16-beacon ring.",
  logisticRobotCount: "Robots in each Roboport",
  workerRobotSpeedResearch: "Robot speed research",
  workerRobotCargoResearch: "Robot cargo research",
  robotFlightTime: "One-way robot flight",
  robotSupplyTime: "Robot chest supply",
  bufferChestAssumption:
    "Experimental assumption: every displayed Buffer chest starts full. Robot timing covers only the local Roboport-to-chest leg; remote provider travel, congestion and charging queues are excluded.",
  payloadInsertion: "Payload insertion time",
  inserterThroughput: "Inserter throughput",
  siloCycle: "Effective silo cycle",
  steamConsumer: "Steam generator",
  highTemperatureLoss:
    "Steam engines accept 500 °C steam but waste the energy above 165 °C; the calculator applies that conversion loss.",
  downstreamProducts: "Products using this material",
  chooseNextProduct: "Choose the next product",
  targetReturn: "Target recycled material",
  desiredQualityOutput: "Desired target-quality output",
  thrusterEstimateNotice:
    "Thruster travel uses the official thrust and drag formula as a steady-state estimate; asteroid slowdowns are not included.",
  preloadedNotice:
    "Optimal loading assumes every launch rocket is built and preloaded before the platform arrives.",
  rocketPayloadBottleneck:
    "Payload-wave bottleneck: one preloaded silo is required per rocket in the cargo batch. Faster silos, modules or beacons therefore cannot reduce the placement count at this setting.",
  payloadWaveTitle: "The cargo batch—not silo speed—sets this build count",
  payloadWaveExplanation:
    "All rockets in one arriving platform batch must be ready together, so one preloaded silo is reserved per rocket. Faster silos only reduce the displayed count when sustained launch throughput becomes the larger requirement, or when cargo per transit is reduced.",
  cargoStorageBottleneck:
    "Platform storage bottleneck: the selected Cargo bays cannot hold the requested batch, so more freight platforms are needed. Cargo bays needed for the requested batch:",
  flightCalculation: "Flight calculation",
  launchCalculation: "Loading & silo calculation",
  inventoryTabs: "Recipe categories",
  minutes: "minutes",
  seconds: "seconds",
  path: "Route",
  energyLayoutNote:
    "The drawing uses the ideal entity ratio for the selected planet, quality, generator and block size; calculated totals may contain several copies.",
  factoryTotals: "All-production totals",
  factoryTotalsHint:
    "Shared resources are merged; each process still shows the machines assigned to every product chain.",
  combinedResources: "Combined resource demand",
  productionProcesses: "Production processes & machines",
  directInputs: "Direct ingredients",
  collapseProductResult: "Collapse this product",
  expandProductResult: "Expand this product",
  allChainsGenerated:
    "Every selected product uses its full upstream chain by default. Disable the chain beside an individual product to exclude it.",
  beltThroughput: "Belt throughput",
  beltThroughputHint:
    "Equivalent and whole belts for every solid item stream in the selected productions.",
  beltType: "Transport belt",
  beltStacking: "Belt stack size",
  unstacked: "Unstacked",
  stackInserterLevel: "Stack inserter researched",
  beltCapacityOne: "Transport belt capacity 1",
  beltCapacityTwo: "Transport belt capacity 2",
  splitSharedStreams: "Separate shared materials by product",
  splitSharedStreamsHint:
    "On: each top-level product receives its own stream. Off: shared material demand is combined.",
  beltCapacity: "Belt capacity",
  beltEquivalents: "Filled belts",
  beltsRequired: "Belts required",
  lastBeltLoad: "Last belt load",
  combinedStream: "Combined stream",
  totalBeltLoad: "total capacity used",
  insertersPerMachine: "Inserters per machine",
  inShort: "In",
  outShort: "Out",
  inputs: "Inputs",
  constructionSummary: "Complete construction bill",
  constructionSummaryHint:
    "Everything to place for the selected products and their enabled production chains.",
  buildKindSource: "Extraction & supply",
  buildKindMachine: "Production machine",
  buildKindModule: "Modules",
  buildKindBeacon: "Beacons",
  buildKindInserter: "Inserters",
  steamOrientation:
    "The preview groups the boiler row and the selected steam generators and shows their selected ratio; connect water and steam in game.",
  solarOrientation:
    "The panel and accumulator rows use the selected planet and quality ratio; neither entity has directional ports.",
  nuclearOrientation:
    "Reactors retain their cardinal grid; Heat exchangers and the selected generators are grouped upright in rows.",
  heatingOrientation:
    "The Heating tower, Heat exchangers and selected generators are grouped upright in rows using the selected ratio.",
  fusionOrientation:
    "Reactors retain the neighbour pattern; Fusion generators and Cryogenic plants are grouped upright in rows. Plasma and fluid connections are intentionally omitted.",
};

const v4Translations: Record<Locale, Partial<Record<UiKey, string>>> = {
  en: {
    actualSpm: "Supplied science packs",
  },
  de: {
    chainMaster: "Kettenweite Konfiguration", applyEntireChain: "Gilt für jedes vorgelagerte Rezept, sofern der Knoten nicht einzeln überschrieben wird.", machinePriority: "Bevorzugte Maschine", modulePriority: "Modulpriorität",
    rocketPayloadBottleneck: "Nutzlast-Wellenlimit: Für jede Rakete der Frachtcharge wird ein vorgeladenes Silo benötigt. Schnellere Silos, Module oder Effektverteiler verringern die Bauzahl bei dieser Einstellung daher nicht.", cargoStorageBottleneck: "Plattform-Speicherlimit: Die gewählten Frachträume fassen die gewünschte Charge nicht, daher werden mehr Frachter benötigt. Benötigte Frachträume für die gewünschte Charge:", flightCalculation: "Flugzeitberechnung", launchCalculation: "Beladungs- & Siloberechnung", inventoryTabs: "Rezeptkategorien",
    actualSpm: "Zugeführte Forschungspakete", effectiveSpm: "Effektive Forschungsrate", scienceSupplyMode: "Zugeführte Forschungspakete", scienceTargetMode: "Gewünschte effektive Forschung", researchPerPack: "Forschungswert je zugeführtem Paket", perLab: "je Labor", scienceSpeedNote: "Geschwindigkeitsmodule, Effektverteiler und Laborqualität verändern die Verarbeitungskapazität und damit die benötigte Laborzahl. Aus einem festen Paketstrom erzeugen sie nicht mehr Forschung; Paketqualität, Produktivität und der 50-%-Verbrauch des Biolabs tun dies.",
    rocketSilosToPlace: "Zu platzierende Raketensilos", siloLoading: "Silofracht-Beladung", logisticRobots: "Logistikroboter", inserters: "Greifarme", experimental: "Experimentell",
    experimentalInserterLoading: "Experimentell: Ein Greifarm belädt jedes Silo über das mittlere Feld der unteren Reihe. Dort kann kein Effektverteiler stehen; das physische Maximum sinkt deshalb auf 15.",
    payloadInsertion: "Fracht-Einsetzzeit", inserterThroughput: "Greifarmdurchsatz", siloCycle: "Effektiver Silozyklus", steamConsumer: "Dampfgenerator",
    highTemperatureLoss: "Dampfmaschinen nehmen 500-°C-Dampf an, verschwenden aber die Energie oberhalb von 165 °C; dieser Umwandlungsverlust wird eingerechnet.",
    downstreamProducts: "Produkte mit diesem Material", chooseNextProduct: "Nächstes Produkt auswählen", targetReturn: "Zielmaterial der Wiederverwertung", desiredQualityOutput: "Gewünschter Output in Zielqualität",
    rocket: "Raketenfracht", currentProducts: "Aktuelle Produkte", noProductSelected: "Noch kein Produkt ausgewählt",
    resetCurrent: "Diesen Rechner zurücksetzen",
    clickMaterial: "Dieses Material als aktuelles Ziel übernehmen", optimizedLayout: "Optimierte geteilte Anordnung", manualBeaconLayout: "Manuelle Effektverteilerauswahl",
    energyBlueprint: "Kompakter Verhältnis-Bauplan", orientation: "Ausrichtung & Aufbau", reactorGrid: "Reaktorblock", neighborLinks: "Direkte Nachbarschaften",
    rocketCargo: "Raketenfracht", sourcePlanet: "Startplanet", destinationPlanet: "Zielplanet", cargoPerTransit: "Fracht je Umlauf", rocketCapacity: "Raketenkapazität",
    launchesPerTransit: "Starts je Umlauf", rocketPartResearch: "Forschung: Raketenbauteil-Produktivität", platformSpeed: "Plattformgeschwindigkeit", manualSpeed: "Manuelle Geschwindigkeit",
    deriveFromThrusters: "Aus Triebwerken berechnen", thrusterCount: "Triebwerke", thrusterQuality: "Triebwerksqualität", throttle: "Triebwerksfüllstand",
    platformMass: "Plattformmasse", platformWidth: "Plattformbreite", cargoBays: "Frachträume", flightTime: "Einfacher Flug", roundTrip: "Hin- und Rückflug",
    loadingTime: "Raketenbeladung", landingTime: "Frachtlandung", platformsRequired: "Benötigte Frachter", sustainedSilos: "Silobetrieb dauerhaft",
    waveSilos: "Vorgeladene Silos", rocketParts: "Material für Raketenbauteile", preloadedNotice: "Die optimale Beladung setzt voraus, dass bei Ankunft der Plattform alle Raketen fertig gebaut und vorgeladen sind.",
    launchesPerMinute: "Starts pro Minute", landingWaves: "Landewellen", tiles: "Felder", rocketSelectionError: "Wähle einen transportierbaren Gegenstand und zwei unterschiedliche verbundene Orte.",
    thrusterEstimateNotice: "Die Flugzeit nutzt die offizielle Schub- und Widerstandsformel als stationäre Schätzung; Verzögerungen durch Asteroiden sind nicht enthalten.",
    minutes: "Minuten", seconds: "Sekunden", path: "Route", energyLayoutNote: "Die Zeichnung verwendet das ideale Maschinenverhältnis für den gewählten Planeten, die Qualität, den Dampfgenerator und die Blockgröße; die berechneten Summen können mehrere Blöcke enthalten.",
  },
  "es-ES": {
    chainMaster: "Configuración de toda la cadena", applyEntireChain: "Se aplica a todas las recetas anteriores salvo que un nodo tenga una configuración propia.", machinePriority: "Máquina preferida", modulePriority: "Prioridad de módulos",
    rocketPayloadBottleneck: "Límite por oleada de carga: se necesita un silo precargado por cada cohete del lote. En esta configuración, silos, módulos o faros más rápidos no reducen el número a construir.", cargoStorageBottleneck: "Límite de almacenamiento de la plataforma: las bahías seleccionadas no admiten el lote solicitado, por lo que se necesitan más plataformas. Bahías necesarias para el lote:", flightCalculation: "Cálculo de vuelo", launchCalculation: "Cálculo de carga y silos", inventoryTabs: "Categorías de recetas",
    actualSpm: "Paquetes científicos suministrados", effectiveSpm: "Tasa de investigación efectiva", scienceSupplyMode: "Paquetes científicos suministrados", scienceTargetMode: "Investigación efectiva objetivo", researchPerPack: "Investigación por paquete suministrado", perLab: "por laboratorio", scienceSpeedNote: "Los módulos de velocidad, los faros y la calidad del laboratorio cambian la capacidad de procesamiento y, por tanto, el número de laboratorios. No crean más investigación a partir de un flujo fijo de paquetes; sí lo hacen la calidad del paquete, la productividad y el consumo del 50 % del biolaboratorio.",
    rocketSilosToPlace: "Silos de cohete que colocar", siloLoading: "Carga del silo", logisticRobots: "Robots logísticos", inserters: "Brazos insertadores", experimental: "Experimental",
    experimentalInserterLoading: "Experimental: un brazo insertador carga cada silo por la casilla central inferior. Esa casilla no puede alojar un faro, por lo que el máximo físico baja a 15.",
    payloadInsertion: "Tiempo de inserción de carga", inserterThroughput: "Rendimiento del brazo", siloCycle: "Ciclo efectivo del silo", steamConsumer: "Generador de vapor",
    highTemperatureLoss: "Las máquinas de vapor aceptan vapor a 500 °C, pero desperdician la energía por encima de 165 °C; la calculadora aplica esta pérdida.",
    downstreamProducts: "Productos que usan este material", chooseNextProduct: "Elegir el producto siguiente", targetReturn: "Material reciclado objetivo", desiredQualityOutput: "Producción deseada de la calidad objetivo",
    rocket: "Carga por cohete", currentProducts: "Productos actuales", noProductSelected: "Aún no hay ningún producto seleccionado",
    resetCurrent: "Restablecer esta calculadora",
    clickMaterial: "Usar este material como objetivo actual", optimizedLayout: "Diseño compartido optimizado", manualBeaconLayout: "Selección manual de faros",
    energyBlueprint: "Plano compacto de proporciones", orientation: "Orientación y montaje", reactorGrid: "Matriz de reactores", neighborLinks: "Enlaces vecinos cardinales",
    rocketCargo: "Carga de cohete", sourcePlanet: "Origen", destinationPlanet: "Destino", cargoPerTransit: "Carga por viaje", rocketCapacity: "Capacidad del cohete",
    launchesPerTransit: "Lanzamientos por viaje", rocketPartResearch: "Investigación de productividad de piezas de cohete", platformSpeed: "Velocidad de la plataforma", manualSpeed: "Velocidad manual",
    deriveFromThrusters: "Calcular desde propulsores", thrusterCount: "Propulsores", thrusterQuality: "Calidad del propulsor", throttle: "Nivel de fluido del propulsor",
    platformMass: "Masa de la plataforma", platformWidth: "Anchura de la plataforma", cargoBays: "Bahías de carga", flightTime: "Vuelo de ida", roundTrip: "Ida y vuelta",
    loadingTime: "Carga de cohetes", landingTime: "Aterrizaje de carga", platformsRequired: "Plataformas de carga", sustainedSilos: "Silos sostenidos",
    waveSilos: "Silos precargados", rocketParts: "Materiales de piezas de cohete", preloadedNotice: "La carga óptima supone que todos los cohetes necesarios ya están construidos y cargados al llegar la plataforma.",
    launchesPerMinute: "Lanzamientos por minuto", landingWaves: "Oleadas de aterrizaje", tiles: "casillas", rocketSelectionError: "Selecciona un objeto transportable y dos ubicaciones conectadas diferentes.",
    thrusterEstimateNotice: "El viaje usa la fórmula oficial de empuje y resistencia como estimación de régimen estable; no incluye ralentizaciones por asteroides.",
    minutes: "minutos", seconds: "segundos", path: "Ruta", energyLayoutNote: "El dibujo usa la proporción ideal de entidades para el planeta, la calidad, el generador y el tamaño de bloque seleccionados; los totales pueden contener varias copias.",
    steamOrientation: "La vista agrupa la fila de calderas y los generadores de vapor seleccionados y muestra su proporción; conecta el agua y el vapor en el juego.", solarOrientation: "Las filas de paneles y acumuladores usan la proporción del planeta y la calidad seleccionados; ninguna entidad tiene orientación.",
    nuclearOrientation: "Los reactores conservan su cuadrícula cardinal; los intercambiadores y los generadores seleccionados aparecen erguidos y agrupados en filas.", heatingOrientation: "La torre, los intercambiadores y los generadores seleccionados aparecen erguidos y agrupados en filas con la proporción elegida.",
    fusionOrientation: "Los reactores conservan el patrón de vecindad; los generadores y las plantas criogénicas aparecen erguidos y agrupados en filas. Se omiten las conexiones de plasma y fluidos.",
  },
  fr: {
    chainMaster: "Configuration de toute la chaîne", applyEntireChain: "S’applique à chaque recette en amont sauf si un nœud possède son propre réglage.", machinePriority: "Machine préférée", modulePriority: "Priorité des modules",
    rocketPayloadBottleneck: "Limite de vague de fret : un silo préchargé est requis par fusée du lot. Des silos, modules ou diffuseurs plus rapides ne réduisent donc pas le nombre à construire avec ce réglage.", cargoStorageBottleneck: "Limite de stockage de la plateforme : les baies sélectionnées ne contiennent pas le lot demandé, donc davantage de plateformes sont nécessaires. Baies requises pour le lot :", flightCalculation: "Calcul du vol", launchCalculation: "Calcul du chargement et des silos", inventoryTabs: "Catégories de recettes",
    actualSpm: "Packs de science fournis", effectiveSpm: "Débit de recherche effectif", scienceSupplyMode: "Packs de science fournis", scienceTargetMode: "Recherche effective visée", researchPerPack: "Recherche par pack fourni", perLab: "par laboratoire", scienceSpeedNote: "Les modules de vitesse, les diffuseurs et la qualité du laboratoire modifient la capacité de traitement et donc le nombre de laboratoires requis. Ils ne créent pas davantage de recherche à partir d’un flux fixe de packs ; la qualité des packs, la productivité et la consommation de 50 % du biolaboratoire le font.",
    rocketSilosToPlace: "Silos à fusée à placer", siloLoading: "Chargement du silo", logisticRobots: "Robots logistiques", inserters: "Bras robotisés", experimental: "Expérimental",
    experimentalInserterLoading: "Expérimental : un bras charge chaque silo par la case centrale inférieure. Cette case ne peut pas recevoir de diffuseur, donc le maximum physique passe à 15.",
    payloadInsertion: "Temps d’insertion du fret", inserterThroughput: "Débit du bras", siloCycle: "Cycle effectif du silo", steamConsumer: "Générateur à vapeur",
    highTemperatureLoss: "Les machines à vapeur acceptent la vapeur à 500 °C mais gaspillent l’énergie au-dessus de 165 °C ; ce rendement réduit est pris en compte.",
    downstreamProducts: "Produits utilisant ce matériau", chooseNextProduct: "Choisir le produit suivant", targetReturn: "Matériau recyclé cible", desiredQualityOutput: "Production souhaitée à la qualité cible",
    rocket: "Fret par fusée", currentProducts: "Produits actuels", noProductSelected: "Aucun produit sélectionné",
    resetCurrent: "Réinitialiser ce calculateur",
    clickMaterial: "Utiliser ce matériau comme cible actuelle", optimizedLayout: "Disposition partagée optimisée", manualBeaconLayout: "Sélection manuelle des diffuseurs",
    energyBlueprint: "Plan de ratio compact", orientation: "Orientation et montage", reactorGrid: "Grille de réacteurs", neighborLinks: "Liaisons cardinales",
    rocketCargo: "Fret de fusée", sourcePlanet: "Origine", destinationPlanet: "Destination", cargoPerTransit: "Fret par trajet", rocketCapacity: "Capacité de la fusée",
    launchesPerTransit: "Lancements par trajet", rocketPartResearch: "Recherche de productivité des éléments de fusée", platformSpeed: "Vitesse de la plateforme", manualSpeed: "Vitesse manuelle",
    deriveFromThrusters: "Calculer depuis les propulseurs", thrusterCount: "Propulseurs", thrusterQuality: "Qualité des propulseurs", throttle: "Niveau de fluide des propulseurs",
    platformMass: "Masse de la plateforme", platformWidth: "Largeur de la plateforme", cargoBays: "Baies de fret", flightTime: "Vol aller", roundTrip: "Aller-retour",
    loadingTime: "Chargement des fusées", landingTime: "Atterrissage du fret", platformsRequired: "Plateformes de fret", sustainedSilos: "Silos en continu",
    waveSilos: "Silos préchargés", rocketParts: "Matériaux des éléments de fusée", preloadedNotice: "Le chargement optimal suppose que toutes les fusées requises sont construites et préchargées avant l’arrivée de la plateforme.",
    launchesPerMinute: "Lancements par minute", landingWaves: "Vagues d’atterrissage", tiles: "cases", rocketSelectionError: "Sélectionnez un objet transportable et deux lieux connectés différents.",
    thrusterEstimateNotice: "Le trajet utilise la formule officielle de poussée et de traînée comme estimation en régime établi ; les ralentissements dus aux astéroïdes ne sont pas inclus.",
    minutes: "minutes", seconds: "secondes", path: "Trajet", energyLayoutNote: "Le dessin utilise le ratio idéal d’entités pour la planète, la qualité, le générateur et la taille de bloc sélectionnés ; les totaux peuvent contenir plusieurs blocs.",
    steamOrientation: "L’aperçu regroupe la rangée de chaudières et les générateurs de vapeur sélectionnés et montre leur ratio ; raccordez l’eau et la vapeur en jeu.", solarOrientation: "Les rangées de panneaux et d’accumulateurs utilisent le ratio de la planète et de la qualité sélectionnées ; ces entités n’ont pas d’orientation.",
    nuclearOrientation: "Les réacteurs conservent leur grille cardinale ; les échangeurs et les générateurs sélectionnés sont regroupés debout en rangées.", heatingOrientation: "La tour, les échangeurs et les générateurs sélectionnés sont regroupés debout en rangées selon le ratio choisi.",
    fusionOrientation: "Les réacteurs conservent leur motif de voisinage ; générateurs et usines cryogéniques sont regroupés debout en rangées. Les connexions de plasma et de fluides sont omises.",
  },
  it: {
    chainMaster: "Configurazione dell’intera catena", applyEntireChain: "Si applica a ogni ricetta a monte, salvo una configurazione specifica del nodo.", machinePriority: "Macchina preferita", modulePriority: "Priorità dei moduli",
    rocketPayloadBottleneck: "Limite dell’ondata di carico: serve un silo precaricato per ogni razzo del lotto. Con questa impostazione, silos, moduli o fari più veloci non riducono il numero da costruire.", cargoStorageBottleneck: "Limite di stoccaggio della piattaforma: i vani selezionati non contengono il carico richiesto, quindi servono più piattaforme. Vani necessari per il carico:", flightCalculation: "Calcolo del volo", launchCalculation: "Calcolo del carico e dei silos", inventoryTabs: "Categorie delle ricette",
    actualSpm: "Pacchetti scientifici forniti", effectiveSpm: "Ricerca effettiva", scienceSupplyMode: "Pacchetti scientifici forniti", scienceTargetMode: "Ricerca effettiva desiderata", researchPerPack: "Ricerca per pacchetto fornito", perLab: "per laboratorio", scienceSpeedNote: "I moduli velocità, i fari e la qualità del laboratorio cambiano la capacità di elaborazione e quindi il numero di laboratori necessario. Non aumentano la ricerca ottenuta da un flusso fisso di pacchetti; lo fanno qualità dei pacchetti, produttività e consumo al 50% del biolaboratorio.",
    rocketSilosToPlace: "Sili per razzi da costruire", siloLoading: "Caricamento del silo", logisticRobots: "Robot logistici", inserters: "Inseritori", experimental: "Sperimentale",
    experimentalInserterLoading: "Sperimentale: un inseritore carica ogni silo dalla casella centrale inferiore. In quella casella non può esserci un faro, quindi il massimo fisico scende a 15.",
    payloadInsertion: "Tempo di inserimento del carico", inserterThroughput: "Portata dell’inseritore", siloCycle: "Ciclo effettivo del silo", steamConsumer: "Generatore a vapore",
    highTemperatureLoss: "I motori a vapore accettano vapore a 500 °C, ma sprecano l’energia oltre 165 °C; il calcolatore applica questa perdita.",
    downstreamProducts: "Prodotti che usano questo materiale", chooseNextProduct: "Scegli il prodotto successivo", targetReturn: "Materiale riciclato obiettivo", desiredQualityOutput: "Produzione desiderata della qualità obiettivo",
    rocket: "Trasporto con razzi", currentProducts: "Prodotti attuali", noProductSelected: "Nessun prodotto ancora selezionato",
    resetCurrent: "Reimposta questo calcolatore",
    clickMaterial: "Usa questo materiale come obiettivo corrente", optimizedLayout: "Disposizione condivisa ottimizzata", manualBeaconLayout: "Selezione manuale dei fari",
    energyBlueprint: "Progetto compatto dei rapporti", orientation: "Orientamento e montaggio", reactorGrid: "Griglia dei reattori", neighborLinks: "Collegamenti cardinali",
    rocketCargo: "Carico del razzo", sourcePlanet: "Origine", destinationPlanet: "Destinazione", cargoPerTransit: "Carico per viaggio", rocketCapacity: "Capacità del razzo",
    launchesPerTransit: "Lanci per viaggio", rocketPartResearch: "Ricerca produttività parti del razzo", platformSpeed: "Velocità della piattaforma", manualSpeed: "Velocità manuale",
    deriveFromThrusters: "Calcola dai propulsori", thrusterCount: "Propulsori", thrusterQuality: "Qualità dei propulsori", throttle: "Livello fluido dei propulsori",
    platformMass: "Massa piattaforma", platformWidth: "Larghezza piattaforma", cargoBays: "Vani di carico", flightTime: "Volo di andata", roundTrip: "Andata e ritorno",
    loadingTime: "Caricamento razzi", landingTime: "Atterraggio del carico", platformsRequired: "Piattaforme cargo", sustainedSilos: "Sili continui",
    waveSilos: "Sili precaricati", rocketParts: "Materiali delle parti del razzo", preloadedNotice: "Il caricamento ottimale presuppone che tutti i razzi necessari siano già costruiti e caricati all’arrivo della piattaforma.",
    launchesPerMinute: "Lanci al minuto", landingWaves: "Ondate di atterraggio", tiles: "caselle", rocketSelectionError: "Seleziona un oggetto trasportabile e due località collegate differenti.",
    thrusterEstimateNotice: "Il viaggio usa la formula ufficiale di spinta e resistenza come stima a regime; non include i rallentamenti causati dagli asteroidi.",
    minutes: "minuti", seconds: "secondi", path: "Rotta", energyLayoutNote: "Il disegno usa il rapporto ideale di entità per pianeta, qualità, generatore e dimensione del blocco selezionati; i totali possono includere più blocchi.",
    steamOrientation: "L’anteprima raggruppa la fila di caldaie e i generatori a vapore selezionati e ne mostra il rapporto; collega acqua e vapore nel gioco.", solarOrientation: "Le file di pannelli e accumulatori usano il rapporto del pianeta e della qualità selezionati; nessuna delle due entità ha orientamento.",
    nuclearOrientation: "I reattori mantengono la griglia cardinale; scambiatori e generatori selezionati sono raggruppati in file e mostrati diritti.", heatingOrientation: "Torre, scambiatori e generatori selezionati sono raggruppati in file e mostrati diritti secondo il rapporto scelto.",
    fusionOrientation: "I reattori mantengono lo schema di adiacenza; generatori e impianti criogenici sono raggruppati in file e mostrati diritti. Le connessioni di plasma e fluidi sono omesse.",
  },
  ja: {
    chainMaster: "生産チェーン共通設定", applyEntireChain: "個別ノードで上書きしない限り、すべての上流レシピに適用します。", machinePriority: "優先生産設備", modulePriority: "モジュール優先順位",
    rocketPayloadBottleneck: "貨物ウェーブが上限です。貨物ロット内のロケット1基ごとに事前装填済みサイロが1基必要なため、この設定ではサイロ・モジュール・ビーコンを高速化しても設置数は減りません。", cargoStorageBottleneck: "プラットフォーム保管上限：選択した貨物ベイでは指定バッチを収容できないため、より多くの貨物プラットフォームが必要です。指定バッチに必要な貨物ベイ：", flightCalculation: "飛行計算", launchCalculation: "積載・サイロ計算", inventoryTabs: "レシピ分類",
    actualSpm: "供給するサイエンスパック", effectiveSpm: "実効研究速度", scienceSupplyMode: "供給するサイエンスパック", scienceTargetMode: "目標実効研究速度", researchPerPack: "供給パック1個あたりの研究", perLab: "研究所あたり", scienceSpeedNote: "速度モジュール、ビーコン、研究所の品質は処理能力と必要な研究所数を変えます。一定のパック供給量から得られる研究量は増えません。パック品質、生産力、バイオ研究所の50%消費が研究量を増やします。",
    rocketSilosToPlace: "設置するロケットサイロ", siloLoading: "サイロ貨物の積載", logisticRobots: "物流ロボット", inserters: "インサータ", experimental: "試験機能",
    experimentalInserterLoading: "試験機能：各サイロを下辺中央のインサータ1台で積載します。そのマスにはビーコンを置けないため、物理上限は15台です。",
    payloadInsertion: "貨物挿入時間", inserterThroughput: "インサータ処理量", siloCycle: "実効サイロ周期", steamConsumer: "蒸気発電機",
    highTemperatureLoss: "蒸気機関は500 °Cの蒸気を受け入れますが、165 °Cを超えるエネルギーは失われます。この変換損失を計算に含めます。",
    downstreamProducts: "この素材を使用する製品", chooseNextProduct: "次の製品を選択", targetReturn: "目標の再生素材", desiredQualityOutput: "目標品質の希望出力",
    rocket: "ロケット輸送", currentProducts: "現在の製品", noProductSelected: "製品がまだ選択されていません",
    resetCurrent: "この計算機をリセット",
    clickMaterial: "この素材を現在の対象にする", optimizedLayout: "最適化された共有配置", manualBeaconLayout: "ビーコンの手動選択",
    energyBlueprint: "コンパクトな比率設計", orientation: "向きと接続", reactorGrid: "リアクター配列", neighborLinks: "上下左右の隣接リンク",
    rocketCargo: "ロケット貨物", sourcePlanet: "出発地", destinationPlanet: "目的地", cargoPerTransit: "1航行あたりの貨物", rocketCapacity: "ロケット容量",
    launchesPerTransit: "1航行あたりの打上げ", rocketPartResearch: "ロケット部品生産性研究", platformSpeed: "プラットフォーム速度", manualSpeed: "手動速度",
    deriveFromThrusters: "スラスターから計算", thrusterCount: "スラスター", thrusterQuality: "スラスター品質", throttle: "スラスター流体量",
    platformMass: "プラットフォーム質量", platformWidth: "プラットフォーム幅", cargoBays: "貨物ベイ", flightTime: "片道飛行", roundTrip: "往復",
    loadingTime: "ロケット積込み", landingTime: "貨物降下", platformsRequired: "貨物プラットフォーム", sustainedSilos: "連続運転サイロ",
    waveSilos: "事前装填サイロ", rocketParts: "ロケット部品材料", preloadedNotice: "最適積込みは、プラットフォーム到着前に必要なロケットがすべて完成・装填済みであることを前提とします。",
    launchesPerMinute: "1分あたりの打上げ", landingWaves: "着陸ウェーブ", tiles: "マス", rocketSelectionError: "輸送可能なアイテムと、接続された異なる2地点を選択してください。",
    thrusterEstimateNotice: "移動時間は公式の推力・抗力式による定常速度の推定値です。小惑星による減速は含みません。",
    minutes: "分", seconds: "秒", path: "経路", energyLayoutNote: "図は選択した惑星、品質、発電機、ブロックサイズに応じた理想的な設備比率を示します。合計には複数ブロックが含まれる場合があります。",
    steamOrientation: "ボイラー列と選択した蒸気発電設備を正立した列でまとめ、選択中の比率を示します。水と蒸気の配管はゲーム内で接続してください。", solarOrientation: "ソーラーパネルと蓄電池の列は選択した惑星と品質の比率です。どちらにも向きはありません。",
    nuclearOrientation: "原子炉は隣接グリッドを維持し、熱交換器と選択した発電機は正立した列でまとめて表示します。", heatingOrientation: "加熱塔、熱交換器、選択した発電機を、選択中の比率で正立した列にまとめます。",
    fusionOrientation: "核融合炉は隣接パターンを維持し、核融合発電機と低温プラントは正立した列でまとめます。プラズマと流体の接続は省略します。",
  },
  ru: {
    chainMaster: "Настройки всей цепочки", applyEntireChain: "Применяется ко всем предыдущим рецептам, если узел не переопределён отдельно.", machinePriority: "Предпочтительная машина", modulePriority: "Приоритет модулей",
    rocketPayloadBottleneck: "Ограничение волной груза: для каждой ракеты в партии нужна заранее загруженная шахта. Поэтому при этих настройках более быстрые шахты, модули или маяки не уменьшают их количество.", cargoStorageBottleneck: "Ограничение хранилища платформы: выбранные грузовые отсеки не вмещают заданную партию, поэтому требуется больше платформ. Отсеков для заданной партии:", flightCalculation: "Расчёт полёта", launchCalculation: "Расчёт загрузки и шахт", inventoryTabs: "Категории рецептов",
    actualSpm: "Подаваемые научные пакеты", effectiveSpm: "Эффективная скорость исследований", scienceSupplyMode: "Подаваемые научные пакеты", scienceTargetMode: "Целевая эффективная скорость", researchPerPack: "Исследование на поданный пакет", perLab: "на лабораторию", scienceSpeedNote: "Модули скорости, маяки и качество лаборатории меняют пропускную способность и число необходимых лабораторий. Они не увеличивают исследование из фиксированного потока пакетов; это делают качество пакетов, продуктивность и 50-процентный расход биолаборатории.",
    rocketSilosToPlace: "Ракетные шахты для размещения", siloLoading: "Загрузка шахты", logisticRobots: "Логистические дроны", inserters: "Манипуляторы", experimental: "Экспериментально",
    experimentalInserterLoading: "Экспериментально: один манипулятор загружает каждую шахту через центральную нижнюю клетку. Там нельзя поставить маяк, поэтому физический максимум снижается до 15.",
    payloadInsertion: "Время загрузки груза", inserterThroughput: "Пропускная способность манипулятора", siloCycle: "Эффективный цикл шахты", steamConsumer: "Парогенератор",
    highTemperatureLoss: "Паровые машины принимают пар 500 °C, но теряют энергию выше 165 °C; калькулятор учитывает эту потерю.",
    downstreamProducts: "Продукты из этого материала", chooseNextProduct: "Выбрать следующий продукт", targetReturn: "Целевой материал переработки", desiredQualityOutput: "Желаемый выпуск целевого качества",
    rocket: "Ракетные перевозки", currentProducts: "Текущие продукты", noProductSelected: "Продукт пока не выбран",
    resetCurrent: "Сбросить этот калькулятор",
    clickMaterial: "Сделать этот материал текущей целью", optimizedLayout: "Оптимальная общая схема", manualBeaconLayout: "Ручной выбор маяков",
    energyBlueprint: "Компактная схема соотношений", orientation: "Ориентация и подключение", reactorGrid: "Сетка реакторов", neighborLinks: "Соседние связи по сторонам",
    rocketCargo: "Ракетный груз", sourcePlanet: "Откуда", destinationPlanet: "Куда", cargoPerTransit: "Груз за рейс", rocketCapacity: "Вместимость ракеты",
    launchesPerTransit: "Запусков за рейс", rocketPartResearch: "Исследование продуктивности деталей ракеты", platformSpeed: "Скорость платформы", manualSpeed: "Заданная скорость",
    deriveFromThrusters: "Рассчитать по двигателям", thrusterCount: "Двигатели", thrusterQuality: "Качество двигателей", throttle: "Заполнение двигателя",
    platformMass: "Масса платформы", platformWidth: "Ширина платформы", cargoBays: "Грузовые отсеки", flightTime: "Полёт в одну сторону", roundTrip: "Полный рейс",
    loadingTime: "Загрузка ракетами", landingTime: "Посадка груза", platformsRequired: "Грузовые платформы", sustainedSilos: "Шахты для потока",
    waveSilos: "Предзагруженные шахты", rocketParts: "Материалы деталей ракеты", preloadedNotice: "Оптимальная загрузка предполагает, что к прибытию платформы все нужные ракеты уже построены и загружены.",
    launchesPerMinute: "Запусков в минуту", landingWaves: "Волны посадки", tiles: "клеток", rocketSelectionError: "Выберите перевозимый предмет и два разных связанных пункта.",
    thrusterEstimateNotice: "Время полёта использует официальную формулу тяги и сопротивления как стационарную оценку; замедление из-за астероидов не учитывается.",
    minutes: "минуты", seconds: "секунды", path: "Маршрут", energyLayoutNote: "Схема использует идеальное соотношение объектов для выбранных планеты, качества, генератора и размера блока; итог может включать несколько блоков.",
    steamOrientation: "Котлы и выбранные паровые генераторы сгруппированы вертикально стоящими рядами с выбранным соотношением; воду и пар подключите в игре.", solarOrientation: "Ряды панелей и аккумуляторов используют соотношение для выбранных планеты и качества; эти объекты не имеют направления.",
    nuclearOrientation: "Реакторы сохраняют кардинальную сетку; теплообменники и выбранные генераторы показаны вертикально и сгруппированы в ряды.", heatingOrientation: "Башня, теплообменники и выбранные генераторы показаны вертикально и сгруппированы в ряды с выбранным соотношением.",
    fusionOrientation: "Реакторы сохраняют схему соседства; термоядерные генераторы и криогенные установки показаны вертикально в рядах. Соединения плазмы и жидкостей не отображаются.",
  },
  "zh-CN": {
    chainMaster: "整条生产链设置", applyEntireChain: "应用于所有上游配方，除非某个节点单独覆盖。", machinePriority: "首选生产设备", modulePriority: "插件优先级",
    rocketPayloadBottleneck: "受货物批次限制：货物批次中的每枚火箭都需要一座预装载发射井，因此在当前设置下，更快的发射井、插件或插件塔不会减少所需建造数量。", cargoStorageBottleneck: "平台存储受限：所选货舱无法容纳目标批次，因此需要更多货运平台。该批次所需货舱数：", flightCalculation: "航行计算", launchCalculation: "装载与发射井计算", inventoryTabs: "配方分类",
    actualSpm: "输入的科研包", effectiveSpm: "有效科研速率", scienceSupplyMode: "输入的科研包", scienceTargetMode: "目标有效科研速率", researchPerPack: "每个输入科研包的研究量", perLab: "每座研究中心", scienceSpeedNote: "速度插件、插件塔和研究中心品质只会改变处理能力及所需研究中心数量，不会让固定科研包流产生更多研究量；科研包品质、产能以及生物研究室50%的消耗率才会提高每包价值。",
    rocketSilosToPlace: "需建造的火箭发射井", siloLoading: "发射井货物装载", logisticRobots: "物流机器人", inserters: "机械臂", experimental: "实验性",
    experimentalInserterLoading: "实验性：每座发射井由一台机械臂从底边中央格装载。该格无法放置信标，因此物理上限降为15个。",
    payloadInsertion: "货物装载时间", inserterThroughput: "机械臂吞吐量", siloCycle: "发射井有效周期", steamConsumer: "蒸汽发电机",
    highTemperatureLoss: "蒸汽机可接收500 °C蒸汽，但会浪费165 °C以上的能量；计算器会计入该转换损失。",
    downstreamProducts: "使用此材料的产品", chooseNextProduct: "选择下一个产品", targetReturn: "目标回收材料", desiredQualityOutput: "目标品质的期望产量",
    rocket: "火箭货运", currentProducts: "当前产品", noProductSelected: "尚未选择产品",
    resetCurrent: "重置此计算器",
    clickMaterial: "将此材料设为当前目标", optimizedLayout: "优化共享布局", manualBeaconLayout: "手动插件塔选择",
    energyBlueprint: "紧凑比例蓝图", orientation: "方向与连接", reactorGrid: "反应堆阵列", neighborLinks: "正交相邻连接",
    rocketCargo: "火箭货物", sourcePlanet: "起点", destinationPlanet: "终点", cargoPerTransit: "每航次货物", rocketCapacity: "火箭容量",
    launchesPerTransit: "每航次发射数", rocketPartResearch: "火箭部件产能研究", platformSpeed: "平台速度", manualSpeed: "手动速度",
    deriveFromThrusters: "根据推进器计算", thrusterCount: "推进器", thrusterQuality: "推进器品质", throttle: "推进器流体量",
    platformMass: "平台质量", platformWidth: "平台宽度", cargoBays: "货舱", flightTime: "单程飞行", roundTrip: "往返周期",
    loadingTime: "火箭装载", landingTime: "货物降落", platformsRequired: "货运平台", sustainedSilos: "持续吞吐发射井",
    waveSilos: "预装载发射井", rocketParts: "火箭部件材料", preloadedNotice: "最佳装载假设平台抵达时，所有所需火箭均已建造并预装货物。",
    launchesPerMinute: "每分钟发射数", landingWaves: "降落批次", tiles: "格", rocketSelectionError: "请选择可运输物品以及两个不同且相连的地点。",
    thrusterEstimateNotice: "航行时间使用官方推力与阻力公式作为稳态估算，不包含小行星造成的减速。",
    minutes: "分钟", seconds: "秒", path: "路线", energyLayoutNote: "图中采用当前所选星球、品质、发电机和模块尺寸的理想设施比例；总数可能包含多个模块。",
    steamOrientation: "预览将锅炉和所选蒸汽发电机直立排列成行并显示当前比例；水与蒸汽管路请在游戏中连接。", solarOrientation: "太阳能板和蓄电池按所选星球与品质的比例分行显示；两者均无方向限制。",
    nuclearOrientation: "反应堆保留正交相邻网格；换热器和所选发电机均直立并按行排列。", heatingOrientation: "供热塔、换热器和所选发电机按当前比例直立并分行排列。",
    fusionOrientation: "聚变反应堆保留相邻结构；聚变发电机和低温工厂均直立并按行排列。预览省略等离子与流体连接。",
  },
  "zh-TW": {
    chainMaster: "整條生產鏈設定", applyEntireChain: "套用至所有上游配方，除非個別節點另行覆寫。", machinePriority: "偏好生產設備", modulePriority: "插件優先順序",
    rocketPayloadBottleneck: "受貨物批次限制：貨物批次中的每枚火箭都需要一座預先裝載的發射井，因此目前設定下，更快的發射井、插件或插件塔不會減少所需建造數量。", cargoStorageBottleneck: "平台儲存受限：所選貨艙無法容納目標批次，因此需要更多貨運平台。該批次所需貨艙數：", flightCalculation: "航行計算", launchCalculation: "裝載與發射井計算", inventoryTabs: "配方分類",
    actualSpm: "輸入的科研包", effectiveSpm: "有效科研速率", scienceSupplyMode: "輸入的科研包", scienceTargetMode: "目標有效科研速率", researchPerPack: "每個輸入科研包的研究量", perLab: "每座研究中心", scienceSpeedNote: "速度插件、插件塔和研究中心品質只會改變處理能力及所需研究中心數量，不會讓固定科研包流產生更多研究量；科研包品質、產能以及生物研究室50%的消耗率才會提高每包價值。",
    rocketSilosToPlace: "需建造的火箭發射井", siloLoading: "發射井貨物裝載", logisticRobots: "物流機器人", inserters: "機械臂", experimental: "實驗性",
    experimentalInserterLoading: "實驗性：每座發射井由一台機械臂從底邊中央格裝載。該格無法放置信標，因此物理上限降為15個。",
    payloadInsertion: "貨物裝載時間", inserterThroughput: "機械臂吞吐量", siloCycle: "發射井有效週期", steamConsumer: "蒸汽發電機",
    highTemperatureLoss: "蒸汽機可接收500 °C蒸汽，但會浪費165 °C以上的能量；計算器會計入該轉換損失。",
    downstreamProducts: "使用此材料的產品", chooseNextProduct: "選擇下一個產品", targetReturn: "目標回收材料", desiredQualityOutput: "目標品質的期望產量",
    rocket: "火箭貨運", currentProducts: "目前產品", noProductSelected: "尚未選擇產品",
    resetCurrent: "重設此計算器",
    clickMaterial: "將此材料設為目前目標", optimizedLayout: "最佳化共享配置", manualBeaconLayout: "手動插件塔選擇",
    energyBlueprint: "緊湊比例藍圖", orientation: "方向與連接", reactorGrid: "反應爐陣列", neighborLinks: "正交相鄰連接",
    rocketCargo: "火箭貨物", sourcePlanet: "起點", destinationPlanet: "終點", cargoPerTransit: "每航次貨物", rocketCapacity: "火箭容量",
    launchesPerTransit: "每航次發射數", rocketPartResearch: "火箭零件產能研究", platformSpeed: "平台速度", manualSpeed: "手動速度",
    deriveFromThrusters: "依推進器計算", thrusterCount: "推進器", thrusterQuality: "推進器品質", throttle: "推進器流體量",
    platformMass: "平台質量", platformWidth: "平台寬度", cargoBays: "貨艙", flightTime: "單程飛行", roundTrip: "往返週期",
    loadingTime: "火箭裝載", landingTime: "貨物降落", platformsRequired: "貨運平台", sustainedSilos: "持續吞吐發射井",
    waveSilos: "預裝載發射井", rocketParts: "火箭零件材料", preloadedNotice: "最佳裝載假設平台抵達時，所有所需火箭都已建造並預先裝貨。",
    launchesPerMinute: "每分鐘發射數", landingWaves: "降落批次", tiles: "格", rocketSelectionError: "請選擇可運輸物品以及兩個不同且相連的地點。",
    thrusterEstimateNotice: "航行時間使用官方推力與阻力公式作為穩態估算，不包含小行星造成的減速。",
    minutes: "分鐘", seconds: "秒", path: "路線", energyLayoutNote: "圖中採用目前所選星球、品質、發電機與模組尺寸的理想設施比例；總數可能包含多個模組。",
    steamOrientation: "預覽將鍋爐與所選蒸汽發電機直立排列成行並顯示目前比例；水與蒸汽管路請在遊戲中連接。", solarOrientation: "太陽能板與蓄電池依所選星球與品質的比例分行顯示；兩者皆無方向限制。",
    nuclearOrientation: "反應爐保留正交相鄰網格；熱交換器與所選發電機皆直立並按行排列。", heatingOrientation: "供熱塔、熱交換器與所選發電機依目前比例直立並分行排列。",
    fusionOrientation: "核融合反應爐保留相鄰結構；核融合發電機與低溫工廠皆直立並按行排列。預覽省略電漿與流體連接。",
  },
};
export type UiKey = keyof typeof en;

const translations: Record<Locale, Partial<Record<UiKey, string>>> = {
  en,
  de: {
    title: "Factorio-Produktionsrechner",
    subtitle: "Produktorientiert · offizielle 2.1.17-Daten · offline nutzbar",
    production: "Produktion",
    quality: "Qualität",
    science: "Forschung",
    energy: "Energie",
    recycling: "Recycling",
    qualityRecycling: "Qualitäts-Recycling",
    language: "Sprache",
    productRoute: "Produkt & Herstellungsweg",
    product: "Produkt",
    recipeRoute: "Rezeptweg",
    productionMachine: "Produktionsmaschine",
    targetRate: "Zielrate",
    amount: "Menge",
    unit: "Einheit",
    desiredOutput: "Gewünschter Output",
    inputLimited: "Durch Input begrenzt",
    targetQuality: "Zielqualität",
    ingredientQuality: "Qualität der Zutaten",
    machineQuality: "Maschinenqualität",
    maximumQuality: "Höchste erforschte Qualität",
    modules: "Module",
    machineModules: "Maschinenmodule",
    beaconModules: "Effektverteilermodule",
    beacons: "Effektverteiler",
    enabled: "An",
    disabled: "Aus",
    activePerMachine: "Aktiv je Maschine",
    beaconQuality: "Effektverteilerqualität",
    automatic: "Automatisch",
    manual: "Manuell",
    tier: "Stufe",
    moduleQuality: "Modulqualität",
    slots: "Steckplätze",
    addProduct: "Produkt hinzufügen",
    remove: "Entfernen",
    allQualities: "Alle Qualitäten",
    selectProduct: "Produkt auswählen",
    searchProducts: "Produkte und Flüssigkeiten suchen…",
    noMatch: "Kein passendes Produkt.",
    available: "verfügbar",
    route: "Weg",
    machine: "Maschine",
    ingredients: "Zutaten",
    outputs: "Produkte",
    machinesRequired: "Benötigte Maschinen",
    theoretical: "theoretisch",
    build: "bauen",
    utilization: "Auslastung",
    power: "Energie",
    directPower: "Direktes Setup",
    chainPower: "Vorgelagerte Kette",
    includeEnergy: "Im Energierechner berücksichtigen",
    productionChain: "Produktionskette",
    showChain: "Gesamte Produktionskette anzeigen",
    hideChain: "Produktionskette ausblenden",
    nodeSetup: "Rezept & Maschine",
    nodeModules: "Module & Effektverteiler",
    rawSource: "Rohstoffquelle",
    logistics: "Maschinenlogistik",
    inserter: "Greifarm",
    inserterQuality: "Greifarmqualität",
    capacityResearch: "Kapazitätsforschung",
    handoff: "Übergabe",
    inputLoad: "Inputlast",
    outputLoad: "Outputlast",
    perMachine: "je Maschine",
    geometryCheck: "Geometrieprüfung",
    beaconDesign: "Effektverteiler-Design",
    zoom: "Zoom",
    actualSpm: "Tatsächliche Pakete/min",
    effectiveSpm: "Effektive Forschung/min",
    lab: "Labor",
    biolab: "Biolabor",
    labType: "Forschungsgebäude",
    packQuality: "Forschungspaketqualität",
    beaconsOff: "Effektverteiler aus",
    forcedRing: "Vollständiger Ring mit 16 Effektverteilern",
    manualMw: "Manueller Bedarf",
    importedLoads: "Ausgewählte Rechnerlasten",
    targetDemand: "Zielbedarf",
    reserve: "Reserve",
    technology: "Energietechnik",
    planet: "Planet / Orbit",
    steam: "Dampfkraft",
    solar: "Solar & Akkumulatoren",
    nuclear: "Kernkraft",
    heatingTower: "Heizturm",
    fusion: "Fusionskraft",
    demandSizing: "Auf Bedarf auslegen",
    fixedBlock: "Festen Reaktorblock prüfen",
    reactorBlock: "Reaktoren je Block",
    grossOutput: "Bruttoleistung",
    netOutput: "Netto unterstützte Leistung",
    internalDemand: "Eigenbedarf",
    entities: "Gebäude",
    fuelAndFluids: "Brennstoff & Flüssigkeiten",
    recycleProduct: "Zu recycelndes Produkt",
    recyclerQuality: "Recyclerqualität",
    expectedOutputs: "Erwartete Rückgaben",
    recycleTime: "Recyclingzeit",
    throughput: "Durchsatz",
    lostFluids: "Verlorene Flüssigzutaten",
    warnings: "Hinweise & Warnungen",
    noQualityFluids: "Flüssigkeiten selbst besitzen keine Qualität.",
    normalModeQualityNotice:
      "Manuelle Qualitätsmodule verändern hier Geschwindigkeit und Energie. Die Qualitätsverteilung siehst du unter Qualitätsproduktion.",
    qualitySafeBeacon:
      "Die Qualitätsvorgabe begrenzt Speed-Unterstützung auf einen Effektverteiler mit einem belegten Slot, da Geschwindigkeit Qualität senkt. Manuell kann dies überschrieben werden.",
    passiveSpoilage: "Passives Verderben",
    clickIngredient: "Diese Zutat berechnen",
    reset: "Setup zurücksetzen",
    addInput: "Inputbegrenzung hinzufügen",
    fluid: "Flüssigkeit",
    item: "Gegenstand",
    recipeCount: "Spielerrezepte",
    productCount: "Produkte",
    fullChain: "Gesamtkette",
    actual: "Tatsächlich",
    effective: "Effektiv",
    imported: "Übernommen",
    sourceSelection: "Auswahl der Energielasten",
    normalQuality: "Normale Produktion",
    qualityProduction: "Qualitätsproduktion",
  },
  "es-ES": {
    title: "Calculadora de producción de Factorio",
    subtitle: "Por producto · datos oficiales 2.1.17 · sin conexión",
    production: "Producción",
    quality: "Calidad",
    science: "Ciencia",
    energy: "Energía",
    recycling: "Reciclaje",
    qualityRecycling: "Reciclaje de calidad",
    language: "Idioma",
    productRoute: "Producto y ruta",
    product: "Producto",
    recipeRoute: "Ruta de receta",
    productionMachine: "Máquina de producción",
    targetRate: "Tasa objetivo",
    amount: "Cantidad",
    unit: "Unidad",
    desiredOutput: "Producción deseada",
    inputLimited: "Limitado por entrada",
    targetQuality: "Calidad objetivo",
    ingredientQuality: "Calidad de ingredientes",
    machineQuality: "Calidad de máquina",
    maximumQuality: "Calidad máxima investigada",
    modules: "Módulos",
    machineModules: "Módulos de máquina",
    beaconModules: "Módulos de faro",
    beacons: "Faros",
    enabled: "Activado",
    disabled: "Desactivado",
    activePerMachine: "Activos por máquina",
    beaconQuality: "Calidad de faro",
    automatic: "Automático",
    manual: "Manual",
    tier: "Nivel",
    moduleQuality: "Calidad de módulo",
    slots: "ranuras",
    addProduct: "Añadir producto",
    remove: "Eliminar",
    allQualities: "Todas las calidades",
    selectProduct: "Selecciona un producto",
    searchProducts: "Buscar productos y fluidos…",
    noMatch: "No hay productos coincidentes.",
    available: "disponibles",
    route: "Ruta",
    machine: "Máquina",
    ingredients: "Ingredientes",
    outputs: "Productos",
    machinesRequired: "Máquinas necesarias",
    theoretical: "teóricas",
    build: "construir",
    utilization: "Utilización",
    power: "Energía",
    directPower: "Configuración directa",
    chainPower: "Cadena previa",
    includeEnergy: "Incluir en la calculadora de energía",
    productionChain: "Cadena de producción",
    showChain: "Mostrar cadena completa",
    hideChain: "Ocultar cadena",
    nodeSetup: "Receta y máquina",
    nodeModules: "Módulos y faros",
    rawSource: "Fuente primaria",
    logistics: "Logística por máquina",
    inserter: "Brazo",
    inserterQuality: "Calidad del brazo",
    capacityResearch: "Investigación de capacidad",
    handoff: "Transferencia",
    inputLoad: "Carga de entrada",
    outputLoad: "Carga de salida",
    perMachine: "por máquina",
    geometryCheck: "Comprobación geométrica",
    beaconDesign: "Diseño de faros",
    zoom: "Zoom",
    actualSpm: "Paquetes reales/min",
    effectiveSpm: "Ciencia efectiva/min",
    lab: "Laboratorio",
    biolab: "Biolaboratorio",
    labType: "Edificio de investigación",
    packQuality: "Calidad del paquete",
    beaconsOff: "Faros desactivados",
    forcedRing: "Anillo completo de 16 faros",
    manualMw: "Demanda manual",
    importedLoads: "Cargas seleccionadas",
    targetDemand: "Demanda objetivo",
    reserve: "Reserva",
    technology: "Tecnología energética",
    planet: "Planeta / órbita",
    steam: "Energía de vapor",
    solar: "Solar y acumuladores",
    nuclear: "Energía nuclear",
    heatingTower: "Torre de calefacción",
    fusion: "Energía de fusión",
    demandSizing: "Dimensionar según demanda",
    fixedBlock: "Examinar bloque fijo",
    reactorBlock: "Reactores por bloque",
    grossOutput: "Producción bruta",
    netOutput: "Producción neta",
    internalDemand: "Consumo interno",
    entities: "Entidades",
    fuelAndFluids: "Combustible y fluidos",
    recycleProduct: "Producto a reciclar",
    recyclerQuality: "Calidad del reciclador",
    expectedOutputs: "Retornos esperados",
    recycleTime: "Tiempo de reciclaje",
    throughput: "Rendimiento",
    lostFluids: "Ingredientes fluidos perdidos",
    warnings: "Notas y avisos",
    noQualityFluids: "Los fluidos no pueden tener calidad.",
    normalModeQualityNotice:
      "Los módulos de calidad manuales afectan velocidad y energía. Usa Producción de calidad para ver el reparto.",
    qualitySafeBeacon:
      "La configuración segura limita la velocidad a un faro con una ranura porque la velocidad reduce la calidad. Se puede anular manualmente.",
    passiveSpoilage: "Descomposición pasiva",
    clickIngredient: "Calcular este ingrediente",
    reset: "Restablecer",
    addInput: "Añadir restricción de entrada",
    fluid: "Fluido",
    item: "Objeto",
    recipeCount: "recetas de jugador",
    productCount: "productos",
    fullChain: "Cadena completa",
    actual: "Real",
    effective: "Efectivo",
    imported: "Importado",
    sourceSelection: "Selección de cargas",
    normalQuality: "Producción normal",
    qualityProduction: "Producción de calidad",
  },
  fr: {
    title: "Calculateur de production Factorio",
    subtitle: "Orienté produit · données officielles 2.1.17 · hors ligne",
    production: "Production",
    quality: "Qualité",
    science: "Science",
    energy: "Énergie",
    recycling: "Recyclage",
    qualityRecycling: "Recyclage de qualité",
    language: "Langue",
    productRoute: "Produit et voie",
    product: "Produit",
    recipeRoute: "Recette",
    productionMachine: "Machine de production",
    targetRate: "Débit cible",
    amount: "Quantité",
    unit: "Unité",
    desiredOutput: "Production souhaitée",
    inputLimited: "Limité par l'entrée",
    targetQuality: "Qualité cible",
    ingredientQuality: "Qualité des ingrédients",
    machineQuality: "Qualité de la machine",
    maximumQuality: "Qualité maximale recherchée",
    modules: "Modules",
    machineModules: "Modules de machine",
    beaconModules: "Modules de diffuseur",
    beacons: "Diffuseurs",
    enabled: "Activés",
    disabled: "Désactivés",
    activePerMachine: "Actifs par machine",
    beaconQuality: "Qualité du diffuseur",
    automatic: "Automatique",
    manual: "Manuel",
    tier: "Niveau",
    moduleQuality: "Qualité du module",
    slots: "emplacements",
    addProduct: "Ajouter un produit",
    remove: "Supprimer",
    allQualities: "Toutes les qualités",
    selectProduct: "Choisir un produit",
    searchProducts: "Rechercher produits et fluides…",
    noMatch: "Aucun produit.",
    available: "disponibles",
    route: "Voie",
    machine: "Machine",
    ingredients: "Ingrédients",
    outputs: "Produits",
    machinesRequired: "Machines nécessaires",
    theoretical: "théoriques",
    build: "à construire",
    utilization: "Utilisation",
    power: "Énergie",
    directPower: "Installation directe",
    chainPower: "Chaîne amont",
    includeEnergy: "Inclure dans le calcul d'énergie",
    productionChain: "Chaîne de production",
    showChain: "Afficher toute la chaîne",
    hideChain: "Masquer la chaîne",
    nodeSetup: "Recette et machine",
    nodeModules: "Modules et diffuseurs",
    rawSource: "Source brute",
    logistics: "Logistique par machine",
    inserter: "Bras",
    inserterQuality: "Qualité du bras",
    capacityResearch: "Recherche de capacité",
    handoff: "Transfert",
    inputLoad: "Charge d'entrée",
    outputLoad: "Charge de sortie",
    perMachine: "par machine",
    geometryCheck: "Vérification géométrique",
    beaconDesign: "Plan de diffuseurs",
    zoom: "Zoom",
    actualSpm: "Packs réels/min",
    effectiveSpm: "Science effective/min",
    lab: "Laboratoire",
    biolab: "Biolaboratoire",
    labType: "Bâtiment de recherche",
    packQuality: "Qualité du pack",
    beaconsOff: "Diffuseurs désactivés",
    forcedRing: "Anneau complet de 16 diffuseurs",
    manualMw: "Demande manuelle",
    importedLoads: "Charges sélectionnées",
    targetDemand: "Demande cible",
    reserve: "Réserve",
    technology: "Technologie énergétique",
    planet: "Planète / orbite",
    steam: "Énergie vapeur",
    solar: "Solaire et accumulateurs",
    nuclear: "Énergie nucléaire",
    heatingTower: "Tour thermique",
    fusion: "Énergie de fusion",
    demandSizing: "Dimensionner pour la demande",
    fixedBlock: "Examiner un bloc fixe",
    reactorBlock: "Réacteurs par bloc",
    grossOutput: "Production brute",
    netOutput: "Production nette",
    internalDemand: "Consommation interne",
    entities: "Entités",
    fuelAndFluids: "Combustible et fluides",
    recycleProduct: "Produit à recycler",
    recyclerQuality: "Qualité du recycleur",
    expectedOutputs: "Retours attendus",
    recycleTime: "Temps de recyclage",
    throughput: "Débit",
    lostFluids: "Ingrédients fluides perdus",
    warnings: "Notes et avertissements",
    noQualityFluids: "Les fluides n'ont pas de qualité.",
    normalModeQualityNotice:
      "Les modules de qualité manuels affectent vitesse et énergie. Utilisez Production de qualité pour la répartition.",
    qualitySafeBeacon:
      "Le réglage sûr limite la vitesse à un diffuseur avec un emplacement occupé, car la vitesse réduit la qualité. Réglage manuel possible.",
    passiveSpoilage: "Altération passive",
    clickIngredient: "Calculer cet ingrédient",
    reset: "Réinitialiser",
    addInput: "Ajouter une contrainte",
    fluid: "Fluide",
    item: "Objet",
    recipeCount: "recettes joueur",
    productCount: "produits",
    fullChain: "Chaîne complète",
    actual: "Réel",
    effective: "Effectif",
    imported: "Importé",
    sourceSelection: "Sélection des charges",
    normalQuality: "Production normale",
    qualityProduction: "Production de qualité",
  },
  it: {
    title: "Calcolatore di produzione Factorio",
    subtitle: "Per prodotto · dati ufficiali 2.1.17 · offline",
    production: "Produzione",
    quality: "Qualità",
    science: "Ricerca",
    energy: "Energia",
    recycling: "Riciclaggio",
    qualityRecycling: "Riciclaggio qualità",
    language: "Lingua",
    productRoute: "Prodotto e percorso",
    product: "Prodotto",
    recipeRoute: "Ricetta",
    productionMachine: "Macchina di produzione",
    targetRate: "Velocità obiettivo",
    amount: "Quantità",
    unit: "Unità",
    desiredOutput: "Produzione desiderata",
    inputLimited: "Limitato dall'ingresso",
    targetQuality: "Qualità obiettivo",
    ingredientQuality: "Qualità ingredienti",
    machineQuality: "Qualità macchina",
    maximumQuality: "Qualità massima ricercata",
    modules: "Moduli",
    machineModules: "Moduli macchina",
    beaconModules: "Moduli faro",
    beacons: "Fari",
    enabled: "Attivi",
    disabled: "Disattivi",
    activePerMachine: "Attivi per macchina",
    beaconQuality: "Qualità faro",
    automatic: "Automatico",
    manual: "Manuale",
    tier: "Livello",
    moduleQuality: "Qualità modulo",
    slots: "slot",
    addProduct: "Aggiungi prodotto",
    remove: "Rimuovi",
    allQualities: "Tutte le qualità",
    selectProduct: "Seleziona prodotto",
    searchProducts: "Cerca prodotti e fluidi…",
    noMatch: "Nessun prodotto.",
    available: "disponibili",
    route: "Percorso",
    machine: "Macchina",
    ingredients: "Ingredienti",
    outputs: "Prodotti",
    machinesRequired: "Macchine necessarie",
    theoretical: "teoriche",
    build: "da costruire",
    utilization: "Utilizzo",
    power: "Energia",
    directPower: "Impianto diretto",
    chainPower: "Catena a monte",
    includeEnergy: "Includi nel calcolo energia",
    productionChain: "Catena di produzione",
    showChain: "Mostra catena completa",
    hideChain: "Nascondi catena",
    nodeSetup: "Ricetta e macchina",
    nodeModules: "Moduli e fari",
    rawSource: "Fonte grezza",
    logistics: "Logistica per macchina",
    inserter: "Inseritore",
    inserterQuality: "Qualità inseritore",
    capacityResearch: "Ricerca capacità",
    handoff: "Trasferimento",
    inputLoad: "Carico ingresso",
    outputLoad: "Carico uscita",
    perMachine: "per macchina",
    geometryCheck: "Verifica geometrica",
    beaconDesign: "Design fari",
    zoom: "Zoom",
    actualSpm: "Pacchetti reali/min",
    effectiveSpm: "Ricerca effettiva/min",
    lab: "Laboratorio",
    biolab: "Biolaboratorio",
    labType: "Edificio di ricerca",
    packQuality: "Qualità pacchetto",
    beaconsOff: "Fari disattivi",
    forcedRing: "Anello completo di 16 fari",
    manualMw: "Domanda manuale",
    importedLoads: "Carichi selezionati",
    targetDemand: "Domanda obiettivo",
    reserve: "Riserva",
    technology: "Tecnologia energetica",
    planet: "Pianeta / orbita",
    steam: "Energia a vapore",
    solar: "Solare e accumulatori",
    nuclear: "Energia nucleare",
    heatingTower: "Torre di riscaldamento",
    fusion: "Energia a fusione",
    demandSizing: "Dimensiona per domanda",
    fixedBlock: "Esamina blocco fisso",
    reactorBlock: "Reattori per blocco",
    grossOutput: "Produzione lorda",
    netOutput: "Produzione netta",
    internalDemand: "Consumo interno",
    entities: "Entità",
    fuelAndFluids: "Combustibile e fluidi",
    recycleProduct: "Prodotto da riciclare",
    recyclerQuality: "Qualità riciclatore",
    expectedOutputs: "Ritorni previsti",
    recycleTime: "Tempo di riciclo",
    throughput: "Portata",
    lostFluids: "Ingredienti fluidi persi",
    warnings: "Note e avvisi",
    noQualityFluids: "I fluidi non hanno qualità.",
    normalModeQualityNotice:
      "I moduli qualità manuali influenzano velocità ed energia. Usa Produzione qualità per la distribuzione.",
    qualitySafeBeacon:
      "L'impostazione sicura limita la velocità a un faro con uno slot occupato, perché la velocità riduce la qualità. È modificabile manualmente.",
    passiveSpoilage: "Deperimento passivo",
    clickIngredient: "Calcola questo ingrediente",
    reset: "Ripristina",
    addInput: "Aggiungi vincolo",
    fluid: "Fluido",
    item: "Oggetto",
    recipeCount: "ricette giocatore",
    productCount: "prodotti",
    fullChain: "Catena completa",
    actual: "Reale",
    effective: "Effettivo",
    imported: "Importato",
    sourceSelection: "Selezione carichi",
    normalQuality: "Produzione normale",
    qualityProduction: "Produzione di qualità",
  },
  ja: {
    title: "Factorio 生産計算機",
    subtitle: "製品優先・公式2.1.17データ・オフライン対応",
    production: "生産",
    quality: "品質",
    science: "研究",
    energy: "電力",
    recycling: "リサイクル",
    qualityRecycling: "品質リサイクル",
    language: "言語",
    productRoute: "製品とレシピ",
    product: "製品",
    recipeRoute: "レシピ",
    productionMachine: "生産機械",
    targetRate: "目標速度",
    amount: "数量",
    unit: "単位",
    desiredOutput: "必要な生産量",
    inputLimited: "材料で制限",
    targetQuality: "目標品質",
    ingredientQuality: "材料品質",
    machineQuality: "機械品質",
    maximumQuality: "研究済み最高品質",
    modules: "モジュール",
    machineModules: "機械モジュール",
    beaconModules: "ビーコンモジュール",
    beacons: "ビーコン",
    enabled: "有効",
    disabled: "無効",
    activePerMachine: "機械ごとの有効数",
    beaconQuality: "ビーコン品質",
    automatic: "自動",
    manual: "手動",
    tier: "レベル",
    moduleQuality: "モジュール品質",
    slots: "スロット",
    addProduct: "製品を追加",
    remove: "削除",
    allQualities: "全品質",
    selectProduct: "製品を選択",
    searchProducts: "製品と流体を検索…",
    noMatch: "該当製品なし",
    available: "件",
    route: "レシピ",
    machine: "機械",
    ingredients: "材料",
    outputs: "生産物",
    machinesRequired: "必要機械数",
    theoretical: "理論値",
    build: "設置数",
    utilization: "稼働率",
    power: "電力",
    directPower: "直接設備",
    chainPower: "上流工程",
    includeEnergy: "電力計算に含める",
    productionChain: "生産チェーン",
    showChain: "全生産チェーンを表示",
    hideChain: "チェーンを隠す",
    nodeSetup: "レシピと機械",
    nodeModules: "モジュールとビーコン",
    rawSource: "資源源",
    logistics: "機械物流",
    inserter: "インサータ",
    inserterQuality: "インサータ品質",
    capacityResearch: "容量研究",
    handoff: "受け渡し",
    inputLoad: "入力負荷",
    outputLoad: "出力負荷",
    perMachine: "機械ごと",
    geometryCheck: "配置確認",
    beaconDesign: "ビーコン配置",
    zoom: "ズーム",
    actualSpm: "実消費パック/分",
    effectiveSpm: "有効研究/分",
    lab: "研究所",
    biolab: "バイオ研究所",
    labType: "研究施設",
    packQuality: "サイエンスパック品質",
    beaconsOff: "ビーコンなし",
    forcedRing: "16ビーコン完全リング",
    manualMw: "手動需要",
    importedLoads: "選択した負荷",
    targetDemand: "目標需要",
    reserve: "予備率",
    technology: "発電方式",
    planet: "惑星 / 軌道",
    steam: "蒸気発電",
    solar: "太陽光と蓄電池",
    nuclear: "原子力",
    heatingTower: "加熱塔",
    fusion: "核融合",
    demandSizing: "需要に合わせる",
    fixedBlock: "固定ブロックを確認",
    reactorBlock: "ブロック当たり炉数",
    grossOutput: "総出力",
    netOutput: "正味出力",
    internalDemand: "内部消費",
    entities: "設備",
    fuelAndFluids: "燃料と流体",
    recycleProduct: "リサイクル製品",
    recyclerQuality: "リサイクラー品質",
    expectedOutputs: "期待回収量",
    recycleTime: "処理時間",
    throughput: "処理量",
    lostFluids: "失われる流体材料",
    warnings: "注記と警告",
    noQualityFluids: "流体自体には品質がありません。",
    normalModeQualityNotice:
      "手動品質モジュールは速度と電力に反映されます。品質分布は品質生産で確認してください。",
    qualitySafeBeacon:
      "速度は品質を下げるため、安全設定ではビーコン1台・1スロットに制限します。手動で上書きできます。",
    passiveSpoilage: "自然腐敗",
    clickIngredient: "この材料を計算",
    reset: "リセット",
    addInput: "入力制限を追加",
    fluid: "流体",
    item: "アイテム",
    recipeCount: "プレイヤーレシピ",
    productCount: "製品",
    fullChain: "全チェーン",
    actual: "実際",
    effective: "有効",
    imported: "取り込み",
    sourceSelection: "電力負荷選択",
    normalQuality: "通常生産",
    qualityProduction: "品質生産",
  },
  ru: {
    title: "Калькулятор производства Factorio",
    subtitle: "По продукту · официальные данные 2.1.17 · офлайн",
    production: "Производство",
    quality: "Качество",
    science: "Наука",
    energy: "Энергия",
    recycling: "Переработка",
    qualityRecycling: "Качественная переработка",
    language: "Язык",
    productRoute: "Продукт и способ",
    product: "Продукт",
    recipeRoute: "Рецепт",
    productionMachine: "Производственная машина",
    targetRate: "Целевая скорость",
    amount: "Количество",
    unit: "Единица",
    desiredOutput: "Желаемый выпуск",
    inputLimited: "Ограничено сырьём",
    targetQuality: "Целевое качество",
    ingredientQuality: "Качество ингредиентов",
    machineQuality: "Качество машины",
    maximumQuality: "Максимальное изученное качество",
    modules: "Модули",
    machineModules: "Модули машины",
    beaconModules: "Модули маяка",
    beacons: "Маяки",
    enabled: "Включены",
    disabled: "Выключены",
    activePerMachine: "На машину",
    beaconQuality: "Качество маяка",
    automatic: "Авто",
    manual: "Вручную",
    tier: "Уровень",
    moduleQuality: "Качество модуля",
    slots: "слотов",
    addProduct: "Добавить продукт",
    remove: "Удалить",
    allQualities: "Все качества",
    selectProduct: "Выберите продукт",
    searchProducts: "Поиск продуктов и жидкостей…",
    noMatch: "Совпадений нет.",
    available: "доступно",
    route: "Способ",
    machine: "Машина",
    ingredients: "Ингредиенты",
    outputs: "Продукты",
    machinesRequired: "Нужно машин",
    theoretical: "теоретически",
    build: "построить",
    utilization: "Загрузка",
    power: "Энергия",
    directPower: "Прямая установка",
    chainPower: "Предыдущая цепь",
    includeEnergy: "Учесть в калькуляторе энергии",
    productionChain: "Производственная цепь",
    showChain: "Показать всю цепь",
    hideChain: "Скрыть цепь",
    nodeSetup: "Рецепт и машина",
    nodeModules: "Модули и маяки",
    rawSource: "Источник сырья",
    logistics: "Логистика машины",
    inserter: "Манипулятор",
    inserterQuality: "Качество манипулятора",
    capacityResearch: "Исследование вместимости",
    handoff: "Передача",
    inputLoad: "Входная нагрузка",
    outputLoad: "Выходная нагрузка",
    perMachine: "на машину",
    geometryCheck: "Проверка геометрии",
    beaconDesign: "Схема маяков",
    zoom: "Масштаб",
    actualSpm: "Фактические пакеты/мин",
    effectiveSpm: "Эффективная наука/мин",
    lab: "Лаборатория",
    biolab: "Биолаборатория",
    labType: "Исследовательское здание",
    packQuality: "Качество пакета",
    beaconsOff: "Маяки выключены",
    forcedRing: "Полное кольцо из 16 маяков",
    manualMw: "Ручной спрос",
    importedLoads: "Выбранные нагрузки",
    targetDemand: "Целевая мощность",
    reserve: "Резерв",
    technology: "Тип энергии",
    planet: "Планета / орбита",
    steam: "Паровая энергия",
    solar: "Солнечная и аккумуляторы",
    nuclear: "Ядерная энергия",
    heatingTower: "Нагревательная башня",
    fusion: "Термоядерная энергия",
    demandSizing: "По потребности",
    fixedBlock: "Фиксированный блок",
    reactorBlock: "Реакторов в блоке",
    grossOutput: "Валовая мощность",
    netOutput: "Чистая мощность",
    internalDemand: "Собственное потребление",
    entities: "Объекты",
    fuelAndFluids: "Топливо и жидкости",
    recycleProduct: "Продукт для переработки",
    recyclerQuality: "Качество переработчика",
    expectedOutputs: "Ожидаемый возврат",
    recycleTime: "Время переработки",
    throughput: "Пропускная способность",
    lostFluids: "Потерянные жидкие ингредиенты",
    warnings: "Примечания и предупреждения",
    noQualityFluids: "Жидкости не имеют качества.",
    normalModeQualityNotice:
      "Ручные модули качества влияют на скорость и энергию. Распределение смотрите в режиме качества.",
    qualitySafeBeacon:
      "Безопасная настройка ограничивает скорость одним маяком с одним слотом, так как скорость снижает качество. Можно изменить вручную.",
    passiveSpoilage: "Естественная порча",
    clickIngredient: "Рассчитать ингредиент",
    reset: "Сбросить",
    addInput: "Добавить ограничение",
    fluid: "Жидкость",
    item: "Предмет",
    recipeCount: "рецептов игрока",
    productCount: "продуктов",
    fullChain: "Вся цепь",
    actual: "Фактически",
    effective: "Эффективно",
    imported: "Импортировано",
    sourceSelection: "Выбор энергопотребления",
    normalQuality: "Обычное производство",
    qualityProduction: "Качественное производство",
  },
  "zh-CN": {
    title: "Factorio 生产计算器",
    subtitle: "按产品计算 · 官方2.1.17数据 · 可离线使用",
    production: "生产",
    quality: "品质",
    science: "科研",
    energy: "能源",
    recycling: "回收",
    qualityRecycling: "品质回收",
    language: "语言",
    productRoute: "产品与配方",
    product: "产品",
    recipeRoute: "配方路线",
    productionMachine: "生产机器",
    targetRate: "目标速率",
    amount: "数量",
    unit: "单位",
    desiredOutput: "期望产出",
    inputLimited: "按输入限制",
    targetQuality: "目标品质",
    ingredientQuality: "原料品质",
    machineQuality: "机器品质",
    maximumQuality: "已研究最高品质",
    modules: "插件",
    machineModules: "机器插件",
    beaconModules: "插件塔插件",
    beacons: "插件塔",
    enabled: "开启",
    disabled: "关闭",
    activePerMachine: "每台机器生效数",
    beaconQuality: "插件塔品质",
    automatic: "自动",
    manual: "手动",
    tier: "等级",
    moduleQuality: "插件品质",
    slots: "插槽",
    addProduct: "添加产品",
    remove: "删除",
    allQualities: "全部品质",
    selectProduct: "选择产品",
    searchProducts: "搜索产品和流体…",
    noMatch: "没有匹配产品。",
    available: "可选",
    route: "路线",
    machine: "机器",
    ingredients: "原料",
    outputs: "产物",
    machinesRequired: "所需机器",
    theoretical: "理论值",
    build: "建造",
    utilization: "利用率",
    power: "电力",
    directPower: "直接设施",
    chainPower: "上游生产链",
    includeEnergy: "计入能源计算器",
    productionChain: "生产链",
    showChain: "显示完整生产链",
    hideChain: "隐藏生产链",
    nodeSetup: "配方与机器",
    nodeModules: "插件与插件塔",
    rawSource: "原始资源",
    logistics: "单机物流",
    inserter: "机械臂",
    inserterQuality: "机械臂品质",
    capacityResearch: "容量研究",
    handoff: "搬运方式",
    inputLoad: "输入负载",
    outputLoad: "输出负载",
    perMachine: "每台机器",
    geometryCheck: "几何检查",
    beaconDesign: "插件塔布局",
    zoom: "缩放",
    actualSpm: "实际科技包/分钟",
    effectiveSpm: "有效科研/分钟",
    lab: "研究中心",
    biolab: "生物研究中心",
    labType: "研究设施",
    packQuality: "科技包品质",
    beaconsOff: "关闭插件塔",
    forcedRing: "完整16塔环",
    manualMw: "手动需求",
    importedLoads: "选定计算负载",
    targetDemand: "目标需求",
    reserve: "余量",
    technology: "发电方式",
    planet: "星球 / 轨道",
    steam: "蒸汽发电",
    solar: "太阳能与蓄电池",
    nuclear: "核电",
    heatingTower: "供热塔",
    fusion: "聚变发电",
    demandSizing: "按需求配置",
    fixedBlock: "查看固定反应堆组",
    reactorBlock: "每组反应堆数",
    grossOutput: "总输出",
    netOutput: "净支持输出",
    internalDemand: "内部耗电",
    entities: "设施",
    fuelAndFluids: "燃料与流体",
    recycleProduct: "待回收产品",
    recyclerQuality: "回收机品质",
    expectedOutputs: "期望返还",
    recycleTime: "回收时间",
    throughput: "吞吐量",
    lostFluids: "损失的流体原料",
    warnings: "说明与警告",
    noQualityFluids: "流体本身没有品质。",
    normalModeQualityNotice:
      "手动品质插件会影响速度和耗电；品质分布请在品质生产中查看。",
    qualitySafeBeacon:
      "速度会降低品质，因此安全默认仅用一个插件塔的一个插槽。可手动覆盖。",
    passiveSpoilage: "自然变质",
    clickIngredient: "计算此原料",
    reset: "重置",
    addInput: "添加输入限制",
    fluid: "流体",
    item: "物品",
    recipeCount: "玩家配方",
    productCount: "产品",
    fullChain: "完整生产链",
    actual: "实际",
    effective: "有效",
    imported: "已导入",
    sourceSelection: "能源负载选择",
    normalQuality: "普通生产",
    qualityProduction: "品质生产",
  },
  "zh-TW": {
    title: "Factorio 生產計算器",
    subtitle: "按產品計算 · 官方2.1.17資料 · 可離線使用",
    production: "生產",
    quality: "品質",
    science: "研究",
    energy: "能源",
    recycling: "回收",
    qualityRecycling: "品質回收",
    language: "語言",
    productRoute: "產品與配方",
    product: "產品",
    recipeRoute: "配方路線",
    productionMachine: "生產機器",
    targetRate: "目標速率",
    amount: "數量",
    unit: "單位",
    desiredOutput: "期望產出",
    inputLimited: "按輸入限制",
    targetQuality: "目標品質",
    ingredientQuality: "原料品質",
    machineQuality: "機器品質",
    maximumQuality: "已研究最高品質",
    modules: "插件",
    machineModules: "機器插件",
    beaconModules: "插件塔插件",
    beacons: "插件塔",
    enabled: "開啟",
    disabled: "關閉",
    activePerMachine: "每台機器生效數",
    beaconQuality: "插件塔品質",
    automatic: "自動",
    manual: "手動",
    tier: "等級",
    moduleQuality: "插件品質",
    slots: "插槽",
    addProduct: "新增產品",
    remove: "移除",
    allQualities: "全部品質",
    selectProduct: "選擇產品",
    searchProducts: "搜尋產品與流體…",
    noMatch: "沒有相符產品。",
    available: "可選",
    route: "路線",
    machine: "機器",
    ingredients: "原料",
    outputs: "產物",
    machinesRequired: "所需機器",
    theoretical: "理論值",
    build: "建造",
    utilization: "利用率",
    power: "電力",
    directPower: "直接設施",
    chainPower: "上游生產鏈",
    includeEnergy: "納入能源計算器",
    productionChain: "生產鏈",
    showChain: "顯示完整生產鏈",
    hideChain: "隱藏生產鏈",
    nodeSetup: "配方與機器",
    nodeModules: "插件與插件塔",
    rawSource: "原始資源",
    logistics: "單機物流",
    inserter: "機械臂",
    inserterQuality: "機械臂品質",
    capacityResearch: "容量研究",
    handoff: "搬運方式",
    inputLoad: "輸入負載",
    outputLoad: "輸出負載",
    perMachine: "每台機器",
    geometryCheck: "幾何檢查",
    beaconDesign: "插件塔配置",
    zoom: "縮放",
    actualSpm: "實際科技包/分鐘",
    effectiveSpm: "有效研究/分鐘",
    lab: "研究中心",
    biolab: "生物研究中心",
    labType: "研究設施",
    packQuality: "科技包品質",
    beaconsOff: "關閉插件塔",
    forcedRing: "完整16塔環",
    manualMw: "手動需求",
    importedLoads: "選定計算負載",
    targetDemand: "目標需求",
    reserve: "餘量",
    technology: "發電方式",
    planet: "星球 / 軌道",
    steam: "蒸汽發電",
    solar: "太陽能與蓄電池",
    nuclear: "核能發電",
    heatingTower: "供熱塔",
    fusion: "核融合發電",
    demandSizing: "按需求配置",
    fixedBlock: "查看固定反應爐組",
    reactorBlock: "每組反應爐數",
    grossOutput: "總輸出",
    netOutput: "淨支援輸出",
    internalDemand: "內部耗電",
    entities: "設施",
    fuelAndFluids: "燃料與流體",
    recycleProduct: "待回收產品",
    recyclerQuality: "回收機品質",
    expectedOutputs: "期望返還",
    recycleTime: "回收時間",
    throughput: "吞吐量",
    lostFluids: "損失的流體原料",
    warnings: "說明與警告",
    noQualityFluids: "流體本身沒有品質。",
    normalModeQualityNotice:
      "手動品質插件會影響速度與耗電；品質分布請在品質生產中查看。",
    qualitySafeBeacon:
      "速度會降低品質，因此安全預設僅用一個插件塔的一個插槽。可手動覆寫。",
    passiveSpoilage: "自然變質",
    clickIngredient: "計算此原料",
    reset: "重設",
    addInput: "新增輸入限制",
    fluid: "流體",
    item: "物品",
    recipeCount: "玩家配方",
    productCount: "產品",
    fullChain: "完整生產鏈",
    actual: "實際",
    effective: "有效",
    imported: "已匯入",
    sourceSelection: "能源負載選擇",
    normalQuality: "普通生產",
    qualityProduction: "品質生產",
  },
};

const supplemental: Record<Locale, Partial<Record<UiKey, string>>> = {
  en: {},
  de: {
    invalidSetup: "Dieses Setup kann nicht berechnet werden",
    craftingSpeed: "Herstellungsgeschwindigkeit",
    width: "Breite",
    height: "Höhe",
    blocks: "Blöcke",
    previewCapped:
      "Die Vorschau ist begrenzt; die Summen umfassen alle Maschinen.",
    solidRecycleReturn:
      "Erwartet werden 25 % der festen Rezeptzutaten; flüssige Zutaten werden vernichtet.",
    steamFuelNote:
      "Der Brennstoffbedarf verwendet Kohle mit 4 MJ pro Stück; andere Brennstoffe skalieren nach ihrem Energiewert.",
    solarAverageNote:
      "Angezeigt wird die dauerhaft gemittelte Leistung; die Spitzenleistung ist höher.",
    solarScalingNote:
      "Sonnenintensität und Qualität werden vor der Tag-Nacht-Mittelung angewendet.",
    nuclearNeighborNote:
      "Jeder direkt angrenzende befeuerte Reaktor ergänzt 100 % seiner Grundwärmeleistung.",
    heatingEfficiencyNote:
      "Ein normaler Heizturm wandelt bei 250 % Wirkungsgrad 16 MW Brennstoff in 40 MW Wärme um.",
    fusionDemandNote:
      "Der Verbrauch von Fusionsenergiezellen folgt dem tatsächlichen Netzbedarf.",
    fusionCoolantNote:
      "Kaltes Fluorketon ist ein geschlossener Umlauf und kein dauerhafter Verbrauch.",
    steamOrientation:
      "Die Vorschau gruppiert Kessel und gewählte Dampferzeuger aufrecht in Reihen und zeigt ihr gewähltes Verhältnis; Wasser und Dampf werden im Spiel verbunden.",
    solarOrientation:
      "Solarmodule und Akkumulatoren stehen im Verhältnis des gewählten Planeten und der gewählten Qualität; beide haben keine Ausrichtung.",
    nuclearOrientation:
      "Reaktoren behalten ihr kardinales Raster; Wärmetauscher und gewählte Generatoren werden aufrecht und nach Typ in Reihen gruppiert.",
    heatingOrientation:
      "Heizturm, Wärmetauscher und gewählte Generatoren werden im aktuellen Verhältnis aufrecht und nach Typ in Reihen gruppiert.",
    fusionOrientation:
      "Die Reaktoren behalten ihr Nachbarschaftsmuster; Fusionsgeneratoren und Kryoanlagen stehen aufrecht in Reihen. Plasma- und Fluidverbindungen werden absichtlich nicht gezeichnet.",
  },
  "es-ES": {
    invalidSetup: "No se puede calcular esta configuración",
    craftingSpeed: "Velocidad de fabricación",
    width: "Anchura",
    height: "Altura",
    blocks: "bloques",
    previewCapped:
      "La vista previa está limitada; los totales incluyen todas las máquinas.",
    solidRecycleReturn:
      "El retorno esperado es el 25 % de los ingredientes sólidos; los ingredientes fluidos se destruyen.",
    steamFuelNote:
      "La demanda de combustible usa carbón de 4 MJ por objeto; otros combustibles escalan por su valor energético.",
    solarAverageNote:
      "Se muestra la potencia media sostenida; la potencia máxima es mayor.",
    solarScalingNote:
      "La intensidad solar y la calidad se aplican antes del promedio día/noche.",
    nuclearNeighborNote:
      "Cada reactor alimentado adyacente añade el 100 % de su calor base.",
    heatingEfficiencyNote:
      "Una torre normal convierte 16 MW de combustible en 40 MW de calor con un 250 % de eficiencia.",
    fusionDemandNote:
      "El consumo de celdas de fusión sigue la demanda real de la red.",
    fusionCoolantNote:
      "La fluorocetona fría circula en un circuito cerrado; no es un consumo continuo.",
  },
  fr: {
    invalidSetup: "Cette configuration ne peut pas être calculée",
    craftingSpeed: "Vitesse de fabrication",
    width: "Largeur",
    height: "Hauteur",
    blocks: "blocs",
    previewCapped:
      "L’aperçu est limité ; les totaux incluent toutes les machines.",
    solidRecycleReturn:
      "Le retour attendu est de 25 % des ingrédients solides ; les ingrédients fluides sont détruits.",
    steamFuelNote:
      "La demande de combustible utilise du charbon à 4 MJ par objet ; les autres combustibles suivent leur valeur énergétique.",
    solarAverageNote:
      "Le résultat affiché est la puissance moyenne soutenue ; la puissance de pointe est supérieure.",
    solarScalingNote:
      "L’intensité solaire et la qualité sont appliquées avant la moyenne jour/nuit.",
    nuclearNeighborNote:
      "Chaque réacteur alimenté adjacent ajoute 100 % de sa chaleur de base.",
    heatingEfficiencyNote:
      "Une tour thermique normale convertit 16 MW de combustible en 40 MW de chaleur avec un rendement de 250 %.",
    fusionDemandNote:
      "La consommation de cellules de fusion suit la demande réelle du réseau.",
    fusionCoolantNote:
      "La fluorocétone froide circule en boucle fermée et n’est pas consommée en continu.",
  },
  it: {
    invalidSetup: "Questa configurazione non può essere calcolata",
    craftingSpeed: "Velocità di produzione",
    width: "Larghezza",
    height: "Altezza",
    blocks: "blocchi",
    previewCapped:
      "L’anteprima è limitata; i totali includono tutte le macchine.",
    solidRecycleReturn:
      "Il ritorno previsto è il 25% degli ingredienti solidi; gli ingredienti fluidi vengono distrutti.",
    steamFuelNote:
      "Il consumo di combustibile usa carbone da 4 MJ per oggetto; gli altri combustibili scalano in base al valore energetico.",
    solarAverageNote:
      "È mostrata la potenza media continua; la potenza di picco è superiore.",
    solarScalingNote:
      "Intensità solare e qualità vengono applicate prima della media giorno/notte.",
    nuclearNeighborNote:
      "Ogni reattore alimentato adiacente aggiunge il 100% del proprio calore base.",
    heatingEfficiencyNote:
      "Una torre normale trasforma 16 MW di combustibile in 40 MW di calore con efficienza del 250%.",
    fusionDemandNote:
      "Il consumo delle celle a fusione segue la domanda reale della rete.",
    fusionCoolantNote:
      "Il fluorochetone freddo circola a ciclo chiuso e non viene consumato continuamente.",
  },
  ja: {
    invalidSetup: "この設定は計算できません",
    craftingSpeed: "製作速度",
    width: "幅",
    height: "高さ",
    blocks: "ブロック",
    previewCapped:
      "プレビューは一部のみ表示されますが、合計値には全機械が含まれます。",
    solidRecycleReturn:
      "固体レシピ材料の期待回収率は25%です。流体材料は失われます。",
    steamFuelNote:
      "燃料需要は1個4 MJの石炭を基準とし、他の燃料は発熱量で換算します。",
    solarAverageNote:
      "表示値は持続平均出力で、最大出力はこれより高くなります。",
    solarScalingNote: "太陽光強度と品質を適用してから昼夜平均を計算します。",
    nuclearNeighborNote:
      "上下左右に接する稼働中の原子炉ごとに基本熱出力が100%加算されます。",
    heatingEfficiencyNote:
      "通常品質の加熱塔は250%効率で16 MWの燃料を40 MWの熱に変換します。",
    fusionDemandNote: "核融合燃料セルの消費量は実際の電力需要に追従します。",
    fusionCoolantNote:
      "低温フルオロケトンは閉ループで循環し、継続的には消費されません。",
  },
  ru: {
    invalidSetup: "Эту конфигурацию невозможно рассчитать",
    craftingSpeed: "Скорость производства",
    width: "Ширина",
    height: "Высота",
    blocks: "блоки",
    previewCapped:
      "Предпросмотр ограничен; итоговые значения учитывают все машины.",
    solidRecycleReturn:
      "Ожидаемый возврат составляет 25% твёрдых ингредиентов; жидкие ингредиенты уничтожаются.",
    steamFuelNote:
      "Расход топлива рассчитан по углю с энергией 4 МДж; другие виды топлива масштабируются по энергоёмкости.",
    solarAverageNote:
      "Показана средняя постоянная мощность; пиковая мощность выше.",
    solarScalingNote:
      "Интенсивность света и качество учитываются до усреднения дня и ночи.",
    nuclearNeighborNote:
      "Каждый соседний работающий реактор добавляет 100% своей базовой тепловой мощности.",
    heatingEfficiencyNote:
      "Обычная нагревательная башня превращает 16 МВт топлива в 40 МВт тепла с КПД 250%.",
    fusionDemandNote:
      "Расход термоядерных топливных элементов следует фактической нагрузке сети.",
    fusionCoolantNote:
      "Холодный фторкетон циркулирует в замкнутом контуре и не расходуется постоянно.",
  },
  "zh-CN": {
    invalidSetup: "无法计算此配置",
    craftingSpeed: "制造速度",
    width: "宽度",
    height: "高度",
    blocks: "区块",
    previewCapped: "预览数量有限；总计包含全部机器。",
    solidRecycleReturn: "固体配方原料的期望返还率为25%；流体原料会被销毁。",
    steamFuelNote: "燃料需求按每个4 MJ的煤计算；其他燃料按热值换算。",
    solarAverageNote: "显示的是持续平均功率；峰值功率更高。",
    solarScalingNote: "太阳能强度与品质在昼夜平均之前计算。",
    nuclearNeighborNote: "每个直接相邻且工作的反应堆会增加其基础热输出的100%。",
    heatingEfficiencyNote: "普通供热塔以250%效率将16 MW燃料转化为40 MW热量。",
    fusionDemandNote: "聚变燃料棒的消耗量随电网实际需求变化。",
    fusionCoolantNote: "低温氟酮在闭环中循环，并非持续消耗。",
  },
  "zh-TW": {
    invalidSetup: "無法計算此配置",
    craftingSpeed: "製造速度",
    width: "寬度",
    height: "高度",
    blocks: "區塊",
    previewCapped: "預覽數量有限；總計包含所有機器。",
    solidRecycleReturn: "固體配方原料的預期返還率為25%；流體原料會被銷毀。",
    steamFuelNote: "燃料需求按每個4 MJ的煤計算；其他燃料按熱值換算。",
    solarAverageNote: "顯示的是持續平均功率；峰值功率更高。",
    solarScalingNote: "太陽能強度與品質在晝夜平均之前計算。",
    nuclearNeighborNote: "每個直接相鄰且運作的反應爐會增加其基礎熱輸出的100%。",
    heatingEfficiencyNote: "普通供熱塔以250%效率將16 MW燃料轉化為40 MW熱量。",
    fusionDemandNote: "核融合燃料棒的消耗量隨電網實際需求變化。",
    fusionCoolantNote: "低溫氟酮在閉環中循環，並非持續消耗。",
  },
};

const refinementTranslations: Record<
  Locale,
  Partial<Record<UiKey, string>>
> = {
  en: {},
  de: {
    qualityBeaconMode: "Qualitätsschonend · 1 Effektverteiler / 1 Slot",
    cargoBayQuality: "Frachtraumqualität",
    ignoreInsertion: "Beladung ignorieren",
    experimentalRobotLoading:
      "Experimentell: Jedes Silo nutzt eine volle Pufferkiste, einen Greifarm und den dargestellten lokalen Roboterhangar. Der Roboterflug wird nur für diese kompakte Strecke geschätzt; maximal sind 15 Effektverteiler möglich.",
    ignoreInsertionWarning:
      "Die Beladung wird ignoriert. Raketen gelten als sofort gefüllt oder vorgeladen; Zeiten und Strombedarf von Kisten, Greifarmen und Robotern entfallen. Dadurch bleibt der vollständige Ring aus 16 Effektverteilern möglich.",
    logisticRobotCount: "Roboter je Roboterhangar",
    workerRobotSpeedResearch: "Robotergeschwindigkeitsforschung",
    workerRobotCargoResearch: "Robotertransportmengenforschung",
    robotFlightTime: "Einfacher Roboterflug",
    robotSupplyTime: "Roboterzufuhr zur Kiste",
    bufferChestAssumption:
      "Experimentelle Annahme: Jede dargestellte Pufferkiste ist zu Beginn voll. Die Roboterzeit umfasst nur den lokalen Weg vom Roboterhangar zur Kiste; entfernte Anbieter, Stau und Ladewarteschlangen sind nicht enthalten.",
    payloadWaveTitle: "Die Frachtcharge – nicht die Silogeschwindigkeit – bestimmt diese Bauzahl",
    payloadWaveExplanation:
      "Alle Raketen einer ankommenden Plattformcharge müssen gleichzeitig bereitstehen, daher wird je Rakete ein vorgeladenes Silo reserviert. Schnellere Silos senken die angezeigte Zahl erst, wenn der dauerhafte Startdurchsatz zum größeren Bedarf wird oder die Fracht je Umlauf sinkt.",
  },
  "es-ES": {
    qualityBeaconMode: "Protección de calidad · 1 faro / 1 ranura",
    cargoBayQuality: "Calidad de la bahía de carga",
    ignoreInsertion: "Ignorar inserción",
    experimentalRobotLoading: "Experimental: cada silo usa un cofre solicitador lleno, un brazo y el robopuerto local mostrado. El vuelo se estima solo para este tramo compacto; el máximo físico es de 15 faros.",
    ignoreInsertionWarning: "Se ignora la inserción. Los cohetes se consideran llenos al instante o precargados; no se incluyen tiempo ni energía de cofres, brazos o robots. Así se permiten los 16 faros.",
    logisticRobotCount: "Robots por robopuerto",
    workerRobotSpeedResearch: "Investigación de velocidad de robots",
    workerRobotCargoResearch: "Investigación de carga de robots",
    robotFlightTime: "Vuelo de ida del robot",
    robotSupplyTime: "Suministro robotizado al cofre",
    bufferChestAssumption: "Supuesto experimental: cada cofre solicitador mostrado empieza lleno. El tiempo solo cubre el tramo local entre robopuerto y cofre; excluye proveedores remotos, congestión y colas de recarga.",
    payloadWaveTitle: "El lote de carga, no la velocidad del silo, fija esta cantidad",
    payloadWaveExplanation: "Todos los cohetes de un lote deben estar listos a la vez, por lo que se reserva un silo precargado por cohete. Los silos más rápidos solo reducen la cifra cuando domina el rendimiento sostenido o se reduce la carga por viaje.",
  },
  fr: {
    qualityBeaconMode: "Préservation de qualité · 1 diffuseur / 1 emplacement",
    cargoBayQuality: "Qualité de la baie de fret",
    ignoreInsertion: "Ignorer l’insertion",
    experimentalRobotLoading: "Expérimental : chaque silo utilise un coffre tampon plein, un bras et le roboport local affiché. Le vol n’est estimé que pour ce trajet compact ; le maximum physique est de 15 diffuseurs.",
    ignoreInsertionWarning: "L’insertion est ignorée. Les fusées sont supposées remplies instantanément ou préchargées ; temps et énergie des coffres, bras et robots sont exclus. L’anneau complet de 16 diffuseurs reste possible.",
    logisticRobotCount: "Robots par roboport",
    workerRobotSpeedResearch: "Recherche de vitesse des robots",
    workerRobotCargoResearch: "Recherche de capacité des robots",
    robotFlightTime: "Vol aller du robot",
    robotSupplyTime: "Approvisionnement du coffre",
    bufferChestAssumption: "Hypothèse expérimentale : chaque coffre tampon affiché est plein au départ. Le temps ne couvre que le trajet local roboport–coffre ; fournisseurs distants, congestion et files de recharge sont exclus.",
    payloadWaveTitle: "Le lot de fret, et non la vitesse du silo, fixe ce nombre",
    payloadWaveExplanation: "Toutes les fusées d’un lot doivent être prêtes ensemble : un silo préchargé est donc réservé par fusée. Des silos plus rapides ne réduisent ce nombre que lorsque le débit soutenu domine, ou si le fret par trajet diminue.",
  },
  it: {
    qualityBeaconMode: "Protezione qualità · 1 faro / 1 slot",
    cargoBayQuality: "Qualità del vano di carico",
    ignoreInsertion: "Ignora inserimento",
    experimentalRobotLoading: "Sperimentale: ogni silo usa una cassa di scorta piena, un inseritore e il roboporto locale mostrato. Il volo è stimato solo per questo breve tratto; il massimo fisico è 15 fari.",
    ignoreInsertionWarning: "L’inserimento viene ignorato. I razzi sono considerati riempiti istantaneamente o precaricati; tempi ed energia di casse, inseritori e robot sono esclusi. Rimane possibile l’anello completo di 16 fari.",
    logisticRobotCount: "Robot per roboporto",
    workerRobotSpeedResearch: "Ricerca velocità robot",
    workerRobotCargoResearch: "Ricerca capacità robot",
    robotFlightTime: "Volo robot di sola andata",
    robotSupplyTime: "Rifornimento robot alla cassa",
    bufferChestAssumption: "Ipotesi sperimentale: ogni cassa di scorta mostrata parte piena. Il tempo copre solo il tratto locale roboporto–cassa; fornitori remoti, congestione e code di ricarica sono esclusi.",
    payloadWaveTitle: "È il lotto di carico, non la velocità del silo, a fissare il numero",
    payloadWaveExplanation: "Tutti i razzi di un lotto devono essere pronti insieme, quindi viene riservato un silo precaricato per razzo. Sili più veloci riducono il numero solo quando prevale la portata sostenuta o diminuisce il carico per viaggio.",
  },
  ja: {
    qualityBeaconMode: "品質優先 · ビーコン1基 / 1スロット",
    cargoBayQuality: "貨物ベイの品質",
    ignoreInsertion: "搬入を無視",
    experimentalRobotLoading: "試験機能：各サイロは満杯のバッファーチェスト、インサータ1基、表示されたロボットステーションを使用します。飛行時間はこの短い区間だけを推定し、ビーコン上限は15基です。",
    ignoreInsertionWarning: "搬入を無視します。ロケットは即時に充填済み、または事前装填済みとみなし、チェスト・インサータ・ロボットの時間と電力を除外します。ビーコン16基を使用できます。",
    logisticRobotCount: "ロボットステーション当たりのロボット数",
    workerRobotSpeedResearch: "ロボット移動速度研究",
    workerRobotCargoResearch: "ロボット運搬量研究",
    robotFlightTime: "ロボット片道飛行",
    robotSupplyTime: "ロボットによるチェスト補給",
    bufferChestAssumption: "試験的な前提：表示された各バッファーチェストは最初から満杯です。時間にはロボットステーションからチェストまでの区間のみを含み、遠方の供給元、渋滞、充電待ちは除外します。",
    payloadWaveTitle: "サイロ速度ではなく貨物バッチが必要数を決めています",
    payloadWaveExplanation: "1回の貨物バッチの全ロケットを同時に準備するため、ロケット1機ごとに事前装填済みサイロを確保します。持続打上げ能力が支配的になるか、1便の貨物量を減らすまで高速化で必要数は減りません。",
  },
  ru: {
    qualityBeaconMode: "Сохранение качества · 1 маяк / 1 слот",
    cargoBayQuality: "Качество грузового отсека",
    ignoreInsertion: "Не учитывать загрузку",
    experimentalRobotLoading: "Экспериментально: каждый бункер использует полный буферный сундук, манипулятор и показанный локальный робопорт. Полёт рассчитывается только для этого короткого участка; максимум — 15 маяков.",
    ignoreInsertionWarning: "Загрузка не учитывается. Ракеты считаются мгновенно заполненными или заранее загруженными; время и энергия сундуков, манипуляторов и роботов исключены. Доступно полное кольцо из 16 маяков.",
    logisticRobotCount: "Роботов в каждом робопорте",
    workerRobotSpeedResearch: "Исследование скорости роботов",
    workerRobotCargoResearch: "Исследование грузоподъёмности роботов",
    robotFlightTime: "Полёт робота в одну сторону",
    robotSupplyTime: "Доставка роботами в сундук",
    bufferChestAssumption: "Экспериментальное допущение: каждый показанный буферный сундук изначально полон. Учитывается лишь локальный путь от робопорта до сундука; удалённые поставщики, заторы и очереди на зарядку исключены.",
    payloadWaveTitle: "Количество задаёт партия груза, а не скорость бункера",
    payloadWaveExplanation: "Все ракеты одной партии должны быть готовы одновременно, поэтому на каждую резервируется заранее загруженный бункер. Ускорение уменьшит число только когда решающей станет постоянная пропускная способность или снизится груз за рейс.",
  },
  "zh-CN": {
    qualityBeaconMode: "保品质 · 1座插件塔 / 1个槽位",
    cargoBayQuality: "货舱品质",
    ignoreInsertion: "忽略装载",
    experimentalRobotLoading: "实验性：每座发射井使用一个装满的缓冲箱、一台机械臂和图示本地机器人指令平台。飞行时间只估算这段短距离；最多可用15座插件塔。",
    ignoreInsertionWarning: "忽略装载。火箭视为立即装满或已预装；不计箱子、机械臂和机器人的时间与耗电，因此可保留完整的16座插件塔。",
    logisticRobotCount: "每座机器人指令平台的机器人",
    workerRobotSpeedResearch: "机器人移动速度研究",
    workerRobotCargoResearch: "机器人载货量研究",
    robotFlightTime: "机器人单程飞行",
    robotSupplyTime: "机器人补给缓冲箱",
    bufferChestAssumption: "实验性假设：图示每个缓冲箱初始均为满载。时间仅包含机器人指令平台到缓冲箱的本地航程，不含远端供货、拥堵和充电排队。",
    payloadWaveTitle: "所需数量由货物批次决定，而非发射井速度",
    payloadWaveExplanation: "同一批次的全部火箭必须同时就绪，因此每枚火箭预留一座已装载发射井。只有持续发射吞吐成为更大约束，或降低每航次货量时，加速才会减少数量。",
  },
  "zh-TW": {
    qualityBeaconMode: "保品質 · 1座插件塔 / 1個欄位",
    cargoBayQuality: "貨艙品質",
    ignoreInsertion: "忽略裝載",
    experimentalRobotLoading: "實驗性：每座發射井使用一個裝滿的緩衝箱、一台機械臂和圖示本地機器人司令塔。飛行時間僅估算這段短距離；最多可用15座插件塔。",
    ignoreInsertionWarning: "忽略裝載。火箭視為立即裝滿或已預載；不計箱子、機械臂與機器人的時間及耗電，因此可保留完整的16座插件塔。",
    logisticRobotCount: "每座機器人司令塔的機器人",
    workerRobotSpeedResearch: "機器人移動速度研究",
    workerRobotCargoResearch: "機器人載貨量研究",
    robotFlightTime: "機器人單程飛行",
    robotSupplyTime: "機器人補給緩衝箱",
    bufferChestAssumption: "實驗性假設：圖示每個緩衝箱初始皆為滿載。時間僅包含機器人司令塔到緩衝箱的本地航程，不含遠端供貨、壅塞與充電排隊。",
    payloadWaveTitle: "所需數量由貨物批次決定，而非發射井速度",
    payloadWaveExplanation: "同一批次的所有火箭必須同時就緒，因此每枚火箭保留一座已預載發射井。只有持續發射吞吐成為較大限制，或降低每航次貨量時，加速才會減少數量。",
  },
};

const v5Translations: Record<Locale, Partial<Record<UiKey, string>>> = {
  en: {},
  de: {
    globalChainMaster: "Übergeordnete Kettenkonfiguration",
    applyAllActiveChains: "Änderungen überschreiben diese Einstellung in allen aktiven Produktketten; spätere lokale Änderungen bleiben lokal.",
    subprocessMachines: "Maschinen je Subprozess",
    subprocessMachineHint: "Lege Rezeptweg und Maschine für jedes wiederkehrende vorgelagerte Produkt fest.",
    insertersRequired: "Benötigte Greifarme",
    moveProductToTop: "Dieses Produkt samt Ergebnissen nach oben verschieben",
    factoryTotals: "Gesamtübersicht aller Produktionen",
    factoryTotalsHint: "Gemeinsame Ressourcen werden summiert; die Maschinen bleiben ihren jeweiligen Produktketten zugeordnet.",
    combinedResources: "Zusammengeführter Ressourcenbedarf",
    productionProcesses: "Produktionsprozesse & Maschinen",
    directInputs: "Direkte Zutaten",
    collapseProductResult: "Dieses Produkt einklappen",
    expandProductResult: "Dieses Produkt ausklappen",
    allChainsGenerated: "Jedes ausgewählte Produkt wird standardmäßig mit seiner vollständigen vorgelagerten Kette berechnet. Die Kette kann direkt beim jeweiligen Produkt ausgeschlossen werden.",
    includeProductionChain: "Vollständige Produktionskette einbeziehen",
    includeProductionChainHint: "Standardmäßig aktiv; ausschalten, um nur die direkten Zutaten dieses Rezepts zu verwenden.",
    chainInserterHint: "Standard-Greifarmkonfiguration für jede vorgelagerte Produktionsmaschine.",
    beltThroughput: "Transportband-Durchsatz",
    beltThroughputHint: "Bandäquivalente und tatsächlich benötigte Bänder für jeden festen Materialstrom der ausgewählten Produktionen.",
    beltType: "Transportband",
    beltStacking: "Transportband-Stapelgröße",
    unstacked: "Ungestapelt",
    stackInserterLevel: "Stapelgreifarm erforscht",
    beltCapacityOne: "Transportbandkapazität 1",
    beltCapacityTwo: "Transportbandkapazität 2",
    splitSharedStreams: "Gemeinsame Materialien nach Produkt trennen",
    splitSharedStreamsHint: "An: Jedes Hauptprodukt erhält einen eigenen Materialstrom. Aus: Der gemeinsame Bedarf wird zusammengeführt.",
    beltCapacity: "Bandkapazität",
    beltEquivalents: "Gefüllte Bänder",
    beltsRequired: "Benötigte Bänder",
    lastBeltLoad: "Auslastung des letzten Bands",
    combinedStream: "Zusammengeführter Strom",
    insertersPerMachine: "Greifarme je Maschine",
  },
  "es-ES": {
    globalChainMaster: "Configuración global de todas las cadenas",
    applyAllActiveChains: "Los cambios sustituyen este ajuste en todas las cadenas activas; los cambios locales posteriores siguen siendo locales.",
    subprocessMachines: "Máquinas por subproceso",
    subprocessMachineHint: "Elige la receta y la máquina para cada producto anterior repetido.",
    insertersRequired: "Brazos necesarios",
    moveProductToTop: "Mover este producto y sus resultados arriba",
    factoryTotals: "Totales de toda la producción",
    factoryTotalsHint: "Los recursos comunes se suman; las máquinas siguen asignadas a cada cadena de producto.",
    combinedResources: "Demanda combinada de recursos",
    productionProcesses: "Procesos y máquinas",
    directInputs: "Ingredientes directos",
    collapseProductResult: "Contraer este producto",
    expandProductResult: "Expandir este producto",
    allChainsGenerated: "Cada producto seleccionado usa por defecto toda su cadena anterior. Desactiva la cadena junto a un producto para excluirla.",
    includeProductionChain: "Incluir la cadena de producción completa",
    includeProductionChainHint: "Activado por defecto; desactívalo para usar solo los ingredientes directos de esta receta.",
    chainInserterHint: "Configuración predeterminada de insertadores para cada máquina de producción anterior.",
    beltThroughput: "Rendimiento de cintas",
    beltThroughputHint: "Cintas equivalentes y completas necesarias para cada flujo de objetos sólidos.",
    beltType: "Cinta transportadora",
    beltStacking: "Tamaño de pila en cinta",
    unstacked: "Sin apilar",
    stackInserterLevel: "Insertador de pila investigado",
    beltCapacityOne: "Capacidad de cinta transportadora 1",
    beltCapacityTwo: "Capacidad de cinta transportadora 2",
    splitSharedStreams: "Separar materiales compartidos por producto",
    splitSharedStreamsHint: "Activado: cada producto principal recibe su propio flujo. Desactivado: se combina la demanda compartida.",
    beltCapacity: "Capacidad de cinta",
    beltEquivalents: "Cintas llenas",
    beltsRequired: "Cintas necesarias",
    lastBeltLoad: "Carga de la última cinta",
    combinedStream: "Flujo combinado",
    insertersPerMachine: "Insertadores por máquina",
  },
  fr: {
    globalChainMaster: "Configuration globale de toutes les chaînes",
    applyAllActiveChains: "Les changements remplacent ce réglage dans toutes les chaînes actives ; les modifications locales suivantes restent locales.",
    subprocessMachines: "Machines par sous-processus",
    subprocessMachineHint: "Choisissez la recette et la machine de chaque produit amont récurrent.",
    insertersRequired: "Bras requis",
    moveProductToTop: "Placer ce produit et ses résultats en tête",
    factoryTotals: "Totaux de toute la production",
    factoryTotalsHint: "Les ressources communes sont additionnées ; les machines restent attribuées à chaque chaîne de produit.",
    combinedResources: "Demande combinée en ressources",
    productionProcesses: "Processus et machines",
    directInputs: "Ingrédients directs",
    collapseProductResult: "Replier ce produit",
    expandProductResult: "Déplier ce produit",
    allChainsGenerated: "Chaque produit sélectionné utilise par défaut toute sa chaîne amont. Désactivez la chaîne d’un produit pour l’exclure.",
    includeProductionChain: "Inclure toute la chaîne de production",
    includeProductionChainHint: "Activé par défaut ; désactivez pour utiliser uniquement les ingrédients directs de cette recette.",
    chainInserterHint: "Configuration par défaut des bras pour chaque machine de production en amont.",
    beltThroughput: "Débit des convoyeurs",
    beltThroughputHint: "Convoyeurs équivalents et entiers requis pour chaque flux d’objets solides.",
    beltType: "Convoyeur",
    beltStacking: "Taille des piles sur convoyeur",
    unstacked: "Sans empilement",
    stackInserterLevel: "Bras empileur recherché",
    beltCapacityOne: "Capacité des convoyeurs 1",
    beltCapacityTwo: "Capacité des convoyeurs 2",
    splitSharedStreams: "Séparer les matériaux communs par produit",
    splitSharedStreamsHint: "Activé : chaque produit principal a son propre flux. Désactivé : la demande commune est regroupée.",
    beltCapacity: "Capacité du convoyeur",
    beltEquivalents: "Convoyeurs remplis",
    beltsRequired: "Convoyeurs requis",
    lastBeltLoad: "Charge du dernier convoyeur",
    combinedStream: "Flux regroupé",
    insertersPerMachine: "Bras par machine",
  },
  it: {
    globalChainMaster: "Configurazione globale di tutte le catene",
    applyAllActiveChains: "Le modifiche sostituiscono questa impostazione in tutte le catene attive; le modifiche locali successive restano locali.",
    subprocessMachines: "Macchine per sottoprocesso",
    subprocessMachineHint: "Scegli ricetta e macchina per ogni prodotto a monte ricorrente.",
    insertersRequired: "Inseritori necessari",
    moveProductToTop: "Sposta in alto questo prodotto e i suoi risultati",
    factoryTotals: "Totali di tutta la produzione",
    factoryTotalsHint: "Le risorse comuni vengono sommate; le macchine restano assegnate a ogni catena di prodotto.",
    combinedResources: "Fabbisogno combinato di risorse",
    productionProcesses: "Processi e macchine",
    directInputs: "Ingredienti diretti",
    collapseProductResult: "Comprimi questo prodotto",
    expandProductResult: "Espandi questo prodotto",
    allChainsGenerated: "Ogni prodotto selezionato usa per impostazione predefinita l’intera catena a monte. Disattiva la catena del singolo prodotto per escluderla.",
    includeProductionChain: "Includi l’intera catena di produzione",
    includeProductionChainHint: "Attivo per impostazione predefinita; disattiva per usare solo gli ingredienti diretti di questa ricetta.",
    chainInserterHint: "Configurazione predefinita degli inseritori per ogni macchina di produzione a monte.",
    beltThroughput: "Portata dei nastri",
    beltThroughputHint: "Nastri equivalenti e interi necessari per ogni flusso di oggetti solidi.",
    beltType: "Nastro trasportatore",
    beltStacking: "Dimensione pila sul nastro",
    unstacked: "Non impilato",
    stackInserterLevel: "Inseritore a pila ricercato",
    beltCapacityOne: "Capacità nastro trasportatore 1",
    beltCapacityTwo: "Capacità nastro trasportatore 2",
    splitSharedStreams: "Separa i materiali condivisi per prodotto",
    splitSharedStreamsHint: "Attivo: ogni prodotto principale ha un flusso proprio. Disattivo: la domanda condivisa viene unita.",
    beltCapacity: "Capacità del nastro",
    beltEquivalents: "Nastri pieni",
    beltsRequired: "Nastri necessari",
    lastBeltLoad: "Carico dell’ultimo nastro",
    combinedStream: "Flusso combinato",
    insertersPerMachine: "Inseritori per macchina",
  },
  ja: {
    globalChainMaster: "全製品共通の生産チェーン設定",
    applyAllActiveChains: "変更した項目は有効な全チェーンに上書きされ、その後の個別変更は各チェーン内だけに適用されます。",
    subprocessMachines: "工程別の機械",
    subprocessMachineHint: "各上流製品で使用するレシピと機械を選択します。",
    insertersRequired: "必要インサータ数",
    moveProductToTop: "この製品と結果を先頭へ移動",
    factoryTotals: "全生産の合計",
    factoryTotalsHint: "共通資源は合算し、機械数は各製品チェーンへの所属を表示します。",
    combinedResources: "資源需要の合計",
    productionProcesses: "生産工程と機械",
    directInputs: "直接材料",
    collapseProductResult: "この製品を折りたたむ",
    expandProductResult: "この製品を展開する",
    allChainsGenerated: "選択した各製品は、初期状態で上流の生産チェーン全体を含めて計算されます。除外する場合は各製品のチェーンを無効にしてください。",
    includeProductionChain: "生産チェーン全体を含める",
    includeProductionChainHint: "初期状態では有効です。無効にすると、このレシピの直接材料だけを使用します。",
    chainInserterHint: "上流の各生産設備に適用するデフォルトのインサータ設定です。",
    beltThroughput: "搬送ベルト処理量",
    beltThroughputHint: "各固体アイテム流に相当するベルト数と必要な整数本数を表示します。",
    beltType: "搬送ベルト",
    beltStacking: "ベルト上の積み重ね数",
    unstacked: "積み重ねなし",
    stackInserterLevel: "スタックインサータ研究済み",
    beltCapacityOne: "搬送ベルト容量 1",
    beltCapacityTwo: "搬送ベルト容量 2",
    splitSharedStreams: "共有素材を製品ごとに分離",
    splitSharedStreamsHint: "オン：各主要製品に個別の流れを割り当てます。オフ：共有需要を合算します。",
    beltCapacity: "ベルト容量",
    beltEquivalents: "満載ベルト換算",
    beltsRequired: "必要ベルト数",
    lastBeltLoad: "最後のベルト負荷",
    combinedStream: "合算した流れ",
    insertersPerMachine: "機械1台当たりのインサータ",
  },
  ru: {
    globalChainMaster: "Общие настройки всех цепочек",
    applyAllActiveChains: "Изменение перезаписывает этот параметр во всех активных цепочках; последующие локальные изменения остаются локальными.",
    subprocessMachines: "Машины по подпроцессам",
    subprocessMachineHint: "Выберите рецепт и машину для каждого повторяющегося продукта выше по цепочке.",
    insertersRequired: "Требуется манипуляторов",
    moveProductToTop: "Переместить продукт и результаты наверх",
    factoryTotals: "Итоги всего производства",
    factoryTotalsHint: "Общие ресурсы суммируются, а машины сохраняют привязку к каждой цепочке продукта.",
    combinedResources: "Суммарная потребность в ресурсах",
    productionProcesses: "Процессы и машины",
    directInputs: "Прямые ингредиенты",
    collapseProductResult: "Свернуть этот продукт",
    expandProductResult: "Развернуть этот продукт",
    allChainsGenerated: "Для каждого выбранного продукта по умолчанию рассчитывается вся предшествующая цепочка. Отключите цепочку у отдельного продукта, чтобы исключить её.",
    includeProductionChain: "Учитывать полную производственную цепочку",
    includeProductionChainHint: "Включено по умолчанию; отключите, чтобы учитывать только прямые ингредиенты этого рецепта.",
    chainInserterHint: "Стандартная настройка манипуляторов для каждой машины предшествующей цепочки.",
    beltThroughput: "Пропускная способность конвейеров",
    beltThroughputHint: "Эквивалентное и целое число конвейеров для каждого потока твёрдых предметов.",
    beltType: "Конвейер",
    beltStacking: "Размер стопки на конвейере",
    unstacked: "Без стопок",
    stackInserterLevel: "Пакетный манипулятор исследован",
    beltCapacityOne: "Вместимость конвейера 1",
    beltCapacityTwo: "Вместимость конвейера 2",
    splitSharedStreams: "Разделять общие материалы по продуктам",
    splitSharedStreamsHint: "Вкл.: каждому основному продукту назначается отдельный поток. Выкл.: общий спрос суммируется.",
    beltCapacity: "Вместимость конвейера",
    beltEquivalents: "Полных конвейеров",
    beltsRequired: "Требуется конвейеров",
    lastBeltLoad: "Загрузка последнего конвейера",
    combinedStream: "Общий поток",
    insertersPerMachine: "Манипуляторов на машину",
  },
  "zh-CN": {
    globalChainMaster: "所有产品的全局生产链设置",
    applyAllActiveChains: "更改会覆盖所有已启用生产链中的该项设置；之后的局部更改只作用于本链。",
    subprocessMachines: "各子流程生产设备",
    subprocessMachineHint: "为每种重复的上游产品选择配方和生产设备。",
    insertersRequired: "所需机械臂",
    moveProductToTop: "将此产品及其结果移到顶部",
    factoryTotals: "全部生产总览",
    factoryTotalsHint: "共同资源会合并求和，同时显示每条产品链所属的生产设备数量。",
    combinedResources: "合并资源需求",
    productionProcesses: "生产流程与设备",
    directInputs: "直接原料",
    collapseProductResult: "收起此产品",
    expandProductResult: "展开此产品",
    allChainsGenerated: "每个已选产品默认按完整上游生产链计算。可在对应产品旁关闭生产链以将其排除。",
    includeProductionChain: "计入完整生产链",
    includeProductionChainHint: "默认开启；关闭后只使用该配方的直接原料。",
    chainInserterHint: "应用于每台上游生产设备的默认机械臂设置。",
    beltThroughput: "传送带吞吐量",
    beltThroughputHint: "显示每种固体物料流对应的传送带当量和所需整条数量。",
    beltType: "传送带",
    beltStacking: "传送带堆叠数量",
    unstacked: "不堆叠",
    stackInserterLevel: "已研究堆叠机械臂",
    beltCapacityOne: "传送带容量 1",
    beltCapacityTwo: "传送带容量 2",
    splitSharedStreams: "按产品拆分共享物料",
    splitSharedStreamsHint: "开启：每个主产品使用独立物料流。关闭：共享需求合并计算。",
    beltCapacity: "传送带容量",
    beltEquivalents: "满载传送带当量",
    beltsRequired: "所需传送带",
    lastBeltLoad: "最后一条传送带负载",
    combinedStream: "合并物料流",
    insertersPerMachine: "每台设备所需机械臂",
  },
  "zh-TW": {
    globalChainMaster: "所有產品的全域生產鏈設定",
    applyAllActiveChains: "變更會覆寫所有已啟用生產鏈中的該項設定；之後的局部變更只作用於該鏈。",
    subprocessMachines: "各子流程生產設備",
    subprocessMachineHint: "為每種重複的上游產品選擇配方與生產設備。",
    insertersRequired: "所需機械臂",
    moveProductToTop: "將此產品及結果移至頂部",
    factoryTotals: "全部生產總覽",
    factoryTotalsHint: "共同資源會合併加總，同時顯示每條產品鏈所屬的生產設備數量。",
    combinedResources: "合併資源需求",
    productionProcesses: "生產流程與設備",
    directInputs: "直接原料",
    collapseProductResult: "收合此產品",
    expandProductResult: "展開此產品",
    allChainsGenerated: "每個已選產品預設依完整上游生產鏈計算。可在對應產品旁停用生產鏈以將其排除。",
    includeProductionChain: "納入完整生產鏈",
    includeProductionChainHint: "預設開啟；關閉後只使用此配方的直接原料。",
    chainInserterHint: "套用至每台上游生產設備的預設機械臂設定。",
    beltThroughput: "輸送帶吞吐量",
    beltThroughputHint: "顯示每種固體物料流對應的輸送帶當量與所需整條數量。",
    beltType: "輸送帶",
    beltStacking: "輸送帶堆疊數量",
    unstacked: "不堆疊",
    stackInserterLevel: "已研究堆疊機械臂",
    beltCapacityOne: "輸送帶容量 1",
    beltCapacityTwo: "輸送帶容量 2",
    splitSharedStreams: "依產品拆分共用材料",
    splitSharedStreamsHint: "開啟：每個主產品使用獨立材料流。關閉：合併計算共用需求。",
    beltCapacity: "輸送帶容量",
    beltEquivalents: "滿載輸送帶當量",
    beltsRequired: "所需輸送帶",
    lastBeltLoad: "最後一條輸送帶負載",
    combinedStream: "合併材料流",
    insertersPerMachine: "每台設備所需機械臂",
  },
};

const v6Translations: Record<Locale, Partial<Record<UiKey, string>>> = {
  en: {},
  de: {
    miningDrill: "Erzförderer für Rohstoffe",
    miningDrillHint: "Berechnet förderbare Rohstoffe mit diesem Erzförderer. Kann er einen Rohstoff nicht abbauen, wird der nächste geeignete Erzförderer verwendet.",
    machineResearchAndPriority: "Forschungsstand & automatische Maschinenhierarchie",
    machineResearchAndPriorityHint: "Nur aktivierte Maschinen werden automatisch genutzt. Pro Rezeptfamilie gewinnt die erste kompatible Maschine.",
    unlockedMachines: "Freigeschaltete Maschinen",
    machineHierarchy: "Priorität je Rezeptfamilie",
    machineGroupCrafting: "Montage & Elektronik",
    machineGroupSmelting: "Schmelzen & Metallurgie",
    machineGroupFluids: "Fluide & Chemie",
    machineGroupBiology: "Biologische Produktion",
    machineGroupProcessing: "Spezialverarbeitung",
    movePriorityUp: "Priorität erhöhen",
    movePriorityDown: "Priorität senken",
    totalBeltLoad: "Gesamtkapazität genutzt",
    inShort: "Ein",
    outShort: "Aus",
    inputs: "Eingänge",
    constructionSummary: "Vollständige Bau-Stückliste",
    constructionSummaryHint: "Alles, was für die ausgewählten Produkte und ihre aktivierten Produktionsketten platziert werden muss.",
    buildKindSource: "Förderung & Versorgung",
    buildKindMachine: "Produktionsmaschine",
    buildKindModule: "Module",
    buildKindBeacon: "Effektverteiler",
    buildKindInserter: "Greifarme",
  },
  "es-ES": {
    miningDrill: "Perforadora para recursos",
    miningDrillHint: "Dimensiona los recursos extraíbles con esta perforadora. Si no puede extraer un recurso, se usa la siguiente perforadora compatible.",
    machineResearchAndPriority: "Investigación y jerarquía automática de máquinas",
    machineResearchAndPriorityHint: "Solo se usan automáticamente las máquinas activadas. Gana la primera compatible de cada familia de recetas.",
    unlockedMachines: "Máquinas desbloqueadas",
    machineHierarchy: "Prioridad por familia de recetas",
    machineGroupCrafting: "Montaje y electrónica",
    machineGroupSmelting: "Fundición y metalurgia",
    machineGroupFluids: "Fluidos y química",
    machineGroupBiology: "Producción biológica",
    machineGroupProcessing: "Procesamiento especial",
    movePriorityUp: "Subir prioridad",
    movePriorityDown: "Bajar prioridad",
    totalBeltLoad: "capacidad total utilizada",
    inShort: "Entrada",
    outShort: "Salida",
    inputs: "Entradas",
    constructionSummary: "Lista completa de construcción",
    constructionSummaryHint: "Todo lo necesario para los productos seleccionados y sus cadenas de producción activas.",
    buildKindSource: "Extracción y suministro",
    buildKindMachine: "Máquina de producción",
    buildKindModule: "Módulos",
    buildKindBeacon: "Balizas",
    buildKindInserter: "Insertadores",
  },
  fr: {
    miningDrill: "Foreuse pour ressources brutes",
    miningDrillHint: "Dimensionne les ressources extractibles avec cette foreuse. Si elle ne peut pas extraire une ressource, la foreuse compatible suivante est utilisée.",
    machineResearchAndPriority: "Recherches et hiérarchie automatique des machines",
    machineResearchAndPriorityHint: "Seules les machines activées sont utilisées automatiquement. La première machine compatible de chaque famille est choisie.",
    unlockedMachines: "Machines débloquées",
    machineHierarchy: "Priorité par famille de recettes",
    machineGroupCrafting: "Assemblage et électronique",
    machineGroupSmelting: "Fonderie et métallurgie",
    machineGroupFluids: "Fluides et chimie",
    machineGroupBiology: "Production biologique",
    machineGroupProcessing: "Traitement spécialisé",
    movePriorityUp: "Augmenter la priorité",
    movePriorityDown: "Réduire la priorité",
    totalBeltLoad: "capacité totale utilisée",
    inShort: "Entrée",
    outShort: "Sortie",
    inputs: "Entrées",
    constructionSummary: "Liste complète de construction",
    constructionSummaryHint: "Tout ce qu’il faut placer pour les produits sélectionnés et leurs chaînes actives.",
    buildKindSource: "Extraction et alimentation",
    buildKindMachine: "Machine de production",
    buildKindModule: "Modules",
    buildKindBeacon: "Diffuseurs",
    buildKindInserter: "Bras",
  },
  it: {
    miningDrill: "Trivella per risorse grezze",
    miningDrillHint: "Dimensiona le risorse estraibili con questa trivella. Se non può estrarre una risorsa, viene usata la trivella compatibile successiva.",
    machineResearchAndPriority: "Ricerca e gerarchia automatica delle macchine",
    machineResearchAndPriorityHint: "Vengono usate automaticamente solo le macchine abilitate. Vince la prima compatibile di ogni famiglia di ricette.",
    unlockedMachines: "Macchine sbloccate",
    machineHierarchy: "Priorità per famiglia di ricette",
    machineGroupCrafting: "Assemblaggio ed elettronica",
    machineGroupSmelting: "Fusione e metallurgia",
    machineGroupFluids: "Fluidi e chimica",
    machineGroupBiology: "Produzione biologica",
    machineGroupProcessing: "Lavorazioni speciali",
    movePriorityUp: "Aumenta priorità",
    movePriorityDown: "Riduci priorità",
    totalBeltLoad: "capacità totale utilizzata",
    inShort: "Entrata",
    outShort: "Uscita",
    inputs: "Ingressi",
    constructionSummary: "Distinta completa di costruzione",
    constructionSummaryHint: "Tutto ciò che serve per i prodotti selezionati e le relative catene attive.",
    buildKindSource: "Estrazione e fornitura",
    buildKindMachine: "Macchina di produzione",
    buildKindModule: "Moduli",
    buildKindBeacon: "Fari",
    buildKindInserter: "Inseritori",
  },
  ja: {
    miningDrill: "原料用採掘機",
    miningDrillHint: "採掘可能な原料資源をこの採掘機で計算します。採掘できない資源には、次に対応する採掘機を使用します。",
    machineResearchAndPriority: "研究状況と機械の自動優先順位",
    machineResearchAndPriorityHint: "有効な機械だけを自動使用し、各レシピ系統で最上位の互換機械を選びます。",
    unlockedMachines: "研究済みの機械",
    machineHierarchy: "レシピ系統別の優先順位",
    machineGroupCrafting: "組立・電子工学",
    machineGroupSmelting: "製錬・冶金",
    machineGroupFluids: "流体・化学",
    machineGroupBiology: "生物生産",
    machineGroupProcessing: "特殊処理",
    movePriorityUp: "優先順位を上げる",
    movePriorityDown: "優先順位を下げる",
    totalBeltLoad: "総容量使用率",
    inShort: "入力",
    outShort: "出力",
    inputs: "入力",
    constructionSummary: "建設資材の総一覧",
    constructionSummaryHint: "選択した製品と有効な生産チェーンに配置する全設備です。",
    buildKindSource: "採掘・供給",
    buildKindMachine: "生産機械",
    buildKindModule: "モジュール",
    buildKindBeacon: "ビーコン",
    buildKindInserter: "インサータ",
  },
  ru: {
    miningDrill: "Бур для сырьевых ресурсов",
    miningDrillHint: "Расчёт добываемого сырья выполняется для этого бура. Если ресурс ему недоступен, используется следующая подходящая установка.",
    machineResearchAndPriority: "Исследования и автоматический приоритет машин",
    machineResearchAndPriorityHint: "Автоматика использует только включённые машины и выбирает первую совместимую в каждой группе рецептов.",
    unlockedMachines: "Открытые машины",
    machineHierarchy: "Приоритет по группе рецептов",
    machineGroupCrafting: "Сборка и электроника",
    machineGroupSmelting: "Плавка и металлургия",
    machineGroupFluids: "Жидкости и химия",
    machineGroupBiology: "Биологическое производство",
    machineGroupProcessing: "Специальная переработка",
    movePriorityUp: "Повысить приоритет",
    movePriorityDown: "Понизить приоритет",
    totalBeltLoad: "использование общей пропускной способности",
    inShort: "Вход",
    outShort: "Выход",
    inputs: "Входы",
    constructionSummary: "Полная ведомость строительства",
    constructionSummaryHint: "Всё необходимое для выбранных продуктов и включённых производственных цепочек.",
    buildKindSource: "Добыча и снабжение",
    buildKindMachine: "Производственная машина",
    buildKindModule: "Модули",
    buildKindBeacon: "Маяки",
    buildKindInserter: "Манипуляторы",
  },
  "zh-CN": {
    miningDrill: "原始资源采矿机",
    miningDrillHint: "使用此采矿机计算可开采的原始资源；若无法开采某资源，则使用下一级可用采矿机。",
    machineResearchAndPriority: "研究进度与自动机器优先级",
    machineResearchAndPriorityHint: "自动计算只使用已启用的机器，并在每类配方中选择优先级最高的兼容机器。",
    unlockedMachines: "已解锁机器",
    machineHierarchy: "按配方类型排序",
    machineGroupCrafting: "装配与电子",
    machineGroupSmelting: "冶炼与冶金",
    machineGroupFluids: "流体与化工",
    machineGroupBiology: "生物生产",
    machineGroupProcessing: "特殊加工",
    movePriorityUp: "提高优先级",
    movePriorityDown: "降低优先级",
    totalBeltLoad: "总容量利用率",
    inShort: "入",
    outShort: "出",
    inputs: "输入",
    constructionSummary: "完整建造清单",
    constructionSummaryHint: "所选产品及其启用生产链需要放置的全部设施。",
    buildKindSource: "开采与供应",
    buildKindMachine: "生产机器",
    buildKindModule: "插件",
    buildKindBeacon: "插件塔",
    buildKindInserter: "机械臂",
  },
  "zh-TW": {
    miningDrill: "原始資源採礦機",
    miningDrillHint: "使用此採礦機計算可開採的原始資源；若無法開採某資源，則使用下一級可用採礦機。",
    machineResearchAndPriority: "研究進度與自動設備優先順序",
    machineResearchAndPriorityHint: "自動計算只使用已啟用的設備，並在每類配方中選擇優先順序最高的相容設備。",
    unlockedMachines: "已解鎖設備",
    machineHierarchy: "依配方類型排序",
    machineGroupCrafting: "組裝與電子",
    machineGroupSmelting: "冶煉與冶金",
    machineGroupFluids: "流體與化工",
    machineGroupBiology: "生物生產",
    machineGroupProcessing: "特殊加工",
    movePriorityUp: "提高優先順序",
    movePriorityDown: "降低優先順序",
    totalBeltLoad: "總容量使用率",
    inShort: "入",
    outShort: "出",
    inputs: "輸入",
    constructionSummary: "完整建造清單",
    constructionSummaryHint: "所選產品及其啟用生產鏈需要放置的全部設施。",
    buildKindSource: "開採與供應",
    buildKindMachine: "生產設備",
    buildKindModule: "插件",
    buildKindBeacon: "插件塔",
    buildKindInserter: "機械臂",
  },
};

const qualityMiningTranslations: Record<
  Locale,
  Partial<Record<UiKey, string>>
> = {
  en: {},
  de: {
    miningAndRawQuality: "Förderung & Rohstoffqualität",
    miningModules: "Module im Erzförderer",
    qualityMiningHint: "Quality-Ketten beginnen bei der Förderung: Die gewählten Module belegen alle verfügbaren Plätze im Erzförderer und ihr erwarteter Quality-Output speist alle nachfolgenden Rezepte.",
    miningQualityChance: "Quality-Chance",
    occupiedSlots: "belegte Plätze",
    slotsPerBeacon: "Plätze je Effektverteiler",
  },
  "es-ES": {
    miningAndRawQuality: "Minería y calidad del recurso",
    miningModules: "Módulos de perforadora",
    qualityMiningHint: "Las cadenas de calidad comienzan en la extracción: los módulos elegidos llenan todas las ranuras de la perforadora y su producción de calidad alimenta las recetas posteriores.",
    miningQualityChance: "Probabilidad de calidad",
    occupiedSlots: "ranuras ocupadas",
    slotsPerBeacon: "ranuras por baliza",
  },
  fr: {
    miningAndRawQuality: "Extraction et qualité des ressources",
    miningModules: "Modules de foreuse",
    qualityMiningHint: "Les chaînes de qualité commencent à l’extraction : les modules choisis remplissent tous les emplacements de la foreuse et leur production de qualité alimente les recettes suivantes.",
    miningQualityChance: "Chance de qualité",
    occupiedSlots: "emplacements occupés",
    slotsPerBeacon: "emplacements par diffuseur",
  },
  it: {
    miningAndRawQuality: "Estrazione e qualità delle risorse",
    miningModules: "Moduli della trivella",
    qualityMiningHint: "Le catene di qualità iniziano dall’estrazione: i moduli scelti riempiono tutti gli slot della trivella e la loro produzione di qualità alimenta le ricette successive.",
    miningQualityChance: "Probabilità di qualità",
    occupiedSlots: "slot occupati",
    slotsPerBeacon: "slot per faro",
  },
  ja: {
    miningAndRawQuality: "採掘と原料品質",
    miningModules: "採掘機モジュール",
    qualityMiningHint: "品質チェーンは採掘から始まります。選択したモジュールを採掘機の全スロットに装着し、期待品質の産出物を後続レシピへ供給します。",
    miningQualityChance: "品質確率",
    occupiedSlots: "使用中スロット",
    slotsPerBeacon: "ビーコン当たりのスロット",
  },
  ru: {
    miningAndRawQuality: "Добыча и качество сырья",
    miningModules: "Модули буровой установки",
    qualityMiningHint: "Цепочки качества начинаются с добычи: выбранные модули заполняют все доступные ячейки бура, а ожидаемый качественный выход поступает в последующие рецепты.",
    miningQualityChance: "Шанс качества",
    occupiedSlots: "занятые ячейки",
    slotsPerBeacon: "ячеек на маяк",
  },
  "zh-CN": {
    miningAndRawQuality: "采矿与原料品质",
    miningModules: "采矿机插件",
    qualityMiningHint: "品质生产链从开采开始：所选插件会填满采矿机的全部可用插槽，预期品质产出会供应后续配方。",
    miningQualityChance: "品质概率",
    occupiedSlots: "已占用插槽",
    slotsPerBeacon: "每座插件塔插槽数",
  },
  "zh-TW": {
    miningAndRawQuality: "採礦與原料品質",
    miningModules: "採礦機插件",
    qualityMiningHint: "品質生產鏈從開採開始：所選插件會填滿採礦機的全部可用插槽，預期品質產出會供應後續配方。",
    miningQualityChance: "品質機率",
    occupiedSlots: "已占用插槽",
    slotsPerBeacon: "每座插件塔插槽數",
  },
};

const releaseTranslations: Record<
  Locale,
  Partial<Record<UiKey, string>>
> = {
  en: { help: "Help" },
  de: { help: "Hilfe" },
  "es-ES": { help: "Ayuda" },
  fr: { help: "Aide" },
  it: { help: "Guida" },
  ja: { help: "ヘルプ" },
  ru: { help: "Справка" },
  "zh-CN": { help: "帮助" },
  "zh-TW": { help: "說明" },
};

export function tr(locale: Locale, key: UiKey): string {
  return qualityMiningTranslations[locale][key] ?? releaseTranslations[locale][key] ?? v6Translations[locale][key] ?? v5Translations[locale][key] ?? refinementTranslations[locale][key] ?? v4Translations[locale][key] ?? supplemental[locale][key] ?? translations[locale][key] ?? en[key];
}

export type NameKind =
  | "item"
  | "fluid"
  | "entity"
  | "recipe"
  | "quality"
  | "group"
  | "subgroup"
  | "space";
const sectionOrder: Record<NameKind, string[]> = {
  item: ["item-name", "equipment-name", "entity-name"],
  fluid: ["fluid-name"],
  entity: ["entity-name", "item-name"],
  recipe: ["recipe-name", "item-name", "fluid-name"],
  quality: ["quality-name"],
  group: ["item-group-name"],
  subgroup: ["item-subgroup-name"],
  space: ["space-location-name"],
};

export function localizedName(
  id: string,
  locale: Locale,
  kind: NameKind = "item",
): string {
  if (id === "electromagnetic-plant") return "EMP";
  if (id.startsWith("spoil-")) {
    const source = id.slice(6);
    return `${localizedName(source, locale, "item")} — ${tr(locale, "passiveSpoilage")}`;
  }
  for (const section of sectionOrder[kind]) {
    const value =
      official[locale]?.[section]?.[id] ?? official.en?.[section]?.[id];
    if (value) return value.replace(/\[img=[^\]]+\]\s*/g, "");
  }
  return displayName(id);
}

export function qualityLabel(id: QualityId, locale: Locale): string {
  return localizedName(id, locale, "quality");
}
export function groupLabel(id: ItemGroupId, locale: Locale): string {
  return localizedName(id, locale, "group");
}
export function intlLocale(locale: Locale): string {
  return locale;
}

export function languageLabel(target: Locale, displayLocale: Locale): string {
  const languageTag: Record<Locale, string> = {
    en: "en",
    de: "de",
    "es-ES": "es",
    fr: "fr",
    it: "it",
    ja: "ja",
    ru: "ru",
    "zh-CN": "zh-Hans",
    "zh-TW": "zh-Hant",
  };
  try {
    const label = new Intl.DisplayNames([displayLocale], {
      type: "language",
    }).of(languageTag[target]);
    if (label)
      return label.charAt(0).toLocaleUpperCase(displayLocale) + label.slice(1);
  } catch {
    /* Older browser fallback. */
  }
  return LOCALE_OPTIONS.find((option) => option.id === target)?.label ?? target;
}

export function localizeCoreMessage(
  message: string | undefined,
  locale: Locale,
): string | undefined {
  if (!message || locale === "en") return message;
  if (message === "Enter a non-negative amount.")
    return `${tr(locale, "amount")} ≥ 0`;
  if (message === "Add at least one net input constraint for this route.")
    return tr(locale, "addInput");
  return tr(locale, "invalidSetup");
}
