{#snippet lockable(output: LockableOutputId, value: number | undefined)} {#if cs.lock === output} onStepKey(e, cs.lockValue, 0.001, 0, (v) => (cs.lockValue = v))} oninput={(e) => capDecimals(e, (v) => (cs.lockValue = v))} data-testid={`calculator-locked-${output}`} title={result.lockFeasible ? "" : i18n.t("game.calculator.lock.infeasible")} /> {:else} {@const extra = lockDisabledReason(output)} {fmt(value)} {/if} {/snippet}
tryLoadByName(cs.name)} aria-invalid={nameValidation.ok ? "false" : "true"} data-testid="calculator-name" /> {#each localShipClass as cls (cls.name)} {/each} {#if cs.mode === "ship"} {/if}
{#if cs.mode === "ship"}
{i18n.t("game.calculator.load.label")}
{#each LOAD_MODES as m (m)} {/each}
{#if cs.loadMode === "custom"} onStepKey(e, cs.customLoad, 0.01, 0, (v) => (cs.customLoad = v))} oninput={(e) => capDecimals(e, (v) => (cs.customLoad = v))} aria-invalid={customLoadError !== "" ? "true" : "false"} title={customLoadError} data-testid="calculator-custom-load" /> {:else if cs.loadMode === "full"} {fmt(result.cargoCapacity)} {/if}
{i18n.t("game.calculator.col.empty")} {i18n.t("game.calculator.col.loaded")}
{i18n.t("game.calculator.out.mass")} {@render lockable("emptyMass", result.outputs?.emptyMass)} {@render lockable("loadedMass", result.outputs?.loadedMass)}
{i18n.t("game.calculator.out.speed")} {@render lockable("speedEmpty", result.outputs?.speedEmpty)} {@render lockable("speedLoaded", result.outputs?.speedLoaded)}
{i18n.t("game.calculator.out.attack")} {@render lockable("attack", result.outputs?.attack)}
{i18n.t("game.calculator.out.defense")} {@render lockable("defense", result.outputs?.defense)}
{i18n.t("game.calculator.out.bombing")} {fmt(result.outputs?.bombing)}
{i18n.t("game.calculator.out.cargo_capacity")} {fmt(result.outputs === null ? null : result.cargoCapacity)}
{#if selectedPlanet === null}

{i18n.t("game.calculator.planet.none")}

{:else}

{i18n.t("game.calculator.planet.label", { name: selectedPlanet.name, number: String(selectedPlanet.number), })}

{i18n.t("game.calculator.planet.mat")} {#if cs.matOverridden} onStepKey(e, cs.matValue, 0.01, 0, (v) => (cs.matValue = v))} oninput={(e) => capDecimals(e, (v) => (cs.matValue = v))} aria-invalid={matError !== "" ? "true" : "false"} title={matError} data-testid="calculator-planet-mat" /> {:else} {fmt(cs.matValue)} {/if}
{i18n.t("game.calculator.planet.ships_per_turn")}
{fmt(planetBuild?.shipsPerTurn)}
{i18n.t("game.calculator.planet.turns_per_ship")}
{fmt(planetBuild?.turnsPerShip ?? null)}
{/if}
{:else}
{i18n.t("game.calculator.modern.target")} {i18n.t("game.calculator.modern.cost")}
{#each modernCosts?.perBlock ?? [] as row (row.key)} {@const targetError = targetTechError(row.key)}
{i18n.t(`game.calculator.field.${row.key}` as TranslationKey)} onStepKey( e, cs.targetTech[row.key], 0.001, playerTech[row.key], (v) => (cs.targetTech[row.key] = v), )} oninput={(e) => capDecimals(e, (v) => (cs.targetTech[row.key] = v))} aria-invalid={targetError !== "" ? "true" : "false"} title={targetError} data-testid={`calculator-target-${row.key}`} /> {fmt(row.cost)}
{/each}
{i18n.t("game.calculator.modern.total")} {fmt(modernCosts?.total)}
{/if}