{"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('<', '(?:<|<)').replace('>', '(?:>|>)').replace('&', '(?:&|&)').replace('\"', '(?:\"|")').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('<', '(?:<|<)').replace('>', '(?:>|>)').replace('&', '(?:&|&)').replace('\"', '(?:\"|")').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/"}