/*
 * Application Insights JavaScript SDK - Channel, 3.3.10
 * Copyright (c) Microsoft and contributors. All rights reserved.
 */
var _a, _b;
import { __assignFn as __assign, __extendsFn as __extends } from "@microsoft/applicationinsights-shims";
import dynamicProto from "@microsoft/dynamicproto-js";
import { BreezeChannelIdentifier, DEFAULT_BREEZE_ENDPOINT, DEFAULT_BREEZE_PATH, Event, Exception, Metric, PageView, PageViewPerformance, ProcessLegacy, RemoteDependencyData, RequestHeaders, SampleRate, Trace, createOfflineListener, isInternalApplicationInsightsEndpoint, utlCanUseSessionStorage, utlSetStoragePrefix } from "@microsoft/applicationinsights-common";
import { ActiveStatus, BaseTelemetryPlugin, SenderPostManager, _throwInternal, _warnToConsole, arrForEach, cfgDfBoolean, cfgDfValidate, createProcessTelemetryContext, createUniqueNamespace, dateNow, dumpObj, formatErrorMessageXdr, formatErrorMessageXhr, getExceptionName, getIEVersion, isArray, isBeaconsSupported, isFeatureEnabled, isFetchSupported, isNullOrUndefined, mergeEvtNamespace, objExtend, onConfigChange, parseResponse, prependTransports, runTargetUnload } from "@microsoft/applicationinsights-core-js";
import { createPromise, doAwait, doAwaitResponse } from "@nevware21/ts-async";
import { getInst, isFunction, isNumber, isPromiseLike, isString, isTruthy, mathFloor, mathMax, mathMin, objDeepFreeze, objDefine, scheduleTimeout } from "@nevware21/ts-utils";
import { DependencyEnvelopeCreator, EventEnvelopeCreator, ExceptionEnvelopeCreator, MetricEnvelopeCreator, PageViewEnvelopeCreator, PageViewPerformanceEnvelopeCreator, TraceEnvelopeCreator } from "./EnvelopeCreator";
import { ArraySendBuffer, SessionStorageSendBuffer } from "./SendBuffer";
import { Serializer } from "./Serializer";
import { Sample } from "./TelemetryProcessors/Sample";
import { _DYN_ALWAYS_USE_XHR_OVERR4, _DYN_BASE_TYPE, _DYN_BUFFER_OVERRIDE, _DYN_CLEAR, _DYN_CLEAR_SENT, _DYN_COUNT, _DYN_CUSTOM_HEADERS, _DYN_DIAG_LOG, _DYN_DISABLE_SEND_BEACON_7, _DYN_EMIT_LINE_DELIMITED_0, _DYN_ENABLE_SESSION_STORA5, _DYN_ENDPOINT_URL, _DYN_ENQUEUE, _DYN_GET_SENDER_INST, _DYN_INITIALIZE, _DYN_INSTRUMENTATION_KEY, _DYN_IS_BEACON_API_DISABL3, _DYN_ITEMS_ACCEPTED, _DYN_ITEMS_RECEIVED, _DYN_LENGTH, _DYN_MARK_AS_SENT, _DYN_MAX_BATCH_SIZE_IN_BY1, _DYN_ONUNLOAD_DISABLE_BEA2, _DYN_ONUNLOAD_DISABLE_FET6, _DYN_PUSH, _DYN_SAMPLE_RATE, _DYN_TAGS, _DYN_TRIGGER_SEND, _DYN__BUFFER, _DYN__ON_ERROR, _DYN__ON_PARTIAL_SUCCESS, _DYN__ON_SUCCESS, _DYN__SENDER } from "./__DynamicConstants";
var UNDEFINED_VALUE = undefined;
var EMPTY_STR = "";
var FetchSyncRequestSizeLimitBytes = 65000; // approx 64kb (the current Edge, Firefox and Chrome max limit)
function _getResponseText(xhr) {
    try {
        return xhr.responseText;
    }
    catch (e) {
        // Best effort, as XHR may throw while XDR wont so just ignore
    }
    return null;
}
function isOverrideFn(httpXHROverride) {
    return httpXHROverride && httpXHROverride.sendPOST;
}
var defaultAppInsightsChannelConfig = objDeepFreeze((_a = {
        // Use the default value (handles empty string in the configuration)
        endpointUrl: cfgDfValidate(isTruthy, DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH)
    },
    _a[_DYN_EMIT_LINE_DELIMITED_0 /* @min:emitLineDelimitedJson */] = cfgDfBoolean(),
    _a.maxBatchInterval = 15000,
    _a[_DYN_MAX_BATCH_SIZE_IN_BY1 /* @min:maxBatchSizeInBytes */] = 102400,
    _a.disableTelemetry = cfgDfBoolean(),
    _a[_DYN_ENABLE_SESSION_STORA5 /* @min:enableSessionStorageBuffer */] = cfgDfBoolean(true),
    _a.isRetryDisabled = cfgDfBoolean(),
    _a[_DYN_IS_BEACON_API_DISABL3 /* @min:isBeaconApiDisabled */] = cfgDfBoolean(true),
    _a[_DYN_DISABLE_SEND_BEACON_7 /* @min:disableSendBeaconSplit */] = cfgDfBoolean(true),
    _a.disableXhr = cfgDfBoolean(),
    _a[_DYN_ONUNLOAD_DISABLE_FET6 /* @min:onunloadDisableFetch */] = cfgDfBoolean(),
    _a[_DYN_ONUNLOAD_DISABLE_BEA2 /* @min:onunloadDisableBeacon */] = cfgDfBoolean(),
    _a[_DYN_INSTRUMENTATION_KEY /* @min:instrumentationKey */] = UNDEFINED_VALUE,
    _a.namePrefix = UNDEFINED_VALUE,
    _a.samplingPercentage = cfgDfValidate(_chkSampling, 100),
    _a[_DYN_CUSTOM_HEADERS /* @min:customHeaders */] = UNDEFINED_VALUE,
    _a.convertUndefined = UNDEFINED_VALUE,
    _a.eventsLimitInMem = 10000,
    _a[_DYN_BUFFER_OVERRIDE /* @min:bufferOverride */] = false,
    _a.httpXHROverride = { isVal: isOverrideFn, v: UNDEFINED_VALUE },
    _a[_DYN_ALWAYS_USE_XHR_OVERR4 /* @min:alwaysUseXhrOverride */] = cfgDfBoolean(),
    _a.transports = UNDEFINED_VALUE,
    _a.retryCodes = UNDEFINED_VALUE,
    _a.corsPolicy = UNDEFINED_VALUE,
    _a.maxRetryCnt = { isVal: isNumber, v: 10 },
    _a));
var CrossOriginResourcePolicyHeader = "X-Set-Cross-Origin-Resource-Policy";
function _chkSampling(value) {
    return !isNaN(value) && value > 0 && value <= 100;
}
var EnvelopeTypeCreator = (_b = {},
    _b[Event.dataType] = EventEnvelopeCreator,
    _b[Trace.dataType] = TraceEnvelopeCreator,
    _b[PageView.dataType] = PageViewEnvelopeCreator,
    _b[PageViewPerformance.dataType] = PageViewPerformanceEnvelopeCreator,
    _b[Exception.dataType] = ExceptionEnvelopeCreator,
    _b[Metric.dataType] = MetricEnvelopeCreator,
    _b[RemoteDependencyData.dataType] = DependencyEnvelopeCreator,
    _b);
var Sender = /** @class */ (function (_super) {
    __extends(Sender, _super);
    function Sender() {
        var _this = _super.call(this) || this;
        _this.priority = 1001;
        _this.identifier = BreezeChannelIdentifier;
        // Don't set the defaults here, set them in the _initDefaults() as this is also called during unload
        var _consecutiveErrors; // How many times in a row a retryable error condition has occurred.
        var _retryAt; // The time to retry at in milliseconds from 1970/01/01 (this makes the timer calculation easy).
        var _lastSend; // The time of the last send operation.
        var _paused; // Flag indicating that the sending should be paused
        var _timeoutHandle; // Handle to the timer for delayed sending of batches of data.
        var _serializer;
        var _stamp_specific_redirects;
        var _headers;
        var _syncFetchPayload = 0; // Keep track of the outstanding sync fetch payload total (as sync fetch has limits)
        var _syncUnloadSender; // The identified sender to use for the synchronous unload stage
        var _offlineListener;
        var _evtNamespace;
        var _endpointUrl;
        var _orgEndpointUrl;
        var _maxBatchSizeInBytes;
        var _beaconSupported;
        var _beaconOnUnloadSupported;
        var _beaconNormalSupported;
        var _customHeaders;
        var _disableTelemetry;
        var _instrumentationKey;
        var _convertUndefined;
        var _isRetryDisabled;
        var _maxBatchInterval;
        var _sessionStorageUsed;
        var _bufferOverrideUsed;
        var _namePrefix;
        var _enableSendPromise;
        var _alwaysUseCustomSend;
        var _disableXhr;
        var _fetchKeepAlive;
        var _xhrSend;
        var _fallbackSend;
        var _disableBeaconSplit;
        var _sendPostMgr;
        var _retryCodes;
        var _zipPayload;
        dynamicProto(Sender, _this, function (_self, _base) {
            _initDefaults();
            _self.pause = function () {
                _clearScheduledTimer();
                _paused = true;
            };
            _self.resume = function () {
                if (_paused) {
                    _paused = false;
                    _retryAt = null;
                    // flush if we have exceeded the max-size already
                    _checkMaxSize();
                    _setupTimer();
                }
            };
            _self.flush = function (isAsync, callBack, sendReason) {
                if (isAsync === void 0) { isAsync = true; }
                if (!_paused) {
                    // Clear the normal schedule timer as we are going to try and flush ASAP
                    _clearScheduledTimer();
                    try {
                        var result_1 = _self[_DYN_TRIGGER_SEND /* @min:%2etriggerSend */](isAsync, null, sendReason || 1 /* SendRequestReason.ManualFlush */);
                        // Handles non-promise and always called if the returned promise resolves or rejects
                        return doAwaitResponse(result_1, function (rsp) {
                            if (callBack) {
                                callBack(!rsp.rejected);
                                return true;
                            }
                            // When async=true and no callback, return a promise
                            if (isAsync) {
                                return createPromise(function (resolve) {
                                    resolve(!rsp.rejected);
                                });
                            }
                            return result_1;
                        });
                    }
                    catch (e) {
                        _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 1 /* eLoggingSeverity.CRITICAL */, 22 /* _eInternalMessageId.FlushFailed */, "flush failed, telemetry will not be collected: " + getExceptionName(e), { exception: dumpObj(e) });
                    }
                }
            };
            _self.onunloadFlush = function () {
                if (!_paused) {
                    if (_beaconSupported || _alwaysUseCustomSend) {
                        try {
                            return _self[_DYN_TRIGGER_SEND /* @min:%2etriggerSend */](true, _doUnloadSend, 2 /* SendRequestReason.Unload */);
                        }
                        catch (e) {
                            _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 1 /* eLoggingSeverity.CRITICAL */, 20 /* _eInternalMessageId.FailedToSendQueuedTelemetry */, "failed to flush with beacon sender on page unload, telemetry will not be collected: " + getExceptionName(e), { exception: dumpObj(e) });
                        }
                    }
                    else {
                        _self.flush(false);
                    }
                }
            };
            _self.addHeader = function (name, value) {
                _headers[name] = value;
            };
            _self[_DYN_INITIALIZE /* @min:%2einitialize */] = function (config, core, extensions, pluginChain) {
                if (_self.isInitialized()) {
                    _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 1 /* eLoggingSeverity.CRITICAL */, 28 /* _eInternalMessageId.SenderNotInitialized */, "Sender is already initialized");
                }
                _base[_DYN_INITIALIZE /* @min:%2einitialize */](config, core, extensions, pluginChain);
                var identifier = _self.identifier;
                _serializer = new Serializer(core.logger);
                _consecutiveErrors = 0;
                _retryAt = null;
                _lastSend = 0;
                _self[_DYN__SENDER /* @min:%2e_sender */] = null;
                _stamp_specific_redirects = 0;
                var diagLog = _self[_DYN_DIAG_LOG /* @min:%2ediagLog */]();
                _evtNamespace = mergeEvtNamespace(createUniqueNamespace("Sender"), core.evtNamespace && core.evtNamespace());
                _offlineListener = createOfflineListener(_evtNamespace);
                // This function will be re-called whenever any referenced configuration is changed
                _self._addHook(onConfigChange(config, function (details) {
                    var config = details.cfg;
                    if (config.storagePrefix) {
                        utlSetStoragePrefix(config.storagePrefix);
                    }
                    var ctx = createProcessTelemetryContext(null, config, core);
                    // getExtCfg only finds undefined values from core
                    var senderConfig = ctx.getExtCfg(identifier, defaultAppInsightsChannelConfig);
                    var curExtUrl = senderConfig[_DYN_ENDPOINT_URL /* @min:%2eendpointUrl */];
                    // if it is not inital change (_endpointUrl has value)
                    // if current sender endpoint url is not changed directly
                    // means ExtCfg is not changed directly
                    // then we need to monitor endpoint url changes from core
                    if (_endpointUrl && curExtUrl === _endpointUrl) {
                        var coreUrl = config[_DYN_ENDPOINT_URL /* @min:%2eendpointUrl */];
                        // if core endpoint url is changed
                        if (coreUrl && coreUrl !== curExtUrl) {
                            // and endpoint promise changes is handled by this as well
                            senderConfig[_DYN_ENDPOINT_URL /* @min:%2eendpointUrl */] = coreUrl;
                        }
                    }
                    var csStream = getInst("CompressionStream");
                    // Determine whether to enable payload compression (zipping).
                    _zipPayload = isFeatureEnabled("zipPayload", config, false);
                    if (!isFunction(csStream)) {
                        _zipPayload = false;
                    }
                    var corsPolicy = senderConfig.corsPolicy;
                    if (corsPolicy) {
                        if (corsPolicy === "same-origin" || corsPolicy === "same-site" || corsPolicy === "cross-origin") {
                            _this.addHeader(CrossOriginResourcePolicyHeader, corsPolicy);
                        }
                    }
                    else {
                        delete _headers[CrossOriginResourcePolicyHeader];
                    }
                    if (isPromiseLike(senderConfig[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */])) {
                        // if it is promise, means the endpoint url is from core.endpointurl
                        senderConfig[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */] = config[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */];
                    }
                    objDefine(_self, "_senderConfig", {
                        g: function () {
                            return senderConfig;
                        }
                    });
                    // Only update the endpoint if the original config !== the current config
                    // This is so any redirect endpointUrl is not overwritten
                    if (_orgEndpointUrl !== senderConfig[_DYN_ENDPOINT_URL /* @min:%2eendpointUrl */]) {
                        if (_orgEndpointUrl) {
                            // TODO: add doc to remind users to flush before changing endpoint, otherwise all unsent payload will be sent to new endpoint
                        }
                        _endpointUrl = _orgEndpointUrl = senderConfig[_DYN_ENDPOINT_URL /* @min:%2eendpointUrl */];
                    }
                    // or is not string
                    if (core.activeStatus() === ActiveStatus.PENDING) {
                        // waiting for core promises to be resolved
                        // NOTE: if active status is set to pending, stop sending, clear timer here
                        _self.pause();
                    }
                    else if (core.activeStatus() === ActiveStatus.ACTIVE) {
                        // core status changed from pending to other status
                        _self.resume();
                    }
                    if (_customHeaders && _customHeaders !== senderConfig[_DYN_CUSTOM_HEADERS /* @min:%2ecustomHeaders */]) {
                        // Removing any previously defined custom headers as they have changed
                        arrForEach(_customHeaders, function (customHeader) {
                            delete _headers[customHeader.header];
                        });
                    }
                    _maxBatchSizeInBytes = senderConfig[_DYN_MAX_BATCH_SIZE_IN_BY1 /* @min:%2emaxBatchSizeInBytes */];
                    _beaconSupported = (senderConfig[_DYN_ONUNLOAD_DISABLE_BEA2 /* @min:%2eonunloadDisableBeacon */] === false || senderConfig[_DYN_IS_BEACON_API_DISABL3 /* @min:%2eisBeaconApiDisabled */] === false) && isBeaconsSupported();
                    _beaconOnUnloadSupported = senderConfig[_DYN_ONUNLOAD_DISABLE_BEA2 /* @min:%2eonunloadDisableBeacon */] === false && isBeaconsSupported();
                    _beaconNormalSupported = senderConfig[_DYN_IS_BEACON_API_DISABL3 /* @min:%2eisBeaconApiDisabled */] === false && isBeaconsSupported();
                    _alwaysUseCustomSend = senderConfig[_DYN_ALWAYS_USE_XHR_OVERR4 /* @min:%2ealwaysUseXhrOverride */];
                    _disableXhr = !!senderConfig.disableXhr;
                    _retryCodes = senderConfig.retryCodes;
                    var bufferOverride = senderConfig[_DYN_BUFFER_OVERRIDE /* @min:%2ebufferOverride */];
                    var canUseSessionStorage = !!senderConfig[_DYN_ENABLE_SESSION_STORA5 /* @min:%2eenableSessionStorageBuffer */] &&
                        (!!bufferOverride || utlCanUseSessionStorage());
                    var namePrefix = senderConfig.namePrefix;
                    //Note: emitLineDelimitedJson and eventsLimitInMem is directly accessed via config in senderBuffer
                    //Therefore, if canUseSessionStorage is not changed, we do not need to re initialize a new one
                    var shouldUpdate = (canUseSessionStorage !== _sessionStorageUsed)
                        || (canUseSessionStorage && (_namePrefix !== namePrefix)) // prefixName is only used in session storage
                        || (canUseSessionStorage && (_bufferOverrideUsed !== bufferOverride));
                    if (_self[_DYN__BUFFER /* @min:%2e_buffer */]) {
                        // case1 (Pre and Now enableSessionStorageBuffer settings are same)
                        // if namePrefix changes, transfer current buffer to new buffer
                        // else no action needed
                        //case2 (Pre and Now enableSessionStorageBuffer settings are changed)
                        // transfer current buffer to new buffer
                        if (shouldUpdate) {
                            try {
                                _self[_DYN__BUFFER /* @min:%2e_buffer */] = _self[_DYN__BUFFER /* @min:%2e_buffer */].createNew(diagLog, senderConfig, canUseSessionStorage);
                            }
                            catch (e) {
                                _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 1 /* eLoggingSeverity.CRITICAL */, 12 /* _eInternalMessageId.FailedAddingTelemetryToBuffer */, "failed to transfer telemetry to different buffer storage, telemetry will be lost: " + getExceptionName(e), { exception: dumpObj(e) });
                            }
                        }
                        _checkMaxSize();
                    }
                    else {
                        _self[_DYN__BUFFER /* @min:%2e_buffer */] = canUseSessionStorage
                            ? new SessionStorageSendBuffer(diagLog, senderConfig) : new ArraySendBuffer(diagLog, senderConfig);
                    }
                    _namePrefix = namePrefix;
                    _sessionStorageUsed = canUseSessionStorage;
                    _bufferOverrideUsed = bufferOverride;
                    _fetchKeepAlive = !senderConfig[_DYN_ONUNLOAD_DISABLE_FET6 /* @min:%2eonunloadDisableFetch */] && isFetchSupported(true);
                    _disableBeaconSplit = !!senderConfig[_DYN_DISABLE_SEND_BEACON_7 /* @min:%2edisableSendBeaconSplit */];
                    _self._sample = new Sample(senderConfig.samplingPercentage, diagLog);
                    _instrumentationKey = senderConfig[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */];
                    if (!isPromiseLike(_instrumentationKey) && !_validateInstrumentationKey(_instrumentationKey, config)) {
                        _throwInternal(diagLog, 1 /* eLoggingSeverity.CRITICAL */, 100 /* _eInternalMessageId.InvalidInstrumentationKey */, "Invalid Instrumentation key " + _instrumentationKey);
                    }
                    _customHeaders = senderConfig[_DYN_CUSTOM_HEADERS /* @min:%2ecustomHeaders */];
                    if (isString(_endpointUrl) && !isInternalApplicationInsightsEndpoint(_endpointUrl) && _customHeaders && _customHeaders[_DYN_LENGTH /* @min:%2elength */] > 0) {
                        arrForEach(_customHeaders, function (customHeader) {
                            _this.addHeader(customHeader.header, customHeader.value);
                        });
                    }
                    else {
                        _customHeaders = null;
                    }
                    _enableSendPromise = senderConfig.enableSendPromise;
                    var sendPostConfig = _getSendPostMgrConfig();
                    // only init it once
                    if (!_sendPostMgr) {
                        _sendPostMgr = new SenderPostManager();
                        _sendPostMgr[_DYN_INITIALIZE /* @min:%2einitialize */](sendPostConfig, diagLog);
                    }
                    else {
                        _sendPostMgr.SetConfig(sendPostConfig);
                    }
                    var customInterface = senderConfig.httpXHROverride;
                    var httpInterface = null;
                    var syncInterface = null;
                    // User requested transport(s) values > Beacon > Fetch > XHR
                    // Beacon would be filtered out if user has set disableBeaconApi to true at _getSenderInterface
                    var theTransports = prependTransports([3 /* TransportType.Beacon */, 1 /* TransportType.Xhr */, 2 /* TransportType.Fetch */], senderConfig.transports);
                    httpInterface = _sendPostMgr && _sendPostMgr[_DYN_GET_SENDER_INST /* @min:%2egetSenderInst */](theTransports, false);
                    var xhrInterface = _sendPostMgr && _sendPostMgr.getFallbackInst();
                    _xhrSend = function (payload, isAsync) {
                        return _doSend(xhrInterface, payload, isAsync);
                    };
                    _fallbackSend = function (payload, isAsync) {
                        return _doSend(xhrInterface, payload, isAsync, false);
                    };
                    httpInterface = _alwaysUseCustomSend ? customInterface : (httpInterface || customInterface || xhrInterface);
                    _self[_DYN__SENDER /* @min:%2e_sender */] = function (payload, isAsync) {
                        return _doSend(httpInterface, payload, isAsync);
                    };
                    if (_fetchKeepAlive) {
                        // Try and use the fetch with keepalive
                        _syncUnloadSender = _fetchKeepAliveSender;
                    }
                    var syncTransports = prependTransports([3 /* TransportType.Beacon */, 1 /* TransportType.Xhr */], senderConfig.unloadTransports);
                    if (!_fetchKeepAlive) {
                        // remove fetch from theTransports
                        syncTransports = syncTransports.filter(function (transport) { return transport !== 2 /* TransportType.Fetch */; });
                    }
                    syncInterface = _sendPostMgr && _sendPostMgr[_DYN_GET_SENDER_INST /* @min:%2egetSenderInst */](syncTransports, true);
                    syncInterface = _alwaysUseCustomSend ? customInterface : (syncInterface || customInterface);
                    if ((_alwaysUseCustomSend || senderConfig.unloadTransports || !_syncUnloadSender) && syncInterface) {
                        _syncUnloadSender = function (payload, isAsync) {
                            return _doSend(syncInterface, payload, isAsync);
                        };
                    }
                    if (!_syncUnloadSender) {
                        _syncUnloadSender = _xhrSend;
                    }
                    _disableTelemetry = senderConfig.disableTelemetry;
                    _convertUndefined = senderConfig.convertUndefined || UNDEFINED_VALUE;
                    _isRetryDisabled = senderConfig.isRetryDisabled;
                    _maxBatchInterval = senderConfig.maxBatchInterval;
                }));
            };
            _self.processTelemetry = function (telemetryItem, itemCtx) {
                itemCtx = _self._getTelCtx(itemCtx);
                var diagLogger = itemCtx[_DYN_DIAG_LOG /* @min:%2ediagLog */]();
                try {
                    var isValidate = _validate(telemetryItem, diagLogger);
                    if (!isValidate) {
                        return;
                    }
                    var aiEnvelope = _getEnvelope(telemetryItem, diagLogger);
                    if (!aiEnvelope) {
                        return;
                    }
                    // check if the incoming payload is too large, truncate if necessary
                    var payload = _serializer.serialize(aiEnvelope);
                    // flush if we would exceed the max-size limit by adding this item
                    var buffer = _self[_DYN__BUFFER /* @min:%2e_buffer */];
                    _checkMaxSize(payload);
                    var payloadItem = {
                        item: payload,
                        cnt: 0 // inital cnt will always be 0
                    };
                    // enqueue the payload
                    buffer[_DYN_ENQUEUE /* @min:%2eenqueue */](payloadItem);
                    // ensure an invocation timeout is set
                    _setupTimer();
                }
                catch (e) {
                    _throwInternal(diagLogger, 2 /* eLoggingSeverity.WARNING */, 12 /* _eInternalMessageId.FailedAddingTelemetryToBuffer */, "Failed adding telemetry to the sender's buffer, some telemetry will be lost: " + getExceptionName(e), { exception: dumpObj(e) });
                }
                // hand off the telemetry item to the next plugin
                _self.processNext(telemetryItem, itemCtx);
            };
            _self.isCompletelyIdle = function () {
                return !_paused && _syncFetchPayload === 0 && _self._buffer[_DYN_COUNT /* @min:%2ecount */]() === 0;
            };
            _self.getOfflineListener = function () {
                return _offlineListener;
            };
            /**
             * xhr state changes
             */
            _self._xhrReadyStateChange = function (xhr, payload, countOfItemsInPayload) {
                // since version 3.2.0, this function is no-op
                if (_isStringArr(payload)) {
                    return;
                }
                return _xhrReadyStateChange(xhr, payload, countOfItemsInPayload);
            };
            /**
             * Immediately send buffered data
             * @param isAsync - Indicates if the events should be sent asynchronously
             * @param forcedSender - Indicates the forcedSender, undefined if not passed
             */
            _self[_DYN_TRIGGER_SEND /* @min:%2etriggerSend */] = function (isAsync, forcedSender, sendReason) {
                if (isAsync === void 0) { isAsync = true; }
                var result;
                if (!_paused) {
                    try {
                        var buffer = _self[_DYN__BUFFER /* @min:%2e_buffer */];
                        // Send data only if disableTelemetry is false
                        if (!_disableTelemetry) {
                            if (buffer[_DYN_COUNT /* @min:%2ecount */]() > 0) {
                                var payload = buffer.getItems();
                                _notifySendRequest(sendReason || 0 /* SendRequestReason.Undefined */, isAsync);
                                // invoke send
                                if (forcedSender) {
                                    result = forcedSender.call(_self, payload, isAsync);
                                }
                                else {
                                    result = _self[_DYN__SENDER /* @min:%2e_sender */](payload, isAsync);
                                }
                            }
                            // update lastSend time to enable throttling
                            _lastSend = +new Date;
                        }
                        else {
                            buffer[_DYN_CLEAR /* @min:%2eclear */]();
                        }
                        _clearScheduledTimer();
                    }
                    catch (e) {
                        /* Ignore this error for IE under v10 */
                        var ieVer = getIEVersion();
                        if (!ieVer || ieVer > 9) {
                            _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 1 /* eLoggingSeverity.CRITICAL */, 40 /* _eInternalMessageId.TransmissionFailed */, "Telemetry transmission failed, some telemetry will be lost: " + getExceptionName(e), { exception: dumpObj(e) });
                        }
                        // potential place to call countException q3
                    }
                }
                return result;
            };
            _self.getOfflineSupport = function () {
                return {
                    getUrl: function () {
                        return _endpointUrl;
                    },
                    createPayload: _createPayload,
                    serialize: _serialize,
                    batch: _batch,
                    shouldProcess: function (evt) {
                        return !!_validate(evt);
                    }
                };
            };
            _self._doTeardown = function (unloadCtx, unloadState) {
                _self.onunloadFlush();
                runTargetUnload(_offlineListener, false);
                _initDefaults();
            };
            /**
             * error handler
             */
            _self[_DYN__ON_ERROR /* @min:%2e_onError */] = function (payload, message, event) {
                // since version 3.1.3, string[] is no-op
                if (_isStringArr(payload)) {
                    return;
                }
                return _onError(payload, message, event);
            };
            /**
             * partial success handler
             */
            _self[_DYN__ON_PARTIAL_SUCCESS /* @min:%2e_onPartialSuccess */] = function (payload, results) {
                // since version 3.1.3, string[] is no-op
                if (_isStringArr(payload)) {
                    return;
                }
                return _onPartialSuccess(payload, results);
            };
            /**
             * success handler
             */
            _self[_DYN__ON_SUCCESS /* @min:%2e_onSuccess */] = function (payload, countOfItemsInPayload) {
                // since version 3.1.3, string[] is no-op
                if (_isStringArr(payload)) {
                    return;
                }
                return _onSuccess(payload, countOfItemsInPayload);
                //_self._buffer && _self._buffer.clearSent(payload);
            };
            /**
             * xdr state changes
             */
            _self._xdrOnLoad = function (xdr, payload) {
                // since version 3.1.3, string[] is no-op
                if (_isStringArr(payload)) {
                    return;
                }
                return _xdrOnLoad(xdr, payload);
            };
            // function _getStatsBeat() {
            //     let statsBeatConfig: IStatsBeatState = {
            //         cKey: _self._senderConfig.instrumentationKey,
            //         endpoint: _endpointUrl,
            //         sdkVer: EnvelopeCreator.Version,
            //         type: eStatsType.SDK
            //     };
            //     let core = _self.core;
            //     // During page unload the core may have been cleared and some async events may not have been sent yet
            //     // resulting in the core being null. In this case we don't want to create a statsbeat instance
            //     return core ? core.getStatsBeat(statsBeatConfig) : null;
            // }
            function _xdrOnLoad(xdr, payload) {
                var responseText = _getResponseText(xdr);
                if (xdr && (responseText + "" === "200" || responseText === "")) {
                    _consecutiveErrors = 0;
                    _self[_DYN__ON_SUCCESS /* @min:%2e_onSuccess */](payload, 0);
                }
                else {
                    var results = parseResponse(responseText);
                    if (results && results[_DYN_ITEMS_RECEIVED /* @min:%2eitemsReceived */] && results[_DYN_ITEMS_RECEIVED /* @min:%2eitemsReceived */] > results[_DYN_ITEMS_ACCEPTED /* @min:%2eitemsAccepted */]
                        && !_isRetryDisabled) {
                        _self[_DYN__ON_PARTIAL_SUCCESS /* @min:%2e_onPartialSuccess */](payload, results);
                    }
                    else {
                        _self[_DYN__ON_ERROR /* @min:%2e_onError */](payload, formatErrorMessageXdr(xdr));
                    }
                }
            }
            function _getSendPostMgrConfig() {
                try {
                    var onCompleteFuncs = {
                        xdrOnComplete: function (xdr, oncomplete, payload) {
                            var payloadArr = _getPayloadArr(payload);
                            if (!payloadArr) {
                                return;
                            }
                            //const responseText = _getResponseText(xdr);
                            // let statsbeat = _getStatsBeat();
                            // if (statsbeat) {
                            //     if (xdr && (responseText + "" === "200" || responseText === "")) {
                            //         _consecutiveErrors = 0;
                            //         statsbeat.count(200, payload, _endpointUrl);
                            //     } else {
                            //         const results = parseResponse(responseText);
                            //         if (results && results.itemsReceived && results.itemsReceived > results.itemsAccepted
                            //             && !_isRetryDisabled) {
                            //             statsbeat.count(206, payload, _endpointUrl);
                            //         } else {
                            //             statsbeat.count(499, payload, _endpointUrl);
                            //         }
                            //     }
                            // }
                            return _xdrOnLoad(xdr, payloadArr);
                        },
                        fetchOnComplete: function (response, onComplete, resValue, payload) {
                            var payloadArr = _getPayloadArr(payload);
                            if (!payloadArr) {
                                return;
                            }
                            // let statsbeat = _getStatsBeat();
                            // if (statsbeat) {
                            //     statsbeat.count(response.status, payload, _endpointUrl);
                            // }
                            return _checkResponsStatus(response.status, payloadArr, response.url, payloadArr[_DYN_LENGTH /* @min:%2elength */], response.statusText, resValue || "");
                        },
                        xhrOnComplete: function (request, oncomplete, payload) {
                            var payloadArr = _getPayloadArr(payload);
                            if (!payloadArr) {
                                return;
                            }
                            // let statsbeat = _getStatsBeat();
                            // if (statsbeat && request.readyState === 4) {
                            //     statsbeat.count(request.status, payload, _endpointUrl);
                            // }
                            return _xhrReadyStateChange(request, payloadArr, payloadArr[_DYN_LENGTH /* @min:%2elength */]);
                        },
                        beaconOnRetry: function (data, onComplete, canSend) {
                            // let statsbeat = _getStatsBeat();
                            // if (statsbeat) {
                            //     statsbeat.count(499, data, _endpointUrl);
                            // }
                            return _onBeaconRetry(data, onComplete, canSend);
                        }
                    };
                    var config = {
                        enableSendPromise: _enableSendPromise,
                        isOneDs: false,
                        disableCredentials: false,
                        disableXhr: _disableXhr,
                        disableBeacon: !_beaconNormalSupported,
                        disableBeaconSync: !_beaconOnUnloadSupported,
                        senderOnCompleteCallBack: onCompleteFuncs
                    };
                    return config;
                }
                catch (e) {
                    // eslint-disable-next-line no-empty
                }
                return null;
            }
            /**
             * xhr state changes
             */
            function _xhrReadyStateChange(xhr, payload, countOfItemsInPayload) {
                if (xhr.readyState === 4) {
                    _checkResponsStatus(xhr.status, payload, xhr.responseURL, countOfItemsInPayload, formatErrorMessageXhr(xhr), _getResponseText(xhr) || xhr.response);
                }
            }
            /**
             * error handler
             */
            function _onError(payload, message, event) {
                _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 2 /* eLoggingSeverity.WARNING */, 26 /* _eInternalMessageId.OnError */, "Failed to send telemetry.", { message: message });
                _self._buffer && _self._buffer[_DYN_CLEAR_SENT /* @min:%2eclearSent */](payload);
            }
            /**
             * partial success handler
             */
            function _onPartialSuccess(payload, results) {
                var failed = [];
                var retry = [];
                // Iterate through the reversed array of errors so that splicing doesn't have invalid indexes after the first item.
                var errors = results.errors.reverse();
                for (var _i = 0, errors_1 = errors; _i < errors_1.length; _i++) {
                    var error = errors_1[_i];
                    var extracted = payload.splice(error.index, 1)[0];
                    if (_isRetriable(error.statusCode)) {
                        retry[_DYN_PUSH /* @min:%2epush */](extracted);
                    }
                    else {
                        // All other errors, including: 402 (Monthly quota exceeded) and 439 (Too many requests and refresh cache).
                        failed[_DYN_PUSH /* @min:%2epush */](extracted);
                    }
                }
                if (payload[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    _self[_DYN__ON_SUCCESS /* @min:%2e_onSuccess */](payload, results[_DYN_ITEMS_ACCEPTED /* @min:%2eitemsAccepted */]);
                }
                if (failed[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    _self[_DYN__ON_ERROR /* @min:%2e_onError */](failed, formatErrorMessageXhr(null, ["partial success", results[_DYN_ITEMS_ACCEPTED /* @min:%2eitemsAccepted */], "of", results.itemsReceived].join(" ")));
                }
                if (retry[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    _resendPayload(retry);
                    _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, "Partial success. " +
                        "Delivered: " + payload[_DYN_LENGTH /* @min:%2elength */] + ", Failed: " + failed[_DYN_LENGTH /* @min:%2elength */] +
                        ". Will retry to send " + retry[_DYN_LENGTH /* @min:%2elength */] + " our of " + results[_DYN_ITEMS_RECEIVED /* @min:%2eitemsReceived */] + " items");
                }
            }
            /**
             * success handler
             */
            function _onSuccess(payload, countOfItemsInPayload) {
                _self._buffer && _self._buffer[_DYN_CLEAR_SENT /* @min:%2eclearSent */](payload);
            }
            function _getPayloadArr(payload) {
                try {
                    if (payload) {
                        var internalPayload = payload;
                        var arr = internalPayload.oriPayload;
                        if (arr && arr[_DYN_LENGTH /* @min:%2elength */]) {
                            return arr;
                        }
                        return null;
                    }
                }
                catch (e) {
                    // eslint-disable-next-line no-empty
                }
                return null;
            }
            function _validate(telemetryItem, diagLogger) {
                if (_disableTelemetry) {
                    // Do not send/save data
                    return false;
                }
                // validate input
                if (!telemetryItem) {
                    diagLogger && _throwInternal(diagLogger, 1 /* eLoggingSeverity.CRITICAL */, 7 /* _eInternalMessageId.CannotSendEmptyTelemetry */, "Cannot send empty telemetry");
                    return false;
                }
                // validate event
                if (telemetryItem.baseData && !telemetryItem[_DYN_BASE_TYPE /* @min:%2ebaseType */]) {
                    diagLogger && _throwInternal(diagLogger, 1 /* eLoggingSeverity.CRITICAL */, 70 /* _eInternalMessageId.InvalidEvent */, "Cannot send telemetry without baseData and baseType");
                    return false;
                }
                if (!telemetryItem[_DYN_BASE_TYPE /* @min:%2ebaseType */]) {
                    // Default
                    telemetryItem[_DYN_BASE_TYPE /* @min:%2ebaseType */] = "EventData";
                }
                // ensure a sender was constructed
                if (!_self[_DYN__SENDER /* @min:%2e_sender */]) {
                    diagLogger && _throwInternal(diagLogger, 1 /* eLoggingSeverity.CRITICAL */, 28 /* _eInternalMessageId.SenderNotInitialized */, "Sender was not initialized");
                    return false;
                }
                // check if this item should be sampled in, else add sampleRate tag
                if (!_isSampledIn(telemetryItem)) {
                    // Item is sampled out, do not send it
                    diagLogger && _throwInternal(diagLogger, 2 /* eLoggingSeverity.WARNING */, 33 /* _eInternalMessageId.TelemetrySampledAndNotSent */, "Telemetry item was sampled out and not sent", { SampleRate: _self._sample[_DYN_SAMPLE_RATE /* @min:%2esampleRate */] });
                    return false;
                }
                else {
                    telemetryItem[SampleRate] = _self._sample[_DYN_SAMPLE_RATE /* @min:%2esampleRate */];
                }
                return true;
            }
            function _getEnvelope(telemetryItem, diagLogger) {
                // construct an envelope that Application Insights endpoint can understand
                // if ikey of telemetry is provided and not empty, envelope will use this iKey instead of senderConfig iKey
                var defaultEnvelopeIkey = telemetryItem.iKey || _instrumentationKey;
                var aiEnvelope = Sender.constructEnvelope(telemetryItem, defaultEnvelopeIkey, diagLogger, _convertUndefined);
                if (!aiEnvelope) {
                    _throwInternal(diagLogger, 1 /* eLoggingSeverity.CRITICAL */, 47 /* _eInternalMessageId.CreateEnvelopeError */, "Unable to create an AppInsights envelope");
                    return;
                }
                var doNotSendItem = false;
                // this is for running in legacy mode, where customer may already have a custom initializer present
                if (telemetryItem[_DYN_TAGS /* @min:%2etags */] && telemetryItem[_DYN_TAGS /* @min:%2etags */][ProcessLegacy]) {
                    arrForEach(telemetryItem[_DYN_TAGS /* @min:%2etags */][ProcessLegacy], function (callBack) {
                        try {
                            if (callBack && callBack(aiEnvelope) === false) {
                                doNotSendItem = true;
                                _warnToConsole(diagLogger, "Telemetry processor check returns false");
                            }
                        }
                        catch (e) {
                            // log error but dont stop executing rest of the telemetry initializers
                            // doNotSendItem = true;
                            _throwInternal(diagLogger, 1 /* eLoggingSeverity.CRITICAL */, 64 /* _eInternalMessageId.TelemetryInitializerFailed */, "One of telemetry initializers failed, telemetry item will not be sent: " + getExceptionName(e), { exception: dumpObj(e) }, true);
                        }
                    });
                    delete telemetryItem[_DYN_TAGS /* @min:%2etags */][ProcessLegacy];
                }
                if (doNotSendItem) {
                    return; // do not send, no need to execute next plugin
                }
                return aiEnvelope;
            }
            function _serialize(item) {
                var rlt = EMPTY_STR;
                var diagLogger = _self[_DYN_DIAG_LOG /* @min:%2ediagLog */]();
                try {
                    var valid = _validate(item, diagLogger);
                    var envelope = null;
                    if (valid) {
                        envelope = _getEnvelope(item, diagLogger);
                    }
                    if (envelope) {
                        rlt = _serializer.serialize(envelope);
                    }
                }
                catch (e) {
                    // eslint-disable-next-line no-empty
                }
                return rlt;
            }
            function _batch(arr) {
                var rlt = EMPTY_STR;
                if (arr && arr[_DYN_LENGTH /* @min:%2elength */]) {
                    rlt = "[" + arr.join(",") + "]";
                }
                return rlt;
            }
            function _createPayload(data) {
                var headers = _getHeaders();
                return {
                    urlString: _endpointUrl,
                    data: data,
                    headers: headers
                };
            }
            function _isSampledIn(envelope) {
                return _self._sample.isSampledIn(envelope);
            }
            function _getOnComplete(payload, status, headers, response) {
                // ***********************************************************************************************
                //TODO: handle other status codes
                if (status === 200 && payload) {
                    _self._onSuccess(payload, payload[_DYN_LENGTH /* @min:%2elength */]);
                }
                else {
                    response && _self[_DYN__ON_ERROR /* @min:%2e_onError */](payload, response);
                }
            }
            function _doSend(sendInterface, payload, isAsync, markAsSent) {
                if (markAsSent === void 0) { markAsSent = true; }
                var onComplete = function (status, headers, response) {
                    // let statsbeat = _getStatsBeat();
                    // if (statsbeat) {
                    //     statsbeat.count(status, payloadData, _endpointUrl);
                    // }
                    return _getOnComplete(payload, status, headers, response);
                };
                var payloadData = _getPayload(payload);
                // if (payloadData) {
                //     payloadData.statsBeatData = {startTime: dateNow()};
                // }
                var sendPostFunc = sendInterface && sendInterface.sendPOST;
                if (sendPostFunc && payloadData) {
                    // ***********************************************************************************************
                    // mark payload as sent at the beginning of calling each send function
                    if (markAsSent) {
                        _self._buffer[_DYN_MARK_AS_SENT /* @min:%2emarkAsSent */](payload);
                    }
                    var result_2;
                    var callbackExecuted_1 = false;
                    var resolveFn_1;
                    var rejectFn_1;
                    _sendPostMgr.preparePayload(function (processedPayload) {
                        result_2 = sendPostFunc(processedPayload, onComplete, !isAsync);
                        callbackExecuted_1 = true;
                        if (resolveFn_1) {
                            doAwait(result_2, resolveFn_1, rejectFn_1);
                        }
                    }, _zipPayload, payloadData, !isAsync);
                    if (callbackExecuted_1) {
                        return result_2;
                    }
                    // Callback was not executed synchronously, so we need to return a promise
                    return createPromise(function (resolve, reject) {
                        resolveFn_1 = resolve;
                        rejectFn_1 = reject;
                    });
                }
                return null;
            }
            function _getPayload(payload) {
                if (isArray(payload) && payload[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    var batch = _self[_DYN__BUFFER /* @min:%2e_buffer */].batchPayloads(payload);
                    var headers = _getHeaders();
                    var payloadData = {
                        data: batch,
                        urlString: _endpointUrl,
                        headers: headers,
                        disableXhrSync: _disableXhr,
                        disableFetchKeepAlive: !_fetchKeepAlive,
                        oriPayload: payload
                    };
                    return payloadData;
                }
                return null;
            }
            function _getHeaders() {
                try {
                    var headers = _headers || {};
                    if (isInternalApplicationInsightsEndpoint(_endpointUrl)) {
                        headers[RequestHeaders[6 /* eRequestHeaders.sdkContextHeader */]] = RequestHeaders[7 /* eRequestHeaders.sdkContextHeaderAppIdRequest */];
                    }
                    return headers;
                }
                catch (e) {
                    // eslint-disable-next-line no-empty
                }
                return null;
            }
            function _checkMaxSize(incomingPayload) {
                var incomingSize = incomingPayload ? incomingPayload[_DYN_LENGTH /* @min:%2elength */] : 0;
                if ((_self[_DYN__BUFFER /* @min:%2e_buffer */].size() + incomingSize) > _maxBatchSizeInBytes) {
                    if (!_offlineListener || _offlineListener.isOnline()) { // only trigger send when currently online
                        _self[_DYN_TRIGGER_SEND /* @min:%2etriggerSend */](true, null, 10 /* SendRequestReason.MaxBatchSize */);
                    }
                    return true;
                }
                return false;
            }
            function _checkResponsStatus(status, payload, responseUrl, countOfItemsInPayload, errorMessage, res) {
                var response = null;
                if (!_self._appId) {
                    response = parseResponse(res);
                    if (response && response.appId) {
                        _self._appId = response.appId;
                    }
                }
                if ((status < 200 || status >= 300) && status !== 0) {
                    // Update End Point url if permanent redirect or moved permanently
                    // Updates the end point url before retry
                    if (status === 301 || status === 307 || status === 308) {
                        if (!_checkAndUpdateEndPointUrl(responseUrl)) {
                            _self[_DYN__ON_ERROR /* @min:%2e_onError */](payload, errorMessage);
                            return;
                        }
                    }
                    if (_offlineListener && !_offlineListener.isOnline()) { // offline
                        // Note: Don't check for status == 0, since adblock gives this code
                        if (!_isRetryDisabled) {
                            var offlineBackOffMultiplier = 10; // arbritrary number
                            _resendPayload(payload, offlineBackOffMultiplier);
                            _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, ". Offline - Response Code: ".concat(status, ". Offline status: ").concat(!_offlineListener.isOnline(), ". Will retry to send ").concat(payload.length, " items."));
                        }
                        return;
                    }
                    if (!_isRetryDisabled && _isRetriable(status)) {
                        _resendPayload(payload);
                        _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, ". " +
                            "Response code " + status + ". Will retry to send " + payload[_DYN_LENGTH /* @min:%2elength */] + " items.");
                    }
                    else {
                        _self[_DYN__ON_ERROR /* @min:%2e_onError */](payload, errorMessage);
                    }
                }
                else {
                    // check if the xhr's responseURL or fetch's response.url is same as endpoint url
                    // TODO after 10 redirects force send telemetry with 'redirect=false' as query parameter.
                    _checkAndUpdateEndPointUrl(responseUrl);
                    if (status === 206) {
                        if (!response) {
                            response = parseResponse(res);
                        }
                        if (response && !_isRetryDisabled) {
                            _self[_DYN__ON_PARTIAL_SUCCESS /* @min:%2e_onPartialSuccess */](payload, response);
                        }
                        else {
                            _self[_DYN__ON_ERROR /* @min:%2e_onError */](payload, errorMessage);
                        }
                    }
                    else {
                        _consecutiveErrors = 0;
                        _self[_DYN__ON_SUCCESS /* @min:%2e_onSuccess */](payload, countOfItemsInPayload);
                    }
                }
            }
            function _checkAndUpdateEndPointUrl(responseUrl) {
                // Maximum stamp specific redirects allowed(uncomment this when breeze is ready with not allowing redirects feature)
                if (_stamp_specific_redirects >= 10) {
                    //  _self._senderConfig.endpointUrl = () => Sender._getDefaultAppInsightsChannelConfig().endpointUrl()+"/?redirect=false";
                    //  _stamp_specific_redirects = 0;
                    return false;
                }
                if (!isNullOrUndefined(responseUrl) && responseUrl !== "") {
                    if (responseUrl !== _endpointUrl) {
                        _endpointUrl = responseUrl;
                        ++_stamp_specific_redirects;
                        return true;
                    }
                }
                return false;
            }
            function _doUnloadSend(payload, isAsync) {
                if (_syncUnloadSender) {
                    // We are unloading so always call the sender with sync set to false
                    _syncUnloadSender(payload, false);
                }
                else {
                    // Fallback to the previous beacon Sender (which causes a CORB warning on chrome now)
                    var beaconInst = _sendPostMgr && _sendPostMgr[_DYN_GET_SENDER_INST /* @min:%2egetSenderInst */]([3 /* TransportType.Beacon */], true);
                    return _doSend(beaconInst, payload, isAsync);
                }
            }
            function _onBeaconRetry(payload, onComplete, canSend) {
                var internalPayload = payload;
                var data = internalPayload && internalPayload.oriPayload;
                if (!_disableBeaconSplit) {
                    // Failed to send entire payload so try and split data and try to send as much events as possible
                    var droppedPayload = [];
                    for (var lp = 0; lp < data[_DYN_LENGTH /* @min:%2elength */]; lp++) {
                        var thePayload = data[lp];
                        var arr = [thePayload];
                        var item = _getPayload(arr);
                        if (!canSend(item, onComplete)) {
                            // Can't send anymore, so split the batch and drop the rest
                            droppedPayload[_DYN_PUSH /* @min:%2epush */](thePayload);
                        }
                        else {
                            _self._onSuccess(arr, arr[_DYN_LENGTH /* @min:%2elength */]);
                        }
                    }
                    if (droppedPayload[_DYN_LENGTH /* @min:%2elength */] > 0) {
                        _fallbackSend && _fallbackSend(droppedPayload, true);
                        _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, ". " + "Failed to send telemetry with Beacon API, retried with normal sender.");
                    }
                }
                else {
                    _fallbackSend && _fallbackSend(data, true);
                    _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, ". " + "Failed to send telemetry with Beacon API, retried with normal sender.");
                }
            }
            function _isStringArr(arr) {
                try {
                    if (arr && arr[_DYN_LENGTH /* @min:%2elength */]) {
                        return (isString(arr[0]));
                    }
                }
                catch (e) {
                    //TODO: log, sender use IInternalStorageItem instead of string since 3.1.3
                }
                return null;
            }
            function _fetchKeepAliveSender(payload, isAsync) {
                var transport = null;
                if (isArray(payload)) {
                    var payloadSize = payload[_DYN_LENGTH /* @min:%2elength */];
                    for (var lp = 0; lp < payload[_DYN_LENGTH /* @min:%2elength */]; lp++) {
                        payloadSize += payload[lp].item[_DYN_LENGTH /* @min:%2elength */];
                    }
                    var syncFetchPayload = _sendPostMgr.getSyncFetchPayload();
                    if ((syncFetchPayload + payloadSize) <= FetchSyncRequestSizeLimitBytes) {
                        transport = 2 /* TransportType.Fetch */;
                    }
                    else if (isBeaconsSupported()) {
                        // Fallback to beacon sender as we at least get told which events can't be scheduled
                        transport = 3 /* TransportType.Beacon */;
                    }
                    else {
                        // Payload is going to be too big so just try and send via XHR
                        transport = 1 /* TransportType.Xhr */;
                        _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 2 /* eLoggingSeverity.WARNING */, 40 /* _eInternalMessageId.TransmissionFailed */, ". " + "Failed to send telemetry with Beacon API, retried with xhrSender.");
                    }
                    var inst = _sendPostMgr && _sendPostMgr[_DYN_GET_SENDER_INST /* @min:%2egetSenderInst */]([transport], true);
                    return _doSend(inst, payload, isAsync);
                }
                return null;
            }
            /**
             * Resend payload. Adds payload back to the send buffer and setup a send timer (with exponential backoff).
             * @param payload
             */
            function _resendPayload(payload, linearFactor) {
                if (linearFactor === void 0) { linearFactor = 1; }
                if (!payload || payload[_DYN_LENGTH /* @min:%2elength */] === 0) {
                    return;
                }
                var buffer = _self[_DYN__BUFFER /* @min:%2e_buffer */];
                buffer[_DYN_CLEAR_SENT /* @min:%2eclearSent */](payload);
                _consecutiveErrors++;
                for (var _i = 0, payload_1 = payload; _i < payload_1.length; _i++) {
                    var item = payload_1[_i];
                    item.cnt = item.cnt || 0; // to make sure we have cnt for each payload
                    item.cnt++; // when resend, increase cnt
                    buffer[_DYN_ENQUEUE /* @min:%2eenqueue */](item);
                }
                // setup timer
                _setRetryTime(linearFactor);
                _setupTimer();
            }
            /**
             * Calculates the time to wait before retrying in case of an error based on
             * http://en.wikipedia.org/wiki/Exponential_backoff
             */
            function _setRetryTime(linearFactor) {
                var SlotDelayInSeconds = 10;
                var delayInSeconds;
                if (_consecutiveErrors <= 1) {
                    delayInSeconds = SlotDelayInSeconds;
                }
                else {
                    var backOffSlot = (Math.pow(2, _consecutiveErrors) - 1) / 2;
                    // tslint:disable-next-line:insecure-random
                    var backOffDelay = mathFloor(Math.random() * backOffSlot * SlotDelayInSeconds) + 1;
                    backOffDelay = linearFactor * backOffDelay;
                    delayInSeconds = mathMax(mathMin(backOffDelay, 3600), SlotDelayInSeconds);
                }
                // TODO: Log the backoff time like the C# version does.
                var retryAfterTimeSpan = dateNow() + (delayInSeconds * 1000);
                // TODO: Log the retry at time like the C# version does.
                _retryAt = retryAfterTimeSpan;
            }
            /**
             * Sets up the timer which triggers actually sending the data.
             */
            function _setupTimer() {
                if (!_timeoutHandle && !_paused) {
                    var retryInterval = _retryAt ? mathMax(0, _retryAt - dateNow()) : 0;
                    var timerValue = mathMax(_maxBatchInterval, retryInterval);
                    _timeoutHandle = scheduleTimeout(function () {
                        _timeoutHandle = null;
                        _self[_DYN_TRIGGER_SEND /* @min:%2etriggerSend */](true, null, 1 /* SendRequestReason.NormalSchedule */);
                    }, timerValue);
                }
            }
            function _clearScheduledTimer() {
                _timeoutHandle && _timeoutHandle.cancel();
                _timeoutHandle = null;
                _retryAt = null;
            }
            /**
             * Checks if the SDK should resend the payload after receiving this status code from the backend.
             * @param statusCode
             */
            function _isRetriable(statusCode) {
                // retryCodes = [] means should not retry
                if (!isNullOrUndefined(_retryCodes)) {
                    return _retryCodes[_DYN_LENGTH /* @min:%2elength */] && _retryCodes.indexOf(statusCode) > -1;
                }
                return statusCode === 401 // Unauthorized
                    // Removing as private links can return a 403 which causes excessive retries and session storage usage
                    // || statusCode === 403 // Forbidden
                    || statusCode === 408 // Timeout
                    || statusCode === 429 // Too many requests.
                    || statusCode === 500 // Internal server error.
                    || statusCode === 502 // Bad Gateway.
                    || statusCode === 503 // Service unavailable.
                    || statusCode === 504; // Gateway timeout.
            }
            // Using function lookups for backward compatibility as the getNotifyMgr() did not exist until after v2.5.6
            function _getNotifyMgr() {
                var func = "getNotifyMgr";
                var result;
                var core = _self.core;
                if (core) {
                    // During page unload the core may have been cleared and some async events may not have been sent yet
                    // resulting in the core being null. In this case we don't want to create a statsbeat instance
                    if (core[func]) {
                        result = core[func]();
                    }
                    else {
                        // using _self.core['_notificationManager'] for backward compatibility
                        result = core["_notificationManager"];
                    }
                }
                return result;
            }
            function _notifySendRequest(sendRequest, isAsync) {
                var manager = _getNotifyMgr();
                if (manager && manager.eventsSendRequest) {
                    try {
                        manager.eventsSendRequest(sendRequest, isAsync);
                    }
                    catch (e) {
                        _throwInternal(_self[_DYN_DIAG_LOG /* @min:%2ediagLog */](), 1 /* eLoggingSeverity.CRITICAL */, 74 /* _eInternalMessageId.NotificationException */, "send request notification failed: " + getExceptionName(e), { exception: dumpObj(e) });
                    }
                }
            }
            /**
             * Validate UUID Format
             * Specs taken from https://tools.ietf.org/html/rfc4122 and breeze repo
             */
            function _validateInstrumentationKey(instrumentationKey, config) {
                var disableValidation = config.disableInstrumentationKeyValidation;
                var disableIKeyValidationFlag = isNullOrUndefined(disableValidation) ? false : disableValidation;
                if (disableIKeyValidationFlag) {
                    return true;
                }
                var UUID_Regex = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
                var regexp = new RegExp(UUID_Regex);
                return regexp.test(instrumentationKey);
            }
            function _initDefaults() {
                _self[_DYN__SENDER /* @min:%2e_sender */] = null;
                _self[_DYN__BUFFER /* @min:%2e_buffer */] = null;
                _self._appId = null;
                _self._sample = null;
                _headers = {};
                _offlineListener = null;
                _consecutiveErrors = 0;
                _retryAt = null;
                _lastSend = null;
                _paused = false;
                _timeoutHandle = null;
                _serializer = null;
                _stamp_specific_redirects = 0;
                _syncFetchPayload = 0;
                _syncUnloadSender = null;
                _evtNamespace = null;
                _endpointUrl = null;
                _orgEndpointUrl = null;
                _maxBatchSizeInBytes = 0;
                _beaconSupported = false;
                _customHeaders = null;
                _disableTelemetry = false;
                _instrumentationKey = null;
                _convertUndefined = UNDEFINED_VALUE;
                _isRetryDisabled = false;
                _sessionStorageUsed = null;
                _namePrefix = UNDEFINED_VALUE;
                _disableXhr = false;
                _fetchKeepAlive = false;
                _disableBeaconSplit = false;
                _xhrSend = null;
                _fallbackSend = null;
                _sendPostMgr = null;
                objDefine(_self, "_senderConfig", {
                    g: function () {
                        return objExtend({}, defaultAppInsightsChannelConfig);
                    }
                });
            }
        });
        return _this;
    }
    Sender.constructEnvelope = function (orig, iKey, logger, convertUndefined) {
        var envelope;
        if (iKey !== orig.iKey && !isNullOrUndefined(iKey)) {
            envelope = __assign(__assign({}, orig), { iKey: iKey });
        }
        else {
            envelope = orig;
        }
        var creator = EnvelopeTypeCreator[envelope.baseType] || EventEnvelopeCreator;
        return creator(logger, envelope, convertUndefined);
    };
// Removed Stub for Sender.prototype.pause.
// Removed Stub for Sender.prototype.resume.
// Removed Stub for Sender.prototype.flush.
// Removed Stub for Sender.prototype.onunloadFlush.
// Removed Stub for Sender.prototype.initialize.
// Removed Stub for Sender.prototype.processTelemetry.
// Removed Stub for Sender.prototype._xhrReadyStateChange.
// Removed Stub for Sender.prototype.triggerSend.
// Removed Stub for Sender.prototype._onError.
// Removed Stub for Sender.prototype._onPartialSuccess.
// Removed Stub for Sender.prototype._onSuccess.
// Removed Stub for Sender.prototype._xdrOnLoad.
// Removed Stub for Sender.prototype.addHeader.
// Removed Stub for Sender.prototype.isCompletelyIdle.
// Removed Stub for Sender.prototype.getOfflineSupport.
// Removed Stub for Sender.prototype.getOfflineListener.
    return Sender;
}(BaseTelemetryPlugin));
export { Sender };
//# sourceMappingURL=Sender.js.map