import { RegisterParams, ReadonlyTeleBox, Room, AppContext, Player, View, NetlessApp } from '@netless/window-manager';
import { SlideError, VolumeAdjuster } from '@netless/ppt-player';
import { IPlugin } from '@netless/plugin-system';

declare class AliTrackLogger {
    private logList;
    private checkTimer;
    private config;
    private retryTimes;
    private enable;
    private db;
    private useIndexedDB;
    private readonly DB_NAME;
    private readonly STORE_NAME;
    private readonly BATCH_SIZE;
    constructor();
    private initIndexedDB;
    private storeLogInIndexedDB;
    private getLogsFromIndexedDB;
    private deleteLogsFromIndexedDB;
    private uploadLoggerGlobalEvent;
    start(): Promise<void>;
    pause(): void;
    addLog(message: string, level: Level, taskId: string, randomId: string): Promise<void>;
    private isDatabaseHealthy;
    private recreateDatabase;
    destroy(): void;
    uploadLog(focus?: boolean): Promise<void>;
    setEnable(enable: boolean): void;
}
declare type Level = "info" | "warn" | "error";

declare function preloadResource(taskId: string, prefix: string, maxResolutionLevel: number, onProgress: (p: number) => void, pages?: number[]): Promise<void>;

declare type UrlInterrupter = (url: string) => Promise<string>;
interface ILoaderDelegate {
    /**
     * Load JSON resources, need to return JSON text.
     * @param url Original resource address
     */
    loadJson(url: string): Promise<string>;
    /**
     * Load image resources, return Blob object.
     * @param url Original resource address
     */
    loadImage(url: string): Promise<Blob>;
    /**
     * Media file redirection, mp3 and mp4 resources will call this proxy function, and the redirected URL should be returned.
     * @param url Original resource address
     */
    redirectMedia(url: string): string;
}
interface RtcAudio {
    /**
     * Start playing audio.
     */
    play(): void;
    /**
     * Pause audio playback, and the current playback time of the audio remains unchanged.
     */
    pause(): void;
    /**
     * When the audio object is no longer in use, it is called.
     */
    destroy(): void;
    /**
     * Set volume, parameter value range 0 ~ 1.
     */
    volume(value: number): void;
    /**
     * Get the current playing time of the audio, in seconds.
     */
    get currentTime(): number;
    /**
     * Set the current playback time of the audio, in seconds. Please note that whether the audio is playing or not, it needs to be ensured that the setting is successful.
     * If the audio is in a paused state, set this value to ensure that the next time playback resumes, it starts playing from this position.
     */
    set currentTime(time: number);
    /**
     * Return whether the audio is in a paused state.
     */
    get isPaused(): boolean;
    /**
     * Return audio duration.
     */
    get duration(): number;
    /**
     * When the audio is loaded, for example: when the audio meta data is loaded and the actual duration of the audio is known,
     * this event needs to be triggered. It is necessary to ensure that this event is triggered when
     * You can obtain the updated audio duration through the duration attribute.
     * @param event
     * @param listener
     */
    on(event: "load", listener: () => void): this;
    /**
     * Trigger when the audio is paused.
     * @param event
     * @param listener
     */
    on(event: "pause", listener: () => void): this;
    /**
     * Trigger when the audio is beginning.
     * @param event
     * @param listener
     */
    on(event: "play", listener: () => void): this;
    on(event: "resumeAllAudioInterruptByAudioSessionChanged", listener: () => void): this;
    /**
     * Remove all listeners for the specified event.
     */
    removeAllListeners(event: string): void;
}
interface RtcAudioClazz {
    /**
     * Create an RTC player, with the URL as the audio address.
     * @param url
     */
    new (url: string): RtcAudio;
}
interface ILogger$1 {
    info?(msg: string): void;
    error?(msg: string): void;
    warn?(msg: string): void;
}
declare const SLIDE_EVENTS: {
    /** Synchronous event dispatch. */
    readonly syncDispatch: "syncDispatch";
    /** Synchronous event reception */
    readonly syncReceive: "syncReceive";
    /**
     * This event is only triggered in synchronous mode, indicating that synchronous messages are delayed and require full synchronization.
     */
    readonly syncEventLag: "syncEventLag";
    /** The current slide rendering starts triggering. */
    readonly renderStart: "renderStart";
    /** The current slide rendering is complete. */
    readonly renderEnd: "renderEnd";
    /** Current slide rendering error triggered. */
    readonly renderError: "renderError";
    /** Page number change triggers */
    readonly slideChange: "slideChange";
    /** Trigger at the beginning of the main sequence animation. */
    readonly mainSeqStepStart: "mainSeqStepStart";
    /** Triggered at the end of the main sequence animation. */
    readonly mainSeqStepEnd: "mainSeqStepEnd";
    /**
     * Trigger at the start of any animation.
     */
    readonly animateStart: "animateStart";
    /**
     * Trigger at the end of any animation.
     */
    readonly animateEnd: "animateEnd";
    /** slide State change trigger */
    readonly stateChange: "stateChange";
    /** ppt There is no next action trigger. **/
    readonly slideStepEnd: "slideEnd";
    /** ppt There is no previous action triggered. **/
    readonly slideStepStart: "slideStart";
    readonly useraddLink: "useraddLink";
};
interface ISlideRenderOptions {
    /** Minimum expected rendering fps, default is 40 */
    minFPS?: number;
    /** Expected maximum rendering fps, default is 50 */
    maxFPS?: number;
    /** 渲染分辨倍率, 整数,  default is window.devicePixelRatio */
    resolution?: number;
    /** Whether to automatically adjust the resolution based on fps., default is false */
    autoResolution?: boolean;
    /** Automatically reduce rendering. fps */
    autoFPS?: boolean;
    /** Background color when playing page transition animation, accepts CSS color strings or hexadecimal color values ("#ffffff", 0xffffff) */
    transactionBgColor?: string | number;
    /**
     * Used to set the maximum display resolution. This value not only affects the canvas rendering resolution, but also affects the texture quality.
     * On low-end devices, reducing this value can greatly improve memory usage and image black screen phenomenon.
     * [0] 640 * 360
     * [1] 960 * 540;
     * [2] Normal 1280 * 720; --- default setting for mobile devices.
     * [3] HD 1920 * 1080;
     * [4] 3K 3200 × 1800, greater than 4 is calculated as 4; --- default setting for PC devices.
     * By default, PC devices are set to 3K, and mobile devices are set to 720P.
     */
    maxResolutionLevel?: number;
    /**
     * Whether to force the use of 2D rendering, forcing the use of 2D rendering will lose some 3D, filters, and effects.
     */
    forceCanvas?: boolean;
    /**
     * @deprecated The current version has fixed the screen flickering issue, so there is no need to enable this parameter.
     * Should NVIDIA graphics card detection be enabled, Windows 11 with NVIDIA graphics card may experience screen flickering when playing certain page transition animations.
     * Enabling this option will automatically detect whether it is an NVIDIA graphics card. If it is,
     * it will use different logic to play page transition animations without screen flickering, but the response time for page transitions will be slower by 200 to 1000 ms.
     */
    enableNvidiaDetect?: boolean;
    /**
     * 切页动画截图分辨率等级
     * [0] 640 * 360
     * [1] 960 * 540;
     * [2] Normal 1280 * 720; --- default setting for mobile devices.
     * [3] HD 1920 * 1080;
     * [4] 3K 3200 × 1800, greater than 4 is calculated as 4; --- default setting for PC devices.
     */
    transitionResolutionLevel?: number;
    antialias?: boolean;
}
interface INavigatorDelegate {
    gotoPage?: (index: number) => void;
    openUrl?: (url: string) => void;
}
interface CustomLink {
    pageIndex: number;
    shapeId: string;
    link: string;
}
interface ISlideConfig {
    /** canvas mount dom */
    anchor: HTMLDivElement;
    /** can it interact */
    interactive: boolean;
    /** render options, Optional */
    renderOptions?: ISlideRenderOptions;
    /** Whether to display the control bar and stats */
    controller?: boolean;
    /** Whether to automatically adjust the resolution according to the window size */
    resize?: boolean;
    /** Get room time */
    timestamp?: () => number;
    /**
     * Operating mode
     *
     * "interactive" Interactive mode, everyone can operate ppt
     * "sync" Synchronization mode, only one person can operate ppt
     * "local" Local mode, no synchronization events will be triggered
     */
    mode: "interactive" | "sync" | "local" | "addLink";
    /**
     * Whether to enable global clicking, after turning on, as long as you click within the ppt viewport range,
     * and do not trigger interactive elements inside ppt, it will trigger the next action.
     * Default is false.
     */
    enableGlobalClick?: boolean;
    disableClickDebounce?: boolean;
    /**
     * The provided audio player class, used for rtc mixing
     */
    rtcAudio?: RtcAudioClazz;
    /**
     * Provide logger object for recording operation logs
     */
    logger?: ILogger$1;
    whiteTracker?: WhiteTracker;
    /**
     * Whether to enable local caching, after enabling, ppt remote resources will be cached in indexDB
     * Default is true
     */
    useLocalCache?: boolean;
    /**
     * Resource loading timeout, default 15 seconds
     */
    resourceTimeout?: number;
    /**
     * Remote resource proxy, for detailed use refer to README
     */
    loaderDelegate?: ILoaderDelegate;
    /**
     * PPT page navigation proxy, after adding this property,
     * the page number changes caused by actions within the ppt,
     * all go through the proxy logic.
     * PPT opens the webpage, needs to open through the openUrl method,
     * PPT page turning, needs to turn pages through the gotoPage method.
     */
    navigatorDelegate?: INavigatorDelegate;
    /**
     * Set a fixed height and width for ppt, after setting, ppt will not change automatically with the size of the parent element
     * If there is a need for scaling, you need to call the updateFixedFrameSize method
     * The units of width and height attributes are px
     */
    fixedFrameSize?: {
        width: number;
        height: number;
    };
    /**
     * Client id, in synchronization and interactive scenarios, it needs to be able to distinguish each different client.
     * For the end that receives the synchronization message, this needs to be used
     * ClientId distinguishes whether the message sent by oneself is received by oneself.
     * If in the synchronization and interactive scenarios,
     * not giving this value will cause the status to be out of sync in some cases,
     * the known scenarios are:
     * 1. A certain page of ppt has automatic animation, the next action performed during the animation,
     * on other clients may appear as the next page (i.e. page turning)
     */
    clientId?: string;
    urlInterrupter?: UrlInterrupter;
    /**
     * Whether to enable log tracking, after enabling,
     * local logs will be regularly and quantitatively uploaded to the sdk remote server
     * default is true
     */
    enableTracking?: boolean;
    enableWebAudio?: boolean;
    skipActionWhenFrozen?: boolean;
    enableAutoForward?: boolean;
    customLinks?: CustomLink[];
}
interface MediaState {
    type: "pause" | "play";
    time: number;
    frozenTime?: number;
    fullscreen?: boolean;
}
interface TimeNodeSeqState {
    step: number;
    state: "idle" | "running" | "end" | null;
}
interface ISlideState {
    taskId: string;
    url: string;
    currentSlideIndex: number;
    mainSeqStep: number;
    mainSeqState: "idle" | "running" | "end" | null;
    mediaState: {
        [key: string]: MediaState;
    };
    interactiveSeqState: {
        [key: string]: TimeNodeSeqState;
    };
}
declare type SyncEvent = SyncInteractiveAnimEvent | SyncPrevStepEvent | SyncNextStepEvent | SyncRenderSlideEvent | SyncSetResourceEvent | SyncMediaPlayEvent | SyncMediaPauseEvent | SyncMediaSeekEvent | SyncMediaFullscreenEvent;
interface BasicSyncEvent {
    slideIndex: number;
    uuid?: string;
    incrId?: number;
    clientId?: string;
}
interface SyncMediaPlayEvent extends BasicSyncEvent {
    type: "mediaPlay";
    id: string;
    state: MediaState;
}
interface SyncMediaPauseEvent extends BasicSyncEvent {
    type: "mediaPause";
    id: string;
    state: MediaState;
}
interface SyncMediaSeekEvent extends BasicSyncEvent {
    type: "mediaSeek";
    id: string;
    time: number;
    state: MediaState;
}
interface SyncMediaFullscreenEvent extends BasicSyncEvent {
    type: "mediaFullscreen";
    targetId: string;
    state: boolean;
}
interface SyncInteractiveAnimEvent extends BasicSyncEvent {
    type: "interactiveAnim";
    action: string;
    seqId: string;
}
interface SyncPrevStepEvent extends BasicSyncEvent {
    type: "prevStep";
    next: number;
}
interface SyncNextStepEvent extends BasicSyncEvent {
    type: "nextStep";
    next: number;
}
interface SyncRenderSlideEvent extends BasicSyncEvent {
    type: "renderSlide";
    index: number;
    isForward: boolean;
}
interface SyncSetResourceEvent extends BasicSyncEvent {
    type: "setResource";
    taskId: string;
    url: string;
}
interface SlideEventEmitter {
    removeAllListeners(): this;
    removeListener(event: keyof typeof SLIDE_EVENTS, fn?: any): this;
    emit(event: typeof SLIDE_EVENTS.renderStart, index: number): boolean;
    on(event: typeof SLIDE_EVENTS.renderStart, listener: (index: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.renderEnd, index: number): boolean;
    on(event: typeof SLIDE_EVENTS.renderEnd, listener: (index: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.slideChange, nextSlideIndex: number): boolean;
    on(event: typeof SLIDE_EVENTS.slideChange, listener: (nextSlideIndex: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.syncDispatch, args: SyncEvent): boolean;
    on(event: typeof SLIDE_EVENTS.syncDispatch, listener: (event: SyncEvent) => void): this;
    emit(event: typeof SLIDE_EVENTS.syncReceive, args: SyncEvent): boolean;
    on(event: typeof SLIDE_EVENTS.syncReceive, listener: (event: SyncEvent) => void): this;
    emit(event: typeof SLIDE_EVENTS.renderError, args: {
        error: SlideError;
        index: number;
    }): boolean;
    on(event: typeof SLIDE_EVENTS.renderError, listener: (args: {
        error: SlideError;
        index: number;
    }) => void): this;
    emit(event: typeof SLIDE_EVENTS.animateStart): boolean;
    on(event: typeof SLIDE_EVENTS.animateStart, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.animateEnd): boolean;
    on(event: typeof SLIDE_EVENTS.animateEnd, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.mainSeqStepStart, index: number): boolean;
    on(event: typeof SLIDE_EVENTS.mainSeqStepStart, listener: (index: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.mainSeqStepEnd, index: number): boolean;
    on(event: typeof SLIDE_EVENTS.mainSeqStepEnd, listener: (index: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.stateChange, state: ISlideState): boolean;
    on(event: typeof SLIDE_EVENTS.stateChange, listener: (state: ISlideState) => void): this;
    emit(event: typeof SLIDE_EVENTS.syncEventLag): boolean;
    on(event: typeof SLIDE_EVENTS.syncEventLag, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.slideStepEnd): boolean;
    on(event: typeof SLIDE_EVENTS.slideStepEnd, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.slideStepStart): boolean;
    on(event: typeof SLIDE_EVENTS.slideStepStart, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.useraddLink, taskId: string, pageIndex: number, shapeId: string): void;
    on(event: typeof SLIDE_EVENTS.useraddLink, listener: (taskId: string, pageIndex: number, shapeId: string) => void): this;
}
declare type TrackerEvent = {
    name: string;
    result: string;
    reason: string;
    payload: {
        [key: string]: any;
    };
};
declare type TrackerMeta = {
    slideVersion: string;
};
interface WhiteTracker {
    commit(event: TrackerEvent, meta: TrackerMeta): void;
}
declare const Slide_base: new () => SlideEventEmitter;
declare class Slide extends Slide_base {
    static preloadResource: typeof preloadResource;
    static instances: Slide[];
    static _tempFrozenIds: string[];
    static _tempLog: string;
    static _tempLogIndex: number;
    static flushLog(force?: boolean): Promise<void>;
    static remoteLogAddress: string | null;
    static stopRemoteLog(): void;
    static startRemoteLog(address: string): Promise<void>;
    static appendLogString(logStr: string): void;
    static usePlugin: (plugin: IPlugin) => void;
    /**
     * 设置全局音量, 对所有 Slide 实例都生效
     */
    static volumeAdjuster: VolumeAdjuster;
    static __stageCountLimit: number;
    static setStageCountLimit(limit: number): void;
    private iosResetCache;
    private iosNewPlayer?;
    private version?;
    private __slideState;
    private userInputTime;
    private isSyncingSlideState;
    private frozenTaskManager;
    private randomId;
    private resize;
    private isAnimating;
    private renderingTaskManager;
    private isLoading;
    private interactive;
    private anchor;
    private tracker;
    private player?;
    private renderingIndex;
    private frameWidth;
    private frameHeight;
    private frame;
    private canvasContainer;
    private medianController;
    private frameResizeObserver;
    private timestamp;
    private mode;
    private enableGlobalClick;
    private lastEmitedState;
    private syncQueue;
    private playerController;
    private lock;
    private isInitResized;
    private cacheImage;
    private config;
    private isTouchStart;
    private touchStartId;
    private taskId;
    private volumeAdjuster;
    private designWidth;
    private designHeight;
    private _slideCount;
    private logger;
    private _dispatchIncrId;
    private _receiveIncrId;
    private resizeView;
    private handleViewClick;
    static trackLogger: AliTrackLogger;
    private slideNots;
    private resourceList;
    private get dispatchIncrId();
    constructor(initConfig: ISlideConfig);
    private _updateVolumeByStaticAdjuster;
    private recoverHandler;
    private reportError;
    initSlideConfig(config: ISlideConfig): ISlideConfig;
    static handleFrozenAllSlide: () => void;
    static handleReleaseAllSlide: () => void;
    static handleLogReport: (sessionId: string) => Promise<void>;
    static handleLogDownload: () => Promise<void>;
    private urlInterrupter;
    private initPlayer;
    private userInputHandle;
    private _handleViewClick;
    private handleViewTouchStart;
    private handleViewTouchEnd;
    private createController;
    private handleSlideRef;
    private updateStageCountLimit;
    private setMedianControllerAttribute;
    private frameResizeHandler;
    /**
     *  Update ppt fixed height and width, this method only takes effect when the fixedFrameSize configuration item is set.
     * @param width Width value that needs to be updated, unit px.
     * @param height Height value that needs to be updated, unit px.
     */
    updateFixedFrameSize(width: number, height: number, callback?: () => void): void;
    private _resizeView;
    private receiveSyncHandler;
    /**
     * Set the state of the entire slide, the slide will update the screen with the incoming state.
     * It is called when synchronizing the whole.
     * @param state ISlideState
     */
    setSlideState(state: Partial<ISlideState>): Promise<void>;
    private initInteractiveSeq;
    private initMedia;
    /**
     * 返回 slide 总页数
     */
    get slideCount(): number;
    /**
     * Get the width and height of the slide in pixels,
     * return the array in the form [width, height].
     * Can be called before rendering the slide.
     */
    getSizeAsync(): Promise<[number, number]>;
    /**
     * Get the total number of slides, you can call it before renderSlide.
     */
    getSlideCountAsync(): Promise<number>;
    /**
     * The state of the entire slide, pass the obtained value to another client,
     * and call setSlideState to achieve overall synchronization. Read-only property.
     * @readonly
     */
    get slideState(): ISlideState;
    /**
     * Main sequence animation steps, read-only property.
     * @readonly
     */
    get mainSeqLength(): number;
    /**
     * Main sequence animation, current step, read-only property.
     * @readonly
     */
    get mainSeqStep(): number;
    /**
     * Main sequence animation, current state, read-only property
     * "idle": Animation has not started
     * "running": Animation is in progress
     * "end": Animation has ended
     * null: The current slide does not have a main sequence animation
     * @readonly
     */
    get mainSeqState(): "idle" | "running" | "end" | null;
    /**
     * Real-time rendering properties, read-only properties.
     * @readonly
     */
    get renderOptions(): ISlideRenderOptions | null;
    /**
     * drawCall count, which means the number of times gpu drawElements is called per frame, read-only property.
     * @readonly
     */
    get drawCall(): number;
    /**
     * Rendering fps, read-only property.
     * @readonly
     */
    get renderFps(): number;
    /**
     * js runtime fps, read-only.
     * @readonly
     */
    get runtimeFps(): number;
    /**
     * Render the canvas element of the Slide.
     * @readonly
     */
    get view(): HTMLCanvasElement | null;
    /**
     * Slide width. This width is the design width determined by ppt. Read-only property.
     * @readonly
     */
    get width(): number;
    /**
     * Slide height. This height is the design height determined by ppt. Read-only property.
     * @readonly
     */
    get height(): number;
    /**
     * 更新渲染属性
     * @param renderOptions
     */
    updateRenderOption(renderOptions: ISlideRenderOptions): void;
    /**
     * Set resources after converting ppt
     * @param taskId task id
     * @param url Resource URL prefix
     */
    setResource(taskId: string, url: string): void;
    private flushDebounce;
    setResourceList(taskId: string, urls: string[]): void;
    private _renderSlide;
    private handlePrevSlide;
    private handleNextSlide;
    private handleGotoSlide;
    /**
     * Render the ppt page corresponding to the index parameter.
     * @param index Page number to display, starting from 1.
     */
    renderSlide(index: number, isForward?: boolean): void;
    private needCreateNewPlayer;
    private poseRenderSlide;
    /**
     * Render the page specified by the index directly,
     * regardless of whether the current mode is sync or interactive.
     * Calling this method will not trigger the syncDispatch event.
     * @param index Page number to render
     * @param isForward Whether to flip forward or backward, affecting the page transition animation.
     */
    doRenderSlide(index: number, isForward?: boolean): Promise<void>;
    getSnapshot(): string | null;
    /**
     * 执行下一个主序列动画
     */
    nextStep(): void;
    private doNextStep;
    /**
     * Execute the previous main sequence animation.
     */
    prevStep(): void;
    private doPrevStep;
    private isSlideStateReady;
    private emitStateChange;
    private emitSyncDispatch;
    /**
     * Reset main sequence animation.
     * @param index Number of steps to reset to.
     * @param status The state to be reset to, "start" resets to the beginning of the animation, "end" resets to the end of the animation.
     */
    setMainSeqStep(index: number, status: "start" | "end"): void;
    /**
     * Set whether interaction is allowed.
     * @param val boolean
     */
    setInteractive(val: boolean): void;
    /**
     * Pause playback, asynchronous operation.
     */
    pause(): void;
    /**
     * Resume playback state, asynchronous operation.
     */
    resume(): void;
    private _doFrozen;
    /**
     * Enter freeze state, cache the ppt screen as an image, and release the WebGL context.
     */
    frozen(callback?: () => void): void;
    private _doRelease;
    /**
     * Recover from frozen state.
     */
    release(callback?: () => void): void;
    private _doDestroy;
    private waitLoadEnd;
    preload(index: number): Promise<void>;
    preloadResource(index: number): Promise<void>;
    /**
     * Destruction method.
     */
    destroy(): void;
    /**
     * Destroy the local cache of the current Slide instance, need to be called before destroy.
     */
    clearSlideCache(): void;
    /**
     * Return whether there is a next action in the ppt.
     */
    hasNextStep(): boolean;
    /**
     * Return whether there is a previous action in the ppt.
     */
    hasPrevStep(): boolean;
    /**
     * Capture a screenshot of the current state.
     * @return 图片 dataUrl, if failed return null
     */
    snapshot(): Promise<string | null>;
    /**
     * Capture a screenshot of the final step of the animation.
     * @param index The index of the slide to be captured.
     * @return 图片 dataUrl, if failed return null
     */
    snapshotWithTimingEnd(index: number): Promise<string | null>;
    /**
     * Set the global volume of this Slide instance, asynchronous operation,
     * only modify the local volume, will not trigger synchronous events.
     * @param v Value range 0 ~ 1
     */
    updateGlobalVolume(v: number): void;
    /**
     * Get the global volume of this Slide instance..
     */
    getGlobalVolume(): number;
    /**
     * Destroy all local cache of historical records.
     */
    static clearLocalCache(): void;
    /**
     * @deprecated This API is no longer functional. Please use `slideInstance.clearSlideCache` and `Slide.clearLocalCache` instead.
     */
    static disposeLocalCache(): void;
    getNoteForCurrentSlide(slideIndex: number): Promise<any>;
}

type SlideState = Slide["slideState"];
interface Attributes {
    /** convert task id */
    taskId: string;
    /** base url of converted resources */
    url: string;
    /** internal state of slide, do not change */
    state: SlideState | null;
    resourceList: string[];
    previewList: string[];
    customLinks: CustomLink[];
    slideScale: number;
    translateX: number;
    translateY: number;
}
type MagixPayload = {
    type: typeof SLIDE_EVENTS.syncDispatch;
    payload: SyncEvent;
};
type MagixEvents = {
    [SLIDE_EVENTS.syncDispatch]: MagixPayload;
};

interface FreezableSlide {
    freeze: () => void;
    unfreeze: () => void;
}
declare let useFreezer: boolean;
declare let FreezerLength: number;
declare function getFreezerLength(): number;
/** @param length - must be >= 1, default is 2 */
declare function setFreezerLength(length: number): void;
declare const apps: {
    map: Map<string, FreezableSlide>;
    boxes: Map<string, ReadonlyTeleBox>;
    queue: string[];
    validateQueue(): void;
    set(appId: string, slide: FreezableSlide, box: ReadonlyTeleBox): void;
    delete(appId: string): void;
    focus(appId: string): void;
};
declare function onCreated(callback: (appId: string) => void): () => boolean;
declare function onDestroyed(callback: (appId: string) => void): () => boolean;
type AddHooks = NonNullable<RegisterParams["addHooks"]>;
/**
 * Put this function in your register code:
 * `WindowManager.register({ kind: 'Slide', src: SlideApp, addHooks })`
 * So that it will automatically freeze the app when it is not in focus.
 */
declare const addHooks: AddHooks;

type SideEffectDisposer = () => any;
declare class SideEffectManager {
    /**
     * Add a disposer directly.
     * @param disposer a disposer or a list of disposers
     * @param disposerID Optional id for the disposer
     * @returns disposerID
     */
    addDisposer(disposer: SideEffectDisposer | SideEffectDisposer[], disposerID?: string): string;
    /**
     * @alias addDisposer
     * Add a disposer directly.
     * @param disposer a disposer or a list of disposers
     * @param disposerID Optional id for the disposer
     * @returns disposerID
     */
    push: (disposer: SideEffectDisposer | SideEffectDisposer[], disposerID?: string) => string;
    /**
     * Add a side effect.
     * @param executor Executes side effect. Return a disposer or a list of disposers. Returns null or false to ignore.
     * @param disposerID Optional id for the disposer
     * @returns disposerID
     */
    add(executor: () => SideEffectDisposer | SideEffectDisposer[] | null | false, disposerID?: string): string;
    /**
     * Sugar for addEventListener.
     * @param el
     * @param type
     * @param listener
     * @param options
     * @param disposerID Optional id for the disposer
     * @returns disposerID
     */
    addEventListener<K extends keyof WindowEventMap>(el: Window, type: K, listener: (this: Window, ev: WindowEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions, disposerID?: string): string;
    addEventListener<K extends keyof DocumentEventMap>(el: Document, type: K, listener: (this: Document, ev: DocumentEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions, disposerID?: string): string;
    addEventListener<K extends keyof HTMLElementEventMap>(el: HTMLElement, type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions, disposerID?: string): string;
    addEventListener<K extends keyof MediaQueryListEventMap>(el: MediaQueryList, type: K, listener: (this: HTMLElement, ev: MediaQueryListEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions, disposerID?: string): string;
    /**
     * Sugar for setTimeout.
     * @param handler
     * @param timeout
     * @param disposerID Optional id for the disposer
     * @returns disposerID
     */
    setTimeout(handler: () => void, timeout: number, disposerID?: string): string;
    /**
     * Sugar for setInterval.
     * @param handler
     * @param timeout
     * @param disposerID Optional id for the disposer
     * @returns disposerID
     */
    setInterval(handler: () => void, timeout: number, disposerID?: string): string;
    /**
     * Remove but not run the disposer. Do nothing if not found.
     * @param disposerID
     */
    remove(disposerID: string): SideEffectDisposer | undefined;
    /**
     * Remove and run the disposer. Do nothing if not found.
     * @param disposerID
     */
    flush(disposerID: string): void;
    /**
     * Remove and run all of the disposers.
     */
    flushAll(): void;
    /**
     * All disposers. Use this only when you know what you are doing.
     */
    readonly disposers: Map<string, SideEffectDisposer>;
    genUID(): string;
}

interface DocsViewerPage {
    src: string;
    height: number;
    width: number;
    thumbnail?: string;
}
interface DocsViewerConfig {
    readonly: boolean;
    onNewPageIndex: (index: number, origin?: string) => void;
    onPlay?: () => void;
    urlInterrupter?: (url: string) => Promise<string>;
    onPagesReady?: (pages: DocsViewerPage[]) => void;
}
declare class DocsViewer {
    constructor({ readonly, onNewPageIndex, onPlay, onPagesReady, urlInterrupter, }: DocsViewerConfig);
    protected readonly: boolean;
    protected onNewPageIndex: (index: number, origin?: string) => void;
    protected onPlay?: () => void;
    protected onPagesReady?: (pages: DocsViewerPage[]) => void;
    protected urlInterrupter: (url: string) => Promise<string> | string;
    private _pages;
    set pages(value: DocsViewerPage[]);
    get pages(): DocsViewerPage[];
    $content: HTMLElement;
    $preview: HTMLElement;
    $previewMask: HTMLElement;
    $footer: HTMLElement;
    $pageNumberInput: HTMLInputElement;
    $totalPage: HTMLSpanElement;
    $btnPlay: HTMLButtonElement;
    $btnSidebar: HTMLButtonElement;
    pageIndex: number;
    unmount(): void;
    setReadonly(readonly: boolean): void;
    destroy(): void;
    setPageIndex(pageIndex: number): void;
    refreshTotalPage(): void;
    setSmallBox(isSmallBox: boolean): void;
    render(): HTMLElement;
    protected renderContent(): HTMLElement;
    private previewLazyLoad?;
    protected renderPreview(): HTMLElement;
    private refreshPreview;
    protected renderPreviewMask(): HTMLElement;
    setPaused: () => void;
    setPlaying: () => void;
    refreshBtnSidebar(): void;
    protected renderFooter(): HTMLElement;
    protected renderFooterBtn(className: string, $icon: SVGElement, $iconActive?: SVGElement): HTMLButtonElement;
    protected togglePreview(isShowPreview?: boolean): void;
    protected wrapClassName(className: string): string;
    protected namespace: string;
    protected isShowPreview: boolean;
    protected isSmallBox: boolean;
    protected sideEffect: SideEffectManager;
}

declare function syncSceneWithSlide(room: Room, context: AppContext<Attributes>, slide: Slide, baseScenePath: string): void;

declare const DefaultUrl = "https://convertcdn.netless.link/dynamicConvert";
interface SlideControllerOptions {
    context: AppContext<Attributes, MagixEvents, AppOptions>;
    anchor: HTMLDivElement;
    onRenderStart: () => void;
    onRenderEnd: () => void;
    onPageChanged: (page: number) => void;
    onTransitionStart: () => void;
    onTransitionEnd: () => void;
    onError: (args: {
        error: Error;
        index: number;
    }) => void;
    onRenderError?: (error: Error, pageIndex: number) => void;
    onNavigate?: (index: number, origin?: string) => void;
    showRenderError?: boolean;
    invisibleBehavior?: "frozen" | "pause";
}
type MagixEventListener = Parameters<AppContext<Attributes, MagixEvents>["addMagixEventListener"]>[1];
declare class SlideControllerBase {
    readonly context: SlideControllerOptions["context"];
    slide: Slide;
    readonly showRenderError: boolean;
    readonly onRenderError?: (error: Error, pageIndex: number) => void;
    readonly onNavigate: (index: number, origin?: string) => void;
    protected readonly room?: Room;
    protected readonly player?: Player;
    protected readonly sideEffect: SideEffectManager;
    protected readonly onRenderStart: SlideControllerOptions["onRenderStart"];
    protected readonly onPageChanged: SlideControllerOptions["onPageChanged"];
    protected readonly onTransitionStart: SlideControllerOptions["onTransitionStart"];
    protected readonly onTransitionEnd: SlideControllerOptions["onTransitionEnd"];
    protected readonly onError: SlideControllerOptions["onError"];
    protected syncStateOnceFlag: boolean;
    protected visible: boolean;
    protected savedIsFrozen: boolean;
    protected invisibleBehavior: "frozen" | "pause";
    previewList: string[];
    constructor(props: SlideControllerOptions);
    ready: boolean;
    protected resolveReady: (index: number) => void;
    readonly readyPromise: Promise<void>;
    jumpToPage(page: number, origin?: string): void;
    protected initialize(): void;
    protected kickStart(): void;
    protected registerEventListeners(): void;
    protected onSyncDispatch: (event: SyncEvent) => void;
    protected magixEventListener: MagixEventListener;
    protected syncStateOnce(): void;
    protected onStateChange: (state: SlideState) => void;
    protected pollCount: number;
    protected pollReadyState: () => void;
    protected _pageCount: number;
    get pageCount(): number;
    get page(): number;
    protected createSlide(anchor: HTMLDivElement, defaults?: Partial<ISlideConfig>): Slide;
    protected destroyed: boolean;
    destroy(): void;
    timestamp: () => number;
    isFrozen: boolean;
    protected _toFreeze: -1 | 0 | 1;
    freeze: () => void;
    unfreeze: () => Promise<void>;
    protected bindAppStateChangeEvent: () => void;
    protected onAppStateChangeHandler: (state: "normal" | "minimized" | "maximized") => void;
    protected onAppStatusChangeHandler: (payload: {
        appId: string;
        status: "normal" | "minimized" | "maximized";
    }) => void;
    protected getAppStatus: () => "normal" | "minimized" | "maximized" | undefined;
    protected onVisibilityChange: () => Promise<void>;
}
declare class SlideController extends SlideControllerBase {
    constructor(props: SlideControllerOptions);
}

declare class ResizableContainer {
    private root;
    container: HTMLDivElement;
    private scrollContainer;
    onScaleChanged: ((scale: number) => void) | null;
    private parent;
    private whiteboardContainer;
    private slide;
    private scale;
    private resizeObserver;
    private slideWidth;
    private slideHeight;
    private scrollBar;
    private context;
    private translateX;
    private translateY;
    private enableResize;
    constructor(parent: HTMLElement, context: AppContext<Attributes, MagixEvents, AppOptions>, enableResize: boolean);
    getTranslate(): {
        x: number;
        y: number;
    };
    getScale(): number;
    private renderScrollBar;
    setSlideObject(slide: Slide): void;
    private updateSlideSize;
    updateResizableContainer(): void;
    handleNormalizeTranslate(x: number, y: number, options: {
        triggerScrollBar: boolean;
        triggerSync: boolean;
    }): void;
    scaleContainer(applyScale: number): void;
    addSlideContainer(slideContainer: HTMLDivElement): void;
    addWhiteboardContainer(whiteboardContainer: HTMLDivElement): void;
    getCurrentScale(): number;
    destroy(): void;
}

type MountSlideOptions = Omit<SlideControllerOptions, "context" | "onPageChanged"> & {
    onReady: () => void;
};
interface SlideDocsViewerConfig {
    context: AppContext<Attributes, MagixEvents, AppOptions>;
    box: ReadonlyTeleBox;
    view: View;
    mountSlideController: (options: MountSlideOptions) => SlideController;
    mountWhiteboard: (dom: HTMLDivElement) => void;
    baseScenePath: string;
    appId: string;
    urlInterrupter?: (url: string) => Promise<string>;
    enableScale?: boolean;
    onPagesReady?: (pages: DocsViewerPage[]) => void;
    onNavigate?: (index: number, origin?: string) => void;
}
declare class SlideDocsViewer {
    readonly context: AppContext<Attributes, MagixEvents, AppOptions>;
    viewer: DocsViewer;
    slideController: SlideController | null;
    protected readonly box: ReadonlyTeleBox;
    protected readonly whiteboardView: SlideDocsViewerConfig["view"];
    protected readonly mountSlideController: SlideDocsViewerConfig["mountSlideController"];
    protected readonly mountWhiteboard: SlideDocsViewerConfig["mountWhiteboard"];
    protected readonly onNavigate: (index: number, origin?: string) => void;
    protected readonly baseScenePath: string;
    protected readonly appId: string;
    protected isViewMounted: boolean;
    protected justSildeReadonly: boolean;
    private enableScale;
    constructor({ context, box, view, mountSlideController, mountWhiteboard, baseScenePath, appId, urlInterrupter, enableScale, onPagesReady, onNavigate, }: SlideDocsViewerConfig);
    $slide: HTMLDivElement;
    $whiteboardView: HTMLDivElement;
    $overlay: HTMLDivElement;
    resizableContainer: ResizableContainer;
    setJustSildeReadonly(justSildeReadonly: boolean): void;
    render(): void;
    protected renderOverlay(): HTMLDivElement;
    protected renderSlideContainer(): HTMLDivElement;
    protected renderWhiteboardView(): HTMLDivElement;
    mount(): this;
    protected onError: ({ error, index }: {
        error: Error;
        index: number;
    }) => void;
    protected onRenderStart: () => void;
    protected onRenderEnd: () => void;
    onPageChanged: () => void;
    protected _onPageChangedTimer: number;
    protected _onPageChanged: () => void;
    protected refreshPages: () => void;
    protected getPageIndex(page: number): number;
    unmount(): this;
    setReadonly(readonly: boolean): void;
    destroy(): void;
    toggleClickThrough(tool?: string): void;
    protected scaleDocsToFit: () => void;
    protected onPlay: () => void;
    protected onNewPageIndex: (index: number, origin?: string) => void;
    protected sideEffect: SideEffectManager;
    protected wrapClassName(className: string): string;
    protected namespace: string;
    protected getWhiteSnapshot(pageIndex: number, canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, slideWidth: number, slideHeight: number): Promise<void>;
    protected reportProgress(progress: number, result: {
        pdf: ArrayBuffer;
        title: string;
    } | null): void;
    protected toPdf: () => Promise<null | undefined>;
}

type DebugMessage = {
    slide: boolean | "__instance" | "__debug";
};
type RoomLogger = {
    debug: (...args: any) => void;
    info: (...args: any) => void;
    warn: (...args: any) => void;
};
declare class Logger {
    enable: boolean;
    apps: Record<string, {
        context?: AppContext | null;
        controller?: SlideController | null;
    }>;
    setAppContext(appId: string, context: AppContext | null): void;
    setAppController(appId: string, controller: SlideController | null): void;
    deleteApp(appId: string): void;
    level: "debug" | "verbose";
    roomLogger: RoomLogger | null;
    constructor(enable: boolean);
    initialize(): void;
    dispose(): void;
    log(...args: any[]): void;
    verbose(...args: any[]): void;
    warn(...args: any[]): void;
    /**
     * @example
     * window.postMessage({ slide: '__debug' })
     * window.dispatchEvent(new MessageEvent('message', { data: { slide: '__debug' } }))
     */
    _onMessage: (ev: MessageEvent<DebugMessage> | CustomEvent<DebugMessage>) => void;
}
declare const logger: Logger;
declare const log: (...args: any[]) => void;

interface PreviewParams {
    container: HTMLElement;
    taskId: string;
    url?: string;
    debug?: boolean;
    resourceList?: string[];
}
declare function previewSlide({ container, taskId, resourceList, url, debug, }: PreviewParams): SlidePreviewer;
declare class SlidePreviewer {
    readonly viewer: DocsViewer;
    readonly bgColor: string;
    readonly target: HTMLElement;
    slide: Slide | null;
    debug: boolean;
    $slide: HTMLDivElement;
    protected previewList: string[];
    protected readonly sideEffect: SideEffectManager;
    ready: boolean;
    protected resolveReady: () => void;
    readonly readyPromise: Promise<void>;
    constructor(config: {
        target: HTMLElement;
    });
    render(): void;
    /**
     * In case you have a different window -- for example, in electron.
     * Use this method to re-register hotkeys.
     *
     * @example
     * previewer.registerHotKeys(windowLike)
     */
    registerHotKeys(windowLike: Window): void;
    protected hotkeyListener: (ev: KeyboardEvent) => void;
    mount(taskId: string, url: string, resourceList: string[], previewList?: string[]): void;
    protected renderStyle(): HTMLElement;
    protected registerEventListeners(): void;
    protected onPageChanged: (page: number) => void;
    protected onTransitionStart: () => void;
    protected onTransitionEnd: () => void;
    protected onError: ({ error }: {
        error: Error;
    }) => void;
    protected destroyed: boolean;
    destroy(): void;
    protected refreshPages: () => void;
    protected getPageIndex(page: number): number;
    protected renderSlideContainer(): HTMLDivElement;
    protected onPlay: () => void;
    protected onNewPageIndex: (index: number) => void;
    protected wrapClassName(className: string): string;
    protected namespace: string;
}

declare const usePlugin: (plugin: any) => any;
declare const version: string;

interface AppOptions extends Pick<ISlideConfig, "rtcAudio" | "useLocalCache" | "resourceTimeout" | "loaderDelegate" | "urlInterrupter" | "navigatorDelegate" | "fixedFrameSize" | "logger" | "enableGlobalClick" | "skipActionWhenFrozen"> {
    /** show debug controller */
    debug?: boolean;
    /** scale */
    resolution?: number;
    /** background color for slide animations */
    bgColor?: string;
    /** minimal fps @default 25 */
    minFPS?: number;
    /** maximal fps @default 30 */
    maxFPS?: number;
    /** automatically decrease fps @default true */
    autoFPS?: boolean;
    /** whether to re-scale automatically @default true */
    autoResolution?: boolean;
    /** 0~4, default: 3 */
    maxResolutionLevel?: number;
    /** use canvas2d mode, downside: some 3d effects are lost */
    forceCanvas?: boolean;
    /** fix windows 11 nvidia rendering bug, downside: render next page slows down */
    enableNvidiaDetect?: boolean;
    /** custom error handler */
    onRenderError?: (error: Error, pageIndex: number) => void;
    /** whether to show an overlay of error message @default: true */
    showRenderError?: boolean;
    /** Specify the behavior after hiding the slide; Freeze will destroy the slide and replace it with a snapshot, while Pause simply pauses the slide @default: 'frozen' */
    invisibleBehavior?: "frozen" | "pause";
    /** just readonly, no operate silder */
    justSildeReadonly?: true;
    enableScale?: boolean;
}
interface ILogger {
    info?(msg: string): void;
    error?(msg: string): void;
    warn?(msg: string): void;
}
interface AppResult {
    viewer: () => SlideDocsViewer | null;
    controller: () => SlideController | null | undefined;
    slide: () => Slide | undefined;
    position: () => [page: number, pageCount: number] | undefined;
    nextStep: () => boolean;
    prevStep: () => boolean;
    nextPage: () => boolean;
    prevPage: () => boolean;
    jumpToPage: (page: number) => boolean;
    setSildeReadonly: (bol: boolean) => void;
    onScaleChanged: (cb: (scale: number) => void) => void;
    scaleView: (to: number) => void;
    getViewScale: () => number | undefined;
    translateView: (offsetX: number, offsetY: number) => void;
}
declare const SlideApp: NetlessApp<Attributes, MagixEvents, AppOptions, AppResult>;

export { DefaultUrl, DocsViewer, FreezerLength, SideEffectManager, Slide, SlideController, SlideControllerBase, SlideDocsViewer, SlidePreviewer, addHooks, apps, SlideApp as default, getFreezerLength, log, logger, onCreated, onDestroyed, previewSlide, setFreezerLength, syncSceneWithSlide, useFreezer, usePlugin, version };
export type { AddHooks, AppOptions, AppResult, Attributes, FreezableSlide, ILogger, PreviewParams };
