Created
July 21, 2017 00:27
-
-
Save rokob/991de995e08ccf4ee570a9a000ed2ada to your computer and use it in GitHub Desktop.
Unminified track.js code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //! TrackJS JavaScript error monitoring agent. | |
| //! COPYRIGHT (c) 2017 ALL RIGHTS RESERVED | |
| //! See License at https://trackjs.com/terms/ | |
| (function(k, n, m) { | |
| "use awesome"; | |
| if (k.trackJs) k.console && k.console.warn && k.console.warn("TrackJS global conflict"); | |
| else { | |
| var p = function(a, b, c, d, e) { | |
| this.util = a; | |
| this.onError = b; | |
| this.onFault = c; | |
| this.options = e; | |
| e.enabled && this.initialize(d) | |
| }; | |
| p.prototype = { | |
| initialize: function(a) { | |
| f.forEach(["EventTarget", "Node", "XMLHttpRequest"], function(b) { | |
| f.has(a, b + ".prototype.addEventListener") && (b = a[b].prototype, b.hasOwnProperty("addEventListener") && (this.wrapAndCatch(b, "addEventListener", 1), this.wrapRemoveEventListener(b))) | |
| }, | |
| this); | |
| this.wrapAndCatch(a, "setTimeout", 0); | |
| this.wrapAndCatch(a, "setInterval", 0) | |
| }, | |
| wrapAndCatch: function(a, b, c) { | |
| var d = this, | |
| e = a[b]; | |
| f.isWrappableFunction(e) && (a[b] = function() { | |
| try { | |
| var g = Array.prototype.slice.call(arguments), | |
| l = g[c], | |
| h, y; | |
| if (d.options.bindStack) try { | |
| throw Error(); | |
| } catch (k) { | |
| y = k.stack, h = d.util.isoNow() | |
| } | |
| var F = function() { | |
| try { | |
| if (f.isObject(l)) return l.handleEvent.apply(l, arguments); | |
| if (f.isFunction(l)) return l.apply(this, arguments) | |
| } catch (a) { | |
| throw d.onError("catch", a, { | |
| bindTime: h, | |
| bindStack: y | |
| }), f.wrapError(a); | |
| } | |
| }; | |
| if ("addEventListener" === b && (this._trackJsEvt || (this._trackJsEvt = new q), this._trackJsEvt.get(g[0], l, g[2]))) return; | |
| try { | |
| l && (f.isWrappableFunction(l) || f.isWrappableFunction(l.handleEvent)) && (g[c] = F, "addEventListener" === b && this._trackJsEvt.add(g[0], l, g[2], g[c])) | |
| } catch (k) { | |
| return e.apply(this, arguments) | |
| } | |
| return e.apply(this, g) | |
| } catch (k) { | |
| a[b] = e, d.onFault(k) | |
| } | |
| }) | |
| }, | |
| wrapRemoveEventListener: function(a) { | |
| if (a && a.removeEventListener && this.util.hasFunction(a.removeEventListener, "call")) { | |
| var b = a.removeEventListener; | |
| a.removeEventListener = function(a, d, e) { | |
| if (this._trackJsEvt) { | |
| var g = this._trackJsEvt.get(a, d, e); | |
| if (g) return this._trackJsEvt.remove(a, d, e), b.call(this, a, g, e) | |
| } | |
| return b.call(this, a, d, e) | |
| } | |
| } | |
| } | |
| }; | |
| var q = function() { | |
| this.events = [] | |
| }; | |
| q.prototype = { | |
| add: function(a, b, c, d) { | |
| -1 >= this.indexOf(a, b, c) && (c = this.getEventOptions(c), this.events.push([a, b, c.capture, c.once, c.passive, d])) | |
| }, | |
| get: function(a, b, c) { | |
| a = this.indexOf(a, b, c); | |
| return 0 <= a ? this.events[a][5] : m | |
| }, | |
| getEventOptions: function(a) { | |
| var b = { | |
| capture: !1, | |
| once: !1, | |
| passive: !1 | |
| }; | |
| return f.isBoolean(a) ? f.defaults({}, { | |
| capture: a | |
| }, b) : f.defaults({}, a, b) | |
| }, | |
| indexOf: function(a, b, c) { | |
| c = this.getEventOptions(c); | |
| for (var d = 0; d < this.events.length; d++) { | |
| var e = this.events[d]; | |
| if (e[0] === a && e[1] === b && e[2] === c.capture && e[3] === c.once && e[4] === c.passive) return d | |
| } | |
| return -1 | |
| }, | |
| remove: function(a, b, c) { | |
| a = this.indexOf(a, b, c); | |
| 0 <= a && this.events.splice(a, 1) | |
| } | |
| }; | |
| var t = function(a) { | |
| this.initCurrent(a) | |
| }; | |
| t.prototype = { | |
| current: {}, | |
| initOnly: { | |
| cookie: !0, | |
| enabled: !0, | |
| token: !0, | |
| callback: { | |
| enabled: !0 | |
| }, | |
| console: { | |
| enabled: !0 | |
| }, | |
| navigation: { | |
| enabled: !0 | |
| }, | |
| network: { | |
| enabled: !0, | |
| fetch: !0 | |
| }, | |
| visitor: { | |
| enabled: !0 | |
| }, | |
| window: { | |
| enabled: !0, | |
| promise: !0 | |
| } | |
| }, | |
| defaults: { | |
| application: "", | |
| cookie: !1, | |
| dedupe: !0, | |
| enabled: !0, | |
| errorURL: "https://capture.trackjs.com/capture", | |
| errorNoSSLURL: "http://capture.trackjs.com/capture", | |
| faultURL: "https://usage.trackjs.com/fault.gif", | |
| onError: function() { | |
| return !0 | |
| }, | |
| serialize: function(a) { | |
| function b(a) { | |
| var c = "<" + a.tagName.toLowerCase(); | |
| a = a.attributes || []; | |
| for (var b = 0; b < a.length; b++) c += " " + a[b].name + '="' + a[b].value + '"'; | |
| return c + ">" | |
| } | |
| if ("" === a) return "Empty String"; | |
| if (a === m) return "undefined"; | |
| if (f.isString(a) || f.isNumber(a) || f.isBoolean(a) || f.isFunction(a)) return "" + a; | |
| if (f.isElement(a)) return b(a); | |
| var c; | |
| try { | |
| c = JSON.stringify(a, function(a, c) { | |
| return c === m ? "undefined" : f.isNumber(c) && isNaN(c) ? "NaN" : f.isError(c) ? { | |
| name: c.name, | |
| message: c.message, | |
| stack: c.stack | |
| } : f.isElement(c) ? b(c) : c | |
| }) | |
| } catch (e) { | |
| c = ""; | |
| for (var d in a) a.hasOwnProperty(d) && (c += ',"' + d + '":"' + a[d] + '"'); | |
| c = c ? "{" + c.replace(",", "") + "}" : "Unserializable Object" | |
| } | |
| return c.replace(/"undefined"/g, "undefined").replace(/"NaN"/g, | |
| "NaN") | |
| }, | |
| sessionId: "", | |
| token: "", | |
| userId: "", | |
| version: "", | |
| callback: { | |
| enabled: !0, | |
| bindStack: !1 | |
| }, | |
| console: { | |
| enabled: !0, | |
| display: !0, | |
| error: !0, | |
| warn: !1, | |
| watch: ["log", "debug", "info", "warn", "error"] | |
| }, | |
| navigation: { | |
| enabled: !0 | |
| }, | |
| network: { | |
| enabled: !0, | |
| error: !0, | |
| fetch: !0 | |
| }, | |
| visitor: { | |
| enabled: !0 | |
| }, | |
| usageURL: "https://usage.trackjs.com/usage.gif", | |
| window: { | |
| enabled: !0, | |
| promise: !0 | |
| } | |
| }, | |
| initCurrent: function(a) { | |
| if (this.validate(a, this.defaults, "config", {})) return this.current = f.defaultsDeep({}, a, this.defaults), !0; | |
| this.current = f.defaultsDeep({}, | |
| this.defaults); | |
| console.log("init current config", this.current); | |
| return !1 | |
| }, | |
| setCurrent: function(a) { | |
| return this.validate(a, this.defaults, "config", this.initOnly) ? (this.current = f.defaultsDeep({}, a, this.current), !0) : !1 | |
| }, | |
| validate: function(a, b, c, d) { | |
| var e = !0; | |
| c = c || ""; | |
| d = d || {}; | |
| for (var g in a) | |
| if (a.hasOwnProperty(g)) | |
| if (b.hasOwnProperty(g)) { | |
| var f = typeof b[g]; | |
| f !== typeof a[g] ? (console.warn(c + "." + g + ": property must be type " + f + "."), e = !1) : "[object Array]" !== Object.prototype.toString.call(a[g]) || this.validateArray(a[g], | |
| b[g], c + "." + g) ? "[object Object]" === Object.prototype.toString.call(a[g]) ? e = this.validate(a[g], b[g], c + "." + g, d[g]) : d.hasOwnProperty(g) && (console.warn(c + "." + g + ": property cannot be set after load."), e = !1) : e = !1 | |
| } else console.warn(c + "." + g + ": property not supported."), e = !1; | |
| return e | |
| }, | |
| validateArray: function(a, b, c) { | |
| var d = !0; | |
| c = c || ""; | |
| for (var e = 0; e < a.length; e++) f.contains(b, a[e]) || (console.warn(c + "[" + e + "]: invalid value: " + a[e] + "."), d = !1); | |
| return d | |
| } | |
| }; | |
| var u = function(a, b, c, d, e, g, f) { | |
| this.util = a; | |
| this.log = b; | |
| this.onError = | |
| c; | |
| this.onFault = d; | |
| this.serialize = e; | |
| f.enabled && (g.console = this.wrapConsoleObject(g.console, f)) | |
| }; | |
| u.prototype = { | |
| wrapConsoleObject: function(a, b) { | |
| a = a || {}; | |
| var c = a.log || function() {}, | |
| d = this, | |
| e; | |
| for (e = 0; e < b.watch.length; e++)(function(e) { | |
| var l = a[e] || c; | |
| a[e] = function() { | |
| try { | |
| var a = Array.prototype.slice.call(arguments); | |
| d.log.add("c", { | |
| timestamp: d.util.isoNow(), | |
| severity: e, | |
| message: d.serialize(1 === a.length ? a[0] : a) | |
| }); | |
| if (b[e]) | |
| if (f.isError(a[0]) && 1 === a.length) d.onError("console", a[0]); | |
| else try { | |
| throw Error(d.serialize(1 === | |
| a.length ? a[0] : a)); | |
| } catch (c) { | |
| d.onError("console", c) | |
| } | |
| b.display && (d.util.hasFunction(l, "apply") ? l.apply(this, a) : l(a[0])) | |
| } catch (c) { | |
| d.onFault(c) | |
| } | |
| } | |
| })(b.watch[e]); | |
| return a | |
| }, | |
| report: function() { | |
| return this.log.all("c") | |
| } | |
| }; | |
| var v = function(a, b, c, d, e) { | |
| this.config = a; | |
| this.util = b; | |
| this.log = c; | |
| this.window = d; | |
| this.document = e; | |
| this.correlationId = this.token = null; | |
| this.initialize() | |
| }; | |
| v.prototype = { | |
| initialize: function() { | |
| this.token = this.getCustomerToken(); | |
| this.correlationId = this.getCorrelationId() | |
| }, | |
| getCustomerToken: function() { | |
| if (this.config.current.token) return this.config.current.token; | |
| var a = this.document.getElementsByTagName("script"); | |
| return a[a.length - 1].getAttribute("data-token") | |
| }, | |
| getCorrelationId: function() { | |
| var a; | |
| if (!this.config.current.cookie) return this.util.uuid(); | |
| try { | |
| a = this.document.cookie.replace(/(?:(?:^|.*;\s*)TrackJS\s*\=\s*([^;]*).*$)|^.*$/, "$1"), a || (a = this.util.uuid(), this.document.cookie = "TrackJS=" + a + "; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/") | |
| } catch (b) { | |
| a = this.util.uuid() | |
| } | |
| return a | |
| }, | |
| report: function() { | |
| return { | |
| application: this.config.current.application, | |
| correlationId: this.correlationId, | |
| sessionId: this.config.current.sessionId, | |
| token: this.token, | |
| userId: this.config.current.userId, | |
| version: this.config.current.version | |
| } | |
| } | |
| }; | |
| var w = function(a) { | |
| this.loadedOn = (new Date).getTime(); | |
| this.window = a | |
| }; | |
| w.prototype = { | |
| discoverDependencies: function() { | |
| var a, b = {}; | |
| this.window.jQuery && this.window.jQuery.fn && this.window.jQuery.fn.jquery && (b.jQuery = this.window.jQuery.fn.jquery); | |
| this.window.jQuery && this.window.jQuery.ui && this.window.jQuery.ui.version && (b.jQueryUI = this.window.jQuery.ui.version); | |
| this.window.angular && | |
| this.window.angular.version && this.window.angular.version.full && (b.angular = this.window.angular.version.full); | |
| for (a in this.window) | |
| if ("_trackJs" !== a && "_trackJS" !== a && "_trackjs" !== a && "webkitStorageInfo" !== a && "webkitIndexedDB" !== a && "top" !== a && "parent" !== a && "frameElement" !== a) try { | |
| if (this.window[a]) { | |
| var c = this.window[a].version || this.window[a].Version || this.window[a].VERSION; | |
| "string" === typeof c && (b[a] = c) | |
| } | |
| } catch (d) {} | |
| return b | |
| }, | |
| report: function() { | |
| return { | |
| age: (new Date).getTime() - this.loadedOn, | |
| dependencies: this.discoverDependencies(), | |
| userAgent: this.window.navigator.userAgent, | |
| viewportHeight: this.window.document.documentElement.clientHeight, | |
| viewportWidth: this.window.document.documentElement.clientWidth | |
| } | |
| } | |
| }; | |
| var z = function(a) { | |
| this.util = a; | |
| this.appender = []; | |
| this.maxLength = 30 | |
| }; | |
| z.prototype = { | |
| all: function(a) { | |
| var b = [], | |
| c, d; | |
| for (d = 0; d < this.appender.length; d++)(c = this.appender[d]) && c.category === a && b.push(c.value); | |
| return b | |
| }, | |
| clear: function() { | |
| this.appender.length = 0 | |
| }, | |
| truncate: function() { | |
| this.appender.length > this.maxLength && (this.appender = this.appender.slice(Math.max(this.appender.length - | |
| this.maxLength, 0))) | |
| }, | |
| add: function(a, b) { | |
| var c = this.util.uuid(); | |
| this.appender.push({ | |
| key: c, | |
| category: a, | |
| value: b | |
| }); | |
| this.truncate(); | |
| return c | |
| }, | |
| get: function(a, b) { | |
| var c, d; | |
| for (d = 0; d < this.appender.length; d++) | |
| if (c = this.appender[d], c.category === a && c.key === b) return c.value; | |
| return !1 | |
| } | |
| }; | |
| var A = function(a, b) { | |
| this.log = a; | |
| this.options = b; | |
| b.enabled && this.watch() | |
| }; | |
| A.prototype = { | |
| isCompatible: function(a) { | |
| a = a || k; | |
| return !f.has(a, "chrome.app.runtime") && f.has(a, "addEventListener") && f.has(a, "history.pushState") | |
| }, | |
| record: function(a, | |
| b, c) { | |
| this.log.add("h", { | |
| type: a, | |
| from: f.truncate(b, 250), | |
| to: f.truncate(c, 250), | |
| on: f.isoNow() | |
| }) | |
| }, | |
| report: function() { | |
| return this.log.all("h") | |
| }, | |
| watch: function() { | |
| if (this.isCompatible()) { | |
| var a = this, | |
| b = f.getLocationURL().relative; | |
| k.addEventListener("popstate", function() { | |
| var c = f.getLocationURL().relative; | |
| a.record("popState", b, c); | |
| b = c | |
| }, !0); | |
| f.forEach(["pushState", "replaceState"], function(c) { | |
| f.patch(history, c, function(d) { | |
| return function() { | |
| b = f.getLocationURL().relative; | |
| var e = d.apply(this, arguments), | |
| g = f.getLocationURL().relative; | |
| a.record(c, b, g); | |
| b = g; | |
| return e | |
| } | |
| }) | |
| }) | |
| } | |
| } | |
| }; | |
| var B = function(a, b, c, d, e, g) { | |
| this.util = a; | |
| this.log = b; | |
| this.onError = c; | |
| this.onFault = d; | |
| this.window = e; | |
| this.options = g; | |
| g.enabled && this.initialize(e) | |
| }; | |
| B.prototype = { | |
| initialize: function(a) { | |
| a.XMLHttpRequest && this.util.hasFunction(a.XMLHttpRequest.prototype.open, "apply") && this.watchNetworkObject(a.XMLHttpRequest); | |
| a.XDomainRequest && this.util.hasFunction(a.XDomainRequest.prototype.open, "apply") && this.watchNetworkObject(a.XDomainRequest); | |
| this.options.fetch && f.isWrappableFunction(a.fetch) && | |
| this.watchFetch() | |
| }, | |
| watchFetch: function() { | |
| var a = this.log, | |
| b = this.options, | |
| c = this.onError; | |
| f.patch(k, "fetch", function(d) { | |
| return function(e, g) { | |
| var l = e instanceof Request ? e : new Request(e, g), | |
| h = d.apply(k, arguments); | |
| h._tjsId = a.add("n", { | |
| type: "fetch", | |
| startedOn: f.isoNow(), | |
| method: l.method, | |
| url: l.url | |
| }); | |
| return h.then(function(d) { | |
| var e = a.get("n", h._tjsId); | |
| e && (f.defaults(e, { | |
| completedOn: f.isoNow(), | |
| statusCode: d.status, | |
| statusText: d.statusText | |
| }), b.error && 400 <= d.status && c("ajax", e.statusCode + " " + e.statusText + ": " + e.method + | |
| " " + e.url)); | |
| return d | |
| })["catch"](function(d) { | |
| var e = a.get("n", h._tjsId); | |
| e && (f.defaults(e, { | |
| completedOn: f.isoNow(), | |
| statusCode: 0, | |
| statusText: (d || "").toString() | |
| }), b.error && c("ajax", d)); | |
| throw d; | |
| }) | |
| } | |
| }) | |
| }, | |
| watchNetworkObject: function(a) { | |
| var b = this, | |
| c = a.prototype.open, | |
| d = a.prototype.send; | |
| a.prototype.open = function(a, b) { | |
| var d = (b || "").toString(); | |
| 0 > d.indexOf("localhost:0") && (this._trackJs = { | |
| method: a, | |
| url: d | |
| }); | |
| return c.apply(this, arguments) | |
| }; | |
| a.prototype.send = function() { | |
| try { | |
| if (!this._trackJs) return d.apply(this, arguments); | |
| this._trackJs.logId = b.log.add("n", { | |
| type: "xhr", | |
| startedOn: b.util.isoNow(), | |
| method: this._trackJs.method, | |
| url: this._trackJs.url | |
| }); | |
| b.listenForNetworkComplete(this) | |
| } catch (a) { | |
| b.onFault(a) | |
| } | |
| return d.apply(this, arguments) | |
| }; | |
| return a | |
| }, | |
| listenForNetworkComplete: function(a) { | |
| var b = this; | |
| b.window.ProgressEvent && a.addEventListener && a.addEventListener("readystatechange", function() { | |
| 4 === a.readyState && b.finalizeNetworkEvent(a) | |
| }, !0); | |
| a.addEventListener ? a.addEventListener("load", function() { | |
| b.finalizeNetworkEvent(a); | |
| b.checkNetworkFault(a) | |
| }, !0) : setTimeout(function() { | |
| try { | |
| var c = a.onload; | |
| a.onload = function() { | |
| b.finalizeNetworkEvent(a); | |
| b.checkNetworkFault(a); | |
| "function" === typeof c && b.util.hasFunction(c, "apply") && c.apply(a, arguments) | |
| }; | |
| var d = a.onerror; | |
| a.onerror = function() { | |
| b.finalizeNetworkEvent(a); | |
| b.checkNetworkFault(a); | |
| "function" === typeof oldOnError && d.apply(a, arguments) | |
| } | |
| } catch (e) { | |
| b.onFault(e) | |
| } | |
| }, 0) | |
| }, | |
| finalizeNetworkEvent: function(a) { | |
| if (a._trackJs) { | |
| var b = this.log.get("n", a._trackJs.logId); | |
| b && (b.completedOn = this.util.isoNow(), b.statusCode = 1223 == | |
| a.status ? 204 : a.status, b.statusText = 1223 == a.status ? "No Content" : a.statusText) | |
| } | |
| }, | |
| checkNetworkFault: function(a) { | |
| if (this.options.error && 400 <= a.status && 1223 != a.status) { | |
| var b = a._trackJs || {}; | |
| this.onError("ajax", a.status + " " + a.statusText + ": " + b.method + " " + b.url) | |
| } | |
| }, | |
| report: function() { | |
| return this.log.all("n") | |
| } | |
| }; | |
| var x = function(a, b) { | |
| this.util = a; | |
| this.config = b; | |
| this.disabled = !1; | |
| this.throttleStats = { | |
| attemptCount: 0, | |
| throttledCount: 0, | |
| lastAttempt: (new Date).getTime() | |
| }; | |
| k.JSON && k.JSON.stringify || (this.disabled = !0) | |
| }; | |
| x.prototype = { | |
| errorEndpoint: function(a) { | |
| var b = this.config.current.errorURL; | |
| this.util.testCrossdomainXhr() || -1 !== k.location.protocol.indexOf("https") || (b = this.config.current.errorNoSSLURL); | |
| return b + "?token=" + a | |
| }, | |
| usageEndpoint: function(a) { | |
| return this.appendObjectAsQuery(a, this.config.current.usageURL) | |
| }, | |
| trackerFaultEndpoint: function(a) { | |
| return this.appendObjectAsQuery(a, this.config.current.faultURL) | |
| }, | |
| appendObjectAsQuery: function(a, b) { | |
| b += "?"; | |
| for (var c in a) a.hasOwnProperty(c) && (b += encodeURIComponent(c) + "=" + encodeURIComponent(a[c]) + | |
| "&"); | |
| return b | |
| }, | |
| getCORSRequest: function(a, b) { | |
| var c; | |
| this.util.testCrossdomainXhr() ? (c = new k.XMLHttpRequest, c.open(a, b), c.setRequestHeader("Content-Type", "text/plain")) : "undefined" !== typeof k.XDomainRequest ? (c = new k.XDomainRequest, c.open(a, b)) : c = null; | |
| return c | |
| }, | |
| sendTrackerFault: function(a) { | |
| this.throttle(a) || ((new Image).src = this.trackerFaultEndpoint(a)) | |
| }, | |
| sendUsage: function(a) { | |
| (new Image).src = this.usageEndpoint(a) | |
| }, | |
| sendError: function(a, b) { | |
| var c = this; | |
| if (!this.disabled && !this.throttle(a)) try { | |
| var d = this.getCORSRequest("POST", | |
| this.errorEndpoint(b)); | |
| d.onreadystatechange = function() { | |
| 4 === d.readyState && 200 !== d.status && (c.disabled = !0) | |
| }; | |
| d._trackJs = m; | |
| d.send(k.JSON.stringify(a)) | |
| } catch (e) { | |
| throw this.disabled = !0, e; | |
| } | |
| }, | |
| throttle: function(a) { | |
| var b = (new Date).getTime(); | |
| this.throttleStats.attemptCount++; | |
| if (this.throttleStats.lastAttempt + 1E3 >= b) { | |
| if (this.throttleStats.lastAttempt = b, 10 < this.throttleStats.attemptCount) return this.throttleStats.throttledCount++, !0 | |
| } else a.throttled = this.throttleStats.throttledCount, this.throttleStats.attemptCount = | |
| 0, this.throttleStats.lastAttempt = b, this.throttleStats.throttledCount = 0; | |
| return !1 | |
| } | |
| }; | |
| var f = function() { | |
| function a(c, d, e, g) { | |
| e = e || !1; | |
| g = g || 0; | |
| f.forEach(d, function(d) { | |
| f.forEach(f.keys(d), function(f) { | |
| null === d[f] || d[f] === m ? c[f] = d[f] : e && 10 > g && "[object Object]" === b(d[f]) ? (c[f] = c[f] || {}, a(c[f], [d[f]], e, g + 1)) : c.hasOwnProperty(f) || (c[f] = d[f]) | |
| }) | |
| }); | |
| return c | |
| } | |
| function b(a) { | |
| return Object.prototype.toString.call(a) | |
| } | |
| return { | |
| addEventListenerSafe: function(a, b, e, f) { | |
| a.addEventListener ? a.addEventListener(b, e, f) : a.attachEvent && | |
| a.attachEvent("on" + b, e) | |
| }, | |
| afterDocumentLoad: function(a) { | |
| var b = !1; | |
| "complete" === n.readyState ? f.defer(a) : (f.addEventListenerSafe(n, "readystatechange", function() { | |
| "complete" !== n.readyState || b || (f.defer(a), b = !0) | |
| }), setTimeout(function() { | |
| b || (f.defer(a), b = !0) | |
| }, 1E4)) | |
| }, | |
| bind: function(a, b) { | |
| return function() { | |
| return a.apply(b, Array.prototype.slice.call(arguments)) | |
| } | |
| }, | |
| contains: function(a, b) { | |
| var e; | |
| for (e = 0; e < a.length; e++) | |
| if (a[e] === b) return !0; | |
| return !1 | |
| }, | |
| defaults: function(c) { | |
| return a(c, Array.prototype.slice.call(arguments, | |
| 1), !1) | |
| }, | |
| defaultsDeep: function(c) { | |
| return a(c, Array.prototype.slice.call(arguments, 1), !0) | |
| }, | |
| defer: function(a, b) { | |
| setTimeout(function() { | |
| a.apply(b) | |
| }) | |
| }, | |
| forEach: function(a, b, e) { | |
| if (a.forEach) return a.forEach(b, e); | |
| for (var f = 0; f < a.length;) b.call(e, a[f], f, a), f++ | |
| }, | |
| getLocation: function() { | |
| return k.location.toString().replace(/ /g, "%20") | |
| }, | |
| getLocationURL: function() { | |
| return f.parseURL(f.getLocation()) | |
| }, | |
| has: function(a, b) { | |
| for (var e = b.split("."), f = a, l = 0; l < e.length; l++) | |
| if (f[e[l]]) f = f[e[l]]; | |
| else return !1; | |
| return !0 | |
| }, | |
| hasFunction: function(a, | |
| b) { | |
| try { | |
| return !!a[b] | |
| } catch (e) { | |
| return !1 | |
| } | |
| }, | |
| isArray: function(a) { | |
| return "[object Array]" === b(a) | |
| }, | |
| isBoolean: function(a) { | |
| return "boolean" === typeof a || f.isObject(a) && "[object Boolean]" === b(a) | |
| }, | |
| isBrowserIE: function(a) { | |
| a = a || k.navigator.userAgent; | |
| var b = a.match(/Trident\/([\d.]+)/); | |
| return b && "7.0" === b[1] ? 11 : (a = a.match(/MSIE ([\d.]+)/)) ? parseInt(a[1], 10) : !1 | |
| }, | |
| isBrowserSupported: function() { | |
| var a = this.isBrowserIE(); | |
| return !a || 8 <= a | |
| }, | |
| isError: function(a) { | |
| if (!f.isObject(a)) return !1; | |
| var d = b(a); | |
| return "[object Error]" === d || | |
| "[object DOMException]" === d || f.isString(a.name) && f.isString(a.message) | |
| }, | |
| isElement: function(a) { | |
| return f.isObject(a) && 1 === a.nodeType | |
| }, | |
| isFunction: function(a) { | |
| return !(!a || "function" !== typeof a) | |
| }, | |
| isNumber: function(a) { | |
| return "number" === typeof a || f.isObject(a) && "[object Number]" === b(a) | |
| }, | |
| isObject: function(a) { | |
| return !(!a || "object" !== typeof a) | |
| }, | |
| isString: function(a) { | |
| return "string" === typeof a || !f.isArray(a) && f.isObject(a) && "[object String]" === b(a) | |
| }, | |
| isWrappableFunction: function(a) { | |
| return this.isFunction(a) && this.hasFunction(a, | |
| "apply") | |
| }, | |
| isoNow: function() { | |
| var a = new Date; | |
| return a.toISOString ? a.toISOString() : a.getUTCFullYear() + "-" + this.pad(a.getUTCMonth() + 1) + "-" + this.pad(a.getUTCDate()) + "T" + this.pad(a.getUTCHours()) + ":" + this.pad(a.getUTCMinutes()) + ":" + this.pad(a.getUTCSeconds()) + "." + String((a.getUTCMilliseconds() / 1E3).toFixed(3)).slice(2, 5) + "Z" | |
| }, | |
| keys: function(a) { | |
| if (!f.isObject(a)) return []; | |
| var b = [], | |
| e; | |
| for (e in a) a.hasOwnProperty(e) && b.push(e); | |
| return b | |
| }, | |
| noop: function() {}, | |
| pad: function(a) { | |
| a = String(a); | |
| 1 === a.length && (a = "0" + a); | |
| return a | |
| }, | |
| parseURL: function(a) { | |
| var b = a.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/); | |
| if (!b) return {}; | |
| b = { | |
| protocol: b[2], | |
| host: b[4], | |
| path: b[5], | |
| query: b[6], | |
| hash: b[8] | |
| }; | |
| b.origin = (b.protocol || "") + "://" + (b.host || ""); | |
| b.relative = (b.path || "") + (b.query || "") + (b.hash || ""); | |
| b.href = a; | |
| return b | |
| }, | |
| patch: function(a, b, e) { | |
| a[b] = e(a[b] || f.noop) | |
| }, | |
| testCrossdomainXhr: function() { | |
| return "withCredentials" in new XMLHttpRequest | |
| }, | |
| truncate: function(a, b) { | |
| if (a.length <= b) return a; | |
| var e = a.length - b; | |
| return a.substr(0, b) + "...{" + | |
| e + "}" | |
| }, | |
| uuid: function() { | |
| return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(a) { | |
| var b = 16 * Math.random() | 0; | |
| return ("x" == a ? b : b & 3 | 8).toString(16) | |
| }) | |
| }, | |
| wrapError: function(a) { | |
| if (a.innerError) return a; | |
| var b = Error("TrackJS Caught: " + (a.message || a)); | |
| b.description = "TrackJS Caught: " + a.description; | |
| b.file = a.file; | |
| b.line = a.line || a.lineNumber; | |
| b.column = a.column || a.columnNumber; | |
| b.stack = a.stack; | |
| b.innerError = a; | |
| return b | |
| } | |
| } | |
| }(), | |
| C = function(a, b, c, d, e, f) { | |
| this.util = a; | |
| this.log = b; | |
| this.onError = c; | |
| this.onFault = d; | |
| this.options = | |
| f; | |
| this.document = e; | |
| f.enabled && this.initialize(e) | |
| }; | |
| C.prototype = { | |
| initialize: function(a) { | |
| var b = this.util.bind(this.onDocumentClicked, this), | |
| c = this.util.bind(this.onInputChanged, this); | |
| a.addEventListener ? (a.addEventListener("click", b, !0), a.addEventListener("blur", c, !0)) : a.attachEvent && (a.attachEvent("onclick", b), a.attachEvent("onfocusout", c)) | |
| }, | |
| onDocumentClicked: function(a) { | |
| try { | |
| var b = this.getElementFromEvent(a); | |
| b && b.tagName && (this.isDescribedElement(b, "a") || this.isDescribedElement(b, "button") || this.isDescribedElement(b, | |
| "input", ["button", "submit"]) ? this.writeVisitorEvent(b, "click") : this.isDescribedElement(b, "input", ["checkbox", "radio"]) && this.writeVisitorEvent(b, "input", b.value, b.checked)) | |
| } catch (c) { | |
| this.onFault(c) | |
| } | |
| }, | |
| onInputChanged: function(a) { | |
| try { | |
| var b = this.getElementFromEvent(a); | |
| if (b && b.tagName) | |
| if (this.isDescribedElement(b, "textarea")) this.writeVisitorEvent(b, "input", b.value); | |
| else if (this.isDescribedElement(b, "select") && b.options && b.options.length) this.onSelectInputChanged(b); | |
| else this.isDescribedElement(b, "input") && | |
| !this.isDescribedElement(b, "input", ["button", "submit", "hidden", "checkbox", "radio"]) && this.writeVisitorEvent(b, "input", b.value) | |
| } catch (c) { | |
| this.onFault(c) | |
| } | |
| }, | |
| onSelectInputChanged: function(a) { | |
| if (a.multiple) | |
| for (var b = 0; b < a.options.length; b++) a.options[b].selected && this.writeVisitorEvent(a, "input", a.options[b].value); | |
| else 0 <= a.selectedIndex && a.options[a.selectedIndex] && this.writeVisitorEvent(a, "input", a.options[a.selectedIndex].value) | |
| }, | |
| writeVisitorEvent: function(a, b, c, d) { | |
| "password" === this.getElementType(a) && | |
| (c = m); | |
| this.log.add("v", { | |
| timestamp: this.util.isoNow(), | |
| action: b, | |
| element: { | |
| tag: a.tagName.toLowerCase(), | |
| attributes: this.getElementAttributes(a), | |
| value: this.getMetaValue(c, d) | |
| } | |
| }) | |
| }, | |
| getElementFromEvent: function(a) { | |
| return a.target || n.elementFromPoint(a.clientX, a.clientY) | |
| }, | |
| isDescribedElement: function(a, b, c) { | |
| if (a.tagName.toLowerCase() !== b.toLowerCase()) return !1; | |
| if (!c) return !0; | |
| a = this.getElementType(a); | |
| for (b = 0; b < c.length; b++) | |
| if (c[b] === a) return !0; | |
| return !1 | |
| }, | |
| getElementType: function(a) { | |
| return (a.getAttribute("type") || | |
| "").toLowerCase() | |
| }, | |
| getElementAttributes: function(a) { | |
| for (var b = {}, c = 0; c < a.attributes.length; c++) "value" !== a.attributes[c].name.toLowerCase() && (b[a.attributes[c].name] = a.attributes[c].value); | |
| return b | |
| }, | |
| getMetaValue: function(a, b) { | |
| return a === m ? m : { | |
| length: a.length, | |
| pattern: this.matchInputPattern(a), | |
| checked: b | |
| } | |
| }, | |
| matchInputPattern: function(a) { | |
| return "" === a ? "empty" : /^[a-z0-9!#$%&'*+=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(a) ? "email" : | |
| /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/.test(a) || /^(\d{4}[\/\-](0?[1-9]|1[012])[\/\-]0?[1-9]|[12][0-9]|3[01])$/.test(a) ? "date" : /^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/.test(a) ? "usphone" : /^\s*$/.test(a) ? "whitespace" : /^\d*$/.test(a) ? "numeric" : /^[a-zA-Z]*$/.test(a) ? | |
| "alpha" : /^[a-zA-Z0-9]*$/.test(a) ? "alphanumeric" : "characters" | |
| }, | |
| report: function() { | |
| return this.log.all("v") | |
| } | |
| }; | |
| var D = function(a, b, c, d, e) { | |
| this.onError = a; | |
| this.onFault = b; | |
| this.serialize = c; | |
| e.enabled && this.watchWindowErrors(d); | |
| e.promise && this.watchPromiseErrors(d) | |
| }; | |
| D.prototype = { | |
| watchPromiseErrors: function(a) { | |
| var b = this; | |
| a.addEventListener ? a.addEventListener("unhandledrejection", function(a) { | |
| a = a || {}; | |
| a = a.detail ? a.detail.reason : a.reason; | |
| if (a !== m) { | |
| if (!f.isError(a)) try { | |
| throw Error(b.serialize(a)); | |
| } catch (d) { | |
| a = d | |
| } | |
| b.onError("promise", | |
| a) | |
| } | |
| }) : a.onunhandledrejection = function(a) { | |
| b.onError("promise", a) | |
| } | |
| }, | |
| watchWindowErrors: function(a) { | |
| var b = this; | |
| f.patch(a, "onerror", function(a) { | |
| return function(d, e, f, l, h) { | |
| try { | |
| h = h || {}, h.message = h.message || b.serialize(d), h.name = h.name || "Error", h.line = h.line || parseInt(f, 10) || null, h.column = h.column || parseInt(l, 10) || null, "[object Event]" !== Object.prototype.toString.call(d) || e ? h.file = h.file || b.serialize(e) : h.file = (d.target || {}).src, b.onError("window", h) | |
| } catch (k) { | |
| b.onFault(k) | |
| } | |
| a.apply(this, arguments) | |
| } | |
| }) | |
| } | |
| }; | |
| var E = | |
| function(a, b, c, d, e, g, l, h, k, m, n, p, q, x, t, u, v) { | |
| try { | |
| if (this.window = t, this.document = u, this.util = f, this.onError = this.util.bind(this.onError, this), this.onFault = this.util.bind(this.onFault, this), this.serialize = this.util.bind(this.serialize, this), this.config = new d(a), this.transmitter = new n(this.util, this.config), this.log = new h(this.util), this.api = new b(this.config, this.util, this.onError, this.serialize), this.metadata = new k(this.serialize), this.environment = new l(this.window), this.customer = new g(this.config, | |
| this.util, this.log, this.window, this.document), this.customer.token && (this.apiConsoleWatcher = new e(this.util, this.log, this.onError, this.onFault, this.serialize, this.api, this.config.defaults.console), this.config.current.enabled && (this.windowConsoleWatcher = new e(this.util, this.log, this.onError, this.onFault, this.serialize, this.window, this.config.current.console), this.util.isBrowserSupported()))) { | |
| this.callbackWatcher = new c(this.util, this.onError, this.onFault, this.window, this.config.current.callback); | |
| this.visitorWatcher = | |
| new p(this.util, this.log, this.onError, this.onFault, this.document, this.config.current.visitor); | |
| this.navigationWatcher = new v(this.log, this.config.current.navigation); | |
| this.networkWatcher = new m(this.util, this.log, this.onError, this.onFault, this.window, this.config.current.network); | |
| this.windowWatcher = new q(this.onError, this.onFault, this.serialize, this.window, this.config.current.window); | |
| var r = this; | |
| f.afterDocumentLoad(function() { | |
| r.transmitter.sendUsage({ | |
| token: r.customer.token, | |
| correlationId: r.customer.correlationId, | |
| application: r.config.current.application, | |
| x: r.util.uuid() | |
| }) | |
| }) | |
| } | |
| } catch (w) { | |
| this.onFault(w) | |
| } | |
| }; | |
| E.prototype = { | |
| reveal: function() { | |
| if (this.customer.token) return this.api.addMetadata = this.metadata.addMetadata, this.api.removeMetadata = this.metadata.removeMetadata, this.api; | |
| this.config.current.enabled && this.window.console && this.window.console.warn && this.window.console.warn("TrackJS could not find a token"); | |
| return m | |
| }, | |
| onError: function() { | |
| var a, b = !1; | |
| return function(c, d, e) { | |
| if (f.isBrowserSupported() && this.config.current.enabled) try { | |
| if (e = | |
| e || { | |
| bindStack: null, | |
| bindTime: null, | |
| force: !1 | |
| }, d && f.isError(d) || (d = { | |
| name: "Error", | |
| message: this.serialize(d, e.force) | |
| }), -1 === d.message.indexOf("TrackJS Caught")) | |
| if (b && -1 !== d.message.indexOf("Script error")) b = !1; | |
| else { | |
| var g = f.defaultsDeep({}, { | |
| bindStack: e.bindStack, | |
| bindTime: e.bindTime, | |
| column: d.column || d.columnNumber, | |
| console: this.windowConsoleWatcher.report(), | |
| customer: this.customer.report(), | |
| entry: c, | |
| environment: this.environment.report(), | |
| file: d.file || d.fileName, | |
| line: d.line || d.lineNumber, | |
| message: d.message, | |
| metadata: this.metadata.report(), | |
| nav: this.navigationWatcher.report(), | |
| network: this.networkWatcher.report(), | |
| url: (k.location || "").toString(), | |
| stack: d.stack, | |
| timestamp: this.util.isoNow(), | |
| visitor: this.visitorWatcher.report(), | |
| version: "2.8.4" | |
| }); | |
| if (!e.force) try { | |
| if (!this.config.current.onError(g, d)) return | |
| } catch (m) { | |
| g.console.push({ | |
| timestamp: this.util.isoNow(), | |
| severity: "error", | |
| message: m.message | |
| }); | |
| var l = this; | |
| setTimeout(function() { | |
| l.onError("catch", m, { | |
| force: !0 | |
| }) | |
| }, 0) | |
| } | |
| if (this.config.current.dedupe) { | |
| var h = (g.message + g.stack).substr(0, 1E4); | |
| if (h === | |
| a) return; | |
| a = h | |
| } | |
| this.log.clear(); | |
| setTimeout(function() { | |
| b = !1 | |
| }); | |
| b = !0; | |
| this.transmitter.sendError(g, this.customer.token) | |
| } | |
| } catch (m) { | |
| this.onFault(m) | |
| } | |
| } | |
| }(), | |
| onFault: function(a) { | |
| var b = this.transmitter || new x; | |
| a = a || {}; | |
| a = { | |
| token: this.customer.token, | |
| file: a.file || a.fileName, | |
| msg: a.message || "unknown", | |
| stack: (a.stack || "unknown").substr(0, 500), | |
| url: this.window.location, | |
| v: "2.8.4", | |
| h: "5185f9f5d33a5f573259dbc513ba36f779dc37fb", | |
| x: this.util.uuid() | |
| }; | |
| b.sendTrackerFault(a) | |
| }, | |
| serialize: function(a, b) { | |
| if (this.config.current.serialize && | |
| !b) try { | |
| return this.config.current.serialize(a) | |
| } catch (c) { | |
| this.onError("catch", c, { | |
| force: !0 | |
| }) | |
| } | |
| return this.config.defaults.serialize(a) | |
| } | |
| }; | |
| p = new E(k._trackJs || k._trackJS || k._trackjs || {}, function(a, b, c, d) { | |
| return { | |
| attempt: function(a, d) { | |
| try { | |
| var f = Array.prototype.slice.call(arguments, 2); | |
| return a.apply(d || this, f) | |
| } catch (h) { | |
| throw c("catch", h), b.wrapError(h); | |
| } | |
| }, | |
| configure: function(b) { | |
| return a.setCurrent(b) | |
| }, | |
| track: function(a) { | |
| var b = d(a); | |
| a = a || {}; | |
| if (!a.stack) try { | |
| throw Error(b); | |
| } catch (f) { | |
| a = f | |
| } | |
| c("direct", a) | |
| }, | |
| watch: function(a, | |
| d) { | |
| return function() { | |
| try { | |
| var f = Array.prototype.slice.call(arguments, 0); | |
| return a.apply(d || this, f) | |
| } catch (h) { | |
| throw c("catch", h), b.wrapError(h); | |
| } | |
| } | |
| }, | |
| watchAll: function(a) { | |
| var d = Array.prototype.slice.call(arguments, 1), | |
| f; | |
| for (f in a) "function" === typeof a[f] && (b.contains(d, f) || function() { | |
| var d = a[f]; | |
| a[f] = function() { | |
| try { | |
| var a = Array.prototype.slice.call(arguments, 0); | |
| return d.apply(this, a) | |
| } catch (e) { | |
| throw c("catch", e), b.wrapError(e); | |
| } | |
| } | |
| }()); | |
| return a | |
| }, | |
| hash: "5185f9f5d33a5f573259dbc513ba36f779dc37fb", | |
| version: "2.8.4" | |
| } | |
| }, | |
| p, t, u, v, w, z, | |
| function(a) { | |
| var b = {}; | |
| return { | |
| addMetadata: function(a, d) { | |
| b[a] = d | |
| }, | |
| removeMetadata: function(a) { | |
| delete b[a] | |
| }, | |
| report: function() { | |
| var c = [], | |
| d; | |
| for (d in b) b.hasOwnProperty(d) && c.push({ | |
| key: d, | |
| value: a(b[d]) | |
| }); | |
| return c | |
| }, | |
| store: b | |
| } | |
| }, B, x, C, D, q, k, n, A); | |
| k.trackJs = p.reveal() | |
| } | |
| })(window, document); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment