import { AnalysisApi } from "./analysis.js";
import { AreaMetricsApi } from "./areaMetrics.js";
import { AuthApi } from "./auth/auth.js";
import { ColorbarApi } from "./colorbar.js";
import { ElementsApi } from "./elements.js";
import { ExperimentalApi } from "./experimental/index.js";
import { ExtensionsApi } from "./extensions.js";
import { GeneratorsApi } from "./generators.js";
import { GeoDataApi } from "./geodata.js";
import { GeometryApi } from "./geometry.js";
import { IframeMessenger, type CreateSubscriptionResult } from "./iframe-messenger.js";
import { IntegrateApi } from "./integrate.js";
import { LibraryApi } from "./library.js";
import { PredictiveAnalysisApi } from "./predictive-analysis.js";
import { ProjectApi } from "./project.js";
import { ProposalApi } from "./proposal.js";
import { CameraApi } from "./scene/camera.js";
import { DesignToolApi } from "./scene/design-tool.js";
import { RenderApi } from "./scene/render.js";
import { SunApi } from "./scene/sun.js";
import { TerrainApi } from "./scene/terrain.js";
import { SelectionApi } from "./selection.js";
import { SettingsApi } from "./settings.js";
import type { EventHandler, RequestHandler, SubscribeHandler } from "./types.js";
export declare const defaultAllowedOrigins: (string | RegExp)[];
export declare function checkAllowedOrigin(origin: string, allowedOrigins: Readonly<typeof defaultAllowedOrigins>): boolean;
export type EmbeddedViewSdkConfig = Readonly<{
    debug?: boolean | undefined;
    origin?: string | undefined;
    allowedOrigins?: readonly string[] | undefined;
}>;
export declare class EmbeddedViewSdk {
    #private;
    readonly config?: EmbeddedViewSdkConfig | undefined;
    source: Window;
    readonly origin: string;
    /**
     * Experimental APIs are subject to change at any time without notice.
     *
     * Do not rely on experimental APIs in production code.
     */
    experimental: ExperimentalApi;
    analysis: AnalysisApi;
    extensions: ExtensionsApi;
    elements: ElementsApi;
    generators: GeneratorsApi;
    geometry: GeometryApi;
    integrateElements: IntegrateApi;
    library: LibraryApi;
    project: ProjectApi;
    proposal: ProposalApi;
    camera: CameraApi;
    sun: SunApi;
    terrain: TerrainApi;
    render: RenderApi;
    selection: SelectionApi;
    areaMetrics: AreaMetricsApi;
    predictiveAnalysis: PredictiveAnalysisApi;
    designTool: DesignToolApi;
    auth: AuthApi;
    colorbar: ColorbarApi;
    geoData: GeoDataApi;
    settings: SettingsApi;
    constructor(config?: EmbeddedViewSdkConfig | undefined);
    ping(): Promise<string>;
    /**
     * @hidden
     * @internal
     */
    getIframeMessenger(): IframeMessenger;
    getProjectId(): string;
    getExtensionId(): string;
    /**
     * Get the region for which the current Forma Site Design project is hosted.
     * If you're using the Forma Site Design API, you need to use this to determine
     * the `X-Ads-Region` header value. The possible values are `US` and `EMEA`
     * @returns "EMEA" or "US"
     */
    getRegion(): "EMEA" | "US";
    /**
     * Get the preferred presentation unit system for the project.
     * It is important to note that all programmatic interfaces operate with metric units.
     * This value should be used to determine the default unit system for the UI.
     * If this value is imperial, you should convert and dispaly results in imperial units in the UI.
     */
    getPresentationUnitSystem(): Promise<"metric" | "imperial">;
    /**
     * Check for access to perform edit operations in the current project.
     *
     * @example
     * ```js
     * const canEdit = await Forma.getCanEdit()
     * if (canEdit) {
     *  await Forma.proposal.addElement({ urn })
     * } else {
     *   console.log("User need to have collaborator or admin role to add elements")
     * }
     * ```
     */
    getCanEdit(): Promise<boolean>;
    /**
     * Check for access to view the current project's hub
     * @example
     * ```js
     * const canViewHub = await Forma.getCanViewHub()
     * if (canViewHub) {
     *   const projectData = await Forma.project.get()
     *   await Forma.extensions.storage.getTextObject({
     *     key: "some-key",
     *     authcontext: projectData.hubId
     *   })
     * }
     * ```
     */
    getCanViewHub(): Promise<boolean>;
    /**
     * Check for access to edit the current project's hub
     * @example
     * ```js
     * const canViewHub = await Forma.getCanEditHub()
     * if (canEditHub) {
     *   const projectData = await Forma.project.get()
     *   await Forma.extensions.storage.setObject({
     *     key: "some-key",
     *     authcontext: projectData.hubId,
     *     data: "some awesome data"
     *   })
     * }
     * ```
     */
    getCanEditHub(): Promise<boolean>;
    /**
     * Retrieve the embedded view ID used to identify this embedded view.
     *
     * You can set a custom embedded view ID when dynamically opening
     * an embedded view inside a floating panel.
     */
    getEmbeddedViewId(): string;
    static getHostOrigin(): string;
    /**
     * @hidden
     * @internal
     *
     * @remarks
     * This method allows only one handler to be registered per action.
     * Registering a new handler for the same action will replace the existing handler.
     */
    setRequestHandler(name: string, handler: RequestHandler): void;
    /**
     * @hidden
     * @internal
     */
    deleteRequestHandler(name: string): boolean;
    /**
     * @hidden
     * @internal
     *
     * @remarks
     * This method allows only one handler to be registered per action.
     * Registering a new handler for the same action will replace the existing handler.
     */
    setEventHandler(name: string, handler: EventHandler): void;
    /**
     * @hidden
     * @internal
     */
    deleteEventHandler(name: string): boolean;
    /**
     * @hidden
     * @internal
     *
     * @remarks
     * This method allows only one handler to be registered per action.
     * Registering a new handler for the same action will replace the existing handler.
     */
    setSubscribeHandler(name: string, handler: SubscribeHandler): void;
    /**
     * @hidden
     * @internal
     */
    deleteSubscribeHandler(name: string): boolean;
    /**
     * @hidden
     * @internal
     */
    sendRequest<T, R>(action: string, payload: T, transfer?: Transferable[]): Promise<R>;
    /**
     * @hidden
     * @internal
     */
    sendEvent<T>(action: string, payload: T, transfer?: Transferable[]): Promise<void>;
    /**
     * @hidden
     * @internal
     */
    createSubscription<T, O extends Record<string, unknown> = Record<string, unknown>>(name: string, handler: (event: T) => void, options?: O): Promise<CreateSubscriptionResult>;
    /**
     * Open another embedded view in a floating panel.
     *
     * The embedded view will be owned by the current embedded view,
     * and automatically closed when the current embedded view is closed.
     *
     * To wait for the embedded view to be ready or being closed, listen to
     * the relevant events via {@link onEmbeddedViewStateChange}
     * before invoking this method. Methods such as {@link createMessagePort}
     * will automatically wait for the embedded view to be ready.
     *
     * If the URL is invalid or the embedded view cannot be initialized,
     * the state of the embedded view will remain open and not connected,
     * until the user closes the panel which triggers the closed state.
     *
     * @experimental
     */
    openFloatingPanel(options: {
        embeddedViewId: string;
        url: string;
        /**
         * Title shown for the floating panel.
         */
        title?: string | undefined;
        /**
         * The initial size of the floating panel.
         *
         * The panel will be shrinked if it cannot fit within the main area.
         */
        preferredSize?: {
            width: number;
            height: number;
        } | undefined;
        /**
         * The initial position of the floating panel.
         */
        placement?: {
            type: "right";
            /**
             * Offset from the top position of the current embedded view.
             *
             * This allows to position the floating panel at the
             * same top position as e.g. a clicked button.
             *
             * `Element.getBoundingClientRect().top` can be used to
             * calculate a value for this.
             *
             * @defaultValue 0
             */
            offsetTop?: number | undefined;
        } | {
            type: "fullscreen";
        } | {
            /**
             * Position the floating panel in center of the available view.
             */
            type: "center";
        } | undefined;
        /**
         * Absolute URL to an icon.
         *
         * The icon will be displayed as a square (currently 24x24 pixels).
         *
         * @defaultValue A generic icon.
         */
        iconUrl?: string | undefined;
        /**
         * Hide the icon.
         *
         * @defaultValue false
         */
        hideIcon?: boolean | undefined;
        /**
         * Disable the minimize functionality.
         *
         * @defaultValue false
         */
        disableMinimize?: boolean | undefined;
        /**
         * Disable the resize functionality.
         *
         * @defaultValue false
         */
        disableResize?: boolean | undefined;
        /**
         * Minimum width for a resizable floating panel.
         *
         * This is the width of the embedded view, so the actual
         * panel width will be larger to include the spacing around.
         *
         * Can not be specified below the default value.
         *
         * Can not be specified above 400.
         *
         * @defaultValue 100
         */
        minimumWidth?: number | undefined;
        /**
         * Minimum height for a resizable floating panel.
         *
         * This is the height of the embedded view, so the actual
         * panel height will be larger to include the header and
         * spacing around.
         *
         * Can not be specified below the default value.
         *
         * Can not be specified above 400.
         *
         * @defaultValue 60
         */
        minimumHeight?: number | undefined;
    }): Promise<void>;
    /**
     * Close an embedded view belonging to this extension.
     *
     * Currently only floating panels can be closed.
     *
     * If the embedded view is not open this will still resolve successfully.
     *
     * @experimental
     */
    closeEmbeddedView(options: {
        embeddedViewId: string;
    }): Promise<void>;
    /**
     * Listen to when the state of an embedded view belonging to the current
     * extension changes.
     *
     * @experimental
     */
    onEmbeddedViewStateChange(handler: (payload: {
        embeddedViewId: string;
        state: "opened" | "connected" | "disconnected" | "closed";
    }) => void): Promise<CreateSubscriptionResult>;
    /**
     * Subscribe to locale updates.
     *
     * The handler will be called when the locale updates or locale becomes ready.
     *
     * @example
     * ```js
     * const i18n = ... // your i18n library
     *
     * void Forma.onLocaleUpdate(({ locale }) => {
     *   i18n.setLocale(locale)
     * })
     * ```
     *
     * @param handler function to be called when the locale updates
     * @returns { unsubscribe: () => void } object with an `unsubscribe` method to stop subscribing to the event
     */
    onLocaleUpdate(handler: (payload: {
        locale: string;
    }) => void): Promise<CreateSubscriptionResult>;
    /**
     * Register a handler to be called when the embedded view is closing.
     * It will be called before the embedded view is removed from the DOM.
     * The handler must resolve before the timeout duration.
     *
     * @example
     * const { unsubscribe } = Forma.onEmbeddedViewClosing(async ({ timeoutDuration }) => {
     *    await new Promise((resolve) => setTimeout(() => {
     *      console.log(`The embedded view will be removed from DOM within ${timeoutDuration}ms`)
     *      resolve(null)
     *    }, 5000))
     * })
     *
     * // Later, when you want to stop listening for changes:
     * unsubscribe()
     *
     * @param handler function to be called when the embedded view is closing. The handler must resolve before the timeout duration.
     * @returns { unsubscribe: () => void } object with an `unsubscribe` method to stop subscribing to the event
     *
     * @remarks
     * This will not function when the user closes the tab or browser gracefully.
     * To ensure robustness, please also handle these events.
     * Learn more at [Window: beforeunload event](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event).
     *
     * @experimental
     */
    onEmbeddedViewClosing(handler: (payload: {
        timeoutDuration: number;
    }) => Promise<void>): CreateSubscriptionResult;
    /**
     * Create a MessagePort that can be used to communicate directly with
     * another embedded view belonging to the current extension.
     *
     * The other embedded view must have called the {@link onMessagePort} method
     * during initialization for this to succeeed.
     *
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API
     * @experimental
     */
    createMessagePort(options: {
        /**
         * The ID of the embedded view to communicate with.
         */
        embeddedViewId: string;
        /**
         * Optional name for the port. Can be used if setting
         * up multiple ports to distinguish between them.
         */
        portName?: string | undefined;
    }): Promise<MessagePort>;
    /**
     * Receive a MessagePort initiated from {@link createMessagePort}.
     *
     * The first time this is called, the handler will receive any
     * queued message ports.
     *
     * @returns A function that can be used to unsubscribe.
     *
     * @experimental
     */
    onMessagePort(handler: (payload: {
        portName?: string | undefined;
        port: MessagePort;
    }) => void): () => void;
}
