/*
 * Microsoft Application Insights Core Javascript SDK, 3.3.11
 * Copyright (c) Microsoft and contributors. All rights reserved.
 *
 * Microsoft Application Insights Team
 * https://github.com/microsoft/ApplicationInsights-JS#readme
 */

declare namespace ApplicationInsights {
    /**
     * Get all of the registered events on the target object, this is primarily used for testing cleanup but may also be used by
     * applications to remove their own events
     * @param target - The EventTarget that has registered events
     * @param eventName - [Optional] The name of the event to return the registered handlers and full name (with namespaces)
     * @param evtNamespace - [Optional] Additional namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace,
     * if the eventName also includes a namespace the namespace(s) are merged into a single namespace
     */
    function __getRegisteredEvents(target: any, eventName?: string, evtNamespace?: string | string[]): _IRegisteredEvents[];

    const ActiveStatus: EnumValue<typeof eActiveStatus>;

    type ActiveStatus = number | eActiveStatus;

    /**
     * Trys to add an event handler for the specified event to the window, body and document
     * @param eventName  - The name of the event
     * @param callback  - The callback function that needs to be executed for the given event
     * @param evtNamespace - [Optional] Namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace.
     * @returns - true if the handler was successfully added
     */
    function addEventHandler(eventName: string, callback: any, evtNamespace?: string | string[] | null): boolean;

    /**
     * Bind the listener to the array of events
     * @param events - An string array of event names to bind the listener to
     * @param listener - The event callback to call when the event is triggered
     * @param excludeEvents - [Optional] An array of events that should not be hooked (if possible), unless no other events can be.
     * @param evtNamespace - [Optional] Namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace.
     * @returns true - when at least one of the events was registered otherwise false
     */
    function addEventListeners(events: string[], listener: any, excludeEvents?: string[], evtNamespace?: string | string[]): boolean;

    /**
     * Listen to the pagehide and visibility changing to 'hidden' events, because the 'visibilitychange' uses
     * an internal proxy to detect the visibility state you SHOULD use a unique namespace when if you plan to call
     * removePageShowEventListener as the remove ignores the listener argument for the 'visibilitychange' event.
     * @param listener - The event callback to call when a page hide event is triggered
     * @param excludeEvents - [Optional] An array of events that should not be hooked (if possible), unless no other events can be.
     * @param evtNamespace - [Optional] A Namespace to append to the event listeners so they can be uniquely identified and removed
     * based on this namespace. This call also adds an additional unique "pageshow" namespace to the events
     * so that only the matching "removePageHideEventListener" can remove these events.
     * Suggestion: pass as true if you are also calling addPageUnloadEventListener as that also hooks pagehide
     * @returns true - when at least one of the events was registered otherwise false
     */
    function addPageHideEventListener(listener: any, excludeEvents?: string[] | null, evtNamespace?: string | string[] | null): boolean;

    /**
     * Listen to the pageshow and visibility changing to 'visible' events, because the 'visibilitychange' uses
     * an internal proxy to detect the visibility state you SHOULD use a unique namespace when if you plan to call
     * removePageShowEventListener as the remove ignores the listener argument for the 'visibilitychange' event.
     * @param listener - The event callback to call when a page is show event is triggered
     * @param excludeEvents - [Optional] An array of events that should not be hooked (if possible), unless no other events can be.
     * @param evtNamespace - [Optional/Recommended] A Namespace to append to the event listeners so they can be uniquely
     * identified and removed based on this namespace. This call also adds an additional unique "pageshow" namespace to the events
     * so that only the matching "removePageShowEventListener" can remove these events.
     * @returns true - when at least one of the events was registered otherwise false
     */
    function addPageShowEventListener(listener: any, excludeEvents?: string[] | null, evtNamespace?: string | string[] | null): boolean;

    /**
     * Listen to the 'beforeunload', 'unload' and 'pagehide' events which indicates a page unload is occurring,
     * this does NOT listen to the 'visibilitychange' event as while it does indicate that the page is being hidden
     * it does not *necessarily* mean that the page is being completely unloaded, it can mean that the user is
     * just navigating to a different Tab and may come back (without unloading the page). As such you may also
     * need to listen to the 'addPageHideEventListener' and 'addPageShowEventListener' events.
     * @param listener - The event callback to call when a page unload event is triggered
     * @param excludeEvents - [Optional] An array of events that should not be hooked, unless no other events can be.
     * @param evtNamespace - [Optional] Namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace.
     * @returns true - when at least one of the events was registered otherwise false
     */
    function addPageUnloadEventListener(listener: any, excludeEvents?: string[], evtNamespace?: string | string[]): boolean;

    /**
     * append the XHR headers.
     * @internal
     */
    function _appendHeader(theHeaders: any, xhr: XMLHttpRequest, name: string): any;

    /**
     * @group Classes
     * @group Entrypoint
     */
    class AppInsightsCore<CfgType extends IConfiguration = IConfiguration> implements IAppInsightsCore<CfgType> {
        config: CfgType;
        logger: IDiagnosticLogger;
        /**
         * An array of the installed plugins that provide a version
         */
        readonly pluginVersionStringArr: string[];
        /**
         * The formatted string of the installed plugins that contain a version number
         */
        readonly pluginVersionString: string;
        /**
         * Returns a value that indicates whether the instance has already been previously initialized.
         */
        isInitialized: () => boolean;
        /**
         * Function used to identify the get w parameter used to identify status bit to some channels
         */
        getWParam: () => number;
        constructor();
        initialize(config: CfgType, extensions: IPlugin[], logger?: IDiagnosticLogger, notificationManager?: INotificationManager): void;
        getChannels(): IChannelControls[];
        track(telemetryItem: ITelemetryItem): void;
        getProcessTelContext(): IProcessTelemetryContext;
        getNotifyMgr(): INotificationManager;
        /**
         * Adds a notification listener. The SDK calls methods on the listener when an appropriate notification is raised.
         * The added plugins must raise notifications. If the plugins do not implement the notifications, then no methods will be
         * called.
         * @param listener - An INotificationListener object.
         */
        addNotificationListener(listener: INotificationListener): void;
        /**
         * Removes all instances of the listener.
         * @param listener - INotificationListener to remove.
         */
        removeNotificationListener(listener: INotificationListener): void;
        /**
         * Get the current cookie manager for this instance
         */
        getCookieMgr(): ICookieMgr;
        /**
         * Set the current cookie manager for this instance
         * @param cookieMgr - The manager, if set to null/undefined will cause the default to be created
         */
        setCookieMgr(cookieMgr: ICookieMgr): void;
        getPerfMgr(): IPerfManager;
        setPerfMgr(perfMgr: IPerfManager): void;
        eventCnt(): number;
        /**
         * Enable the timer that checks the logger.queue for log messages to be flushed.
         * Note: Since 3.0.1 and 2.8.13 this is no longer an interval timer but is a normal
         * timer that is only started when this function is called and then subsequently
         * only _if_ there are any logger.queue messages to be sent.
         */
        pollInternalLogs(eventName?: string): ITimerHandler;
        /**
         * Stop the timer that log messages from logger.queue when available
         */
        stopPollingInternalLogs(): void;
        /**
         * Add a telemetry processor to decorate or drop telemetry events.
         * @param telemetryInitializer - The Telemetry Initializer function
         * @returns - A ITelemetryInitializerHandler to enable the initializer to be removed
         */
        addTelemetryInitializer(telemetryInitializer: TelemetryInitializerFunction): ITelemetryInitializerHandler;
        /**
         * Unload and Tear down the SDK and any initialized plugins, after calling this the SDK will be considered
         * to be un-initialized and non-operational, re-initializing the SDK should only be attempted if the previous
         * unload call return `true` stating that all plugins reported that they also unloaded, the recommended
         * approach is to create a new instance and initialize that instance.
         * This is due to possible unexpected side effects caused by plugins not supporting unload / teardown, unable
         * to successfully remove any global references or they may just be completing the unload process asynchronously.
         * If you pass isAsync as `true` (also the default) and DO NOT pass a callback function then an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * will be returned which will resolve once the unload is complete. The actual implementation of the `IPromise`
         * will be a native Promise (if supported) or the default as supplied by [ts-async library](https://github.com/nevware21/ts-async)
         * @param isAsync - Can the unload be performed asynchronously (default)
         * @param unloadComplete - An optional callback that will be called once the unload has completed
         * @param cbTimeout - An optional timeout to wait for any flush operations to complete before proceeding with the
         * unload. Defaults to 5 seconds.
         * @returns Nothing or if occurring asynchronously a [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * which will be resolved once the unload is complete, the [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * will only be returned when no callback is provided and isAsync is true
         */
        unload(isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void | IPromise<ITelemetryUnloadState>;
        getPlugin<T extends IPlugin = IPlugin>(pluginIdentifier: string): ILoadedPlugin<T>;
        /**
         * Add a new plugin to the installation
         * @param plugin - The new plugin to add
         * @param replaceExisting - should any existing plugin be replaced, default is false
         * @param doAsync - Should the add be performed asynchronously
         * @param addCb - [Optional] callback to call after the plugin has been added
         */
        addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting?: boolean, doAsync?: boolean, addCb?: (added?: boolean) => void): void;
        /**
         * Update the configuration used and broadcast the changes to all loaded plugins
         * @param newConfig - The new configuration is apply
         * @param mergeExisting - Should the new configuration merge with the existing or just replace it. Default is to true.
         */
        updateCfg(newConfig: CfgType, mergeExisting?: boolean): void;
        /**
         * Returns the unique event namespace that should be used
         */
        evtNamespace(): string;
        /**
         * Add an unload handler that will be called when the SDK is being unloaded
         * @param handler - the handler
         */
        addUnloadCb(handler: UnloadHandler): void;
        /**
         * Flush and send any batched / cached data immediately
         * @param async - send data asynchronously when true (defaults to true)
         * @param callBack - if specified, notify caller when send is complete, the channel should return true to indicate to the caller that it will be called.
         * If the caller doesn't return true the caller should assume that it may never be called.
         * @param sendReason - specify the reason that you are calling "flush" defaults to ManualFlush (1) if not specified
         * @returns - true if the callback will be return after the flush is complete otherwise the caller should assume that any provided callback will never be called
         */
        flush(isAsync?: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason): void;
        /**
         * Gets the current distributed trace context for this instance if available
         * @param createNew - Optional flag to create a new instance if one doesn't currently exist, defaults to true
         */
        getTraceCtx(createNew?: boolean): IDistributedTraceContext | null;
        /**
         * Sets the current distributed trace context for this instance if available
         */
        setTraceCtx(newTracectx: IDistributedTraceContext): void;
        /**
         * Add this hook so that it is automatically removed during unloading
         * @param hooks - The single hook or an array of IInstrumentHook objects
         */
        addUnloadHook(hooks: IUnloadHook | IUnloadHook[] | Iterator<IUnloadHook> | ILegacyUnloadHook | ILegacyUnloadHook[] | Iterator<ILegacyUnloadHook>): void;
        /**
         * Watches and tracks changes for accesses to the current config, and if the accessed config changes the
         * handler will be recalled.
         * @param handler - The watcher handler to call when the config changes
         * @returns A watcher handler instance that can be used to remove itself when being unloaded
         */
        onCfgChange(handler: WatcherFunction<CfgType>): IUnloadHook;
        /**
         * Watches and tracks status of initialization process
         * @returns ActiveStatus
         * @since 3.3.0
         * If returned status is active, it means initialization process is completed.
         * If returned status is pending, it means the initialization process is waiting for promieses to be resolved.
         * If returned status is inactive, it means ikey is invalid or can 't get ikey or enpoint url from promsises.
         */
        activeStatus(): eActiveStatus | number;
        /**
         * Set Active Status to pending, which will block the incoming changes until internal promises are resolved
         * @internal Internal use
         * @since 3.3.0
         */
        _setPendingStatus(): void;
        protected releaseQueue(): void;
        /**
         * Hook for Core extensions to allow them to update their own configuration before updating all of the plugins.
         * @param updateCtx - The plugin update context
         * @param updateState - The Update State
         * @returns boolean - True means the extension class will call updateState otherwise the Core will
         */
        protected _updateHook?(updateCtx: IProcessTelemetryUpdateContext, updateState: ITelemetryUpdateState): void | boolean;
    }

    function areCookiesSupported(logger?: IDiagnosticLogger): any;

    /**
     * Calls the provided `callbackFn` function once for each element in an array in ascending index order. It is not invoked for index properties
     * that have been deleted or are uninitialized. And unlike the ES6 forEach() you CAN stop or break the iteration by returning -1 from the
     * `callbackFn` function.
     *
     * The range (number of elements) processed by arrForEach() is set before the first call to the `callbackFn`. Any elements added beyond the range
     * or elements which as assigned to indexes already processed will not be visited by the `callbackFn`.
     * @group Array
     * @group ArrayLike
     * @typeParam T - Identifies the element type of the array
     * @param theArray - The array or array like object of elements to be searched.
     * @param callbackfn - A `synchronous` function that accepts up to three arguments. arrForEach calls the callbackfn function one time for each element in the array.
     * @param thisArg - An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, null or undefined
     * the array will be used as the this value.
     * @remarks
     * arrForEach expects a `synchronous` function.
     * arrForEach does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callback.
     * @example
     * ```ts
     * const items = ['item1', 'item2', 'item3'];
     * const copyItems = [];
     *
     * // before using for loop
     * for (let i = 0; i < items.length; i++) {
     *   copyItems.push(items[i]);
     * }
     *
     * // before using forEach()
     * items.forEach((item) => {
     *   copyItems.push(item);
     * });
     *
     * // after
     * arrForEach(items, (item) => {
     *   copyItems.push(item);
     *   // May return -1 to abort the iteration
     * });
     *
     * // Also supports input as an array like object
     * const items = { length: 3, 0: 'item1', 1: 'item2', 2: 'item3' };
     * ```
     */
    function arrForEach<T = any>(theArray: ArrayLike<T>, callbackfn: (value: T, index: number, array: T[]) => void | number, thisArg?: any): void;

    /**
     * The arrIndexOf() method returns the first index at which a given element can be found in the array,
     * or -1 if it is not present.
     * `arrIndexOf()` compares searchElement to elements of the Array using strict equality (the same
     * method used by the === or triple-equals operator).
     * @function
     * @group Array
     * @group ArrayLike
     * @typeParam T - Identifies the type of array elements
     * @param theArray - The array or array like object of elements to be searched.
     * @param searchElement - The element to locate in the array.
     * @param fromIndex - The index to start the search at. If the index is greater than or equal to
     * the array's length, -1 is returned, which means the array will not be searched. If the provided
     * index value is a negative number, it is taken as the offset from the end of the array.
     * Note: if the provided index is negative, the array is still searched from front to back. If the
     * provided index is 0, then the whole array will be searched. Default: 0 (entire array is searched).
     * @return The first index of the element in the array; -1 if not found.
     * @example
     * ```ts
     * const array = [2, 9, 9];
     * arrIndexOf(array, 2);     // 0
     * arrIndexOf(array, 7);     // -1
     * arrIndexOf(array, 9, 2);  // 2
     * arrIndexOf(array, 2, -1); // -1
     * arrIndexOf(array, 2, -3); // 0
     *
     * let indices: number[] = [];
     * const array = ['a', 'b', 'a', 'c', 'a', 'd'];
     * const element = 'a';
     * let idx = arrIndexOf(array, element);
     * while (idx !== -1) {
     *   indices.push(idx);
     *   idx = arrIndexOf(array, element, idx + 1);
     * }
     * console.log(indices);
     * // [0, 2, 4]
     *
     * function updateVegetablesCollection (veggies, veggie) {
     *     if (arrIndexOf(veggies, veggie) === -1) {
     *         veggies.push(veggie);
     *         console.log('New veggies collection is : ' + veggies);
     *     } else {
     *         console.log(veggie + ' already exists in the veggies collection.');
     *     }
     * }
     *
     * let veggies = ['potato', 'tomato', 'chillies', 'green-pepper'];
     *
     * updateVegetablesCollection(veggies, 'spinach');
     * // New veggies collection is : potato,tomato,chillies,green-pepper,spinach
     * updateVegetablesCollection(veggies, 'spinach');
     * // spinach already exists in the veggies collection.
     *
     * // Array Like
     * let arrayLike = {
     *   length: 3,
     *   0: "potato",
     *   1: "tomato",
     *   2: "chillies",
     *   3: "green-pepper"  // Not checked as index is > length
     * };
     *
     * arrIndexOf(arrayLike, "potato"); // 0
     * arrIndexOf(arrayLike, "tomato"); // 1
     * arrIndexOf(arrayLike, "chillies"); 2
     * arrIndexOf(arrayLike, "green-pepper"); // -1
     * ```
     */
    const arrIndexOf: <T>(theArray: ArrayLike<T>, searchElement: T, fromIndex?: number) => number;

    /**
     * The arrMap() method creates a new array populated with the results of calling a provided function on every
     * element in the calling array.
     *
     * `arrMap` calls a provided callbackFn function once for each element in an array, in order, and constructs
     * a new array from the results. callbackFn is invoked only for indexes of the array which have assigned
     * values (including undefined).
     *
     * It is not called for missing elements of the array; that is:
     * - indexes that have never been set;
     * - indexes which have been deleted.
     *
     * @function
     * @since 0.3.3
     * @group Array
     * @group ArrayLike
     * @typeParam T - Identifies the type of the array elements
     * @typeParam R - Identifies the type of the elements returned by the callback function, defaults to T.
     * @param theArray - The array or array like object of elements to be searched.
     * @param callbackFn - The function that is called for evetn element of `theArray`.
     * @param thisArg - The value to use as the `this` when executing the `callbackFn`.
     * @example
     * ```ts
     * const numbers = [1, 4, 9];
     * const roots = arrMap(numbers, (num) => Math.sqrt(num));
     *
     * // roots is now     [1, 2, 3]
     * // numbers is still [1, 4, 9]
     *
     * const kvArray = [{ key: 1, value: 10 },
     *                  { key: 2, value: 20 },
     *                  { key: 3, value: 30 }];
     *
     * const reformattedArray = arrMap(kvArray, ({ key, value}) => ({ [key]: value }));
     *
     * // reformattedArray is now [{1: 10}, {2: 20}, {3: 30}],
     *
     * // kvArray is still:
     * // [{key: 1, value: 10},
     * //  {key: 2, value: 20},
     * //  {key: 3, value: 30}]
     *
     * // Also supports Array Like objects with same output
     * const kvArray = {
     *   length: 3,
     *   0: { key: 1, value: 10 },
     *   1: { key: 2, value: 20 },
     *   2: { key: 3, value: 30 }
     * };
     * ```
     */
    const arrMap: <T, R = T>(theArray: ArrayLike<T>, callbackFn: ArrMapCallbackFn<T, R>, thisArg?: any) => R[];

    /**
     * Callback signature for {@link arrMap} that is called for every element of array. Each time callbackFn
     * executes, the returned value is added to newArray.
     *
     * @since 0.3.3
     * @group Array
     * @group ArrayLike
     * @typeParam T - Identifies the type of the array elements
     * @typeParam R - Identifies the type of the elements returned by the callback function, defaults to T.
     * @param value - The current element being processed in the array.
     * @param index - The index of the current element being processed in the array.
     * @param array - The array that the `map` function was called on.
     */
    type ArrMapCallbackFn<T, R = T> = (value: T, index?: number, array?: T[]) => R;

    /**
     * The arrReduce() method executes a user-supplied "reducer" callback function on each element of the array,
     * in order, passing in the return value from the calculation on the preceding element. The final result of
     * running the reducer across all elements of the array is a single value.
     *
     * The first time that the callback is run there is no "return value of the previous calculation". If supplied,
     * an initial value may be used in its place. Otherwise the array element at index 0 is used as the initial
     * value and iteration starts from the next element (index 1 instead of index 0).
     * @function
     * @group Array
     * @group ArrayLike
     * @typeParam T - Identifies the type of array elements
     * @param theArray - The array or array like object of elements to be searched.
     * @param callbackfn - A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
     * @param initialValue - If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
     * @returns The value that results from running the "reducer" callback function to completion over the entire array.
     * @example
     * ```ts
     * const getMax = (a: number, b: number) => Math.max(a, b);
     *
     * // callback is invoked for each element in the array starting at index 0
     * arrReduce([1, 100], getMax, 50); // 100
     * arrReduce([    50], getMax, 10); // 50
     *
     * // callback is invoked once for element at index 1
     * arrReduce([1, 100], getMax);     // 100
     *
     * // callback is not invoked
     * arrReduce([    50], getMax);     // 50
     * arrReduce([      ], getMax, 1);  // 1
     *
     * arrReduce([      ], getMax);     // throws TypeError
     *
     * // Also supports Array like objects
     * arrReduce({ length: 2, 0: 1, 1: 100 }, getMax, 50); // 100
     * arrReduce({ length: 1, 0: 50 }, getMax, 10); // 50
     *
     * // callback is invoked once for element at index 1
     * arrReduce({ length: 2, 0: 1, 1: 100 }, getMax);     // 100
     *
     * // callback is not invoked
     * arrReduce({ length: 1, 0: 50 }, getMax);     // 50
     * arrReduce({ length: 0 }, getMax, 1);  // 1
     * ```
     */
    const arrReduce: <T, R = T>(theArray: ArrayLike<T>, callbackfn: ArrReduceCallbackFn<T, R>, initialValue?: T | R) => R;

    /**
     * The `reducer` function called for {@link arrReduce}.
     * @group Array
     * @group ArrayLike
     * @typeParam T - Identifies the type of array elements
     * @typeParam R - Identifies the type of the return array elements (defaults to T)
     * @param previousValue - The value resulting from the previous call to callbackFn. On first call, initialValue if
     * specified, otherwise the value of array[0].
     * @param currentValue - The value of the current element. On first call, the value of array[0] if an initialValue
     * was specified, otherwise the value of array[1].
     * @param currentIndex - The index position of currentValue in the array. On first call, 0 if initialValue was
     * specified, otherwise 1.
     * @param array -The array being traversed.
     */
    type ArrReduceCallbackFn<T, R = T> = (previousValue: T | R, currentValue: T, currentIndex: number, array: T[]) => R;

    /**
     * The asString() method returns a string representing the value by
     * explicitly using `String(`value`)`.
     *
     * @function
     * @since 0.4.3
     * @group String
     * @group Conversion
     * @group Value
     * @param value - The value to get a string representation of
     * @example
     * ```ts
     * const arr = [ 1, 2, 3];
     * asString(arr);       // "1,2,3"
     * asString(null);      // "null"
     * asString(undefined); // "undefined"
     * asString(42);        // "42"
     * asString(Symbol.for("Hello"));   // "Symbol(Hello)"
     * ```
     */
    const asString: (value: any) => string;

    /**
     * Binds the specified function to an event, so that the function gets called whenever the event fires on the object
     * @param obj - Object to add the event too.
     * @param eventNameWithoutOn - String that specifies any of the standard DHTML Events without "on" prefix and optional (dot "." prefixed) namespaces "click" "click.mynamespace".
     * @param handlerRef - Pointer that specifies the function to call when event fires
     * @param useCapture - [Optional] Defaults to false
     * @returns True if the function was bound successfully to the event, otherwise false
     */
    function attachEvent(obj: any, eventNameWithoutOn: string, handlerRef: any, useCapture?: boolean): boolean;

    /**
     * BaseTelemetryPlugin provides a basic implementation of the ITelemetryPlugin interface so that plugins
     * can avoid implementation the same set of boiler plate code as well as provide a base
     * implementation so that new default implementations can be added without breaking all plugins.
     */
    abstract class BaseTelemetryPlugin implements ITelemetryPlugin {
        identifier: string;
        version?: string;
        /**
         * Holds the core instance that was used during initialization
         */
        core: IAppInsightsCore;
        priority: number;
        /**
         * Call back for telemetry processing before it it is sent
         * @param env - This is the current event being reported
         * @param itemCtx - This is the context for the current request, ITelemetryPlugin instances
         * can optionally use this to access the current core instance or define / pass additional information
         * to later plugins (vs appending items to the telemetry item)
         */
        processNext: (env: ITelemetryItem, itemCtx: IProcessTelemetryContext) => void;
        /**
         * Set next extension for telemetry processing, this is now optional as plugins should use the
         * processNext() function of the passed IProcessTelemetryContext instead. It is being kept for
         * now for backward compatibility only.
         * @deprecated - Use processNext() function of the passed IProcessTelemetryContext instead
         */
        setNextPlugin?: (next: ITelemetryPlugin | ITelemetryPluginChain) => void;
        /**
         * Returns the current diagnostic logger that can be used to log issues, if no logger is currently
         * assigned a new default one will be created and returned.
         */
        diagLog: (itemCtx?: IProcessTelemetryContext) => IDiagnosticLogger;
        /**
         * Returns whether the plugin has been initialized
         */
        isInitialized: () => boolean;
        /**
         * Helper to return the current IProcessTelemetryContext, if the passed argument exists this just
         * returns that value (helps with minification for callers), otherwise it will return the configured
         * context or a temporary one.
         * @param currentCtx - [Optional] The current execution context
         */
        protected _getTelCtx: (currentCtx?: IProcessTelemetryContext) => IProcessTelemetryContext;
        /**
         * Internal helper to allow setting of the internal initialized setting for inherited instances and unit testing
         */
        protected setInitialized: (isInitialized: boolean) => void;
        /**
         * Teardown / Unload hook to allow implementations to perform some additional unload operations before the BaseTelemetryPlugin
         * finishes it's removal.
         * @param unloadCtx - This is the context that should be used during unloading.
         * @param unloadState - The details / state of the unload process, it holds details like whether it should be unloaded synchronously or asynchronously and the reason for the unload.
         * @param asyncCallback - An optional callback that the plugin must call if it returns true to inform the caller that it has completed any async unload/teardown operations.
         * @returns boolean - true if the plugin has or will call asyncCallback, this allows the plugin to perform any asynchronous operations.
         */
        protected _doTeardown?: (unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState, asyncCallback?: () => void) => void | boolean;
        /**
         * Extension hook to allow implementations to perform some additional update operations before the BaseTelemetryPlugin finishes it's removal
         * @param updateCtx - This is the context that should be used during updating.
         * @param updateState - The details / state of the update process, it holds details like the current and previous configuration.
         * @param asyncCallback - An optional callback that the plugin must call if it returns true to inform the caller that it has completed any async update operations.
         * @returns boolean - true if the plugin has or will call asyncCallback, this allows the plugin to perform any asynchronous operations.
         */
        protected _doUpdate?: (updateCtx?: IProcessTelemetryUpdateContext, updateState?: ITelemetryUpdateState, asyncCallback?: () => void) => void | boolean;
        /**
         * Exposes the underlying unload hook container instance for this extension to allow it to be passed down to any sub components of the class.
         * This should NEVER be exposed or called publically as it's scope is for internal use by BaseTelemetryPlugin and any derived class (which is why
         * it's scoped as protected)
         */
        protected readonly _unloadHooks: IUnloadHookContainer;
        constructor();
        initialize(config: IConfiguration, core: IAppInsightsCore, extensions: IPlugin[], pluginChain?: ITelemetryPluginChain): void;
        /**
         * Tear down the plugin and remove any hooked value, the plugin should be removed so that it is no longer initialized and
         * therefore could be re-initialized after being torn down. The plugin should ensure that once this has been called any further
         * processTelemetry calls are ignored and it just calls the processNext() with the provided context.
         * @param unloadCtx - This is the context that should be used during unloading.
         * @param unloadState - The details / state of the unload process, it holds details like whether it should be unloaded synchronously or asynchronously and the reason for the unload.
         * @returns boolean - true if the plugin has or will call processNext(), this for backward compatibility as previously teardown was synchronous and returned nothing.
         */
        teardown(unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState): void | boolean;
        abstract processTelemetry(env: ITelemetryItem, itemCtx?: IProcessTelemetryContext): void;
        /**
         * The the plugin should re-evaluate configuration and update any cached configuration settings.
         * @param updateCtx - This is the context that should be used during updating.
         * @param updateState - The details / state of the update process, it holds details like the current and previous configuration.
         * @returns boolean - true if the plugin has or will call updateCtx.processNext(), this allows the plugin to perform any asynchronous operations.
         */
        update(updateCtx: IProcessTelemetryUpdateContext, updateState: ITelemetryUpdateState): void | boolean;
        /**
         * Add an unload handler that will be called when the SDK is being unloaded
         * @param handler - the handler
         */
        protected _addUnloadCb(handler: UnloadHandler): void;
        /**
         * Add this hook so that it is automatically removed during unloading
         * @param hooks - The single hook or an array of IInstrumentHook objects
         */
        protected _addHook(hooks: IUnloadHook | IUnloadHook[] | Iterator<IUnloadHook> | ILegacyUnloadHook | ILegacyUnloadHook[] | Iterator<ILegacyUnloadHook>): void;
    }

    /**
     *  The eBatchDiscardedReason enumeration contains a set of values that specify the reason for discarding offline batches.
     */
    const BatchDiscardedReason: EnumValue<typeof eBatchDiscardedReason>;

    type BatchDiscardedReason = number | eBatchDiscardedReason;

    /**
     * Mark the provided value so that if it's included into the configuration it will NOT have
     * its properties converted into a dynamic (reactive) object. If the object is not a plain object
     * or an array (ie. a class) this function has not affect as only Objects and Arrays are converted
     * into dynamic objects in the dynamic configuration.
     *
     * When you have tagged a value as both {@link forceDynamicConversion} and blocked force will take precedence.
     *
     * You should only need to use this function, if you are creating dynamic "classes" from objects
     * which confirm to the require interface. A common case for this is during unit testing where it's
     * easier to create mock extensions.
     *
     * If `value` is falsy (null / undefined / 0 / empty string etc) it will not be tagged and
     * if there is an exception adding the property to the value (because its frozen etc) the
     * exception will be swallowed
     *
     * @example
     * ```ts
     * // This is a valid "extension", but it is technically an object
     * // So when included in the config.extensions it WILL be cloned and then
     * // converted into a dynamic object, where all of its properties will become
     * // get/set object properties and will be tracked. While this WILL still
     * // function, when attempt to use a mocking framework on top of this the
     * // functions are now technically get accessors which return a function
     * // and this can cause some mocking frameworks to fail.
     * let mockChannel = {
     *      pause: () => { },
     *      resume: () => { },
     *      teardown: () => { },
     *      flush: (async: any, callBack: any) => { },
     *      processTelemetry: (env: any) => { },
     *      setNextPlugin: (next: any) => { },
     *      initialize: (config: any, core: any, extensions: any) => { },
     *      identifier: "testChannel",
     *      priority: 1003
     * };
     * ```
     * @param value - The object that you want to block from being converted into a
     * trackable dynamic object
     * @returns The original value
     */
    function blockDynamicConversion<T>(value: T): T;

    const enum CdnFeatureMode {
        /**
         * not set, user defined/config defaults value will be used
         */
        none = 1,
        /**
         * config from cdn will Not be applied
         */
        disable = 2,
        /**
         * try to apply config from cdn
         */
        enable = 3,
        /**
         * force enable
         */
        forceOn = 4,
        /**
         * force disable
         */
        forceOff = 5
    }

    /**
     * Helper which returns an IConfigDefaultCheck instance identifying that value associated with this property
     * should not have it's properties converted into a dynamic config properties.
     * @param defaultValue - The default value to apply it not provided or it's not valid
     * @returns a new IConfigDefaultCheck structure
     */
    function cfgDfBlockPropValue<V, T = IConfiguration, C = IConfiguration>(defaultValue: V | IConfigDefaults<V, T>): IConfigDefaultCheck<T, V, C>;

    /**
     * Helper which returns an IConfigDefaultCheck instance that will validate and convert the user
     * provided value to a boolean from a string or boolean value
     * @param defaultValue - The default value to apply it not provided or it's not valid
     * @param fallBackName - The fallback configuration name if the current value is not available
     * @returns a new IConfigDefaultCheck structure
     */
    function cfgDfBoolean<T, C = IConfiguration>(defaultValue?: boolean, fallBackName?: keyof T | keyof C | Array<keyof T | keyof C>): IConfigDefaultCheck<T, boolean, C>;

    /**
     * Helper which returns an IConfigDefaultCheck instance that will validate that the user
     * provided value is a function.
     * @param defaultValue - The default value to apply it not provided or it's not valid
     * @returns a new IConfigDefaultCheck structure
     */
    function cfgDfFunc<V, T, C = IConfiguration>(defaultValue?: V): IConfigDefaultCheck<T, V, C>;

    /**
     * Helper which returns an IConfigDefaultCheck instance with the field defined as an object
     * that should be merged
     * @param defaultValue - The default value to apply it not provided or it's not valid
     * @returns a new IConfigDefaultCheck structure
     */
    function cfgDfMerge<V, T = IConfiguration, C = IConfiguration>(defaultValue: V | IConfigDefaults<V, T>): IConfigDefaultCheck<T, V, C>;

    /**
     * Helper which returns an IConfigDefaultCheck instance with the provided field set function
     * @param setter - The IConfigCheckFn function to validate the user provided value
     * @param defaultValue - The default value to apply it not provided or it's not valid
     * @returns a new IConfigDefaultCheck structure
     */
    function cfgDfSet<V, T, C = IConfiguration>(setter: IConfigSetFn<T, V>, defaultValue: V): IConfigDefaultCheck<T, V, C>;

    /**
     * Helper which returns an IConfigDefaultCheck instance that will validate that the user
     * provided value is a function.
     * @param defaultValue - The default string value to apply it not provided or it's not valid, defaults to an empty string
     * @returns a new IConfigDefaultCheck structure
     */
    function cfgDfString<T, C = IConfiguration>(defaultValue?: string): IConfigDefaultCheck<T, string, C>;

    /**
     * Helper which returns an IConfigDefaultCheck instance with the provided field validator
     * @param validator - The IConfigCheckFn function to validate the user provided value
     * @param defaultValue - The default value to apply it not provided or it's not valid
     * @param fallBackName - The fallback configuration name if the current value is not available
     * @returns a new IConfigDefaultCheck structure
     */
    function cfgDfValidate<V, T, C = IConfiguration>(validator: IConfigCheckFn<V>, defaultValue: V, fallBackName?: keyof T | keyof C | Array<keyof T | keyof C>): IConfigDefaultCheck<T, V, C>;

    /**
     * Converts the XHR getAllResponseHeaders to a map containing the header key and value.
     * @internal
     */
    function convertAllHeadersToMap(headersString: string): {
        [headerName: string]: string;
    };

    /**
     * Simpler helper to create a dynamic class that implements the interface and populates the values with the defaults.
     * Only instance properties (hasOwnProperty) values are copied from the defaults to the new instance
     * @param defaults - Simple helper
     */
    function createClassFromInterface<T>(defaults?: T): new () => T;

    function createCookieMgr(rootConfig?: IConfiguration, logger?: IDiagnosticLogger): ICookieMgr;

    function createCustomDomEvent(eventName: string, details?: any): CustomEvent;

    /**
     * Create or return a dynamic version of the passed config, if it is not already dynamic
     * @param config - The config to be converted into a dynamic config
     * @param defaultConfig - The default values to apply on the config if the properties don't already exist
     * @param inPlace - Should the config be converted in-place into a dynamic config or a new instance returned, defaults to true
     * @returns The dynamic config handler for the config (whether new or existing)
     */
    function createDynamicConfig<T = IConfiguration>(config: T, defaultConfig?: IConfigDefaults<T>, logger?: IDiagnosticLogger, inPlace?: boolean): IDynamicConfigHandler<T>;

    /**
     * Create an enum style object which has both the key \=\> value and value \=\> key mappings
     * @param values - The values to populate on the new object
     * @returns
     */
    const createEnumStyle: <E>(values: {
        [key in keyof E]: E[keyof E];
    }) => EnumValue<E>;

    /**
     * Creates a new Telemetry Item context with the current config, core and plugin execution chain
     * @param plugins - The plugin instances that will be executed
     * @param config - The current config
     * @param core - The current core instance
     * @param startAt - Identifies the next plugin to execute, if null there is no "next" plugin and if undefined it should assume the start of the chain
     */
    function createProcessTelemetryContext(telemetryChain: ITelemetryPluginChain | null, cfg: IConfiguration, core: IAppInsightsCore, startAt?: IPlugin): IProcessTelemetryContext;

    /**
     * Create a new ITraceParent instance using the provided values.
     * @param traceId - The traceId to use, when invalid a new random W3C id will be generated.
     * @param spanId - The parent/span id to use, a new random value will be generated if it is invalid.
     * @param flags - The traceFlags to use, defaults to zero (0) if not supplied or invalid
     * @param version - The version to used, defaults to version "01" if not supplied or invalid.
     * @returns
     */
    function createTraceParent(traceId?: string, spanId?: string, flags?: number, version?: string): ITraceParent;

    function createUniqueNamespace(name: string, includeVersion?: boolean): string;

    function createUnloadHandlerContainer(): IUnloadHandlerContainer;

    /**
     * Create a IUnloadHookContainer which can be used to remember unload hook functions to be executed during the component unloading
     * process.
     * @returns A new IUnloadHookContainer instance
     */
    function createUnloadHookContainer(): IUnloadHookContainer;

    /**
     * Create a 2 index map that maps an enum's key and value to the defined map value, X["key"] \=\> mapValue and X[0] \=\> mapValue.
     * Generic values
     * - E = the const enum type (typeof eRequestHeaders);
     * - V = Identifies the valid values for the keys, this should include both the enum numeric and string key of the type. The
     * resulting "Value" of each entry identifies the valid values withing the assignments.
     * @param values - The values to populate on the new object
     * @returns
     */
    const createValueMap: <E, V = E>(values: {
        [key in keyof E]: [E[keyof E], V[keyof V]];
    }) => V;

    /**
     * Return the number of milliseconds that have elapsed since January 1, 1970 00:00:00 UTC.
     *
     * To offer protection against timing attacks and fingerprinting, the precision of utcNow()
     * might get rounded depending on browser settings. In Firefox, the privacy.reduceTimerPrecision
     * preference is enabled by default and defaults to 20µs in Firefox 59; in 60 it will be 2ms.
     *
     * @since 0.4.4
     * @group Timer
     *
     * @returns A Number representing the milliseconds elapsed since the UNIX epoch.
     * @example
     * ```ts
     * let now = utcNow();
     * ```
     */
    function dateNow(): number;

    /**
     * Perform a deep freeze on the object and all of it's contained values / properties by recursively calling
     * `objFreeze()` on all enumerable properties of the object and on each property returned.
     * This implementation handles recursive objects (objects that reference themselves) by tracking visited objects.
     * @group Object
     * @param value - the object to be completly frozen.
     * @returns The originally passed in object.
     */
    function deepFreeze<T>(value: T): T;

    /**
     * Removes an event handler for the specified event
     * @param Object - to remove the event from
     * @param eventNameWithoutOn  - The name of the event, with optional namespaces or just the namespaces,
     * such as "click", "click.mynamespace" or ".mynamespace"
     * @param handlerRef - The callback function that needs to be removed from the given event, when using a
     * namespace (with or without a qualifying event) this may be null to remove all previously attached event handlers
     * otherwise this will only remove events with this specific handler.
     * @param useCapture - [Optional] Defaults to false
     */
    function detachEvent(obj: any, eventNameWithoutOn: string, handlerRef: any, useCapture?: boolean): void;

    class DiagnosticLogger implements IDiagnosticLogger {
        identifier: string;
        /**
         * The internal logging queue
         */
        queue: _InternalLogMessage[];
        constructor(config?: IConfiguration);
        /**
         * 0: OFF (default)
         * 1: CRITICAL
         * 2: \>= WARNING
         */
        consoleLoggingLevel(): number;
        /**
         * This method will throw exceptions in debug mode or attempt to log the error as a console warning.
         * @param severity  - The severity of the log message
         * @param message - The log message.
         */
        throwInternal(severity: LoggingSeverity, msgId: _InternalMessageId, msg: string, properties?: Object, isUserAct?: boolean): void;
        /**
         * This will write a debug message to the console if possible
         * @param message - The debug message
         */
        debugToConsole(message: string): void;
        /**
         * This will write a warning to the console if possible
         * @param message  - The warning message
         */
        warnToConsole(message: string): void;
        /**
         * This will write an error to the console if possible
         * @param message - The warning message
         */
        errorToConsole(message: string): void;
        /**
         * Resets the internal message count
         */
        resetInternalMessageCount(): void;
        /**
         * Logs a message to the internal queue.
         * @param severity - The severity of the log message
         * @param message - The message to log.
         */
        logInternalMessage(severity: LoggingSeverity, message: _InternalLogMessage): void;
        /**
         * Unload and remove any state that this IDiagnosticLogger may be holding, this is generally called when the
         * owning SDK is being unloaded.
         * @param isAsync - Can the unload be performed asynchronously (default)
         * @returns If the unload occurs synchronously then nothing should be returned, if happening asynchronously then
         * the function should return an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * / Promise to allow any listeners to wait for the operation to complete.
         */
        unload(isAsync?: boolean): void | IPromise<void>;
    }

    function dispatchEvent_2(target: EventTarget, evnt: Event | CustomEvent): boolean;
    const dispatchEvent: typeof dispatchEvent_2;

    /**
     * Helper function to wrap a function with a perf event
     * @param mgrSource - The Performance Manager or a Performance provider source (may be null)
     * @param getSource - The callback to create the source name for the event (if perf monitoring is enabled)
     * @param func - The function to call and measure
     * @param details - A function to return the payload details
     * @param isAsync - Is the event / function being call asynchronously or synchronously
     */
    function doPerf<T>(mgrSource: IPerfManagerProvider | IPerfManager, getSource: () => string, func: (perfEvt?: IPerfEvent) => T, details?: () => any, isAsync?: boolean): T;

    /**
     * Call the unload function on all targets handling any returned [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
     * / Promise before calling the next targets unload
     * @param targets - An array of the targets to unload
     * @param isAsync - The caller identifies whether it is expecting the operations to complete synchronously or asynchronously.  Even
     * if the caller is not waiting the operation may still be performed asynchronously depending on the component and the reverse is
     * also true.
     * @param done - Optional callback function to call once all of the unload functions have been called.
     */
    function doUnloadAll<T>(targets: Array<{
        unload?: (isAsync?: boolean) => T | IPromise<T>;
    }>, isAsync?: boolean, done?: () => void): void | IPromise<void>;

    /**
     * Returns string representation of an object suitable for diagnostics logging.
     * @group Error
     * @group Diagnostic
     * @param object - The object to be converted to a diagnostic string value
     * @param format - Identifies whether the JSON value should be formated
     * - `true` - Format with 4 spaces
     * - 'number' - The number of spaces to format with
     * - `false` (or not Truthy) - Do not format
     * @returns A string representation of the object suitable for diagnostics logging
     * @example
     * ```ts
     * let obj = { a: 1, b: "Hello", c: { d: 2, e: "Darkness" } };
     *
     * let objStr = dumpObj(obj);
     * // objStr === "[object Object]: { a: 1, b: "Hello", c: { d: 2, e: "Darkness" } }"
     *
     * let objStrFmt = dumpObj(obj, true);
     * // objStrFmt === "[object Object]: {\n    a: 1,\n    b: "Hello",\n    c: {\n        d: 2,\n        e: "Darkness"\n    }\n}"
     *
     * let objStrFmt2 = dumpObj(obj, 2);
     * // objStrFmt2 === "[object Object]: {\n  a: 1,\n  b: "Hello",\n  c: {\n    d: 2,\n    e: "Darkness"\n  }\n}"
     *
     * let objStrFmt3 = dumpObj(obj, 0);
     * // objStrFmt3 === "[object Object]: { a: 1, b: "Hello", c: { d: 2, e: "Darkness" } }"
     *
     * let objStrFmt4 = dumpObj(obj, false);
     * // objStrFmt4 === "[object Object]: { a: 1, b: "Hello", c: { d: 2, e: "Darkness" } }"
     *
     * let objStrFmt5 = dumpObj(obj, null);
     * // objStrFmt5 === "[object Object]: { a: 1, b: "Hello", c: { d: 2, e: "Darkness" } }"
     *
     * let objStrFmt6 = dumpObj(obj, undefined);
     * // objStrFmt6 === "[object Object]: { a: 1, b: "Hello", c: { d: 2, e: "Darkness" } }"
     *
     * let objStrFmt7 = dumpObj(obj, "");
     * // objStrFmt7 === "[object Object]: { a: 1, b: "Hello", c: { d: 2, e: "Darkness" } }"
     *
     * let err = new Error("Hello Darkness");
     * let errStr = dumpObj(err);
     * // errStr === "[object Error]: { stack: 'Error: Hello Darkness\n    at <anonymous>:1:13', message: 'Hello Darkness', name: 'Error'"
     *
     * let errStrFmt = dumpObj(err, true);
     * // errStrFmt === "[object Error]: {\n    stack: "Error: Hello Darkness\n    at <anonymous>:1:13",\n    message: "Hello Darkness",\n    name: "Error"\n}"
     *
     * let errStrFmt2 = dumpObj(err, 2);
     * // errStrFmt2 === "[object Error]: {\n  stack: "Error: Hello Darkness\n    at <anonymous>:1:13",\n  message: "Hello Darkness",\n  name: "Error"\n}"
     *
     * let errStrFmt3 = dumpObj(err, 0);
     * // errStrFmt3 === "[object Error]: { stack: "Error: Hello Darkness\n    at <anonymous>:1:13", message: "Hello Darkness", name: "Error" }"
     *
     * ```
     * @see {@link dumpObj}
     */
    function dumpObj(object: any, format?: boolean | number): string;

    const enum eActiveStatus {
        NONE = 0,
        /**
         * inactive status means there might be rejected ikey/endpoint promises or ikey/endpoint resolved is not valid
         */
        INACTIVE = 1,
        /**
         * active mean ikey/endpoint promises is resolved and initializing with ikey/endpoint is successful
         */
        ACTIVE = 2,
        /**
         * Waiting for promises to be resolved
         * NOTE: if status is set to be pending, incoming changes will be dropped until pending status is removed
         */
        PENDING = 3
    }

    /**
     * The eBatchDiscardedReason enumeration contains a set of values that specify the reason for discarding offline batches.
     */
    const enum eBatchDiscardedReason {
        /**
         * Unknown.
         */
        Unknown = 0,
        /**
         * Status set to non-retryable after sending
         */
        NonRetryableStatus = 1,
        /**
         * Batches with lower number of critical events are dropped to free up storage space
         */
        CleanStorage = 2,
        /**
         * The batches in storage exceed max allowed time
         */
        MaxInStorageTimeExceeded = 3
    }

    /**
     * The eEventsDiscardedReason enumeration contains a set of values that specify the reason for discarding an event.
     */
    const enum eEventsDiscardedReason {
        /**
         * Unknown.
         */
        Unknown = 0,
        /**
         * Status set to non-retryable.
         */
        NonRetryableStatus = 1,
        /**
         * The event is invalid.
         */
        InvalidEvent = 2,
        /**
         * The size of the event is too large.
         */
        SizeLimitExceeded = 3,
        /**
         * The server is not accepting events from this instrumentation key.
         */
        KillSwitch = 4,
        /**
         * The event queue is full.
         */
        QueueFull = 5,
        /**
         * The sendBeacon API call failed for reasons other than size limits.
         */
        BeaconSendFailure = 6
    }

    const enum _eInternalMessageId {
        BrowserDoesNotSupportLocalStorage = 0,
        BrowserCannotReadLocalStorage = 1,
        BrowserCannotReadSessionStorage = 2,
        BrowserCannotWriteLocalStorage = 3,
        BrowserCannotWriteSessionStorage = 4,
        BrowserFailedRemovalFromLocalStorage = 5,
        BrowserFailedRemovalFromSessionStorage = 6,
        CannotSendEmptyTelemetry = 7,
        ClientPerformanceMathError = 8,
        ErrorParsingAISessionCookie = 9,
        ErrorPVCalc = 10,
        ExceptionWhileLoggingError = 11,
        FailedAddingTelemetryToBuffer = 12,
        FailedMonitorAjaxAbort = 13,
        FailedMonitorAjaxDur = 14,
        FailedMonitorAjaxOpen = 15,
        FailedMonitorAjaxRSC = 16,
        FailedMonitorAjaxSend = 17,
        FailedMonitorAjaxGetCorrelationHeader = 18,
        FailedToAddHandlerForOnBeforeUnload = 19,
        FailedToSendQueuedTelemetry = 20,
        FailedToReportDataLoss = 21,
        FlushFailed = 22,
        MessageLimitPerPVExceeded = 23,
        MissingRequiredFieldSpecification = 24,
        NavigationTimingNotSupported = 25,
        OnError = 26,
        SessionRenewalDateIsZero = 27,
        SenderNotInitialized = 28,
        StartTrackEventFailed = 29,
        StopTrackEventFailed = 30,
        StartTrackFailed = 31,
        StopTrackFailed = 32,
        TelemetrySampledAndNotSent = 33,
        TrackEventFailed = 34,
        TrackExceptionFailed = 35,
        TrackMetricFailed = 36,
        TrackPVFailed = 37,
        TrackPVFailedCalc = 38,
        TrackTraceFailed = 39,
        TransmissionFailed = 40,
        FailedToSetStorageBuffer = 41,
        FailedToRestoreStorageBuffer = 42,
        InvalidBackendResponse = 43,
        FailedToFixDepricatedValues = 44,
        InvalidDurationValue = 45,
        TelemetryEnvelopeInvalid = 46,
        CreateEnvelopeError = 47,
        MaxUnloadHookExceeded = 48,
        CannotSerializeObject = 48,
        CannotSerializeObjectNonSerializable = 49,
        CircularReferenceDetected = 50,
        ClearAuthContextFailed = 51,
        ExceptionTruncated = 52,
        IllegalCharsInName = 53,
        ItemNotInArray = 54,
        MaxAjaxPerPVExceeded = 55,
        MessageTruncated = 56,
        NameTooLong = 57,
        SampleRateOutOfRange = 58,
        SetAuthContextFailed = 59,
        SetAuthContextFailedAccountName = 60,
        StringValueTooLong = 61,
        StartCalledMoreThanOnce = 62,
        StopCalledWithoutStart = 63,
        TelemetryInitializerFailed = 64,
        TrackArgumentsNotSpecified = 65,
        UrlTooLong = 66,
        SessionStorageBufferFull = 67,
        CannotAccessCookie = 68,
        IdTooLong = 69,
        InvalidEvent = 70,
        FailedMonitorAjaxSetRequestHeader = 71,
        SendBrowserInfoOnUserInit = 72,
        PluginException = 73,
        NotificationException = 74,
        SnippetScriptLoadFailure = 99,
        InvalidInstrumentationKey = 100,
        CannotParseAiBlobValue = 101,
        InvalidContentBlob = 102,
        TrackPageActionEventFailed = 103,
        FailedAddingCustomDefinedRequestContext = 104,
        InMemoryStorageBufferFull = 105,
        InstrumentationKeyDeprecation = 106,
        ConfigWatcherException = 107,
        DynamicConfigException = 108,
        DefaultThrottleMsgKey = 109,
        CdnDeprecation = 110,
        SdkLdrUpdate = 111,
        InitPromiseException = 112,
        StatsBeatManagerException = 113,
        StatsBeatException = 114
    }

    const enum eLoggingSeverity {
        /**
         * No Logging will be enabled
         */
        DISABLED = 0,
        /**
         * Error will be sent as internal telemetry
         */
        CRITICAL = 1,
        /**
         * Error will NOT be sent as internal telemetry, and will only be shown in browser console
         */
        WARNING = 2,
        /**
         * The Error will NOT be sent as an internal telemetry, and will only be shown in the browser
         * console if the logging level allows it.
         */
        DEBUG = 3
    }

    /**
     * A type that identifies an enum class generated from a constant enum.
     * @group Enum
     * @typeParam E - The constant enum type
     *
     * Returned from {@link createEnum}
     */
    type EnumCls<E = any> = {
        readonly [key in keyof E extends string | number | symbol ? keyof E : never]: key extends string ? E[key] : key;
    } & {
        readonly [key in keyof E]: E[key];
    };

    type EnumValue<E = any> = EnumCls<E>;

    /**
     * Removes an event handler for the specified event
     * @param Object - to remove the event from
     * @param eventName - The name of the event, with optional namespaces or just the namespaces,
     * such as "click", "click.mynamespace" or ".mynamespace"
     * @param handlerRef - The callback function that needs to be removed from the given event, when using a
     * namespace (with or without a qualifying event) this may be null to remove all previously attached event handlers
     * otherwise this will only remove events with this specific handler.
     * @param evtNamespace - [Optional] Additional namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace,
     * if the eventName also includes a namespace the namespace(s) are merged into a single namespace
     * @param useCapture - [Optional] Defaults to false
     */
    function eventOff<T>(target: T, eventName: string, handlerRef: any, evtNamespace?: string | string[] | null, useCapture?: boolean): void;

    /**
     * Binds the specified function to an event, so that the function gets called whenever the event fires on the object
     * @param obj - Object to add the event too.
     * @param eventName - String that specifies any of the standard DHTML Events without "on" prefix, if may also include an optional (dot "." prefixed)
     * namespaces "click" "click.mynamespace" in addition to specific namespaces.
     * @param handlerRef - Pointer that specifies the function to call when event fires
     * @param evtNamespace - [Optional] Additional namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace,
     * if the eventName also includes a namespace the namespace(s) are merged into a single namespace
     * @param useCapture - [Optional] Defaults to false
     * @returns True if the function was bound successfully to the event, otherwise false
     */
    function eventOn<T>(target: T, eventName: string, handlerRef: any, evtNamespace?: string | string[] | null, useCapture?: boolean): boolean;

    /**
     * The EventsDiscardedReason enumeration contains a set of values that specify the reason for discarding an event.
     */
    const EventsDiscardedReason: EnumValue<typeof eEventsDiscardedReason>;

    type EventsDiscardedReason = number | eEventsDiscardedReason;

    const enum FeatureOptInMode {
        /**
         * not set, completely depends on cdn cfg
         */
        none = 1,
        /**
         * try to not apply config from cdn
         */
        disable = 2,
        /**
         * try to apply config from cdn
         */
        enable = 3
    }

    /**
     * Redacts sensitive information from a URL string, including credentials and specific query parameters.
     * @param input - The URL string to be redacted.
     * @param config - Configuration object that contain redactUrls setting.
     * @returns The redacted URL string or the original string if no redaction was needed or possible.
     */
    function fieldRedaction(input: string, config: IConfiguration): string;

    /**
     * This defines the handler function that is called via the finally when the promise is resolved or rejected
     */
    type FinallyPromiseHandler = (() => void) | undefined | null;

    /**
     * Find all script tags in the provided document and return the information about them.
     * @param doc - The document to search for script tags
     * @returns
     */
    function findAllScripts(doc: any): scriptsInfo[];

    /**
     * Helper function to fetch the named meta-tag from the page.
     * @param name - The name of the meta-tag to find.
     */
    function findMetaTag(name: string): any;

    /**
     * Helper function to fetch the named server timing value from the page response (first navigation event).
     * @param name - The name of the server timing value to find.
     */
    function findNamedServerTiming(name: string): any;

    /**
     * Helper function to fetch the passed traceparent from the page, looking for it as a meta-tag or a Server-Timing header.
     * @param selectIdx - If the found value is comma separated which is the preferred entry to select, defaults to the first
     * @returns
     */
    function findW3cTraceParent(selectIdx?: number): ITraceParent;

    /**
     * This is the reverse case of {@link blockDynamicConversion} in that this will tag an
     * object to indicate that it should always be converted into a dynamic trackable object
     * even when not an object or array. So all properties of this object will become
     * get / set accessor functions.
     *
     * When you have tagged a value as both {@link forceDynamicConversion} and blocked force will take precedence.
     *
     * If `value` is falsy (null / undefined / 0 / empty string etc) it will not be tagged and
     * if there is an exception adding the property to the value (because its frozen etc) the
     * exception will be swallowed.
     * @param value - The object that should be tagged and converted if included into a dynamic
     * configuration.
     * @returns The original value
     */
    function forceDynamicConversion<T>(value: T): T;

    function formatErrorMessageXdr(xdr: IXDomainRequest, message?: string): string;

    function formatErrorMessageXhr(xhr: XMLHttpRequest, message?: string): string;

    /**
     * Format the ITraceParent value as a string using the supported and know version formats.
     * So even if the passed traceParent is a later version the string value returned from this
     * function will convert it to only the known version formats.
     * This currently only supports version "00" and invalid "ff"
     * @param value - The parsed traceParent value
     * @returns
     */
    function formatTraceParent(value: ITraceParent): string;

    /**
     * generate W3C trace id
     */
    function generateW3CId(): string;

    /**
     * get the XHR getAllResponseHeaders.
     * @internal
     */
    function _getAllResponseHeaders(xhr: XMLHttpRequest, isOneDs?: boolean): {};

    /**
     * Returns the global console object
     */
    function getConsole(): Console | null;

    /**
     * Returns the crypto object if it is present otherwise null.
     * This helper is used to access the crypto object from the current
     * global instance which could be window or globalThis for a web worker
     */
    function getCrypto(): Crypto | null;

    function getDebugExt(config: IConfiguration): IDbgExtension;

    function getDebugListener(config: IConfiguration): INotificationListener;

    /**
     * Return the global `document` instance.
     * @function
     * @group Environment
     * @returns
     */
    const getDocument: () => Document;

    /**
     * @internal
     * Get the dynamic config handler if the value is already dynamic
     * @returns
     */
    function getDynamicConfigHandler<T = IConfiguration, V = IConfiguration>(value: V | IDynamicConfigHandler<T>): IDynamicConfigHandler<T> | null;

    /**
     * Returns the name of object if it's an Error. Otherwise, returns empty string.
     */
    function getExceptionName(object: any): string;

    /**
     * Get the current global performance manager that will be used with no performance manager is supplied.
     * @returns - The current default manager
     */
    function getGblPerfMgr(): IPerfManager;

    /**
     * Returns the current global scope object, for a normal web page this will be the current
     * window, for a Web Worker this will be current worker global scope via "self". The internal
     * implementation returns the first available instance object in the following order
     * - globalThis (New standard)
     * - self (Will return the current window instance for supported browsers)
     * - window (fallback for older browser implementations)
     * - global (NodeJS standard)
     * - <null> (When all else fails)
     * While the return type is a Window for the normal case, not all environments will support all
     * of the properties or functions. And this caches the lookup of the global as in some environments
     * this can be an expensive operation.
     * @group Environment
     * @param useCached - [Optional] used for testing to bypass the cached lookup, when `true` this will
     * cause the cached global to be reset.
     */
    function getGlobal(useCached?: boolean): Window;

    /**
     * Return the named global object if available, will return null if the object is not available.
     * @group Environment
     * @param name - The globally named object, may be any valid property key (string, number or symbol)
     * @param useCached - [Optional] used for testing to bypass the cached lookup, when `true` this will
     * cause the cached global to be reset.
     * @example
     * ```ts
     * // This does not cause the evaluation to occur
     * window.myGlobal = "Hello";
     * let cachedValue = getInst("myGlobal");
     * // cachedValue === "Hello"
     *
     * window.myGlobal = "Darkness";
     * // getInst("myGlobal") === "Darkness"
     *
     * let promiseCls = getInst("Promise");
     * // May throw if the global is not supported by the runtime
     * // otherwise the Promise class.
     * ```
     */
    function getGlobalInst<T>(name: string | number | symbol, useCached?: boolean): T | null;

    /**
     * Returns the global `history` instance
     * @function
     * @group Environment
     * @returns
     */
    const getHistory: () => History;

    /**
     * Gets IE version returning the document emulation mode if we are running on IE, or null otherwise
     */
    function getIEVersion(userAgentStr?: string): number;

    /**
     * Returns the global JSON object if it is present otherwise null.
     * This helper is used to access the JSON object without causing an exception
     * "Uncaught ReferenceError: JSON is not defined"
     */
    function getJSON(): JSON | null;

    /**
     * Returns the global location object if it is present otherwise null.
     * This helper is used to access the location object without causing an exception
     * "Uncaught ReferenceError: location is not defined"
     */
    function getLocation(checkForMock?: boolean): Location | null;

    /**
     * Returns the crypto object if it is present otherwise null.
     * This helper is used to access the crypto object from the current
     * global instance which could be window or globalThis for a web worker
     */
    function getMsCrypto(): Crypto | null;

    /**
     * Returns the global `navigator` instance
     * @function
     * @group Environment
     * @returns
     */
    const getNavigator: () => Navigator;

    /**
     * Returns the global `performance` Object if available, which can be used to
     * gather performance information about the current document. It serves as the
     * point of exposure for the Performance Timeline API, the High Resolution Time
     * API, the Navigation Timing API, the User Timing API, and the Resource Timing API.
     *
     * @since 0.4.4
     * @group Environment
     * @returns The global performance object if available.
     */
    function getPerformance(): Performance;

    function getResponseText(xhr: XMLHttpRequest | IXDomainRequest): string;

    /**
     * Returns the current value from the target object if not null or undefined otherwise sets the new value and returns it
     * @param target - The target object to return or set the default value
     * @param field - The key for the field to set on the target
     * @param defValue - [Optional] The value to set if not already present, when not provided a empty object will be added
     */
    function getSetValue<T, K extends keyof T>(target: T, field: K, defValue?: T[K]): T[K];

    /**
     * Return the global `window` instance.
     * @function
     * @group Environment
     * @returns
     */
    const getWindow: () => Window;

    /**
     * Identify whether the runtime contains a `document` object
     * @group Environment
     * @returns - True if a `document` exists
     */
    function hasDocument(): boolean;

    /**
     * Identifies whether the runtime contains a `history` object
     * @group Environment
     * @returns
     */
    function hasHistory(): boolean;

    /**
     * Checks if JSON object is available, this is required as we support the API running without a
     * window /document (eg. Node server, electron webworkers) and if we attempt to assign a history
     * object to a local variable or pass as an argument an "Uncaught ReferenceError: JSON is not defined"
     * exception will be thrown.
     * Defined as a function to support lazy / late binding environments.
     */
    function hasJSON(): boolean;

    /**
     * Identify whether the runtimne contains a `navigator` object
     * @group Environment
     * @returns
     */
    function hasNavigator(): boolean;

    /**
     * The objHasOwnProperty() method returns a boolean indicating whether the object
     * has the specified property as its own property (as opposed to inheriting it).
     *
     * The objHasOwnProperty() method returns true if the specified property is a direct
     * property of the object — even if the value is null or undefined. The method returns
     * false if the property is inherited, or has not been declared at all. Unlike the in
     * operator, this method does not check for the specified property in the object's
     * prototype chain.
     *
     * The method can be called on most JavaScript objects, because most objects descend
     * from Object, and hence inherit its methods. For example Array is an Object, so you
     * can use objHasOwnProperty() method to check whether an index exists:
     * @group Object
     * @param obj - The object being evaluated
     * @param prop - The String or Symbol of the property to test
     * @returns `true` if the object has the specified property as own property; otherwise `false`
     * @example
     * ```ts
     * let example = {};
     * objHasOwnProperty(example, 'prop');   // false
     *
     * example.prop = 'exists';
     * objHasOwnProperty(example, 'prop');   // true - 'prop' has been defined
     *
     * example.prop = null;
     * objHasOwnProperty(example, 'prop');   // true - own property exists with value of null
     *
     * example.prop = undefined;
     * objHasOwnProperty(example, 'prop');   // true - own property exists with value of undefined
     * ```
     */
    function hasOwnProperty<T = any>(obj: T, prop: PropertyKey): boolean;

    /**
     * Identify whether the runtime contains a `window` object
     * @group Environment
     * @returns
     */
    function hasWindow(): boolean;

    interface IAppInsightsCore<CfgType extends IConfiguration = IConfiguration> extends IPerfManagerProvider {
        readonly config: CfgType;
        /**
         * The current logger instance for this instance.
         */
        readonly logger: IDiagnosticLogger;
        /**
         * An array of the installed plugins that provide a version
         */
        readonly pluginVersionStringArr: string[];
        /**
         * The formatted string of the installed plugins that contain a version number
         */
        readonly pluginVersionString: string;
        /**
         * Returns a value that indicates whether the instance has already been previously initialized.
         */
        isInitialized?: () => boolean;
        initialize(config: CfgType, extensions: IPlugin[], logger?: IDiagnosticLogger, notificationManager?: INotificationManager): void;
        getChannels(): IChannelControls[];
        track(telemetryItem: ITelemetryItem): void;
        /**
         * Get the current notification manager
         */
        getNotifyMgr(): INotificationManager;
        /**
         * Get the current cookie manager for this instance
         */
        getCookieMgr(): ICookieMgr;
        /**
         * Set the current cookie manager for this instance
         * @param cookieMgr - The manager, if set to null/undefined will cause the default to be created
         */
        setCookieMgr(cookieMgr: ICookieMgr): void;
        /**
         * Adds a notification listener. The SDK calls methods on the listener when an appropriate notification is raised.
         * The added plugins must raise notifications. If the plugins do not implement the notifications, then no methods will be
         * called.
         * @param listener - An INotificationListener object.
         */
        addNotificationListener?(listener: INotificationListener): void;
        /**
         * Removes all instances of the listener.
         * @param listener - INotificationListener to remove.
         */
        removeNotificationListener?(listener: INotificationListener): void;
        /**
         * Add a telemetry processor to decorate or drop telemetry events.
         * @param telemetryInitializer - The Telemetry Initializer function
         * @returns - A ITelemetryInitializerHandler to enable the initializer to be removed
         */
        addTelemetryInitializer(telemetryInitializer: TelemetryInitializerFunction): ITelemetryInitializerHandler;
        pollInternalLogs?(eventName?: string): ITimerHandler;
        stopPollingInternalLogs?(): void;
        /**
         * Return a new instance of the IProcessTelemetryContext for processing events
         */
        getProcessTelContext(): IProcessTelemetryContext;
        /**
         * Unload and Tear down the SDK and any initialized plugins, after calling this the SDK will be considered
         * to be un-initialized and non-operational, re-initializing the SDK should only be attempted if the previous
         * unload call return `true` stating that all plugins reported that they also unloaded, the recommended
         * approach is to create a new instance and initialize that instance.
         * This is due to possible unexpected side effects caused by plugins not supporting unload / teardown, unable
         * to successfully remove any global references or they may just be completing the unload process asynchronously.
         * If you pass isAsync as `true` (also the default) and DO NOT pass a callback function then an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * will be returned which will resolve once the unload is complete. The actual implementation of the `IPromise`
         * will be a native Promise (if supported) or the default as supplied by [ts-async library](https://github.com/nevware21/ts-async)
         * @param isAsync - Can the unload be performed asynchronously (default)
         * @param unloadComplete - An optional callback that will be called once the unload has completed
         * @param cbTimeout - An optional timeout to wait for any flush operations to complete before proceeding with the
         * unload. Defaults to 5 seconds.
         * @returns Nothing or if occurring asynchronously a [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * which will be resolved once the unload is complete, the [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * will only be returned when no callback is provided and isAsync is true
         */
        unload(isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void | IPromise<ITelemetryUnloadState>;
        /**
         * Find and return the (first) plugin with the specified identifier if present
         */
        getPlugin<T extends IPlugin = IPlugin>(pluginIdentifier: string): ILoadedPlugin<T>;
        /**
         * Add a new plugin to the installation
         * @param plugin - The new plugin to add
         * @param replaceExisting - should any existing plugin be replaced, default is false
         * @param doAsync - Should the add be performed asynchronously
         * @param addCb - [Optional] callback to call after the plugin has been added
         */
        addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting?: boolean, doAsync?: boolean, addCb?: (added?: boolean) => void): void;
        /**
         * Update the configuration used and broadcast the changes to all loaded plugins, this does NOT support updating, adding or removing
         * any the plugins (extensions or channels). It will notify each plugin (if supported) that the configuration has changed but it will
         * not remove or add any new plugins, you need to call addPlugin or getPlugin(identifier).remove();
         * @param newConfig - The new configuration is apply
         * @param mergeExisting - Should the new configuration merge with the existing or just replace it. Default is to merge.
         */
        updateCfg(newConfig: CfgType, mergeExisting?: boolean): void;
        /**
         * Returns the unique event namespace that should be used when registering events
         */
        evtNamespace(): string;
        /**
         * Add a handler that will be called when the SDK is being unloaded
         * @param handler - the handler
         */
        addUnloadCb(handler: UnloadHandler): void;
        /**
         * Add this hook so that it is automatically removed during unloading
         * @param hooks - The single hook or an array of IInstrumentHook objects
         */
        addUnloadHook(hooks: IUnloadHook | IUnloadHook[] | Iterator<IUnloadHook> | ILegacyUnloadHook | ILegacyUnloadHook[] | Iterator<ILegacyUnloadHook>): void;
        /**
         * Flush and send any batched / cached data immediately
         * @param async - send data asynchronously when true (defaults to true)
         * @param callBack - if specified, notify caller when send is complete, the channel should return true to indicate to the caller that it will be called.
         * If the caller doesn't return true the caller should assume that it may never be called.
         * @param sendReason - specify the reason that you are calling "flush" defaults to ManualFlush (1) if not specified
         * @param cbTimeout - An optional timeout to wait for any flush operations to complete before proceeding with the unload. Defaults to 5 seconds.
         * @returns - true if the callback will be return after the flush is complete otherwise the caller should assume that any provided callback will never be called
         */
        flush(isAsync?: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason, cbTimeout?: number): boolean | void;
        /**
         * Gets the current distributed trace context for this instance if available
         * @param createNew - Optional flag to create a new instance if one doesn't currently exist, defaults to true
         */
        getTraceCtx(createNew?: boolean): IDistributedTraceContext | null;
        /**
         * Sets the current distributed trace context for this instance if available
         */
        setTraceCtx(newTraceCtx: IDistributedTraceContext | null | undefined): void;
        /**
         * Watches and tracks changes for accesses to the current config, and if the accessed config changes the
         * handler will be recalled.
         * @returns A watcher handler instance that can be used to remove itself when being unloaded
         */
        onCfgChange(handler: WatcherFunction<CfgType>): IUnloadHook;
        /**
         * Function used to identify the get w parameter used to identify status bit to some channels
         */
        getWParam: () => number;
        /**
         * Watches and tracks status of initialization process
         * @returns ActiveStatus
         * @since 3.3.0
         * If returned status is active, it means initialization process is completed.
         * If returned status is pending, it means the initialization process is waiting for promieses to be resolved.
         * If returned status is inactive, it means ikey is invalid or can 't get ikey or enpoint url from promsises.
         */
        activeStatus?: () => eActiveStatus | number;
        /**
         * Set Active Status to pending, which will block the incoming changes until internal promises are resolved
         * @internal Internal use
         * @since 3.3.0
         */
        _setPendingStatus?: () => void;
    }

    interface IBackendResponse {
        /**
         * Number of items received by the backend
         */
        readonly itemsReceived: number;
        /**
         * Number of items succesfuly accepted by the backend
         */
        readonly itemsAccepted: number;
        /**
         * List of errors for items which were not accepted
         */
        readonly errors: IResponseError[];
        /**
         * App id returned by the backend - not necessary returned, but we don't need it with each response.
         */
        readonly appId?: string;
    }

    interface IBaseProcessingContext {
        /**
         * The current core instance for the request
         */
        core: () => IAppInsightsCore;
        /**
         * THe current diagnostic logger for the request
         */
        diagLog: () => IDiagnosticLogger;
        /**
         * Gets the current core config instance
         */
        getCfg: () => IConfiguration;
        /**
         * Gets the named extension config
         */
        getExtCfg: <T>(identifier: string, defaultValue?: IConfigDefaults<T>) => T;
        /**
         * Gets the named config from either the named identifier extension or core config if neither exist then the
         * default value is returned
         * @param identifier - The named extension identifier
         * @param field - The config field name
         * @param defaultValue - The default value to return if no defined config exists
         */
        getConfig: (identifier: string, field: string, defaultValue?: number | string | boolean | string[] | RegExp[] | Function) => number | string | boolean | string[] | RegExp[] | Function;
        /**
         * Helper to allow plugins to check and possibly shortcut executing code only
         * required if there is a nextPlugin
         */
        hasNext: () => boolean;
        /**
         * Returns the next configured plugin proxy
         */
        getNext: () => ITelemetryPluginChain;
        /**
         * Helper to set the next plugin proxy
         */
        setNext: (nextCtx: ITelemetryPluginChain) => void;
        /**
         * Synchronously iterate over the context chain running the callback for each plugin, once
         * every plugin has been executed via the callback, any associated onComplete will be called.
         * @param callback - The function call for each plugin in the context chain
         */
        iterate: <T extends ITelemetryPlugin = ITelemetryPlugin>(callback: (plugin: T) => void) => void;
        /**
         * Set the function to call when the current chain has executed all processNext or unloadNext items.
         * @param onComplete - The onComplete to call
         * @param that - The "this" value to use for the onComplete call, if not provided or undefined defaults to the current context
         * @param args - Any additional arguments to pass to the onComplete function
         */
        onComplete: (onComplete: () => void, that?: any, ...args: any[]) => void;
        /**
         * Create a new context using the core and config from the current instance, returns a new instance of the same type
         * @param plugins - The execution order to process the plugins, if null or not supplied
         *                  then the current execution order will be copied.
         * @param startAt - The plugin to start processing from, if missing from the execution
         *                  order then the next plugin will be NOT set.
         */
        createNew: (plugins?: IPlugin[] | ITelemetryPluginChain, startAt?: IPlugin) => IBaseProcessingContext;
    }

    /**
     * Provides data transmission capabilities
     */
    interface IChannelControls extends ITelemetryPlugin {
        /**
         * Pause sending data
         */
        pause?(): void;
        /**
         * Resume sending data
         */
        resume?(): void;
        /**
         * Tear down the plugin and remove any hooked value, the plugin should be removed so that it is no longer initialized and
         * therefore could be re-initialized after being torn down. The plugin should ensure that once this has been called any further
         * processTelemetry calls are ignored and it just calls the processNext() with the provided context.
         * @param unloadCtx - This is the context that should be used during unloading.
         * @param unloadState - The details / state of the unload process, it holds details like whether it should be unloaded synchronously or asynchronously and the reason for the unload.
         * @returns boolean - true if the plugin has or will call processNext(), this for backward compatibility as previously teardown was synchronous and returned nothing.
         */
        teardown?: (unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState) => void | boolean;
        /**
         * Flush to send data immediately; channel should default to sending data asynchronously. If executing asynchronously and
         * you DO NOT pass a callback function then a [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * will be returned which will resolve once the flush is complete. The actual implementation of the `IPromise`
         * will be a native Promise (if supported) or the default as supplied by [ts-async library](https://github.com/nevware21/ts-async)
         * @param isAsync - send data asynchronously when true
         * @param callBack - if specified, notify caller when send is complete, the channel should return true to indicate to the caller that it will be called.
         * If the caller doesn't return true the caller should assume that it may never be called.
         * @param sendReason - specify the reason that you are calling "flush" defaults to ManualFlush (1) if not specified
         * @returns - If a callback is provided `true` to indicate that callback will be called after the flush is complete otherwise the caller
         * should assume that any provided callback will never be called, Nothing or if occurring asynchronously a
         * [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html) which will be resolved once the unload is complete,
         * the [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html) will only be returned when no callback is provided
         * and isAsync is true.
         */
        flush?(isAsync: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason): boolean | void | IPromise<boolean>;
        /**
         * Get offline support
         * @returns IInternalOfflineSupport
         */
        getOfflineSupport?: () => IInternalOfflineSupport;
    }

    interface IChannelControlsHost extends IChannelControls {
        /**
         * Get and return the named channel instance (if present) from the queues
         * @param pluginIdentifier - The identifier name of the plugin
         */
        getChannel<T extends IPlugin = IPlugin>(pluginIdentifier: string): T;
    }

    /**
     * The type to identify whether the default value should be applied in preference to the provided value.
     */
    type IConfigCheckFn<V> = (value: V) => boolean;

    /**
     * The default values with a check function
     */
    interface IConfigDefaultCheck<T, V, C = IConfiguration> {
        /**
         * Callback function to check if the user-supplied value is valid, if not the default will be applied
         */
        isVal?: IConfigCheckFn<V>;
        /**
         * Optional function to allow converting and setting of the default value
         */
        set?: IConfigSetFn<T, V>;
        /**
         * The default value to apply if the user-supplied value is not valid
         */
        v?: V | IConfigDefaults<V, T>;
        /**
         *  The default fallback key if the main key is not present, this is the key value from the config
         */
        fb?: keyof T | keyof C | Array<keyof T | keyof C>;
        /**
         * Use this check to determine the default fallback, default only checked whether the property isDefined,
         * therefore `null`; `""` are considered to be valid values.
         */
        dfVal?: (value: any) => boolean;
        /**
         * Specify that any provided value should have the default value(s) merged into the value rather than
         * just using either the default of user provided values. Mergeed objects will automatically be marked
         * as referenced.
         */
        mrg?: boolean;
        /**
         * Set this field of the target as referenced, which will cause any object or array instance
         * to be updated in-place rather than being entirely replaced. All other values will continue to be replaced.
         * This is required for nested default objects to avoid multiple repetitive updates to listeners
         * @returns The referenced properties current value
         */
        ref?: boolean;
        /**
         * Set this field of the target as read-only, which will block this single named property from
         * ever being changed for the target instance.
         * This does NOT freeze or seal the instance, it just stops the direct re-assignment of the named property,
         * if the value is a non-primitive (ie. an object or array) it's properties will still be mutable.
         * @returns The referenced properties current value
         */
        rdOnly?: boolean;
        /**
         * Block the value associated with this property from having it's properties / values converted into
         * dynamic properties, this is generally used to block objects or arrays provided by external libraries
         * which may be a plain object with readonly (non-configurable) or const properties.
         */
        blkVal?: boolean;
    }

    /**
     * The Type definition to define default values to be applied to the config
     * The value may be either the direct value or a ConfigDefaultCheck definition
     */
    type IConfigDefaults<T, C = IConfiguration> = {
        [key in keyof T]: T[key] | IConfigDefaultCheck<T, T[key], C>;
    };

    /**
     * The type which identifies the function use to validate the user supplied value
     */
    type IConfigSetFn<T, V> = (value: any, defValue: V, theConfig: T) => V;

    /**
     * Configuration provided to SDK core
     */
    interface IConfiguration {
        /**
         * Instrumentation key of resource. Either this or connectionString must be specified.
         */
        instrumentationKey?: string | IPromise<string>;
        /**
         * Connection string of resource. Either this or instrumentationKey must be specified.
         */
        connectionString?: string | IPromise<string>;
        /**
         * Set the timer interval (in ms) for internal logging queue, this is the
         * amount of time to wait after logger.queue messages are detected to be sent.
         * Note: since 3.0.1 and 2.8.13 the diagnostic logger timer is a normal timeout timer
         * and not an interval timer. So this now represents the timer "delay" and not
         * the frequency at which the events are sent.
         */
        diagnosticLogInterval?: number;
        /**
         * Maximum number of iKey transmitted logging telemetry per page view
         */
        maxMessageLimit?: number;
        /**
         * Console logging level. All logs with a severity level higher
         * than the configured level will be printed to console. Otherwise
         * they are suppressed. ie Level 2 will print both CRITICAL and
         * WARNING logs to console, level 1 prints only CRITICAL.
         *
         * Note: Logs sent as telemetry to instrumentation key will also
         * be logged to console if their severity meets the configured loggingConsoleLevel
         *
         * 0: ALL console logging off
         * 1: logs to console: severity \>= CRITICAL
         * 2: logs to console: severity \>= WARNING
         */
        loggingLevelConsole?: number;
        /**
         * Telemtry logging level to instrumentation key. All logs with a severity
         * level higher than the configured level will sent as telemetry data to
         * the configured instrumentation key.
         *
         * 0: ALL iKey logging off
         * 1: logs to iKey: severity \>= CRITICAL
         * 2: logs to iKey: severity \>= WARNING
         */
        loggingLevelTelemetry?: number;
        /**
         * If enabled, uncaught exceptions will be thrown to help with debugging
         */
        enableDebug?: boolean;
        /**
         * Endpoint where telemetry data is sent
         */
        endpointUrl?: string | IPromise<string>;
        /**
         * Extension configs loaded in SDK
         */
        extensionConfig?: {
            [key: string]: any;
        };
        /**
         * Additional plugins that should be loaded by core at runtime
         */
        readonly extensions?: ITelemetryPlugin[];
        /**
         * Channel queues that is setup by caller in desired order.
         * If channels are provided here, core will ignore any channels that are already setup, example if there is a SKU with an initialized channel
         */
        readonly channels?: IChannelControls[][];
        /**
         * Flag that disables the Instrumentation Key validation.
         */
        disableInstrumentationKeyValidation?: boolean;
        /**
         * [Optional] When enabled this will create local perfEvents based on sections of the code that have been instrumented
         * to emit perfEvents (via the doPerf()) when this is enabled. This can be used to identify performance issues within
         * the SDK, the way you are using it or optionally your own instrumented code.
         * The provided IPerfManager implementation does NOT send any additional telemetry events to the server it will only fire
         * the new perfEvent() on the INotificationManager which you can listen to.
         * This also does not use the window.performance API, so it will work in environments where this API is not supported.
         */
        enablePerfMgr?: boolean;
        /**
         * [Optional] Callback function that will be called to create a the IPerfManager instance when required and `enablePerfMgr`
         * is enabled, this enables you to override the default creation of a PerfManager() without needing to `setPerfMgr()`
         * after initialization.
         */
        createPerfMgr?: (core: IAppInsightsCore, notificationManager: INotificationManager) => IPerfManager;
        /**
         * [Optional] Fire every single performance event not just the top level root performance event. Defaults to false.
         */
        perfEvtsSendAll?: boolean;
        /**
         * [Optional] Identifies the default length used to generate random session and user id's if non currently exists for the user / session.
         * Defaults to 22, previous default value was 5, if you need to keep the previous maximum length you should set this value to 5.
         */
        idLength?: number;
        /**
         * @description Custom cookie domain. This is helpful if you want to share Application Insights cookies across subdomains. It
         * can be set here or as part of the cookieCfg.domain, the cookieCfg takes precedence if both are specified.
         * @defaultValue ""
         */
        cookieDomain?: string;
        /**
         * @description Custom cookie path. This is helpful if you want to share Application Insights cookies behind an application
         * gateway. It can be set here or as part of the cookieCfg.domain, the cookieCfg takes precedence if both are specified.
         * @defaultValue ""
         */
        cookiePath?: string;
        /**
         * [Optional] A boolean that indicated whether to disable the use of cookies by the SDK. If true, the SDK will not store or
         * read any data from cookies. Cookie usage can be re-enabled after initialization via the core.getCookieMgr().enable().
         */
        disableCookiesUsage?: boolean;
        /**
         * [Optional] A Cookie Manager configuration which includes hooks to allow interception of the get, set and delete cookie
         * operations. If this configuration is specified any specified enabled and domain properties will take precedence over the
         * cookieDomain and disableCookiesUsage values.
         */
        cookieCfg?: ICookieMgrConfig;
        /**
         * [Optional] An array of the page unload events that you would like to be ignored, special note there must be at least one valid unload
         * event hooked, if you list all or the runtime environment only supports a listed "disabled" event it will still be hooked, if required by the SDK.
         * Unload events include "beforeunload", "unload", "visibilitychange" (with 'hidden' state) and "pagehide".
         *
         * This can be used to avoid jQuery 3.7.1+ deprecation warnings and Chrome warnings about the unload event:
         * @example
         * ```javascript
         * {
         *   disablePageUnloadEvents: ["unload"]
         * }
         * ```
         *
         * For more details, see the [Page Unload Events documentation](https://microsoft.github.io/ApplicationInsights-JS/PageUnloadEvents.html).
         */
        disablePageUnloadEvents?: string[];
        /**
         * [Optional] An array of page show events that you would like to be ignored, special note there must be at lease one valid show event
         * hooked, if you list all or the runtime environment only supports a listed (disabled) event it will STILL be hooked, if required by the SDK.
         * Page Show events include "pageshow" and "visibilitychange" (with 'visible' state).
         *
         * @example
         * ```javascript
         * {
         *   disablePageShowEvents: ["pageshow"]
         * }
         * ```
         *
         * For more details, see the [Page Unload Events documentation](https://microsoft.github.io/ApplicationInsights-JS/PageUnloadEvents.html).
         */
        disablePageShowEvents?: string[];
        /**
         * [Optional] A flag for performance optimization to disable attempting to use the Chrome Debug Extension, if disabled and the extension is installed
         * this will not send any notifications.
         */
        disableDbgExt?: boolean;
        /**
         * Add "&w=0" parameter to support UA Parsing when web-workers don't have access to Document.
         * Default is false
         */
        enableWParam?: boolean;
        /**
         * Custom optional value that will be added as a prefix for storage name.
         * @defaultValue undefined
         */
        storagePrefix?: string;
        /**
         * Custom optional value to opt in features
         * @defaultValue undefined
         */
        featureOptIn?: IFeatureOptIn;
        /**
         * If your connection string, instrumentation key and endpoint url are promises,
         * this config is to manually set timeout for those promises.
         * Default: 50000ms
         * @since 3.3.0
         */
        initTimeOut?: number;
        /**
         * If your connection string, instrumentation key and endpoint url are promises,
         * this config is to manually set in memory proxy track calls count limit before promises finished.
         * Default: 100
         * @since 3.3.0
         */
        initInMemoMaxSize?: number;
        /**
         * [Optional] Set additional configuration for exceptions, such as more scripts to include in the exception telemetry.
         * @since 3.3.2
         */
        expCfg?: IExceptionConfig;
        /**
         * [Optional] A flag to enable or disable the use of the field redaction for urls.
         * @defaultValue true
         */
        redactUrls?: boolean;
        /**
         * [Optional] Additional query parameters to redact beyond the default set.
         * Use this to specify custom parameters that contain sensitive information.
         * These will be combined with the default parameters that are redacted.
         * @defaultValue ["sig", "Signature", "AWSAccessKeyId", "X-Goog-Signature"]
         * @example ["sig", "Signature", "AWSAccessKeyId", "X-Goog-Signature","auth_token", "api_key", "private_data"]
         */
        redactQueryParams?: string[];
    }

    interface ICookieMgr {
        /**
         * Enable or Disable the usage of cookies
         */
        setEnabled(value: boolean): void;
        /**
         * Can the system use cookies, if this returns false then all cookie setting and access functions will return nothing
         */
        isEnabled(): boolean;
        /**
         * Set the named cookie with the value and optional domain and optional
         * @param name - The name of the cookie
         * @param value - The value of the cookie (Must already be encoded)
         * @param maxAgeSec - [optional] The maximum number of SECONDS that this cookie should survive
         * @param domain - [optional] The domain to set for the cookie
         * @param path - [optional] Path to set for the cookie, if not supplied will default to "/"
         * @returns - True if the cookie was set otherwise false (Because cookie usage is not enabled or available)
         */
        set(name: string, value: string, maxAgeSec?: number, domain?: string, path?: string): boolean;
        /**
         * Get the value of the named cookie
         * @param name - The name of the cookie
         */
        get(name: string): string;
        /**
         * Delete/Remove the named cookie if cookie support is available and enabled.
         * Note: Not using "delete" as the name because it's a reserved word which would cause issues on older browsers
         * @param name - The name of the cookie
         * @param path - [optional] Path to set for the cookie, if not supplied will default to "/"
         * @returns - True if the cookie was marked for deletion otherwise false (Because cookie usage is not enabled or available)
         */
        del(name: string, path?: string): boolean;
        /**
         * Purge the cookie from the system if cookie support is available, this function ignores the enabled setting of the manager
         * so any cookie will be removed.
         * Note: Not using "delete" as the name because it's a reserved word which would cause issues on older browsers
         * @param name - The name of the cookie
         * @param path - [optional] Path to set for the cookie, if not supplied will default to "/"
         * @returns - True if the cookie was marked for deletion otherwise false (Because cookie usage is not available)
         */
        purge(name: string, path?: string): boolean;
        /**
         * Optional Callback hook to allow the cookie manager to update it's configuration, not generally implemented now that
         * dynamic configuration is supported
         * @param updateState - The new configuration state to apply to the cookie manager
         */
        update?(updateState: ITelemetryUpdateState): void;
        /**
         * Unload and remove any state that this ICookieMgr may be holding, this is generally called when the
         * owning SDK is being unloaded.
         * @param isAsync - Can the unload be performed asynchronously (default)
         * @returns If the unload occurs synchronously then nothing should be returned, if happening asynchronously then
         * the function should return an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * / Promise to allow any listeners to wait for the operation to complete.
         */
        unload?(isAsync?: boolean): void | IPromise<void>;
    }

    /**
     * Configuration definition for instance based cookie management configuration
     */
    interface ICookieMgrConfig {
        /**
         * Defaults to true, A boolean that indicates whether the use of cookies by the SDK is enabled by the current instance.
         * If false, the instance of the SDK initialized by this configuration will not store or read any data from cookies
         */
        enabled?: boolean;
        /**
         * Custom cookie domain. This is helpful if you want to share Application Insights cookies across subdomains.
         */
        domain?: string;
        /**
         * Specifies the path to use for the cookie, defaults to '/'
         */
        path?: string;
        /**
         * Specify the cookie name(s) to be ignored, this will cause any matching cookie name to never be read or written.
         * They may still be explicitly purged or deleted. You do not need to repeat the name in the `blockedCookies`
         * configuration.(Since v2.8.8)
         */
        ignoreCookies?: string[];
        /**
         * Specify the cookie name(s) to never be written, this will cause any cookie name to never be created or updated,
         * they will still be read unless also included in the ignoreCookies and may still be explicitly purged or deleted.
         * If not provided defaults to the same list provided in ignoreCookies. (Since v2.8.8)
         */
        blockedCookies?: string[];
        /**
         * Hook function to fetch the named cookie value.
         * @param name - The name of the cookie
         */
        getCookie?: (name: string) => string;
        /**
         * Hook function to set the named cookie with the specified value.
         * @param name - The name of the cookie
         * @param value - The value to set for the cookie
         */
        setCookie?: (name: string, value: string) => void;
        /**
         * Hook function to delete the named cookie with the specified value, separated from
         * setCookie to avoid the need to parse the value to determine whether the cookie is being
         * added or removed.
         * @param name - The name of the cookie
         * @param cookieValue - The value to set to expire the cookie
         */
        delCookie?: (name: string, cookieValue: string) => void;
        /**
         * Defaults to false, when true this will disable the deferral behavior that occurs when cookies are disabled,
         * reverting to the previous behavior where cookie operations would simply return false when cookies are disabled.
         * This is provided to maintain backward compatibility if applications depend on the previous behavior.
         * When false (default), cookie operations are deferred until cookies are enabled, supporting consent scenarios.
         * @since v3.3.10
         */
        disableCookieDefer?: boolean;
    }

    interface ICustomProperties {
        [key: string]: any;
    }

    interface IDbgExtension {
        isEnabled: () => boolean;
        enable: () => void;
        disable: () => void;
        listener: INotificationListener;
        sendEvt?: (name: string, data: any) => void;
        debugMsg?: (name: string, data: any) => void;
        diagLog?: (name: string, data: any) => void;
    }

    interface IDiagnosticLogger {
        /**
         * 0: OFF
         * 1: only critical (default)
         * 2: critical + info
         */
        consoleLoggingLevel: () => number;
        /**
         * The internal logging queue
         */
        queue: _InternalLogMessage[];
        /**
         * This method will throw exceptions in debug mode or attempt to log the error as a console warning.
         * @param severity - The severity of the log message
         * @param message - The log message.
         */
        throwInternal(severity: LoggingSeverity, msgId: _InternalMessageId, msg: string, properties?: Object, isUserAct?: boolean): void;
        /**
         * This will write a debug message to the console if possible
         * @param message - The debug message
         */
        debugToConsole?(message: string): void;
        /**
         * This will write a warning to the console if possible
         * @param message - The warning message
         */
        warnToConsole(message: string): void;
        /**
         * This will write an error to the console if possible.
         * Provided by the default DiagnosticLogger instance, and internally the SDK will fall back to warnToConsole, however,
         * direct callers MUST check for its existence on the logger as you can provide your own IDiagnosticLogger instance.
         * @param message - The error message
         */
        errorToConsole?(message: string): void;
        /**
         * Resets the internal message count
         */
        resetInternalMessageCount(): void;
        /**
         * Logs a message to the internal queue.
         * @param severity - The severity of the log message
         * @param message - The message to log.
         */
        logInternalMessage?(severity: LoggingSeverity, message: _InternalLogMessage): void;
        /**
         * Optional Callback hook to allow the diagnostic logger to update it's configuration
         * @param updateState - The new configuration state to apply to the diagnostic logger
         */
        update?(updateState: ITelemetryUpdateState): void;
        /**
         * Unload and remove any state that this IDiagnosticLogger may be holding, this is generally called when the
         * owning SDK is being unloaded.
         * @param isAsync - Can the unload be performed asynchronously (default)
         * @returns If the unload occurs synchronously then nothing should be returned, if happening asynchronously then
         * the function should return an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * / Promise to allow any listeners to wait for the operation to complete.
         */
        unload?(isAsync?: boolean): void | IPromise<void>;
    }

    interface IDistributedTraceContext {
        /**
         * Returns the current name of the page
         */
        getName(): string;
        /**
         * Sets the current name of the page
         * @param pageName - The name of the page
         */
        setName(pageName: string): void;
        /**
         * Returns the unique identifier for a trace. All requests / spans from the same trace share the same traceId.
         * Must be read from incoming headers or generated according to the W3C TraceContext specification,
         * in a hex representation of 16-byte array. A.k.a. trace-id, TraceID or Distributed TraceID
         */
        getTraceId(): string;
        /**
         * Set the unique identifier for a trace. All requests / spans from the same trace share the same traceId.
         * Must be conform to the W3C TraceContext specification, in a hex representation of 16-byte array.
         * A.k.a. trace-id, TraceID or Distributed TraceID https://www.w3.org/TR/trace-context/#trace-id
         */
        setTraceId(newValue: string): void;
        /**
         * Self-generated 8-bytes identifier of the incoming request. Must be a hex representation of 8-byte array.
         * Also know as the parentId, used to link requests together
         */
        getSpanId(): string;
        /**
         * Self-generated 8-bytes identifier of the incoming request. Must be a hex representation of 8-byte array.
         * Also know as the parentId, used to link requests together
         * https://www.w3.org/TR/trace-context/#parent-id
         */
        setSpanId(newValue: string): void;
        /**
         * An integer representation of the W3C TraceContext trace-flags.
         */
        getTraceFlags(): number | undefined;
        /**
         * https://www.w3.org/TR/trace-context/#trace-flags
         * @param newValue - An integer representation of the W3C TraceContext trace-flags.
         */
        setTraceFlags(newValue?: number): void;
    }

    /**
     * This interface identifies the config which can track changes
     */
    interface IDynamicConfigHandler<T = IConfiguration> {
        /**
         * Unique Id for this config handler
         */
        readonly uid: string;
        /**
         * Link back to the configuration object that should be used to get/set values
         */
        cfg: T;
        /**
         * The logger instance to use to logger any issues
         */
        logger: IDiagnosticLogger;
        /**
         * Helper to call any listeners that are waiting to be notified
         */
        notify: () => void;
        /**
         * Watch and track changes for accesses to the current config anb
         */
        watch: (configHandler: WatcherFunction<T>) => IWatcherHandler<T>;
        /**
         * Set the value against the provided config/name with the value, the property
         * will be converted to be dynamic (if not already) as long as the provided config
         * is already a tracked dynamic object.
         * @throws TypeError if the provided config is not a monitored dynamic config
         */
        set: <C, V>(theConfig: C, name: string, value: V) => V;
        /**
         * Set default values for the config if not present.
         * @param theConfig - The configuration object to set default on (if missing)
         * @param defaultValues - The default values to apply to the config
         */
        setDf: <C>(theConfig: C, defaultValues: IConfigDefaults<C, T>) => C;
        /**
         * Set this named property of the target as referenced, which will cause any object or array instances
         * to be updated in-place rather than being entirely replaced. All other values will continue to be replaced.
         * @param target - The object which has (or will have) the named property
         * @param name - The name of the property in the target
         * @returns The referenced properties current value.
         */
        ref: <C, V = any>(target: C, name: string) => V;
        /**
         * Set this named property of the target as read-only, which will block this single named property from
         * ever being changed for the target instance.
         * This does NOT freeze or seal the instance, it just stops the direct re-assignment of the named property,
         * if the value is a non-primitive (ie. an object or array) it's properties will still be mutable.
         * @param target - The object which has (or will have) the named property
         * @param name - The name of the property in the target
         * @returns The referenced properties current value.
         */
        rdOnly: <C, V = any>(target: C, name: string) => V;
        /**
         * Set the `value` that is or will be assigned to this named property of the target will not have it's
         * properties converted into dynamic properties, this means that any changes the values properties will
         * not be monitored for changes and therefore will not cause any listeners to be notified in any value
         * is changed. If the value associated with the `target[name]` is change this is still dynamic and will
         * cause listeners to be notified.
         * @param target - The object which has (or will have) the named property
         * @param name - The name of the property in the target
         * @returns The referenced properties current value.
         * @example
         * ```ts
         * let localValue = target[name];   // If within a listener this will cause the listener to be called again
         * target[name] = newValue;         // This will notify listeners that accessed target[name]
         *
         * // This will not cause lsiteners to be called because propa is not converted and value of target[name]
         * // did not change.
         * target[name].propa = 1;
         * target[name].propb = 2;
         *
         * // If within a listener this will caused the listener to be called again only if target[name] is reassigned
         * // not if the value associated with propa is changed.
         * let localValue = target[name].propa;
         * ```
         */
        blkVal: <C, V = any>(target: C, name: string) => V;
    }

    interface IDynamicPropertyHandler<T = IConfiguration> {
        /**
         * Identifies the name of the field that is handled by this handler
         */
        n: string;
        /**
         * The current collection is watcher handlers which should be called if the value changes
         */
        h: IWatcherHandler<T>[];
    }

    /**
     * Configuration for extra exceptions information sent with the exception telemetry.
     * @example
     * ```js
     * const appInsights = new ApplicationInsights({
     config: {
     connectionString: 'InstrumentationKey=YOUR_INSTRUMENTATION_KEY_GOES_HERE',
     expCfg: {
     inclScripts: true,
     expLog : () => {
     return {logs: ["log info 1", "log info 2"]};
     },
     maxLogs : 100
     }
     }
     });
     appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical});
     * ```
     * @interface IExceptionConfig
     */
    interface IExceptionConfig {
        /**
         * If set to true, when exception is sent out, the SDK will also send out all scripts basic info that are loaded on the page.
         * Notice: This would increase the size of the exception telemetry.
         * @defaultvalue true
         */
        inclScripts?: boolean;
        /**
         * Callback function for collecting logs to be included in telemetry data.
         *
         * The length of logs to generate is controlled by the `maxLogs` parameter.
         *
         * This callback is called before telemetry data is sent, allowing for dynamic customization of the logs.
         *
         * @returns An object with the following property:
         * - logs: An array of strings, where each string represents a log entry to be included in the telemetry.
         *
         * @property maxLogs - Specifies the maximum number of logs that can be generated. If not explicitly set, it defaults to 50.
         */
        expLog?: () => {
            logs: string[];
        };
        /**
         * The maximum number of logs to include in the telemetry data.
         * If not explicitly set, it defaults to 50.
         * This is used in conjunction with the `expLog` callback.
         */
        maxLogs?: number;
    }

    interface IFeatureOptIn {
        [feature: string]: IFeatureOptInDetails;
    }

    interface IFeatureOptInDetails {
        /**
         * sets feature opt-in mode
         * @default undefined
         */
        mode?: FeatureOptInMode;
        /**
         * Identifies configuration override values when given feature is enabled
         * NOTE: should use flat string for fields, for example, if you want to set value for extensionConfig.Ananlytics.disableAjaxTrackig in configurations,
         * you should use "extensionConfig.Ananlytics.disableAjaxTrackig" as field name: \{["extensionConfig.Analytics.disableAjaxTrackig"]:1\}
         * Default: undefined
         */
        onCfg?: {
            [field: string]: any;
        };
        /**
         * Identifies configuration override values when given feature is disabled
         * NOTE: should use flat string for fields, for example, if you want to set value for extensionConfig.Ananlytics.disableAjaxTrackig in configurations,
         * you should use "extensionConfig.Ananlytics.disableAjaxTrackig" as field name: \{["extensionConfig.Analytics.disableAjaxTrackig"]:1\}
         * Default: undefined
         */
        offCfg?: {
            [field: string]: any;
        };
        /**
         * define if should block any changes from cdn cfg, if set to true, cfgValue will be applied under all scenarios
         * @default false
         */
        blockCdnCfg?: boolean;
    }

    interface IInstrumentCallDetails {
        name: string;
        inst: any;
        /**
         * This returns an object that the hook function can use to store hook specific
         * context, it it not shared with any other hook instances and is unique for the
         * current call.
         * A hook implementation can use this to pass / share context between different
         * hook callbacks eg. request/response requst/hookErrors etc.
         */
        ctx: () => any;
        /**
         * Allows the hook functions to replace the original arguments
         * @param idx - The argument index (0 based)
         * @param value - The new value for the argument
         */
        set: (idx: number, value: any) => void;
        /**
         * The result of the original method, only populated after the original method has returned
         */
        rslt?: any;
        /**
         * The error (exception) which occurred while executing the original method
         */
        err?: Error;
        /**
         * The Event object from (window.event) at the start of the original call
         */
        evt?: Event;
    }

    /**
     * The holder of the specific instance callback
     */
    interface IInstrumentHook extends IUnloadHook {
        /** Unique Id for this callback on the hooked method */
        id: number;
        /** Holds the callbacks */
        cbks: IInstrumentHooksCallbacks;
        /** Remove this hook from the function */
        rm: () => void;
    }

    interface IInstrumentHooks {
        i: number;
        n: string;
        f: any;
        h: IInstrumentHook[];
    }

    /**
     * The callbacks to call for the instrumented function, you must provide at least the request and/or response callbacks, both are not required.
     * You must always supply the error callback
     */
    interface IInstrumentHooksCallbacks {
        /**
         * [Optional] Namespace details (same as the namespace used for events), useful for debugging and testing to
         * identify the source of the instrumented hooks
         */
        ns?: string | string[];
        /**
         * The hook callback to call before the original function is called
         */
        req?: InstrumentorHooksCallback;
        /**
         * The hook callback to call after the original function was called
         */
        rsp?: InstrumentorHooksCallback;
        /**
         * The callback to call if the hook function causes an exception
         */
        hkErr?: InstrumentorHooksCallback;
        /**
         * The callback to call if the original function causes an exception, even if you
         * supply a callback the original exception will still be thrown
         */
        fnErr?: InstrumentorHooksCallback;
    }

    /**
     * Internal Interface
     */
    interface IInternalOfflineSupport {
        /**
         * Get current endpoint url
         * @returns endpoint
         */
        getUrl: () => string;
        /**
         * Create payload data
         * @returns IPayloadData
         */
        createPayload: (data: string | Uint8Array) => IPayloadData;
        /**
         * Serialize an item into a string
         * @param input - telemetry item
         * @param convertUndefined - convert undefined to a custom-defined object
         * @returns Serialized string
         */
        serialize?: (input: ITelemetryItem, convertUndefined?: any) => string;
        /**
         * Batch an array of strings into one string
         * @param arr - array of strings
         * @returns a string represent all items in the given array
         */
        batch?: (arr: string[]) => string;
        /**
         * If the item should be processed by offline channel
         * @param evt - telemetry item
         * @returns should process or not
         */
        shouldProcess?: (evt: ITelemetryItem) => boolean;
        /**
         * Create 1ds payload data
         * @param evts - ITelemetryItems
         * @returns IPayloadData
         */
        createOneDSPayload?: (evts: ITelemetryItem[]) => IPayloadData;
    }

    /**
     * Internal interface
     * internal sendpost interface
     * @internal
     * @since version after 3.1.0
     */
    interface _IInternalXhrOverride extends IXHROverride {
        _transport?: TransportType;
        _isSync?: boolean;
    }

    /**
     * An alternate interface which provides automatic removal during unloading of the component
     */
    interface ILegacyUnloadHook {
        /**
         * Legacy Self remove the referenced component
         */
        remove: () => void;
    }

    interface ILoadedPlugin<T extends IPlugin> {
        plugin: T;
        /**
         * Identifies whether the plugin is enabled and can process events. This is slightly different from isInitialized as the plugin may be initialized but disabled
         * via the setEnabled() or it may be a shared plugin which has had it's teardown function called from another instance..
         * @returns boolean = true if the plugin is in a state where it is operational.
         */
        isEnabled: () => boolean;
        /**
         * You can optionally enable / disable a plugin from processing events.
         * Setting enabled to true will not necessarily cause the `isEnabled()` to also return true
         * as the plugin must also have been successfully initialized and not had it's `teardown` method called
         * (unless it's also been re-initialized)
         */
        setEnabled: (isEnabled: boolean) => void;
        remove: (isAsync?: boolean, removeCb?: (removed?: boolean) => void) => void;
    }

    /**
     * Initialize the queue of plugins
     * @param plugins - The array of plugins to initialize and setting of the next plugin
     * @param config - The current config for the instance
     * @param core - THe current core instance
     * @param extensions - The extensions
     */
    function initializePlugins(processContext: IProcessTelemetryContext, extensions: IPlugin[]): void;

    /**
     * An interface used for the notification listener.
     * @interface
     */
    interface INotificationListener {
        /**
         * [Optional] A function called when events are sent.
         * @param events - The array of events that have been sent.
         */
        eventsSent?: (events: ITelemetryItem[]) => void;
        /**
         * [Optional] A function called when events are discarded.
         * @param events - The array of events that have been discarded.
         * @param reason - The reason for discarding the events. The EventsDiscardedReason
         * constant should be used to check the different values.
         * @param sendType - [Optional] The send type used when the events were discarded.
         */
        eventsDiscarded?: (events: ITelemetryItem[], reason: number, sendType?: number) => void;
        /**
         * [Optional] A function called when the events have been requested to be sent to the sever.
         * @param sendReason - The reason why the event batch is being sent.
         * @param isAsync - A flag which identifies whether the requests are being sent in an async or sync manner.
         */
        eventsSendRequest?: (sendReason: number, isAsync?: boolean) => void;
        /**
         * [Optional] This event is sent if you have enabled perf events, they are primarily used to track internal performance testing and debugging
         * the event can be displayed via the debug plugin extension.
         * @param perfEvent - The performance event object
         */
        perfEvent?: (perfEvent: IPerfEvent) => void;
        /**
         * Unload and remove any state that this INotificationListener may be holding, this is generally called when the
         * owning Manager is being unloaded.
         * @param isAsync - Can the unload be performed asynchronously (default)
         * @returns If the unload occurs synchronously then nothing should be returned, if happening asynchronously then
         * the function should return an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * / Promise to allow any listeners to wait for the operation to complete.
         */
        unload?(isAsync?: boolean): void | IPromise<void>;
        /**
         * [Optional] A function called when the offline events have been stored to the persistent storage
         * @param events - items that are stored in the persistent storage
         * @since v3.1.1
         */
        offlineEventsStored?(events: ITelemetryItem[]): void;
        /**
         * [Optional] A function called when the offline events have been sent from the persistent storage
         * @param batch - payload data that is sent from the persistent storage
         * @since v3.1.1
         */
        offlineBatchSent?(batch: IPayloadData): void;
        /**
         * [Optional] A function called when the offline events have been dropped from the persistent storage
         * @param cnt - count of batches dropped
         * @param reason - the reason why the batches is dropped
         * @since v3.1.1
         */
        offlineBatchDrop?(cnt: number, reason?: number): void;
    }

    /**
     * Class to manage sending notifications to all the listeners.
     */
    interface INotificationManager {
        listeners: INotificationListener[];
        /**
         * Adds a notification listener.
         * @param listener - The notification listener to be added.
         */
        addNotificationListener(listener: INotificationListener): void;
        /**
         * Removes all instances of the listener.
         * @param listener - AWTNotificationListener to remove.
         */
        removeNotificationListener(listener: INotificationListener): void;
        /**
         * Notification for events sent.
         * @param events - The array of events that have been sent.
         */
        eventsSent(events: ITelemetryItem[]): void;
        /**
         * Notification for events being discarded.
         * @param events - The array of events that have been discarded by the SDK.
         * @param reason - The reason for which the SDK discarded the events. The EventsDiscardedReason
         * constant should be used to check the different values.
         * @param sendType - [Optional] The send type used when the events were discarded.
         */
        eventsDiscarded(events: ITelemetryItem[], reason: number, sendType?: number): void;
        /**
         * [Optional] A function called when the events have been requested to be sent to the sever.
         * @param sendReason - The reason why the event batch is being sent.
         * @param isAsync - A flag which identifies whether the requests are being sent in an async or sync manner.
         */
        eventsSendRequest?(sendReason: number, isAsync: boolean): void;
        /**
         * [Optional] This event is sent if you have enabled perf events, they are primarily used to track internal performance testing and debugging
         * the event can be displayed via the debug plugin extension.
         * @param perfEvent - The perf event details
         */
        perfEvent?(perfEvent: IPerfEvent): void;
        /**
         * Unload and remove any state that this INotificationManager may be holding, this is generally called when the
         * owning SDK is being unloaded.
         * @param isAsync - Can the unload be performed asynchronously (default)
         * @returns If the unload occurs synchronously then nothing should be returned, if happening asynchronously then
         * the function should return an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * / Promise to allow any listeners to wait for the operation to complete.
         */
        unload?(isAsync?: boolean): void | IPromise<void>;
        /**
         * [Optional] A function called when the offline events have been stored to the persistent storage
         * @param events - items that are stored in the persistent storage
         * @since v3.1.1
         */
        offlineEventsStored?(events: ITelemetryItem[]): void;
        /**
         * [Optional] A function called when the offline events have been sent from the persistent storage
         * @param batch - payload data that is sent from the persistent storage
         * @since v3.1.1
         */
        offlineBatchSent?(batch: IPayloadData): void;
        /**
         * [Optional] A function called when the offline events have been dropped from the persistent storage
         * @param cnt - count of batches dropped
         * @param reason - the reason why the batches is dropped
         * @since v3.1.1
         */
        offlineBatchDrop?(cnt: number, reason?: number): void;
    }

    /**
     * Add an instrumentation hook to the provided named "event" for the target class / object, this doesn't check whether the
     * named "event" is in fact a function and just assigns the instrumentation hook to the target[evtName]
     * @param target - The target object
     * @param evtName - The name of the event
     * @param callbacks - The callbacks to configure and call whenever the function is called
     * @param checkPrototype - If the function doesn't exist on the target should it attempt to hook the prototype function
     * @param checkParentProto - If the function doesn't exist on the target or it's prototype should it attempt to hook the parent's prototype
     */
    function InstrumentEvent(target: any, evtName: string, callbacks: IInstrumentHooksCallbacks, checkPrototype?: boolean, checkParentProto?: boolean): IInstrumentHook;

    /**
     * Intercept the named prototype functions for the target class / object
     * @param target - The target object
     * @param funcName - The function name
     * @param callbacks - The callbacks to configure and call whenever the function is called
     * @param checkPrototype - If the function doesn't exist on the target should it attempt to hook the prototype function
     * @param checkParentProto - If the function doesn't exist on the target or it's prototype should it attempt to hook the parent's prototype
     */
    function InstrumentFunc(target: any, funcName: string, callbacks: IInstrumentHooksCallbacks, checkPrototype?: boolean, checkParentProto?: boolean): IInstrumentHook;

    /**
     * Intercept the named functions for the target class / object
     * @param target - The target object
     * @param funcNames - The function names to intercept and call
     * @param callbacks - The callbacks to configure and call whenever the function is called
     * @param checkPrototype - If the function doesn't exist on the target should it attempt to hook the prototype function
     * @param checkParentProto - If the function doesn't exist on the target or it's prototype should it attempt to hook the parent's prototype
     */
    function InstrumentFuncs(target: any, funcNames: string[], callbacks: IInstrumentHooksCallbacks, checkPrototype?: boolean, checkParentProto?: boolean): IInstrumentHook[];

    /**
     * A callback function that will be called for the wrapped instrumentation function
     * before the original function is executed.
     */
    type InstrumentorHooksCallback = (funcArgs: IInstrumentCallDetails, ...orgArgs: any[]) => void;

    /**
     * Intercept the named prototype functions for the target class / object
     * @param target - The target object
     * @param funcName - The function name
     * @param callbacks - The callbacks to configure and call whenever the function is called
     */
    function InstrumentProto(target: any, funcName: string, callbacks: IInstrumentHooksCallbacks): IInstrumentHook;

    /**
     * Intercept the named prototype functions for the target class / object
     * @param target - The target object
     * @param funcNames - The function names to intercept and call
     * @param callbacks - The callbacks to configure and call whenever the function is called
     */
    function InstrumentProtos(target: any, funcNames: string[], callbacks: IInstrumentHooksCallbacks): IInstrumentHook[];

    class _InternalLogMessage {
        static dataType: string;
        message: string;
        messageId: _InternalMessageId;
        constructor(msgId: _InternalMessageId, msg: string, isUserAct?: boolean, properties?: Object);
    }

    type _InternalMessageId = number | _eInternalMessageId;

    /** IPayloadData describes interface of payload sent via POST channel */
    interface IPayloadData {
        urlString: string;
        data: Uint8Array | string;
        headers?: {
            [name: string]: string;
        };
        timeout?: number;
        disableXhrSync?: boolean;
        disableFetchKeepAlive?: boolean;
        sendReason?: SendRequestReason;
    }

    /**
     * This interface identifies the details of an internal performance event - it does not represent an outgoing reported event
     */
    interface IPerfEvent {
        /**
         * The name of the performance event
         */
        name: string;
        /**
         * The start time of the performance event
         */
        start: number;
        /**
         * The payload (contents) of the perfEvent, may be null or only set after the event has completed depending on
         * the runtime environment.
         */
        payload: any;
        /**
         * Is this occurring from an asynchronous event
         */
        isAsync: boolean;
        /**
         * Identifies the total inclusive time spent for this event, including the time spent for child events,
         * this will be undefined until the event is completed
         */
        time?: number;
        /**
         * Identifies the exclusive time spent in for this event (not including child events),
         * this will be undefined until the event is completed.
         */
        exTime?: number;
        /**
         * The Parent event that was started before this event was created
         */
        parent?: IPerfEvent;
        /**
         * The child perf events that are contained within the total time of this event.
         */
        childEvts?: IPerfEvent[];
        /**
         * Identifies whether this event is a child event of a parent
         */
        isChildEvt: () => boolean;
        /**
         * Get the names additional context associated with this perf event
         */
        getCtx?: (key: string) => any;
        /**
         * Set the named additional context to be associated with this perf event, this will replace any existing value
         */
        setCtx?: (key: string, value: any) => void;
        /**
         * Mark this event as completed, calculating the total execution time.
         */
        complete: () => void;
    }

    /**
     * This defines an internal performance manager for tracking and reporting the internal performance of the SDK -- It does
     * not represent or report any event to the server.
     */
    interface IPerfManager {
        /**
         * Create a new event and start timing, the manager may return null/undefined to indicate that it does not
         * want to monitor this source event.
         * @param src - The source name of the event
         * @param payloadDetails - An optional callback function to fetch the payload details for the event.
         * @param isAsync - Is the event occurring from a async event
         */
        create(src: string, payloadDetails?: () => any, isAsync?: boolean): IPerfEvent | null | undefined;
        /**
         * Complete the perfEvent and fire any notifications.
         * @param perfEvent - Fire the event which will also complete the passed event
         */
        fire(perfEvent: IPerfEvent): void;
        /**
         * Set an execution context value
         * @param key - The context key name
         * @param value - The value
         */
        setCtx(key: string, value: any): void;
        /**
         * Get the execution context value
         * @param key - The context key
         */
        getCtx(key: string): any;
    }

    /**
     * Identifies an interface to a host that can provide an IPerfManager implementation
     */
    interface IPerfManagerProvider {
        /**
         * Get the current performance manager
         */
        getPerfMgr(): IPerfManager;
        /**
         * Set the current performance manager
         * @param perfMgr - The performance manager
         */
        setPerfMgr(perfMgr: IPerfManager): void;
    }

    interface IPlugin {
        /**
         * Initialize plugin loaded by SDK
         * @param config - The config for the plugin to use
         * @param core - The current App Insights core to use for initializing this plugin instance
         * @param extensions - The complete set of extensions to be used for initializing the plugin
         * @param pluginChain - [Optional] specifies the current plugin chain which identifies the
         * set of plugins and the order they should be executed for the current request.
         */
        initialize: (config: IConfiguration, core: IAppInsightsCore, extensions: IPlugin[], pluginChain?: ITelemetryPluginChain) => void;
        /**
         * Returns a value that indicates whether the plugin has already been previously initialized.
         * New plugins should implement this method to avoid being initialized more than once.
         */
        isInitialized?: () => boolean;
        /**
         * Tear down the plugin and remove any hooked value, the plugin should be removed so that it is no longer initialized and
         * therefore could be re-initialized after being torn down. The plugin should ensure that once this has been called any further
         * processTelemetry calls are ignored and it just calls the processNext() with the provided context.
         * @param unloadCtx - This is the context that should be used during unloading.
         * @param unloadState - The details / state of the unload process, it holds details like whether it should be unloaded synchronously or asynchronously and the reason for the unload.
         * @returns boolean - true if the plugin has or will call processNext(), this for backward compatibility as previously teardown was synchronous and returned nothing.
         */
        teardown?: (unloadCtx: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState) => void | boolean;
        /**
         * Extension name
         */
        readonly identifier: string;
        /**
         * Plugin version (available in data.properties.version in common schema)
         */
        readonly version?: string;
        /**
         * The App Insights core to use for backward compatibility.
         * Therefore the interface will be able to access the core without needing to cast to "any".
         * [optional] any 3rd party plugins which are already implementing this interface don't fail to compile.
         */
        core?: IAppInsightsCore;
    }

    /**
     * The current context for the current call to processTelemetry(), used to support sharing the same plugin instance
     * between multiple AppInsights instances
     */
    interface IProcessTelemetryContext extends IBaseProcessingContext {
        /**
         * Call back for telemetry processing before it it is sent
         * @param env - This is the current event being reported
         * @returns boolean (true) if there is no more plugins to process otherwise false or undefined (void)
         */
        processNext: (env: ITelemetryItem) => boolean | void;
        /**
         * Create a new context using the core and config from the current instance, returns a new instance of the same type
         * @param plugins - The execution order to process the plugins, if null or not supplied
         *                  then the current execution order will be copied.
         * @param startAt - The plugin to start processing from, if missing from the execution
         *                  order then the next plugin will be NOT set.
         */
        createNew: (plugins?: IPlugin[] | ITelemetryPluginChain, startAt?: IPlugin) => IProcessTelemetryContext;
    }

    /**
     * The current context for the current call to teardown() implementations, used to support when plugins are being removed
     * or the SDK is being unloaded.
     */
    interface IProcessTelemetryUnloadContext extends IBaseProcessingContext {
        /**
         * This Plugin has finished unloading, so unload the next one
         * @param uploadState - The state of the unload process
         * @returns boolean (true) if there is no more plugins to process otherwise false or undefined (void)
         */
        processNext: (unloadState: ITelemetryUnloadState) => boolean | void;
        /**
         * Create a new context using the core and config from the current instance, returns a new instance of the same type
         * @param plugins - The execution order to process the plugins, if null or not supplied
         *                  then the current execution order will be copied.
         * @param startAt - The plugin to start processing from, if missing from the execution
         *                  order then the next plugin will be NOT set.
         */
        createNew: (plugins?: IPlugin[] | ITelemetryPluginChain, startAt?: IPlugin) => IProcessTelemetryUnloadContext;
    }

    /**
     * The current context for the current call to the plugin update() implementations, used to support the notifications
     * for when plugins are added, removed or the configuration was changed.
     */
    interface IProcessTelemetryUpdateContext extends IBaseProcessingContext {
        /**
         * This Plugin has finished unloading, so unload the next one
         * @param updateState - The update State
         * @returns boolean (true) if there is no more plugins to process otherwise false or undefined (void)
         */
        processNext: (updateState: ITelemetryUpdateState) => boolean | void;
        /**
         * Create a new context using the core and config from the current instance, returns a new instance of the same type
         * @param plugins - The execution order to process the plugins, if null or not supplied
         *                  then the current execution order will be copied.
         * @param startAt - The plugin to start processing from, if missing from the execution
         *                  order then the next plugin will be NOT set.
         */
        createNew: (plugins?: IPlugin[] | ITelemetryPluginChain, startAt?: IPlugin) => IProcessTelemetryUpdateContext;
    }

    /**
     * Create a Promise object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
     * This interface definition, closely mirrors the typescript / javascript PromiseLike<T> and Promise<T> definitions as well as providing
     * simular functions as that provided by jQuery deferred objects.
     *
     * The returned Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers
     * with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous
     * methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point
     * in the future.
     *
     * A Promise is in one of these states:
     * <ul>
     * <li> pending: initial state, neither fulfilled nor rejected.
     * <li> fulfilled: meaning that the operation was completed successfully.
     * <li> rejected: meaning that the operation failed.
     * </ul>
     *
     * A pending promise can either be fulfilled with a value or rejected with a reason (error). When either of these options happens, the
     * associated handlers queued up by a promise's then method are called synchronously. If the promise has already been fulfilled or rejected
     * when a corresponding handler is attached, the handler will be called synchronously, so there is no race condition between an asynchronous
     * operation completing and its handlers being attached.
     *
     * As the `then()` and `catch()` methods return promises, they can be chained.
     * @typeParam T - Identifies the expected return type from the promise
     */
    interface IPromise<T> extends PromiseLike<T>, Promise<T> {
        /**
         * Returns a string representation of the current state of the promise. The promise can be in one of four states.
         * <ul>
         * <li> <b>"pending"</b>: The promise is not yet in a completed state (neither "rejected"; or "resolved").</li>
         * <li> <b>"resolved"</b>: The promise is in the resolved state.</li>
         * <li> <b>"rejected"</b>: The promise is in the rejected state.</li>
         * </ul>
         * @example
         * ```ts
         * let doResolve;
         * let promise: IPromise<any> = createSyncPromise((resolve) => {
         *  doResolve = resolve;
         * });
         *
         * let state: string = promise.state();
         * console.log("State: " + state);      // State: pending
         * doResolve(true);                     // Promise will resolve synchronously as it's a synchronous promise
         * console.log("State: " + state);      // State: resolved
         * ```
         */
        state?: string;
        /**
         * Attaches callbacks for the resolution and/or rejection of the Promise.
         * @param onResolved - The callback to execute when the Promise is resolved.
         * @param onRejected - The callback to execute when the Promise is rejected.
         * @returns A Promise for the completion of which ever callback is executed.
         * @example
         * ```ts
         * const promise1 = createPromise((resolve, reject) => {
         *   resolve('Success!');
         * });
         *
         * promise1.then((value) => {
         *   console.log(value);
         *   // expected output: "Success!"
         * });
         * ```
         */
        then<TResult1 = T, TResult2 = never>(onResolved?: ResolvedPromiseHandler<T, TResult1>, onRejected?: RejectedPromiseHandler<TResult2>): IPromise<TResult1 | TResult2>;
        /**
         * Attaches callbacks for the resolution and/or rejection of the Promise.
         * @param onResolved - The callback to execute when the Promise is resolved.
         * @param onRejected - The callback to execute when the Promise is rejected.
         * @returns A Promise for the completion of which ever callback is executed.
         * @example
         * ```ts
         * const promise1 = createPromise((resolve, reject) => {
         *   resolve('Success!');
         * });
         *
         * promise1.then((value) => {
         *   console.log(value);
         *   // expected output: "Success!"
         * });
         * ```
         */
        then<TResult1 = T, TResult2 = never>(onResolved?: ResolvedPromiseHandler<T, TResult1>, onRejected?: RejectedPromiseHandler<TResult2>): PromiseLike<TResult1 | TResult2>;
        /**
         * Attaches callbacks for the resolution and/or rejection of the Promise.
         * @param onResolved - The callback to execute when the Promise is resolved.
         * @param onRejected - The callback to execute when the Promise is rejected.
         * @returns A Promise for the completion of which ever callback is executed.
         * @example
         * ```ts
         * const promise1 = createPromise((resolve, reject) => {
         *   resolve('Success!');
         * });
         *
         * promise1.then((value) => {
         *   console.log(value);
         *   // expected output: "Success!"
         * });
         * ```
         */
        then<TResult1 = T, TResult2 = never>(onResolved?: ResolvedPromiseHandler<T, TResult1>, onRejected?: RejectedPromiseHandler<TResult2>): IPromise<TResult1 | TResult2>;
        /**
         * Attaches a callback for only the rejection of the Promise.
         * @param onRejected - The callback to execute when the Promise is rejected.
         * @returns A Promise for the completion of the callback.
         * @example
         * ```ts
         * const promise1 = createPromise((resolve, reject) => {
         *   throw 'Uh-oh!';
         * });
         *
         * promise1.catch((error) => {
         *   console.error(error);
         * });
         * // expected output: Uh-oh!
         * ```
         */
        catch<TResult = never>(onRejected?: ((reason: any) => TResult | IPromise<TResult>) | undefined | null): IPromise<T | TResult>;
        /**
         * Attaches a callback for only the rejection of the Promise.
         * @param onRejected - The callback to execute when the Promise is rejected.
         * @returns A Promise for the completion of the callback.
         * @example
         * ```ts
         * const promise1 = createPromise((resolve, reject) => {
         *   throw 'Uh-oh!';
         * });
         *
         * promise1.catch((error) => {
         *   console.error(error);
         * });
         * // expected output: Uh-oh!
         * ```
         */
        catch<TResult = never>(onRejected?: ((reason: any) => TResult | IPromise<TResult>) | undefined | null): PromiseLike<T | TResult>;
        /**
         * Attaches a callback for only the rejection of the Promise.
         * @param onRejected - The callback to execute when the Promise is rejected.
         * @returns A Promise for the completion of the callback.
         * @example
         * ```ts
         * const promise1 = createPromise((resolve, reject) => {
         *   throw 'Uh-oh!';
         * });
         *
         * promise1.catch((error) => {
         *   console.error(error);
         * });
         * // expected output: Uh-oh!
         * ```
         */
        catch<TResult = never>(onRejected?: ((reason: any) => TResult | IPromise<TResult>) | undefined | null): IPromise<T | TResult>;
        /**
         * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
         * resolved value cannot be modified from the callback.
         * @param onfinally - The callback to execute when the Promise is settled (fulfilled or rejected).
         * @returns A Promise for the completion of the callback.
         * @example
         * ```ts
         * function doFunction() {
         *   return createPromise((resolve, reject) => {
         *     if (Math.random() > 0.5) {
         *       resolve('Function has completed');
         *     } else {
         *       reject(new Error('Function failed to process'));
         *     }
         *   });
         * }
         *
         * doFunction().then((data) => {
         *     console.log(data);
         * }).catch((err) => {
         *     console.error(err);
         * }).finally(() => {
         *     console.log('Function processing completed');
         * });
         * ```
         */
        finally(onfinally?: FinallyPromiseHandler): IPromise<T>;
    }

    interface _IRegisteredEvents {
        name: string;
        handler: any;
    }

    interface IResponseError {
        readonly index: number;
        readonly statusCode: number;
        readonly message: string;
    }

    /**
     * Checks if the type of value is an Array.
     *
     * @function
     * @group Type Identity
     * @group Array
     * @param arg - Value to be checked.
     * @return True if the value is a Array, false otherwise.
     * @example
     * ```ts
     * import { isArray, isObject } from "@nevware21/ts-utils";
     *
     * function performAction(value: any) {
     *     if (isArray(value) || isObject(value)) {
     *         // Do something
     *     } else {
     *         // Do something else
     *     }
     * }
     * ```
     */
    const isArray: <T = any>(arg: any) => arg is Array<T>;

    /**
     * Checks if HTML5 Beacons are supported in the current environment.
     * @param useCached - [Optional] used for testing to bypass the cached lookup, when `true` this will
     * cause the cached global to be reset.
     * @returns True if supported, false otherwise.
     */
    function isBeaconsSupported(useCached?: boolean): boolean;

    /**
     * Checks if the type of value is a boolean.
     * @function
     * @group Type Identity
     * @param value - Value to be checked.
     * @return True if the value is a boolean, false otherwise.
     */
    const isBoolean: (value: any) => value is boolean;

    /**
     * Check if an object is of type Date
     * @function
     * @group Type Identity
     * @example
     * ```ts
     * import { isDate } from "@nevware21/ts-utils";
     *
     * let _theDate = null;
     *
     * function getSetDate(newDate?: any) {
     *     _theDate = isDate(newDate) ? newDate : new Date();
     *
     *     return _theDate;
     * }
     * ```
     */
    const isDate: (value: any) => value is Date;

    /**
     * internal interface
     * Define functions when xhr/xdr/fetch requests are successfully returned. If they are not defined, oncomplete with be called instead
     * @internal for internal use only
     */
    interface _ISenderOnComplete {
        /**
         * defined xdr onload function to handle response
         * @param dxr - xdr request object
         * @param oncomplete - oncomplete function
         * @since version after 3.1.0
         */
        xdrOnComplete?(xdr: IXDomainRequest, onComplete: OnCompleteCallback, payload?: IPayloadData): void;
        /**
         * defined fetch on complete function to handle response
         * @param response - response object
         * @param onComplete - oncomplete function
         * @param resValue - response.text().value
         * @since version after 3.1.0
         */
        fetchOnComplete?(response: Response, onComplete: OnCompleteCallback, resValue?: string, payload?: IPayloadData): void;
        /**
         * defined xhr onreadystatechange function to handle response
         * @param request - request object
         * @param oncomplete - oncomplete function
         * @since version after 3.1.0
         */
        xhrOnComplete?(request: XMLHttpRequest, onComplete: OnCompleteCallback, payload?: IPayloadData): void;
        /**
         * Define functions during beacon can not send payload after first attempt. If not defined, will be apyload will be retried with fallback sender.
         * @param data - payload data
         * @param onComplete - oncomplete function
         * @param canSend - can the current data sent by beacon sender
         * @since version after 3.1.0
         */
        beaconOnRetry?(data: IPayloadData, onComplete: OnCompleteCallback, canSend: (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => boolean): void;
    }

    /**
     * Internal interface for SendPostMnager
     * @internal for internal use only
     */
    interface _ISendPostMgrConfig {
        /**
         * Enable the sender interface to return a promise
         * Note: Enabling this may cause unhandled promise rejection errors to occur if you do not listen and handle any rejection response,
         * Defaults to false
         * @since version after 3.1.0
         */
        enableSendPromise?: boolean;
        /**
         * Identifies if the sender is 1ds post channel
         * Default is false
         * @since version after 3.1.0
         */
        isOneDs?: boolean;
        /**
         * Identify if Credentials should be disabled for 1ds post channel, application insights sender will igore this config
         * Default is false
         * @since version after 3.1.0
         */
        disableCredentials?: boolean;
        /**
         * Identifies if `XMLHttpRequest` or `XDomainRequest` (for IE version before 9) should be used
         * Default: false
         * @since 3.1.1
         */
        disableXhr?: boolean;
        /**
         * Is beacon disabled during async sending
         * Default: false
         * @since version after 3.1.0
         */
        disableBeacon?: boolean;
        /**
         * Is beacon disabled during sync sending
         * Default: false
         * @since version after 3.1.0
         */
        disableBeaconSync?: boolean;
        /**
         * Is FetchKeepAlive disabled during sync sending
         * Default: false
         * @since version after 3.1.0
         */
        disableFetchKeepAlive?: boolean;
        /**
         * Identifies functions when xhr/xdr/fetch requests are successfully returned. If they are not defined, oncomplete with be called instead
         * @since version after 3.1.0
         */
        senderOnCompleteCallBack?: _ISenderOnComplete;
        /**
         * time wrapper to handle payload timeout
         * this is for 1ds post channel only
         * Default: null
         * @since version after 3.1.0
         */
        timeWrapper?: _ITimeoutOverrideWrapper;
        /**
         * [Optional] flag to indicate whether the sendBeacon and fetch (with keep-alive flag) should add the "NoResponseBody" query string
         * value to indicate that the server should return a 204 for successful requests. Defaults to true
         * this is for 1ds post channel only
         * Default: true
         * @since version after 3.1.0
         */
        addNoResponse?: boolean;
        /**
         * [Optional] Specify whether cross-site Access-Control fetch requests should include credentials such as cookies,
         * authentication headers, or TLS client certificates.
         *
         * Possible values:
         * - "omit": never send credentials in the request or include credentials in the response.
         * - "include": always include credentials, even cross-origin.
         * - "same-origin": only send and include credentials for same-origin requests.
         *
         * If not set, the default value will be "include".
         *
         * For more information, refer to:
         * - [Fetch API - Using Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials)
         * @since version after 3.3.1
         */
        fetchCredentials?: RequestCredentials;
    }

    /**
     * Checks if the type of value is a Error object.
     * @function
     * @group Type Identity
     * @group Error
     * @param value - Value to be checked.
     * @return True if the value is a Error, false otherwise.
     */
    const isError: (value: any) => value is Error;

    /**
     * Checks if the feature is enabled on not. If the feature is not defined, it will return the default state if provided or undefined.
     * If the feature is defined, it will check the mode and return true if the mode is enable or false if the mode is disable.
     * @param feature - The feature name to check
     * @param cfg - The configuration object to check the feature state against
     * @param sdkDefaultState - Optional default state to return if the feature is not defined
     * @returns True if the feature is enabled, false if the feature is disabled, or undefined if the feature is not defined and no default state is provided.
     */
    function isFeatureEnabled<T extends IConfiguration = IConfiguration>(feature?: string, cfg?: T, sdkDefaultState?: boolean): boolean | undefined;

    /**
     * Checks if the Fetch API is supported in the current environment.
     * @param withKeepAlive - [Optional] If True, check if fetch is available and it supports the keepalive feature, otherwise only check if fetch is supported
     * @returns True if supported, otherwise false
     */
    function isFetchSupported(withKeepAlive?: boolean): boolean;

    /**
     * Checks to see if the past value is a function value
     * @function
     * @group Type Identity
     * @param value - The value to check
     * @returns
     * @example
     * ```ts
     * function myFunction() { }
     * isFunction(null);            // false
     * isFunction(undefined);       // false
     * isFunction("null");          // false
     * isFunction("undefined");     // false
     * isFunction("1");             // false
     * isFunction("aa");            // false
     * isFunction(new Date());      // false
     * isFunction(1);               // false
     * isFunction("");              // false
     * isFunction(myFunction);      // true
     * isFunction([]);              // false
     * isFunction(new Array(1));    // false
     * ```
     */
    const isFunction: (value: any) => value is Function;

    /**
     * Identifies whether the current environment appears to be IE
     */
    function isIE(): boolean;

    function isNotNullOrUndefined<T>(value: T): value is T;

    /**
     * Checks if the type of value does not evaluate to true value, handling some special
     * case usages of Boolean(true/false) and new Boolean(true/false).
     * @group Value Check
     * @param value - Value to be checked.
     * @return True if the value is not truthy, false otherwise.
     */
    function isNotTruthy(value: any): boolean;

    function isNotUndefined<T>(value: T): value is T;

    /**
     * Checks if the provided value is null, undefined or contains the string value of "undefined".
     * @group Type Identity
     * @group Value Check
     * @param value - The value to check
     * @returns `true` if the value is `null` or `undefined`
     * @example
     * ```ts
     * isNullOrUndefined(null);         // true
     * isNullOrUndefined(undefined);    // true
     * isNullOrUndefined("undefined");  // true
     *
     * let value = null;
     * isNullOrUndefined(value);        // true
     * let value = undefined;
     * isNullOrUndefined(value);        // true
     *
     * isNullOrUndefined("");           // false
     * isNullOrUndefined(0);            // false
     * isNullOrUndefined(new Date());   // false
     * isNullOrUndefined(true);         // false
     * isNullOrUndefined(false);        // false
     * ```
     */
    function isNullOrUndefined(value: any): boolean;

    /**
     * Checks if the type of value is a number.
     * @function
     * @group Type Identity
     * @param value - Value to be checked.
     * @return True if the value is a number, false otherwise.
     */
    const isNumber: (value: any) => value is number;

    /**
     * Checks to see if the past value is an object value
     * @function
     * @group Type Identity
     * @group Object
     * @typeParam T - The object type, defaults to any
     * @param value - The value to check
     * @returns
     */
    function isObject<T>(value: T): value is T;

    /**
     * Returns whether the environment is reporting that we are running in a React Native Environment
     */
    function isReactNative(): boolean;

    function isSafari(userAgentStr?: string): boolean;

    /**
     * Is the parsed traceParent indicating that the trace is currently sampled.
     * @param value - The parsed traceParent value
     * @returns
     */
    function isSampledFlag(value: ITraceParent): boolean;

    /**
     * Checks to see if the past value is a string value
     * @function
     * @group Type Identity
     * @group String
     * @param value - The value to check
     * @returns
     * @example
     * ```ts
     * isString("");            // true
     * isString("null");        // true
     * isString("undefined");   // true
     * isString(String(""));    // true
     *
     * isString(null);          // false
     * isString(undefined);     // false
     * isString(0);             // false
     * ```
     */
    const isString: (value: any) => value is string;

    /**
     * Checks if the type of value is a symbol.
     *
     * @function
     * @group Symbol
     * @param value - Value to be checked.
     * @return True if the value is a symbol, false otherwise.
     */
    const isSymbol: (value: any) => value is symbol;

    /**
     * Checks if the type of value evaluates to true value, handling some special
     * case usages of Boolean(true/false) and new Boolean(true/false).
     * @group Value Check
     * @param value - Value to be checked.
     * @return True if the value is not truthy, false otherwise.
     */
    function isTruthy(value: any): boolean;

    /**
     * Validate if the provided value object is of the expected type
     * @group Type Identity
     * @param value - The value to check
     * @param theType - The expected type name as a string
     * @returns `true` if the value matches the provided type
     */
    function isTypeof(value: any, theType: string): boolean;

    /**
     * Checks if the provided value is undefined or contains the string value "undefined",
     * if you want to consider the string value as undefined see {@link isStrictUndefined}
     * @group Type Identity
     * @group Value Check
     * @param value - The value to check
     * @returns true if the value is undefined or "undefined", otherwise false
     * @example
     * ```ts
     * isUndefined(undefined);              // true
     * isUndefined("undefined");            // true
     *
     * isUndefined(null);                   // false
     * isUndefined("null");                 // false
     * isUndefined("1");                    // false
     * isUndefined("aa");                   // false
     * isUndefined(new Date());             // false
     * isUndefined(1);                      // false
     * isUndefined("");                     // false
     * isUndefined(_dummyFunction);         // false
     * isUndefined([]);                     // false
     * isUndefined(new Array(1));           // false
     * isUndefined(true);                   // false
     * isUndefined(false);                  // false
     * isUndefined("true");                 // false
     * isUndefined("false");                // false
     * isUndefined(new Boolean(true));      // false
     * isUndefined(new Boolean(false));     // false
     * isUndefined(new Boolean("true"));    // false
     * isUndefined(new Boolean("false"));   // false
     * isUndefined(Boolean(true));          // false
     * isUndefined(Boolean(false));         // false
     * isUndefined(Boolean("true"));        // false
     * isUndefined(Boolean("false"));       // false
     * isUndefined(new RegExp(""));         // false
     * isUndefined(new ArrayBuffer(0));     // false
     * isUndefined(new Error("Test Error"));// false
     * isUndefined(new TypeError("Test TypeError"));    // false
     * isUndefined(new TestError("Test TestError"));    // false
     * isUndefined(_dummyError());          // false
     * isUndefined(Promise.reject());       // false
     * isUndefined(Promise.resolve());      // false
     * isUndefined(new Promise(() => {}));  // false
     * isUndefined(_simplePromise());       // false
     * isUndefined(_simplePromiseLike());   // false
     * isUndefined(Object.create(null));    // false
     * isUndefined(polyObjCreate(null));    // false
     * ```
     */
    function isUndefined(value: any): boolean;

    /**
     * Is the provided W3c span id (aka. parent id) a valid string representation, it must be a 16-character
     * string of lowercase hexadecimal characters, for example, 00f067aa0ba902b7.
     * If all characters are zero (0000000000000000) this is considered an invalid value.
     * @param value - The W3c span id to be validated
     * @returns true if valid otherwise false
     */
    function isValidSpanId(value: string): boolean;

    /**
     * Is the provided W3c Trace Id a valid string representation, it must be a 32-character string
     * of lowercase hexadecimal characters for example, 4bf92f3577b34da6a3ce929d0e0e4736.
     * If all characters as zero (00000000000000000000000000000000) it will be considered an invalid value.
     * @param value - The W3c trace Id to be validated
     * @returns true if valid otherwise false
     */
    function isValidTraceId(value: string): boolean;

    /**
     * Validates that the provided ITraceParent instance conforms to the currently supported specifications
     * @param value - The parsed traceParent value
     * @returns
     */
    function isValidTraceParent(value: ITraceParent): boolean;

    /**
     * Checks if XMLHttpRequest is supported
     * @returns True if supported, otherwise false
     */
    function isXhrSupported(): boolean;

    interface ITelemetryInitializerContainer {
        /**
         * Add a telemetry processor to decorate or drop telemetry events.
         * @param telemetryInitializer - The Telemetry Initializer function
         * @returns - A ITelemetryInitializerHandler to enable the initializer to be removed
         */
        addTelemetryInitializer(telemetryInitializer: TelemetryInitializerFunction): ITelemetryInitializerHandler | void;
    }

    interface ITelemetryInitializerHandler extends ILegacyUnloadHook {
        remove(): void;
    }

    /**
     * Telemety item supported in Core
     */
    interface ITelemetryItem {
        /**
         * CommonSchema Version of this SDK
         */
        ver?: string;
        /**
         * Unique name of the telemetry item
         */
        name: string;
        /**
         * Timestamp when item was sent
         */
        time?: string;
        /**
         * Identifier of the resource that uniquely identifies which resource data is sent to
         */
        iKey?: string;
        /**
         * System context properties of the telemetry item, example: ip address, city etc
         */
        ext?: {
            [key: string]: any;
        };
        /**
         * System context property extensions that are not global (not in ctx)
         */
        tags?: Tags;
        /**
         * Custom data
         */
        data?: ICustomProperties;
        /**
         * Telemetry type used for part B
         */
        baseType?: string;
        /**
         * Based on schema for part B
         */
        baseData?: {
            [key: string]: any;
        };
    }

    /**
     * Configuration provided to SDK core
     */
    interface ITelemetryPlugin extends ITelemetryProcessor, IPlugin {
        /**
         * Set next extension for telemetry processing, this is now optional as plugins should use the
         * processNext() function of the passed IProcessTelemetryContext instead. It is being kept for
         * now for backward compatibility only.
         * @deprecated - Use processNext() function of the passed IProcessTelemetryContext instead
         */
        setNextPlugin?: (next: ITelemetryPlugin | ITelemetryPluginChain) => void;
        /**
         * Priority of the extension
         */
        readonly priority: number;
    }

    /**
     * Configuration provided to SDK core
     */
    interface ITelemetryPluginChain extends ITelemetryProcessor {
        /**
         * Returns the underlying plugin that is being proxied for the processTelemetry call
         */
        getPlugin: () => ITelemetryPlugin;
        /**
         * Returns the next plugin
         */
        getNext: () => ITelemetryPluginChain;
        /**
         * This plugin is being unloaded and should remove any hooked events and cleanup any global/scoped values, after this
         * call the plugin will be removed from the telemetry processing chain and will no longer receive any events..
         * @param unloadCtx - The unload context to use for this call.
         * @param unloadState - The details of the unload operation
         */
        unload?: (unloadCtx: IProcessTelemetryUnloadContext, unloadState: ITelemetryUnloadState) => void;
    }

    interface ITelemetryProcessor {
        /**
         * Call back for telemetry processing before it it is sent
         * @param env - This is the current event being reported
         * @param itemCtx - This is the context for the current request, ITelemetryPlugin instances
         * can optionally use this to access the current core instance or define / pass additional information
         * to later plugins (vs appending items to the telemetry item)
         */
        processTelemetry: (env: ITelemetryItem, itemCtx?: IProcessTelemetryContext) => void;
        /**
         * The the plugin should re-evaluate configuration and update any cached configuration settings or
         * plugins. If implemented this method will be called whenever a plugin is added or removed and if
         * the configuration has bee updated.
         * @param updateCtx - This is the context that should be used during updating.
         * @param updateState - The details / state of the update process, it holds details like the current and previous configuration.
         * @returns boolean - true if the plugin has or will call updateCtx.processNext(), this allows the plugin to perform any asynchronous operations.
         */
        update?: (updateCtx: IProcessTelemetryUpdateContext, updateState: ITelemetryUpdateState) => void | boolean;
    }

    interface ITelemetryUnloadState {
        reason: TelemetryUnloadReason;
        isAsync: boolean;
        flushComplete?: boolean;
    }

    interface ITelemetryUpdateState {
        /**
         * Identifies the reason for the update notification, this is a bitwise numeric value
         */
        reason: TelemetryUpdateReason;
        /**
         * This is a new active configuration that should be used
         */
        cfg?: IConfiguration;
        /**
         * The detected changes
         */
        oldCfg?: IConfiguration;
        /**
         * If this is a configuration update this was the previous configuration that was used
         */
        newConfig?: IConfiguration;
        /**
         * Was the new config requested to be merged with the existing config
         */
        merge?: boolean;
        /**
         * This holds a collection of plugins that have been added (if the reason identifies that one or more plugins have been added)
         */
        added?: IPlugin[];
        /**
         * This holds a collection of plugins that have been removed (if the reason identifies that one or more plugins have been removed)
         */
        removed?: IPlugin[];
    }

    /**
     * Internal interface
     * Simple internal timeout wrapper
     * @internal
     * @since version after 3.1.0
     */
    interface _ITimeoutOverrideWrapper {
        set: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => ITimerHandler;
    }

    /**
     * A Timer handler which is returned from {@link scheduleTimeout} which contains functions to
     * cancel or restart (refresh) the timeout function.
     *
     * @since 0.4.4
     * @group Timer
     */
    interface ITimerHandler {
        /**
         * Cancels a timeout that was previously scheduled, after calling this function any previously
         * scheduled timer will not execute.
         * @example
         * ```ts
         * let theTimer = scheduleTimeout(...);
         * theTimer.cancel();
         * ```
         */
        cancel(): void;
        /**
         * Reschedules the timer to call its callback at the previously specified duration
         * adjusted to the current time. This is useful for refreshing a timer without allocating
         * a new JavaScript object.
         *
         * Using this on a timer that has already called its callback will reactivate the timer.
         * Calling on a timer that has not yet executed will just reschedule the current timer.
         * @example
         * ```ts
         * let theTimer = scheduleTimeout(...);
         * // The timer will be restarted (if already executed) or rescheduled (if it has not yet executed)
         * theTimer.refresh();
         * ```
         */
        refresh(): ITimerHandler;
        /**
         * When called, requests that the event loop not exit so long when the ITimerHandler is active.
         * Calling timer.ref() multiple times will have no effect. By default, all ITimerHandler objects
         * will create "ref'ed" instances, making it normally unnecessary to call timer.ref() unless
         * timer.unref() had been called previously.
         * @since 0.7.0
         * @returns the ITimerHandler instance
         * @example
         * ```ts
         * let theTimer = createTimeout(...);
         *
         * // Make sure the timer is referenced (the default) so that the runtime (Node) does not terminate
         * // if there is a waiting referenced timer.
         * theTimer.ref();
         * ```
         */
        ref(): this;
        /**
         * When called, the any active ITimerHandler instance will not require the event loop to remain
         * active (Node.js). If there is no other activity keeping the event loop running, the process may
         * exit before the ITimerHandler instance callback is invoked. Calling timer.unref() multiple times
         * will have no effect.
         * @since 0.7.0
         * @returns the ITimerHandler instance
         * @example
         * ```ts
         * let theTimer = createTimeout(...);
         *
         * // Unreference the timer so that the runtime (Node) may terminate if nothing else is running.
         * theTimer.unref();
         * ```
         */
        unref(): this;
        /**
         * If true, any running referenced `ITimerHandler` instance will keep the Node.js event loop active.
         * @since 0.7.0
         * @example
         * ```ts
         * let theTimer = createTimeout(...);
         *
         * // Unreference the timer so that the runtime (Node) may terminate if nothing else is running.
         * theTimer.unref();
         * let hasRef = theTimer.hasRef(); // false
         *
         * theTimer.ref();
         * hasRef = theTimer.hasRef(); // true
         * ```
         */
        hasRef(): boolean;
        /**
         * Gets or Sets a flag indicating if the underlying timer is currently enabled and running.
         * Setting the enabled flag to the same as it's current value has no effect, setting to `true`
         * when already `true` will not {@link ITimerHandler.refresh | refresh}() the timer.
         * And setting to `false` will {@link ITimerHandler.cancel | cancel}() the timer.
         * @since 0.8.1
         * @example
         * ```ts
         * let theTimer = createTimeout(...);
         *
         * // Check if enabled
         * theTimer.enabled; // false
         *
         * // Start the timer
         * theTimer.enabled = true;     // Same as calling refresh()
         * theTimer.enabled; //true
         *
         * // Has no effect as it's already running
         * theTimer.enabled = true;
         *
         * // Will refresh / restart the time
         * theTimer.refresh()
         *
         * let theTimer = scheduleTimeout(...);
         *
         * // Check if enabled
         * theTimer.enabled; // true
         * ```
         */
        enabled: boolean;
    }

    /**
     * This interface represents the components of a W3C traceparent header
     */
    interface ITraceParent {
        /**
         * The version of the definition, this MUST be a string with a length of 2 and only contain lowercase
         * hexadecimal characters. A value of 'ff' is considered to be an invalid version.
         */
        version: string;
        /**
         * This is the ID of the whole trace forest and is used to uniquely identify a distributed trace
         * through a system. It is represented as a 32-character string of lowercase hexadecimal characters,
         * for example, 4bf92f3577b34da6a3ce929d0e0e4736.
         * All characters as zero (00000000000000000000000000000000) is considered an invalid value.
         */
        traceId: string;
        /**
         * This is the ID of the current request as known by the caller (in some tracing systems, this is also
         * known as the parent-id, where a span is the execution of a client request). It is represented as an
         * 16-character string of lowercase hexadecimal characters, for example, 00f067aa0ba902b7.
         * All bytes as zero (0000000000000000) is considered an invalid value.
         */
        spanId: string;
        /**
         * An 8-bit value of flags that controls tracing such as sampling, trace level, etc. These flags are
         * recommendations given by the caller rather than strict rules to follow.
         * As this is a bit field, you cannot interpret flags by decoding the hex value and looking at the resulting
         * number. For example, a flag 00000001 could be encoded as 01 in hex, or 09 in hex if present with the flag
         * 00001000. A common mistake in bit fields is forgetting to mask when interpreting flags.
         */
        traceFlags: number;
    }

    interface IUnloadableComponent {
        /**
         * Teardown / Unload hook to allow implementations to perform some additional unload operations before the BaseTelemetryPlugin
         * finishes it's removal.
         * @param unloadCtx - This is the context that should be used during unloading.
         * @param unloadState - The details / state of the unload process, it holds details like whether it should be unloaded synchronously or asynchronously and the reason for the unload.
         * @param asyncCallback - An optional callback that the plugin must call if it returns true to inform the caller that it has completed any async unload/teardown operations.
         * @returns boolean - true if the plugin has or will call asyncCallback, this allows the plugin to perform any asynchronous operations.
         */
        _doUnload?: (unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState, asyncCallback?: () => void) => void | boolean;
    }

    interface IUnloadHandlerContainer {
        add: (handler: UnloadHandler) => void;
        run: (itemCtx: IProcessTelemetryUnloadContext, unloadState: ITelemetryUnloadState) => void;
    }

    /**
     * An interface which provides automatic removal during unloading of the component
     */
    interface IUnloadHook {
        /**
         * Self remove the referenced component
         */
        rm: () => void;
    }

    /**
     * Interface which identifiesAdd this hook so that it is automatically removed during unloading
     * @param hooks - The single hook or an array of IInstrumentHook objects
     */
    interface IUnloadHookContainer {
        add: (hooks: IUnloadHook | IUnloadHook[] | Iterator<IUnloadHook> | ILegacyUnloadHook | ILegacyUnloadHook[] | Iterator<ILegacyUnloadHook>) => void;
        run: (logger?: IDiagnosticLogger) => void;
    }

    interface IWatchDetails<T = IConfiguration> {
        /**
         * The current config object
         */
        cfg: T;
        /**
         * Set the value against the provided config/name with the value, the property
         * will be converted to be dynamic (if not already) as long as the provided config
         * is already a tracked dynamic object.
         * @throws TypeError if the provided config is not a monitored dynamic config
         */
        set: <C, V>(theConfig: C, name: string, value: V) => V;
        /**
         * Set default values for the config if not present.
         * @param theConfig - The configuration object to set default on (if missing)
         * @param defaultValues - The default values to apply to the config
         */
        setDf: <C>(theConfig: C, defaultValues: IConfigDefaults<C>) => C;
        /**
         * Set this named property of the target as referenced, which will cause any object or array instance
         * to be updated in-place rather than being entirely replaced. All other values will continue to be replaced.
         * @returns The referenced properties current value
         */
        ref: <C, V = any>(target: C, name: string) => V;
        /**
         * Set this named property of the target as read-only, which will block this single named property from
         * ever being changed for the target instance.
         * This does NOT freeze or seal the instance, it just stops the direct re-assignment of the named property,
         * if the value is a non-primitive (ie. an object or array) it's properties will still be mutable.
         * @returns The referenced properties current value
         */
        rdOnly: <C, V = any>(target: C, name: string) => V;
    }

    interface IWatcherHandler<T = IConfiguration> extends IUnloadHook {
        fn: WatcherFunction<T>;
        rm: () => void;
    }

    interface IXDomainRequest extends XMLHttpRequestEventTarget {
        readonly responseText: string;
        send(payload: string): void;
        open(method: string, url: string): void;
        timeout: number;
        contentType: string;
        addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
        addEventListener(type: "load" | "timeout", listener: (ev: Event) => any, useCapture?: boolean): void;
        addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
    }

    /**
     * The IXHROverride interface overrides the way HTTP requests are sent.
     */
    interface IXHROverride {
        sendPOST: SendPOSTFunction;
    }

    const LoggingSeverity: EnumValue<typeof eLoggingSeverity>;

    type LoggingSeverity = number | eLoggingSeverity;

    /**
     * Logs a message to the internal queue.
     * @param logger - The Diagnostic Logger instance to use.
     * @param severity  - The severity of the log message
     * @param message - The message to log.
     */
    function _logInternalMessage(logger: IDiagnosticLogger, severity: LoggingSeverity, message: _InternalLogMessage): void;

    function mergeEvtNamespace(theNamespace: string, namespaces?: string | string[] | null): string | string[];

    const MinChannelPriorty: number;

    /**
     * Generate a random 32-bit number between (0x000000..0xFFFFFFFF) or (-0x80000000..0x7FFFFFFF), using MWC (Multiply with carry)
     * instead of Math.random() defaults to un-signed.
     * Used as a replacement random generator for IE to avoid issues with older IE instances.
     * @param signed - True to return a signed 32-bit number (-0x80000000..0x7FFFFFFF) otherwise an unsigned one (0x000000..0xFFFFFFFF)
     */
    function mwcRandom32(signed?: boolean): number;

    /**
     * Seed the MWC random number generator with the specified seed or a random value
     * @param value - optional the number to used as the seed, if undefined, null or zero a random value will be chosen
     */
    function mwcRandomSeed(value?: number): void;

    function newGuid(): string;

    /**
     * Generate random base64 id string.
     * The default length is 22 which is 132-bits so almost the same as a GUID but as base64 (the previous default was 5)
     * @param maxLength - Optional value to specify the length of the id to be generated, defaults to 22
     */
    function newId(maxLength?: number): string;

    /**
     * Validates that the string name conforms to the JS IdentifierName specification and if not
     * normalizes the name so that it would. This method does not identify or change any keywords
     * meaning that if you pass in a known keyword the same value will be returned.
     * This is a simplified version
     * @param name - The name to validate
     */
    function normalizeJsName(name: string): string;

    /**
     * Class to manage sending notifications to all the listeners.
     */
    class NotificationManager implements INotificationManager {
        readonly listeners: INotificationListener[];
        constructor(config?: IConfiguration);
        /**
         * Adds a notification listener.
         * @param listener - The notification listener to be added.
         */
        addNotificationListener(listener: INotificationListener): void;
        /**
         * Removes all instances of the listener.
         * @param listener - AWTNotificationListener to remove.
         */
        removeNotificationListener(listener: INotificationListener): void;
        /**
         * Notification for events sent.
         * @param events - The array of events that have been sent.
         */
        eventsSent(events: ITelemetryItem[]): void;
        /**
         * Notification for events being discarded.
         * @param events - The array of events that have been discarded by the SDK.
         * @param reason - The reason for which the SDK discarded the events. The EventsDiscardedReason
         * constant should be used to check the different values.
         */
        eventsDiscarded(events: ITelemetryItem[], reason: number): void;
        /**
         * [Optional] A function called when the events have been requested to be sent to the sever.
         * @param sendReason - The reason why the event batch is being sent.
         * @param isAsync - A flag which identifies whether the requests are being sent in an async or sync manner.
         */
        eventsSendRequest?(sendReason: number, isAsync: boolean): void;
        /**
         * [Optional] This event is sent if you have enabled perf events, they are primarily used to track internal performance testing and debugging
         * the event can be displayed via the debug plugin extension.
         * @param perfEvent - The performance event object containing relevant performance data.
         */
        perfEvent?(perfEvent: IPerfEvent): void;
        /**
         * Unload and remove any state that this INotificationManager may be holding, this is generally called when the
         * owning SDK is being unloaded.
         * @param isAsync - Can the unload be performed asynchronously (default)
         * @returns If the unload occurs synchronously then nothing should be returned, if happening asynchronously then
         * the function should return an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * / Promise to allow any listeners to wait for the operation to complete.
         */
        unload?(isAsync?: boolean): void | IPromise<void>;
        /**
         * [Optional] A function called when the offline events have been stored to the persistent storage
         * @param events - events that are stored in the persistent storage
         */
        offlineEventsStored?(events: ITelemetryItem[]): void;
        /**
         * [Optional] A function called when the offline events have been sent from the persistent storage
         * @param batch - payload data that is sent from the persistent storage
         */
        offlineBatchSent?(batch: IPayloadData): void;
        /**
         * [Optional] A function called when the offline events have been dropped from the persistent storage
         * @param cnt - count of batches dropped
         * @param reason - the reason why the batches is dropped
         * @since v3.1.1
         */
        offlineBatchDrop?(cnt: number, reason?: number): void;
    }

    /**
     * Try to define get/set object property accessors for the target object/prototype, this will provide compatibility with
     * existing API definition when run within an ES5+ container that supports accessors but still enable the code to be loaded
     * and executed in an ES3 container, providing basic IE8 compatibility.
     * @deprecated It is recommended that you use {@link objDefine} instead {@link objDefineAccessors} as this internally creates
     * the {@link ObjDefinePropDescriptor} definition based on your provided arguments. And only using a minimum set of functions
     * reduces your overall bundle size.
     * @group Object
     * @param target - The object on which to define the property.
     * @param prop - The name of the property to be defined or modified.
     * @param getProp - The getter function to wire against the getter.
     * @param setProp - The setter function to wire against the setter.
     * @param configurable - Can the value be changed, defaults to true
     * @param enumerable - Should this get property be enumerable, defaults to true.
     * @returns The object that was passed to the function
     */
    function objDefineAccessors<T, V = any>(target: T, prop: PropertyKey, getProp?: (() => V) | null, setProp?: ((v: V) => void) | null, configurable?: boolean, enumerable?: boolean): T;

    /**
     * Pass in the objects to merge as arguments, this will only "merge" (extend) properties that are owned by the object.
     * It will NOT merge inherited or non-enumerable properties.
     * @param obj1 - object to merge.  Set this argument to 'true' for a deep extend.
     * @param obj2 - object to merge.
     * @param obj3 - object to merge.
     * @param obj4 - object to merge.
     * @param obj5 - object to merge.
     * @returns The extended first object.
     */
    function objExtend<T2, T3, T4, T5, T6>(deepExtend?: boolean, obj2?: T2, obj3?: T3, obj4?: T4, obj5?: T5, obj6?: T6): T2 & T3 & T4 & T5 & T6;

    function objExtend<T1, T2, T3, T4, T5, T6>(obj1?: T1, obj2?: T2, obj3?: T3, obj4?: T4, obj5?: T5, obj6?: T6): T1 & T2 & T3 & T4 & T5 & T6;

    /**
     * Calls the provided `callbackFn` function once for each key in an object. This is equivelent to `arrForEach(Object.keys(theObject), callbackFn)` or
     * if not using the array helper `Object.keys(theObject).forEach(callbackFn)` except that this helper avoid creating a temporary of the object
     * keys before iterating over them and like the `arrForEach` helper you CAN stop or break the iteration by returning -1 from the `callbackFn` function.
     * @group Object
     * @typeParam T - The object type
     * @param callbackfn - A function that accepts up to two arguments, the key name and the current value of the property represented by the key.
     * @param thisArg - [Optional] An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, null or undefined
     * the object will be used as the this value.
     * @example
     * ```ts
     * function performAction<T>(target: T, source: any) {
     *    if (!isNullOrUndefined(source)) {
     *        objForEachKey(source, (key, value) => {
     *            // Set the target with a reference to the same value with the same name
     *            target[key] = value;
     *        });
     *    }
     *
     *    return target;
     * }
     * ```
     */
    function objForEachKey<T>(theObject: T, callbackfn: (key: string, value: T[keyof T]) => void | number, thisArg?: any): void;

    /**
     * The `objFreeze()` method freezes an object. A frozen object can no longer be changed; freezing an object
     * prevents new properties from being added to it, existing properties from being removed, prevents changing the
     * enumerability, configurability, or writability of existing properties, and prevents the values of existing
     * properties from being changed. In addition, freezing an object also prevents its prototype from being changed.
     * `objFreeze()` returns the same object that was passed in.
     *
     * Nothing can be added to or removed from the properties set of a frozen object. Any attempt to do so will fail,
     * either silently or by throwing a TypeError exception (most commonly, but not exclusively, when in strict mode).
     *
     * For data properties of a frozen object, values cannot be changed, the writable and configurable attributes are
     * set to false. Accessor properties (getters and setters) work the same (and still give the illusion that you are
     * changing the value). Note that values that are objects can still be modified, unless they are also frozen. As
     * an object, an array can be frozen; after doing so, its elements cannot be altered and no elements can be added
     * to or removed from the array.
     *
     * `objFreeze()` returns the same object that was passed into the function. It does not create a frozen copy.
     * @function
     * @group Object
     * @param value - The object to freeze.
     * @returns The object that was passed to the function.
     */
    const objFreeze: <T>(value: T) => T;

    /**
     * The `objKeys()` method returns an array of a given object's own enumerable property names, iterated in
     * the same order that a normal loop would.
     *
     * objKeys() returns an array whose elements are strings corresponding to the enumerable properties found
     * directly upon object. The ordering of the properties is the same as that given by looping over the
     * properties of the object manually.
     * @function
     * @group Object
     * @param value - The object to obtain a copy of the keys from
     * @returns An array of the properties names for the value object.
     * @example
     * ```ts
     * // simple array
     * const arr = ['a', 'b', 'c'];
     * console.log(objKeys(arr)); // console: ['0', '1', '2']
     *
     * // array-like object
     * const obj = { 0: 'a', 1: 'b', 2: 'c' };
     * console.log(objKeys(obj)); // console: ['0', '1', '2']
     *
     * // array-like object with random key ordering
     * const anObj = { 100: 'a', 2: 'b', 7: 'c' };
     * console.log(objKeys(anObj)); // console: ['2', '7', '100']
     *
     * // getFoo is a property which isn't enumerable
     * const myObj = objCreate({}, {
     *   getFoo: {
     *     value() { return this.foo; }
     *   }
     * });
     * myObj.foo = 1;
     * console.log(objKeys(myObj)); // console: ['foo']
     * ```
     */
    const objKeys: (value: any) => string[];

    /**
     * The `objSeal()` method seals an object, preventing new properties from being added to it and marking all
     * existing properties as non-configurable. Values of present properties can still be changed as long as they
     * are writable.
     * @function
     * @group Object
     * @param value - The object which should be sealed.
     * @returns The object being sealed.
     */
    const objSeal: <T>(value: T) => T;

    /**
     * The `objToString()` method returns a string representing the object. This explicitly
     * always calls the `Object.prototype.toString()` method.
     *
     * An object's toString() method is most commonly invoked when that object undergoes:
     * - explicit type conversion to a string (for example, String(myObject))
     * - implicit type coercion into a string (for example, myObject + "hello world")
     *
     * @group Object
     * @param value - The object to be converted into a string
     * @returns A string representation of the object
     * @example
     * ```ts
     * objToString(new Date()); // [object Date]
     * objToString(new String()); // [object String]
     *
     * // Math has its Symbol.toStringTag
     * objToString(Math); // [object Math]
     *
     * objToString(undefined); // [object Undefined]
     * objToString(null); // [object Null]
     * ```
     */
    function objToString(value: any): string;

    type OnCompleteCallback = (status: number, headers: {
        [headerName: string]: string;
    }, response?: string) => void;

    /**
     * Watch and track changes for accesses to the current config, the provided config MUST already be
     * a dynamic config or a child accessed via the dynamic config
     * @param logger - The logger instance to use if there is no existing handler
     * @returns A watcher handler instance that can be used to remove itself when being unloaded
     * @throws TypeError if the provided config is not a dynamic config instance
     */
    function onConfigChange<T = IConfiguration>(config: T, configHandler: WatcherFunction<T>, logger?: IDiagnosticLogger): IWatcherHandler<T>;

    /**
     * Create and open an XMLHttpRequest object
     * @param method - The request method
     * @param urlString - The url
     * @param withCredentials - Option flag indicating that credentials should be sent
     * @param disabled - Optional flag indicating that the XHR object should be marked as disabled and not tracked (default is false)
     * @param isSync - Optional flag indicating if the instance should be a synchronous request (defaults to false)
     * @param timeout - Optional value identifying the timeout value that should be assigned to the XHR request
     * @returns A new opened XHR request
     */
    function openXhr(method: string, urlString: string, withCredentials?: boolean, disabled?: boolean, isSync?: boolean, timeout?: number): XMLHttpRequest;

    /**
     * A helper function to assist with JIT performance for objects that have properties added / removed dynamically
     * this is primarily for chromium based browsers and has limited effects on Firefox and none of IE. Only call this
     * function after you have finished "updating" the object, calling this within loops reduces or defeats the benefits.
     * This helps when iterating using for..in, objKeys() and objForEach()
     * @param theObject - The object to be optimized if possible
     */
    function optimizeObject<T>(theObject: T): T;

    /**
     * Parses the response from the backend.
     * @param response - XMLHttpRequest or XDomainRequest response
     */
    function parseResponse(response: any, diagLog?: IDiagnosticLogger): IBackendResponse;

    /**
     * Attempt to parse the provided string as a W3C TraceParent header value (https://www.w3.org/TR/trace-context/#traceparent-header)
     *
     * @param value - The value to be parsed
     * @param selectIdx - If the found value is comma separated which is the preferred entry to select, defaults to the first
     * @returns
     */
    function parseTraceParent(value: string, selectIdx?: number): ITraceParent;

    class PerfEvent implements IPerfEvent {
        static ParentContextKey: string;
        static ChildrenContextKey: string;
        /**
         * The name of the event
         */
        name: string;
        /**
         * The start time of the event in ms
         */
        start: number;
        /**
         * The payload (contents) of the perfEvent, may be null or only set after the event has completed depending on
         * the runtime environment.
         */
        payload: any;
        /**
         * Is this occurring from an asynchronous event
         */
        isAsync: boolean;
        /**
         * Identifies the total inclusive time spent for this event, including the time spent for child events,
         * this will be undefined until the event is completed
         */
        time?: number;
        /**
         * Identifies the exclusive time spent in for this event (not including child events),
         * this will be undefined until the event is completed.
         */
        exTime?: number;
        /**
         * Identifies whether this event is a child event of a parent
         */
        isChildEvt: () => boolean;
        getCtx?: (key: string) => any | null | undefined;
        setCtx?: (key: string, value: any) => void;
        complete: () => void;
        constructor(name: string, payloadDetails: () => any, isAsync: boolean);
    }

    class PerfManager implements IPerfManager {
        /**
         * General bucket used for execution context set and retrieved via setCtx() and getCtx.
         * Defined as private so it can be visualized via the DebugPlugin
         */
        // private ctx;
        constructor(manager?: INotificationManager);
        /**
         * Create a new event and start timing, the manager may return null/undefined to indicate that it does not
         * want to monitor this source event.
         * @param src - The source name of the event
         * @param payloadDetails - An optional callback function to fetch the payload details for the event.
         * @param isAsync - Is the event occurring from a async event
         */
        create(src: string, payload?: any, isAsync?: boolean): IPerfEvent | null | undefined;
        /**
         * Complete the perfEvent and fire any notifications.
         * @param perfEvent - Fire the event which will also complete the passed event
         */
        fire(perfEvent: IPerfEvent): void;
        /**
         * Set an execution context value
         * @param key - The context key name
         * @param value - The value
         */
        setCtx(key: string, value: any): void;
        /**
         * Get the execution context value
         * @param key - The context key
         */
        getCtx(key: string): any;
    }

    /**
     * Returns the number of milliseconds that has elapsed since the time origin, if
     * the runtime does not support the `performance` API it will fallback to return
     * the number of milliseconds since the unix epoch.
     *
     * @since 0.4.4
     * @group Timer
     *
     * @returns The number of milliseconds as a `DOMHighResTimeStamp` double value or
     * an integer depending on the runtime.
     * @example
     * ```ts
     * let now = perfNow();
     * ```
     */
    function perfNow(): number;

    function prependTransports(theTransports: TransportType[], newTransports: TransportType | TransportType[]): TransportType[];

    /**
     * This class will be removed!
     * @deprecated use createProcessTelemetryContext() instead
     */
    class ProcessTelemetryContext implements IProcessTelemetryContext {
        /**
         * Gets the current core config instance
         */
        getCfg: () => IConfiguration;
        getExtCfg: <T>(identifier: string, defaultValue?: IConfigDefaults<T>) => T;
        getConfig: (identifier: string, field: string, defaultValue?: number | string | boolean | string[] | RegExp[] | Function) => number | string | boolean | string[] | RegExp[] | Function;
        /**
         * Returns the IAppInsightsCore instance for the current request
         */
        core: () => IAppInsightsCore;
        /**
         * Returns the current IDiagnosticsLogger for the current request
         */
        diagLog: () => IDiagnosticLogger;
        /**
         * Helper to allow inherited classes to check and possibly shortcut executing code only
         * required if there is a nextPlugin
         */
        hasNext: () => boolean;
        /**
         * Returns the next configured plugin proxy
         */
        getNext: () => ITelemetryPluginChain;
        /**
         * Helper to set the next plugin proxy
         */
        setNext: (nextCtx: ITelemetryPluginChain) => void;
        /**
         * Call back for telemetry processing before it it is sent
         * @param env - This is the current event being reported
         * @param itemCtx - This is the context for the current request, ITelemetryPlugin instances
         * can optionally use this to access the current core instance or define / pass additional information
         * to later plugins (vs appending items to the telemetry item)
         * @returns boolean (true) if there is no more plugins to process otherwise false or undefined (void)
         */
        processNext: (env: ITelemetryItem) => boolean | void;
        /**
         * Synchronously iterate over the context chain running the callback for each plugin, once
         * every plugin has been executed via the callback, any associated onComplete will be called.
         * @param callback - The function call for each plugin in the context chain
         */
        iterate: <T extends ITelemetryPlugin = ITelemetryPlugin>(callback: (plugin: T) => void) => void;
        /**
         * Create a new context using the core and config from the current instance
         * @param plugins - The execution order to process the plugins, if null or not supplied
         *                  then the current execution order will be copied.
         * @param startAt - The plugin to start processing from, if missing from the execution
         *                  order then the next plugin will be NOT set.
         */
        createNew: (plugins?: IPlugin[] | ITelemetryPluginChain, startAt?: IPlugin) => IProcessTelemetryContext;
        /**
         * Set the function to call when the current chain has executed all processNext or unloadNext items.
         */
        onComplete: (onComplete: () => void) => void;
        /**
         * Creates a new Telemetry Item context with the current config, core and plugin execution chain
         * @param plugins - The plugin instances that will be executed
         * @param config - The current config
         * @param core - The current core instance
         */
        constructor(pluginChain: ITelemetryPluginChain, config: IConfiguration, core: IAppInsightsCore, startAt?: IPlugin);
    }

    /**
     * Effectively assigns all enumerable properties (not just own properties) and functions (including inherited prototype) from
     * the source object to the target, it attempts to use proxy getters / setters (if possible) and proxy functions to avoid potential
     * implementation issues by assigning prototype functions as instance ones
     *
     * This method is the primary method used to "update" the snippet proxy with the ultimate implementations.
     *
     * Special ES3 Notes:
     * Updates (setting) of direct property values on the target or indirectly on the source object WILL NOT WORK PROPERLY, updates to the
     * properties of "referenced" object will work (target.context.newValue = 10 =\> will be reflected in the source.context as it's the
     * same object). ES3 Failures: assigning target.myProp = 3 -\> Won't change source.myProp = 3, likewise the reverse would also fail.
     * @param target - The target object to be assigned with the source properties and functions
     * @param source - The source object which will be assigned / called by setting / calling the targets proxies
     * @param chkSet - An optional callback to determine whether a specific property/function should be proxied
     */
    function proxyAssign<T, S>(target: T, source: S, chkSet?: (name: string, isFunc?: boolean, source?: S, target?: T) => boolean): T;

    /**
     * Creates a proxy function on the target which internally will call the source version with all arguments passed to the target method.
     *
     * @param target - The target object to be assigned with the source properties and functions
     * @param name - The function name that will be added on the target
     * @param source - The source object which will be assigned / called by setting / calling the targets proxies
     * @param theFunc - The function name on the source that will be proxied on the target
     * @param overwriteTarget - If `false` this will not replace any pre-existing name otherwise (the default) it will overwrite any existing name
     */
    function proxyFunctionAs<T, S>(target: T, name: string, source: S | (() => S), theFunc: (keyof S), overwriteTarget?: boolean): void;

    /**
     * Creates proxy functions on the target which internally will call the source version with all arguments passed to the target method.
     *
     * @param target - The target object to be assigned with the source properties and functions
     * @param source - The source object which will be assigned / called by setting / calling the targets proxies
     * @param functionsToProxy - An array of function names that will be proxied on the target
     * @param overwriteTarget - If false this will not replace any pre-existing name otherwise (the default) it will overwrite any existing name
     */
    function proxyFunctions<T, S>(target: T, source: S | (() => S), functionsToProxy: (keyof S)[], overwriteTarget?: boolean): T;

    /**
     * generate a random 32-bit number (0x000000..0xFFFFFFFF) or (-0x80000000..0x7FFFFFFF), defaults un-unsigned.
     * @param signed - True to return a signed 32-bit number (-0x80000000..0x7FFFFFFF) otherwise an unsigned one (0x000000..0xFFFFFFFF)
     */
    function random32(signed?: boolean): number;

    /**
     * Generate a random value between 0 and maxValue, max value should be limited to a 32-bit maximum.
     * So maxValue(16) will produce a number from 0..16 (range of 17)
     * @param maxValue - The max value for the range
     */
    function randomValue(maxValue: number): number;

    /**
     * This defines the handler function for when a promise is rejected.
     * @param value - This is the value passed as part of resolving the Promise
     * @return This may return a value, another Promise or void. @see {@link https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html#then | IPromise.then} for how the value is handled.
     */
    type RejectedPromiseHandler<T = never> = (((reason: any) => T | IPromise<T> | PromiseLike<T>) | undefined | null);

    /**
     * Trys to remove event handler(s) for the specified event/namespace to the window, body and document
     * @param eventName - The name of the event, with optional namespaces or just the namespaces,
     * such as "click", "click.mynamespace" or ".mynamespace"
     * @param callback - The callback function that needs to be removed from the given event, when using a
     * namespace (with or without a qualifying event) this may be null to remove all previously attached event handlers
     * otherwise this will only remove events with this specific handler.
     * @param evtNamespace - [Optional] Namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace.
     */
    function removeEventHandler(eventName: string, callback: any, evtNamespace?: string | string[] | null): void;

    /**
     * Remove the listener from the array of events
     * @param events - An string array of event names to bind the listener to
     * @param listener - The event callback to call when the event is triggered
     * @param evtNamespace - [Optional] Namespace(s) to append to the event listeners so they can be uniquely identified and removed based on this namespace.
     */
    function removeEventListeners(events: string[], listener: any, evtNamespace?: string | string[]): void;

    /**
     * Removes the pageHide event listeners added by addPageHideEventListener, because the 'visibilitychange' uses
     * an internal proxy to detect the visibility state you SHOULD use a unique namespace when calling addPageHideEventListener
     * as the remove ignores the listener argument for the 'visibilitychange' event.
     * @param listener - The specific listener to remove for the 'pageshow' event only (ignored for 'visibilitychange')
     * @param evtNamespace - The unique namespace used when calling addPageShowEventListener
     */
    function removePageHideEventListener(listener: any, evtNamespace?: string | string[] | null): void;

    /**
     * Removes the pageShow event listeners added by addPageShowEventListener, because the 'visibilitychange' uses
     * an internal proxy to detect the visibility state you SHOULD use a unique namespace when calling addPageShowEventListener
     * as the remove ignores the listener argument for the 'visibilitychange' event.
     * @param listener - The specific listener to remove for the 'pageshow' event only (ignored for 'visibilitychange')
     * @param evtNamespace - The unique namespace used when calling addPageShowEventListener
     */
    function removePageShowEventListener(listener: any, evtNamespace?: string | string[] | null): void;

    /**
     * Remove any matching 'beforeunload', 'unload' and 'pagehide' events that may have been added via addEventListener,
     * addEventListeners, addPageUnloadEventListener or addPageHideEventListener.
     * @param listener - The specific event callback to to be removed
     * @param evtNamespace - [Optional] Namespace(s) uniquely identified and removed based on this namespace.
     * @returns true - when at least one of the events was registered otherwise false
     */
    function removePageUnloadEventListener(listener: any, evtNamespace?: string | string[]): void;

    /**
     * This defines the handler function for when a promise is resolved.
     * @param value - This is the value passed as part of resolving the Promise
     * @return This may return a value, another Promise or void. @see {@link https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html#then | IPromise.then} for how the value is handled.
     */
    type ResolvedPromiseHandler<T, TResult1 = T> = (((value: T) => TResult1 | IPromise<TResult1> | PromiseLike<TResult1>) | undefined | null);

    /**
     * Run the unload function of the target object if it exists
     * @param target - The target object that contains the unload function
     * @param isAsync - The caller identifies whether it is expecting the operation to complete synchronously or asynchronously. Even
     * if the caller is not waiting the operation may still be performed asynchronously depending on the component and the reverse is
     * also true.
     * @returns The result of the target function
     */
    function runTargetUnload<T>(target: {
        unload?: (isAsync?: boolean) => T;
    }, isAsync?: boolean): T;

    /**
     * Helper to return the ICookieMgr from the core (if not null/undefined) or a default implementation
     * associated with the configuration or a legacy default.
     * @param core - The AppInsightsCore instance to get the cookie manager from
     * @param config - The config to use if the core is not available
     * @returns
     */
    function safeGetCookieMgr(core: IAppInsightsCore, config?: IConfiguration): ICookieMgr;

    function safeGetLogger(core: IAppInsightsCore, config?: IConfiguration): IDiagnosticLogger;

    interface scriptsInfo {
        url: string;
        crossOrigin?: string;
        async?: boolean;
        defer?: boolean;
        referrerPolicy?: string;
    }

    function sendCustomEvent(evtName: string, cfg?: any, customDetails?: any): boolean;

    /**
     * This Internal component
     * Manager SendPost functions
     * SendPostManger
     * @internal for internal use only
     */
    class SenderPostManager {
        constructor();
        initialize(config: _ISendPostMgrConfig, diagLog: IDiagnosticLogger): void;
        /**
         * Get size of current sync fetch payload
         */
        getSyncFetchPayload(): number;
        /**
         * reset Config
         * @returns True if set is successfully
         */
        SetConfig(config: _ISendPostMgrConfig): boolean;
        /**
         * Get current xhr instance
         */
        getSenderInst(transports: TransportType[], sync?: boolean): IXHROverride;
        /**
         * Get current fallback sender instance
         */
        getFallbackInst(): IXHROverride;
        _doTeardown(unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState): void;
        preparePayload(callback: (processedPayload: IPayloadData) => void, zipPayload: boolean, payload: IPayloadData, isSync: boolean): void;
    }

    /**
     * SendPOSTFunction type defines how an HTTP POST request is sent to an ingestion server
     * @param payload - The payload object that should be sent, contains the url, bytes/string and headers for the request
     * @param oncomplete - The function to call once the request has completed whether a success, failure or timeout
     * @param sync - A boolean flag indicating whether the request should be sent as a synchronous request.
     */
    type SendPOSTFunction = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => void | IPromise<boolean>;

    /**
     * The EventsDiscardedReason enumeration contains a set of values that specify the reason for discarding an event.
     */
    const enum SendRequestReason {
        /**
         * No specific reason was specified
         */
        Undefined = 0,
        /**
         * Events are being sent based on the normal event schedule / timer.
         */
        NormalSchedule = 1,
        /**
         * A manual flush request was received
         */
        ManualFlush = 1,
        /**
         * Unload event is being processed
         */
        Unload = 2,
        /**
         * The event(s) being sent are sync events
         */
        SyncEvent = 3,
        /**
         * The Channel was resumed
         */
        Resumed = 4,
        /**
         * The event(s) being sent as a retry
         */
        Retry = 5,
        /**
         * The SDK is unloading
         */
        SdkUnload = 6,
        /**
         * Maximum batch size would be exceeded
         */
        MaxBatchSize = 10,
        /**
         * The Maximum number of events have already been queued
         */
        MaxQueuedEvents = 20
    }

    /**
     * Enable the lookup of test mock objects if requested
     * @param enabled - A flag to enable or disable the mock
     */
    function setEnableEnvMocks(enabled: boolean): void;

    /**
     * Set the global performance manager to use when there is no core instance or it has not been initialized yet.
     * @param perfManager - The IPerfManager instance to use when no performance manager is supplied.
     */
    function setGblPerfMgr(perfManager: IPerfManager): void;

    /**
     * Sets the provided value on the target instance using the field name when the provided chk function returns true, the chk
     * function will only be called if the new value is no equal to the original value.
     * @param target - The target object
     * @param field - The key of the target
     * @param value - The value to set
     * @param valChk - [Optional] Callback to check the value that if supplied will be called check if the new value can be set
     * @param srcChk - [Optional] Callback to check to original value that if supplied will be called if the new value should be set (if allowed)
     * @returns The existing or new value, depending what was set
     */
    function setValue<T, K extends keyof T>(target: T, field: K, value: T[K], valChk?: ((value: T[K]) => boolean) | null, srcChk?: ((value: T[K]) => boolean) | null): T[K];

    function sortPlugins<T = IPlugin>(plugins: T[]): T[];

    /**
     * A simple wrapper (for minification support) to check if the value contains the search string.
     * @param value - The string value to check for the existence of the search value
     * @param search - The value search within the value
     */
    function strContains(value: string, search: string): boolean;

    /**
     * This method lets you determine whether or not a string ends with another string. This method is case-sensitive.
     * @function
     * @group String
     * @param value - The value to be checked
     * @param searchString - The characters to be searched for at the end of `value` string.
     * @param length - If provided, it is used as the length of `value`. Defaults to value.length.
     */
    const strEndsWith: (value: string, searchString: string, length?: number) => boolean;

    const strFunction = "function";

    const strObject = "object";

    const strPrototype = "prototype";

    /**
     * This method lets you determine whether or not a string begins with another string. This method is case-sensitive.
     * @function
     * @group String
     * @param value - The value to be checked
     * @param searchString - The characters to be searched for at the start of the string
     * @param position - [Optional] The position in this string at which to begin searching for `searchString`.
     * Defaults to 0
     * @returns `true` if the given characters are found at the beginning of the string; otherwise, `false`.
     */
    const strStartsWith: (value: string, searchString: string, position?: number) => boolean;

    /**
     * The trim() method removes whitespace from both ends of a string and returns a new string,
     * without modifying the original string. Whitespace in this context is all the whitespace
     * characters (space, tab, no-break space, etc.) and all the line terminator characters
     * (LF, CR, etc.).
     *
     * @function
     * @group String
     * @param value - The string value to be trimmed.
     * @returns A new string representing str stripped of whitespace from both its beginning and end.
     * If neither the beginning or end of str has any whitespace, a new string is still returned (essentially
     * a copy of str), with no exception being thrown.
     * To return a new string with whitespace trimmed from just one end, use `strTrimStart()` or `strTrimEnd()`.
     */
    const strTrim: (value: string) => string;

    const strUndefined = "undefined";

    interface Tags {
        [key: string]: any;
    }

    type TelemetryInitializerFunction = <T extends ITelemetryItem>(item: T) => boolean | void;

    /**
     * The TelemetryUnloadReason enumeration contains the possible reasons for why a plugin is being unloaded / torndown().
     */
    const enum TelemetryUnloadReason {
        /**
         * Teardown has been called without any context.
         */
        ManualTeardown = 0,
        /**
         * Just this plugin is being removed
         */
        PluginUnload = 1,
        /**
         * This instance of the plugin is being removed and replaced
         */
        PluginReplace = 2,
        /**
         * The entire SDK is being unloaded
         */
        SdkUnload = 50
    }

    /**
     * The TelemetryUpdateReason enumeration contains a set of bit-wise values that specify the reason for update request.
     */
    const enum TelemetryUpdateReason {
        /**
         * Unknown.
         */
        Unknown = 0,
        /**
         * The configuration has ben updated or changed
         */
        ConfigurationChanged = 1,
        /**
         * One or more plugins have been added
         */
        PluginAdded = 16,
        /**
         * One or more plugins have been removed
         */
        PluginRemoved = 32
    }

    /**
     * Test hook for setting the maximum number of unload hooks and calling a monitor function when the hooks are added or removed
     * This allows for automatic test failure when the maximum number of unload hooks is exceeded
     * @param maxHooks - The maximum number of unload hooks
     * @param addMonitor - The monitor function to call when hooks are added or removed
     */
    function _testHookMaxUnloadHooksCb(maxHooks?: number, addMonitor?: (state: string, hooks: Array<ILegacyUnloadHook | IUnloadHook>) => void): void;

    /**
     * Throws an Aggregation Error which includes all of the errors that led to this error occurring
     * @param message - The message describing the aggregation error (the sourceError details are added to this)
     * @param sourceErrors - An array of the errors that caused this situation
     */
    function throwAggregationError(message: string, sourceErrors: any[]): never;

    /**
     * Throw an error exception with the specified optional message
     * @group Error
     * @param message - The optional message to include in the error
     */
    function throwError(message?: string): never;

    /**
     * This is a helper method which will call throwInternal on the passed logger, will throw exceptions in
     * debug mode or attempt to log the error as a console warning. This helper is provided mostly to better
     * support minification as logger.throwInternal() will not compress the publish "throwInternal" used throughout
     * the code.
     * @param logger - The Diagnostic Logger instance to use.
     * @param severity - The severity of the log message
     * @param message  - The log message.
     */
    function _throwInternal(logger: IDiagnosticLogger, severity: LoggingSeverity, msgId: _InternalMessageId, msg: string, properties?: Object, isUserAct?: boolean): void;

    /**
     * Convert a date to I.S.O. format in IE8
     */
    function toISOString(date: Date): string;

    const enum TransportType {
        /**
         * Use the default available api
         */
        NotSet = 0,
        /**
         * Use XMLHttpRequest or XMLDomainRequest if available
         */
        Xhr = 1,
        /**
         * Use the Fetch api if available
         */
        Fetch = 2,
        /**
         * Use sendBeacon api if available
         */
        Beacon = 3
    }

    function uaDisallowsSameSiteNone(userAgent: string): boolean;

    const Undefined = "undefined";

    /**
     * Teardown / Unload helper to perform teardown/unloading operations for the provided components synchronously or asynchronously, this will call any
     * _doTeardown() or _doUnload() functions on the provided components to allow them to finish removal.
     * @param components - The components you want to unload
     * @param unloadCtx - This is the context that should be used during unloading.
     * @param unloadState - The details / state of the unload process, it holds details like whether it should be unloaded synchronously or asynchronously and the reason for the unload.
     * @param asyncCallback - An optional callback that the plugin must call if it returns true to inform the caller that it has completed any async unload/teardown operations.
     * @returns boolean - true if the plugin has or will call asyncCallback, this allows the plugin to perform any asynchronous operations.
     */
    function unloadComponents(components: any | IUnloadableComponent[], unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState, asyncCallback?: () => void): void | boolean;

    type UnloadHandler = (itemCtx: IProcessTelemetryUnloadContext, unloadState: ITelemetryUnloadState) => void;

    function useXDomainRequest(): boolean | undefined;

    /**
     * This is a helper method which will call warnToConsole on the passed logger with the provided message.
     * @param logger - The Diagnostic Logger instance to use.
     * @param message  - The log message.
     */
    function _warnToConsole(logger: IDiagnosticLogger, message: string): void;

    type WatcherFunction<T = IConfiguration> = (details: IWatchDetails<T>) => void;

}