import { HitObject, IHasColumn, IHasX, IHoldableObject, HitSample, HitType, ControlPointInfo, BeatmapDifficultySection, EventGenerator, Autoplay, Cinema, DoubleTime, BeatmapConverter, IBeatmap, IMod, IApplicableToConverter, ModBitwise, ModType, Easy, Flashlight, HalfTime, HardRock, Hidden, IApplicableToBeatmap, ModCombination, Nightcore, NoFail, NoMod, Perfect, SuddenDeath, RulesetBeatmap, BeatmapProcessor, IHitObject, FastRandom, Vector2, DifficultyAttributes, PerformanceAttributes, DifficultyHitObject, StrainDecaySkill, DifficultyCalculator, IRuleset, Skill, PerformanceCalculator, IScoreInfo, ReplayFrame, IConvertibleReplayFrame, LegacyReplayFrame, ReplayConverter, IReplayFrame, HitWindows, HitResult, Ruleset } from 'osu-classes';

declare abstract class ManiaHitObject extends HitObject implements IHasColumn, IHasX {
  protected _originalColumn: number;
  protected _column: number;

  /**
     * The original column of this hit object before any changes.
     */
  get originalColumn(): number;
  set originalColumn(value: number);

  /**
     * The column of this hit object.
     */
  get column(): number;
  set column(value: number);

  /**
     * The starting X-position of the hit object.
     */
  get startX(): number;

  /**
     * The ending X-position of the hit object.
     */
  get endX(): number;
  clone(): this;
}

declare class Note extends ManiaHitObject {
}

declare class HoldHead extends Note {
}

declare class HoldTail extends Note {
}

declare class Hold extends ManiaHitObject implements IHoldableObject {
  /**
     * The time between ticks of this hold.
     */
  tickInterval: number;
  nodeSamples: HitSample[][];

  /**
     * The time at which this hold ends.
     */
  endTime: number;
  hitType: HitType;
  get duration(): number;
  get head(): HoldHead | null;
  get tail(): HoldTail | null;
  get column(): number;
  set column(value: number);
  applyDefaultsToSelf(controlPoints: ControlPointInfo, difficulty: BeatmapDifficultySection): void;
  createNestedHitObjects(): void;
  clone(): this;
}

declare class HoldTick extends ManiaHitObject {
}

declare class ManiaEventGenerator extends EventGenerator {
  static generateHoldTicks(hold: Hold): Generator<ManiaHitObject>;
}

declare class ManiaAutoplay extends Autoplay {
}

declare class ManiaCinema extends Cinema {
}

declare class ManiaDoubleTime extends DoubleTime {
  multiplier: number;
}

declare class ManiaBeatmapConverter extends BeatmapConverter {
  /**
     * Maximum number of previous notes to consider for density calculation.
     */
  static MAX_NOTES_FOR_DENSITY: number;

  /**
     * The maximum number of supported keys in a single stage.
     */
  static MAX_STAGE_KEYS: number;
  originalRuleset: number;
  originalTargetColumns: number;
  targetColumns: number;
  isDual: boolean;
  private _rng;
  private _prevNoteTimes;
  private _density;
  private _lastTime;
  private _lastPosition;
  private _lastPattern;
  private _lastStair;
  private _converted?;
  canConvert(beatmap: IBeatmap): boolean;
  convertBeatmap(original: IBeatmap): ManiaBeatmap;
  convertHitObjects(beatmap: IBeatmap): Generator<ManiaHitObject>;

  /**
     * Method that generates hit objects for osu!mania specific beatmaps.
     * @param hitObject The hit object that will be converted.
     * @param beatmap The beatmap which objects will be converted.
     * This is used to look-up any values dependent on a fully-loaded beatmap.
     * @returns The hit objects generated.
     */
  private _generateSpecific;

  /**
     * Method that generates hit objects for non-osu!mania beatmaps.
     * @param hitObject The hit object that will be converted.
     * @param beatmap The beatmap which objects will be converted.
     * This is used to look-up any values dependent on a fully-loaded beatmap.
     * @returns The hit objects generated.
     */
  private _generateConverted;
  private _updateTargetColumns;
  private _computeDensity;
  private _recordNote;
  createBeatmap(): ManiaBeatmap;
}

declare class ManiaDualStages implements IMod, IApplicableToConverter {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  type: ModType;
  multiplier: number;
  isRanked: boolean;
  incompatibles: ModBitwise;
  applyToConverter(converter: ManiaBeatmapConverter): void;
}

declare class ManiaEasy extends Easy {
}

declare class ManiaFadeIn implements IMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  type: ModType;
  multiplier: number;
  isRanked: boolean;
  incompatibles: ModBitwise;
}

declare class ManiaFlashlight extends Flashlight {
  multiplier: number;
  incompatibles: ModBitwise;
}

declare class ManiaHalfTime extends HalfTime {
  multiplier: number;
}

declare class ManiaHardRock extends HardRock {
  multiplier: number;
}

declare class ManiaHidden extends Hidden {
  multiplier: number;
  incompatibles: ModBitwise;
}

declare abstract class ManiaKeyMod implements IMod, IApplicableToConverter {
  abstract name: string;
  abstract acronym: string;
  abstract bitwise: ModBitwise;
  abstract keyCount: number;
  type: ModType;
  multiplier: number;
  isRanked: boolean;
  incompatibles: ModBitwise;
  applyToConverter(converter: ManiaBeatmapConverter): void;
}

declare class ManiaKey1 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaKey2 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaKey3 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaKey4 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaKey5 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaKey6 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaKey7 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaKey8 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaKey9 extends ManiaKeyMod {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  keyCount: number;
  incompatibles: number;
}

declare class ManiaMirror implements IMod, IApplicableToBeatmap {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  type: ModType;
  multiplier: number;
  isRanked: boolean;
  incompatibles: ModBitwise;
  applyToBeatmap(beatmap: ManiaBeatmap): void;
}

declare class ManiaModCombination extends ModCombination {
  get mode(): number;
  protected get _availableMods(): IMod[];
}

declare class ManiaNightcore extends Nightcore {
}

declare class ManiaNoFail extends NoFail {
}

declare class ManiaNoMod extends NoMod {
}

declare class ManiaPerfect extends Perfect {
}

declare class ManiaRandom implements IMod, IApplicableToBeatmap {
  name: string;
  acronym: string;
  bitwise: ModBitwise;
  type: ModType;
  multiplier: number;
  isRanked: boolean;
  incompatibles: ModBitwise;
  applyToBeatmap(beatmap: ManiaBeatmap): void;
}

declare class ManiaSuddenDeath extends SuddenDeath {
}

declare enum ColumnType {
  Even = 0,
  Odd = 1,
  Special = 2,
}

/**
 * Defines properties for each stage in a osu!mania playfield.
 */
declare class StageDefinition {
  /**
     * The number of columns which this stage contains.
     */
  columns: number;
  constructor(columns?: number);

  /**
     * Whether the column index is a special column for this stage.
     * @param column The 0-based column index.
     * @returns Whether the column is a special column.
     */
  isSpecialColumn(column: number): boolean;

  /**
     * Get the type of column given a column index.
     * @param column The 0-based column index.
     * @returns The type of the column.
     */
  getTypeOfColumn(column: number): ColumnType;

  /**
     * Creates a new copy of this stage definition.
     * @returns The copy of this stage definition.
     */
  clone(): StageDefinition;
}

declare class ManiaBeatmap extends RulesetBeatmap {
  mods: ManiaModCombination;

  /**
     * The definitions for each stage in a osu!mania playfield.
     */
  stages: StageDefinition[];

  /**
     * The total number of columns that were present
     * in this {@link ManiaBeatmap} before any user adjustments.
     */
  readonly originalTotalColumns: number;
  hitObjects: ManiaHitObject[];
  constructor(stage: StageDefinition, columns?: number);

  /**
     * Beatmap game mode.
     */
  get mode(): number;

  /**
     * Total number of columns represented by all stages in this ManiaBeatmap.
     */
  get totalColumns(): number;
  get maxCombo(): number;
  get notes(): Note[];
  get holds(): Hold[];
}

declare class ManiaBeatmapProcessor extends BeatmapProcessor {
}

/**
 * Creates a pattern containing hit objects.
 */
declare class Pattern {
  /**
     * All hit objects contained in this pattern.
     */
  hitObjects: ManiaHitObject[];

  /**
     * All columns contained in this pattern
     */
  containedColumns: Set<number>;

  /**
     * Check whether a column of this patterns contains a hit object.
     * @param column The column index.
     * @returns Whether the column contains a hit object.
     */
  columnHasObject(column: number): boolean;

  /**
     * Amount of columns taken up by hit objects in this pattern.
     */
  get columnsWithObjects(): number;

  /**
     * Adds a hit object to this pattern.
     * @param hitObject The hit object to add.
     */
  addHitObject(hitObject: ManiaHitObject): void;

  /**
     * Copies hit object from another pattern to this one.
     * @param other The other pattern.
     */
  addPatternHitObjects(other: Pattern): void;

  /**
     * Clears this pattern, removing all hit objects.
     */
  clear(): void;
}

interface IFindOptions {
  /**
     * A list of patterns for which the validity of a column
     * should be checked against. A column is not a valid candidate
     * if a hit object occupies the same column in any of the patterns.
     */
  patterns?: Pattern[];

  /**
     * The minimum column index.
     */
  lowerBound?: number;

  /**
     * The maximum column index.
     */
  upperBound?: number;

  /**
     * A function to retrieve the next column.
     * A randomisation scheme will be used by default.
     */
  nextColumn?: (column: number) => number;

  /**
     * A function to perform additional validation checks to determine
     * if a column is a valid candidate for a hit object.
     */
  validate?: (column: number) => boolean;
}

/**
 * Generator to create a pattern } from a hit object.
 */
declare abstract class PatternGenerator {
  /**
     * The last pattern.
     */
  protected readonly previousPattern: Pattern;

  /**
     * The hit object to create the pattern for.
     */
  protected readonly hitObject: IHitObject;

  /**
     * The beatmap which hit object is a part of.
     */
  protected readonly beatmap: ManiaBeatmap;

  /**
     * The original beatmap.
     */
  protected readonly originalBeatmap: IBeatmap;
  protected readonly totalColumns: number;

  /**
     * The column index at which to start generating random notes.
     */
  protected readonly randomStart: number;
  protected readonly rng: FastRandom;
  constructor(hitObject: IHitObject, beatmap: ManiaBeatmap, originalBeatmap: IBeatmap, previousPattern: Pattern, rng: FastRandom);

  /**
     * Converts an x-position into a column.
     * @param position The x-position.
     * @param allowSpecial Whether to treat as 7K + 1.
     * @returns The column.
     */
  protected getColumn(position: number, allowSpecial?: boolean): number;

  /**
     * Generates a count of notes to be generated } from probabilities.
     * @param p2 Probability for 2 notes to be generated.
     * @param p3 Probability for 3 notes to be generated.
     * @param p4 Probability for 4 notes to be generated.
     * @param p5 Probability for 5 notes to be generated.
     * @param p6 Probability for 6 notes to be generated.
     * @returns The amount of notes to be generated.
     */
  protected getRandomNoteCount(p2: number, p3: number, p4?: number, p5?: number, p6?: number): number;
  private _conversionDiff;

  /**
     * A difficulty factor used for various conversion methods } from osu!stable.
     */
  get conversionDifficulty(): number;

  /**
     * Finds a new column in which a hit object can be placed.
     * @param column The initial column to test.
     * This may be returned if it is already a valid column.
     * @param options Options for finding column.
     * @returns A column which has passed the validation check and for which
     * there are no hit objects in any of patterns occupying the same column.
     */
  protected findAvailableColumn(column: number, options: IFindOptions): number;

  /**
     * Returns a random column index in the range [lowerBound, upperBound).
     * @param lowerBound The minimum column index.
     * @param upperBound The maximum column index.
     */
  protected getRandomColumn(lowerBound?: number, upperBound?: number): number;

  /**
     * Generates the patterns for a hit object, each filled with hit objects.
     * @returns The pattern containing the hit objects.
     */
  abstract generate(): Generator<Pattern>;
}

/**
 * The type of pattern to generate. Used for legacy patterns.
 */
declare enum PatternType {
  None = 0,

  /**
     * Keep the same as last row.
     */
  ForceStack = 1,

  /**
     * Keep different } from last row.
     */
  ForceNotStack = 2,

  /**
     * Keep as single note at its original position.
     */
  KeepSingle = 4,

  /**
     * Use a lower random value.
     */
  LowProbability = 8,

  /**
     * Reserved.
     */
  Alternate = 16,

  /**
     * Ignore the repeat count.
     */
  ForceSigSlider = 32,

  /**
     * Convert slider to circle.
     */
  ForceNotSlider = 64,

  /**
     * Notes gathered together.
     */
  Gathered = 128,
  Mirror = 256,

  /**
     * Change 0 -> 6.
     */
  Reverse = 512,

  /**
     * 1 -> 5 -> 1 -> 5 like reverse.
     */
  Cycle = 1024,

  /**
     * Next note will be at column + 1.
     */
  Stair = 2048,

  /**
     * Next note will be at column - 1.
     */
  ReverseStair = 4096,
}

/**
 * A pattern generator for IHasDistance hit objects.
 */
declare class DistanceObjectPatternGenerator extends PatternGenerator {
  /**
     * Base osu! slider scoring distance.
     */
  static BASE_SCORING_DISTANCE: number;
  readonly startTime: number;
  readonly endTime: number;
  readonly segmentDuration: number;
  readonly spanCount: number;
  protected convertType: PatternType;
  constructor(hitObject: IHitObject, beatmap: ManiaBeatmap, originalBeatmap: IBeatmap, previousPattern: Pattern, rng: FastRandom);
  generate(): Generator<Pattern>;
  protected generatePattern(): Pattern;

  /**
     * Generates random hold notes that start at an span the same amount of rows.
     * @param startTime Start time of each hold note.
     * @param noteCount Number of hold notes.
     * @returns The pattern containing the hit objects.
     */
  protected generateRandomHoldNotes(startTime: number, noteCount: number): Pattern;

  /**
     * Generates random notes, with one note per row and no stacking.
     * @param startTime The start time.
     * @param noteCount The number of notes.
     * @returns The pattern containing the hit objects.
     */
  protected generateRandomNotes(startTime: number, noteCount: number): Pattern;

  /**
     * Generates a stair of notes, with one note per row.
     * @param startTime The start time.
     * @returns The pattern containing the hit objects.
     */
  protected generateStair(startTime: number): Pattern;

  /**
     * Generates random notes with 1-2 notes per row and no stacking.
     * @param startTime The start time.
     * @returns The pattern containing the hit objects.
     */
  protected generateRandomMultipleNotes(startTime: number): Pattern;

  /**
     * Generates random hold notes. The amount of hold notes generated is determined by probabilities.
     * @param startTime The hold note start time.
     * @param p2 The probability required for 2 hold notes to be generated.
     * @param p3 The probability required for 3 hold notes to be generated.
     * @param p4 The probability required for 4 hold notes to be generated.
     * @returns The pattern containing the hit objects.
     */
  protected generateNRandomNotes(startTime: number, p2: number, p3: number, p4: number): Pattern;

  /**
     * Generates tiled hold notes. You can think of this as a stair of hold notes.
     * @param startTime The first hold note start time.
     * @returns The pattern containing the hit objects.
     */
  protected generateTiledHoldNotes(startTime: number): Pattern;

  /**
     * Generates a hold note alongside normal notes.
     * @param startTime The start time of notes.
     * @returns The pattern containing the hit objects.
     */
  protected generateHoldAndNormalNotes(startTime: number): Pattern;

  /**
     * Retrieves the list of hit samples that occur
     * at time greater than or equal to specified time.
     * @param time The time to retrieve the hit sample list } from.
     * @returns The hit sample list at specified time.
     */
  protected hitSamplesAt(time: number): HitSample[];

  /**
     * Retrieves the list of node samples that occur
     * at time greater than or equal to specified time.
     * @param time The time to retrieve node samples at.
     * @returns The node sample list at specified time.
     */
  protected nodeSamplesAt(time: number): HitSample[][];

  /**
     * Constructs and adds a note to a pattern.
     * @param pattern The pattern to add to.
     * @param column The column to add the note to.
     * @param startTime The start time of the note.
     * @param endTime The end time of the note
     * (set to startTime for a non-hold note).
     */
  protected addToPattern(pattern: Pattern, column: number, startTime: number, endTime: number): void;
}

declare class EndTimeObjectPatternGenerator extends PatternGenerator {
  protected readonly endTime: number;
  protected readonly convertType: PatternType;
  constructor(hitObject: IHitObject, beatmap: ManiaBeatmap, originalBeatmap: IBeatmap, previousPattern: Pattern, rng: FastRandom);
  generate(): Generator<Pattern>;
  protected getRandomColumn(lowerBound?: number): number;

  /**
     * Constructs and adds a note to a pattern.
     * @param pattern The pattern to add to.
     * @param column The column to add the note to.
     * @param holdNote Whether to add a hold note.
     */
  protected addToPattern(pattern: Pattern, column: number, isHoldNote: boolean): void;
}

declare class HitObjectPatternGenerator extends PatternGenerator {
  stairType: PatternType;
  protected convertType: PatternType;
  constructor(hitObject: IHitObject, beatmap: ManiaBeatmap, originalBeatmap: IBeatmap, previousPattern: Pattern, rng: FastRandom, previousTime: number, previousPosition: Vector2, density: number, lastStair: PatternType);
  generate(): Generator<Pattern>;
  private _generateCore;

  /**
     * Generates random notes.
     * This will generate as many as it can up to noteCount,
     * accounting for any stacks if this.convertType is forcing no stacks.
     * @param noteCount The amount of notes to generate.
     * @returns The pattern containing the hit objects.
     */
  protected generateRandomNotes(noteCount: number): Pattern;

  /**
     * Whether this hit object can generate a note in the special column.
     */
  protected hasSpecialColumn(): boolean;

  /**
     * Generates a random pattern.
     * @param p2 Probability for 2 notes to be generated.
     * @param p3 Probability for 3 notes to be generated.
     * @param p4 Probability for 4 notes to be generated.
     * @param p5 Probability for 5 notes to be generated.
     * @returns The pattern containing the hit objects.
     */
  protected generateRandomPattern(p2: number, p3: number, p4: number, p5: number): Pattern;

  /**
     * Generates a random pattern which has both normal and mirrored notes.
     * @param centreProbability The probability for a note
     * to be added to the centre column.
     * @param p2 Probability for 2 notes to be generated.
     * @param p3 Probability for 3 notes to be generated.
     * @returns The pattern containing the hit objects.
     */
  protected generateRandomPatternWithMirrored(centreProbability: number, p2: number, p3: number): Pattern;

  /**
     * Generates a count of notes to be generated } from a list of probabilities.
     * @param p2 Probability for 2 notes to be generated.
     * @param p3 Probability for 3 notes to be generated.
     * @param p4 Probability for 4 notes to be generated.
     * @param p5 Probability for 5 notes to be generated.
     * @returns The amount of notes to be generated.
     */
  protected getRandomNoteCount(p2: number, p3: number, p4: number, p5: number): number;

  /**
     * Generates a count of notes to be generated } from a list of probabilities.
     * @param centreProbability The probability for a note
     * to be added to the centre column.
     * @param p2 Probability for 2 notes to be generated.
     * @param p3 Probability for 3 notes to be generated.
     * @returns A tuple with the amount of notes to be generated
     * and flag that determines whether to add a note to the centre column.
     * The note to be added to the centre column will NOT be part of this count.
     */
  protected getRandomNoteCountMirrored(centreProbability: number, p2: number, p3: number): [number, boolean];

  /**
     * Constructs and adds a note to a pattern.
     * @param pattern The pattern to add to.
     * @param column The column to add the note to.
     */
  protected addToPattern(pattern: Pattern, column: number): void;
}

/**
 * A pattern generator for osu!mania-specific beatmaps.
 */
declare class SpecificBeatmapPatternGenerator extends PatternGenerator {
  generate(): Generator<Pattern>;
}

declare class ManiaDifficultyAttributes extends DifficultyAttributes {
  /**
     * The hit window for a GREAT hit inclusive of rate-adjusting mods (DT/HT/etc).
     * Rate-adjusting mods do not affect the hit window at all in osu-stable.
     */
  greatHitWindow: number;
}

/**
 * Describes the performance of a score, as output by a performance calculator.
 */
declare class ManiaPerformanceAttributes extends PerformanceAttributes {
  /**
     * The mods which were applied to the beatmap.
     */
  mods: ManiaModCombination;

  /**
     * The strain performance of a score.
     */
  difficultyPerformance: number;

  /**
     * Creates new difficulty attributes.
     * @param mods The mods which were applied to the beatmap.
     * @param totalPerformance The total performance of a score.
     */
  constructor(mods: ManiaModCombination, totalPerformance: number);
}

declare class ManiaDifficultyHitObject extends DifficultyHitObject {
  /**
     * The hit object wrapped by this difficulty hit object.
     */
  baseObject: ManiaHitObject;
  constructor(hitObject: IHitObject, lastObject: IHitObject, clockRate: number, objects: DifficultyHitObject[], index: number);
}

declare class Strain extends StrainDecaySkill {
  private static INDIVIDUAL_DECAY_BASE;
  private static OVERALL_DECAY_BASE;
  private static RELEASE_THRESHOLD;
  protected _skillMultiplier: number;
  protected _strainDecayBase: number;
  private readonly _startTimes;
  private readonly _endTimes;
  private readonly _individualStrains;
  private _individualStrain;
  private _overallStrain;
  constructor(mods: ModCombination, totalColumns: number);
  protected _strainValueOf(current: DifficultyHitObject): number;
  protected _calculateInitialStrain(time: number, current: DifficultyHitObject): number;
  private static _applyDecay;
}

declare class ManiaDifficultyCalculator extends DifficultyCalculator<ManiaDifficultyAttributes> {
  private static STAR_SCALING_FACTOR;
  private readonly _isForCurrentRuleset;
  private readonly _originalOverallDifficulty;
  constructor(beatmap: IBeatmap, ruleset: IRuleset);
  protected _createDifficultyAttributes(beatmap: IBeatmap, mods: ManiaModCombination, skills: Skill[], clockRate: number): ManiaDifficultyAttributes;
  protected _createDifficultyHitObjects(beatmap: IBeatmap, clockRate: number): ManiaDifficultyHitObject[];
  protected _sortObjects(input: DifficultyHitObject[]): DifficultyHitObject[];
  protected _createSkills(beatmap: IBeatmap, mods: ManiaModCombination): Skill[];
  get difficultyMods(): IMod[];
  private _getHitWindow300;
}

declare class ManiaPerformanceCalculator extends PerformanceCalculator {
  attributes: ManiaDifficultyAttributes;
  private _mods;
  private _countPerfect;
  private _countGreat;
  private _countGood;
  private _countOk;
  private _countMeh;
  private _countMiss;
  constructor(ruleset: IRuleset, attributes?: DifficultyAttributes, score?: IScoreInfo);
  calculateAttributes(attributes?: DifficultyAttributes, score?: IScoreInfo): ManiaPerformanceAttributes;
  private _computeDifficultyValue;
  private _addParams;
  private get _totalHits();
  private get _customAccuracy();
}

declare enum ManiaAction {
  /**
     * Special 1
     */
  Special1 = 1,

  /**
     * Special 2
     */
  Special2 = 2,

  /**
     * This offsets the start value of normal keys in-case we add more special keys
     * above at a later time, without breaking replays/configs.
     *
     * Key 1
     */
  Key1 = 10,

  /**
     * Key 2
     */
  Key2 = 11,

  /**
     * Key 3
     */
  Key3 = 12,

  /**
     * Key 4
     */
  Key4 = 13,

  /**
     * Key 5
     */
  Key5 = 14,

  /**
     * Key 6
     */
  Key6 = 15,

  /**
     * Key 7
     */
  Key7 = 16,

  /**
     * Key 8
     */
  Key8 = 17,

  /**
     * Key 9
     */
  Key9 = 18,

  /**
     * Key 10
     */
  Key10 = 19,

  /**
     * Key 11
     */
  Key11 = 20,

  /**
     * Key 12
     */
  Key12 = 21,

  /**
     * Key 13
     */
  Key13 = 22,

  /**
     * Key 14
     */
  Key14 = 23,

  /**
     * Key 15
     */
  Key15 = 24,

  /**
     * Key 16
     */
  Key16 = 25,

  /**
     * Key 17
     */
  Key17 = 26,

  /**
     * Key 18
     */
  Key18 = 27,

  /**
     * Key 19
     */
  Key19 = 28,

  /**
     * Key 20
     */
  Key20 = 29,
}

declare class ManiaReplayFrame extends ReplayFrame implements IConvertibleReplayFrame {
  /**
     * Button actions of this replay frame.
     */
  actions: Set<ManiaAction>;
  fromLegacy(currentFrame: LegacyReplayFrame, _: ManiaReplayFrame | null, beatmap?: IBeatmap): this;
  toLegacy(beatmap?: IBeatmap): LegacyReplayFrame;

  /**
     * Find the overall index (across all stages) for a specified special key.
     * @param maniaBeatmap The beatmap.
     * @param specialOffset The special key offset (0 is S1).
     * @returns The overall index for the special column.
     */
  private _getSpecialColumnIndex;

  /**
     * @param beatmap The beatmap.
     * @param index The overall index to check.
     * @returns Whether the column at an overall index
     * (across all stages) is a special column.
     */
  private _isColumnAtIndexSpecial;
}

/**
 * osu!mania replay converter.
 */
declare class ManiaReplayConverter extends ReplayConverter {
  protected _createConvertibleReplayFrame(): ManiaReplayFrame;
  protected _isConvertedReplayFrame(frame: IReplayFrame): boolean;
}

declare class ManiaHitWindows extends HitWindows {
  isHitResultAllowed(result: HitResult): boolean;
}

/**
 * osu!mania ruleset.
 */
declare class ManiaRuleset extends Ruleset {
  /**
     * osu!mania ruleset ID.
     */
  get id(): number;

  /**
     * Applies osu!mania ruleset to a beatmap.
     * @param beatmap The beatmap.
     * @returns A new osu!mania beatmap with applied ruleset.
     */
  applyToBeatmap(beatmap: IBeatmap): ManiaBeatmap;

  /**
     * Applies osu!mania ruleset and mods to a beatmap.
     * @param beatmap The beatmap.
     * @param mods osu!mania mod combination.
     * @returns A new osu!mania beatmap with applied mods.
     */
  applyToBeatmapWithMods(beatmap: IBeatmap, mods?: ManiaModCombination): ManiaBeatmap;

  /**
     * Resets a mod combination from a beatmap.
     * @param beatmap The beatmap.
     * @returns A new beatmap with no mods.
     */
  resetMods(beatmap: IBeatmap): ManiaBeatmap;

  /**
     * Creates a new mod combination by converting legacy mod bitwise.
     * @param input Mod bitwise or acronyms.
     * @returns A new mod combination.
     */
  createModCombination(input?: number | string): ManiaModCombination;

  /**
     * @returns A new osu!mania beatmap processor.
     */
  protected _createBeatmapProcessor(): ManiaBeatmapProcessor;

  /**
     * @returns A new osu!mania beatmap converter.
     */
  protected _createBeatmapConverter(): ManiaBeatmapConverter;

  /**
     * @returns A new osu!mania replay converter.
     */
  protected _createReplayConverter(): ManiaReplayConverter;

  /**
     * @param beatmap The beatmap for which the calculation will be done.
     * @returns A new osu!mania difficulty calculator.
     */
  createDifficultyCalculator(beatmap: IBeatmap): ManiaDifficultyCalculator;

  /**
     * @param attributes The difficulty attributes.
     * @param score Score information.
     * @returns A new osu!mania performance calculator.
     */
  createPerformanceCalculator(attributes?: ManiaDifficultyAttributes, score?: IScoreInfo): ManiaPerformanceCalculator;
}

export { ColumnType, DistanceObjectPatternGenerator, EndTimeObjectPatternGenerator, HitObjectPatternGenerator, Hold, HoldHead, HoldTail, HoldTick, ManiaAction, ManiaAutoplay, ManiaBeatmap, ManiaBeatmapConverter, ManiaBeatmapProcessor, ManiaCinema, ManiaDifficultyAttributes, ManiaDifficultyCalculator, ManiaDifficultyHitObject, ManiaDoubleTime, ManiaDualStages, ManiaEasy, ManiaEventGenerator, ManiaFadeIn, ManiaFlashlight, ManiaHalfTime, ManiaHardRock, ManiaHidden, ManiaHitObject, ManiaHitWindows, ManiaKey1, ManiaKey2, ManiaKey3, ManiaKey4, ManiaKey5, ManiaKey6, ManiaKey7, ManiaKey8, ManiaKey9, ManiaKeyMod, ManiaMirror, ManiaModCombination, ManiaNightcore, ManiaNoFail, ManiaNoMod, ManiaPerfect, ManiaPerformanceAttributes, ManiaPerformanceCalculator, ManiaRandom, ManiaReplayConverter, ManiaReplayFrame, ManiaRuleset, ManiaSuddenDeath, Note, Pattern, PatternGenerator, PatternType, SpecificBeatmapPatternGenerator, StageDefinition, Strain };
