exceptionless.min.js.map 331 KB
Newer Older
frank.xa.zhang's avatar
frank.xa.zhang committed
1
{"version":3,"sources":["tracekit.js","exceptionless.min.js","/source/exceptionless.ts"],"names":["window","undefined","_has","object","key","Object","prototype","hasOwnProperty","call","_isUndefined","what","TraceKit","_oldTraceKit","_slice","slice","UNKNOWN_FUNCTION","noConflict","wrap","func","wrapped","apply","this","arguments","e","report","subscribe","handler","installGlobalHandler","handlers","push","unsubscribe","i","length","splice","notifyHandlers","stack","isWindowError","exception","collectWindowErrors","concat","inner","traceKitWindowOnError","message","url","lineNo","columnNo","errorObj","lastExceptionStack","computeStackTrace","augmentStackTraceWithInitialElement","processLastException","location","line","column","guessFunctionName","context","gatherContext","mode","_oldOnerrorHandler","_onErrorHandlerInstalled","onerror","_lastExceptionStack","_lastArgs","lastArgs","lastException","ex","setTimeout","incomplete","loadSource","remoteFetching","getXHR","XMLHttpRequest","ActiveXObject","request","open","send","responseText","getSource","sourceCache","source","domain","document","match","exec","split","m","reFunctionArgNames","reGuessFunction","maxLines","linesBefore","Math","floor","linesOfContext","linesAfter","start","max","end","min","escapeRegExp","text","replace","escapeCodeAsRegExpForMatchingInsideHTML","body","findSourceInUrls","re","urls","j","join","substring","index","lastIndexOf","findSourceInLine","fragment","RegExp","findSourceByFunctionBody","parts","result","href","scripts","getElementsByTagName","code","codeRE","eventRE","script","src","name","args","event","computeStackTraceFromStackProp","element","chrome","gecko","winjs","lines","reference","isNative","indexOf","columnNumber","computeStackTraceFromStacktraceProp","stacktrace","opera10Regex","opera11Regex","exc","computeStackTraceFromOperaMultiLineMessage","lineRE1","lineRE2","lineRE3","inlineScriptBlocks","s","item","relativeLine","pos","innerText","midline","stackInfo","initial","unshift","partial","computeStackTraceByWalkingCallerChain","depth","functionName","funcs","recursion","curr","caller","toString","input","description","sourceURL","fileName","lineNumber","debug","computeStackTraceOfCaller","Error","ofCaller","extendToAsynchronousCallbacks","_helper","fnName","originalFn","originalCallback","module","exports","define","amd","global","root","factory","require","exceptionless","parseDate","value","dateRegx","a","Date","getDefaultsSettingsFromScriptTag","Utils","parseQueryString","pop","processUnhandledException","stackTrace","options","builder","ExceptionlessClient","createUnhandledException","status","pluginContextData","submit","__extends","d","b","__","constructor","p","create","SubmissionResponse","statusCode","success","badRequest","serviceUnavailable","paymentRequired","unableToAuthenticate","notFound","requestEntityTooLarge","SettingsManager","onChanged","_handlers","applySavedServerSettings","config","isValid","savedSettings","getSavedServerSettings","log","info","version","settings","merge","changed","getVersion","checkVersion","currentVersion","updateSettings","_this","enabled","unableToUpdateMessage","error","submissionClient","getSettings","response","warn","savedServerSettings","newSettings","settingsVersion","storage","save","get","DefaultLastReferenceIdManager","_lastReferenceId","getLast","clearLast","setLast","eventId","ConsoleLog","trace","level","console","msg","NullLog","EventPluginContext","client","contextData","ContextData","defineProperty","enumerable","configurable","EventPluginManager","run","callback","plugin","next","cancelled","plugins","wrappedPlugins","priority","addDefaultPlugins","addPlugin","ConfigurationDefaultsPlugin","ErrorPlugin","DuplicateCheckerPlugin","EventExclusionPlugin","ModuleInfoPlugin","RequestInfoPlugin","EnvironmentInfoPlugin","SubmissionMethodPlugin","HeartbeatPlugin","heartbeatInterval","_interval","clearInterval","_intervalId","user","data","identity","setInterval","submitSessionHeartbeat","ReferenceIdPlugin","reference_id","type","guid","DefaultEventQueue","_processingQueue","_config","enqueue","eventWillNotBeQueued","areQueuedItemsDiscarded","ensureQueueTimer","timestamp","queue","logText","process","isAppExiting","queueNotProcessed","events_1","submissionBatchSize","serverUrl","postEvents","map","processSubmissionResponse","eventsPosted","suspendProcessing","durationInMinutes","discardFutureQueuedItems","clearQueue","_suspendProcessingUntil","getTime","_discardQueuedItemsUntil","clear","onEventsPosted","events","_queueTimer","onProcessQueue","isQueueProcessingSuspended","noSubmission","removeEvents","round","remove","InMemoryStorageProvider","maxQueueItems","InMemoryStorage","DefaultSubmissionClient","configurationVersionHeader","JSON","stringify","createRequest","cb","createSubmissionCallback","submissionAdapter","sendRequest","postUserDescription","referenceId","path","encodeURIComponent","headers","SettingsResponse","parse","isNaN","sendHeartbeat","sessionIdOrUserId","closeSession","heartbeatServerUrl","method","apiKey","userAgent","parseInt","addRange","target","values","_i","getHashCode","hash","character","charCodeAt","getCookies","cookies","exclusions","cookie","isMatch","isEmpty","s4","random","defaultValues","parseVersion","versionRegex","matches","query","pairs","pair","decodeURIComponent","randomNumber","patterns","ignoreCase","trim","toLowerCase","some","pattern","startsWithWildcard","endsWithWildcard","endsWith","startsWith","keys","prefix","suffix","maxDepth","stringifyImpl","obj","excludedKeys","cache","flattened","prop","toBoolean","defaultValue","Configuration","configSettings","inject","fn","defaultTags","defaultData","lastReferenceIdManager","_serverUrl","_heartbeatServerUrl","_updateSettingsWhenIdleInterval","_dataExclusions","_userAgentBotPatterns","_plugins","defaults","updateSettingsWhenIdleInterval","environmentInfoCollector","errorParser","moduleCollector","requestInfoCollector","_apiKey","set","addDataExclusions","addUserAgentBotPatterns","userAgentBotPatterns","sort","p1","p2","pluginOrName","pluginAction","pluginExists","removePlugin","setVersion","setUserIdentity","userInfoOrIdentity","USER_KEY","userInfo","shouldRemove","useSessions","sendHeartbeats","useReferenceIds","useLocalStorage","useDebugLogger","_defaultSettings","EventBuilder","_validIdentifierErrorMessage","setType","setSource","setReferenceId","isValidIdentifier","setEventReference","id","setProperty","setMessage","setGeo","latitude","longitude","geo","setUserDescription","emailAddress","email_address","setManualStackingInfo","signatureData","title","signature_data","setManualStackingKey","manualStackingKey","ManualStackingKey","setValue","addTags","tags","excludedPropertyNames","dataExclusions","markAsCritical","critical","addRequestInfo","submitEvent","isDigit","isLetter","isMinus","setException","getException","markAsUnhandledError","setSubmissionMethod","getSubmissionMethod","settingsOrApiKey","updateSettingsTimer","_timeoutId","createException","createEvent","submitException","submissionMethod","submitUnhandledException","createFeatureUsage","feature","submitFeatureUsage","createLog","sourceOrMessage","submitLog","createNotFound","resource","submitNotFound","createSessionStart","submitSessionStart","submitSessionEnd","date","ctx","ev","updateUserEmailAndDescription","email","userDescription","getLastReferenceId","initialDelay","clearTimeout","interval","_instance","tag","ERROR_KEY","ignoredProperties","parser","additionalData","collector","modules","getModules","REQUEST_KEY","requestInfo","getRequestInfo","user_agent","ENVIRONMENT_KEY","environmentInfo","getEnvironmentInfo","getCurrentTime","now","_mergedEvents","_processedHashcodes","_getCurrentTime","shift","resubmit","hashCode","stack_trace","count","now_1","merged","filter","incrementCount","updateDate","h","MergedEvent","_context","_count","getLogLevel","getMinLogLevel","loggerName","getTypeAndSourceSetting","isLog","sourcePrefix","minLogLevel","logLevel","maxItems","items","lastTimestamp","limit","KeyValueStorageBase","single","ensureIndex","getKey","json","write","read","safeDelete","forEach","createIndex","readAllKeys","getTimestamp","BrowserStorage","_super","namespace","isAvailable","localStorage","x","setItem","removeItem","getItem","substr","DefaultErrorParser","getParameters","parameters","params","getStackFrames","stackFrames","ANONYMOUS","frames","frame","file_name","line_number","TRACEKIT_STACK_TRACE_KEY","DefaultModuleCollector","module_id","innerHTML","DefaultRequestInfoCollector","navigator","is_secure","protocol","host","hostname","port","pathname","query_string","search","referrer","DefaultSubmissionAdapter","complete","xhr","parseResponseHeaders","headerStr","headerPairs","headerPair","separator","isCompleted","statusText","TIMEOUT","LOADED","responseBody","getAllResponseHeaders","WITH_CREDENTIALS","setRequestHeader","XDomainRequest","useSetTimeout","timeout","onreadystatechange","readyState","onprogress","ontimeout","onload","BrowserStorageProvider","stackTraceLimit","Infinity"],"mappings":"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","file":"exceptionless.min.js","sourcesContent":["/**\n * https://github.com/csnover/TraceKit\n * @license MIT\n * @namespace TraceKit\n */\n(function(window, undefined) {\nif (!window) {\n    return;\n}\n\nvar TraceKit = {};\nvar _oldTraceKit = window.TraceKit;\n\n// global reference to slice\nvar _slice = [].slice;\nvar UNKNOWN_FUNCTION = '?';\n\n/**\n * A better form of hasOwnProperty<br/>\n * Example: `_has(MainHostObject, property) === true/false`\n *\n * @param {Object} object to check property\n * @param {string} key to check\n * @return {Boolean} true if the object has the key and it is not inherited\n */\nfunction _has(object, key) {\n    return Object.prototype.hasOwnProperty.call(object, key);\n}\n\n/**\n * Returns true if the parameter is undefined<br/>\n * Example: `_isUndefined(val) === true/false`\n *\n * @param {*} what Value to check\n * @return {Boolean} true if undefined and false otherwise\n */\nfunction _isUndefined(what) {\n    return typeof what === 'undefined';\n}\n\n/**\n * Export TraceKit out to another variable<br/>\n * Example: `var TK = TraceKit.noConflict()`\n * @return {Object} The TraceKit object\n * @memberof TraceKit\n */\nTraceKit.noConflict = function noConflict() {\n    window.TraceKit = _oldTraceKit;\n    return TraceKit;\n};\n\n/**\n * Wrap any function in a TraceKit reporter<br/>\n * Example: `func = TraceKit.wrap(func);`\n *\n * @param {Function} func Function to be wrapped\n * @return {Function} The wrapped func\n * @memberof TraceKit\n */\nTraceKit.wrap = function traceKitWrapper(func) {\n    function wrapped() {\n        try {\n            return func.apply(this, arguments);\n        } catch (e) {\n            TraceKit.report(e);\n            throw e;\n        }\n    }\n    return wrapped;\n};\n\n/**\n * Cross-browser processing of unhandled exceptions\n *\n * Syntax:\n * ```js\n *   TraceKit.report.subscribe(function(stackInfo) { ... })\n *   TraceKit.report.unsubscribe(function(stackInfo) { ... })\n *   TraceKit.report(exception)\n *   try { ...code... } catch(ex) { TraceKit.report(ex); }\n * ```\n *\n * Supports:\n *   - Firefox: full stack trace with line numbers, plus column number\n *     on top frame; column number is not guaranteed\n *   - Opera: full stack trace with line and column numbers\n *   - Chrome: full stack trace with line and column numbers\n *   - Safari: line and column number for the top frame only; some frames\n *     may be missing, and column number is not guaranteed\n *   - IE: line and column number for the top frame only; some frames\n *     may be missing, and column number is not guaranteed\n *\n * In theory, TraceKit should work on all of the following versions:\n *   - IE5.5+ (only 8.0 tested)\n *   - Firefox 0.9+ (only 3.5+ tested)\n *   - Opera 7+ (only 10.50 tested; versions 9 and earlier may require\n *     Exceptions Have Stacktrace to be enabled in opera:config)\n *   - Safari 3+ (only 4+ tested)\n *   - Chrome 1+ (only 5+ tested)\n *   - Konqueror 3.5+ (untested)\n *\n * Requires TraceKit.computeStackTrace.\n *\n * Tries to catch all unhandled exceptions and report them to the\n * subscribed handlers. Please note that TraceKit.report will rethrow the\n * exception. This is REQUIRED in order to get a useful stack trace in IE.\n * If the exception does not reach the top of the browser, you will only\n * get a stack trace from the point where TraceKit.report was called.\n *\n * Handlers receive a TraceKit.StackTrace object as described in the\n * TraceKit.computeStackTrace docs.\n *\n * @memberof TraceKit\n * @namespace\n */\nTraceKit.report = (function reportModuleWrapper() {\n    var handlers = [],\n        lastArgs = null,\n        lastException = null,\n        lastExceptionStack = null;\n\n    /**\n     * Add a crash handler.\n     * @param {Function} handler\n     * @memberof TraceKit.report\n     */\n    function subscribe(handler) {\n        installGlobalHandler();\n        handlers.push(handler);\n    }\n\n    /**\n     * Remove a crash handler.\n     * @param {Function} handler\n     * @memberof TraceKit.report\n     */\n    function unsubscribe(handler) {\n        for (var i = handlers.length - 1; i >= 0; --i) {\n            if (handlers[i] === handler) {\n                handlers.splice(i, 1);\n            }\n        }\n    }\n\n    /**\n     * Dispatch stack information to all handlers.\n     * @param {TraceKit.StackTrace} stack\n     * @param {boolean} isWindowError Is this a top-level window error?\n     * @memberof TraceKit.report\n     * @throws An exception if an error occurs while calling an handler.\n     */\n    function notifyHandlers(stack, isWindowError) {\n        var exception = null;\n        if (isWindowError && !TraceKit.collectWindowErrors) {\n          return;\n        }\n        for (var i in handlers) {\n            if (_has(handlers, i)) {\n                try {\n                    handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2)));\n                } catch (inner) {\n                    exception = inner;\n                }\n            }\n        }\n\n        if (exception) {\n            throw exception;\n        }\n    }\n\n    var _oldOnerrorHandler, _onErrorHandlerInstalled;\n\n    /**\n     * Ensures all global unhandled exceptions are recorded.\n     * Supported by Gecko and IE.\n     * @param {string} message Error message.\n     * @param {string} url URL of script that generated the exception.\n     * @param {(number|string)} lineNo The line number at which the error occurred.\n     * @param {(number|string)=} columnNo The column number at which the error occurred.\n     * @param {Error=} errorObj The actual Error object.\n     * @memberof TraceKit.report\n     */\n    function traceKitWindowOnError(message, url, lineNo, columnNo, errorObj) {\n        var stack = null;\n\n        if (lastExceptionStack) {\n            TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message);\n    \t    processLastException();\n\t    } else if (errorObj) {\n            stack = TraceKit.computeStackTrace(errorObj);\n            notifyHandlers(stack, true);\n        } else {\n            var location = {\n              'url': url,\n              'line': lineNo,\n              'column': columnNo\n            };\n            location.func = TraceKit.computeStackTrace.guessFunctionName(location.url, location.line);\n            location.context = TraceKit.computeStackTrace.gatherContext(location.url, location.line);\n            stack = {\n              'mode': 'onerror',\n              'message': message,\n              'stack': [location]\n            };\n\n            notifyHandlers(stack, true);\n        }\n\n        if (_oldOnerrorHandler) {\n            return _oldOnerrorHandler.apply(this, arguments);\n        }\n\n        return false;\n    }\n\n    /**\n     * Install a global onerror handler\n     * @memberof TraceKit.report\n     */\n    function installGlobalHandler () {\n        if (_onErrorHandlerInstalled === true) {\n            return;\n        }\n        _oldOnerrorHandler = window.onerror;\n        window.onerror = traceKitWindowOnError;\n        _onErrorHandlerInstalled = true;\n    }\n\n    /**\n     * Process the most recent exception\n     * @memberof TraceKit.report\n     */\n    function processLastException() {\n        var _lastExceptionStack = lastExceptionStack,\n            _lastArgs = lastArgs;\n        lastArgs = null;\n        lastExceptionStack = null;\n        lastException = null;\n        notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs));\n    }\n\n    /**\n     * Reports an unhandled Error to TraceKit.\n     * @param {Error} ex\n     * @memberof TraceKit.report\n     * @throws An exception if an incomplete stack trace is detected (old IE browsers).\n     */\n    function report(ex) {\n        if (lastExceptionStack) {\n            if (lastException === ex) {\n                return; // already caught by an inner catch block, ignore\n            } else {\n              processLastException();\n            }\n        }\n\n        var stack = TraceKit.computeStackTrace(ex);\n        lastExceptionStack = stack;\n        lastException = ex;\n        lastArgs = _slice.call(arguments, 1);\n\n        // If the stack trace is incomplete, wait for 2 seconds for\n        // slow slow IE to see if onerror occurs or not before reporting\n        // this exception; otherwise, we will end up with an incomplete\n        // stack trace\n        window.setTimeout(function () {\n            if (lastException === ex) {\n                processLastException();\n            }\n        }, (stack.incomplete ? 2000 : 0));\n\n        throw ex; // re-throw to propagate to the top level (and cause window.onerror)\n    }\n\n    report.subscribe = subscribe;\n    report.unsubscribe = unsubscribe;\n    return report;\n}());\n\n/**\n * An object representing a single stack frame.\n * @typedef {Object} StackFrame\n * @property {string} url The JavaScript or HTML file URL.\n * @property {string} func The function name, or empty for anonymous functions (if guessing did not work).\n * @property {string[]?} args The arguments passed to the function, if known.\n * @property {number=} line The line number, if known.\n * @property {number=} column The column number, if known.\n * @property {string[]} context An array of source code lines; the middle element corresponds to the correct line#.\n * @memberof TraceKit\n */\n\n/**\n * An object representing a JavaScript stack trace.\n * @typedef {Object} StackTrace\n * @property {string} name The name of the thrown exception.\n * @property {string} message The exception error message.\n * @property {TraceKit.StackFrame[]} stack An array of stack frames.\n * @property {string} mode 'stack', 'stacktrace', 'multiline', 'callers', 'onerror', or 'failed' -- method used to collect the stack trace.\n * @memberof TraceKit\n */\n\n/**\n * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript\n *\n * Syntax:\n *   ```js\n *   s = TraceKit.computeStackTrace.ofCaller([depth])\n *   s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below)\n *   ```\n *\n * Supports:\n *   - Firefox:  full stack trace with line numbers and unreliable column\n *               number on top frame\n *   - Opera 10: full stack trace with line and column numbers\n *   - Opera 9-: full stack trace with line numbers\n *   - Chrome:   full stack trace with line and column numbers\n *   - Safari:   line and column number for the topmost stacktrace element\n *               only\n *   - IE:       no line numbers whatsoever\n *\n * Tries to guess names of anonymous functions by looking for assignments\n * in the source code. In IE and Safari, we have to guess source file names\n * by searching for function bodies inside all page scripts. This will not\n * work for scripts that are loaded cross-domain.\n * Here be dragons: some function names may be guessed incorrectly, and\n * duplicate functions may be mismatched.\n *\n * TraceKit.computeStackTrace should only be used for tracing purposes.\n * Logging of unhandled exceptions should be done with TraceKit.report,\n * which builds on top of TraceKit.computeStackTrace and provides better\n * IE support by utilizing the window.onerror event to retrieve information\n * about the top of the stack.\n *\n * Note: In IE and Safari, no stack trace is recorded on the Error object,\n * so computeStackTrace instead walks its *own* chain of callers.\n * This means that:\n *  * in Safari, some methods may be missing from the stack trace;\n *  * in IE, the topmost function in the stack trace will always be the\n *    caller of computeStackTrace.\n *\n * This is okay for tracing (because you are likely to be calling\n * computeStackTrace from the function you want to be the topmost element\n * of the stack trace anyway), but not okay for logging unhandled\n * exceptions (because your catch block will likely be far away from the\n * inner function that actually caused the exception).\n *\n * Tracing example:\n *  ```js\n *     function trace(message) {\n *         var stackInfo = TraceKit.computeStackTrace.ofCaller();\n *         var data = message + \"\\n\";\n *         for(var i in stackInfo.stack) {\n *             var item = stackInfo.stack[i];\n *             data += (item.func || '[anonymous]') + \"() in \" + item.url + \":\" + (item.line || '0') + \"\\n\";\n *         }\n *         if (window.console)\n *             console.info(data);\n *         else\n *             alert(data);\n *     }\n * ```\n * @memberof TraceKit\n * @namespace\n */\nTraceKit.computeStackTrace = (function computeStackTraceWrapper() {\n    var debug = false,\n        sourceCache = {};\n\n    /**\n     * Attempts to retrieve source code via XMLHttpRequest, which is used\n     * to look up anonymous function names.\n     * @param {string} url URL of source code.\n     * @return {string} Source contents.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function loadSource(url) {\n        if (!TraceKit.remoteFetching) { //Only attempt request if remoteFetching is on.\n            return '';\n        }\n        try {\n            var getXHR = function() {\n                try {\n                    return new window.XMLHttpRequest();\n                } catch (e) {\n                    // explicitly bubble up the exception if not found\n                    return new window.ActiveXObject('Microsoft.XMLHTTP');\n                }\n            };\n\n            var request = getXHR();\n            request.open('GET', url, false);\n            request.send('');\n            return request.responseText;\n        } catch (e) {\n            return '';\n        }\n    }\n\n    /**\n     * Retrieves source code from the source code cache.\n     * @param {string} url URL of source code.\n     * @return {Array.<string>} Source contents.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function getSource(url) {\n        if (typeof url !== 'string') {\n            return [];\n        }\n\n        if (!_has(sourceCache, url)) {\n            // URL needs to be able to fetched within the acceptable domain.  Otherwise,\n            // cross-domain errors will be triggered.\n            /*\n                Regex matches:\n                0 - Full Url\n                1 - Protocol\n                2 - Domain\n                3 - Port (Useful for internal applications)\n                4 - Path\n            */\n            var source = '';\n            var domain = '';\n            try { domain = window.document.domain; } catch (e) { }\n            var match = /(.*)\\:\\/\\/([^:\\/]+)([:\\d]*)\\/{0,1}([\\s\\S]*)/.exec(url);\n            if (match && match[2] === domain) {\n                source = loadSource(url);\n            }\n            sourceCache[url] = source ? source.split('\\n') : [];\n        }\n\n        return sourceCache[url];\n    }\n\n    /**\n     * Tries to use an externally loaded copy of source code to determine\n     * the name of a function by looking at the name of the variable it was\n     * assigned to, if any.\n     * @param {string} url URL of source code.\n     * @param {(string|number)} lineNo Line number in source code.\n     * @return {string} The function name, if discoverable.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function guessFunctionName(url, lineNo) {\n        var reFunctionArgNames = /function ([^(]*)\\(([^)]*)\\)/,\n            reGuessFunction = /['\"]?([0-9A-Za-z$_]+)['\"]?\\s*[:=]\\s*(function|eval|new Function)/,\n            line = '',\n            maxLines = 10,\n            source = getSource(url),\n            m;\n\n        if (!source.length) {\n            return UNKNOWN_FUNCTION;\n        }\n\n        // Walk backwards from the first line in the function until we find the line which\n        // matches the pattern above, which is the function definition\n        for (var i = 0; i < maxLines; ++i) {\n            line = source[lineNo - i] + line;\n\n            if (!_isUndefined(line)) {\n                if ((m = reGuessFunction.exec(line))) {\n                    return m[1];\n                } else if ((m = reFunctionArgNames.exec(line))) {\n                    return m[1];\n                }\n            }\n        }\n\n        return UNKNOWN_FUNCTION;\n    }\n\n    /**\n     * Retrieves the surrounding lines from where an exception occurred.\n     * @param {string} url URL of source code.\n     * @param {(string|number)} line Line number in source code to centre\n     * around for context.\n     * @return {?Array.<string>} Lines of source code.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function gatherContext(url, line) {\n        var source = getSource(url);\n\n        if (!source.length) {\n            return null;\n        }\n\n        var context = [],\n            // linesBefore & linesAfter are inclusive with the offending line.\n            // if linesOfContext is even, there will be one extra line\n            //   *before* the offending line.\n            linesBefore = Math.floor(TraceKit.linesOfContext / 2),\n            // Add one extra line if linesOfContext is odd\n            linesAfter = linesBefore + (TraceKit.linesOfContext % 2),\n            start = Math.max(0, line - linesBefore - 1),\n            end = Math.min(source.length, line + linesAfter - 1);\n\n        line -= 1; // convert to 0-based index\n\n        for (var i = start; i < end; ++i) {\n            if (!_isUndefined(source[i])) {\n                context.push(source[i]);\n            }\n        }\n\n        return context.length > 0 ? context : null;\n    }\n\n    /**\n     * Escapes special characters, except for whitespace, in a string to be\n     * used inside a regular expression as a string literal.\n     * @param {string} text The string.\n     * @return {string} The escaped string literal.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function escapeRegExp(text) {\n        return text.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#]/g, '\\\\$&');\n    }\n\n    /**\n     * Escapes special characters in a string to be used inside a regular\n     * expression as a string literal. Also ensures that HTML entities will\n     * be matched the same as their literal friends.\n     * @param {string} body The string.\n     * @return {string} The escaped string.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function escapeCodeAsRegExpForMatchingInsideHTML(body) {\n        return escapeRegExp(body).replace('<', '(?:<|&lt;)').replace('>', '(?:>|&gt;)').replace('&', '(?:&|&amp;)').replace('\"', '(?:\"|&quot;)').replace(/\\s+/g, '\\\\s+');\n    }\n\n    /**\n     * Determines where a code fragment occurs in the source code.\n     * @param {RegExp} re The function definition.\n     * @param {Array.<string>} urls A list of URLs to search.\n     * @return {?Object.<string, (string|number)>} An object containing\n     * the url, line, and column number of the defined function.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function findSourceInUrls(re, urls) {\n        var source, m;\n        for (var i = 0, j = urls.length; i < j; ++i) {\n            // console.log('searching', urls[i]);\n            if ((source = getSource(urls[i])).length) {\n                source = source.join('\\n');\n                if ((m = re.exec(source))) {\n                    // console.log('Found function in ' + urls[i]);\n\n                    return {\n                        'url': urls[i],\n                        'line': source.substring(0, m.index).split('\\n').length,\n                        'column': m.index - source.lastIndexOf('\\n', m.index) - 1\n                    };\n                }\n            }\n        }\n\n        // console.log('no match');\n\n        return null;\n    }\n\n    /**\n     * Determines at which column a code fragment occurs on a line of the\n     * source code.\n     * @param {string} fragment The code fragment.\n     * @param {string} url The URL to search.\n     * @param {(string|number)} line The line number to examine.\n     * @return {?number} The column number.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function findSourceInLine(fragment, url, line) {\n        var source = getSource(url),\n            re = new RegExp('\\\\b' + escapeRegExp(fragment) + '\\\\b'),\n            m;\n\n        line -= 1;\n\n        if (source && source.length > line && (m = re.exec(source[line]))) {\n            return m.index;\n        }\n\n        return null;\n    }\n\n    /**\n     * Determines where a function was defined within the source code.\n     * @param {(Function|string)} func A function reference or serialized\n     * function definition.\n     * @return {?Object.<string, (string|number)>} An object containing\n     * the url, line, and column number of the defined function.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function findSourceByFunctionBody(func) {\n        if (_isUndefined(window && window.document)) {\n            return;\n        }\n\n        var urls = [window.location.href],\n            scripts = window.document.getElementsByTagName('script'),\n            body,\n            code = '' + func,\n            codeRE = /^function(?:\\s+([\\w$]+))?\\s*\\(([\\w\\s,]*)\\)\\s*\\{\\s*(\\S[\\s\\S]*\\S)\\s*\\}\\s*$/,\n            eventRE = /^function on([\\w$]+)\\s*\\(event\\)\\s*\\{\\s*(\\S[\\s\\S]*\\S)\\s*\\}\\s*$/,\n            re,\n            parts,\n            result;\n\n        for (var i = 0; i < scripts.length; ++i) {\n            var script = scripts[i];\n            if (script.src) {\n                urls.push(script.src);\n            }\n        }\n\n        if (!(parts = codeRE.exec(code))) {\n            re = new RegExp(escapeRegExp(code).replace(/\\s+/g, '\\\\s+'));\n        }\n\n        // not sure if this is really necessary, but I don’t have a test\n        // corpus large enough to confirm that and it was in the original.\n        else {\n            var name = parts[1] ? '\\\\s+' + parts[1] : '',\n                args = parts[2].split(',').join('\\\\s*,\\\\s*');\n\n            body = escapeRegExp(parts[3]).replace(/;$/, ';?'); // semicolon is inserted if the function ends with a comment.replace(/\\s+/g, '\\\\s+');\n            re = new RegExp('function' + name + '\\\\s*\\\\(\\\\s*' + args + '\\\\s*\\\\)\\\\s*{\\\\s*' + body + '\\\\s*}');\n        }\n\n        // look for a normal function definition\n        if ((result = findSourceInUrls(re, urls))) {\n            return result;\n        }\n\n        // look for an old-school event handler function\n        if ((parts = eventRE.exec(code))) {\n            var event = parts[1];\n            body = escapeCodeAsRegExpForMatchingInsideHTML(parts[2]);\n\n            // look for a function defined in HTML as an onXXX handler\n            re = new RegExp('on' + event + '=[\\\\\\'\"]\\\\s*' + body + '\\\\s*[\\\\\\'\"]', 'i');\n\n            if ((result = findSourceInUrls(re, urls[0]))) {\n                return result;\n            }\n\n            // look for ???\n            re = new RegExp(body);\n\n            if ((result = findSourceInUrls(re, urls))) {\n                return result;\n            }\n        }\n\n        return null;\n    }\n\n    // Contents of Exception in various browsers.\n    //\n    // SAFARI:\n    // ex.message = Can't find variable: qq\n    // ex.line = 59\n    // ex.sourceId = 580238192\n    // ex.sourceURL = http://...\n    // ex.expressionBeginOffset = 96\n    // ex.expressionCaretOffset = 98\n    // ex.expressionEndOffset = 98\n    // ex.name = ReferenceError\n    //\n    // FIREFOX:\n    // ex.message = qq is not defined\n    // ex.fileName = http://...\n    // ex.lineNumber = 59\n    // ex.columnNumber = 69\n    // ex.stack = ...stack trace... (see the example below)\n    // ex.name = ReferenceError\n    //\n    // CHROME:\n    // ex.message = qq is not defined\n    // ex.name = ReferenceError\n    // ex.type = not_defined\n    // ex.arguments = ['aa']\n    // ex.stack = ...stack trace...\n    //\n    // INTERNET EXPLORER:\n    // ex.message = ...\n    // ex.name = ReferenceError\n    //\n    // OPERA:\n    // ex.message = ...message... (see the example below)\n    // ex.name = ReferenceError\n    // ex.opera#sourceloc = 11  (pretty much useless, duplicates the info in ex.message)\n    // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace'\n\n    /**\n     * Computes stack trace information from the stack property.\n     * Chrome and Gecko use this property.\n     * @param {Error} ex\n     * @return {?TraceKit.StackTrace} Stack trace information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceFromStackProp(ex) {\n        if (!ex.stack) {\n            return null;\n        }\n\n        var chrome = /^\\s*at (.*?) ?\\(((?:file|https?|blob|chrome-extension|native|webpack|eval).*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i,\n            gecko = /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)((?:file|https?|blob|chrome|webpack|\\[native).*?)(?::(\\d+))?(?::(\\d+))?\\s*$/i,\n            winjs = /^\\s*at (?:((?:\\[object object\\])?.+) )?\\(?((?:ms-appx|https?|webpack|blob):.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i,\n            lines = ex.stack.split('\\n'),\n            stack = [],\n            parts,\n            element,\n            reference = /^(.*) is undefined$/.exec(ex.message);\n\n        for (var i = 0, j = lines.length; i < j; ++i) {\n            if ((parts = chrome.exec(lines[i]))) {\n                var isNative = parts[2] && parts[2].indexOf('native') !== -1;\n                element = {\n                    'url': !isNative ? parts[2] : null,\n                    'func': parts[1] || UNKNOWN_FUNCTION,\n                    'args': isNative ? [parts[2]] : [],\n                    'line': parts[3] ? +parts[3] : null,\n                    'column': parts[4] ? +parts[4] : null\n                };\n            } else if ( parts = winjs.exec(lines[i]) ) {\n                element = {\n                    'url': parts[2],\n                    'func': parts[1] || UNKNOWN_FUNCTION,\n                    'args': [],\n                    'line': +parts[3],\n                    'column': parts[4] ? +parts[4] : null\n                };\n            } else if ((parts = gecko.exec(lines[i]))) {\n                element = {\n                    'url': parts[3],\n                    'func': parts[1] || UNKNOWN_FUNCTION,\n                    'args': parts[2] ? parts[2].split(',') : [],\n                    'line': parts[4] ? +parts[4] : null,\n                    'column': parts[5] ? +parts[5] : null\n                };\n            } else {\n                continue;\n            }\n\n            if (!element.func && element.line) {\n                element.func = guessFunctionName(element.url, element.line);\n            }\n\n            if (element.line) {\n                element.context = gatherContext(element.url, element.line);\n            }\n\n            stack.push(element);\n        }\n\n        if (!stack.length) {\n            return null;\n        }\n\n        if (stack[0] && stack[0].line && !stack[0].column && reference) {\n            stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line);\n        } else if (!stack[0].column && !_isUndefined(ex.columnNumber)) {\n            // FireFox uses this awesome columnNumber property for its top frame\n            // Also note, Firefox's column number is 0-based and everything else expects 1-based,\n            // so adding 1\n            stack[0].column = ex.columnNumber + 1;\n        }\n\n        return {\n            'mode': 'stack',\n            'name': ex.name,\n            'message': ex.message,\n            'stack': stack\n        };\n    }\n\n    /**\n     * Computes stack trace information from the stacktrace property.\n     * Opera 10+ uses this property.\n     * @param {Error} ex\n     * @return {?TraceKit.StackTrace} Stack trace information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceFromStacktraceProp(ex) {\n        // Access and store the stacktrace property before doing ANYTHING\n        // else to it because Opera is not very good at providing it\n        // reliably in other circumstances.\n        var stacktrace = ex.stacktrace;\n        if (!stacktrace) {\n            return;\n        }\n\n        var opera10Regex = / line (\\d+).*script (?:in )?(\\S+)(?:: in function (\\S+))?$/i,\n            opera11Regex = / line (\\d+), column (\\d+)\\s*(?:in (?:<anonymous function: ([^>]+)>|([^\\)]+))\\((.*)\\))? in (.*):\\s*$/i,\n            lines = stacktrace.split('\\n'),\n            stack = [],\n            parts;\n\n        for (var line = 0; line < lines.length; line += 2) {\n            var element = null;\n            if ((parts = opera10Regex.exec(lines[line]))) {\n                element = {\n                    'url': parts[2],\n                    'line': +parts[1],\n                    'column': null,\n                    'func': parts[3],\n                    'args':[]\n                };\n            } else if ((parts = opera11Regex.exec(lines[line]))) {\n                element = {\n                    'url': parts[6],\n                    'line': +parts[1],\n                    'column': +parts[2],\n                    'func': parts[3] || parts[4],\n                    'args': parts[5] ? parts[5].split(',') : []\n                };\n            }\n\n            if (element) {\n                if (!element.func && element.line) {\n                    element.func = guessFunctionName(element.url, element.line);\n                }\n                if (element.line) {\n                    try {\n                        element.context = gatherContext(element.url, element.line);\n                    } catch (exc) {}\n                }\n\n                if (!element.context) {\n                    element.context = [lines[line + 1]];\n                }\n\n                stack.push(element);\n            }\n        }\n\n        if (!stack.length) {\n            return null;\n        }\n\n        return {\n            'mode': 'stacktrace',\n            'name': ex.name,\n            'message': ex.message,\n            'stack': stack\n        };\n    }\n\n    /**\n     * NOT TESTED.\n     * Computes stack trace information from an error message that includes\n     * the stack trace.\n     * Opera 9 and earlier use this method if the option to show stack\n     * traces is turned on in opera:config.\n     * @param {Error} ex\n     * @return {?TraceKit.StackTrace} Stack information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceFromOperaMultiLineMessage(ex) {\n        // TODO: Clean this function up\n        // Opera includes a stack trace into the exception message. An example is:\n        //\n        // Statement on line 3: Undefined variable: undefinedFunc\n        // Backtrace:\n        //   Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz\n        //         undefinedFunc(a);\n        //   Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy\n        //           zzz(x, y, z);\n        //   Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx\n        //           yyy(a, a, a);\n        //   Line 1 of function script\n        //     try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); }\n        //   ...\n\n        var lines = ex.message.split('\\n');\n        if (lines.length < 4) {\n            return null;\n        }\n\n        var lineRE1 = /^\\s*Line (\\d+) of linked script ((?:file|https?|blob)\\S+)(?:: in function (\\S+))?\\s*$/i,\n            lineRE2 = /^\\s*Line (\\d+) of inline#(\\d+) script in ((?:file|https?|blob)\\S+)(?:: in function (\\S+))?\\s*$/i,\n            lineRE3 = /^\\s*Line (\\d+) of function script\\s*$/i,\n            stack = [],\n            scripts = (window && window.document && window.document.getElementsByTagName('script')),\n            inlineScriptBlocks = [],\n            parts;\n\n        for (var s in scripts) {\n            if (_has(scripts, s) && !scripts[s].src) {\n                inlineScriptBlocks.push(scripts[s]);\n            }\n        }\n\n        for (var line = 2; line < lines.length; line += 2) {\n            var item = null;\n            if ((parts = lineRE1.exec(lines[line]))) {\n                item = {\n                    'url': parts[2],\n                    'func': parts[3],\n                    'args': [],\n                    'line': +parts[1],\n                    'column': null\n                };\n            } else if ((parts = lineRE2.exec(lines[line]))) {\n                item = {\n                    'url': parts[3],\n                    'func': parts[4],\n                    'args': [],\n                    'line': +parts[1],\n                    'column': null // TODO: Check to see if inline#1 (+parts[2]) points to the script number or column number.\n                };\n                var relativeLine = (+parts[1]); // relative to the start of the <SCRIPT> block\n                var script = inlineScriptBlocks[parts[2] - 1];\n                if (script) {\n                    var source = getSource(item.url);\n                    if (source) {\n                        source = source.join('\\n');\n                        var pos = source.indexOf(script.innerText);\n                        if (pos >= 0) {\n                            item.line = relativeLine + source.substring(0, pos).split('\\n').length;\n                        }\n                    }\n                }\n            } else if ((parts = lineRE3.exec(lines[line]))) {\n                var url = window.location.href.replace(/#.*$/, '');\n                var re = new RegExp(escapeCodeAsRegExpForMatchingInsideHTML(lines[line + 1]));\n                var src = findSourceInUrls(re, [url]);\n                item = {\n                    'url': url,\n                    'func': '',\n                    'args': [],\n                    'line': src ? src.line : parts[1],\n                    'column': null\n                };\n            }\n\n            if (item) {\n                if (!item.func) {\n                    item.func = guessFunctionName(item.url, item.line);\n                }\n                var context = gatherContext(item.url, item.line);\n                var midline = (context ? context[Math.floor(context.length / 2)] : null);\n                if (context && midline.replace(/^\\s*/, '') === lines[line + 1].replace(/^\\s*/, '')) {\n                    item.context = context;\n                } else {\n                    // if (context) alert(\"Context mismatch. Correct midline:\\n\" + lines[i+1] + \"\\n\\nMidline:\\n\" + midline + \"\\n\\nContext:\\n\" + context.join(\"\\n\") + \"\\n\\nURL:\\n\" + item.url);\n                    item.context = [lines[line + 1]];\n                }\n                stack.push(item);\n            }\n        }\n        if (!stack.length) {\n            return null; // could not parse multiline exception message as Opera stack trace\n        }\n\n        return {\n            'mode': 'multiline',\n            'name': ex.name,\n            'message': lines[0],\n            'stack': stack\n        };\n    }\n\n    /**\n     * Adds information about the first frame to incomplete stack traces.\n     * Safari and IE require this to get complete data on the first frame.\n     * @param {TraceKit.StackTrace} stackInfo Stack trace information from\n     * one of the compute* methods.\n     * @param {string} url The URL of the script that caused an error.\n     * @param {(number|string)} lineNo The line number of the script that\n     * caused an error.\n     * @param {string=} message The error generated by the browser, which\n     * hopefully contains the name of the object that caused the error.\n     * @return {boolean} Whether or not the stack information was\n     * augmented.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function augmentStackTraceWithInitialElement(stackInfo, url, lineNo, message) {\n        var initial = {\n            'url': url,\n            'line': lineNo\n        };\n\n        if (initial.url && initial.line) {\n            stackInfo.incomplete = false;\n\n            if (!initial.func) {\n                initial.func = guessFunctionName(initial.url, initial.line);\n            }\n\n            if (!initial.context) {\n                initial.context = gatherContext(initial.url, initial.line);\n            }\n\n            var reference = / '([^']+)' /.exec(message);\n            if (reference) {\n                initial.column = findSourceInLine(reference[1], initial.url, initial.line);\n            }\n\n            if (stackInfo.stack.length > 0) {\n                if (stackInfo.stack[0].url === initial.url) {\n                    if (stackInfo.stack[0].line === initial.line) {\n                        return false; // already in stack trace\n                    } else if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) {\n                        stackInfo.stack[0].line = initial.line;\n                        stackInfo.stack[0].context = initial.context;\n                        return false;\n                    }\n                }\n            }\n\n            stackInfo.stack.unshift(initial);\n            stackInfo.partial = true;\n            return true;\n        } else {\n            stackInfo.incomplete = true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Computes stack trace information by walking the arguments.caller\n     * chain at the time the exception occurred. This will cause earlier\n     * frames to be missed but is the only way to get any stack trace in\n     * Safari and IE. The top frame is restored by\n     * {@link augmentStackTraceWithInitialElement}.\n     * @param {Error} ex\n     * @return {TraceKit.StackTrace=} Stack trace information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceByWalkingCallerChain(ex, depth) {\n        var functionName = /function\\s+([_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*)?\\s*\\(/i,\n            stack = [],\n            funcs = {},\n            recursion = false,\n            parts,\n            item,\n            source;\n\n        for (var curr = computeStackTraceByWalkingCallerChain.caller; curr && !recursion; curr = curr.caller) {\n            if (curr === computeStackTrace || curr === TraceKit.report) {\n                // console.log('skipping internal function');\n                continue;\n            }\n\n            item = {\n                'url': null,\n                'func': UNKNOWN_FUNCTION,\n                'args': [],\n                'line': null,\n                'column': null\n            };\n\n            if (curr.name) {\n                item.func = curr.name;\n            } else if ((parts = functionName.exec(curr.toString()))) {\n                item.func = parts[1];\n            }\n\n            if (typeof item.func === 'undefined') {\n              try {\n                item.func = parts.input.substring(0, parts.input.indexOf('{'));\n              } catch (e) { }\n            }\n\n            if ((source = findSourceByFunctionBody(curr))) {\n                item.url = source.url;\n                item.line = source.line;\n\n                if (item.func === UNKNOWN_FUNCTION) {\n                    item.func = guessFunctionName(item.url, item.line);\n                }\n\n                var reference = / '([^']+)' /.exec(ex.message || ex.description);\n                if (reference) {\n                    item.column = findSourceInLine(reference[1], source.url, source.line);\n                }\n            }\n\n            if (funcs['' + curr]) {\n                recursion = true;\n            }else{\n                funcs['' + curr] = true;\n            }\n\n            stack.push(item);\n        }\n\n        if (depth) {\n            // console.log('depth is ' + depth);\n            // console.log('stack is ' + stack.length);\n            stack.splice(0, depth);\n        }\n\n        var result = {\n            'mode': 'callers',\n            'name': ex.name,\n            'message': ex.message,\n            'stack': stack\n        };\n        augmentStackTraceWithInitialElement(result, ex.sourceURL || ex.fileName, ex.line || ex.lineNumber, ex.message || ex.description);\n        return result;\n    }\n\n    /**\n     * Computes a stack trace for an exception.\n     * @param {Error} ex\n     * @param {(string|number)=} depth\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTrace(ex, depth) {\n        var stack = null;\n        depth = (depth == null ? 0 : +depth);\n\n        try {\n            // This must be tried first because Opera 10 *destroys*\n            // its stacktrace property if you try to access the stack\n            // property first!!\n            stack = computeStackTraceFromStacktraceProp(ex);\n            if (stack) {\n                return stack;\n            }\n        } catch (e) {\n            if (debug) {\n                throw e;\n            }\n        }\n\n        try {\n            stack = computeStackTraceFromStackProp(ex);\n            if (stack) {\n                return stack;\n            }\n        } catch (e) {\n            if (debug) {\n                throw e;\n            }\n        }\n\n        try {\n            stack = computeStackTraceFromOperaMultiLineMessage(ex);\n            if (stack) {\n                return stack;\n            }\n        } catch (e) {\n            if (debug) {\n                throw e;\n            }\n        }\n\n        try {\n            stack = computeStackTraceByWalkingCallerChain(ex, depth + 1);\n            if (stack) {\n                return stack;\n            }\n        } catch (e) {\n            if (debug) {\n                throw e;\n            }\n        }\n\n        return {\n            'mode': 'failed'\n        };\n    }\n\n    /**\n     * Logs a stacktrace starting from the previous call and working down.\n     * @param {(number|string)=} depth How many frames deep to trace.\n     * @return {TraceKit.StackTrace} Stack trace information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceOfCaller(depth) {\n        depth = (depth == null ? 0 : +depth) + 1; // \"+ 1\" because \"ofCaller\" should drop one frame\n        try {\n            throw new Error();\n        } catch (ex) {\n            return computeStackTrace(ex, depth + 1);\n        }\n    }\n\n    computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement;\n    computeStackTrace.guessFunctionName = guessFunctionName;\n    computeStackTrace.gatherContext = gatherContext;\n    computeStackTrace.ofCaller = computeStackTraceOfCaller;\n    computeStackTrace.getSource = getSource;\n\n    return computeStackTrace;\n}());\n\n/**\n * Extends support for global error handling for asynchronous browser\n * functions. Adopted from Closure Library's errorhandler.js\n * @memberof TraceKit\n */\nTraceKit.extendToAsynchronousCallbacks = function () {\n    var _helper = function _helper(fnName) {\n        var originalFn = window[fnName];\n        window[fnName] = function traceKitAsyncExtension() {\n            // Make a copy of the arguments\n            var args = _slice.call(arguments);\n            var originalCallback = args[0];\n            if (typeof (originalCallback) === 'function') {\n                args[0] = TraceKit.wrap(originalCallback);\n            }\n            // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it\n            // also only supports 2 argument and doesn't care what \"this\" is, so we\n            // can just call the original function directly.\n            if (originalFn.apply) {\n                return originalFn.apply(this, args);\n            } else {\n                return originalFn(args[0], args[1]);\n            }\n        };\n    };\n\n    _helper('setTimeout');\n    _helper('setInterval');\n};\n\n//Default options:\nif (!TraceKit.remoteFetching) {\n    TraceKit.remoteFetching = true;\n}\nif (!TraceKit.collectWindowErrors) {\n    TraceKit.collectWindowErrors = true;\n}\nif (!TraceKit.linesOfContext || TraceKit.linesOfContext < 1) {\n    // 5 lines before, the offending line, 5 lines after\n    TraceKit.linesOfContext = 11;\n}\n\n// UMD export\nif (typeof module !== 'undefined' && module.exports && window.module !== module) {\n    module.exports = TraceKit;\n} else if (typeof define === 'function' && define.amd) {\n    define('TraceKit', [], TraceKit);\n} else {\n    window.TraceKit = TraceKit;\n}\n\n}(typeof window !== 'undefined' ? window : global));\n","/**\n * https://github.com/csnover/TraceKit\n * @license MIT\n * @namespace TraceKit\n */\n(function(window, undefined) {\nif (!window) {\n    return;\n}\n\nvar TraceKit = {};\nvar _oldTraceKit = window.TraceKit;\n\n// global reference to slice\nvar _slice = [].slice;\nvar UNKNOWN_FUNCTION = '?';\n\n/**\n * A better form of hasOwnProperty<br/>\n * Example: `_has(MainHostObject, property) === true/false`\n *\n * @param {Object} object to check property\n * @param {string} key to check\n * @return {Boolean} true if the object has the key and it is not inherited\n */\nfunction _has(object, key) {\n    return Object.prototype.hasOwnProperty.call(object, key);\n}\n\n/**\n * Returns true if the parameter is undefined<br/>\n * Example: `_isUndefined(val) === true/false`\n *\n * @param {*} what Value to check\n * @return {Boolean} true if undefined and false otherwise\n */\nfunction _isUndefined(what) {\n    return typeof what === 'undefined';\n}\n\n/**\n * Export TraceKit out to another variable<br/>\n * Example: `var TK = TraceKit.noConflict()`\n * @return {Object} The TraceKit object\n * @memberof TraceKit\n */\nTraceKit.noConflict = function noConflict() {\n    window.TraceKit = _oldTraceKit;\n    return TraceKit;\n};\n\n/**\n * Wrap any function in a TraceKit reporter<br/>\n * Example: `func = TraceKit.wrap(func);`\n *\n * @param {Function} func Function to be wrapped\n * @return {Function} The wrapped func\n * @memberof TraceKit\n */\nTraceKit.wrap = function traceKitWrapper(func) {\n    function wrapped() {\n        try {\n            return func.apply(this, arguments);\n        } catch (e) {\n            TraceKit.report(e);\n            throw e;\n        }\n    }\n    return wrapped;\n};\n\n/**\n * Cross-browser processing of unhandled exceptions\n *\n * Syntax:\n * ```js\n *   TraceKit.report.subscribe(function(stackInfo) { ... })\n *   TraceKit.report.unsubscribe(function(stackInfo) { ... })\n *   TraceKit.report(exception)\n *   try { ...code... } catch(ex) { TraceKit.report(ex); }\n * ```\n *\n * Supports:\n *   - Firefox: full stack trace with line numbers, plus column number\n *     on top frame; column number is not guaranteed\n *   - Opera: full stack trace with line and column numbers\n *   - Chrome: full stack trace with line and column numbers\n *   - Safari: line and column number for the top frame only; some frames\n *     may be missing, and column number is not guaranteed\n *   - IE: line and column number for the top frame only; some frames\n *     may be missing, and column number is not guaranteed\n *\n * In theory, TraceKit should work on all of the following versions:\n *   - IE5.5+ (only 8.0 tested)\n *   - Firefox 0.9+ (only 3.5+ tested)\n *   - Opera 7+ (only 10.50 tested; versions 9 and earlier may require\n *     Exceptions Have Stacktrace to be enabled in opera:config)\n *   - Safari 3+ (only 4+ tested)\n *   - Chrome 1+ (only 5+ tested)\n *   - Konqueror 3.5+ (untested)\n *\n * Requires TraceKit.computeStackTrace.\n *\n * Tries to catch all unhandled exceptions and report them to the\n * subscribed handlers. Please note that TraceKit.report will rethrow the\n * exception. This is REQUIRED in order to get a useful stack trace in IE.\n * If the exception does not reach the top of the browser, you will only\n * get a stack trace from the point where TraceKit.report was called.\n *\n * Handlers receive a TraceKit.StackTrace object as described in the\n * TraceKit.computeStackTrace docs.\n *\n * @memberof TraceKit\n * @namespace\n */\nTraceKit.report = (function reportModuleWrapper() {\n    var handlers = [],\n        lastArgs = null,\n        lastException = null,\n        lastExceptionStack = null;\n\n    /**\n     * Add a crash handler.\n     * @param {Function} handler\n     * @memberof TraceKit.report\n     */\n    function subscribe(handler) {\n        installGlobalHandler();\n        handlers.push(handler);\n    }\n\n    /**\n     * Remove a crash handler.\n     * @param {Function} handler\n     * @memberof TraceKit.report\n     */\n    function unsubscribe(handler) {\n        for (var i = handlers.length - 1; i >= 0; --i) {\n            if (handlers[i] === handler) {\n                handlers.splice(i, 1);\n            }\n        }\n    }\n\n    /**\n     * Dispatch stack information to all handlers.\n     * @param {TraceKit.StackTrace} stack\n     * @param {boolean} isWindowError Is this a top-level window error?\n     * @memberof TraceKit.report\n     * @throws An exception if an error occurs while calling an handler.\n     */\n    function notifyHandlers(stack, isWindowError) {\n        var exception = null;\n        if (isWindowError && !TraceKit.collectWindowErrors) {\n          return;\n        }\n        for (var i in handlers) {\n            if (_has(handlers, i)) {\n                try {\n                    handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2)));\n                } catch (inner) {\n                    exception = inner;\n                }\n            }\n        }\n\n        if (exception) {\n            throw exception;\n        }\n    }\n\n    var _oldOnerrorHandler, _onErrorHandlerInstalled;\n\n    /**\n     * Ensures all global unhandled exceptions are recorded.\n     * Supported by Gecko and IE.\n     * @param {string} message Error message.\n     * @param {string} url URL of script that generated the exception.\n     * @param {(number|string)} lineNo The line number at which the error occurred.\n     * @param {(number|string)=} columnNo The column number at which the error occurred.\n     * @param {Error=} errorObj The actual Error object.\n     * @memberof TraceKit.report\n     */\n    function traceKitWindowOnError(message, url, lineNo, columnNo, errorObj) {\n        var stack = null;\n\n        if (lastExceptionStack) {\n            TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message);\n    \t    processLastException();\n\t    } else if (errorObj) {\n            stack = TraceKit.computeStackTrace(errorObj);\n            notifyHandlers(stack, true);\n        } else {\n            var location = {\n              'url': url,\n              'line': lineNo,\n              'column': columnNo\n            };\n            location.func = TraceKit.computeStackTrace.guessFunctionName(location.url, location.line);\n            location.context = TraceKit.computeStackTrace.gatherContext(location.url, location.line);\n            stack = {\n              'mode': 'onerror',\n              'message': message,\n              'stack': [location]\n            };\n\n            notifyHandlers(stack, true);\n        }\n\n        if (_oldOnerrorHandler) {\n            return _oldOnerrorHandler.apply(this, arguments);\n        }\n\n        return false;\n    }\n\n    /**\n     * Install a global onerror handler\n     * @memberof TraceKit.report\n     */\n    function installGlobalHandler () {\n        if (_onErrorHandlerInstalled === true) {\n            return;\n        }\n        _oldOnerrorHandler = window.onerror;\n        window.onerror = traceKitWindowOnError;\n        _onErrorHandlerInstalled = true;\n    }\n\n    /**\n     * Process the most recent exception\n     * @memberof TraceKit.report\n     */\n    function processLastException() {\n        var _lastExceptionStack = lastExceptionStack,\n            _lastArgs = lastArgs;\n        lastArgs = null;\n        lastExceptionStack = null;\n        lastException = null;\n        notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs));\n    }\n\n    /**\n     * Reports an unhandled Error to TraceKit.\n     * @param {Error} ex\n     * @memberof TraceKit.report\n     * @throws An exception if an incomplete stack trace is detected (old IE browsers).\n     */\n    function report(ex) {\n        if (lastExceptionStack) {\n            if (lastException === ex) {\n                return; // already caught by an inner catch block, ignore\n            } else {\n              processLastException();\n            }\n        }\n\n        var stack = TraceKit.computeStackTrace(ex);\n        lastExceptionStack = stack;\n        lastException = ex;\n        lastArgs = _slice.call(arguments, 1);\n\n        // If the stack trace is incomplete, wait for 2 seconds for\n        // slow slow IE to see if onerror occurs or not before reporting\n        // this exception; otherwise, we will end up with an incomplete\n        // stack trace\n        window.setTimeout(function () {\n            if (lastException === ex) {\n                processLastException();\n            }\n        }, (stack.incomplete ? 2000 : 0));\n\n        throw ex; // re-throw to propagate to the top level (and cause window.onerror)\n    }\n\n    report.subscribe = subscribe;\n    report.unsubscribe = unsubscribe;\n    return report;\n}());\n\n/**\n * An object representing a single stack frame.\n * @typedef {Object} StackFrame\n * @property {string} url The JavaScript or HTML file URL.\n * @property {string} func The function name, or empty for anonymous functions (if guessing did not work).\n * @property {string[]?} args The arguments passed to the function, if known.\n * @property {number=} line The line number, if known.\n * @property {number=} column The column number, if known.\n * @property {string[]} context An array of source code lines; the middle element corresponds to the correct line#.\n * @memberof TraceKit\n */\n\n/**\n * An object representing a JavaScript stack trace.\n * @typedef {Object} StackTrace\n * @property {string} name The name of the thrown exception.\n * @property {string} message The exception error message.\n * @property {TraceKit.StackFrame[]} stack An array of stack frames.\n * @property {string} mode 'stack', 'stacktrace', 'multiline', 'callers', 'onerror', or 'failed' -- method used to collect the stack trace.\n * @memberof TraceKit\n */\n\n/**\n * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript\n *\n * Syntax:\n *   ```js\n *   s = TraceKit.computeStackTrace.ofCaller([depth])\n *   s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below)\n *   ```\n *\n * Supports:\n *   - Firefox:  full stack trace with line numbers and unreliable column\n *               number on top frame\n *   - Opera 10: full stack trace with line and column numbers\n *   - Opera 9-: full stack trace with line numbers\n *   - Chrome:   full stack trace with line and column numbers\n *   - Safari:   line and column number for the topmost stacktrace element\n *               only\n *   - IE:       no line numbers whatsoever\n *\n * Tries to guess names of anonymous functions by looking for assignments\n * in the source code. In IE and Safari, we have to guess source file names\n * by searching for function bodies inside all page scripts. This will not\n * work for scripts that are loaded cross-domain.\n * Here be dragons: some function names may be guessed incorrectly, and\n * duplicate functions may be mismatched.\n *\n * TraceKit.computeStackTrace should only be used for tracing purposes.\n * Logging of unhandled exceptions should be done with TraceKit.report,\n * which builds on top of TraceKit.computeStackTrace and provides better\n * IE support by utilizing the window.onerror event to retrieve information\n * about the top of the stack.\n *\n * Note: In IE and Safari, no stack trace is recorded on the Error object,\n * so computeStackTrace instead walks its *own* chain of callers.\n * This means that:\n *  * in Safari, some methods may be missing from the stack trace;\n *  * in IE, the topmost function in the stack trace will always be the\n *    caller of computeStackTrace.\n *\n * This is okay for tracing (because you are likely to be calling\n * computeStackTrace from the function you want to be the topmost element\n * of the stack trace anyway), but not okay for logging unhandled\n * exceptions (because your catch block will likely be far away from the\n * inner function that actually caused the exception).\n *\n * Tracing example:\n *  ```js\n *     function trace(message) {\n *         var stackInfo = TraceKit.computeStackTrace.ofCaller();\n *         var data = message + \"\\n\";\n *         for(var i in stackInfo.stack) {\n *             var item = stackInfo.stack[i];\n *             data += (item.func || '[anonymous]') + \"() in \" + item.url + \":\" + (item.line || '0') + \"\\n\";\n *         }\n *         if (window.console)\n *             console.info(data);\n *         else\n *             alert(data);\n *     }\n * ```\n * @memberof TraceKit\n * @namespace\n */\nTraceKit.computeStackTrace = (function computeStackTraceWrapper() {\n    var debug = false,\n        sourceCache = {};\n\n    /**\n     * Attempts to retrieve source code via XMLHttpRequest, which is used\n     * to look up anonymous function names.\n     * @param {string} url URL of source code.\n     * @return {string} Source contents.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function loadSource(url) {\n        if (!TraceKit.remoteFetching) { //Only attempt request if remoteFetching is on.\n            return '';\n        }\n        try {\n            var getXHR = function() {\n                try {\n                    return new window.XMLHttpRequest();\n                } catch (e) {\n                    // explicitly bubble up the exception if not found\n                    return new window.ActiveXObject('Microsoft.XMLHTTP');\n                }\n            };\n\n            var request = getXHR();\n            request.open('GET', url, false);\n            request.send('');\n            return request.responseText;\n        } catch (e) {\n            return '';\n        }\n    }\n\n    /**\n     * Retrieves source code from the source code cache.\n     * @param {string} url URL of source code.\n     * @return {Array.<string>} Source contents.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function getSource(url) {\n        if (typeof url !== 'string') {\n            return [];\n        }\n\n        if (!_has(sourceCache, url)) {\n            // URL needs to be able to fetched within the acceptable domain.  Otherwise,\n            // cross-domain errors will be triggered.\n            /*\n                Regex matches:\n                0 - Full Url\n                1 - Protocol\n                2 - Domain\n                3 - Port (Useful for internal applications)\n                4 - Path\n            */\n            var source = '';\n            var domain = '';\n            try { domain = window.document.domain; } catch (e) { }\n            var match = /(.*)\\:\\/\\/([^:\\/]+)([:\\d]*)\\/{0,1}([\\s\\S]*)/.exec(url);\n            if (match && match[2] === domain) {\n                source = loadSource(url);\n            }\n            sourceCache[url] = source ? source.split('\\n') : [];\n        }\n\n        return sourceCache[url];\n    }\n\n    /**\n     * Tries to use an externally loaded copy of source code to determine\n     * the name of a function by looking at the name of the variable it was\n     * assigned to, if any.\n     * @param {string} url URL of source code.\n     * @param {(string|number)} lineNo Line number in source code.\n     * @return {string} The function name, if discoverable.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function guessFunctionName(url, lineNo) {\n        var reFunctionArgNames = /function ([^(]*)\\(([^)]*)\\)/,\n            reGuessFunction = /['\"]?([0-9A-Za-z$_]+)['\"]?\\s*[:=]\\s*(function|eval|new Function)/,\n            line = '',\n            maxLines = 10,\n            source = getSource(url),\n            m;\n\n        if (!source.length) {\n            return UNKNOWN_FUNCTION;\n        }\n\n        // Walk backwards from the first line in the function until we find the line which\n        // matches the pattern above, which is the function definition\n        for (var i = 0; i < maxLines; ++i) {\n            line = source[lineNo - i] + line;\n\n            if (!_isUndefined(line)) {\n                if ((m = reGuessFunction.exec(line))) {\n                    return m[1];\n                } else if ((m = reFunctionArgNames.exec(line))) {\n                    return m[1];\n                }\n            }\n        }\n\n        return UNKNOWN_FUNCTION;\n    }\n\n    /**\n     * Retrieves the surrounding lines from where an exception occurred.\n     * @param {string} url URL of source code.\n     * @param {(string|number)} line Line number in source code to centre\n     * around for context.\n     * @return {?Array.<string>} Lines of source code.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function gatherContext(url, line) {\n        var source = getSource(url);\n\n        if (!source.length) {\n            return null;\n        }\n\n        var context = [],\n            // linesBefore & linesAfter are inclusive with the offending line.\n            // if linesOfContext is even, there will be one extra line\n            //   *before* the offending line.\n            linesBefore = Math.floor(TraceKit.linesOfContext / 2),\n            // Add one extra line if linesOfContext is odd\n            linesAfter = linesBefore + (TraceKit.linesOfContext % 2),\n            start = Math.max(0, line - linesBefore - 1),\n            end = Math.min(source.length, line + linesAfter - 1);\n\n        line -= 1; // convert to 0-based index\n\n        for (var i = start; i < end; ++i) {\n            if (!_isUndefined(source[i])) {\n                context.push(source[i]);\n            }\n        }\n\n        return context.length > 0 ? context : null;\n    }\n\n    /**\n     * Escapes special characters, except for whitespace, in a string to be\n     * used inside a regular expression as a string literal.\n     * @param {string} text The string.\n     * @return {string} The escaped string literal.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function escapeRegExp(text) {\n        return text.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#]/g, '\\\\$&');\n    }\n\n    /**\n     * Escapes special characters in a string to be used inside a regular\n     * expression as a string literal. Also ensures that HTML entities will\n     * be matched the same as their literal friends.\n     * @param {string} body The string.\n     * @return {string} The escaped string.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function escapeCodeAsRegExpForMatchingInsideHTML(body) {\n        return escapeRegExp(body).replace('<', '(?:<|&lt;)').replace('>', '(?:>|&gt;)').replace('&', '(?:&|&amp;)').replace('\"', '(?:\"|&quot;)').replace(/\\s+/g, '\\\\s+');\n    }\n\n    /**\n     * Determines where a code fragment occurs in the source code.\n     * @param {RegExp} re The function definition.\n     * @param {Array.<string>} urls A list of URLs to search.\n     * @return {?Object.<string, (string|number)>} An object containing\n     * the url, line, and column number of the defined function.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function findSourceInUrls(re, urls) {\n        var source, m;\n        for (var i = 0, j = urls.length; i < j; ++i) {\n            // console.log('searching', urls[i]);\n            if ((source = getSource(urls[i])).length) {\n                source = source.join('\\n');\n                if ((m = re.exec(source))) {\n                    // console.log('Found function in ' + urls[i]);\n\n                    return {\n                        'url': urls[i],\n                        'line': source.substring(0, m.index).split('\\n').length,\n                        'column': m.index - source.lastIndexOf('\\n', m.index) - 1\n                    };\n                }\n            }\n        }\n\n        // console.log('no match');\n\n        return null;\n    }\n\n    /**\n     * Determines at which column a code fragment occurs on a line of the\n     * source code.\n     * @param {string} fragment The code fragment.\n     * @param {string} url The URL to search.\n     * @param {(string|number)} line The line number to examine.\n     * @return {?number} The column number.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function findSourceInLine(fragment, url, line) {\n        var source = getSource(url),\n            re = new RegExp('\\\\b' + escapeRegExp(fragment) + '\\\\b'),\n            m;\n\n        line -= 1;\n\n        if (source && source.length > line && (m = re.exec(source[line]))) {\n            return m.index;\n        }\n\n        return null;\n    }\n\n    /**\n     * Determines where a function was defined within the source code.\n     * @param {(Function|string)} func A function reference or serialized\n     * function definition.\n     * @return {?Object.<string, (string|number)>} An object containing\n     * the url, line, and column number of the defined function.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function findSourceByFunctionBody(func) {\n        if (_isUndefined(window && window.document)) {\n            return;\n        }\n\n        var urls = [window.location.href],\n            scripts = window.document.getElementsByTagName('script'),\n            body,\n            code = '' + func,\n            codeRE = /^function(?:\\s+([\\w$]+))?\\s*\\(([\\w\\s,]*)\\)\\s*\\{\\s*(\\S[\\s\\S]*\\S)\\s*\\}\\s*$/,\n            eventRE = /^function on([\\w$]+)\\s*\\(event\\)\\s*\\{\\s*(\\S[\\s\\S]*\\S)\\s*\\}\\s*$/,\n            re,\n            parts,\n            result;\n\n        for (var i = 0; i < scripts.length; ++i) {\n            var script = scripts[i];\n            if (script.src) {\n                urls.push(script.src);\n            }\n        }\n\n        if (!(parts = codeRE.exec(code))) {\n            re = new RegExp(escapeRegExp(code).replace(/\\s+/g, '\\\\s+'));\n        }\n\n        // not sure if this is really necessary, but I don’t have a test\n        // corpus large enough to confirm that and it was in the original.\n        else {\n            var name = parts[1] ? '\\\\s+' + parts[1] : '',\n                args = parts[2].split(',').join('\\\\s*,\\\\s*');\n\n            body = escapeRegExp(parts[3]).replace(/;$/, ';?'); // semicolon is inserted if the function ends with a comment.replace(/\\s+/g, '\\\\s+');\n            re = new RegExp('function' + name + '\\\\s*\\\\(\\\\s*' + args + '\\\\s*\\\\)\\\\s*{\\\\s*' + body + '\\\\s*}');\n        }\n\n        // look for a normal function definition\n        if ((result = findSourceInUrls(re, urls))) {\n            return result;\n        }\n\n        // look for an old-school event handler function\n        if ((parts = eventRE.exec(code))) {\n            var event = parts[1];\n            body = escapeCodeAsRegExpForMatchingInsideHTML(parts[2]);\n\n            // look for a function defined in HTML as an onXXX handler\n            re = new RegExp('on' + event + '=[\\\\\\'\"]\\\\s*' + body + '\\\\s*[\\\\\\'\"]', 'i');\n\n            if ((result = findSourceInUrls(re, urls[0]))) {\n                return result;\n            }\n\n            // look for ???\n            re = new RegExp(body);\n\n            if ((result = findSourceInUrls(re, urls))) {\n                return result;\n            }\n        }\n\n        return null;\n    }\n\n    // Contents of Exception in various browsers.\n    //\n    // SAFARI:\n    // ex.message = Can't find variable: qq\n    // ex.line = 59\n    // ex.sourceId = 580238192\n    // ex.sourceURL = http://...\n    // ex.expressionBeginOffset = 96\n    // ex.expressionCaretOffset = 98\n    // ex.expressionEndOffset = 98\n    // ex.name = ReferenceError\n    //\n    // FIREFOX:\n    // ex.message = qq is not defined\n    // ex.fileName = http://...\n    // ex.lineNumber = 59\n    // ex.columnNumber = 69\n    // ex.stack = ...stack trace... (see the example below)\n    // ex.name = ReferenceError\n    //\n    // CHROME:\n    // ex.message = qq is not defined\n    // ex.name = ReferenceError\n    // ex.type = not_defined\n    // ex.arguments = ['aa']\n    // ex.stack = ...stack trace...\n    //\n    // INTERNET EXPLORER:\n    // ex.message = ...\n    // ex.name = ReferenceError\n    //\n    // OPERA:\n    // ex.message = ...message... (see the example below)\n    // ex.name = ReferenceError\n    // ex.opera#sourceloc = 11  (pretty much useless, duplicates the info in ex.message)\n    // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace'\n\n    /**\n     * Computes stack trace information from the stack property.\n     * Chrome and Gecko use this property.\n     * @param {Error} ex\n     * @return {?TraceKit.StackTrace} Stack trace information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceFromStackProp(ex) {\n        if (!ex.stack) {\n            return null;\n        }\n\n        var chrome = /^\\s*at (.*?) ?\\(((?:file|https?|blob|chrome-extension|native|webpack|eval).*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i,\n            gecko = /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)((?:file|https?|blob|chrome|webpack|\\[native).*?)(?::(\\d+))?(?::(\\d+))?\\s*$/i,\n            winjs = /^\\s*at (?:((?:\\[object object\\])?.+) )?\\(?((?:ms-appx|https?|webpack|blob):.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i,\n            lines = ex.stack.split('\\n'),\n            stack = [],\n            parts,\n            element,\n            reference = /^(.*) is undefined$/.exec(ex.message);\n\n        for (var i = 0, j = lines.length; i < j; ++i) {\n            if ((parts = chrome.exec(lines[i]))) {\n                var isNative = parts[2] && parts[2].indexOf('native') !== -1;\n                element = {\n                    'url': !isNative ? parts[2] : null,\n                    'func': parts[1] || UNKNOWN_FUNCTION,\n                    'args': isNative ? [parts[2]] : [],\n                    'line': parts[3] ? +parts[3] : null,\n                    'column': parts[4] ? +parts[4] : null\n                };\n            } else if ( parts = winjs.exec(lines[i]) ) {\n                element = {\n                    'url': parts[2],\n                    'func': parts[1] || UNKNOWN_FUNCTION,\n                    'args': [],\n                    'line': +parts[3],\n                    'column': parts[4] ? +parts[4] : null\n                };\n            } else if ((parts = gecko.exec(lines[i]))) {\n                element = {\n                    'url': parts[3],\n                    'func': parts[1] || UNKNOWN_FUNCTION,\n                    'args': parts[2] ? parts[2].split(',') : [],\n                    'line': parts[4] ? +parts[4] : null,\n                    'column': parts[5] ? +parts[5] : null\n                };\n            } else {\n                continue;\n            }\n\n            if (!element.func && element.line) {\n                element.func = guessFunctionName(element.url, element.line);\n            }\n\n            if (element.line) {\n                element.context = gatherContext(element.url, element.line);\n            }\n\n            stack.push(element);\n        }\n\n        if (!stack.length) {\n            return null;\n        }\n\n        if (stack[0] && stack[0].line && !stack[0].column && reference) {\n            stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line);\n        } else if (!stack[0].column && !_isUndefined(ex.columnNumber)) {\n            // FireFox uses this awesome columnNumber property for its top frame\n            // Also note, Firefox's column number is 0-based and everything else expects 1-based,\n            // so adding 1\n            stack[0].column = ex.columnNumber + 1;\n        }\n\n        return {\n            'mode': 'stack',\n            'name': ex.name,\n            'message': ex.message,\n            'stack': stack\n        };\n    }\n\n    /**\n     * Computes stack trace information from the stacktrace property.\n     * Opera 10+ uses this property.\n     * @param {Error} ex\n     * @return {?TraceKit.StackTrace} Stack trace information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceFromStacktraceProp(ex) {\n        // Access and store the stacktrace property before doing ANYTHING\n        // else to it because Opera is not very good at providing it\n        // reliably in other circumstances.\n        var stacktrace = ex.stacktrace;\n        if (!stacktrace) {\n            return;\n        }\n\n        var opera10Regex = / line (\\d+).*script (?:in )?(\\S+)(?:: in function (\\S+))?$/i,\n            opera11Regex = / line (\\d+), column (\\d+)\\s*(?:in (?:<anonymous function: ([^>]+)>|([^\\)]+))\\((.*)\\))? in (.*):\\s*$/i,\n            lines = stacktrace.split('\\n'),\n            stack = [],\n            parts;\n\n        for (var line = 0; line < lines.length; line += 2) {\n            var element = null;\n            if ((parts = opera10Regex.exec(lines[line]))) {\n                element = {\n                    'url': parts[2],\n                    'line': +parts[1],\n                    'column': null,\n                    'func': parts[3],\n                    'args':[]\n                };\n            } else if ((parts = opera11Regex.exec(lines[line]))) {\n                element = {\n                    'url': parts[6],\n                    'line': +parts[1],\n                    'column': +parts[2],\n                    'func': parts[3] || parts[4],\n                    'args': parts[5] ? parts[5].split(',') : []\n                };\n            }\n\n            if (element) {\n                if (!element.func && element.line) {\n                    element.func = guessFunctionName(element.url, element.line);\n                }\n                if (element.line) {\n                    try {\n                        element.context = gatherContext(element.url, element.line);\n                    } catch (exc) {}\n                }\n\n                if (!element.context) {\n                    element.context = [lines[line + 1]];\n                }\n\n                stack.push(element);\n            }\n        }\n\n        if (!stack.length) {\n            return null;\n        }\n\n        return {\n            'mode': 'stacktrace',\n            'name': ex.name,\n            'message': ex.message,\n            'stack': stack\n        };\n    }\n\n    /**\n     * NOT TESTED.\n     * Computes stack trace information from an error message that includes\n     * the stack trace.\n     * Opera 9 and earlier use this method if the option to show stack\n     * traces is turned on in opera:config.\n     * @param {Error} ex\n     * @return {?TraceKit.StackTrace} Stack information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceFromOperaMultiLineMessage(ex) {\n        // TODO: Clean this function up\n        // Opera includes a stack trace into the exception message. An example is:\n        //\n        // Statement on line 3: Undefined variable: undefinedFunc\n        // Backtrace:\n        //   Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz\n        //         undefinedFunc(a);\n        //   Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy\n        //           zzz(x, y, z);\n        //   Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx\n        //           yyy(a, a, a);\n        //   Line 1 of function script\n        //     try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); }\n        //   ...\n\n        var lines = ex.message.split('\\n');\n        if (lines.length < 4) {\n            return null;\n        }\n\n        var lineRE1 = /^\\s*Line (\\d+) of linked script ((?:file|https?|blob)\\S+)(?:: in function (\\S+))?\\s*$/i,\n            lineRE2 = /^\\s*Line (\\d+) of inline#(\\d+) script in ((?:file|https?|blob)\\S+)(?:: in function (\\S+))?\\s*$/i,\n            lineRE3 = /^\\s*Line (\\d+) of function script\\s*$/i,\n            stack = [],\n            scripts = (window && window.document && window.document.getElementsByTagName('script')),\n            inlineScriptBlocks = [],\n            parts;\n\n        for (var s in scripts) {\n            if (_has(scripts, s) && !scripts[s].src) {\n                inlineScriptBlocks.push(scripts[s]);\n            }\n        }\n\n        for (var line = 2; line < lines.length; line += 2) {\n            var item = null;\n            if ((parts = lineRE1.exec(lines[line]))) {\n                item = {\n                    'url': parts[2],\n                    'func': parts[3],\n                    'args': [],\n                    'line': +parts[1],\n                    'column': null\n                };\n            } else if ((parts = lineRE2.exec(lines[line]))) {\n                item = {\n                    'url': parts[3],\n                    'func': parts[4],\n                    'args': [],\n                    'line': +parts[1],\n                    'column': null // TODO: Check to see if inline#1 (+parts[2]) points to the script number or column number.\n                };\n                var relativeLine = (+parts[1]); // relative to the start of the <SCRIPT> block\n                var script = inlineScriptBlocks[parts[2] - 1];\n                if (script) {\n                    var source = getSource(item.url);\n                    if (source) {\n                        source = source.join('\\n');\n                        var pos = source.indexOf(script.innerText);\n                        if (pos >= 0) {\n                            item.line = relativeLine + source.substring(0, pos).split('\\n').length;\n                        }\n                    }\n                }\n            } else if ((parts = lineRE3.exec(lines[line]))) {\n                var url = window.location.href.replace(/#.*$/, '');\n                var re = new RegExp(escapeCodeAsRegExpForMatchingInsideHTML(lines[line + 1]));\n                var src = findSourceInUrls(re, [url]);\n                item = {\n                    'url': url,\n                    'func': '',\n                    'args': [],\n                    'line': src ? src.line : parts[1],\n                    'column': null\n                };\n            }\n\n            if (item) {\n                if (!item.func) {\n                    item.func = guessFunctionName(item.url, item.line);\n                }\n                var context = gatherContext(item.url, item.line);\n                var midline = (context ? context[Math.floor(context.length / 2)] : null);\n                if (context && midline.replace(/^\\s*/, '') === lines[line + 1].replace(/^\\s*/, '')) {\n                    item.context = context;\n                } else {\n                    // if (context) alert(\"Context mismatch. Correct midline:\\n\" + lines[i+1] + \"\\n\\nMidline:\\n\" + midline + \"\\n\\nContext:\\n\" + context.join(\"\\n\") + \"\\n\\nURL:\\n\" + item.url);\n                    item.context = [lines[line + 1]];\n                }\n                stack.push(item);\n            }\n        }\n        if (!stack.length) {\n            return null; // could not parse multiline exception message as Opera stack trace\n        }\n\n        return {\n            'mode': 'multiline',\n            'name': ex.name,\n            'message': lines[0],\n            'stack': stack\n        };\n    }\n\n    /**\n     * Adds information about the first frame to incomplete stack traces.\n     * Safari and IE require this to get complete data on the first frame.\n     * @param {TraceKit.StackTrace} stackInfo Stack trace information from\n     * one of the compute* methods.\n     * @param {string} url The URL of the script that caused an error.\n     * @param {(number|string)} lineNo The line number of the script that\n     * caused an error.\n     * @param {string=} message The error generated by the browser, which\n     * hopefully contains the name of the object that caused the error.\n     * @return {boolean} Whether or not the stack information was\n     * augmented.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function augmentStackTraceWithInitialElement(stackInfo, url, lineNo, message) {\n        var initial = {\n            'url': url,\n            'line': lineNo\n        };\n\n        if (initial.url && initial.line) {\n            stackInfo.incomplete = false;\n\n            if (!initial.func) {\n                initial.func = guessFunctionName(initial.url, initial.line);\n            }\n\n            if (!initial.context) {\n                initial.context = gatherContext(initial.url, initial.line);\n            }\n\n            var reference = / '([^']+)' /.exec(message);\n            if (reference) {\n                initial.column = findSourceInLine(reference[1], initial.url, initial.line);\n            }\n\n            if (stackInfo.stack.length > 0) {\n                if (stackInfo.stack[0].url === initial.url) {\n                    if (stackInfo.stack[0].line === initial.line) {\n                        return false; // already in stack trace\n                    } else if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) {\n                        stackInfo.stack[0].line = initial.line;\n                        stackInfo.stack[0].context = initial.context;\n                        return false;\n                    }\n                }\n            }\n\n            stackInfo.stack.unshift(initial);\n            stackInfo.partial = true;\n            return true;\n        } else {\n            stackInfo.incomplete = true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Computes stack trace information by walking the arguments.caller\n     * chain at the time the exception occurred. This will cause earlier\n     * frames to be missed but is the only way to get any stack trace in\n     * Safari and IE. The top frame is restored by\n     * {@link augmentStackTraceWithInitialElement}.\n     * @param {Error} ex\n     * @return {TraceKit.StackTrace=} Stack trace information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceByWalkingCallerChain(ex, depth) {\n        var functionName = /function\\s+([_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*)?\\s*\\(/i,\n            stack = [],\n            funcs = {},\n            recursion = false,\n            parts,\n            item,\n            source;\n\n        for (var curr = computeStackTraceByWalkingCallerChain.caller; curr && !recursion; curr = curr.caller) {\n            if (curr === computeStackTrace || curr === TraceKit.report) {\n                // console.log('skipping internal function');\n                continue;\n            }\n\n            item = {\n                'url': null,\n                'func': UNKNOWN_FUNCTION,\n                'args': [],\n                'line': null,\n                'column': null\n            };\n\n            if (curr.name) {\n                item.func = curr.name;\n            } else if ((parts = functionName.exec(curr.toString()))) {\n                item.func = parts[1];\n            }\n\n            if (typeof item.func === 'undefined') {\n              try {\n                item.func = parts.input.substring(0, parts.input.indexOf('{'));\n              } catch (e) { }\n            }\n\n            if ((source = findSourceByFunctionBody(curr))) {\n                item.url = source.url;\n                item.line = source.line;\n\n                if (item.func === UNKNOWN_FUNCTION) {\n                    item.func = guessFunctionName(item.url, item.line);\n                }\n\n                var reference = / '([^']+)' /.exec(ex.message || ex.description);\n                if (reference) {\n                    item.column = findSourceInLine(reference[1], source.url, source.line);\n                }\n            }\n\n            if (funcs['' + curr]) {\n                recursion = true;\n            }else{\n                funcs['' + curr] = true;\n            }\n\n            stack.push(item);\n        }\n\n        if (depth) {\n            // console.log('depth is ' + depth);\n            // console.log('stack is ' + stack.length);\n            stack.splice(0, depth);\n        }\n\n        var result = {\n            'mode': 'callers',\n            'name': ex.name,\n            'message': ex.message,\n            'stack': stack\n        };\n        augmentStackTraceWithInitialElement(result, ex.sourceURL || ex.fileName, ex.line || ex.lineNumber, ex.message || ex.description);\n        return result;\n    }\n\n    /**\n     * Computes a stack trace for an exception.\n     * @param {Error} ex\n     * @param {(string|number)=} depth\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTrace(ex, depth) {\n        var stack = null;\n        depth = (depth == null ? 0 : +depth);\n\n        try {\n            // This must be tried first because Opera 10 *destroys*\n            // its stacktrace property if you try to access the stack\n            // property first!!\n            stack = computeStackTraceFromStacktraceProp(ex);\n            if (stack) {\n                return stack;\n            }\n        } catch (e) {\n            if (debug) {\n                throw e;\n            }\n        }\n\n        try {\n            stack = computeStackTraceFromStackProp(ex);\n            if (stack) {\n                return stack;\n            }\n        } catch (e) {\n            if (debug) {\n                throw e;\n            }\n        }\n\n        try {\n            stack = computeStackTraceFromOperaMultiLineMessage(ex);\n            if (stack) {\n                return stack;\n            }\n        } catch (e) {\n            if (debug) {\n                throw e;\n            }\n        }\n\n        try {\n            stack = computeStackTraceByWalkingCallerChain(ex, depth + 1);\n            if (stack) {\n                return stack;\n            }\n        } catch (e) {\n            if (debug) {\n                throw e;\n            }\n        }\n\n        return {\n            'mode': 'failed'\n        };\n    }\n\n    /**\n     * Logs a stacktrace starting from the previous call and working down.\n     * @param {(number|string)=} depth How many frames deep to trace.\n     * @return {TraceKit.StackTrace} Stack trace information.\n     * @memberof TraceKit.computeStackTrace\n     */\n    function computeStackTraceOfCaller(depth) {\n        depth = (depth == null ? 0 : +depth) + 1; // \"+ 1\" because \"ofCaller\" should drop one frame\n        try {\n            throw new Error();\n        } catch (ex) {\n            return computeStackTrace(ex, depth + 1);\n        }\n    }\n\n    computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement;\n    computeStackTrace.guessFunctionName = guessFunctionName;\n    computeStackTrace.gatherContext = gatherContext;\n    computeStackTrace.ofCaller = computeStackTraceOfCaller;\n    computeStackTrace.getSource = getSource;\n\n    return computeStackTrace;\n}());\n\n/**\n * Extends support for global error handling for asynchronous browser\n * functions. Adopted from Closure Library's errorhandler.js\n * @memberof TraceKit\n */\nTraceKit.extendToAsynchronousCallbacks = function () {\n    var _helper = function _helper(fnName) {\n        var originalFn = window[fnName];\n        window[fnName] = function traceKitAsyncExtension() {\n            // Make a copy of the arguments\n            var args = _slice.call(arguments);\n            var originalCallback = args[0];\n            if (typeof (originalCallback) === 'function') {\n                args[0] = TraceKit.wrap(originalCallback);\n            }\n            // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it\n            // also only supports 2 argument and doesn't care what \"this\" is, so we\n            // can just call the original function directly.\n            if (originalFn.apply) {\n                return originalFn.apply(this, args);\n            } else {\n                return originalFn(args[0], args[1]);\n            }\n        };\n    };\n\n    _helper('setTimeout');\n    _helper('setInterval');\n};\n\n//Default options:\nif (!TraceKit.remoteFetching) {\n    TraceKit.remoteFetching = true;\n}\nif (!TraceKit.collectWindowErrors) {\n    TraceKit.collectWindowErrors = true;\n}\nif (!TraceKit.linesOfContext || TraceKit.linesOfContext < 1) {\n    // 5 lines before, the offending line, 5 lines after\n    TraceKit.linesOfContext = 11;\n}\n\n// UMD export\nif (typeof module !== 'undefined' && module.exports && window.module !== module) {\n    module.exports = TraceKit;\n} else if (typeof define === 'function' && define.amd) {\n    define('TraceKit', [], TraceKit);\n} else {\n    window.TraceKit = TraceKit;\n}\n\n}(typeof window !== 'undefined' ? window : global));\n\n\n(function(root, factory) {\n  var require, exports, module;\n  if (typeof define === 'function' && define.amd) {\n    define('exceptionless', [\"require\",\"exports\",\"module\",\"TraceKit\"], factory);\n  } else if (typeof exports === 'object') {\n    module.exports = factory(require, exports, module, require('TraceKit'));\n  } else {\n    root.exceptionless = factory(require, exports, module, root.TraceKit);\n  }\n}(this, function(require, exports, module, TraceKit) {\nif (!require) {\n\trequire = function(name) {\n\t\treturn (typeof window !== \"undefined\" ? window : global)[name];\n\t}\n}\nif (!exports) {\n\tvar exports = {};\n}\n\n\"use strict\";\nvar __extends = (this && this.__extends) || function (d, b) {\n    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];\n    function __() { this.constructor = d; }\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n};\nvar TraceKit = require('TraceKit');\nvar SubmissionResponse = (function () {\n    function SubmissionResponse(statusCode, message) {\n        this.success = false;\n        this.badRequest = false;\n        this.serviceUnavailable = false;\n        this.paymentRequired = false;\n        this.unableToAuthenticate = false;\n        this.notFound = false;\n        this.requestEntityTooLarge = false;\n        this.statusCode = statusCode;\n        this.message = message;\n        this.success = statusCode >= 200 && statusCode <= 299;\n        this.badRequest = statusCode === 400;\n        this.serviceUnavailable = statusCode === 503;\n        this.paymentRequired = statusCode === 402;\n        this.unableToAuthenticate = statusCode === 401 || statusCode === 403;\n        this.notFound = statusCode === 404;\n        this.requestEntityTooLarge = statusCode === 413;\n    }\n    return SubmissionResponse;\n}());\nexports.SubmissionResponse = SubmissionResponse;\nvar SettingsManager = (function () {\n    function SettingsManager() {\n    }\n    SettingsManager.onChanged = function (handler) {\n        !!handler && this._handlers.push(handler);\n    };\n    SettingsManager.applySavedServerSettings = function (config) {\n        if (!config || !config.isValid) {\n            return;\n        }\n        var savedSettings = this.getSavedServerSettings(config);\n        config.log.info(\"Applying saved settings: v\" + savedSettings.version);\n        config.settings = Utils.merge(config.settings, savedSettings.settings);\n        this.changed(config);\n    };\n    SettingsManager.getVersion = function (config) {\n        if (!config || !config.isValid) {\n            return 0;\n        }\n        var savedSettings = this.getSavedServerSettings(config);\n        return savedSettings.version || 0;\n    };\n    SettingsManager.checkVersion = function (version, config) {\n        var currentVersion = this.getVersion(config);\n        if (version <= currentVersion) {\n            return;\n        }\n        config.log.info(\"Updating settings from v\" + currentVersion + \" to v\" + version);\n        this.updateSettings(config, currentVersion);\n    };\n    SettingsManager.updateSettings = function (config, version) {\n        var _this = this;\n        if (!config || !config.enabled) {\n            return;\n        }\n        var unableToUpdateMessage = 'Unable to update settings';\n        if (!config.isValid) {\n            config.log.error(unableToUpdateMessage + \": ApiKey is not set.\");\n            return;\n        }\n        if (!version || version < 0) {\n            version = this.getVersion(config);\n        }\n        config.log.info(\"Checking for updated settings from: v\" + version + \".\");\n        config.submissionClient.getSettings(config, version, function (response) {\n            if (!config || !response || !response.success || !response.settings) {\n                config.log.warn(unableToUpdateMessage + \": \" + response.message);\n                return;\n            }\n            config.settings = Utils.merge(config.settings, response.settings);\n            var savedServerSettings = SettingsManager.getSavedServerSettings(config);\n            for (var key in savedServerSettings) {\n                if (response.settings[key]) {\n                    continue;\n                }\n                delete config.settings[key];\n            }\n            var newSettings = {\n                version: response.settingsVersion,\n                settings: response.settings\n            };\n            config.storage.settings.save(newSettings);\n            config.log.info(\"Updated settings: v\" + newSettings.version);\n            _this.changed(config);\n        });\n    };\n    SettingsManager.changed = function (config) {\n        var handlers = this._handlers;\n        for (var index = 0; index < handlers.length; index++) {\n            try {\n                handlers[index](config);\n            }\n            catch (ex) {\n                config.log.error(\"Error calling onChanged handler: \" + ex);\n            }\n        }\n    };\n    SettingsManager.getSavedServerSettings = function (config) {\n        var item = config.storage.settings.get()[0];\n        if (item && item.value && item.value.version && item.value.settings) {\n            return item.value;\n        }\n        return { version: 0, settings: {} };\n    };\n    SettingsManager._handlers = [];\n    return SettingsManager;\n}());\nexports.SettingsManager = SettingsManager;\nvar DefaultLastReferenceIdManager = (function () {\n    function DefaultLastReferenceIdManager() {\n        this._lastReferenceId = null;\n    }\n    DefaultLastReferenceIdManager.prototype.getLast = function () {\n        return this._lastReferenceId;\n    };\n    DefaultLastReferenceIdManager.prototype.clearLast = function () {\n        this._lastReferenceId = null;\n    };\n    DefaultLastReferenceIdManager.prototype.setLast = function (eventId) {\n        this._lastReferenceId = eventId;\n    };\n    return DefaultLastReferenceIdManager;\n}());\nexports.DefaultLastReferenceIdManager = DefaultLastReferenceIdManager;\nvar ConsoleLog = (function () {\n    function ConsoleLog() {\n    }\n    ConsoleLog.prototype.trace = function (message) {\n        this.log('trace', message);\n    };\n    ConsoleLog.prototype.info = function (message) {\n        this.log('info', message);\n    };\n    ConsoleLog.prototype.warn = function (message) {\n        this.log('warn', message);\n    };\n    ConsoleLog.prototype.error = function (message) {\n        this.log('error', message);\n    };\n    ConsoleLog.prototype.log = function (level, message) {\n        if (console) {\n            var msg = \"[\" + level + \"] Exceptionless: \" + message;\n            if (console[level]) {\n                console[level](msg);\n            }\n            else if (console.log) {\n                console[\"log\"](msg);\n            }\n        }\n    };\n    return ConsoleLog;\n}());\nexports.ConsoleLog = ConsoleLog;\nvar NullLog = (function () {\n    function NullLog() {\n    }\n    NullLog.prototype.trace = function (message) { };\n    NullLog.prototype.info = function (message) { };\n    NullLog.prototype.warn = function (message) { };\n    NullLog.prototype.error = function (message) { };\n    return NullLog;\n}());\nexports.NullLog = NullLog;\nvar EventPluginContext = (function () {\n    function EventPluginContext(client, event, contextData) {\n        this.client = client;\n        this.event = event;\n        this.contextData = contextData ? contextData : new ContextData();\n    }\n    Object.defineProperty(EventPluginContext.prototype, \"log\", {\n        get: function () {\n            return this.client.config.log;\n        },\n        enumerable: true,\n        configurable: true\n    });\n    return EventPluginContext;\n}());\nexports.EventPluginContext = EventPluginContext;\nvar EventPluginManager = (function () {\n    function EventPluginManager() {\n    }\n    EventPluginManager.run = function (context, callback) {\n        var wrap = function (plugin, next) {\n            return function () {\n                try {\n                    if (!context.cancelled) {\n                        plugin.run(context, next);\n                    }\n                }\n                catch (ex) {\n                    context.cancelled = true;\n                    context.log.error(\"Error running plugin '\" + plugin.name + \"': \" + ex.message + \". Discarding Event.\");\n                }\n                if (context.cancelled && !!callback) {\n                    callback(context);\n                }\n            };\n        };\n        var plugins = context.client.config.plugins;\n        var wrappedPlugins = [];\n        if (!!callback) {\n            wrappedPlugins[plugins.length] = wrap({ name: 'cb', priority: 9007199254740992, run: callback }, null);\n        }\n        for (var index = plugins.length - 1; index > -1; index--) {\n            wrappedPlugins[index] = wrap(plugins[index], !!callback || (index < plugins.length - 1) ? wrappedPlugins[index + 1] : null);\n        }\n        wrappedPlugins[0]();\n    };\n    EventPluginManager.addDefaultPlugins = function (config) {\n        config.addPlugin(new ConfigurationDefaultsPlugin());\n        config.addPlugin(new ErrorPlugin());\n        config.addPlugin(new DuplicateCheckerPlugin());\n        config.addPlugin(new EventExclusionPlugin());\n        config.addPlugin(new ModuleInfoPlugin());\n        config.addPlugin(new RequestInfoPlugin());\n        config.addPlugin(new EnvironmentInfoPlugin());\n        config.addPlugin(new SubmissionMethodPlugin());\n    };\n    return EventPluginManager;\n}());\nexports.EventPluginManager = EventPluginManager;\nvar HeartbeatPlugin = (function () {\n    function HeartbeatPlugin(heartbeatInterval) {\n        if (heartbeatInterval === void 0) { heartbeatInterval = 30000; }\n        this.priority = 100;\n        this.name = 'HeartbeatPlugin';\n        this._interval = heartbeatInterval;\n    }\n    HeartbeatPlugin.prototype.run = function (context, next) {\n        clearInterval(this._intervalId);\n        var user = context.event.data['@user'];\n        if (user && user.identity) {\n            this._intervalId = setInterval(function () { return context.client.submitSessionHeartbeat(user.identity); }, this._interval);\n        }\n        next && next();\n    };\n    return HeartbeatPlugin;\n}());\nexports.HeartbeatPlugin = HeartbeatPlugin;\nvar ReferenceIdPlugin = (function () {\n    function ReferenceIdPlugin() {\n        this.priority = 20;\n        this.name = 'ReferenceIdPlugin';\n    }\n    ReferenceIdPlugin.prototype.run = function (context, next) {\n        if ((!context.event.reference_id || context.event.reference_id.length === 0) && context.event.type === 'error') {\n            context.event.reference_id = Utils.guid().replace('-', '').substring(0, 10);\n        }\n        next && next();\n    };\n    return ReferenceIdPlugin;\n}());\nexports.ReferenceIdPlugin = ReferenceIdPlugin;\nvar DefaultEventQueue = (function () {\n    function DefaultEventQueue(config) {\n        this._handlers = [];\n        this._processingQueue = false;\n        this._config = config;\n    }\n    DefaultEventQueue.prototype.enqueue = function (event) {\n        var eventWillNotBeQueued = 'The event will not be queued.';\n        var config = this._config;\n        var log = config.log;\n        if (!config.enabled) {\n            log.info(\"Configuration is disabled. \" + eventWillNotBeQueued);\n            return;\n        }\n        if (!config.isValid) {\n            log.info(\"Invalid Api Key. \" + eventWillNotBeQueued);\n            return;\n        }\n        if (this.areQueuedItemsDiscarded()) {\n            log.info(\"Queue items are currently being discarded. \" + eventWillNotBeQueued);\n            return;\n        }\n        this.ensureQueueTimer();\n        var timestamp = config.storage.queue.save(event);\n        var logText = \"type=\" + event.type + \" \" + (!!event.reference_id ? 'refid=' + event.reference_id : '');\n        if (timestamp) {\n            log.info(\"Enqueuing event: \" + timestamp + \" \" + logText);\n        }\n        else {\n            log.error(\"Could not enqueue event \" + logText);\n        }\n    };\n    DefaultEventQueue.prototype.process = function (isAppExiting) {\n        var _this = this;\n        var queueNotProcessed = 'The queue will not be processed.';\n        var config = this._config;\n        var log = config.log;\n        if (this._processingQueue) {\n            return;\n        }\n        log.info('Processing queue...');\n        if (!config.enabled) {\n            log.info(\"Configuration is disabled. \" + queueNotProcessed);\n            return;\n        }\n        if (!config.isValid) {\n            log.info(\"Invalid Api Key. \" + queueNotProcessed);\n            return;\n        }\n        this._processingQueue = true;\n        this.ensureQueueTimer();\n        try {\n            var events_1 = config.storage.queue.get(config.submissionBatchSize);\n            if (!events_1 || events_1.length === 0) {\n                this._processingQueue = false;\n                return;\n            }\n            log.info(\"Sending \" + events_1.length + \" events to \" + config.serverUrl + \".\");\n            config.submissionClient.postEvents(events_1.map(function (e) { return e.value; }), config, function (response) {\n                _this.processSubmissionResponse(response, events_1);\n                _this.eventsPosted(events_1.map(function (e) { return e.value; }), response);\n                log.info('Finished processing queue.');\n                _this._processingQueue = false;\n            }, isAppExiting);\n        }\n        catch (ex) {\n            log.error(\"Error processing queue: \" + ex);\n            this.suspendProcessing();\n            this._processingQueue = false;\n        }\n    };\n    DefaultEventQueue.prototype.suspendProcessing = function (durationInMinutes, discardFutureQueuedItems, clearQueue) {\n        var config = this._config;\n        if (!durationInMinutes || durationInMinutes <= 0) {\n            durationInMinutes = 5;\n        }\n        config.log.info(\"Suspending processing for \" + durationInMinutes + \" minutes.\");\n        this._suspendProcessingUntil = new Date(new Date().getTime() + (durationInMinutes * 60000));\n        if (discardFutureQueuedItems) {\n            this._discardQueuedItemsUntil = this._suspendProcessingUntil;\n        }\n        if (clearQueue) {\n            config.storage.queue.clear();\n        }\n    };\n    DefaultEventQueue.prototype.onEventsPosted = function (handler) {\n        !!handler && this._handlers.push(handler);\n    };\n    DefaultEventQueue.prototype.eventsPosted = function (events, response) {\n        var handlers = this._handlers;\n        for (var index = 0; index < handlers.length; index++) {\n            try {\n                handlers[index](events, response);\n            }\n            catch (ex) {\n                this._config.log.error(\"Error calling onEventsPosted handler: \" + ex);\n            }\n        }\n    };\n    DefaultEventQueue.prototype.areQueuedItemsDiscarded = function () {\n        return this._discardQueuedItemsUntil && this._discardQueuedItemsUntil > new Date();\n    };\n    DefaultEventQueue.prototype.ensureQueueTimer = function () {\n        var _this = this;\n        if (!this._queueTimer) {\n            this._queueTimer = setInterval(function () { return _this.onProcessQueue(); }, 10000);\n        }\n    };\n    DefaultEventQueue.prototype.isQueueProcessingSuspended = function () {\n        return this._suspendProcessingUntil && this._suspendProcessingUntil > new Date();\n    };\n    DefaultEventQueue.prototype.onProcessQueue = function () {\n        if (!this.isQueueProcessingSuspended() && !this._processingQueue) {\n            this.process();\n        }\n    };\n    DefaultEventQueue.prototype.processSubmissionResponse = function (response, events) {\n        var noSubmission = 'The event will not be submitted.';\n        var config = this._config;\n        var log = config.log;\n        if (response.success) {\n            log.info(\"Sent \" + events.length + \" events.\");\n            this.removeEvents(events);\n            return;\n        }\n        if (response.serviceUnavailable) {\n            log.error('Server returned service unavailable.');\n            this.suspendProcessing();\n            return;\n        }\n        if (response.paymentRequired) {\n            log.info('Too many events have been submitted, please upgrade your plan.');\n            this.suspendProcessing(null, true, true);\n            return;\n        }\n        if (response.unableToAuthenticate) {\n            log.info(\"Unable to authenticate, please check your configuration. \" + noSubmission);\n            this.suspendProcessing(15);\n            this.removeEvents(events);\n            return;\n        }\n        if (response.notFound || response.badRequest) {\n            log.error(\"Error while trying to submit data: \" + response.message);\n            this.suspendProcessing(60 * 4);\n            this.removeEvents(events);\n            return;\n        }\n        if (response.requestEntityTooLarge) {\n            var message = 'Event submission discarded for being too large.';\n            if (config.submissionBatchSize > 1) {\n                log.error(message + \" Retrying with smaller batch size.\");\n                config.submissionBatchSize = Math.max(1, Math.round(config.submissionBatchSize / 1.5));\n            }\n            else {\n                log.error(message + \" \" + noSubmission);\n                this.removeEvents(events);\n            }\n            return;\n        }\n        if (!response.success) {\n            log.error(\"Error submitting events: \" + (response.message || 'Please check the network tab for more info.'));\n            this.suspendProcessing();\n        }\n    };\n    DefaultEventQueue.prototype.removeEvents = function (events) {\n        for (var index = 0; index < (events || []).length; index++) {\n            this._config.storage.queue.remove(events[index].timestamp);\n        }\n    };\n    return DefaultEventQueue;\n}());\nexports.DefaultEventQueue = DefaultEventQueue;\nvar InMemoryStorageProvider = (function () {\n    function InMemoryStorageProvider(maxQueueItems) {\n        if (maxQueueItems === void 0) { maxQueueItems = 250; }\n        this.queue = new InMemoryStorage(maxQueueItems);\n        this.settings = new InMemoryStorage(1);\n    }\n    return InMemoryStorageProvider;\n}());\nexports.InMemoryStorageProvider = InMemoryStorageProvider;\nvar DefaultSubmissionClient = (function () {\n    function DefaultSubmissionClient() {\n        this.configurationVersionHeader = 'x-exceptionless-configversion';\n    }\n    DefaultSubmissionClient.prototype.postEvents = function (events, config, callback, isAppExiting) {\n        var data = JSON.stringify(events);\n        var request = this.createRequest(config, 'POST', config.serverUrl + \"/api/v2/events\", data);\n        var cb = this.createSubmissionCallback(config, callback);\n        return config.submissionAdapter.sendRequest(request, cb, isAppExiting);\n    };\n    DefaultSubmissionClient.prototype.postUserDescription = function (referenceId, description, config, callback) {\n        var path = config.serverUrl + \"/api/v2/events/by-ref/\" + encodeURIComponent(referenceId) + \"/user-description\";\n        var data = JSON.stringify(description);\n        var request = this.createRequest(config, 'POST', path, data);\n        var cb = this.createSubmissionCallback(config, callback);\n        return config.submissionAdapter.sendRequest(request, cb);\n    };\n    DefaultSubmissionClient.prototype.getSettings = function (config, version, callback) {\n        var request = this.createRequest(config, 'GET', config.serverUrl + \"/api/v2/projects/config?v=\" + version);\n        var cb = function (status, message, data, headers) {\n            if (status !== 200) {\n                return callback(new SettingsResponse(false, null, -1, null, message));\n            }\n            var settings;\n            try {\n                settings = JSON.parse(data);\n            }\n            catch (e) {\n                config.log.error(\"Unable to parse settings: '\" + data + \"'\");\n            }\n            if (!settings || isNaN(settings.version)) {\n                return callback(new SettingsResponse(false, null, -1, null, 'Invalid configuration settings.'));\n            }\n            callback(new SettingsResponse(true, settings.settings || {}, settings.version));\n        };\n        return config.submissionAdapter.sendRequest(request, cb);\n    };\n    DefaultSubmissionClient.prototype.sendHeartbeat = function (sessionIdOrUserId, closeSession, config) {\n        var request = this.createRequest(config, 'GET', config.heartbeatServerUrl + \"/api/v2/events/session/heartbeat?id=\" + sessionIdOrUserId + \"&close=\" + closeSession);\n        config.submissionAdapter.sendRequest(request);\n    };\n    DefaultSubmissionClient.prototype.createRequest = function (config, method, url, data) {\n        if (data === void 0) { data = null; }\n        return {\n            method: method,\n            url: url,\n            data: data,\n            apiKey: config.apiKey,\n            userAgent: config.userAgent\n        };\n    };\n    DefaultSubmissionClient.prototype.createSubmissionCallback = function (config, callback) {\n        var _this = this;\n        return function (status, message, data, headers) {\n            var settingsVersion = headers && parseInt(headers[_this.configurationVersionHeader], 10);\n            SettingsManager.checkVersion(settingsVersion, config);\n            callback(new SubmissionResponse(status, message));\n        };\n    };\n    return DefaultSubmissionClient;\n}());\nexports.DefaultSubmissionClient = DefaultSubmissionClient;\nvar Utils = (function () {\n    function Utils() {\n    }\n    Utils.addRange = function (target) {\n        var values = [];\n        for (var _i = 1; _i < arguments.length; _i++) {\n            values[_i - 1] = arguments[_i];\n        }\n        if (!target) {\n            target = [];\n        }\n        if (!values || values.length === 0) {\n            return target;\n        }\n        for (var index = 0; index < values.length; index++) {\n            if (values[index] && target.indexOf(values[index]) < 0) {\n                target.push(values[index]);\n            }\n        }\n        return target;\n    };\n    Utils.getHashCode = function (source) {\n        if (!source || source.length === 0) {\n            return 0;\n        }\n        var hash = 0;\n        for (var index = 0; index < source.length; index++) {\n            var character = source.charCodeAt(index);\n            hash = ((hash << 5) - hash) + character;\n            hash |= 0;\n        }\n        return hash;\n    };\n    Utils.getCookies = function (cookies, exclusions) {\n        var result = {};\n        var parts = (cookies || '').split('; ');\n        for (var index = 0; index < parts.length; index++) {\n            var cookie = parts[index].split('=');\n            if (!Utils.isMatch(cookie[0], exclusions)) {\n                result[cookie[0]] = cookie[1];\n            }\n        }\n        return !Utils.isEmpty(result) ? result : null;\n    };\n    Utils.guid = function () {\n        function s4() {\n            return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);\n        }\n        return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\n    };\n    Utils.merge = function (defaultValues, values) {\n        var result = {};\n        for (var key in defaultValues || {}) {\n            if (!!defaultValues[key]) {\n                result[key] = defaultValues[key];\n            }\n        }\n        for (var key in values || {}) {\n            if (!!values[key]) {\n                result[key] = values[key];\n            }\n        }\n        return result;\n    };\n    Utils.parseVersion = function (source) {\n        if (!source) {\n            return null;\n        }\n        var versionRegex = /(v?((\\d+)\\.(\\d+)(\\.(\\d+))?)(?:-([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?(?:\\+([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?)/;\n        var matches = versionRegex.exec(source);\n        if (matches && matches.length > 0) {\n            return matches[0];\n        }\n        return null;\n    };\n    Utils.parseQueryString = function (query, exclusions) {\n        if (!query || query.length === 0) {\n            return null;\n        }\n        var pairs = query.split('&');\n        if (pairs.length === 0) {\n            return null;\n        }\n        var result = {};\n        for (var index = 0; index < pairs.length; index++) {\n            var pair = pairs[index].split('=');\n            if (!Utils.isMatch(pair[0], exclusions)) {\n                result[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);\n            }\n        }\n        return !Utils.isEmpty(result) ? result : null;\n    };\n    Utils.randomNumber = function () {\n        return Math.floor(Math.random() * 9007199254740992);\n    };\n    Utils.isMatch = function (input, patterns, ignoreCase) {\n        if (ignoreCase === void 0) { ignoreCase = true; }\n        if (!input || typeof input !== 'string') {\n            return false;\n        }\n        var trim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n        input = (ignoreCase ? input.toLowerCase() : input).replace(trim, '');\n        return (patterns || []).some(function (pattern) {\n            if (typeof pattern !== 'string') {\n                return false;\n            }\n            pattern = (ignoreCase ? pattern.toLowerCase() : pattern).replace(trim, '');\n            if (pattern.length <= 0) {\n                return false;\n            }\n            var startsWithWildcard = pattern[0] === '*';\n            if (startsWithWildcard) {\n                pattern = pattern.slice(1);\n            }\n            var endsWithWildcard = pattern[pattern.length - 1] === '*';\n            if (endsWithWildcard) {\n                pattern = pattern.substring(0, pattern.length - 1);\n            }\n            if (startsWithWildcard && endsWithWildcard) {\n                return pattern.length <= input.length && input.indexOf(pattern, 0) !== -1;\n            }\n            if (startsWithWildcard) {\n                return Utils.endsWith(input, pattern);\n            }\n            if (endsWithWildcard) {\n                return Utils.startsWith(input, pattern);\n            }\n            return input === pattern;\n        });\n    };\n    Utils.isEmpty = function (input) {\n        return input === null || (typeof (input) === 'object' && Object.keys(input).length === 0);\n    };\n    Utils.startsWith = function (input, prefix) {\n        return input.substring(0, prefix.length) === prefix;\n    };\n    Utils.endsWith = function (input, suffix) {\n        return input.indexOf(suffix, input.length - suffix.length) !== -1;\n    };\n    Utils.stringify = function (data, exclusions, maxDepth) {\n        function stringifyImpl(obj, excludedKeys) {\n            var cache = [];\n            return JSON.stringify(obj, function (key, value) {\n                if (Utils.isMatch(key, excludedKeys)) {\n                    return;\n                }\n                if (typeof value === 'object' && !!value) {\n                    if (cache.indexOf(value) !== -1) {\n                        return;\n                    }\n                    cache.push(value);\n                }\n                return value;\n            });\n        }\n        if (({}).toString.call(data) === '[object Object]') {\n            var flattened = {};\n            for (var prop in data) {\n                var value = data[prop];\n                if (value === data) {\n                    continue;\n                }\n                flattened[prop] = data[prop];\n            }\n            return stringifyImpl(flattened, exclusions);\n        }\n        if (({}).toString.call(data) === '[object Array]') {\n            var result = [];\n            for (var index = 0; index < data.length; index++) {\n                result[index] = JSON.parse(stringifyImpl(data[index], exclusions));\n            }\n            return JSON.stringify(result);\n        }\n        return stringifyImpl(data, exclusions);\n    };\n    Utils.toBoolean = function (input, defaultValue) {\n        if (defaultValue === void 0) { defaultValue = false; }\n        if (typeof input === 'boolean') {\n            return input;\n        }\n        if (input === null || typeof input !== 'number' && typeof input !== 'string') {\n            return defaultValue;\n        }\n        switch ((input + '').toLowerCase().trim()) {\n            case 'true':\n            case 'yes':\n            case '1': return true;\n            case 'false':\n            case 'no':\n            case '0':\n            case null: return false;\n        }\n        return defaultValue;\n    };\n    return Utils;\n}());\nexports.Utils = Utils;\nvar Configuration = (function () {\n    function Configuration(configSettings) {\n        this.defaultTags = [];\n        this.defaultData = {};\n        this.enabled = true;\n        this.lastReferenceIdManager = new DefaultLastReferenceIdManager();\n        this.settings = {};\n        this._serverUrl = 'https://collector.exceptionless.io';\n        this._heartbeatServerUrl = 'https://heartbeat.exceptionless.io';\n        this._updateSettingsWhenIdleInterval = 120000;\n        this._dataExclusions = [];\n        this._userAgentBotPatterns = [];\n        this._plugins = [];\n        this._handlers = [];\n        function inject(fn) {\n            return typeof fn === 'function' ? fn(this) : fn;\n        }\n        configSettings = Utils.merge(Configuration.defaults, configSettings);\n        this.log = inject(configSettings.log) || new NullLog();\n        this.apiKey = configSettings.apiKey;\n        this.serverUrl = configSettings.serverUrl;\n        this.heartbeatServerUrl = configSettings.heartbeatServerUrl;\n        this.updateSettingsWhenIdleInterval = configSettings.updateSettingsWhenIdleInterval;\n        this.environmentInfoCollector = inject(configSettings.environmentInfoCollector);\n        this.errorParser = inject(configSettings.errorParser);\n        this.lastReferenceIdManager = inject(configSettings.lastReferenceIdManager) || new DefaultLastReferenceIdManager();\n        this.moduleCollector = inject(configSettings.moduleCollector);\n        this.requestInfoCollector = inject(configSettings.requestInfoCollector);\n        this.submissionBatchSize = inject(configSettings.submissionBatchSize) || 50;\n        this.submissionAdapter = inject(configSettings.submissionAdapter);\n        this.submissionClient = inject(configSettings.submissionClient) || new DefaultSubmissionClient();\n        this.storage = inject(configSettings.storage) || new InMemoryStorageProvider();\n        this.queue = inject(configSettings.queue) || new DefaultEventQueue(this);\n        SettingsManager.applySavedServerSettings(this);\n        EventPluginManager.addDefaultPlugins(this);\n    }\n    Object.defineProperty(Configuration.prototype, \"apiKey\", {\n        get: function () {\n            return this._apiKey;\n        },\n        set: function (value) {\n            this._apiKey = value || null;\n            this.log.info(\"apiKey: \" + this._apiKey);\n            this.changed();\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Object.defineProperty(Configuration.prototype, \"isValid\", {\n        get: function () {\n            return !!this.apiKey && this.apiKey.length >= 10;\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Object.defineProperty(Configuration.prototype, \"serverUrl\", {\n        get: function () {\n            return this._serverUrl;\n        },\n        set: function (value) {\n            if (!!value) {\n                this._serverUrl = value;\n                this._heartbeatServerUrl = value;\n                this.log.info(\"serverUrl: \" + value);\n                this.changed();\n            }\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Object.defineProperty(Configuration.prototype, \"heartbeatServerUrl\", {\n        get: function () {\n            return this._heartbeatServerUrl;\n        },\n        set: function (value) {\n            if (!!value) {\n                this._heartbeatServerUrl = value;\n                this.log.info(\"heartbeatServerUrl: \" + value);\n                this.changed();\n            }\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Object.defineProperty(Configuration.prototype, \"updateSettingsWhenIdleInterval\", {\n        get: function () {\n            return this._updateSettingsWhenIdleInterval;\n        },\n        set: function (value) {\n            if (typeof value !== 'number') {\n                return;\n            }\n            if (value <= 0) {\n                value = -1;\n            }\n            else if (value > 0 && value < 15000) {\n                value = 15000;\n            }\n            this._updateSettingsWhenIdleInterval = value;\n            this.log.info(\"updateSettingsWhenIdleInterval: \" + value);\n            this.changed();\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Object.defineProperty(Configuration.prototype, \"dataExclusions\", {\n        get: function () {\n            var exclusions = this.settings['@@DataExclusions'];\n            return this._dataExclusions.concat(exclusions && exclusions.split(',') || []);\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Configuration.prototype.addDataExclusions = function () {\n        var exclusions = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n            exclusions[_i - 0] = arguments[_i];\n        }\n        this._dataExclusions = Utils.addRange.apply(Utils, [this._dataExclusions].concat(exclusions));\n    };\n    Object.defineProperty(Configuration.prototype, \"userAgentBotPatterns\", {\n        get: function () {\n            var patterns = this.settings['@@UserAgentBotPatterns'];\n            return this._userAgentBotPatterns.concat(patterns && patterns.split(',') || []);\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Configuration.prototype.addUserAgentBotPatterns = function () {\n        var userAgentBotPatterns = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n            userAgentBotPatterns[_i - 0] = arguments[_i];\n        }\n        this._userAgentBotPatterns = Utils.addRange.apply(Utils, [this._userAgentBotPatterns].concat(userAgentBotPatterns));\n    };\n    Object.defineProperty(Configuration.prototype, \"plugins\", {\n        get: function () {\n            return this._plugins.sort(function (p1, p2) {\n                return (p1.priority < p2.priority) ? -1 : (p1.priority > p2.priority) ? 1 : 0;\n            });\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Configuration.prototype.addPlugin = function (pluginOrName, priority, pluginAction) {\n        var plugin = !!pluginAction ? { name: pluginOrName, priority: priority, run: pluginAction } : pluginOrName;\n        if (!plugin || !plugin.run) {\n            this.log.error('Add plugin failed: Run method not defined');\n            return;\n        }\n        if (!plugin.name) {\n            plugin.name = Utils.guid();\n        }\n        if (!plugin.priority) {\n            plugin.priority = 0;\n        }\n        var pluginExists = false;\n        var plugins = this._plugins;\n        for (var index = 0; index < plugins.length; index++) {\n            if (plugins[index].name === plugin.name) {\n                pluginExists = true;\n                break;\n            }\n        }\n        if (!pluginExists) {\n            plugins.push(plugin);\n        }\n    };\n    Configuration.prototype.removePlugin = function (pluginOrName) {\n        var name = typeof pluginOrName === 'string' ? pluginOrName : pluginOrName.name;\n        if (!name) {\n            this.log.error('Remove plugin failed: Plugin name not defined');\n            return;\n        }\n        var plugins = this._plugins;\n        for (var index = 0; index < plugins.length; index++) {\n            if (plugins[index].name === name) {\n                plugins.splice(index, 1);\n                break;\n            }\n        }\n    };\n    Configuration.prototype.setVersion = function (version) {\n        if (!!version) {\n            this.defaultData['@version'] = version;\n        }\n    };\n    Configuration.prototype.setUserIdentity = function (userInfoOrIdentity, name) {\n        var USER_KEY = '@user';\n        var userInfo = typeof userInfoOrIdentity !== 'string' ? userInfoOrIdentity : { identity: userInfoOrIdentity, name: name };\n        var shouldRemove = !userInfo || (!userInfo.identity && !userInfo.name);\n        if (shouldRemove) {\n            delete this.defaultData[USER_KEY];\n        }\n        else {\n            this.defaultData[USER_KEY] = userInfo;\n        }\n        this.log.info(\"user identity: \" + (shouldRemove ? 'null' : userInfo.identity));\n    };\n    Object.defineProperty(Configuration.prototype, \"userAgent\", {\n        get: function () {\n            return 'exceptionless-js/1.4.3';\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Configuration.prototype.useSessions = function (sendHeartbeats, heartbeatInterval) {\n        if (sendHeartbeats === void 0) { sendHeartbeats = true; }\n        if (heartbeatInterval === void 0) { heartbeatInterval = 30000; }\n        if (sendHeartbeats) {\n            this.addPlugin(new HeartbeatPlugin(heartbeatInterval));\n        }\n    };\n    Configuration.prototype.useReferenceIds = function () {\n        this.addPlugin(new ReferenceIdPlugin());\n    };\n    Configuration.prototype.useLocalStorage = function () {\n    };\n    Configuration.prototype.useDebugLogger = function () {\n        this.log = new ConsoleLog();\n    };\n    Configuration.prototype.onChanged = function (handler) {\n        !!handler && this._handlers.push(handler);\n    };\n    Configuration.prototype.changed = function () {\n        var handlers = this._handlers;\n        for (var index = 0; index < handlers.length; index++) {\n            try {\n                handlers[index](this);\n            }\n            catch (ex) {\n                this.log.error(\"Error calling onChanged handler: \" + ex);\n            }\n        }\n    };\n    Object.defineProperty(Configuration, \"defaults\", {\n        get: function () {\n            if (Configuration._defaultSettings === null) {\n                Configuration._defaultSettings = {};\n            }\n            return Configuration._defaultSettings;\n        },\n        enumerable: true,\n        configurable: true\n    });\n    Configuration._defaultSettings = null;\n    return Configuration;\n}());\nexports.Configuration = Configuration;\nvar EventBuilder = (function () {\n    function EventBuilder(event, client, pluginContextData) {\n        this._validIdentifierErrorMessage = 'must contain between 8 and 100 alphanumeric or \\'-\\' characters.';\n        this.target = event;\n        this.client = client;\n        this.pluginContextData = pluginContextData || new ContextData();\n    }\n    EventBuilder.prototype.setType = function (type) {\n        if (!!type) {\n            this.target.type = type;\n        }\n        return this;\n    };\n    EventBuilder.prototype.setSource = function (source) {\n        if (!!source) {\n            this.target.source = source;\n        }\n        return this;\n    };\n    EventBuilder.prototype.setReferenceId = function (referenceId) {\n        if (!this.isValidIdentifier(referenceId)) {\n            throw new Error(\"ReferenceId \" + this._validIdentifierErrorMessage);\n        }\n        this.target.reference_id = referenceId;\n        return this;\n    };\n    EventBuilder.prototype.setEventReference = function (name, id) {\n        if (!name) {\n            throw new Error('Invalid name');\n        }\n        if (!id || !this.isValidIdentifier(id)) {\n            throw new Error(\"Id \" + this._validIdentifierErrorMessage);\n        }\n        this.setProperty('@ref:' + name, id);\n        return this;\n    };\n    EventBuilder.prototype.setMessage = function (message) {\n        if (!!message) {\n            this.target.message = message;\n        }\n        return this;\n    };\n    EventBuilder.prototype.setGeo = function (latitude, longitude) {\n        if (latitude < -90.0 || latitude > 90.0) {\n            throw new Error('Must be a valid latitude value between -90.0 and 90.0.');\n        }\n        if (longitude < -180.0 || longitude > 180.0) {\n            throw new Error('Must be a valid longitude value between -180.0 and 180.0.');\n        }\n        this.target.geo = latitude + \",\" + longitude;\n        return this;\n    };\n    EventBuilder.prototype.setUserIdentity = function (userInfoOrIdentity, name) {\n        var userInfo = typeof userInfoOrIdentity !== 'string' ? userInfoOrIdentity : { identity: userInfoOrIdentity, name: name };\n        if (!userInfo || (!userInfo.identity && !userInfo.name)) {\n            return this;\n        }\n        this.setProperty('@user', userInfo);\n        return this;\n    };\n    EventBuilder.prototype.setUserDescription = function (emailAddress, description) {\n        if (emailAddress && description) {\n            this.setProperty('@user_description', { email_address: emailAddress, description: description });\n        }\n        return this;\n    };\n    EventBuilder.prototype.setManualStackingInfo = function (signatureData, title) {\n        if (signatureData) {\n            var stack = {\n                signature_data: signatureData\n            };\n            if (title) {\n                stack.title = title;\n            }\n            this.setProperty('@stack', stack);\n        }\n        return this;\n    };\n    EventBuilder.prototype.setManualStackingKey = function (manualStackingKey, title) {\n        if (manualStackingKey) {\n            var data = {\n                'ManualStackingKey': manualStackingKey\n            };\n            this.setManualStackingInfo(data, title);\n        }\n        return this;\n    };\n    EventBuilder.prototype.setValue = function (value) {\n        if (!!value) {\n            this.target.value = value;\n        }\n        return this;\n    };\n    EventBuilder.prototype.addTags = function () {\n        var tags = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n            tags[_i - 0] = arguments[_i];\n        }\n        this.target.tags = Utils.addRange.apply(Utils, [this.target.tags].concat(tags));\n        return this;\n    };\n    EventBuilder.prototype.setProperty = function (name, value, maxDepth, excludedPropertyNames) {\n        if (!name || (value === undefined || value == null)) {\n            return this;\n        }\n        if (!this.target.data) {\n            this.target.data = {};\n        }\n        var result = JSON.parse(Utils.stringify(value, this.client.config.dataExclusions.concat(excludedPropertyNames || []), maxDepth));\n        if (!Utils.isEmpty(result)) {\n            this.target.data[name] = result;\n        }\n        return this;\n    };\n    EventBuilder.prototype.markAsCritical = function (critical) {\n        if (critical) {\n            this.addTags('Critical');\n        }\n        return this;\n    };\n    EventBuilder.prototype.addRequestInfo = function (request) {\n        if (!!request) {\n            this.pluginContextData['@request'] = request;\n        }\n        return this;\n    };\n    EventBuilder.prototype.submit = function (callback) {\n        this.client.submitEvent(this.target, this.pluginContextData, callback);\n    };\n    EventBuilder.prototype.isValidIdentifier = function (value) {\n        if (!value) {\n            return true;\n        }\n        if (value.length < 8 || value.length > 100) {\n            return false;\n        }\n        for (var index = 0; index < value.length; index++) {\n            var code = value.charCodeAt(index);\n            var isDigit = (code >= 48) && (code <= 57);\n            var isLetter = ((code >= 65) && (code <= 90)) || ((code >= 97) && (code <= 122));\n            var isMinus = code === 45;\n            if (!(isDigit || isLetter) && !isMinus) {\n                return false;\n            }\n        }\n        return true;\n    };\n    return EventBuilder;\n}());\nexports.EventBuilder = EventBuilder;\nvar ContextData = (function () {\n    function ContextData() {\n    }\n    ContextData.prototype.setException = function (exception) {\n        if (exception) {\n            this['@@_Exception'] = exception;\n        }\n    };\n    Object.defineProperty(ContextData.prototype, \"hasException\", {\n        get: function () {\n            return !!this['@@_Exception'];\n        },\n        enumerable: true,\n        configurable: true\n    });\n    ContextData.prototype.getException = function () {\n        return this['@@_Exception'] || null;\n    };\n    ContextData.prototype.markAsUnhandledError = function () {\n        this['@@_IsUnhandledError'] = true;\n    };\n    Object.defineProperty(ContextData.prototype, \"isUnhandledError\", {\n        get: function () {\n            return !!this['@@_IsUnhandledError'];\n        },\n        enumerable: true,\n        configurable: true\n    });\n    ContextData.prototype.setSubmissionMethod = function (method) {\n        if (method) {\n            this['@@_SubmissionMethod'] = method;\n        }\n    };\n    ContextData.prototype.getSubmissionMethod = function () {\n        return this['@@_SubmissionMethod'] || null;\n    };\n    return ContextData;\n}());\nexports.ContextData = ContextData;\nvar ExceptionlessClient = (function () {\n    function ExceptionlessClient(settingsOrApiKey, serverUrl) {\n        var _this = this;\n        if (typeof settingsOrApiKey === 'object') {\n            this.config = new Configuration(settingsOrApiKey);\n        }\n        else {\n            this.config = new Configuration({ apiKey: settingsOrApiKey, serverUrl: serverUrl });\n        }\n        this.updateSettingsTimer(5000);\n        this.config.onChanged(function (config) { return _this.updateSettingsTimer(_this._timeoutId > 0 ? 5000 : 0); });\n        this.config.queue.onEventsPosted(function (events, response) { return _this.updateSettingsTimer(); });\n    }\n    ExceptionlessClient.prototype.createException = function (exception) {\n        var pluginContextData = new ContextData();\n        pluginContextData.setException(exception);\n        return this.createEvent(pluginContextData).setType('error');\n    };\n    ExceptionlessClient.prototype.submitException = function (exception, callback) {\n        this.createException(exception).submit(callback);\n    };\n    ExceptionlessClient.prototype.createUnhandledException = function (exception, submissionMethod) {\n        var builder = this.createException(exception);\n        builder.pluginContextData.markAsUnhandledError();\n        builder.pluginContextData.setSubmissionMethod(submissionMethod);\n        return builder;\n    };\n    ExceptionlessClient.prototype.submitUnhandledException = function (exception, submissionMethod, callback) {\n        this.createUnhandledException(exception, submissionMethod).submit(callback);\n    };\n    ExceptionlessClient.prototype.createFeatureUsage = function (feature) {\n        return this.createEvent().setType('usage').setSource(feature);\n    };\n    ExceptionlessClient.prototype.submitFeatureUsage = function (feature, callback) {\n        this.createFeatureUsage(feature).submit(callback);\n    };\n    ExceptionlessClient.prototype.createLog = function (sourceOrMessage, message, level) {\n        var builder = this.createEvent().setType('log');\n        if (message && level) {\n            builder = builder.setSource(sourceOrMessage).setMessage(message).setProperty('@level', level);\n        }\n        else if (message) {\n            builder = builder.setSource(sourceOrMessage).setMessage(message);\n        }\n        else {\n            builder = builder.setMessage(sourceOrMessage);\n            try {\n                var caller = this.createLog.caller;\n                builder = builder.setSource(caller && caller.caller && caller.caller.name);\n            }\n            catch (e) {\n                this.config.log.trace('Unable to resolve log source: ' + e.message);\n            }\n        }\n        return builder;\n    };\n    ExceptionlessClient.prototype.submitLog = function (sourceOrMessage, message, level, callback) {\n        this.createLog(sourceOrMessage, message, level).submit(callback);\n    };\n    ExceptionlessClient.prototype.createNotFound = function (resource) {\n        return this.createEvent().setType('404').setSource(resource);\n    };\n    ExceptionlessClient.prototype.submitNotFound = function (resource, callback) {\n        this.createNotFound(resource).submit(callback);\n    };\n    ExceptionlessClient.prototype.createSessionStart = function () {\n        return this.createEvent().setType('session');\n    };\n    ExceptionlessClient.prototype.submitSessionStart = function (callback) {\n        this.createSessionStart().submit(callback);\n    };\n    ExceptionlessClient.prototype.submitSessionEnd = function (sessionIdOrUserId) {\n        if (sessionIdOrUserId) {\n            this.config.log.info(\"Submitting session end: \" + sessionIdOrUserId);\n            this.config.submissionClient.sendHeartbeat(sessionIdOrUserId, true, this.config);\n        }\n    };\n    ExceptionlessClient.prototype.submitSessionHeartbeat = function (sessionIdOrUserId) {\n        if (sessionIdOrUserId) {\n            this.config.log.info(\"Submitting session heartbeat: \" + sessionIdOrUserId);\n            this.config.submissionClient.sendHeartbeat(sessionIdOrUserId, false, this.config);\n        }\n    };\n    ExceptionlessClient.prototype.createEvent = function (pluginContextData) {\n        return new EventBuilder({ date: new Date() }, this, pluginContextData);\n    };\n    ExceptionlessClient.prototype.submitEvent = function (event, pluginContextData, callback) {\n        function cancelled(context) {\n            if (!!context) {\n                context.cancelled = true;\n            }\n            return !!callback && callback(context);\n        }\n        var context = new EventPluginContext(this, event, pluginContextData);\n        if (!event) {\n            return cancelled(context);\n        }\n        if (!this.config.enabled) {\n            this.config.log.info('Event submission is currently disabled.');\n            return cancelled(context);\n        }\n        if (!event.data) {\n            event.data = {};\n        }\n        if (!event.tags || !event.tags.length) {\n            event.tags = [];\n        }\n        EventPluginManager.run(context, function (ctx) {\n            var config = ctx.client.config;\n            var ev = ctx.event;\n            if (!ctx.cancelled) {\n                if (!ev.type || ev.type.length === 0) {\n                    ev.type = 'log';\n                }\n                if (!ev.date) {\n                    ev.date = new Date();\n                }\n                config.queue.enqueue(ev);\n                if (ev.reference_id && ev.reference_id.length > 0) {\n                    ctx.log.info(\"Setting last reference id '\" + ev.reference_id + \"'\");\n                    config.lastReferenceIdManager.setLast(ev.reference_id);\n                }\n            }\n            !!callback && callback(ctx);\n        });\n    };\n    ExceptionlessClient.prototype.updateUserEmailAndDescription = function (referenceId, email, description, callback) {\n        var _this = this;\n        if (!referenceId || !email || !description || !this.config.enabled) {\n            return !!callback && callback(new SubmissionResponse(500, 'cancelled'));\n        }\n        var userDescription = { email_address: email, description: description };\n        this.config.submissionClient.postUserDescription(referenceId, userDescription, this.config, function (response) {\n            if (!response.success) {\n                _this.config.log.error(\"Failed to submit user email and description for event '\" + referenceId + \"': \" + response.statusCode + \" \" + response.message);\n            }\n            !!callback && callback(response);\n        });\n    };\n    ExceptionlessClient.prototype.getLastReferenceId = function () {\n        return this.config.lastReferenceIdManager.getLast();\n    };\n    ExceptionlessClient.prototype.updateSettingsTimer = function (initialDelay) {\n        var _this = this;\n        this.config.log.info(\"Updating settings timer with delay: \" + initialDelay);\n        this._timeoutId = clearTimeout(this._timeoutId);\n        this._timeoutId = clearInterval(this._intervalId);\n        var interval = this.config.updateSettingsWhenIdleInterval;\n        if (interval > 0) {\n            var updateSettings = function () { return SettingsManager.updateSettings(_this.config); };\n            if (initialDelay > 0) {\n                this._timeoutId = setTimeout(updateSettings, initialDelay);\n            }\n            this._intervalId = setInterval(updateSettings, interval);\n        }\n    };\n    Object.defineProperty(ExceptionlessClient, \"default\", {\n        get: function () {\n            if (ExceptionlessClient._instance === null) {\n                ExceptionlessClient._instance = new ExceptionlessClient(null);\n            }\n            return ExceptionlessClient._instance;\n        },\n        enumerable: true,\n        configurable: true\n    });\n    ExceptionlessClient._instance = null;\n    return ExceptionlessClient;\n}());\nexports.ExceptionlessClient = ExceptionlessClient;\nvar ConfigurationDefaultsPlugin = (function () {\n    function ConfigurationDefaultsPlugin() {\n        this.priority = 10;\n        this.name = 'ConfigurationDefaultsPlugin';\n    }\n    ConfigurationDefaultsPlugin.prototype.run = function (context, next) {\n        var config = context.client.config;\n        var defaultTags = config.defaultTags || [];\n        for (var index = 0; index < defaultTags.length; index++) {\n            var tag = defaultTags[index];\n            if (!!tag && context.event.tags.indexOf(tag) < 0) {\n                context.event.tags.push(tag);\n            }\n        }\n        var defaultData = config.defaultData || {};\n        for (var key in defaultData) {\n            if (!!defaultData[key]) {\n                var result = JSON.parse(Utils.stringify(defaultData[key], config.dataExclusions));\n                if (!Utils.isEmpty(result)) {\n                    context.event.data[key] = result;\n                }\n            }\n        }\n        next && next();\n    };\n    return ConfigurationDefaultsPlugin;\n}());\nexports.ConfigurationDefaultsPlugin = ConfigurationDefaultsPlugin;\nvar ErrorPlugin = (function () {\n    function ErrorPlugin() {\n        this.priority = 30;\n        this.name = 'ErrorPlugin';\n    }\n    ErrorPlugin.prototype.run = function (context, next) {\n        var ERROR_KEY = '@error';\n        var ignoredProperties = [\n            'arguments',\n            'column',\n            'columnNumber',\n            'description',\n            'fileName',\n            'message',\n            'name',\n            'number',\n            'line',\n            'lineNumber',\n            'opera#sourceloc',\n            'sourceId',\n            'sourceURL',\n            'stack',\n            'stackArray',\n            'stacktrace'\n        ];\n        var exception = context.contextData.getException();\n        if (!!exception) {\n            context.event.type = 'error';\n            if (!context.event.data[ERROR_KEY]) {\n                var config = context.client.config;\n                var parser = config.errorParser;\n                if (!parser) {\n                    throw new Error('No error parser was defined.');\n                }\n                var result = parser.parse(context, exception);\n                if (!!result) {\n                    var additionalData = JSON.parse(Utils.stringify(exception, config.dataExclusions.concat(ignoredProperties)));\n                    if (!Utils.isEmpty(additionalData)) {\n                        if (!result.data) {\n                            result.data = {};\n                        }\n                        result.data['@ext'] = additionalData;\n                    }\n                    context.event.data[ERROR_KEY] = result;\n                }\n            }\n        }\n        next && next();\n    };\n    return ErrorPlugin;\n}());\nexports.ErrorPlugin = ErrorPlugin;\nvar ModuleInfoPlugin = (function () {\n    function ModuleInfoPlugin() {\n        this.priority = 50;\n        this.name = 'ModuleInfoPlugin';\n    }\n    ModuleInfoPlugin.prototype.run = function (context, next) {\n        var ERROR_KEY = '@error';\n        var collector = context.client.config.moduleCollector;\n        if (context.event.data[ERROR_KEY] && !context.event.data['@error'].modules && !!collector) {\n            var modules = collector.getModules(context);\n            if (modules && modules.length > 0) {\n                context.event.data[ERROR_KEY].modules = modules;\n            }\n        }\n        next && next();\n    };\n    return ModuleInfoPlugin;\n}());\nexports.ModuleInfoPlugin = ModuleInfoPlugin;\nvar RequestInfoPlugin = (function () {\n    function RequestInfoPlugin() {\n        this.priority = 70;\n        this.name = 'RequestInfoPlugin';\n    }\n    RequestInfoPlugin.prototype.run = function (context, next) {\n        var REQUEST_KEY = '@request';\n        var config = context.client.config;\n        var collector = config.requestInfoCollector;\n        if (!context.event.data[REQUEST_KEY] && !!collector) {\n            var requestInfo = collector.getRequestInfo(context);\n            if (!!requestInfo) {\n                if (Utils.isMatch(requestInfo.user_agent, config.userAgentBotPatterns)) {\n                    context.log.info('Cancelling event as the request user agent matches a known bot pattern');\n                    context.cancelled = true;\n                }\n                else {\n                    context.event.data[REQUEST_KEY] = requestInfo;\n                }\n            }\n        }\n        next && next();\n    };\n    return RequestInfoPlugin;\n}());\nexports.RequestInfoPlugin = RequestInfoPlugin;\nvar EnvironmentInfoPlugin = (function () {\n    function EnvironmentInfoPlugin() {\n        this.priority = 80;\n        this.name = 'EnvironmentInfoPlugin';\n    }\n    EnvironmentInfoPlugin.prototype.run = function (context, next) {\n        var ENVIRONMENT_KEY = '@environment';\n        var collector = context.client.config.environmentInfoCollector;\n        if (!context.event.data[ENVIRONMENT_KEY] && collector) {\n            var environmentInfo = collector.getEnvironmentInfo(context);\n            if (!!environmentInfo) {\n                context.event.data[ENVIRONMENT_KEY] = environmentInfo;\n            }\n        }\n        next && next();\n    };\n    return EnvironmentInfoPlugin;\n}());\nexports.EnvironmentInfoPlugin = EnvironmentInfoPlugin;\nvar SubmissionMethodPlugin = (function () {\n    function SubmissionMethodPlugin() {\n        this.priority = 100;\n        this.name = 'SubmissionMethodPlugin';\n    }\n    SubmissionMethodPlugin.prototype.run = function (context, next) {\n        var submissionMethod = context.contextData.getSubmissionMethod();\n        if (!!submissionMethod) {\n            context.event.data['@submission_method'] = submissionMethod;\n        }\n        next && next();\n    };\n    return SubmissionMethodPlugin;\n}());\nexports.SubmissionMethodPlugin = SubmissionMethodPlugin;\nvar DuplicateCheckerPlugin = (function () {\n    function DuplicateCheckerPlugin(getCurrentTime, interval) {\n        var _this = this;\n        if (getCurrentTime === void 0) { getCurrentTime = function () { return Date.now(); }; }\n        if (interval === void 0) { interval = 30000; }\n        this.priority = 1010;\n        this.name = 'DuplicateCheckerPlugin';\n        this._mergedEvents = [];\n        this._processedHashcodes = [];\n        this._getCurrentTime = getCurrentTime;\n        this._interval = interval;\n        setInterval(function () {\n            while (_this._mergedEvents.length > 0) {\n                _this._mergedEvents.shift().resubmit();\n            }\n        }, interval);\n    }\n    DuplicateCheckerPlugin.prototype.run = function (context, next) {\n        var _this = this;\n        function getHashCode(error) {\n            var hashCode = 0;\n            while (error) {\n                if (error.message && error.message.length) {\n                    hashCode += (hashCode * 397) ^ Utils.getHashCode(error.message);\n                }\n                if (error.stack_trace && error.stack_trace.length) {\n                    hashCode += (hashCode * 397) ^ Utils.getHashCode(JSON.stringify(error.stack_trace));\n                }\n                error = error.inner;\n            }\n            return hashCode;\n        }\n        var error = context.event.data['@error'];\n        var hashCode = getHashCode(error);\n        if (hashCode) {\n            var count = context.event.count || 1;\n            var now_1 = this._getCurrentTime();\n            var merged = this._mergedEvents.filter(function (s) { return s.hashCode === hashCode; })[0];\n            if (merged) {\n                merged.incrementCount(count);\n                merged.updateDate(context.event.date);\n                context.log.info('Ignoring duplicate event with hash: ' + hashCode);\n                context.cancelled = true;\n            }\n            if (!context.cancelled && this._processedHashcodes.some(function (h) { return h.hash === hashCode && h.timestamp >= (now_1 - _this._interval); })) {\n                context.log.trace('Adding event with hash: ' + hashCode);\n                this._mergedEvents.push(new MergedEvent(hashCode, context, count));\n                context.cancelled = true;\n            }\n            if (!context.cancelled) {\n                context.log.trace('Enqueueing event with hash: ' + hashCode + 'to cache.');\n                this._processedHashcodes.push({ hash: hashCode, timestamp: now_1 });\n                while (this._processedHashcodes.length > 50) {\n                    this._processedHashcodes.shift();\n                }\n            }\n        }\n        next && next();\n    };\n    return DuplicateCheckerPlugin;\n}());\nexports.DuplicateCheckerPlugin = DuplicateCheckerPlugin;\nvar MergedEvent = (function () {\n    function MergedEvent(hashCode, context, count) {\n        this.hashCode = hashCode;\n        this._context = context;\n        this._count = count;\n    }\n    MergedEvent.prototype.incrementCount = function (count) {\n        this._count += count;\n    };\n    MergedEvent.prototype.resubmit = function () {\n        this._context.event.count = this._count;\n        this._context.client.config.queue.enqueue(this._context.event);\n    };\n    MergedEvent.prototype.updateDate = function (date) {\n        if (date > this._context.event.date) {\n            this._context.event.date = date;\n        }\n    };\n    return MergedEvent;\n}());\nvar EventExclusionPlugin = (function () {\n    function EventExclusionPlugin() {\n        this.priority = 45;\n        this.name = 'EventExclusionPlugin';\n    }\n    EventExclusionPlugin.prototype.run = function (context, next) {\n        function getLogLevel(level) {\n            switch ((level || '').toLowerCase().trim()) {\n                case 'trace':\n                case 'true':\n                case '1':\n                case 'yes':\n                    return 0;\n                case 'debug':\n                    return 1;\n                case 'info':\n                    return 2;\n                case 'warn':\n                    return 3;\n                case 'error':\n                    return 4;\n                case 'fatal':\n                    return 5;\n                case 'off':\n                case 'false':\n                case '0':\n                case 'no':\n                    return 6;\n                default:\n                    return -1;\n            }\n        }\n        function getMinLogLevel(settings, loggerName) {\n            if (loggerName === void 0) { loggerName = '*'; }\n            return getLogLevel(getTypeAndSourceSetting(settings, 'log', loggerName, 'Trace') + '');\n        }\n        function getTypeAndSourceSetting(settings, type, source, defaultValue) {\n            if (settings === void 0) { settings = {}; }\n            if (defaultValue === void 0) { defaultValue = undefined; }\n            if (!type) {\n                return defaultValue;\n            }\n            var isLog = type === 'log';\n            var sourcePrefix = \"@@\" + type + \":\";\n            var value = settings[sourcePrefix + source];\n            if (value) {\n                return !isLog ? Utils.toBoolean(value) : value;\n            }\n            for (var key in settings) {\n                if (Utils.startsWith(key.toLowerCase(), sourcePrefix.toLowerCase()) && Utils.isMatch(source, [key.substring(sourcePrefix.length)])) {\n                    return !isLog ? Utils.toBoolean(settings[key]) : settings[key];\n                }\n            }\n            return defaultValue;\n        }\n        var ev = context.event;\n        var log = context.log;\n        var settings = context.client.config.settings;\n        if (ev.type === 'log') {\n            var minLogLevel = getMinLogLevel(settings, ev.source);\n            var logLevel = getLogLevel(ev.data['@level']);\n            if (logLevel >= 0 && (logLevel > 5 || logLevel < minLogLevel)) {\n                log.info('Cancelling log event due to minimum log level.');\n                context.cancelled = true;\n            }\n        }\n        else if (ev.type === 'error') {\n            var error = ev.data['@error'];\n            while (!context.cancelled && error) {\n                if (getTypeAndSourceSetting(settings, ev.type, error.type, true) === false) {\n                    log.info(\"Cancelling error from excluded exception type: \" + error.type);\n                    context.cancelled = true;\n                }\n                error = error.inner;\n            }\n        }\n        else if (getTypeAndSourceSetting(settings, ev.type, ev.source, true) === false) {\n            log.info(\"Cancelling event from excluded type: \" + ev.type + \" and source: \" + ev.source);\n            context.cancelled = true;\n        }\n        next && next();\n    };\n    return EventExclusionPlugin;\n}());\nexports.EventExclusionPlugin = EventExclusionPlugin;\nvar SettingsResponse = (function () {\n    function SettingsResponse(success, settings, settingsVersion, exception, message) {\n        if (settingsVersion === void 0) { settingsVersion = -1; }\n        if (exception === void 0) { exception = null; }\n        if (message === void 0) { message = null; }\n        this.success = false;\n        this.settingsVersion = -1;\n        this.success = success;\n        this.settings = settings;\n        this.settingsVersion = settingsVersion;\n        this.exception = exception;\n        this.message = message;\n    }\n    return SettingsResponse;\n}());\nexports.SettingsResponse = SettingsResponse;\nvar InMemoryStorage = (function () {\n    function InMemoryStorage(maxItems) {\n        this.items = [];\n        this.lastTimestamp = 0;\n        this.maxItems = maxItems;\n    }\n    InMemoryStorage.prototype.save = function (value) {\n        if (!value) {\n            return null;\n        }\n        var items = this.items;\n        var timestamp = Math.max(Date.now(), this.lastTimestamp + 1);\n        var item = { timestamp: timestamp, value: value };\n        if (items.push(item) > this.maxItems) {\n            items.shift();\n        }\n        this.lastTimestamp = timestamp;\n        return item.timestamp;\n    };\n    InMemoryStorage.prototype.get = function (limit) {\n        return this.items.slice(0, limit);\n    };\n    InMemoryStorage.prototype.remove = function (timestamp) {\n        var items = this.items;\n        for (var i = 0; i < items.length; i++) {\n            if (items[i].timestamp === timestamp) {\n                items.splice(i, 1);\n                return;\n            }\n        }\n    };\n    InMemoryStorage.prototype.clear = function () {\n        this.items = [];\n    };\n    return InMemoryStorage;\n}());\nexports.InMemoryStorage = InMemoryStorage;\nvar KeyValueStorageBase = (function () {\n    function KeyValueStorageBase(maxItems) {\n        this.lastTimestamp = 0;\n        this.maxItems = maxItems;\n    }\n    KeyValueStorageBase.prototype.save = function (value, single) {\n        if (!value) {\n            return null;\n        }\n        this.ensureIndex();\n        var items = this.items;\n        var timestamp = Math.max(Date.now(), this.lastTimestamp + 1);\n        var key = this.getKey(timestamp);\n        var json = JSON.stringify(value);\n        try {\n            this.write(key, json);\n            this.lastTimestamp = timestamp;\n            if (items.push(timestamp) > this.maxItems) {\n                this.delete(this.getKey(items.shift()));\n            }\n        }\n        catch (e) {\n            return null;\n        }\n        return timestamp;\n    };\n    KeyValueStorageBase.prototype.get = function (limit) {\n        var _this = this;\n        this.ensureIndex();\n        return this.items.slice(0, limit)\n            .map(function (timestamp) {\n            var key = _this.getKey(timestamp);\n            try {\n                var json = _this.read(key);\n                var value = JSON.parse(json, parseDate);\n                return { timestamp: timestamp, value: value };\n            }\n            catch (error) {\n                _this.safeDelete(key);\n                return null;\n            }\n        })\n            .filter(function (item) { return item != null; });\n    };\n    KeyValueStorageBase.prototype.remove = function (timestamp) {\n        this.ensureIndex();\n        var items = this.items;\n        var index = items.indexOf(timestamp);\n        if (index >= 0) {\n            var key = this.getKey(timestamp);\n            this.safeDelete(key);\n            items.splice(index, 1);\n        }\n        ;\n    };\n    KeyValueStorageBase.prototype.clear = function () {\n        var _this = this;\n        this.items.forEach(function (item) { return _this.safeDelete(_this.getKey(item)); });\n        this.items = [];\n    };\n    KeyValueStorageBase.prototype.ensureIndex = function () {\n        if (!this.items) {\n            this.items = this.createIndex();\n            this.lastTimestamp = Math.max.apply(Math, [0].concat(this.items)) + 1;\n        }\n    };\n    KeyValueStorageBase.prototype.safeDelete = function (key) {\n        try {\n            this.delete(key);\n        }\n        catch (error) {\n        }\n    };\n    KeyValueStorageBase.prototype.createIndex = function () {\n        var _this = this;\n        try {\n            var keys = this.readAllKeys();\n            return keys.map(function (key) {\n                try {\n                    var timestamp = _this.getTimestamp(key);\n                    if (!timestamp) {\n                        _this.safeDelete(key);\n                        return null;\n                    }\n                    return timestamp;\n                }\n                catch (error) {\n                    _this.safeDelete(key);\n                    return null;\n                }\n            }).filter(function (timestamp) { return timestamp != null; })\n                .sort(function (a, b) { return a - b; });\n        }\n        catch (error) {\n            return [];\n        }\n    };\n    return KeyValueStorageBase;\n}());\nexports.KeyValueStorageBase = KeyValueStorageBase;\nfunction parseDate(key, value) {\n    var dateRegx = /\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d:[0-5]\\d|Z)/g;\n    if (typeof value === 'string') {\n        var a = dateRegx.exec(value);\n        if (a) {\n            return new Date(value);\n        }\n    }\n    return value;\n}\n;\nvar BrowserStorage = (function (_super) {\n    __extends(BrowserStorage, _super);\n    function BrowserStorage(namespace, prefix, maxItems) {\n        if (prefix === void 0) { prefix = 'com.exceptionless.'; }\n        if (maxItems === void 0) { maxItems = 20; }\n        _super.call(this, maxItems);\n        this.prefix = prefix + namespace + '-';\n    }\n    BrowserStorage.isAvailable = function () {\n        try {\n            var storage = window.localStorage, x = '__storage_test__';\n            storage.setItem(x, x);\n            storage.removeItem(x);\n            return true;\n        }\n        catch (e) {\n            return false;\n        }\n    };\n    BrowserStorage.prototype.write = function (key, value) {\n        window.localStorage.setItem(key, value);\n    };\n    BrowserStorage.prototype.read = function (key) {\n        return window.localStorage.getItem(key);\n    };\n    BrowserStorage.prototype.readAllKeys = function () {\n        var _this = this;\n        return Object.keys(window.localStorage)\n            .filter(function (key) { return key.indexOf(_this.prefix) === 0; });\n    };\n    BrowserStorage.prototype.delete = function (key) {\n        window.localStorage.removeItem(key);\n    };\n    BrowserStorage.prototype.getKey = function (timestamp) {\n        return this.prefix + timestamp;\n    };\n    BrowserStorage.prototype.getTimestamp = function (key) {\n        return parseInt(key.substr(this.prefix.length), 10);\n    };\n    return BrowserStorage;\n}(KeyValueStorageBase));\nexports.BrowserStorage = BrowserStorage;\nvar DefaultErrorParser = (function () {\n    function DefaultErrorParser() {\n    }\n    DefaultErrorParser.prototype.parse = function (context, exception) {\n        function getParameters(parameters) {\n            var params = (typeof parameters === 'string' ? [parameters] : parameters) || [];\n            var result = [];\n            for (var index = 0; index < params.length; index++) {\n                result.push({ name: params[index] });\n            }\n            return result;\n        }\n        function getStackFrames(stackFrames) {\n            var ANONYMOUS = '<anonymous>';\n            var frames = [];\n            for (var index = 0; index < stackFrames.length; index++) {\n                var frame = stackFrames[index];\n                frames.push({\n                    name: (frame.func || ANONYMOUS).replace('?', ANONYMOUS),\n                    parameters: getParameters(frame.args),\n                    file_name: frame.url,\n                    line_number: frame.line || 0,\n                    column: frame.column || 0\n                });\n            }\n            return frames;\n        }\n        var TRACEKIT_STACK_TRACE_KEY = '@@_TraceKit.StackTrace';\n        var stackTrace = !!context.contextData[TRACEKIT_STACK_TRACE_KEY]\n            ? context.contextData[TRACEKIT_STACK_TRACE_KEY]\n            : TraceKit.computeStackTrace(exception, 25);\n        if (!stackTrace) {\n            throw new Error('Unable to parse the exceptions stack trace.');\n        }\n        var message = typeof (exception) === 'string' ? exception : undefined;\n        return {\n            type: stackTrace.name,\n            message: stackTrace.message || exception.message || message,\n            stack_trace: getStackFrames(stackTrace.stack || [])\n        };\n    };\n    return DefaultErrorParser;\n}());\nexports.DefaultErrorParser = DefaultErrorParser;\nvar DefaultModuleCollector = (function () {\n    function DefaultModuleCollector() {\n    }\n    DefaultModuleCollector.prototype.getModules = function (context) {\n        if (document && document.getElementsByTagName) {\n            return null;\n        }\n        var modules = [];\n        var scripts = document.getElementsByTagName('script');\n        if (scripts && scripts.length > 0) {\n            for (var index = 0; index < scripts.length; index++) {\n                if (scripts[index].src) {\n                    modules.push({\n                        module_id: index,\n                        name: scripts[index].src,\n                        version: Utils.parseVersion(scripts[index].src)\n                    });\n                }\n                else if (!!scripts[index].innerHTML) {\n                    modules.push({\n                        module_id: index,\n                        name: 'Script Tag',\n                        version: Utils.getHashCode(scripts[index].innerHTML).toString()\n                    });\n                }\n            }\n        }\n        return modules;\n    };\n    return DefaultModuleCollector;\n}());\nexports.DefaultModuleCollector = DefaultModuleCollector;\nvar DefaultRequestInfoCollector = (function () {\n    function DefaultRequestInfoCollector() {\n    }\n    DefaultRequestInfoCollector.prototype.getRequestInfo = function (context) {\n        if (!document || !navigator || !location) {\n            return null;\n        }\n        var exclusions = context.client.config.dataExclusions;\n        var requestInfo = {\n            user_agent: navigator.userAgent,\n            is_secure: location.protocol === 'https:',\n            host: location.hostname,\n            port: location.port && location.port !== '' ? parseInt(location.port, 10) : 80,\n            path: location.pathname,\n            cookies: Utils.getCookies(document.cookie, exclusions),\n            query_string: Utils.parseQueryString(location.search.substring(1), exclusions)\n        };\n        if (document.referrer && document.referrer !== '') {\n            requestInfo.referrer = document.referrer;\n        }\n        return requestInfo;\n    };\n    return DefaultRequestInfoCollector;\n}());\nexports.DefaultRequestInfoCollector = DefaultRequestInfoCollector;\nvar DefaultSubmissionAdapter = (function () {\n    function DefaultSubmissionAdapter() {\n    }\n    DefaultSubmissionAdapter.prototype.sendRequest = function (request, callback, isAppExiting) {\n        var TIMEOUT = 'timeout';\n        var LOADED = 'loaded';\n        var WITH_CREDENTIALS = 'withCredentials';\n        var isCompleted = false;\n        var useSetTimeout = false;\n        function complete(mode, xhr) {\n            function parseResponseHeaders(headerStr) {\n                function trim(value) {\n                    return value.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n                }\n                var headers = {};\n                var headerPairs = (headerStr || '').split('\\u000d\\u000a');\n                for (var index = 0; index < headerPairs.length; index++) {\n                    var headerPair = headerPairs[index];\n                    var separator = headerPair.indexOf('\\u003a\\u0020');\n                    if (separator > 0) {\n                        headers[trim(headerPair.substring(0, separator).toLowerCase())] = headerPair.substring(separator + 2);\n                    }\n                }\n                return headers;\n            }\n            if (isCompleted) {\n                return;\n            }\n            isCompleted = true;\n            var message = xhr.statusText;\n            var responseText = xhr.responseText;\n            var status = xhr.status;\n            if (mode === TIMEOUT || status === 0) {\n                message = 'Unable to connect to server.';\n                status = 0;\n            }\n            else if (mode === LOADED && !status) {\n                status = request.method === 'POST' ? 202 : 200;\n            }\n            else if (status < 200 || status > 299) {\n                var responseBody = xhr.responseBody;\n                if (!!responseBody && !!responseBody.message) {\n                    message = responseBody.message;\n                }\n                else if (!!responseText && responseText.indexOf('message') !== -1) {\n                    try {\n                        message = JSON.parse(responseText).message;\n                    }\n                    catch (e) {\n                        message = responseText;\n                    }\n                }\n            }\n            callback && callback(status || 500, message || '', responseText, parseResponseHeaders(xhr.getAllResponseHeaders && xhr.getAllResponseHeaders()));\n        }\n        function createRequest(userAgent, method, url) {\n            var xhr = new XMLHttpRequest();\n            if (WITH_CREDENTIALS in xhr) {\n                xhr.open(method, url, true);\n                xhr.setRequestHeader('X-Exceptionless-Client', userAgent);\n                if (method === 'POST') {\n                    xhr.setRequestHeader('Content-Type', 'application/json');\n                }\n            }\n            else if (typeof XDomainRequest !== 'undefined') {\n                useSetTimeout = true;\n                xhr = new XDomainRequest();\n                xhr.open(method, location.protocol === 'http:' ? url.replace('https:', 'http:') : url);\n            }\n            else {\n                xhr = null;\n            }\n            if (xhr) {\n                xhr.timeout = 10000;\n            }\n            return xhr;\n        }\n        var url = \"\" + request.url + (request.url.indexOf('?') === -1 ? '?' : '&') + \"access_token=\" + encodeURIComponent(request.apiKey);\n        var xhr = createRequest(request.userAgent, request.method || 'POST', url);\n        if (!xhr) {\n            return (callback && callback(503, 'CORS not supported.'));\n        }\n        if (WITH_CREDENTIALS in xhr) {\n            xhr.onreadystatechange = function () {\n                if (xhr.readyState !== 4) {\n                    return;\n                }\n                complete(LOADED, xhr);\n            };\n        }\n        xhr.onprogress = function () { };\n        xhr.ontimeout = function () { return complete(TIMEOUT, xhr); };\n        xhr.onerror = function () { return complete('error', xhr); };\n        xhr.onload = function () { return complete(LOADED, xhr); };\n        if (useSetTimeout) {\n            setTimeout(function () { return xhr.send(request.data); }, 500);\n        }\n        else {\n            xhr.send(request.data);\n        }\n    };\n    return DefaultSubmissionAdapter;\n}());\nexports.DefaultSubmissionAdapter = DefaultSubmissionAdapter;\nvar BrowserStorageProvider = (function () {\n    function BrowserStorageProvider(prefix, maxQueueItems) {\n        if (maxQueueItems === void 0) { maxQueueItems = 250; }\n        this.queue = new BrowserStorage('q', prefix, maxQueueItems);\n        this.settings = new BrowserStorage('settings', prefix, 1);\n    }\n    return BrowserStorageProvider;\n}());\nexports.BrowserStorageProvider = BrowserStorageProvider;\nfunction getDefaultsSettingsFromScriptTag() {\n    if (!document || !document.getElementsByTagName) {\n        return null;\n    }\n    var scripts = document.getElementsByTagName('script');\n    for (var index = 0; index < scripts.length; index++) {\n        if (scripts[index].src && scripts[index].src.indexOf('/exceptionless') > -1) {\n            return Utils.parseQueryString(scripts[index].src.split('?').pop());\n        }\n    }\n    return null;\n}\nfunction processUnhandledException(stackTrace, options) {\n    var builder = ExceptionlessClient.default.createUnhandledException(new Error(stackTrace.message || (options || {}).status || 'Script error'), 'onerror');\n    builder.pluginContextData['@@_TraceKit.StackTrace'] = stackTrace;\n    builder.submit();\n}\nConfiguration.prototype.useLocalStorage = function () {\n    if (BrowserStorage.isAvailable()) {\n        this.storage = new BrowserStorageProvider();\n        SettingsManager.applySavedServerSettings(this);\n        this.changed();\n    }\n};\nvar defaults = Configuration.defaults;\nvar settings = getDefaultsSettingsFromScriptTag();\nif (settings && (settings.apiKey || settings.serverUrl)) {\n    defaults.apiKey = settings.apiKey;\n    defaults.serverUrl = settings.serverUrl;\n}\ndefaults.errorParser = new DefaultErrorParser();\ndefaults.moduleCollector = new DefaultModuleCollector();\ndefaults.requestInfoCollector = new DefaultRequestInfoCollector();\ndefaults.submissionAdapter = new DefaultSubmissionAdapter();\nTraceKit.report.subscribe(processUnhandledException);\nTraceKit.extendToAsynchronousCallbacks();\nError.stackTraceLimit = Infinity;\n\nreturn exports;\n\n}));\n\n\n","import * as TraceKit from 'TraceKit';\nexport interface IEvent {\n  type?: string;\n  source?: string;\n  date?: Date;\n  tags?: string[];\n  message?: string;\n  geo?: string;\n  value?: number;\n  data?: any;\n  reference_id?: string;\n  count?: number;\n}\n\nexport class SubmissionResponse {\n  public success: boolean = false;\n  public badRequest: boolean = false;\n  public serviceUnavailable: boolean = false;\n  public paymentRequired: boolean = false;\n  public unableToAuthenticate: boolean = false;\n  public notFound: boolean = false;\n  public requestEntityTooLarge: boolean = false;\n  public statusCode: number;\n  public message: string;\n\n  constructor(statusCode: number, message?: string) {\n    this.statusCode = statusCode;\n    this.message = message;\n\n    this.success = statusCode >= 200 && statusCode <= 299;\n    this.badRequest = statusCode === 400;\n    this.serviceUnavailable = statusCode === 503;\n    this.paymentRequired = statusCode === 402;\n    this.unableToAuthenticate = statusCode === 401 || statusCode === 403;\n    this.notFound = statusCode === 404;\n    this.requestEntityTooLarge = statusCode === 413;\n  }\n}\n\nexport interface ILastReferenceIdManager {\n  getLast(): string;\n  clearLast(): void;\n  setLast(eventId: string): void;\n}\n\nexport interface ILog {\n  trace(message: string): void;\n  info(message: string): void;\n  warn(message: string): void;\n  error(message: string): void;\n}\n\n                                                                                                                 \n\nexport interface IEventQueue {\n  enqueue(event: IEvent): void;\n  process(isAppExiting?: boolean): void;\n  suspendProcessing(durationInMinutes?: number, discardFutureQueuedItems?: boolean, clearQueue?: boolean): void;\n  onEventsPosted(handler: (events: IEvent[], response: SubmissionResponse) => void): void;\n}\n\n                                                                                                                                  \n\nexport interface IEnvironmentInfoCollector {\n  getEnvironmentInfo(context: EventPluginContext): IEnvironmentInfo;\n}\n\n                                                                                                              \n\nexport interface IErrorParser {\n  parse(context: EventPluginContext, exception: Error): IError;\n}\n\n                                                                                                                \n\nexport interface IModuleCollector {\n  getModules(context: EventPluginContext): IModule[];\n}\n\n                                                                                                                          \n\nexport interface IRequestInfoCollector {\n  getRequestInfo(context: EventPluginContext): IRequestInfo;\n}\n\n                                      \n\nexport interface IStorageProvider {\n  queue: IStorage;\n  settings: IStorage;\n}\n\n                                                                                                                   \n\nexport interface ISubmissionAdapter {\n  sendRequest(request: SubmissionRequest, callback?: SubmissionCallback, isAppExiting?: boolean): void;\n}\n\n                                                                                                                                                                                                                                                                                           \n\nexport interface ISubmissionClient {\n  postEvents(events: IEvent[], config: Configuration, callback: (response: SubmissionResponse) => void, isAppExiting?: boolean): void;\n  postUserDescription(referenceId: string, description: IUserDescription, config: Configuration, callback: (response: SubmissionResponse) => void): void;\n  getSettings(config: Configuration, version: number, callback: (response: SettingsResponse) => void): void;\n  sendHeartbeat(sessionIdOrUserId: string, closeSession: boolean, config: Configuration): void;\n}\n\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \n\nexport interface IConfigurationSettings {\n  apiKey?: string;\n  serverUrl?: string;\n  heartbeatServerUrl?: string;\n  updateSettingsWhenIdleInterval?: number;\n  environmentInfoCollector?: IEnvironmentInfoCollector;\n  errorParser?: IErrorParser;\n  lastReferenceIdManager?: ILastReferenceIdManager;\n  log?: ILog;\n  moduleCollector?: IModuleCollector;\n  requestInfoCollector?: IRequestInfoCollector;\n  submissionBatchSize?: number;\n  submissionClient?: ISubmissionClient;\n  submissionAdapter?: ISubmissionAdapter;\n  storage?: IStorageProvider;\n  queue?: IEventQueue;\n}\n\n                                                                                                                                                     \n\ninterface ISettingsWithVersion {\n  version: number;\n  settings: { [key: string]: string };\n}\n\nexport class SettingsManager {\n  /**\n   * A list of handlers that will be fired when the settings change.\n   * @type {Array}\n   * @private\n   */\n  private static _handlers: { (config: Configuration): void }[] = [];\n\n  public static onChanged(handler: (config: Configuration) => void) {\n    !!handler && this._handlers.push(handler);\n  }\n\n  public static applySavedServerSettings(config: Configuration): void {\n    if (!config || !config.isValid) {\n      return;\n    }\n\n    let savedSettings = this.getSavedServerSettings(config);\n    config.log.info(`Applying saved settings: v${savedSettings.version}`);\n    config.settings = Utils.merge(config.settings, savedSettings.settings);\n    this.changed(config);\n  }\n\n  public static getVersion(config: Configuration): number {\n    if (!config || !config.isValid) {\n      return 0;\n    }\n\n    let savedSettings = this.getSavedServerSettings(config);\n    return savedSettings.version || 0;\n  }\n\n  public static checkVersion(version: number, config: Configuration): void {\n    let currentVersion: number = this.getVersion(config);\n    if (version <= currentVersion) {\n      return;\n    }\n\n    config.log.info(`Updating settings from v${currentVersion} to v${version}`);\n    this.updateSettings(config, currentVersion);\n  }\n\n  public static updateSettings(config: Configuration, version?: number): void {\n    if (!config || !config.enabled) {\n      return;\n    }\n\n    let unableToUpdateMessage = 'Unable to update settings';\n    if (!config.isValid) {\n      config.log.error(`${unableToUpdateMessage}: ApiKey is not set.`);\n      return;\n    }\n\n    if (!version || version < 0) {\n      version = this.getVersion(config);\n    }\n\n    config.log.info(`Checking for updated settings from: v${version}.`);\n    config.submissionClient.getSettings(config, version, (response: SettingsResponse) => {\n      if (!config || !response || !response.success || !response.settings) {\n        config.log.warn(`${unableToUpdateMessage}: ${response.message}`);\n        return;\n      }\n\n      config.settings = Utils.merge(config.settings, response.settings);\n\n      // TODO: Store snapshot of settings after reading from config and attributes and use that to revert to defaults.\n      // Remove any existing server settings that are not in the new server settings.\n      let savedServerSettings = SettingsManager.getSavedServerSettings(config);\n      for (let key in savedServerSettings) {\n        if (response.settings[key]) {\n          continue;\n        }\n\n        delete config.settings[key];\n      }\n\n      let newSettings = <ISettingsWithVersion>{\n        version: response.settingsVersion,\n        settings: response.settings\n      };\n\n      config.storage.settings.save(newSettings);\n\n      config.log.info(`Updated settings: v${newSettings.version}`);\n      this.changed(config);\n    });\n  }\n\n  private static changed(config: Configuration) {\n    let handlers = this._handlers; // optimization for minifier.\n    for (let index = 0; index < handlers.length; index++) {\n      try {\n        handlers[index](config);\n      } catch (ex) {\n        config.log.error(`Error calling onChanged handler: ${ex}`);\n      }\n    }\n  }\n\n  private static getSavedServerSettings(config: Configuration): ISettingsWithVersion {\n    let item = config.storage.settings.get()[0];\n    if (item && item.value && item.value.version && item.value.settings) {\n      return item.value;\n    }\n\n    return { version: 0, settings: {} };\n  }\n}\n\n                                                                    \n\nexport class DefaultLastReferenceIdManager implements ILastReferenceIdManager {\n  /**\n   * Gets the last event's reference id that was submitted to the server.\n   * @type {string}\n   * @private\n   */\n  private _lastReferenceId: string = null;\n\n  /**\n   * Gets the last event's reference id that was submitted to the server.\n   * @returns {string}\n   */\n  public getLast(): string {\n    return this._lastReferenceId;\n  }\n\n  /**\n   * Clears the last event's reference id.\n   */\n  public clearLast(): void {\n    this._lastReferenceId = null;\n  }\n\n  /**\n   * Sets the last event's reference id.\n   * @param eventId\n   */\n  public setLast(eventId: string): void {\n    this._lastReferenceId = eventId;\n  }\n}\n\n                              \n\nexport class ConsoleLog implements ILog {\n  public trace(message: string): void {\n    this.log('trace', message);\n  }\n\n  public info(message: string): void {\n    this.log('info', message);\n  }\n\n  public warn(message: string): void {\n    this.log('warn', message);\n  }\n\n  public error(message: string): void {\n    this.log('error', message);\n  }\n\n  private log(level: string, message: string) {\n    if (console) {\n      let msg = `[${level}] Exceptionless: ${message}`;\n\n      if (console[level]) {\n        console[level](msg);\n      } else if (console.log) {\n        console[`log`](msg);\n      }\n    }\n  }\n}\n\n                              \n\nexport class NullLog implements ILog {\n  public trace(message: string): void { }\n  public info(message: string): void { }\n  public warn(message: string): void { }\n  public error(message: string): void { }\n}\n\nexport interface IUserInfo {\n  identity?: string;\n  name?: string;\n  data?: any;\n}\n\n                                                                                                         \n\nexport interface IEventPlugin {\n  priority?: number;\n  name?: string;\n  run(context: EventPluginContext, next?: () => void): void;\n}\n\n                                                                                                                                                                                             \n\nexport class EventPluginContext {\n  public cancelled: boolean;\n  public client: ExceptionlessClient;\n  public event: IEvent;\n  public contextData: ContextData;\n\n  constructor(client: ExceptionlessClient, event: IEvent, contextData?: ContextData) {\n    this.client = client;\n    this.event = event;\n    this.contextData = contextData ? contextData : new ContextData();\n  }\n\n  public get log(): ILog {\n    return this.client.config.log;\n  }\n}\n\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \n\nexport class EventPluginManager {\n  public static run(context: EventPluginContext, callback: (context?: EventPluginContext) => void): void {\n    let wrap = function(plugin: IEventPlugin, next?: () => void): () => void {\n      return () => {\n        try {\n          if (!context.cancelled) {\n            plugin.run(context, next);\n          }\n        } catch (ex) {\n          context.cancelled = true;\n          context.log.error(`Error running plugin '${plugin.name}': ${ex.message}. Discarding Event.`);\n        }\n\n        if (context.cancelled && !!callback) {\n          callback(context);\n        }\n      };\n    };\n\n    let plugins: IEventPlugin[] = context.client.config.plugins; // optimization for minifier.\n    let wrappedPlugins: { (): void }[] = [];\n    if (!!callback) {\n      wrappedPlugins[plugins.length] = wrap({ name: 'cb', priority: 9007199254740992, run: callback }, null);\n    }\n\n    for (let index = plugins.length - 1; index > -1; index--) {\n      wrappedPlugins[index] = wrap(plugins[index], !!callback || (index < plugins.length - 1) ? wrappedPlugins[index + 1] : null);\n    }\n\n    wrappedPlugins[0]();\n  }\n\n  public static addDefaultPlugins(config: Configuration): void {\n    config.addPlugin(new ConfigurationDefaultsPlugin());\n    config.addPlugin(new ErrorPlugin());\n    config.addPlugin(new DuplicateCheckerPlugin());\n    config.addPlugin(new EventExclusionPlugin());\n    config.addPlugin(new ModuleInfoPlugin());\n    config.addPlugin(new RequestInfoPlugin());\n    config.addPlugin(new EnvironmentInfoPlugin());\n    config.addPlugin(new SubmissionMethodPlugin());\n  }\n}\n\n                                                                                                                                                               \n\nexport class HeartbeatPlugin implements IEventPlugin {\n  public priority: number = 100;\n  public name: string = 'HeartbeatPlugin';\n\n  private _interval: number;\n  private _intervalId: any;\n\n  constructor (heartbeatInterval: number = 30000) {\n    this._interval = heartbeatInterval;\n  }\n\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    clearInterval(this._intervalId);\n\n    let user: IUserInfo = context.event.data['@user'];\n    if (user && user.identity) {\n      this._intervalId = setInterval(() => context.client.submitSessionHeartbeat(user.identity), this._interval);\n    }\n\n    next && next();\n  }\n}\n\n                                                                                                                                                \n\nexport class ReferenceIdPlugin implements IEventPlugin {\n  public priority: number = 20;\n  public name: string = 'ReferenceIdPlugin';\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    if ((!context.event.reference_id || context.event.reference_id.length === 0) && context.event.type === 'error') {\n      context.event.reference_id = Utils.guid().replace('-', '').substring(0, 10);\n    }\n\n    next && next();\n  }\n}\n\n                                                                                                                                                                                                                                                                                                                                     \n\nexport class DefaultEventQueue implements IEventQueue {\n  /**\n   * The configuration object.\n   * @type {Configuration}\n   * @private\n   */\n  private _config: Configuration;\n\n  /**\n   * A list of handlers that will be fired when events are submitted.\n   * @type {Array}\n   * @private\n   */\n  private _handlers: { (events: IEvent[], response: SubmissionResponse): void }[] = [];\n\n  /**\n   * Suspends processing until the specified time.\n   * @type {Date}\n   * @private\n   */\n  private _suspendProcessingUntil: Date;\n\n  /**\n   * Discards queued items until the specified time.\n   * @type {Date}\n   * @private\n   */\n  private _discardQueuedItemsUntil: Date;\n\n  /**\n   * Returns true if the queue is processing.\n   * @type {boolean}\n   * @private\n   */\n  private _processingQueue: boolean = false;\n\n  /**\n   * Processes the queue every xx seconds.\n   * @type {Timer}\n   * @private\n   */\n  private _queueTimer: any;\n\n  constructor(config: Configuration) {\n    this._config = config;\n  }\n\n  public enqueue(event: IEvent): void {\n    const eventWillNotBeQueued: string = 'The event will not be queued.'; // optimization for minifier.\n    let config: Configuration = this._config; // Optimization for minifier.\n    let log: ILog = config.log; // Optimization for minifier.\n\n    if (!config.enabled) {\n      log.info(`Configuration is disabled. ${eventWillNotBeQueued}`);\n      return;\n    }\n\n    if (!config.isValid) {\n      log.info(`Invalid Api Key. ${eventWillNotBeQueued}`);\n      return;\n    }\n\n    if (this.areQueuedItemsDiscarded()) {\n      log.info(`Queue items are currently being discarded. ${eventWillNotBeQueued}`);\n      return;\n    }\n\n    this.ensureQueueTimer();\n\n    let timestamp = config.storage.queue.save(event);\n    let logText = `type=${event.type} ${!!event.reference_id ? 'refid=' + event.reference_id : ''}`;\n    if (timestamp) {\n      log.info(`Enqueuing event: ${timestamp} ${logText}`);\n    } else {\n      log.error(`Could not enqueue event ${logText}`);\n    }\n  }\n\n  public process(isAppExiting?: boolean): void {\n    const queueNotProcessed: string = 'The queue will not be processed.'; // optimization for minifier.\n    let config: Configuration = this._config; // Optimization for minifier.\n    let log: ILog = config.log; // Optimization for minifier.\n\n    if (this._processingQueue) {\n      return;\n    }\n\n    log.info('Processing queue...');\n    if (!config.enabled) {\n      log.info(`Configuration is disabled. ${queueNotProcessed}`);\n      return;\n    }\n\n    if (!config.isValid) {\n      log.info(`Invalid Api Key. ${queueNotProcessed}`);\n      return;\n    }\n\n    this._processingQueue = true;\n    this.ensureQueueTimer();\n\n    try {\n      let events = config.storage.queue.get(config.submissionBatchSize);\n      if (!events || events.length === 0) {\n        this._processingQueue = false;\n        return;\n      }\n\n      log.info(`Sending ${events.length} events to ${config.serverUrl}.`);\n      config.submissionClient.postEvents(events.map(e => e.value), config, (response: SubmissionResponse) => {\n        this.processSubmissionResponse(response, events);\n        this.eventsPosted(events.map(e => e.value), response);\n        log.info('Finished processing queue.');\n        this._processingQueue = false;\n      }, isAppExiting);\n    } catch (ex) {\n      log.error(`Error processing queue: ${ex}`);\n      this.suspendProcessing();\n      this._processingQueue = false;\n    }\n  }\n\n  public suspendProcessing(durationInMinutes?: number, discardFutureQueuedItems?: boolean, clearQueue?: boolean): void {\n    let config: Configuration = this._config; // Optimization for minifier.\n\n    if (!durationInMinutes || durationInMinutes <= 0) {\n      durationInMinutes = 5;\n    }\n\n    config.log.info(`Suspending processing for ${durationInMinutes} minutes.`);\n    this._suspendProcessingUntil = new Date(new Date().getTime() + (durationInMinutes * 60000));\n\n    if (discardFutureQueuedItems) {\n      this._discardQueuedItemsUntil = this._suspendProcessingUntil;\n    }\n\n    if (clearQueue) {\n      // Account is over the limit and we want to ensure that the sample size being sent in will contain newer errors.\n      config.storage.queue.clear();\n    }\n  }\n\n  public onEventsPosted(handler: (events: IEvent[], response: SubmissionResponse) => void): void {\n    !!handler && this._handlers.push(handler);\n  }\n\n  private eventsPosted(events: IEvent[], response: SubmissionResponse) {\n    let handlers = this._handlers; // optimization for minifier.\n    for (let index = 0; index < handlers.length; index++) {\n      try {\n        handlers[index](events, response);\n      } catch (ex) {\n        this._config.log.error(`Error calling onEventsPosted handler: ${ex}`);\n      }\n    }\n  }\n\n  private areQueuedItemsDiscarded(): boolean {\n    return this._discardQueuedItemsUntil && this._discardQueuedItemsUntil > new Date();\n  }\n\n  private ensureQueueTimer(): void {\n    if (!this._queueTimer) {\n      this._queueTimer = setInterval(() => this.onProcessQueue(), 10000);\n    }\n  }\n\n  private isQueueProcessingSuspended(): boolean {\n    return this._suspendProcessingUntil && this._suspendProcessingUntil > new Date();\n  }\n\n  private onProcessQueue(): void {\n    if (!this.isQueueProcessingSuspended() && !this._processingQueue) {\n      this.process();\n    }\n  }\n\n  private processSubmissionResponse(response: SubmissionResponse, events: IStorageItem[]): void {\n    const noSubmission: string = 'The event will not be submitted.'; // Optimization for minifier.\n    let config: Configuration = this._config; // Optimization for minifier.\n    let log: ILog = config.log; // Optimization for minifier.\n\n    if (response.success) {\n      log.info(`Sent ${events.length} events.`);\n      this.removeEvents(events);\n      return;\n    }\n\n    if (response.serviceUnavailable) {\n      // You are currently over your rate limit or the servers are under stress.\n      log.error('Server returned service unavailable.');\n      this.suspendProcessing();\n      return;\n    }\n\n    if (response.paymentRequired) {\n      // If the organization over the rate limit then discard the event.\n      log.info('Too many events have been submitted, please upgrade your plan.');\n      this.suspendProcessing(null, true, true);\n      return;\n    }\n\n    if (response.unableToAuthenticate) {\n      // The api key was suspended or could not be authorized.\n      log.info(`Unable to authenticate, please check your configuration. ${noSubmission}`);\n      this.suspendProcessing(15);\n      this.removeEvents(events);\n      return;\n    }\n\n    if (response.notFound || response.badRequest) {\n      // The service end point could not be found.\n      log.error(`Error while trying to submit data: ${response.message}`);\n      this.suspendProcessing(60 * 4);\n      this.removeEvents(events);\n      return;\n    }\n\n    if (response.requestEntityTooLarge) {\n      let message = 'Event submission discarded for being too large.';\n      if (config.submissionBatchSize > 1) {\n        log.error(`${message} Retrying with smaller batch size.`);\n        config.submissionBatchSize = Math.max(1, Math.round(config.submissionBatchSize / 1.5));\n      } else {\n        log.error(`${message} ${noSubmission}`);\n        this.removeEvents(events);\n      }\n\n      return;\n    }\n\n    if (!response.success) {\n      log.error(`Error submitting events: ${response.message || 'Please check the network tab for more info.'}`);\n      this.suspendProcessing();\n    }\n  }\n\n  private removeEvents(events: IStorageItem[]) {\n    for (let index = 0; index < (events || []).length; index++) {\n      this._config.storage.queue.remove(events[index].timestamp);\n    }\n  }\n}\n\n                                                                                                                                                  \n\nexport class InMemoryStorageProvider implements IStorageProvider {\n  public queue: IStorage;\n  public settings: IStorage;\n\n  constructor(maxQueueItems: number = 250) {\n    this.queue = new InMemoryStorage(maxQueueItems);\n    this.settings = new InMemoryStorage(1);\n  }\n\n}\n\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \n\ndeclare var XDomainRequest: { new (); create(); };\n\nexport class DefaultSubmissionClient implements ISubmissionClient {\n  public configurationVersionHeader: string = 'x-exceptionless-configversion';\n\n  public postEvents(events: IEvent[], config: Configuration, callback: (response: SubmissionResponse) => void, isAppExiting?: boolean): void {\n    let data = JSON.stringify(events);\n    let request = this.createRequest(config, 'POST',  `${config.serverUrl}/api/v2/events`, data);\n    let cb = this.createSubmissionCallback(config, callback);\n\n    return config.submissionAdapter.sendRequest(request, cb, isAppExiting);\n  }\n\n  public postUserDescription(referenceId: string, description: IUserDescription, config: Configuration, callback: (response: SubmissionResponse) => void): void {\n    let path = `${config.serverUrl}/api/v2/events/by-ref/${encodeURIComponent(referenceId)}/user-description`;\n    let data = JSON.stringify(description);\n    let request = this.createRequest(config, 'POST', path, data);\n    let cb = this.createSubmissionCallback(config, callback);\n\n    return config.submissionAdapter.sendRequest(request, cb);\n  }\n\n  public getSettings(config: Configuration, version: number, callback: (response: SettingsResponse) => void): void {\n    let request = this.createRequest(config, 'GET', `${config.serverUrl}/api/v2/projects/config?v=${version}`);\n    let cb = (status, message, data?, headers?) => {\n      if (status !== 200) {\n        return callback(new SettingsResponse(false, null, -1, null, message));\n      }\n\n      let settings: IClientConfiguration;\n      try {\n        settings = JSON.parse(data);\n      } catch (e) {\n        config.log.error(`Unable to parse settings: '${data}'`);\n      }\n\n      if (!settings || isNaN(settings.version)) {\n        return callback(new SettingsResponse(false, null, -1, null, 'Invalid configuration settings.'));\n      }\n\n      callback(new SettingsResponse(true, settings.settings || {}, settings.version));\n    };\n\n    return config.submissionAdapter.sendRequest(request, cb);\n  }\n\n  public sendHeartbeat(sessionIdOrUserId: string, closeSession: boolean, config: Configuration): void {\n    let request = this.createRequest(config, 'GET', `${config.heartbeatServerUrl}/api/v2/events/session/heartbeat?id=${sessionIdOrUserId}&close=${closeSession}`);\n    config.submissionAdapter.sendRequest(request);\n  }\n\n  private createRequest(config: Configuration, method: string, url: string, data: string = null): SubmissionRequest {\n    return {\n      method,\n      url,\n      data,\n      apiKey: config.apiKey,\n      userAgent: config.userAgent\n    };\n  }\n\n  private createSubmissionCallback(config: Configuration, callback: (response: SubmissionResponse) => void) {\n    return (status, message, data?, headers?) => {\n      let settingsVersion: number = headers && parseInt(headers[this.configurationVersionHeader], 10);\n      SettingsManager.checkVersion(settingsVersion, config);\n\n      callback(new SubmissionResponse(status, message));\n    };\n  }\n}\n\nexport class Utils {\n  public static addRange<T>(target: T[], ...values: T[]) {\n    if (!target) {\n      target = [];\n    }\n\n    if (!values || values.length === 0) {\n      return target;\n    }\n\n    for (let index = 0; index < values.length; index++) {\n      if (values[index] && target.indexOf(values[index]) < 0) {\n        target.push(values[index]);\n      }\n    }\n\n    return target;\n  }\n\n  public static getHashCode(source: string): number {\n    if (!source || source.length === 0) {\n      return 0;\n    }\n\n    let hash: number = 0;\n    for (let index = 0; index < source.length; index++) {\n      let character = source.charCodeAt(index);\n      hash = ((hash << 5) - hash) + character;\n      hash |= 0;\n    }\n\n    return hash;\n  }\n\n  public static getCookies(cookies: string, exclusions?: string[]): Object {\n    let result: Object = {};\n\n    let parts: string[] = (cookies || '').split('; ');\n    for (let index = 0; index < parts.length; index++) {\n      let cookie: string[] = parts[index].split('=');\n      if (!Utils.isMatch(cookie[0], exclusions)) {\n        result[cookie[0]] = cookie[1];\n      }\n    }\n\n    return !Utils.isEmpty(result) ? result : null;\n  }\n\n  public static guid(): string {\n    function s4() {\n      return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);\n    }\n\n    return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\n  }\n\n  public static merge(defaultValues: Object, values: Object) {\n    let result: Object = {};\n\n    for (let key in defaultValues || {}) {\n      if (!!defaultValues[key]) {\n        result[key] = defaultValues[key];\n      }\n    }\n\n    for (let key in values || {}) {\n      if (!!values[key]) {\n        result[key] = values[key];\n      }\n    }\n\n    return result;\n  }\n\n  public static parseVersion(source: string): string {\n    if (!source) {\n      return null;\n    }\n\n    let versionRegex = /(v?((\\d+)\\.(\\d+)(\\.(\\d+))?)(?:-([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?(?:\\+([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?)/;\n    let matches = versionRegex.exec(source);\n    if (matches && matches.length > 0) {\n      return matches[0];\n    }\n\n    return null;\n  }\n\n  public static parseQueryString(query: string, exclusions?: string[]) {\n    if (!query || query.length === 0) {\n      return null;\n    }\n\n    let pairs: string[] = query.split('&');\n    if (pairs.length === 0) {\n      return null;\n    }\n\n    let result: Object = {};\n    for (let index = 0; index < pairs.length; index++) {\n      let pair = pairs[index].split('=');\n      if (!Utils.isMatch(pair[0], exclusions)) {\n        result[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);\n      }\n    }\n\n    return !Utils.isEmpty(result) ? result : null;\n  }\n\n  public static randomNumber(): number {\n    return Math.floor(Math.random() * 9007199254740992);\n  }\n\n  /**\n   * Checks to see if a value matches a pattern.\n   * @param input the value to check against the @pattern.\n   * @param pattern The pattern to check, supports wild cards (*).\n   */\n  public static isMatch(input: string, patterns: string[], ignoreCase: boolean = true): boolean {\n    if (!input || typeof input !== 'string') {\n      return false;\n    }\n\n    let trim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n    input = (ignoreCase ? input.toLowerCase() : input).replace(trim, '');\n\n    return (patterns || []).some(pattern => {\n      if (typeof pattern !== 'string') {\n        return false;\n      }\n\n      pattern = (ignoreCase ? pattern.toLowerCase() : pattern).replace(trim, '');\n      if (pattern.length <= 0) {\n        return false;\n      }\n\n      let startsWithWildcard: boolean = pattern[0] === '*';\n      if (startsWithWildcard) {\n        pattern = pattern.slice(1);\n      }\n\n      let endsWithWildcard: boolean = pattern[pattern.length - 1] === '*';\n      if (endsWithWildcard) {\n        pattern = pattern.substring(0, pattern.length - 1);\n      }\n\n      if (startsWithWildcard && endsWithWildcard) {\n        return pattern.length <= input.length && input.indexOf(pattern, 0) !== -1;\n      }\n\n      if (startsWithWildcard) {\n        return Utils.endsWith(input, pattern);\n      }\n\n      if (endsWithWildcard) {\n        return Utils.startsWith(input, pattern);\n      }\n\n      return input === pattern;\n    });\n  }\n\n  public static isEmpty(input: Object) {\n    return input === null || (typeof (input) === 'object' && Object.keys(input).length === 0);\n  }\n\n  public static startsWith(input: string, prefix: string): boolean {\n    return input.substring(0, prefix.length) === prefix;\n  }\n\n  public static endsWith(input: string, suffix: string): boolean {\n    return input.indexOf(suffix, input.length - suffix.length) !== -1;\n  }\n\n  /**\n   * Stringifys an object with optional exclusions and max depth.\n   * @param data The data object to add.\n   * @param exclusions Any property names that should be excluded.\n   * @param maxDepth The max depth of the object to include.\n   */\n  public static stringify(data: any, exclusions?: string[], maxDepth?: number): string {\n    function stringifyImpl(obj: any, excludedKeys: string[]): string {\n      let cache: string[] = [];\n      return JSON.stringify(obj, function(key: string, value: any) {\n        if (Utils.isMatch(key, excludedKeys)) {\n          return;\n        }\n\n        if (typeof value === 'object' && !!value) {\n          if (cache.indexOf(value) !== -1) {\n            // Circular reference found, discard key\n            return;\n          }\n\n          cache.push(value);\n        }\n\n        return value;\n      });\n    }\n\n    if (({}).toString.call(data) === '[object Object]') {\n      let flattened = {};\n      /* tslint:disable:forin */\n      for (let prop in data) {\n        let value = data[prop];\n        if (value === data) {\n          continue;\n        }\n        flattened[prop] = data[prop];\n      }\n      /* tslint:enable:forin */\n\n      return stringifyImpl(flattened, exclusions);\n    }\n\n    if (({}).toString.call(data) === '[object Array]') {\n      let result = [];\n      for (let index = 0; index < data.length; index++) {\n        result[index] = JSON.parse(stringifyImpl(data[index], exclusions));\n      }\n\n      return JSON.stringify(result);\n    }\n\n    return stringifyImpl(data, exclusions);\n  }\n\n  public static toBoolean(input, defaultValue: boolean = false): boolean {\n    if (typeof input === 'boolean') {\n      return input;\n    }\n\n    if (input === null || typeof input !== 'number' && typeof input !== 'string') {\n      return defaultValue;\n    }\n\n    switch ((input + '').toLowerCase().trim()) {\n      case 'true': case 'yes': case '1': return true;\n      case 'false': case 'no': case '0': case null: return false;\n    }\n\n    return defaultValue;\n  }\n}\n\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 \n\nexport class Configuration implements IConfigurationSettings {\n  /**\n   * The default configuration settings that are applied to new configuration instances.\n   * @type {IConfigurationSettings}\n   * @private\n   */\n  private static _defaultSettings: IConfigurationSettings = null;\n\n  /**\n   * A default list of tags that will automatically be added to every\n   * report submitted to the server.\n   *\n   * @type {Array}\n   */\n  public defaultTags: string[] = [];\n\n  /**\n   * A default list of of extended data objects that will automatically\n   * be added to every report submitted to the server.\n   *\n   * @type {{}}\n   */\n  public defaultData: Object = {};\n\n  /**\n   * Whether the client is currently enabled or not. If it is disabled,\n   * submitted errors will be discarded and no data will be sent to the server.\n   *\n   * @returns {boolean}\n   */\n  public enabled: boolean = true;\n\n  public environmentInfoCollector: IEnvironmentInfoCollector;\n  public errorParser: IErrorParser;\n  public lastReferenceIdManager: ILastReferenceIdManager = new DefaultLastReferenceIdManager();\n  public log: ILog;\n  public moduleCollector: IModuleCollector;\n  public requestInfoCollector: IRequestInfoCollector;\n\n  /**\n   * Maximum number of events that should be sent to the server together in a batch. (Defaults to 50)\n   */\n  public submissionBatchSize: number;\n  public submissionAdapter: ISubmissionAdapter;\n  public submissionClient: ISubmissionClient;\n\n  /**\n   * Contains a dictionary of custom settings that can be used to control\n   * the client and will be automatically updated from the server.\n   */\n  public settings: Object = {};\n\n  public storage: IStorageProvider;\n\n  public queue: IEventQueue;\n\n  /**\n   * The API key that will be used when sending events to the server.\n   * @type {string}\n   * @private\n   */\n  private _apiKey: string;\n\n  /**\n   * The server url that all events will be sent to.\n   * @type {string}\n   * @private\n   */\n  private _serverUrl: string = 'https://collector.exceptionless.io';\n\n  /**\n   * The heartbeat server url that all heartbeats will be sent to.\n   * @type {string}\n   * @private\n   */\n  private _heartbeatServerUrl: string = 'https://heartbeat.exceptionless.io';\n\n  /**\n   * How often the client should check for updated server settings when idle. The default is every 2 minutes.\n   * @type {number}\n   * @private\n   */\n  private _updateSettingsWhenIdleInterval: number = 120000;\n\n  /**\n   * A list of exclusion patterns.\n   * @type {Array}\n   * @private\n   */\n  private _dataExclusions: string[] = [];\n\n  /**\n   * A list of user agent patterns.\n   * @type {Array}\n   * @private\n   */\n  private _userAgentBotPatterns: string[] = [];\n\n  /**\n   * The list of plugins that will be used in this configuration.\n   * @type {Array}\n   * @private\n   */\n  private _plugins: IEventPlugin[] = [];\n\n  /**\n   * A list of handlers that will be fired when configuration changes.\n   * @type {Array}\n   * @private\n   */\n  private _handlers: { (config: Configuration): void }[] = [];\n\n  constructor(configSettings?: IConfigurationSettings) {\n    function inject(fn: any) {\n      return typeof fn === 'function' ? fn(this) : fn;\n    }\n\n    configSettings = Utils.merge(Configuration.defaults, configSettings);\n\n    this.log = inject(configSettings.log) || new NullLog();\n    this.apiKey = configSettings.apiKey;\n    this.serverUrl = configSettings.serverUrl;\n    this.heartbeatServerUrl = configSettings.heartbeatServerUrl;\n    this.updateSettingsWhenIdleInterval = configSettings.updateSettingsWhenIdleInterval;\n\n    this.environmentInfoCollector = inject(configSettings.environmentInfoCollector);\n    this.errorParser = inject(configSettings.errorParser);\n    this.lastReferenceIdManager = inject(configSettings.lastReferenceIdManager) || new DefaultLastReferenceIdManager();\n    this.moduleCollector = inject(configSettings.moduleCollector);\n    this.requestInfoCollector = inject(configSettings.requestInfoCollector);\n    this.submissionBatchSize = inject(configSettings.submissionBatchSize) || 50;\n    this.submissionAdapter = inject(configSettings.submissionAdapter);\n    this.submissionClient = inject(configSettings.submissionClient) || new DefaultSubmissionClient();\n    this.storage = inject(configSettings.storage) || new InMemoryStorageProvider();\n    this.queue = inject(configSettings.queue) || new DefaultEventQueue(this);\n\n    SettingsManager.applySavedServerSettings(this);\n    EventPluginManager.addDefaultPlugins(this);\n  }\n\n  /**\n   * The API key that will be used when sending events to the server.\n   * @returns {string}\n   */\n  public get apiKey(): string {\n    return this._apiKey;\n  }\n\n  /**\n   * The API key that will be used when sending events to the server.\n   * @param value\n   */\n  public set apiKey(value: string) {\n    this._apiKey = value || null;\n    this.log.info(`apiKey: ${this._apiKey}`);\n    this.changed();\n  }\n\n  /**\n   * Returns true if the apiKey is valid.\n   * @returns {boolean}\n   */\n  public get isValid(): boolean {\n    return !!this.apiKey && this.apiKey.length >= 10;\n  }\n\n  /**\n   * The server url that all events will be sent to.\n   * @returns {string}\n   */\n  public get serverUrl(): string {\n    return this._serverUrl;\n  }\n\n  /**\n   * The server url that all events will be sent to.\n   * @param value\n   */\n  public set serverUrl(value: string) {\n    if (!!value) {\n      this._serverUrl = value;\n      this._heartbeatServerUrl = value;\n      this.log.info(`serverUrl: ${value}`);\n      this.changed();\n    }\n  }\n\n  /**\n   * The heartbeat server url that all heartbeats will be sent to.\n   * @returns {string}\n   */\n  public get heartbeatServerUrl(): string {\n    return this._heartbeatServerUrl;\n  }\n\n  /**\n   * The heartbeat server url that all heartbeats will be sent to.\n   * @param value\n   */\n  public set heartbeatServerUrl(value: string) {\n    if (!!value) {\n      this._heartbeatServerUrl = value;\n      this.log.info(`heartbeatServerUrl: ${value}`);\n      this.changed();\n    }\n  }\n\n  /**\n   * How often the client should check for updated server settings when idle. The default is every 2 minutes.\n   * @returns {number}\n   */\n  public get updateSettingsWhenIdleInterval(): number {\n    return this._updateSettingsWhenIdleInterval;\n  }\n\n  /**\n   * How often the client should check for updated server settings when idle. The default is every 2 minutes.\n   * @param value\n   */\n  public set updateSettingsWhenIdleInterval(value: number) {\n    if (typeof value !== 'number') {\n      return;\n    }\n\n    if (value <= 0) {\n      value = -1;\n    } else if (value > 0 && value < 15000) {\n      value = 15000;\n    }\n\n    this._updateSettingsWhenIdleInterval = value;\n    this.log.info(`updateSettingsWhenIdleInterval: ${value}`);\n    this.changed();\n  }\n\n  /**\n   *  A list of exclusion patterns that will automatically remove any data that\n   *  matches them from any data submitted to the server.\n   *\n   *  For example, entering CreditCard will remove any extended data properties,\n   *  form fields, cookies and query parameters from the report.\n   *\n   * @returns {string[]}\n   */\n  public get dataExclusions(): string[] {\n    let exclusions: string = this.settings['@@DataExclusions'];\n    return this._dataExclusions.concat(exclusions && exclusions.split(',') || []);\n  }\n\n  /**\n   * Add items to the list of exclusion patterns that will automatically remove any\n   * data that matches them from any data submitted to the server.\n   *\n   * For example, entering CreditCard will remove any extended data properties, form\n   * fields, cookies and query parameters from the report.\n   *\n   * @param exclusions\n   */\n  public addDataExclusions(...exclusions: string[]) {\n    this._dataExclusions = Utils.addRange<string>(this._dataExclusions, ...exclusions);\n  }\n\n  /**\n   * A list of user agent patterns that will cause any event with a matching user agent to not be submitted.\n   *\n   * For example, entering *Bot* will cause any events that contains a user agent of Bot will not be submitted.\n   *\n   * @returns {string[]}\n   */\n  public get userAgentBotPatterns(): string[] {\n    let patterns: string = this.settings['@@UserAgentBotPatterns'];\n    return this._userAgentBotPatterns.concat(patterns && patterns.split(',') || []);\n  }\n\n  /**\n   * Add items to the list of user agent patterns that will cause any event with a matching user agent to not be submitted.\n   *\n   * For example, entering *Bot* will cause any events that contains a user agent of Bot will not be submitted.\n   *\n   * @param userAgentBotPatterns\n   */\n  public addUserAgentBotPatterns(...userAgentBotPatterns: string[]) {\n    this._userAgentBotPatterns = Utils.addRange<string>(this._userAgentBotPatterns, ...userAgentBotPatterns);\n  }\n\n  /**\n   * The list of plugins that will be used in this configuration.\n   * @returns {IEventPlugin[]}\n   */\n  public get plugins(): IEventPlugin[] {\n    return this._plugins.sort((p1: IEventPlugin, p2: IEventPlugin) => {\n      return (p1.priority < p2.priority) ? -1 : (p1.priority > p2.priority) ? 1 : 0;\n    });\n  }\n\n  /**\n   * Register an plugin to be used in this configuration.\n   * @param plugin\n   */\n  public addPlugin(plugin: IEventPlugin): void;\n\n  /**\n   * Register an plugin to be used in this configuration.\n   * @param name The name used to identify the plugin.\n   * @param priority Used to determine plugins priority.\n   * @param pluginAction A function that is run.\n   */\n  public addPlugin(name: string, priority: number, pluginAction: (context: EventPluginContext, next?: () => void) => void): void;\n  public addPlugin(pluginOrName: IEventPlugin | string, priority?: number, pluginAction?: (context: EventPluginContext, next?: () => void) => void): void {\n    let plugin: IEventPlugin = !!pluginAction ? { name: <string>pluginOrName, priority: priority, run: pluginAction } : <IEventPlugin>pluginOrName;\n    if (!plugin || !plugin.run) {\n      this.log.error('Add plugin failed: Run method not defined');\n      return;\n    }\n\n    if (!plugin.name) {\n      plugin.name = Utils.guid();\n    }\n\n    if (!plugin.priority) {\n      plugin.priority = 0;\n    }\n\n    let pluginExists: boolean = false;\n    let plugins = this._plugins; // optimization for minifier.\n    for (let index = 0; index < plugins.length; index++) {\n      if (plugins[index].name === plugin.name) {\n        pluginExists = true;\n        break;\n      }\n    }\n\n    if (!pluginExists) {\n      plugins.push(plugin);\n    }\n  }\n\n  /**\n   * Remove the plugin from this configuration.\n   * @param plugin\n   */\n  public removePlugin(plugin: IEventPlugin): void;\n\n  /**\n   * Remove an plugin by key from this configuration.\n   * @param name\n   */\n  public removePlugin(name: string): void;\n  public removePlugin(pluginOrName: IEventPlugin | string): void {\n    let name: string = typeof pluginOrName === 'string' ? pluginOrName : pluginOrName.name;\n    if (!name) {\n      this.log.error('Remove plugin failed: Plugin name not defined');\n      return;\n    }\n\n    let plugins = this._plugins; // optimization for minifier.\n    for (let index = 0; index < plugins.length; index++) {\n      if (plugins[index].name === name) {\n        plugins.splice(index, 1);\n        break;\n      }\n    }\n  }\n\n  /**\n   * Automatically set the application version for events.\n   * @param version\n   */\n  public setVersion(version: string): void {\n    if (!!version) {\n      this.defaultData['@version'] = version;\n    }\n  }\n\n  public setUserIdentity(userInfo: IUserInfo): void;\n  public setUserIdentity(identity: string): void;\n  public setUserIdentity(identity: string, name: string): void;\n  public setUserIdentity(userInfoOrIdentity: IUserInfo | string, name?: string): void {\n    const USER_KEY: string = '@user'; // optimization for minifier.\n    let userInfo: IUserInfo = typeof userInfoOrIdentity !== 'string' ? userInfoOrIdentity : { identity: userInfoOrIdentity, name: name };\n\n    let shouldRemove: boolean = !userInfo || (!userInfo.identity && !userInfo.name);\n    if (shouldRemove) {\n      delete this.defaultData[USER_KEY];\n    } else {\n      this.defaultData[USER_KEY] = userInfo;\n    }\n\n    this.log.info(`user identity: ${shouldRemove ? 'null' : userInfo.identity}`);\n  }\n\n  /**\n   * Used to identify the client that sent the events to the server.\n   * @returns {string}\n   */\n  public get userAgent(): string {\n    return 'exceptionless-js/1.0.0.0';\n  }\n\n  /**\n   * Automatically send a heartbeat to keep the session alive.\n   */\n  public useSessions(sendHeartbeats: boolean = true, heartbeatInterval: number = 30000): void {\n    if (sendHeartbeats) {\n      this.addPlugin(new HeartbeatPlugin(heartbeatInterval));\n    }\n  }\n\n  /**\n   * Automatically set a reference id for error events.\n   */\n  public useReferenceIds(): void {\n    this.addPlugin(new ReferenceIdPlugin());\n  }\n\n  public useLocalStorage(): void {\n    // This method will be injected via the prototype.\n  }\n\n  // TODO: Support a min log level.\n  public useDebugLogger(): void {\n    this.log = new ConsoleLog();\n  }\n\n  public onChanged(handler: (config: Configuration) => void) {\n    !!handler && this._handlers.push(handler);\n  }\n\n  private changed() {\n    let handlers = this._handlers; // optimization for minifier.\n    for (let index = 0; index < handlers.length; index++) {\n      try {\n        handlers[index](this);\n      } catch (ex) {\n        this.log.error(`Error calling onChanged handler: ${ex}`);\n      }\n    }\n  }\n\n  /**\n   * The default configuration settings that are applied to new configuration instances.\n   * @returns {IConfigurationSettings}\n   */\n  public static get defaults() {\n    if (Configuration._defaultSettings === null) {\n      Configuration._defaultSettings = {};\n    }\n\n    return Configuration._defaultSettings;\n  }\n}\n\n                                                                                                                                                                                                                                                                                                                                                                                   \n\nexport class EventBuilder {\n  public target: IEvent;\n  public client: ExceptionlessClient;\n  public pluginContextData: ContextData;\n\n  private _validIdentifierErrorMessage: string = 'must contain between 8 and 100 alphanumeric or \\'-\\' characters.'; // optimization for minifier.\n\n  constructor(event: IEvent, client: ExceptionlessClient, pluginContextData?: ContextData) {\n    this.target = event;\n    this.client = client;\n    this.pluginContextData = pluginContextData || new ContextData();\n  }\n\n  public setType(type: string): EventBuilder {\n    if (!!type) {\n      this.target.type = type;\n    }\n\n    return this;\n  }\n\n  public setSource(source: string): EventBuilder {\n    if (!!source) {\n      this.target.source = source;\n    }\n\n    return this;\n  }\n\n  public setReferenceId(referenceId: string): EventBuilder {\n    if (!this.isValidIdentifier(referenceId)) {\n      throw new Error(`ReferenceId ${this._validIdentifierErrorMessage}`);\n    }\n\n    this.target.reference_id = referenceId;\n    return this;\n  }\n\n  /**\n   * Allows you to reference a parent event by its ReferenceId property. This allows you to have parent and child relationships.\n   * @param name Reference name\n   * @param id The reference id that points to a specific event\n   * @returns {EventBuilder}\n     */\n  public setEventReference(name: string, id: string): EventBuilder {\n    if (!name) {\n      throw new Error('Invalid name');\n    }\n\n    if (!id || !this.isValidIdentifier(id)) {\n      throw new Error(`Id ${this._validIdentifierErrorMessage}`);\n    }\n\n    this.setProperty('@ref:' + name, id);\n    return this;\n  }\n\n  public setMessage(message: string): EventBuilder {\n    if (!!message) {\n      this.target.message = message;\n    }\n\n    return this;\n  }\n\n  public setGeo(latitude: number, longitude: number): EventBuilder {\n    if (latitude < -90.0 || latitude > 90.0) {\n      throw new Error('Must be a valid latitude value between -90.0 and 90.0.');\n    }\n\n    if (longitude < -180.0 || longitude > 180.0) {\n      throw new Error('Must be a valid longitude value between -180.0 and 180.0.');\n    }\n\n    this.target.geo = `${latitude},${longitude}`;\n    return this;\n  }\n\n  public setUserIdentity(userInfo: IUserInfo): EventBuilder;\n  public setUserIdentity(identity: string): EventBuilder;\n  public setUserIdentity(identity: string, name: string): EventBuilder;\n  public setUserIdentity(userInfoOrIdentity: IUserInfo | string, name?: string): EventBuilder {\n    let userInfo = typeof userInfoOrIdentity !== 'string' ? userInfoOrIdentity : { identity: userInfoOrIdentity, name: name };\n    if (!userInfo || (!userInfo.identity && !userInfo.name)) {\n      return this;\n    }\n\n    this.setProperty('@user', userInfo);\n    return this;\n  }\n\n  /**\n   * Sets the user's description of the event.\n   *\n   * @param emailAddress The email address\n   * @param description The user's description of the event.\n   * @returns {EventBuilder}\n     */\n  public setUserDescription(emailAddress: string, description: string): EventBuilder {\n    if (emailAddress && description) {\n      this.setProperty('@user_description', { email_address: emailAddress, description: description });\n    }\n\n    return this;\n  }\n\n  /**\n   * Changes default stacking behavior by setting manual\n   * stacking information.\n   * @param signatureData A dictionary of strings to use for stacking.\n   * @param title An optional title for the stacking information.\n   * @returns {EventBuilder}\n     */\n  public setManualStackingInfo(signatureData: any, title?: string) {\n    if (signatureData) {\n      let stack = <IManualStackingInfo>{\n        signature_data: signatureData\n      };\n      if (title) {\n        stack.title = title;\n      }\n      this.setProperty('@stack', stack);\n    }\n\n    return this;\n  }\n\n  /**\n   * Changes default stacking behavior by setting the stacking key.\n   * @param manualStackingKey The manual stacking key.\n   * @param title An optional title for the stacking information.\n   * @returns {EventBuilder}\n     */\n  public setManualStackingKey(manualStackingKey: string, title?: string): EventBuilder {\n    if (manualStackingKey) {\n      let data = {\n        'ManualStackingKey': manualStackingKey\n      };\n      this.setManualStackingInfo(data, title);\n    }\n\n    return this;\n  }\n\n  public setValue(value: number): EventBuilder {\n    if (!!value) {\n      this.target.value = value;\n    }\n\n    return this;\n  }\n\n  public addTags(...tags: string[]): EventBuilder {\n    this.target.tags = Utils.addRange<string>(this.target.tags, ...tags);\n    return this;\n  }\n\n  /**\n   * Adds the object to extended data. Uses @excludedPropertyNames\n   * to exclude data from being included in the event.\n   * @param name The data object to add.\n   * @param value The name of the object to add.\n   * @param maxDepth The max depth of the object to include.\n   * @param excludedPropertyNames Any property names that should be excluded.\n   */\n  public setProperty(name: string, value: any, maxDepth?: number, excludedPropertyNames?: string[]): EventBuilder {\n    if (!name || (value === undefined || value == null)) {\n      return this;\n    }\n\n    if (!this.target.data) {\n      this.target.data = {};\n    }\n\n    let result = JSON.parse(Utils.stringify(value, this.client.config.dataExclusions.concat(excludedPropertyNames || []), maxDepth));\n    if (!Utils.isEmpty(result)) {\n      this.target.data[name] = result;\n    }\n\n    return this;\n  }\n\n  public markAsCritical(critical: boolean): EventBuilder {\n    if (critical) {\n      this.addTags('Critical');\n    }\n\n    return this;\n  }\n\n  public addRequestInfo(request: Object): EventBuilder {\n    if (!!request) {\n      this.pluginContextData['@request'] = request;\n    }\n\n    return this;\n  }\n\n  public submit(callback?: (context: EventPluginContext) => void): void {\n    this.client.submitEvent(this.target, this.pluginContextData, callback);\n  }\n\n  private isValidIdentifier(value: string): boolean {\n    if (!value) {\n      return true;\n    }\n\n    if (value.length < 8 || value.length > 100) {\n      return false;\n    }\n\n    for (let index = 0; index < value.length; index++) {\n      let code = value.charCodeAt(index);\n      let isDigit = (code >= 48) && (code <= 57);\n      let isLetter = ((code >= 65) && (code <= 90)) || ((code >= 97) && (code <= 122));\n      let isMinus = code === 45;\n\n      if (!(isDigit || isLetter) && !isMinus) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n}\n\nexport interface IUserDescription {\n  email_address?: string;\n  description?: string;\n  data?: any;\n}\n\nexport class ContextData {\n  public setException(exception: Error): void {\n    if (exception) {\n      this['@@_Exception'] = exception;\n    }\n  }\n\n  public get hasException(): boolean {\n    return !!this['@@_Exception'];\n  }\n\n  public getException(): Error {\n    return this['@@_Exception'] || null;\n  }\n\n  public markAsUnhandledError(): void {\n    this['@@_IsUnhandledError'] = true;\n  }\n\n  public get isUnhandledError(): boolean {\n    return !!this['@@_IsUnhandledError'];\n  }\n\n  public setSubmissionMethod(method: string): void {\n    if (method) {\n      this['@@_SubmissionMethod'] = method;\n    }\n  }\n\n  public getSubmissionMethod(): string {\n    return this['@@_SubmissionMethod'] || null;\n  }\n}\n\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          \n\nexport class ExceptionlessClient {\n  /**\n   * The default ExceptionlessClient instance.\n   * @type {ExceptionlessClient}\n   * @private\n   */\n  private static _instance: ExceptionlessClient = null;\n\n  public config: Configuration;\n\n  private _intervalId: any;\n  private _timeoutId: any;\n\n  constructor();\n  constructor(settings: IConfigurationSettings);\n  constructor(apiKey: string, serverUrl?: string);\n  constructor(settingsOrApiKey?: IConfigurationSettings | string, serverUrl?: string) {\n    if (typeof settingsOrApiKey === 'object') {\n      this.config = new Configuration(settingsOrApiKey);\n    } else {\n      this.config = new Configuration({ apiKey: <string>settingsOrApiKey, serverUrl: serverUrl });\n    }\n\n    this.updateSettingsTimer(5000);\n    this.config.onChanged((config) => this.updateSettingsTimer(this._timeoutId > 0 ? 5000 : 0));\n    this.config.queue.onEventsPosted((events, response) =>  this.updateSettingsTimer());\n  }\n\n  public createException(exception: Error): EventBuilder {\n    let pluginContextData = new ContextData();\n    pluginContextData.setException(exception);\n    return this.createEvent(pluginContextData).setType('error');\n  }\n\n  public submitException(exception: Error, callback?: (context: EventPluginContext) => void): void {\n    this.createException(exception).submit(callback);\n  }\n\n  public createUnhandledException(exception: Error, submissionMethod?: string): EventBuilder {\n    let builder = this.createException(exception);\n    builder.pluginContextData.markAsUnhandledError();\n    builder.pluginContextData.setSubmissionMethod(submissionMethod);\n\n    return builder;\n  }\n\n  public submitUnhandledException(exception: Error, submissionMethod?: string, callback?: (context: EventPluginContext) => void) {\n    this.createUnhandledException(exception, submissionMethod).submit(callback);\n  }\n\n  public createFeatureUsage(feature: string): EventBuilder {\n    return this.createEvent().setType('usage').setSource(feature);\n  }\n\n  public submitFeatureUsage(feature: string, callback?: (context: EventPluginContext) => void): void {\n    this.createFeatureUsage(feature).submit(callback);\n  }\n\n  public createLog(message: string): EventBuilder;\n  public createLog(source: string, message: string): EventBuilder;\n  public createLog(source: string, message: string, level: string): EventBuilder;\n  public createLog(sourceOrMessage: string, message?: string, level?: string): EventBuilder {\n    let builder = this.createEvent().setType('log');\n\n    if (message && level) {\n      builder = builder.setSource(sourceOrMessage).setMessage(message).setProperty('@level', level);\n    } else if (message) {\n      builder = builder.setSource(sourceOrMessage).setMessage(message);\n    } else {\n      builder = builder.setMessage(sourceOrMessage);\n\n      try {\n        // TODO: Look into using https: //www.stevefenton.co.uk/Content/Blog/Date/201304/Blog/Obtaining-A-Class-Name-At-Runtime-In-TypeScript/\n        let caller: any = this.createLog.caller;\n        builder = builder.setSource(caller && caller.caller && caller.caller.name);\n      } catch (e) {\n        this.config.log.trace('Unable to resolve log source: ' + e.message);\n      }\n    }\n\n    return builder;\n  }\n\n  public submitLog(message: string): void;\n  public submitLog(source: string, message: string): void;\n  public submitLog(source: string, message: string, level: string, callback?: (context: EventPluginContext) => void): void;\n  public submitLog(sourceOrMessage: string, message?: string, level?: string, callback?: (context: EventPluginContext) => void): void {\n    this.createLog(sourceOrMessage, message, level).submit(callback);\n  }\n\n  public createNotFound(resource: string): EventBuilder {\n    return this.createEvent().setType('404').setSource(resource);\n  }\n\n  public submitNotFound(resource: string, callback?: (context: EventPluginContext) => void): void {\n    this.createNotFound(resource).submit(callback);\n  }\n\n  public createSessionStart(): EventBuilder {\n    return this.createEvent().setType('session');\n  }\n\n  public submitSessionStart(callback?: (context: EventPluginContext) => void): void {\n    this.createSessionStart().submit(callback);\n  }\n\n  public submitSessionEnd(sessionIdOrUserId: string): void {\n    if (sessionIdOrUserId) {\n      this.config.log.info(`Submitting session end: ${sessionIdOrUserId}`);\n      this.config.submissionClient.sendHeartbeat(sessionIdOrUserId, true, this.config);\n    }\n  }\n\n  public submitSessionHeartbeat(sessionIdOrUserId: string): void {\n    if (sessionIdOrUserId) {\n      this.config.log.info(`Submitting session heartbeat: ${sessionIdOrUserId}`);\n      this.config.submissionClient.sendHeartbeat(sessionIdOrUserId, false, this.config);\n    }\n  }\n\n  public createEvent(pluginContextData?: ContextData): EventBuilder {\n    return new EventBuilder({ date: new Date() }, this, pluginContextData);\n  }\n\n  /**\n   * Submits the event to be sent to the server.\n   * @param event The event data.\n   * @param pluginContextData Any contextual data objects to be used by Exceptionless plugins to gather default information for inclusion in the report information.\n   * @param callback\n   */\n  public submitEvent(event: IEvent, pluginContextData?: ContextData, callback?: (context: EventPluginContext) => void): void {\n    function cancelled(context: EventPluginContext) {\n      if (!!context) {\n        context.cancelled = true;\n      }\n\n      return !!callback && callback(context);\n    }\n\n    let context = new EventPluginContext(this, event, pluginContextData);\n    if (!event) {\n      return cancelled(context);\n    }\n\n    if (!this.config.enabled) {\n      this.config.log.info('Event submission is currently disabled.');\n      return cancelled(context);\n    }\n\n    if (!event.data) {\n      event.data = {};\n    }\n\n    if (!event.tags || !event.tags.length) {\n      event.tags = [];\n    }\n\n    EventPluginManager.run(context, function (ctx: EventPluginContext) {\n      let config = ctx.client.config;\n      let ev = ctx.event;\n\n      if (!ctx.cancelled) {\n        // ensure all required data\n        if (!ev.type || ev.type.length === 0) {\n          ev.type = 'log';\n        }\n\n        if (!ev.date) {\n          ev.date = new Date();\n        }\n\n        config.queue.enqueue(ev);\n\n        if (ev.reference_id && ev.reference_id.length > 0) {\n          ctx.log.info(`Setting last reference id '${ev.reference_id}'`);\n          config.lastReferenceIdManager.setLast(ev.reference_id);\n        }\n      }\n\n      !!callback && callback(ctx);\n    });\n  }\n\n  /**\n   * Updates the user's email address and description of an event for the specified reference id.\n   * @param referenceId The reference id of the event to update.\n   * @param email The user's email address to set on the event.\n   * @param description The user's description of the event.\n   * @param callback The submission response.\n   */\n  public updateUserEmailAndDescription(referenceId: string, email: string, description: string, callback?: (response: SubmissionResponse) => void) {\n    if (!referenceId || !email || !description || !this.config.enabled) {\n      return !!callback && callback(new SubmissionResponse(500, 'cancelled'));\n    }\n\n    let userDescription: IUserDescription = { email_address: email, description: description };\n    this.config.submissionClient.postUserDescription(referenceId, userDescription, this.config, (response: SubmissionResponse) => {\n      if (!response.success) {\n        this.config.log.error(`Failed to submit user email and description for event '${referenceId}': ${response.statusCode} ${response.message}`);\n      }\n\n      !!callback && callback(response);\n    });\n  }\n\n  /**\n   * Gets the last event client id that was submitted to the server.\n   * @returns {string} The event client id.\n   */\n  public getLastReferenceId(): string {\n    return this.config.lastReferenceIdManager.getLast();\n  }\n\n  private updateSettingsTimer(initialDelay?: number) {\n    this.config.log.info(`Updating settings timer with delay: ${initialDelay}`);\n\n    this._timeoutId = clearTimeout(this._timeoutId);\n    this._timeoutId = clearInterval(this._intervalId);\n\n    let interval = this.config.updateSettingsWhenIdleInterval;\n    if (interval > 0) {\n      let updateSettings = () => SettingsManager.updateSettings(this.config);\n      if (initialDelay > 0) {\n        this._timeoutId = setTimeout(updateSettings, initialDelay);\n      }\n\n      this._intervalId = setInterval(updateSettings, interval);\n    }\n  }\n\n  /**\n   * The default ExceptionlessClient instance.\n   * @type {ExceptionlessClient}\n   */\n  public static get default() {\n    if (ExceptionlessClient._instance === null) {\n      ExceptionlessClient._instance = new ExceptionlessClient(null);\n    }\n\n    return ExceptionlessClient._instance;\n  }\n}\n\nexport interface IManualStackingInfo {\n  title?: string;\n  signature_data?: any;\n}\n\nexport interface IModule {\n  data?: any;\n\n  module_id?: number;\n  name?: string;\n  version?: string;\n  is_entry?: boolean;\n  created_date?: Date;\n  modified_date?: Date;\n}\n\nexport interface IRequestInfo {\n  user_agent?: string;\n  http_method?: string;\n  is_secure?: boolean;\n  host?: string;\n  port?: number;\n  path?: string;\n  referrer?: string;\n  client_ip_address?: string;\n  cookies?: any;\n  post_data?: any;\n  query_string?: any;\n  data?: any;\n}\n\nexport interface IEnvironmentInfo {\n  processor_count?: number;\n  total_physical_memory?: number;\n  available_physical_memory?: number;\n  command_line?: string;\n  process_name?: string;\n  process_id?: string;\n  process_memory_size?: number;\n  thread_id?: string;\n  architecture?: string;\n  o_s_name?: string;\n  o_s_version?: string;\n  ip_address?: string;\n  machine_name?: string;\n  install_id?: string;\n  runtime_version?: string;\n  data?: any;\n}\n\nexport interface IParameter {\n  data?: any;\n  generic_arguments?: string[];\n\n  name?: string;\n  type?: string;\n  type_namespace?: string;\n}\n\n                                          \n\nexport interface IMethod {\n  data?: any;\n  generic_arguments?: string[];\n  parameters?: IParameter[];\n\n  is_signature_target?: boolean;\n  declaring_namespace?: string;\n  declaring_type?: string;\n  name?: string;\n  module_id?: number;\n}\n\n                                    \n\nexport interface IStackFrame extends IMethod {\n  file_name?: string;\n  line_number?: number;\n  column?: number;\n}\n\n                                                                                 \n\nexport interface IInnerError {\n  message?: string;\n  type?: string;\n  code?: string;\n  data?: any;\n  inner?: IInnerError;\n  stack_trace?: IStackFrame[];\n  target_method?: IMethod;\n}\n\n                                                                                                                                                \n\nexport class ConfigurationDefaultsPlugin implements IEventPlugin {\n  public priority: number = 10;\n  public name: string = 'ConfigurationDefaultsPlugin';\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    let config = context.client.config;\n    let defaultTags: string[] = config.defaultTags || [];\n    for (let index = 0; index < defaultTags.length; index++) {\n      let tag = defaultTags[index];\n      if (!!tag && context.event.tags.indexOf(tag) < 0) {\n        context.event.tags.push(tag);\n      }\n    }\n\n    let defaultData: Object = config.defaultData || {};\n    for (let key in defaultData) {\n      if (!!defaultData[key]) {\n        let result = JSON.parse(Utils.stringify(defaultData[key], config.dataExclusions));\n        if (!Utils.isEmpty(result)) {\n          context.event.data[key] = result;\n        }\n      }\n    }\n\n    next && next();\n  }\n}\n\n                                                                                                                                                \n\nexport class ErrorPlugin implements IEventPlugin {\n  public priority: number = 30;\n  public name: string = 'ErrorPlugin';\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    const ERROR_KEY: string = '@error'; // optimization for minifier.\n    let ignoredProperties: string[] = [\n      'arguments',\n      'column',\n      'columnNumber',\n      'description',\n      'fileName',\n      'message',\n      'name',\n      'number',\n      'line',\n      'lineNumber',\n      'opera#sourceloc',\n      'sourceId',\n      'sourceURL',\n      'stack',\n      'stackArray',\n      'stacktrace'\n    ];\n\n    let exception = context.contextData.getException();\n    if (!!exception) {\n      context.event.type = 'error';\n\n      if (!context.event.data[ERROR_KEY]) {\n        let config = context.client.config;\n        let parser = config.errorParser;\n        if (!parser) {\n          throw new Error('No error parser was defined.');\n        }\n\n        let result = parser.parse(context, exception);\n        if (!!result) {\n          let additionalData = JSON.parse(Utils.stringify(exception, config.dataExclusions.concat(ignoredProperties)));\n          if (!Utils.isEmpty(additionalData)) {\n            if (!result.data) {\n              result.data = {};\n            }\n            result.data['@ext'] = additionalData;\n          }\n\n          context.event.data[ERROR_KEY] = result;\n        }\n      }\n    }\n\n    next && next();\n  }\n}\n\n                                                                                                                                                           \n\nexport class ModuleInfoPlugin implements IEventPlugin {\n  public priority: number = 50;\n  public name: string = 'ModuleInfoPlugin';\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    const ERROR_KEY: string = '@error'; // optimization for minifier.\n\n    let collector = context.client.config.moduleCollector;\n    if (context.event.data[ERROR_KEY] && !context.event.data['@error'].modules && !!collector) {\n      let modules: IModule[] = collector.getModules(context);\n      if (modules && modules.length > 0) {\n        context.event.data[ERROR_KEY].modules = modules;\n      }\n    }\n\n    next && next();\n  }\n}\n\n                                                                                                                                                                                                          \n\nexport class RequestInfoPlugin implements IEventPlugin {\n  public priority: number = 70;\n  public name: string = 'RequestInfoPlugin';\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    const REQUEST_KEY: string = '@request'; // optimization for minifier.\n\n    let config = context.client.config;\n    let collector = config.requestInfoCollector;\n    if (!context.event.data[REQUEST_KEY] && !!collector) {\n      let requestInfo: IRequestInfo = collector.getRequestInfo(context);\n      if (!!requestInfo) {\n        if (Utils.isMatch(requestInfo.user_agent, config.userAgentBotPatterns)) {\n          context.log.info('Cancelling event as the request user agent matches a known bot pattern');\n          context.cancelled = true;\n        } else {\n          context.event.data[REQUEST_KEY] = requestInfo;\n        }\n      }\n    }\n\n    next && next();\n  }\n}\n\n                                                                                                                                                                             \n\nexport class EnvironmentInfoPlugin implements IEventPlugin {\n  public priority: number = 80;\n  public name: string = 'EnvironmentInfoPlugin';\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    const ENVIRONMENT_KEY: string = '@environment'; // optimization for minifier.\n\n    let collector = context.client.config.environmentInfoCollector;\n    if (!context.event.data[ENVIRONMENT_KEY] && collector) {\n      let environmentInfo: IEnvironmentInfo = collector.getEnvironmentInfo(context);\n      if (!!environmentInfo) {\n        context.event.data[ENVIRONMENT_KEY] = environmentInfo;\n      }\n    }\n\n    next && next();\n  }\n}\n\n                                                                                                           \n\nexport class SubmissionMethodPlugin implements IEventPlugin {\n  public priority: number = 100;\n  public name: string = 'SubmissionMethodPlugin';\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    let submissionMethod: string = context.contextData.getSubmissionMethod();\n    if (!!submissionMethod) {\n      context.event.data['@submission_method'] = submissionMethod;\n    }\n\n    next && next();\n  }\n}\n\n                                                                                                                                                                                                        \n\nexport class DuplicateCheckerPlugin implements IEventPlugin {\n  public priority: number = 1010;\n  public name: string = 'DuplicateCheckerPlugin';\n\n  private _mergedEvents: MergedEvent[] = [];\n  private _processedHashcodes: TimestampedHash[] = [];\n  private _getCurrentTime: () => number;\n  private _interval: number;\n\n  constructor(getCurrentTime: () => number = () => Date.now(), interval: number = 30000) {\n    this._getCurrentTime = getCurrentTime;\n    this._interval = interval;\n\n    setInterval(() => {\n      while (this._mergedEvents.length > 0) {\n        this._mergedEvents.shift().resubmit();\n      }\n    }, interval);\n  }\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    function getHashCode(error: IInnerError): number {\n      let hashCode = 0;\n      while (error) {\n        if (error.message && error.message.length) {\n          hashCode += (hashCode * 397) ^ Utils.getHashCode(error.message);\n        }\n        if (error.stack_trace && error.stack_trace.length) {\n          hashCode += (hashCode * 397) ^ Utils.getHashCode(JSON.stringify(error.stack_trace));\n        }\n        error = error.inner;\n      }\n\n      return hashCode;\n    }\n\n    let error = context.event.data['@error'];\n    let hashCode = getHashCode(error);\n    if (hashCode) {\n      let count = context.event.count || 1;\n      let now = this._getCurrentTime();\n\n      let merged = this._mergedEvents.filter(s => s.hashCode === hashCode)[0];\n      if (merged) {\n        merged.incrementCount(count);\n        merged.updateDate(context.event.date);\n        context.log.info('Ignoring duplicate event with hash: ' + hashCode);\n        context.cancelled = true;\n      }\n\n      if (!context.cancelled && this._processedHashcodes.some(h => h.hash === hashCode && h.timestamp >= (now - this._interval))) {\n        context.log.trace('Adding event with hash: ' + hashCode);\n        this._mergedEvents.push(new MergedEvent(hashCode, context, count));\n        context.cancelled = true;\n      }\n\n      if (!context.cancelled) {\n        context.log.trace('Enqueueing event with hash: ' + hashCode + 'to cache.');\n        this._processedHashcodes.push({ hash: hashCode, timestamp: now });\n\n        // Only keep the last 50 recent errors.\n        while (this._processedHashcodes.length > 50) {\n          this._processedHashcodes.shift();\n        }\n      }\n    }\n\n    next && next();\n  }\n}\n\ninterface TimestampedHash {\n  hash: number;\n  timestamp: number;\n}\n\nclass MergedEvent {\n  public hashCode: number;\n  private _count: number;\n  private _context: EventPluginContext;\n\n  constructor(hashCode: number, context: EventPluginContext, count: number) {\n    this.hashCode = hashCode;\n    this._context = context;\n    this._count = count;\n  }\n\n  public incrementCount(count: number) {\n    this._count += count;\n  }\n\n  public resubmit() {\n    this._context.event.count = this._count;\n    this._context.client.config.queue.enqueue(this._context.event);\n  }\n\n  public updateDate(date) {\n    if (date > this._context.event.date) {\n      this._context.event.date = date;\n    }\n  }\n}\n\n                                                                                                                                                                                                        \n\nexport class EventExclusionPlugin implements IEventPlugin {\n  public priority: number = 45;\n  public name: string = 'EventExclusionPlugin';\n\n  public run(context: EventPluginContext, next?: () => void): void {\n    function getLogLevel(level: string): number {\n      switch ((level || '').toLowerCase().trim()) {\n        case 'trace':\n        case 'true':\n        case '1':\n        case 'yes':\n          return 0;\n        case 'debug':\n          return 1;\n        case 'info':\n          return 2;\n        case 'warn':\n          return 3;\n        case 'error':\n          return 4;\n        case 'fatal':\n          return 5;\n        case 'off':\n        case 'false':\n        case '0':\n        case 'no':\n          return 6;\n        default:\n          return -1;\n      }\n    }\n\n    function getMinLogLevel(settings: Object, loggerName: string = '*'): number {\n      return getLogLevel(getTypeAndSourceSetting(settings, 'log', loggerName, 'Trace') + '');\n    }\n\n    function getTypeAndSourceSetting(settings: Object = {}, type: string, source: string, defaultValue: string|boolean = undefined): string|boolean {\n      if (!type) {\n        return defaultValue;\n      }\n\n      let isLog = type === 'log';\n      let sourcePrefix =  `@@${type}:`;\n\n      let value = settings[sourcePrefix + source];\n      if (value) {\n        return !isLog ? Utils.toBoolean(value) : value;\n      }\n\n      // check for wildcard match\n      for (let key in settings) {\n        if (Utils.startsWith(key.toLowerCase(), sourcePrefix.toLowerCase()) && Utils.isMatch(source, [key.substring(sourcePrefix.length)])) {\n          return !isLog ? Utils.toBoolean(settings[key]) : settings[key];\n        }\n      }\n\n      return defaultValue;\n    }\n\n    let ev = context.event;\n    let log = context.log;\n    let settings = context.client.config.settings;\n\n    if (ev.type === 'log') {\n      let minLogLevel = getMinLogLevel(settings, ev.source);\n      let logLevel = getLogLevel(ev.data['@level']);\n\n      if (logLevel >= 0 && (logLevel > 5 || logLevel < minLogLevel)) {\n        log.info('Cancelling log event due to minimum log level.');\n        context.cancelled = true;\n      }\n    } else if (ev.type === 'error') {\n      let error: IInnerError = ev.data['@error'];\n      while (!context.cancelled && error) {\n        if (getTypeAndSourceSetting(settings, ev.type, error.type, true) === false) {\n          log.info(`Cancelling error from excluded exception type: ${error.type}`);\n          context.cancelled = true;\n        }\n\n        error = error.inner;\n      }\n    } else if (getTypeAndSourceSetting(settings, ev.type, ev.source, true) === false) {\n      log.info(`Cancelling event from excluded type: ${ev.type} and source: ${ev.source}`);\n      context.cancelled = true;\n    }\n\n    next && next();\n  }\n}\n\nexport class SettingsResponse {\n  public success: boolean = false;\n  public settings: any;\n  public settingsVersion: number = -1;\n  public message: string;\n  public exception: any;\n\n  constructor(success: boolean, settings: any, settingsVersion: number = -1, exception: any = null, message: string = null) {\n    this.success = success;\n    this.settings = settings;\n    this.settingsVersion = settingsVersion;\n    this.exception = exception;\n    this.message = message;\n  }\n}\n\n                                                                                 \n\nexport interface IError extends IInnerError {\n  modules?: IModule[];\n}\n\nexport interface IStorageItem {\n  timestamp: number;\n  value: any;\n}\n\n                                              \n\nexport interface IStorage {\n  save(value: any): number;\n  get(limit?: number): IStorageItem[];\n  remove(timestamp: number): void;\n  clear(): void;\n}\n\nexport interface SubmissionCallback {\n  (status: number, message: string, data?: string, headers?: Object): void;\n}\n\nexport interface SubmissionRequest {\n  apiKey: string;\n  userAgent: string;\n  method: string;\n  url: string;\n  data: string;\n}\n\n                                                                                     \n\nexport class InMemoryStorage implements IStorage {\n  private maxItems: number;\n  private items: IStorageItem[] = [];\n  private lastTimestamp: number = 0;\n\n  constructor(maxItems: number) {\n    this.maxItems = maxItems;\n  }\n\n  public save(value: any): number {\n    if (!value) {\n      return null;\n    }\n\n    let items = this.items;\n    let timestamp = Math.max(Date.now(), this.lastTimestamp + 1);\n    let item = { timestamp, value };\n\n    if (items.push(item) > this.maxItems) {\n      items.shift();\n    }\n\n    this.lastTimestamp = timestamp;\n    return item.timestamp;\n  }\n\n  public get(limit?: number): IStorageItem[] {\n    return this.items.slice(0, limit);\n  }\n\n  public remove(timestamp: number): void {\n    let items = this.items;\n    for (let i = 0; i < items.length; i++) {\n      if (items[i].timestamp === timestamp) {\n        items.splice(i, 1);\n        return;\n      }\n    }\n  }\n\n  public clear(): void {\n    this.items = [];\n  }\n}\n\nexport interface IClientConfiguration {\n  settings: Object;\n  version: number;\n}\n\n                                                                                     \n\nexport abstract class KeyValueStorageBase implements IStorage {\n  private maxItems: number;\n  private items: number[];\n  private lastTimestamp: number = 0;\n\n  constructor(maxItems) {\n    this.maxItems = maxItems;\n  }\n\n  public save(value: any, single?: boolean): number {\n    if (!value) {\n      return null;\n    }\n\n    this.ensureIndex();\n\n    let items = this.items;\n    let timestamp = Math.max(Date.now(), this.lastTimestamp + 1);\n    let key = this.getKey(timestamp);\n    let json = JSON.stringify(value);\n\n    try {\n      this.write(key, json);\n      this.lastTimestamp = timestamp;\n      if (items.push(timestamp) > this.maxItems) {\n        this.delete(this.getKey(items.shift()));\n      }\n    } catch (e) {\n      return null;\n    }\n\n    return timestamp;\n  }\n\n  public get(limit?: number): IStorageItem[] {\n    this.ensureIndex();\n\n    return this.items.slice(0, limit)\n      .map(timestamp => {\n        // Read and parse item for this timestamp\n        let key = this.getKey(timestamp);\n        try {\n          let json = this.read(key);\n          let value = JSON.parse(json, parseDate);\n          return { timestamp, value };\n        } catch (error) {\n          // Something went wrong - try to delete the cause.\n          this.safeDelete(key);\n          return null;\n        }\n      })\n      .filter(item => item != null);\n  }\n\n  public remove(timestamp: number): void {\n    this.ensureIndex();\n\n    let items = this.items;\n    let index = items.indexOf(timestamp);\n    if (index >= 0) {\n      let key = this.getKey(timestamp);\n      this.safeDelete(key);\n      items.splice(index, 1);\n    };\n  }\n\n  public clear(): void {\n    this.items.forEach(item => this.safeDelete(this.getKey(item)));\n    this.items = [];\n  }\n\n  protected abstract write(key: string, value: string): void;\n  protected abstract read(key: string): string;\n  protected abstract readAllKeys(): string[];\n  protected abstract delete(key: string);\n  protected abstract getKey(timestamp: number): string;\n  protected abstract getTimestamp(key: string): number;\n\n  private ensureIndex() {\n    if (!this.items) {\n      this.items = this.createIndex();\n      this.lastTimestamp = Math.max(0, ...this.items) + 1;\n    }\n  }\n\n  private safeDelete(key: string): void {\n    try {\n      this.delete(key);\n    } catch (error) {\n    }\n  }\n\n  private createIndex() {\n    try {\n      let keys = this.readAllKeys();\n      return keys.map(key => {\n        try {\n          let timestamp = this.getTimestamp(key);\n          if (!timestamp) {\n            this.safeDelete(key);\n            return null;\n          }\n          return timestamp;\n        } catch (error) {\n          this.safeDelete(key);\n          return null;\n        }\n      }).filter(timestamp => timestamp != null)\n        .sort((a, b) => a - b);\n    } catch (error) {\n      return [];\n    }\n  }\n}\n\nfunction parseDate(key, value) {\n  let dateRegx = /\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d:[0-5]\\d|Z)/g;\n  if (typeof value === 'string') {\n    let a = dateRegx.exec(value);\n    if (a) {\n      return new Date(value);\n    }\n  }\n  return value;\n};\n\n                                                            \n\nexport class BrowserStorage extends KeyValueStorageBase {\n  private prefix: string;\n\n  public static isAvailable(): boolean {\n    try {\n      let storage = window.localStorage,\n        x = '__storage_test__';\n      storage.setItem(x, x);\n      storage.removeItem(x);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n\n  constructor(namespace: string, prefix: string = 'com.exceptionless.', maxItems: number = 20) {\n    super(maxItems);\n\n    this.prefix = prefix + namespace + '-';\n  }\n\n  public write(key: string, value: string) {\n    window.localStorage.setItem(key, value);\n  }\n\n  public read(key: string) {\n    return window.localStorage.getItem(key);\n  }\n\n  public readAllKeys() {\n    return Object.keys(window.localStorage)\n      .filter(key => key.indexOf(this.prefix) === 0);\n  }\n\n  public delete(key: string) {\n    window.localStorage.removeItem(key);\n  }\n\n  public getKey(timestamp) {\n    return this.prefix + timestamp;\n  }\n\n  public getTimestamp(key) {\n    return parseInt(key.substr(this.prefix.length), 10);\n  }\n}\n\n                                                                                                                                                                                                                                                                                                           \n\nexport class DefaultErrorParser implements IErrorParser {\n  public parse(context: EventPluginContext, exception: Error): IError {\n    function getParameters(parameters: string | string[]): IParameter[] {\n      let params: string[] = (typeof parameters === 'string' ? [parameters] : parameters) || [];\n\n      let result: IParameter[] = [];\n      for (let index = 0; index < params.length; index++) {\n        result.push({ name: params[index] });\n      }\n\n      return result;\n    }\n\n    function getStackFrames(stackFrames: TraceKit.StackFrame[]): IStackFrame[] {\n      const ANONYMOUS: string = '<anonymous>';\n      let frames: IStackFrame[] = [];\n\n      for (let index = 0; index < stackFrames.length; index++) {\n        let frame = stackFrames[index];\n        frames.push({\n          name: (frame.func || ANONYMOUS).replace('?', ANONYMOUS),\n          parameters: getParameters(frame.args),\n          file_name: frame.url,\n          line_number: frame.line || 0,\n          column: frame.column || 0\n        });\n      }\n\n      return frames;\n    }\n\n    const TRACEKIT_STACK_TRACE_KEY: string = '@@_TraceKit.StackTrace'; // optimization for minifier.\n\n    let stackTrace: TraceKit.StackTrace = !!context.contextData[TRACEKIT_STACK_TRACE_KEY]\n      ? context.contextData[TRACEKIT_STACK_TRACE_KEY]\n      : TraceKit.computeStackTrace(exception, 25);\n\n    if (!stackTrace) {\n      throw new Error('Unable to parse the exceptions stack trace.');\n    }\n\n    let message = typeof(exception) === 'string' ? <any>exception : undefined;\n    return {\n      type: stackTrace.name,\n      message: stackTrace.message || exception.message || message,\n      stack_trace: getStackFrames(stackTrace.stack || [])\n    };\n  }\n}\n\n                                                                                                                                                                                                         \n\nexport class DefaultModuleCollector implements IModuleCollector {\n  public getModules(context: EventPluginContext): IModule[] {\n    if (document && document.getElementsByTagName) {\n      return null;\n    }\n\n    let modules: IModule[] = [];\n    let scripts: NodeListOf<HTMLScriptElement> = document.getElementsByTagName('script');\n    if (scripts && scripts.length > 0) {\n      for (let index = 0; index < scripts.length; index++) {\n        if (scripts[index].src) {\n          modules.push({\n            module_id: index,\n            name: scripts[index].src,\n            version: Utils.parseVersion(scripts[index].src)\n          });\n        } else if (!!scripts[index].innerHTML) {\n          modules.push({\n            module_id: index,\n            name: 'Script Tag',\n            version: Utils.getHashCode(scripts[index].innerHTML).toString()\n          });\n        }\n      }\n    }\n\n    return modules;\n  }\n}\n\n                                                                                                                                                                                                                             \n\nexport class DefaultRequestInfoCollector implements IRequestInfoCollector {\n  public getRequestInfo(context: EventPluginContext): IRequestInfo {\n    if (!document || !navigator || !location) {\n      return null;\n    }\n\n    let exclusions = context.client.config.dataExclusions;\n    let requestInfo: IRequestInfo = {\n      user_agent: navigator.userAgent,\n      is_secure: location.protocol === 'https:',\n      host: location.hostname,\n      port: location.port && location.port !== '' ? parseInt(location.port, 10) : 80,\n      path: location.pathname,\n      // client_ip_address: 'TODO',\n      cookies: Utils.getCookies(document.cookie, exclusions),\n      query_string: Utils.parseQueryString(location.search.substring(1), exclusions)\n    };\n\n    if (document.referrer && document.referrer !== '') {\n      requestInfo.referrer = document.referrer;\n    }\n\n    return requestInfo;\n  }\n}\n\n                                                                                                                                                                              \n\ndeclare var XDomainRequest: { new (); create(); };\n\nexport class DefaultSubmissionAdapter implements ISubmissionAdapter {\n  public sendRequest(request: SubmissionRequest, callback?: SubmissionCallback, isAppExiting?: boolean) {\n    // TODO: Handle sending events when app is exiting with send beacon.\n    const TIMEOUT: string = 'timeout';  // optimization for minifier.\n    const LOADED: string = 'loaded';  // optimization for minifier.\n    const WITH_CREDENTIALS: string = 'withCredentials';  // optimization for minifier.\n\n    let isCompleted: boolean = false;\n    let useSetTimeout: boolean = false;\n    function complete(mode: string, xhr: XMLHttpRequest) {\n      function parseResponseHeaders(headerStr) {\n        function trim(value) {\n          return value.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n        }\n\n        let headers = {};\n        let headerPairs = (headerStr || '').split('\\u000d\\u000a');\n        for (let index: number = 0; index < headerPairs.length; index++) {\n          let headerPair = headerPairs[index];\n          // Can't use split() here because it does the wrong thing\n          // if the header value has the string \": \" in it.\n          let separator = headerPair.indexOf('\\u003a\\u0020');\n          if (separator > 0) {\n            headers[trim(headerPair.substring(0, separator).toLowerCase())] = headerPair.substring(separator + 2);\n          }\n        }\n\n        return headers;\n      }\n\n      if (isCompleted) {\n        return;\n      }\n\n      isCompleted = true;\n\n      let message: string = xhr.statusText;\n      let responseText: string = xhr.responseText;\n      let status: number = xhr.status;\n\n      if (mode === TIMEOUT || status === 0) {\n        message = 'Unable to connect to server.';\n        status = 0;\n      } else if (mode === LOADED && !status) {\n        status = request.method === 'POST' ? 202 : 200;\n      } else if (status < 200 || status > 299) {\n        let responseBody: any = xhr.responseBody;\n        if (!!responseBody && !!responseBody.message) {\n          message = responseBody.message;\n        } else if (!!responseText && responseText.indexOf('message') !== -1) {\n          try {\n            message = JSON.parse(responseText).message;\n          } catch (e) {\n            message = responseText;\n          }\n        }\n      }\n\n      callback && callback(status || 500, message || '', responseText, parseResponseHeaders(xhr.getAllResponseHeaders && xhr.getAllResponseHeaders()));\n    }\n\n    function createRequest(userAgent: string, method: string, url: string): XMLHttpRequest {\n      let xhr: any = new XMLHttpRequest();\n      if (WITH_CREDENTIALS in xhr) {\n        xhr.open(method, url, true);\n\n        xhr.setRequestHeader('X-Exceptionless-Client', userAgent);\n        if (method === 'POST') {\n          xhr.setRequestHeader('Content-Type', 'application/json');\n        }\n      } else if (typeof XDomainRequest !== 'undefined') {\n        useSetTimeout = true;\n        xhr = new XDomainRequest();\n        xhr.open(method, location.protocol === 'http:' ? url.replace('https:', 'http:') : url);\n      } else {\n        xhr = null;\n      }\n\n      if (xhr) {\n        xhr.timeout = 10000;\n      }\n\n      return xhr;\n    }\n\n    let url = `${request.url}${(request.url.indexOf('?') === -1 ? '?' : '&')}access_token=${encodeURIComponent(request.apiKey)}`;\n    let xhr = createRequest(request.userAgent, request.method || 'POST', url);\n    if (!xhr) {\n      return (callback && callback(503, 'CORS not supported.'));\n    }\n\n    if (WITH_CREDENTIALS in xhr) {\n      xhr.onreadystatechange = () => {\n        // xhr not ready.\n        if (xhr.readyState !== 4) {\n          return;\n        }\n\n        complete(LOADED, xhr);\n      };\n    }\n\n    xhr.onprogress = () => { };\n    xhr.ontimeout = () => complete(TIMEOUT, xhr);\n    xhr.onerror = () => complete('error', xhr);\n    xhr.onload = () => complete(LOADED, xhr);\n\n    if (useSetTimeout) {\n      setTimeout(() => xhr.send(request.data), 500);\n    } else {\n      xhr.send(request.data);\n    }\n  }\n}\n\n                                                                                                                                                \n\nexport class BrowserStorageProvider implements IStorageProvider {\n  public queue: IStorage;\n  public settings: IStorage;\n\n  constructor(prefix?: string, maxQueueItems: number = 250) {\n    this.queue = new BrowserStorage('q', prefix, maxQueueItems);\n    this.settings = new BrowserStorage('settings', prefix, 1);\n  }\n\n}\n\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \n\nfunction getDefaultsSettingsFromScriptTag(): IConfigurationSettings {\n  if (!document || !document.getElementsByTagName) {\n    return null;\n  }\n\n  let scripts = document.getElementsByTagName('script');\n  for (let index = 0; index < scripts.length; index++) {\n    if (scripts[index].src && scripts[index].src.indexOf('/exceptionless') > -1) {\n      return Utils.parseQueryString(scripts[index].src.split('?').pop());\n    }\n  }\n  return null;\n}\n\nfunction processUnhandledException(stackTrace: TraceKit.StackTrace, options?: any): void {\n  let builder = ExceptionlessClient.default.createUnhandledException(new Error(stackTrace.message || (options || {}).status || 'Script error'), 'onerror');\n  builder.pluginContextData['@@_TraceKit.StackTrace'] = stackTrace;\n  builder.submit();\n}\n\n/*\nTODO: We currently are unable to parse string exceptions.\nfunction processJQueryAjaxError(event, xhr, settings, error:string): void {\n  let client = ExceptionlessClient.default;\n  if (xhr.status === 404) {\n    client.submitNotFound(settings.url);\n  } else if (xhr.status !== 401) {\n    client.createUnhandledException(error, 'JQuery.ajaxError')\n      .setSource(settings.url)\n      .setProperty('status', xhr.status)\n      .setProperty('request', settings.data)\n      .setProperty('response', xhr.responseText && xhr.responseText.slice && xhr.responseText.slice(0, 1024))\n      .submit();\n  }\n}\n*/\n\nConfiguration.prototype.useLocalStorage = function() {\n  if (BrowserStorage.isAvailable()) {\n    this.storage = new BrowserStorageProvider();\n    SettingsManager.applySavedServerSettings(this);\n    this.changed();\n  }\n};\n\nlet defaults = Configuration.defaults;\nlet settings = getDefaultsSettingsFromScriptTag();\nif (settings && (settings.apiKey || settings.serverUrl)) {\n  defaults.apiKey = settings.apiKey;\n  defaults.serverUrl = settings.serverUrl;\n}\n\ndefaults.errorParser = new DefaultErrorParser();\ndefaults.moduleCollector = new DefaultModuleCollector();\ndefaults.requestInfoCollector = new DefaultRequestInfoCollector();\ndefaults.submissionAdapter = new DefaultSubmissionAdapter();\n\nTraceKit.report.subscribe(processUnhandledException);\nTraceKit.extendToAsynchronousCallbacks();\n\n// window && window.addEventListener && window.addEventListener('beforeunload', function () {\n//   ExceptionlessClient.default.config.queue.process(true);\n// });\n\n// if (typeof $ !== 'undefined' && $(document)) {\n//   $(document).ajaxError(processJQueryAjaxError);\n// }\n\n(<any>Error).stackTraceLimit = Infinity;\n\ndeclare var $;\n\n"],"sourceRoot":"/source/"}