import { type ItemDefVaultRef } from './gunConfigRules'; export type ItemDefValidation = { errors: string[]; warnings: string[]; descriptor: Record | null; /** Relative refs resolved against the descriptor's directory, in play order: mesh/clip first (when relative), then sounds. */ relativeRefs: { ref: string; file: string; }[]; meshRef: string | ItemDefVaultRef | null; /** An emote's `emote.clip` as authored; null on every weapon descriptor. */ clipRef: string | ItemDefVaultRef | null; /** A PAIRED emote's `emote.roles.joiner.clip` as authored; null on a solo emote and on every weapon. */ joinerClipRef: string | ItemDefVaultRef | null; /** An emote's `emote.intro` / `emote.outro` as authored; null when it declares none, and on every weapon. */ introClipRef: string | ItemDefVaultRef | null; outroClipRef: string | ItemDefVaultRef | null; /** A PAIRED emote's authored `emote.roles.offerAtS`; null when absent (the first frame) or unusable. */ offerAtS: number | null; /** Measured duration of the INITIATOR clip, seconds — null when it is a pinned ref or the GLB does not say. */ clipDurationS: number | null; /** Measured durations of the transition clips, on the same terms — what the one-shot chain cap is summed from. */ introDurationS: number | null; outroDurationS: number | null; }; /** The descriptor as publish will shape it: every relative string in `assets.*` (and every emote clip) swapped for a pinned-ref stand-in. */ export declare function toPublishShape(descriptor: Record): Record; export declare function validateItemDefDescriptor(parsed: unknown, baseDir: string): ItemDefValidation; export declare function validateItemDefFile(file: string): ItemDefValidation;