/**
 * Wargear-loadout maths shared by every consumer of the dataset: how many
 * models may take an option, what the maximal (take-every-swap) loadout looks
 * like, the valid count range for each weapon, and whether an edited loadout is
 * legal.
 *
 * The base loadout is derived, not stored: a weapon in `unit.weapon_ids` that
 * never appears as the *replacement* of any option is a **base** weapon, carried
 * by every model; a weapon that does appear as a replacement is **optional**,
 * carried only by the models that took the swap. This holds for uniform infantry
 * squads (every model shares the base loadout) and is exactly right for the
 * cases the corpus pins. Mirror of `crates/wh40kdc/src/data/loadout.rs`.
 *
 * @packageDocumentation
 */
import type { Unit, WargearOption } from "../generated.js";
/** Inclusive count range a single weapon/wargear id may take in a loadout. */
export interface WeaponBound {
    min: number;
    max: number;
}
/** A resolved loadout: entity id (weapon or wargear) → count across the unit. */
export interface Loadout {
    counts: Map<string, number>;
}
/** A loadout-rule violation. `id` is the offending weapon/wargear id. */
export interface Violation {
    id: string;
    code: "exceeds-max" | "below-min";
    message: string;
}
/**
 * The maximum number of models that may take `option` in a unit of `modelCount`
 * models: `any_number` → all models; else `per_n_models` → floor(n / per); else
 * `max_count ?? 1`; then clamped by `max_count` when set. A null constraint is
 * treated as unrestricted (every model). Never negative.
 */
export declare function optionCap(option: WargearOption, modelCount: number): number;
/**
 * The maximal loadout: every base weapon on every model, then each option
 * applied at its full {@link optionCap} (choices take their first branch). Swaps
 * move count from the replaced id to the added id; add-ons only add.
 */
export declare function maximalLoadout(unit: Unit, modelCount: number, options: readonly WargearOption[]): Loadout;
/**
 * Inclusive valid count range for each weapon/wargear id, used to clamp a UI's
 * per-weapon inputs so invalid loadouts are unreachable. A base weapon ranges
 * `[modelCount − maxSwapsAway, modelCount]`; an optional (replacement) id ranges
 * `[0, Σ caps that add it]`.
 */
export declare function weaponBounds(unit: Unit, modelCount: number, options: readonly WargearOption[]): Map<string, WeaponBound>;
/**
 * Clamp a single weapon's requested count into its valid range. Ids with no
 * bound (not part of this unit's loadout) are returned unchanged but floored at
 * zero.
 */
export declare function clampWeaponCount(bounds: Map<string, WeaponBound>, id: string, requested: number): number;
/** Report every weapon/wargear count that falls outside its valid range. */
export declare function validateLoadout(unit: Unit, modelCount: number, options: readonly WargearOption[], counts: Map<string, number>): Violation[];
//# sourceMappingURL=loadout.d.ts.map