import '../../chipper/js/browser/initialize-globals.js';
import '../../assert/js/assert.js';
import '../../globals.js';
import Disposable, { DisposableOptions } from '../../axon/js/Disposable.js';
import { OptionizeDefaults } from '../../phet-core/js/optionize.js';
import IntentionalAny from '../../phet-core/js/types/IntentionalAny.js';
import StrictOmit from '../../phet-core/js/types/StrictOmit.js';
import EventType from './EventType.js';
import { PhetioElementMetadata, PhetioID } from './phet-io-types.js';
import Tandem from './Tandem.js';
import IOType from './types/IOType.js';
type StartEventOptions = {
    data?: Record<string, IntentionalAny> | null;
    getData?: (() => Record<string, IntentionalAny>) | null;
};
type EventMetadata = Record<string, string | boolean | number | Array<string | boolean | number>>;
type SelfOptions = StrictOmit<Partial<PhetioElementMetadata>, 'phetioTypeName' | 'phetioArchetypePhetioID' | 'phetioIsArchetype' | 'phetioEventType'> & {
    tandem?: Tandem;
    descriptionTandem?: Tandem;
    phetioType?: IOType;
    phetioEventType?: EventType;
    phetioEventMetadata?: EventMetadata | null;
    tandemNameSuffix?: string | string[] | null;
};
export type PhetioObjectOptions = SelfOptions & DisposableOptions;
type PhetioObjectMetadataKeys = keyof (StrictOmit<PhetioElementMetadata, 'phetioTypeName' | 'phetioDynamicElementName'>) | 'phetioType';
export type PhetioObjectMetadataInput = Pick<PhetioObject, PhetioObjectMetadataKeys>;
declare class PhetioObject extends Disposable {
    tandem: Tandem;
    private phetioObjectInitialized;
    phetioIsArchetype: boolean;
    phetioBaselineMetadata: PhetioElementMetadata | null;
    private _phetioType;
    private _phetioState;
    private _phetioReadOnly;
    private _phetioDocumentation;
    private _phetioEventType;
    private _phetioHighFrequency;
    private _phetioPlayback;
    private _phetioDynamicElement;
    private _phetioFeatured;
    private _phetioEventMetadata;
    private _phetioDesigned;
    phetioArchetypePhetioID: string | null;
    private linkedElements;
    phetioNotifiedObjectCreated: boolean;
    private phetioMessageStack;
    static readonly DEFAULT_OPTIONS: OptionizeDefaults<StrictOmit<SelfOptions, "phetioDynamicElementName">>;
    phetioID: PhetioID;
    constructor(options?: PhetioObjectOptions);
    /**
     * Like SCENERY/Node, PhetioObject can be configured during construction or later with a mutate call.
     * Noop if provided options keys don't intersect with any key in DEFAULTS; baseOptions are ignored for this calculation.
     */
    protected initializePhetioObject(baseOptions: Partial<PhetioObjectOptions>, providedOptions: PhetioObjectOptions): void;
    static swapCaseOfFirstCharacter(string: string): string;
    get phetioType(): IOType;
    get phetioState(): boolean;
    get phetioReadOnly(): boolean;
    get phetioDocumentation(): string;
    get phetioEventType(): EventType;
    get phetioHighFrequency(): boolean;
    get phetioPlayback(): boolean;
    get phetioDynamicElement(): boolean;
    get phetioFeatured(): boolean;
    get phetioEventMetadata(): EventMetadata | null;
    get phetioDesigned(): boolean;
    /**
     * Start an event for the nested PhET-iO data stream.
     *
     * @param event - the name of the event
     * @param [providedOptions]
     */
    phetioStartEvent(event: string, providedOptions?: StartEventOptions): void;
    /**
     * End an event on the nested PhET-iO data stream. It this object was disposed or dataStream.start was not called,
     * this is a no-op.
     */
    phetioEndEvent(assertCorrectIndices?: boolean): void;
    /**
     * Set any instrumented descendants of this PhetioObject to the same value as this.phetioDynamicElement.
     */
    propagateDynamicFlagsToDescendants(): void;
    /**
     * Used in PhetioEngine
     */
    setPhetioDynamicElement(phetioDynamicElement: boolean): void;
    /**
     * Mark this PhetioObject as an archetype for dynamic elements.
     */
    markDynamicElementArchetype(): void;
    /**
     * A PhetioObject will only be instrumented if the tandem that was passed in was "supplied". See Tandem.supplied
     * for more info.
     */
    isPhetioInstrumented(): boolean;
    /**
     * When an instrumented PhetioObject is linked with another instrumented PhetioObject, this creates a one-way
     * association which is rendered in Studio as a "symbolic" link or hyperlink. Many common code UI elements use this
     * automatically. To keep client sites simple, this has a graceful opt-out mechanism which makes this function a
     * no-op if either this PhetioObject or the target PhetioObject is not instrumented.
     *
     * You can specify the tandem one of three ways:
     * 1. Without specifying tandemName or tandem, it will pluck the tandem.name from the target element
     * 2. If tandemName is specified in the options, it will use that tandem name and nest the tandem under this PhetioObject's tandem
     * 3. If tandem is specified in the options (not recommended), it will use that tandem and nest it anywhere that tandem exists.
     *    Use this option with caution since it allows you to nest the tandem anywhere in the tree.
     *
     * @param element - the target element. Must be instrumented for a LinkedElement to be created-- otherwise gracefully opts out
     * @param [providedOptions]
     */
    addLinkedElement(element: PhetioObject, providedOptions?: LinkedElementOptions): void;
    /**
     * Remove all linked elements linking to the provided PhetioObject. This will dispose all removed LinkedElements. This
     * will be graceful, and doesn't assume or assert that the provided PhetioObject has LinkedElement(s), it will just
     * remove them if they are there.
     */
    removeLinkedElements(potentiallyLinkedElement: PhetioObject): void;
    /**
     * Performs cleanup after the sim's construction has finished.
     */
    onSimulationConstructionCompleted(): void;
    /**
     * Overrideable so that subclasses can return a different PhetioObject for studio autoselect. This method is called
     * when there is a scene graph hit. Return the corresponding target that matches the PhET-iO filters.  Note this means
     * that if PhET-iO Studio is looking for a featured item and this is not featured, it will return 'phetioNotSelectable'.
     * Something is 'phetioNotSelectable' if it is not instrumented or if it does not match the "featured" filtering.
     *
     * The `fromLinking` flag allows a cutoff to prevent recursive linking chains in 'linked' mode. Given these linked elements:
     * cardNode -> card -> cardValueProperty
     * We don't want 'linked' mode to map from cardNode all the way to cardValueProperty (at least automatically), see https://github.com/phetsims/tandem/issues/300
     */
    getPhetioMouseHitTarget(fromLinking?: boolean): PhetioObject | 'phetioNotSelectable';
    /**
     * Determine if this instance should be selectable
     */
    protected getPhetioMouseHitTargetSelf(): PhetioObject | 'phetioNotSelectable';
    /**
     * Factored out function returning if this instance is phetio selectable
     */
    private isPhetioMouseHitSelectable;
    /**
     * This function determines not only if this PhetioObject is phetioFeatured, but if any descendant of this
     * PhetioObject is phetioFeatured, this will influence if this instance is displayed while showing phetioFeatured,
     * since featured children will cause the parent to be displayed as well.
     */
    private isDisplayedInFeaturedTree;
    /**
     * Acquire the linkedElement that most closely relates to this PhetioObject, given some heuristics. First, if there is
     * only a single LinkedElement child, use that. Otherwise, select hard coded names that are likely to be most important.
     */
    getCorrespondingLinkedElement(): PhetioObject | 'noCorrespondingLinkedElement';
    /**
     * Remove this phetioObject from PhET-iO. After disposal, this object is no longer interoperable. Also release any
     * other references created during its lifetime.
     *
     * In order to support the structured data stream, PhetioObjects must end the messages in the correct
     * sequence, without being interrupted by dispose() calls.  Therefore, we do not clear out any of the state
     * related to the endEvent.  Note this means it is acceptable (and expected) for endEvent() to be called on
     * disposed PhetioObjects.
     */
    dispose(): void;
    /**
     * JSONifiable metadata that describes the nature of the PhetioObject.  We must be able to read this
     * for baseline (before object fully constructed we use object) and after fully constructed
     * which includes overrides.
     * @param [object] - used to get metadata keys, can be a PhetioObject, or an options object
     *                          (see usage initializePhetioObject). If not provided, will instead use the value of "this"
     * @returns - metadata plucked from the passed in parameter
     */
    getMetadata(object?: PhetioObjectMetadataInput): PhetioElementMetadata;
    static readonly METADATA_DOCUMENTATION: string;
    static create(options?: PhetioObjectOptions): PhetioObject;
}
type LinkedElementOptions = ({
    tandemName?: string;
    tandem?: never;
} | {
    tandemName?: never;
    tandem?: Tandem;
});
/**
 * Internal class to avoid cyclic dependencies.
 */
declare class LinkedElement extends PhetioObject {
    readonly element: PhetioObject;
    constructor(coreElement: PhetioObject, providedOptions?: LinkedElementOptions);
}
export { PhetioObject as default, LinkedElement };
//# sourceMappingURL=PhetioObject.d.ts.map