/******************************************************************************
 * Spine Runtimes License Agreement
 * Last updated April 5, 2025. Replaces all prior versions.
 *
 * Copyright (c) 2013-2025, Esoteric Software LLC
 *
 * Integration of the Spine Runtimes into software or otherwise creating
 * derivative works of the Spine Runtimes is permitted under the terms and
 * conditions of Section 2 of the Spine Editor License Agreement:
 * http://esotericsoftware.com/spine-editor-license
 *
 * Otherwise, it is permitted to integrate the Spine Runtimes into software
 * or otherwise create derivative works of the Spine Runtimes (collectively,
 * "Products"), provided that each user of the Products must obtain their own
 * Spine Editor license and redistribution of the Products in any form must
 * include this license and copyright notice.
 *
 * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
 * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/
/** biome-ignore-all lint/style/noNonNullAssertion: reference runtime expects some nullable to not be null */
import { Animation, AttachmentTimeline, RotateTimeline } from "./Animation.js";
import type { AnimationStateData } from "./AnimationStateData.js";
import type { Event } from "./Event.js";
import type { Skeleton } from "./Skeleton.js";
import { Interpolation, Pool, StringSet } from "./Utils.js";
/** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies
 * multiple animations on top of each other (layering).
 *
 * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations#AnimationState-API) in the Spine Runtimes Guide. */
export declare class AnimationState {
    static readonly emptyAnimation: Animation;
    /** The AnimationStateData to look up mix durations. */
    data: AnimationStateData;
    /** The list of tracks that have had animations. May contain null entries for tracks that currently have no animation. */
    readonly tracks: (TrackEntry | null)[];
    /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower
     * or faster. Defaults to 1.
     *
     * See {@link TrackEntry.timeScale} to affect a single animation. */
    timeScale: number;
    unkeyedState: number;
    readonly events: Event[];
    readonly listeners: AnimationStateListener[];
    queue: EventQueue;
    propertyIds: StringSet;
    animationsChanged: boolean;
    trackEntryPool: Pool<TrackEntry>;
    constructor(data: AnimationStateData);
    /** Increments each track entry {@link TrackEntry.trackTime}, setting queued animations as current if needed. */
    update(delta: number): void;
    /** Returns true when all mixing from entries are complete. */
    updateMixingFrom(to: TrackEntry, delta: number): boolean;
    /** Poses the skeleton using the track entry animations. The animation state is not changed, so can be applied to multiple
     * skeletons to pose them identically.
     * @returns True if any animations were applied. */
    apply(skeleton: Skeleton): boolean;
    applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
    /** Applies the attachment timeline and sets {@link Slot.attachmentState}.
     * @param retain True if the attachment remains after apply, false if temporary for deform timelines. */
    applyAttachmentTimeline(timeline: AttachmentTimeline, skeleton: Skeleton, time: number, fromSetup: boolean, retain: boolean): void;
    /** Applies the rotate timeline, mixing with the current pose while keeping the same rotation direction chosen as the shortest
     * the first time the mixing was applied. */
    applyRotateTimeline(timeline: RotateTimeline, skeleton: Skeleton, time: number, alpha: number, fromSetup: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
    queueEvents(entry: TrackEntry, animationTime: number): void;
    private eventsReverse;
    /** Removes all animations from all tracks, leaving skeletons in their current pose.
     *
     * Usually you want to use {@link setEmptyAnimations} to mix the skeletons back to the setup pose, rather than leaving
     * them in their current pose. */
    clearTracks(): void;
    /** Removes all animations from the track, leaving skeletons in their current pose.
     *
     * Usually you want to use {@link setEmptyAnimation} to mix the skeletons back to the setup pose, rather than
     * leaving them in their current pose. */
    clearTrack(trackIndex: number): void;
    setTrack(index: number, current: TrackEntry, interrupt: boolean): void;
    /** Sets an animation by name.
     *
     * See {@link setAnimation}. */
    setAnimation(trackIndex: number, animationName: string, loop?: boolean): TrackEntry;
    /** Sets the current animation for a track, discarding any queued animations.
     *
     * If the formerly current track entry is for the same animation and was never applied to a skeleton, it is replaced (not mixed
     * from).
     * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
     *           duration. In either case {@link TrackEntry.trackEnd} determines when the track is cleared.
     * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
     *         after the {@link AnimationStateListener.dispose} event occurs. */
    setAnimation(trackIndex: number, animation: Animation, loop?: boolean): TrackEntry;
    private setAnimation1;
    /** Sets the current animation for a track, discarding any queued animations.
     *
     * If the formerly current track entry is for the same animation and was never applied to a skeleton, it is replaced (not mixed
     * from).
     * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
     *           duration. In either case {@link TrackEntry.getTrackEnd} determines when the track is cleared.
     * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
     *         after the {@link AnimationStateListener.dispose} event occurs. */
    private setAnimation2;
    /** Queues an animation by name.
     *
     * See {@link addAnimation}. */
    addAnimation(trackIndex: number, animationName: string, loop?: boolean, delay?: number): TrackEntry;
    /** Adds an animation to be played after the current or last queued animation for a track. If the track has no entries, this is
     * equivalent to calling {@link setAnimation}.
     * @param delay If > 0, sets {@link TrackEntry.delay}. If <= 0, the delay set is the duration of the previous track entry
     *           minus any mix duration (from {@link data}) plus the specified `delay` (ie the mix ends at (when
     *           `delay` = 0) or before (when `delay` < 0) the previous track entry duration). If the
     *           previous entry is looping, its next loop completion is used instead of its duration.
     * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
     *         after the {@link AnimationStateListener.dispose} event occurs. */
    addAnimation(trackIndex: number, animation: Animation, loop?: boolean, delay?: number): TrackEntry;
    private addAnimation1;
    private addAnimation2;
    /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's
     * {@link TrackEntry.mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out.
     *
     * Mixing out is done by setting an empty animation with a mix duration using either {@link setEmptyAnimation},
     * {@link setEmptyAnimations}, or {@link addEmptyAnimation}. Mixing to an empty animation causes
     * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation
     * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of
     * 0 still needs to be applied one more time to mix out, so the properties it was animating are reverted.
     *
     * Mixing in is done by first setting an empty animation, then adding an animation using
     * {@link addAnimation} with the desired delay (an empty animation has a duration of 0) and on
     * the returned track entry, set the {@link TrackEntry.setMixDuration}. Mixing from an empty animation causes the new
     * animation to be applied more and more over the mix duration. Properties keyed in the new animation transition from the value
     * from lower tracks or from the setup pose value if no lower tracks key the property to the value keyed in the new animation.
     *
     * See <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
     * Runtimes Guide. */
    setEmptyAnimation(trackIndex: number, mixDuration?: number): TrackEntry;
    /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's
     * {@link TrackEntry.mixDuration}. If the track has no entries, it is equivalent to calling
     * {@link setEmptyAnimation}.
     *
     * See {@link setEmptyAnimation} and
     * <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine Runtimes
     * Guide.
     * @param delay If > 0, sets {@link TrackEntry.delay}. If <= 0, the delay set is the duration of the previous track entry minus
     *           any mix duration plus the specified `delay` (ie the mix ends at (when `delay` = 0) or before
     *           (when `delay` < 0) the previous track entry duration). If the previous entry is looping, its next loop
     *           completion is used instead of its duration.
     * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
     *         after the {@link AnimationStateListener.dispose} event occurs. */
    addEmptyAnimation(trackIndex: number, mixDuration?: number, delay?: number): TrackEntry;
    /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
     *
     * See <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
     * Runtimes Guide. */
    setEmptyAnimations(mixDuration?: number): void;
    expandToIndex(index: number): TrackEntry | null;
    /** @param last May be null. */
    trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry | null): TrackEntry;
    /** Removes {@link TrackEntry.next} and all entries after it for the specified entry. */
    clearNext(entry: TrackEntry): void;
    _animationsChanged(): void;
    computeHold(entry: TrackEntry): void;
    /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */
    getTrack(trackIndex: number): TrackEntry | null;
    /** Adds a listener to receive events for all track entries. */
    addListener(listener: AnimationStateListener): void;
    /** Removes the listener added with {@link addListener}. */
    removeListener(listener: AnimationStateListener): void;
    /** Removes all listeners added with {@link addListener}. */
    clearListeners(): void;
    /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an
     * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery
     * are not wanted because new animations are being set. */
    clearListenerNotifications(): void;
}
/** Stores settings and other state for the playback of an animation on an {@link AnimationState} track.
 *
 * References to a track entry must not be kept after the {@link AnimationStateListener.dispose} event occurs. */
export declare class TrackEntry {
    /** The animation to apply for this track entry. */
    animation: Animation | null;
    previous: TrackEntry | null;
    /** The animation queued to start after this animation, or null. `next` makes up a linked list. */
    next: TrackEntry | null;
    /** The track entry for the previous animation when mixing to this animation, or null if no mixing is currently occurring.
     * When mixing from multiple animations, `mixingFrom` makes up a doubly linked list. */
    mixingFrom: TrackEntry | null;
    /** The track entry for the next animation when mixing from this animation, or null if no mixing is currently occurring.
     * When mixing to multiple animations, `mixingTo` makes up a doubly linked list. */
    mixingTo: TrackEntry | null;
    /** The listener for events generated by this track entry, or null.
     *
     * A track entry returned from {@link AnimationState.setAnimation} is already the current animation
     * for the track, so the callback for listener {@link AnimationStateListener.start} will not be called. */
    listener: AnimationStateListener | null;
    /** The index of the track where this track entry is either current or queued.
     *
     * See {@link AnimationState.getTrack}. */
    trackIndex: number;
    /** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
     * duration. */
    loop: boolean;
    /** When true, timelines in this animation that support additive have their values added to the setup or current pose values
     * instead of replacing them. Additive can be set for a new track entry only before {@link AnimationState.apply}
     * is next called. */
    additive: boolean;
    /** If true, the animation will be applied in reverse. */
    reverse: boolean;
    /** If true, mixing rotation between tracks always uses the shortest rotation direction. If the rotation is animated, the
     * shortest rotation direction may change during the mix.
     *
     * If false, the shortest rotation direction is remembered when the mix starts and the same direction is used for the rest
     * of the mix. Defaults to false.
     *
     * See {@link resetRotationDirections}. */
    shortestRotation: boolean;
    keepHold: boolean;
    /** When the interpolated mix percentage is less than the `eventThreshold` , event timelines are applied while
     * this animation is being mixed out. Defaults to 0, so event timelines are not applied while this animation is being mixed
     * out. */
    eventThreshold: number;
    /** When the interpolated mix percentage is less than the `mixAttachmentThreshold`, attachment timelines are
     * applied while this animation is being mixed out. Defaults to 0, so attachment timelines are not applied while this
     * animation is being mixed out. */
    mixAttachmentThreshold: number;
    /** When the computed alpha is greater than `alphaAttachmentThreshold`, attachment timelines are applied. The
     * computed alpha includes {@link alpha} and the interpolated mix percentage. Defaults to 0, so attachment timelines are
     * always applied. */
    alphaAttachmentThreshold: number;
    /** When the interpolated mix percentage is less than the `mixAttachmentThreshold`, attachment timelines are
     * applied while this animation is being mixed out. Defaults to 0, so attachment timelines are not applied while this
     * animation is being mixed out. */
    mixDrawOrderThreshold: number;
    /** The time in seconds for the first frame of this animation, both initially and after looping. Defaults to 0.
     *
     * When setting `animationStart` time, {@link animationLast} can be set to the same value to avoid firing events
     * from the start of the animation. */
    animationStart: number;
    /** The time in seconds for the last frame of this animation. Past this time, non-looping animations hold the pose at this
     * time while looping animations will loop back to {@link animationStart}. Defaults to the {@link Animation.duration}. */
    animationEnd: number;
    /** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. For example, when
     * this animation is applied, event timelines will fire all events between the `animationLast` time (exclusive)
     * and `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this
     * animation is applied. */
    animationLast: number;
    nextAnimationLast: number;
    /** Seconds to postpone playing the animation. Must be >= 0. When this track entry is the current track entry,
     * `delay` postpones incrementing the {@link trackTime}. When this track entry is queued, `delay` is
     * the time from the start of the previous animation to when this track entry will become the current track entry (ie when
     * the previous track entry {@link trackTime} >= this track entry's `delay`).
     *
     * {@link timeScale} affects the delay.
     *
     * When passing `delay` <= 0 to {@link AnimationState.addAnimation} this
     * `delay` is set using a mix duration from {@link AnimationStateData}. To change the {@link mixDuration}
     * afterward, use {@link setMixDuration} so this `delay` is adjusted. */
    delay: number;
    /** The time in seconds this track entry has been the current track entry, starting at 0 and increasing forever. Compare to
     * {@link getAnimationTime}, which is always between {@link animationStart} and {@link animationEnd}.
     *
     * The track time can be set to start the animation at a time other than 0, without affecting looping. When doing so,
     * {@link animationLast} can be set to the same value to avoid firing events from the start of the animation.
     *
     * To set the time an animation starts and loops, use {@link animationStart} and {@link animationEnd}. */
    trackTime: number;
    trackLast: number;
    nextTrackLast: number;
    /** The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float
     * value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time
     * is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the
     * properties keyed by the animation are set to the setup pose and the track is cleared.
     *
     * Usually you want to use {@link AnimationState.addEmptyAnimation} rather than have the animation
     * abruptly cease being applied. */
    trackEnd: number;
    /** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or
     * faster. Defaults to 1.
     *
     * Values < 0 are not supported. To play an animation in reverse, use {@link reverse}.
     *
     * {@link mixTime} is not affected by track entry time scale, so {@link mixDuration} may need to be adjusted to match the
     * animation speed.
     *
     * When using {@link AnimationState.addAnimation} with a `delay` <= 0, the
     * {@link delay} is set using the mix duration from {@link AnimationState.data}, assuming time scale to be 1. If the time
     * scale is not 1, the delay may need to be adjusted.
     *
     * See {@link AnimationState.timeScale} to affect all animations. */
    timeScale: number;
    /** Values < 1 mix this animation with the skeleton's current pose (either the setup pose or the pose from lower tracks).
     * Defaults to 1, which overwrites the skeleton's current pose with this animation.
     *
     * Alpha should be 1 on track 0.
     *
     * See {@link getAlphaAttachmentThreshold}. */
    alpha: number;
    /** Seconds elapsed from 0 to the {@link mixDuration} when mixing from the previous animation to this animation. May
     * be slightly more than `mixDuration` when the mix is complete. */
    mixTime: number;
    /** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
     * {@link AnimationStateData.getMix} based on the animation before this animation (if any).
     *
     * A mix duration of 0 still needs to be applied one more time to mix out, so the the properties it was animating are
     * reverted. A mix duration of 0 can be set at any time to end the mix on the next
     * {@link AnimationState.update | update}.
     *
     * The `mixDuration` can be set manually rather than use the value from
     * {@link AnimationStateData.getMix}. In that case, the `mixDuration` can be set for a new
     * track entry only before {@link AnimationState.update} is next called.
     *
     * When using {@link AnimationState.addAnimation} with a `delay` <= 0, the
     * {@link getDelay} is set using the mix duration from {@link AnimationState.data}. If `mixDuration` is set
     * afterward, the delay needs to be adjusted:
     *
     * <pre>
     * entry.mixDuration = 0.25;<br>
     * entry.delay = entry.previous.getTrackComplete() - entry.mixDuration + 0;
     * </pre>
     *
     * Alternatively, use {@link setMixDuration} to set both the mix duration and recompute the delay:<br>
     *
     * <pre>
      entry.setMixDuration(0.25f, 0); // mixDuration, delay
     * </pre>
     */
    mixDuration: number;
    totalAlpha: number;
    mixInterpolation: Interpolation;
    /** Sets both {@link getMixDuration} and {@link getDelay}.
     * @param delay If > 0, sets {@link getDelay}. If <= 0, the delay set is the duration of the previous track entry minus
     *           the specified mix duration plus the specified `delay` (ie the mix ends at (when `delay` =
     *           0) or before (when `delay` < 0) the previous track entry duration). If the previous entry is
     *           looping, its next loop completion is used instead of its duration. */
    setMixDuration(mixDuration: number, delay?: number): void;
    /** The interpolation to apply to the mix percentage ({@link mixTime} / {@link mixDuration}) when mixing from the previous
     * animation to this animation. Defaults to linear. */
    setMixInterpolation(mixInterpolation: Interpolation): void;
    mix(): number;
    /** For each timeline:
     * - Bit 0, FIRST: 0 = mix from current pose, 1 = mix from setup pose. Timeline is first to set the property.
     * - Bit 1, HOLD: 0 = mix out using alphaMix, 1 = apply full alpha to prevent dipping. Timeline is first on its track to
     * set the property and the next entry (mixingTo) also sets it. When held, timelineHoldMix's mix controls how the hold fades
     * out (for 3+ entry chains where the chain eventually stops setting the property). */
    timelineMode: number[];
    timelineHoldMix: TrackEntry[];
    timelinesRotation: number[];
    reset(): void;
    /** Uses {@link trackTime} to compute the `animationTime`, which is always between {@link animationStart} and
     * {@link animationEnd}. When `trackTime` is 0, `animationTime` is equal to the
     * `animationStart` time. */
    getAnimationTime(): number;
    setAnimationLast(animationLast: number): void;
    /** Returns true if at least one loop has been completed.
     *
     * See {@link AnimationStateListener.complete}. */
    isComplete(): boolean;
    /** When {@link shortestRotation} is false, this clears the directions for mixing this entry's rotation. This can be useful
     * to avoid bones rotating the long way around when using {@link getAlpha} and starting animations on other tracks.
     *
     * Mixing involves finding a rotation between two others. There are two possible solutions: the short or the long way
     * around. When the two rotations change over time, which direction is the short or long way can also change. If the short
     * way was always chosen, bones flip to the other side when that direction became the long way. TrackEntry chooses the short
     * way the first time it is applied and remembers that direction. Resetting that direction makes it choose a new short way
     * on the next apply. */
    resetRotationDirections(): void;
    /** If this track entry is non-looping, this is the track time in seconds when {@link animationEnd} is reached, or the
     * current {@link trackTime} if it has already been reached.
     *
     * If this track entry is looping, this is the track time when this animation will reach its next {@link animationEnd} (the
     * next loop completion). */
    getTrackComplete(): number;
    /** Returns true if this track entry has been applied at least once.
     *
     * See {@link AnimationState.apply}. */
    wasApplied(): boolean;
    /** Returns true if there is a {@link next} track entry and it will become the current track entry during the next
     * {@link AnimationState.update}. */
    isNextReady(): boolean;
}
export declare class EventQueue {
    objects: Array<EventType | TrackEntry | Event>;
    drainDisabled: boolean;
    animState: AnimationState;
    constructor(animState: AnimationState);
    start(entry: TrackEntry): void;
    interrupt(entry: TrackEntry): void;
    end(entry: TrackEntry): void;
    dispose(entry: TrackEntry): void;
    complete(entry: TrackEntry): void;
    event(entry: TrackEntry, event: Event): void;
    drain(): void;
    clear(): void;
}
export declare enum EventType {
    start = 0,
    interrupt = 1,
    end = 2,
    dispose = 3,
    complete = 4,
    event = 5
}
/** The interface to implement for receiving TrackEntry events. It is always safe to call AnimationState methods when receiving
 * events.
 *
 * TrackEntry events are collected during {@link AnimationState.update} and {@link AnimationState.apply} and
 * fired only after those methods are finished.
 *
 * See {@link TrackEntry.listener} and
 * {@link AnimationState.addListener}. */
export interface AnimationStateListener {
    /** Invoked when this entry has been set as the current entry. {@link end} will occur when this entry will no
     * longer be applied.
     *
     * When this event is triggered by calling {@link AnimationState.setAnimation}, take care not to
     * call {@link AnimationState.update} until after the TrackEntry has been configured. */
    start?: (entry: TrackEntry) => void;
    /** Invoked when another entry has replaced this entry as the current entry. This entry may continue being applied for
     * mixing. */
    interrupt?: (entry: TrackEntry) => void;
    /** Invoked when this entry will never be applied again. This only occurs if this entry has previously been set as the
     * current entry ({@link start} was invoked). */
    end?: (entry: TrackEntry) => void;
    /** Invoked when this entry will be disposed. This may occur without the entry ever being set as the current entry.
     * References to the entry should not be kept after dispose is called, as it may be destroyed or reused. */
    dispose?: (entry: TrackEntry) => void;
    /** Invoked every time this entry's animation completes a loop. This may occur during mixing (after
     * {@link interrupt}).
     *
     * If this entry's {@link TrackEntry.mixingTo} is not null, this entry is mixing out (it is not the current entry).
     *
     * Because this event is triggered at the end of {@link AnimationState.apply}, any animations set in response to
     * the event won't be applied until the next time the AnimationState is applied. */
    complete?: (entry: TrackEntry) => void;
    /** Invoked when this entry's animation triggers an event. */
    event?: (entry: TrackEntry, event: Event) => void;
}
export declare abstract class AnimationStateAdapter implements AnimationStateListener {
    start(entry: TrackEntry): void;
    interrupt(entry: TrackEntry): void;
    end(entry: TrackEntry): void;
    dispose(entry: TrackEntry): void;
    complete(entry: TrackEntry): void;
    event(entry: TrackEntry, event: Event): void;
}
export declare const SUBSEQUENT = 0;
export declare const FIRST = 1;
export declare const HOLD = 2;
export declare const HOLD_FIRST = 3;
export declare const SETUP = 1;
export declare const RETAIN = 2;
