-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathKojak.min.js
6 lines (5 loc) · 28.6 KB
/
Kojak.min.js
1
2
3
4
5
6
// Kojak Version 0.1.0
// Last built 2014-03-26
// Distributed Under MIT License
// (c) 2013 Bart Wood
if("contains"in String.prototype||(String.prototype.contains=function(a,b){return-1!==String.prototype.indexOf.call(this,a,b)}),window.Kojak={},Kojak.Core={CLAZZ:"CLAZZ",FUNCTION:"FUNCTION",PAKAGE:"PAKAGE",_REGEX_ALPHA:/^[A-Za-z]+$/,_uniqueId:0,extend:function(a){var b,c,d;for(b=Array.prototype.slice.call(arguments,1),c=0;c<b.length;c++)if(d=b[c])for(var e in d)a[e]=d[e];return a},getContext:function(a){var b,c,d,e;for(Kojak.Core.assert(Kojak.Core.isString(a),"getContext can only be called with a string"),e=window,b=a.split("."),c=0;c<b.length;c++){if(d=b[c],"undefined"==typeof e[d])return void 0;e=e[d]}return e},isObject:function(a){return a===Object(a)},getPropCount:function(a){return Kojak.Core.getKeys(a).length},getKeys:function(a){var b,c=[];Kojak.Core.assert(Kojak.Core.isObject(a),"Only use with objects");for(b in a)a.hasOwnProperty(b)&&c.push(b);return c},getValues:function(a){var b,c=[];Kojak.Core.assert(Kojak.Core.isObject(a),"Only use with objects");for(b in a)a.hasOwnProperty(b)&&c.push(a[b]);return c},unique:function(a){var b,c={},d=[];for(Kojak.Core.assert(Kojak.Core.isArray(a),"Only use unique with arrays"),b=0;b<a.length;b++)Kojak.Core.assert(Kojak.Core.isString(a[b]),"Only use unique with an array of strings"),c[a[b]]||(d.push(a[b]),c[a[b]]=!0);return d},inferKojakType:function(a,b){var c;return b&&Kojak.Core.isFunction(b)?(c=a.substring(0,1),Kojak.Core.isStringOnlyAlphas(c)&&c===c.toUpperCase()?Kojak.Core.CLAZZ:Kojak.Core.FUNCTION):b&&b.constructor&&b.constructor.prototype===Object.prototype?Kojak.Core.PAKAGE:void 0},getPath:function(a){return Kojak.Core.assert(a,"kPath is not defined"),a.length<3||!a.contains(".")?a:a.substring(0,a.lastIndexOf("."))},getObjName:function(a){return Kojak.Core.assert(a,"kPath is not defined"),a.length<3||!a.contains(".")?a:a.substring(a.lastIndexOf(".")+1)},getPakageName:function(a){var b;return Kojak.Core.assert(a,"kPath is not defined"),b=a.split("."),1===b.length?a:("prototype"===b[b.length-1]&&(b=b.splice(0,b.length-1)),b=b.splice(0,b.length-1),b.join("."))},getClazzName:function(a){var b,c="";return Kojak.Core.assert(a,"kPath is not defined"),b=a.split("."),1===b.length?"":("prototype"===b[b.length-1]&&(c=".prototype",b=b.splice(0,b.length-1)),b[b.length-1]+c)},isStringOnlyAlphas:function(a){return Kojak.Core.assert(Kojak.Core.isString(a,"only use with strings")),a.match(Kojak.Core._REGEX_ALPHA)},isStringArray:function(a){var b=!0;return Kojak.Core.isArray(a)?a.forEach(function(a){Kojak.Core.isString(a)||(b=!1)}):b=!1,b},assert:function(a,b){if(!a)throw b},uniqueId:function(){return++Kojak.Core._uniqueId}},["Arguments","Function","String","Number","Array","Date","RegExp","Boolean"].forEach(function(a){Kojak.Core["is"+a]=function(b){return Object.prototype.toString.call(b)==="[object "+a+"]"}}),Kojak.Config={CURRENT_VERSION:1,AUTO_START_NONE:"none",AUTO_START_IMMEDIATE:"immediate",AUTO_ON_JQUERY_LOAD:"on_jquery_load",AUTO_START_DELAYED:"delayed",_LOCAL_STORAGE_KEY:"kojak",_LOCAL_STORAGE_BACKUP_KEY:"kojak_backup",load:function(){localStorage.getItem("kojak")?this._configValues=this._loadLocalStorage():(this._configValues=this._createDefaults(),this._save())},saveBackup:function(){Kojak.Core.assert(localStorage.getItem(Kojak.Config._LOCAL_STORAGE_KEY),"kojak not defined yet in local storage"),localStorage.setItem("kojak_backup",localStorage.getItem(Kojak.Config._LOCAL_STORAGE_KEY))},restoreBackup:function(){Kojak.Core.assert(localStorage.getItem(Kojak.Config._LOCAL_STORAGE_BACKUP_KEY),"no backup existed in local storage"),localStorage.setItem(Kojak.Config._LOCAL_STORAGE_KEY,localStorage.getItem(Kojak.Config._LOCAL_STORAGE_BACKUP_KEY)),this._configValues=this._loadLocalStorage()},getAutoStartInstrumentation:function(){return this._configValues.autoStartInstrumentation},setAutoStartInstrumentation:function(a){Kojak.Core.assert(-1!==[Kojak.Config.AUTO_START_NONE,Kojak.Config.AUTO_START_IMMEDIATE,Kojak.Config.AUTO_ON_JQUERY_LOAD,Kojak.Config.AUTO_START_DELAYED].indexOf(a),"Invalid auto start option '"+a+"'."),this._configValues.autoStartInstrumentation=a,this._save(),console.log("autoStartInstrumentation updated"),Kojak.instrumentor.hasInstrumented()&&console.log("reload your browser to notice the change."),a!==Kojak.Config.AUTO_START_DELAYED||this._isAutoStartDelayValid(this.getAutoStartDelay())||(console.log("setting a default auto start delay"),this.setAutoStartDelay(4e3))},getEnableNetWatcher:function(){return this._configValues.enableNetWatcher},setEnableNetWatcher:function(a){Kojak.Core.assert(Kojak.Core.isBoolean(a),"Invalid enableNetWatcher option '"+a+"'."),this._configValues.enableNetWatcher=a,this._save(),console.log("enableNetWatcher updated"),console.log("reload your browser to notice the change.")},addIncludedPakage:function(a){Kojak.Core.assert(-1===this._configValues.includedPakages.indexOf(a),"Pakage is already included"),this._configValues.includedPakages.push(a),this._save(),console.log("includedPakages updated"),Kojak.instrumentor.hasInstrumented()&&console.log("reload your browser to notice the change")},setIncludedPakages:function(a){Kojak.Core.assert(Kojak.Core.isArray(a),"Only pass an array of strings for the included pakage names"),this._configValues.includedPakages=a,this._save(),console.log("includedPakages updated"),Kojak.instrumentor.hasInstrumented()&&console.log("reload your browser to notice the change.")},removeIncludedPakage:function(a){var b=this._configValues.includedPakages.indexOf(a);Kojak.Core.assert(-1!==b,"Pakage is not currently included."),this._configValues.includedPakages.splice(b,1),this._save(),console.log("included path removed"),Kojak.instrumentor.hasInstrumented()&&console.log("reload your browser to notice the change.")},getIncludedPakages:function(){return this._configValues.includedPakages},arePathsExcluded:function(){var a,b,c=Array.prototype.slice.call(arguments);for(a=0;a<c.length;a++)if(b=c[a],this.isPathExcluded(b))return!0;return!1},isPathExcluded:function(a){var b,c=this._configValues.excludedPaths,d=!1;for(b=0;b<c.length;b++)if(a.contains(c[b])){d=!0;break}return d},getExcludedPaths:function(){return this._configValues.excludedPaths},addExcludedPath:function(a){Kojak.Core.assert(-1===this._configValues.excludedPaths.indexOf(a),"Path is already excluded"),this._configValues.excludedPaths.push(a),this._save(),console.log("excluded paths updated"),Kojak.instrumentor.hasInstrumented()&&console.log("reload your browser to notice the change.")},removeExcludedPath:function(a){var b=this._configValues.excludedPaths.indexOf(a);Kojak.Core.assert(-1!==b,"Path is not currently excluded."),this._configValues.excludedPaths.splice(b,1),this._save(),console.log("excluded paths updated"),Kojak.instrumentor.hasInstrumented()&&console.log("reload your browser to notice the change.")},setExcludedPaths:function(a){Kojak.Core.assert(Kojak.Core.isArray(a),"Only pass an array of strings for the excluded paths"),this._configValues.excludedPaths=a,this._save(),console.log("excludePaths updated"),Kojak.instrumentor.hasInstrumented()&&console.log("reload your browser to notice the change.")},getAutoStartDelay:function(){return this._configValues.autoStartDelay},_isAutoStartDelayValid:function(a){return a>0&&1e5>a},setAutoStartDelay:function(a){Kojak.Core.assert(this._isAutoStartDelayValid(a),"The autoStartDelay option should be a valid number in milliseconds"),this._configValues.autoStartDelay=a,this._save(),console.log("set autoStartDelay to "+a+" milliseconds"),this.getAutoStartInstrumentation()!==Kojak.Config.AUTO_START_DELAYED&&console.log("warning, the auto start is not current auto delayed."),console.log("autoStartDelay updated"),Kojak.instrumentor.hasInstrumented()&&console.log("reload your browser to notice the change.")},getRealTimeFunctionLogging:function(){return this._configValues.realTimeFunctionLogging},setRealTimeFunctionLogging:function(a){Kojak.Core.assert(a===!0||a===!1,"The realTimeFunctionLogging option should be true or false"),this._configValues.realTimeFunctionLogging=a,this._save(),console.log("realTimeFunctionLogging updated"),Kojak.instrumentor.hasInstrumented()&&console.log("changes should be reflected immediately")},_save:function(){localStorage.setItem(Kojak.Config._LOCAL_STORAGE_KEY,JSON.stringify(this._configValues))},_loadLocalStorage:function(){var a=localStorage.getItem(Kojak.Config._LOCAL_STORAGE_KEY),b=JSON.parse(a);return Kojak.Core.assert(b.version,"There is no version in the item '"+Kojak.Config._LOCAL_STORAGE_KEY+"' in localStorage. It looks wrong."),this._upgradeConfig(b),b},_upgradeConfig:function(a){for(;a.version!==Kojak.Config.CURRENT_VERSION;)switch(a.version){case 1:break;case 2:break;default:throw"Unknown version found in your configuration "+config.version}},_createDefaults:function(){return{version:Kojak.Config.CURRENT_VERSION,realTimeFunctionLogging:!1,includedPakages:[],excludedPaths:[],autoStartInstrumentation:Kojak.Config.AUTO_START_NONE,enableNetWatcher:!1}}},Kojak.Formatter={makeTabs:function(a){for(var b="",c=0;a>c;c++)b+=" ";return b},appendPadding:function(a,b){for(a||(a="");a.length<b;)a+=" ";return a},number:function(a){var b,c,d,e,f="";for(b=a.toFixed(2),c=b.substring(b.indexOf(".")),d=b.replace(c,""),d=d.split("").reverse(),e=0;e<d.length;e++)f=d[e]+f,e+1<d.length&&0===(e+1)%3&&(f=","+f);return".00"===c&&(c=""),f+c},formatReport:function(a){Kojak.Core.assert(Kojak.Core.isArray(a),"Reports should be 2d string arrays"),console.table?Kojak.Formatter._formatReportUsingTable(a):Kojak.Formatter._formatReportJustText(a)},_formatReportJustText:function(a){var b,c,d,e,f,g=[];for(b=0;b<a.length;b++)for(c=a[b],e=0;e<c.length;e++)f=c[e],Kojak.Core.isNumber(f)&&(c[e]=f=Kojak.Formatter.number(f)),f+=" ",g[e]?f.length>g[e]&&(g[e]=f.length):g[e]=f.length;for(b=0;b<a.length;b++){for(c=a[b],d="",e=0;e<c.length;e++)d+=Kojak.Formatter.appendPadding(c[e],g[e]);console.log(d)}},_formatReportUsingTable:function(a){var b,c,d,e,f,g=[];if(a.length>1){for(b=a[0],c=1;c<a.length;c++){for(d=a[c],e=[],f=0;f<d.length;f++)e[b[f]]=d[f];g.push(e)}console.table(g),window.tr=g}else Kojak.Formatter._formatReportJustText(a)}},Kojak.FunctionProfile=function(a,b,c){var d=this;Kojak.Core.assert(a&&(a._kPath||""===a._kPath)&&Kojak.Core.isString(b)&&Kojak.Core.isFunction(c),"FunctionProfile constructor args are not correct"),this._container=a,this._functionName=b,this._origFunction=c,this._kPath=a._kPath+"."+b,this._startTimes=[],this._callCount=0,this._callPaths={},this._wholeTime=0,this._wholeTimes=[],this._isolatedTime=0,this._isolatedTimes=[],this.takeCheckpoint(),this._wrappedFunction=function(){var a;if(this instanceof d._wrappedFunction)throw a="Kojak Error! It looks like Kojak wrapped a function that is used as a constructor: "+d._kPath+"\n To fix this you can either rename the reference to the function to start with upper case"+"\n or you could ignore it by passing calling Kojak.Config.addExcludedPath('"+d._kPath+"')";Kojak.instrumentor.recordStartFunction(d);var b=c.apply(this,arguments);return Kojak.instrumentor.recordStopFunction(d),b},this._wrappedFunction._kFProfile=this},Kojak.Core.extend(Kojak.FunctionProfile.prototype,{getContainer:function(){return this._container},getFunctionName:function(){return this._functionName},getOrigFunction:function(){return this._origFunction},getWrappedFunction:function(){return this._wrappedFunction},getKPath:function(){return this._kPath},pushStartTime:function(a){this._startTimes.push(a)},popStartTime:function(){return this._startTimes.pop()},recordCallMetrics:function(a,b,c){this._callPaths[a]?this._callPaths[a]++:this._callPaths[a]=1,this._callCount++,this._isolatedTime+=b,this._wholeTime+=c,this._isolatedTimes.push(b),this._wholeTimes.push(c),this._isolatedTimes_checkpoint.push(b),this._wholeTimes_checkpoint.push(c)},takeCheckpoint:function(){this._callCount_checkpoint=this._callCount,this._wholeTime_checkpoint=this._wholeTime,this._isolatedTime_checkpoint=this._isolatedTime,this._wholeTimes_checkpoint=[],this._isolatedTimes_checkpoint=[]},getProperty:function(a){return this["get"+a]()},getWholeTime:function(){return this._wholeTime},getCallCount:function(){return this._callCount},getCallPaths:function(){return this._callPaths},getIsolatedTime:function(){return this._isolatedTime},getAvgIsolatedTime:function(){return this._callCount>0?this._isolatedTime/this._callCount:0},getAvgWholeTime:function(){return this._callCount>0?this._wholeTime/this._callCount:0},getMaxIsolatedTime:function(){var a=0;return this._isolatedTimes.forEach(function(b){b>a&&(a=b)}),a},getMaxWholeTime:function(){var a=0;return this._wholeTimes.forEach(function(b){b>a&&(a=b)}),a},getCallCount_Checkpoint:function(){return this._callCount-this._callCount_checkpoint},getWholeTime_Checkpoint:function(){return this._wholeTime-this._wholeTime_checkpoint},getIsolatedTime_Checkpoint:function(){return this._isolatedTime-this._isolatedTime_checkpoint},getAvgIsolatedTime_Checkpoint:function(){return this.getCallCount_Checkpoint()>0?this._isolatedTime/this.getCallCount_Checkpoint():0},getAvgWholeTime_Checkpoint:function(){return this.getCallCount_Checkpoint()>0?this._wholeTime_checkpoint/this.getCallCount_Checkpoint():0},getMaxIsolatedTime_Checkpoint:function(){var a=0;return this._isolatedTimes_checkpoint.forEach(function(b){b>a&&(a=b)}),a},getMaxWholeTime_Checkpoint:function(){var a=0;return this._wholeTimes_checkpoint.forEach(function(b){b>a&&(a=b)}),a}}),Kojak.Instrumentor=function(){this._hasInstrumented=!1,this._lastCheckpointTime=void 0,this._origFunctions={},this._functionProfiles=[],this._clazzPaths=[],this._stackLevel=-1,this._stackLevelCumTimes={},this._stackContexts=[]},Kojak.Core.extend(Kojak.Instrumentor.prototype,{instrument:function(){var a;try{Kojak.Core.assert(!this.hasInstrumented(),"The code has already been instrumented"),this._hasInstrumented=!0,a=this._findFunctionCandidates(),this._processFunctionCandidates(a),this._findUniqueClazzPaths(),console.log("Kojak has completed instrumenting. Run Kojak.Report.instrumentedCode() to see what functions have been instrumented")}catch(b){console.error("Error, Kojak instrument has failed ",b),b.stack&&console.error("Stack:\n",b.stack)}},hasInstrumented:function(){return this._hasInstrumented},getClazzPaths:function(){return this._clazzPaths},_findFunctionCandidates:function(){var a,b,c,d,e,f,g,h={};for(a=Kojak.Config.getIncludedPakages().slice(0);a.length>0;)if(b=a.pop(),c=Kojak.Core.getContext(b),!this._shouldIgnorePakage(b,c)){c._kPath=b,Object.defineProperty(c,"_kPath",{enumerable:!1});for(e in c)c.hasOwnProperty(e)&&(f=c[e],g=Kojak.Core.inferKojakType(e,f),(g===Kojak.Core.CLAZZ||g===Kojak.Core.FUNCTION)&&(this._shouldIgnoreFunction(b,e)||(f._kFid?h[f._kFid].push(b+"."+e):(f._kFid=Kojak.Core.uniqueId(),Object.defineProperty(f,"_kFid",{enumerable:!1}),this._origFunctions[f._kFid]=f,h[f._kFid]=[b+"."+e]))),g===Kojak.Core.PAKAGE?a.push(b+"."+e):g===Kojak.Core.CLAZZ&&(a.push(b+"."+e),a.push(b+"."+e+".prototype")));d=Kojak.Core.getObjName(b),Kojak.Core.inferKojakType(d,c)!==Kojak.Core.CLAZZ||c.prototype._kPath||(console.log("---found PACKAGE that is a clazz ",b),a.push(b+".prototype"))}return h},_shouldIgnorePakage:function(a,b){return b?Kojak.Core.inferKojakType(a,b)===Kojak.Core.PAKAGE&&b._kPath?(console.warn("ignored circular/duplicate package reference: ",a),!0):Kojak.Config.isPathExcluded(a):!0},_shouldIgnoreFunction:function(a,b){return Kojak.Config.arePathsExcluded(a,a+"."+b,b)},_processFunctionCandidates:function(a){var b,c,d,e;for(b in a)d=a[b],c=this._origFunctions[b],e=!1,d.forEach(function(a){this._isFuncAClazz(a)&&(e=!0)}.bind(this)),e||d.forEach(function(a){this._instrumentFunction(a,c)}.bind(this))},_isFuncAClazz:function(a){var b,c;return b=Kojak.Core.getObjName(a),c=b.substring(0,1),Kojak.Core.isStringOnlyAlphas(c)&&c===c.toUpperCase()},_instrumentFunction:function(a,b){var c,d,e,f;c=Kojak.Core.getPath(a),e=Kojak.Core.getObjName(a),d=Kojak.Core.getContext(c),d?(f=new Kojak.FunctionProfile(d,e,b),d[e]=f.getWrappedFunction(),this._functionProfiles.push(f)):console.error("Kojak error, the function path could not be located: "+a)},_findUniqueClazzPaths:function(){var a,b,c={};this._functionProfiles.forEach(function(d){a=d.getKPath(),b=Kojak.Core.getPath(a),c[b]||(c[b]=!0,this._clazzPaths.push(b))}.bind(this)),this._clazzPaths.sort()},takeCheckpoint:function(){this.hasInstrumented()||this.instrument(),this._lastCheckpointTime=Date.now(),this._functionProfiles.forEach(function(a){a.takeCheckpoint()}.bind(this))},getLastCheckpointTime:function(){return this._lastCheckpointTime},recordStartFunction:function(a){this._stackLevel++,this._stackLevelCumTimes[this._stackLevel]=0,this._stackContexts[this._stackLevel]=a.getKPath(),a.pushStartTime(Date.now()),Kojak.Config.getRealTimeFunctionLogging()&&console.log(Kojak.Formatter.makeTabs(this._stackLevel)+"start: "+a.getKPath(),Kojak.Formatter.number(a.getIsolatedTime()))},recordStopFunction:function(a){var b,c,d;this._stackLevel--,b=a.popStartTime(),c=Date.now()-b,d=c-this._stackLevelCumTimes[this._stackLevel+1],a.recordCallMetrics(this._stackContexts.join(" > "),d,c),this._stackLevelCumTimes[this._stackLevel]+=c,this._stackContexts.pop(),Kojak.Config.getRealTimeFunctionLogging()&&console.log(Kojak.Formatter.makeTabs(this._stackLevel+1)+"stop: "+a.getKPath(),Kojak.Formatter.number(a.getIsolatedTime()))},getPackageProfiles:function(){return this._packageProfiles},getFunctionProfiles:function(){return this._functionProfiles}}),Kojak.NetProfile=function(a){Kojak.Core.assert(a,"Parameters to NetProfile not set correctly"),this._urlBase=a,this._calls=[]},Kojak.Core.extend(Kojak.NetProfile.prototype,{addCall:function(a,b,c){this._calls.push(new Kojak.NetProfileCall(a,b,c))},getTotalCallTime:function(){var a=0;return this._calls.forEach(function(b){a+=b.getCallTime()}),a},getUrlBase:function(){return this._urlBase},getCallsSortedByDate:function(){return this._calls.sort(function(a,b){return b.getDate()-a.getDate()})}}),Kojak.NetProfile.parseUrl=function(a,b){var c,d,e,f;return Kojak.Core.assert(b,"UrlBase was not defined"),b.contains("?")?(c=b.substring(0,b.indexOf("?")),d=b.substring(b.indexOf("?"))):(c=b,d=""),f=c.split("/"),isNaN(parseInt(f[f.length-1],10))||(e=parseInt(f[f.length-1],10),d="/"+e+d,c=c.replace(e,"")),c+=" ["+a+"]",{urlBase:c,urlParams:d}},Kojak.NetProfileCall=function(a,b,c){Kojak.Core.assert((a||""===a)&&(b||0===b),"Parameters to NetProfile not set correctly"),this._date=Date.now(),this._urlParams=a,this._callTime=b,this._responseSize=c&&c.length?2*c.length:0;try{this._objCount=Kojak.Core.getKeys(JSON.parse(c)).length}catch(d){this._objCount=1}},Kojak.Core.extend(Kojak.NetProfileCall.prototype,{getCallTime:function(){return this._callTime},getDate:function(){return this._date},getUrlParams:function(){return this._urlParams},getResponseSize:function(){return this._responseSize},getObjCount:function(){return this._objCount}}),Kojak.NetWatcher=function(){Kojak.Core.assert(window.jQuery,"You can't use the NetWatcher unless you have included jQuery."),this._hasStarted=!1,this._netProfiles={},this._netProfiles_checkpoint={}},Kojak.Core.extend(Kojak.NetWatcher.prototype,{start:function(){Kojak.Core.assert(!this.hasStarted(),"The Net Watcher has already started."),this._hasStarted=!0,this._onAjaxSend=this._onAjaxSend.bind(this),this._onAjaxComplete=this._onAjaxComplete.bind(this),jQuery(document).ajaxSend(this._onAjaxSend),jQuery(document).ajaxComplete(this._onAjaxComplete)},hasStarted:function(){return this._hasStarted},takeCheckpoint:function(){this.hasStarted()||this.start(),this._netProfiles_checkpoint={}},_onAjaxSend:function(a,b,c){c._kStartTime=Date.now()},_onAjaxComplete:function(a,b,c){c._kStartTime?this.trackNetResponse(c.type,c.url,Date.now()-c._kStartTime,b.responseText):(console.warn("Kojak NetWatcher Warning: a web service call was not properly instrumented. ("+c.url+")"),console.warn(" This is probably because the watcher was started in the middle of a call."))},trackNetResponse:function(a,b,c,d){var e;e=Kojak.NetProfile.parseUrl(a,b),this._netProfiles[e.urlBase]||(this._netProfiles[e.urlBase]=new Kojak.NetProfile(e.urlBase)),this._netProfiles[e.urlBase].addCall(e.urlParams,c,d),this._netProfiles_checkpoint[e.urlBase]||(this._netProfiles_checkpoint[e.urlBase]=this._netProfiles[e.urlBase])},getNetProfiles:function(){return this._netProfiles},getNetProfiles_Checkpoint:function(){return this._netProfiles_checkpoint}}),Kojak.Report={instrumentedCode:function(a){var b,c,d=[],e=0,f=0;if(!Kojak.instrumentor.hasInstrumented())return console.warn("You have not ran Kojak.instrumentor.instrument() yet."),void 0;b=!a,a=a||{},a&&a.filter&&Kojak.Core.assert(Kojak.Core.isString(a.filter)||Kojak.Core.isStringArray(a.filter),"filter must be a string or an array of strings");try{console.log("Currently instrumented code in Kojak: "+(a.filter?"(filtered by '"+a.filter+"')":"")),a.verbose?d.push(["--Pakage--","--Clazz--","--Function--","--Call Count--"]):d.push(["--Pakage--","--Clazz--","--Function Count--"]),c=Kojak.instrumentor.getClazzPaths(),c.forEach(function(b){var c,g,h,i=0;c=Kojak.Core.getPakageName(b),g=Kojak.Core.getClazzName(b),(!a.filter||this._matchesAnyFilter(a.filter,b,c,g))&&(a.verbose?(h=this._getKFuncProfiles(a,b),h.forEach(function(a){d.push([c,g,a.getFunctionName(),a.getCallCount()]),i++}.bind(this))):(i=this._getFunctionCount(b),d.push([c,g,i])),f+=i,e++)}.bind(this)),d.push(["--Number of clazzes reported: "+Kojak.Formatter.number(e),"-","-"]),d.push(["--Number of functions reported: "+Kojak.Formatter.number(f),"-","-"]),a.filter&&d.push(["--Counts are based off of filter: '"+a.filter+"'","-","-"]),b&&d.push(["--Options for command {filter: ['xxx', 'yyy'], verbose: true}","-","-"]),Kojak.Formatter.formatReport(d)}catch(g){console.error("Error, Kojak.Report.instrumentedCode has failed ",g),g.stack&&console.error("Stack:\n",g.stack)}},_getFunctionCount:function(a){var b,c,d,e=0;b=Kojak.Core.getContext(a),Kojak.Core.assert(b,"The clazz could not be found: "+a);for(c in b)b.hasOwnProperty(c)&&(d=b[c],d&&d._kFProfile&&e++);return e},_getKFuncProfiles:function(a,b){var c,d,e,f=[];c=Kojak.Core.getContext(b),Kojak.Core.assert(c,"The clazz could not be found: "+b);for(d in c)c.hasOwnProperty(d)&&(e=c[d],e&&e._kFProfile&&(!a.filter||this._matchesAnyFilter(a.filter,d,e._kFProfile.getKPath()))&&f.push(e._kFProfile));return f=f.sort(function(a,b){return b.getFunctionName()-a.getFunctionName()})},funcPerf:function(a){var b,c;b=["KPath","IsolatedTime","WholeTime","CallCount","AvgIsolatedTime","AvgWholeTime","MaxIsolatedTime","MaxWholeTime"],c=["IsolatedTime","CallCount"],a||(a={}),a.sortBy||(a.sortBy="IsolatedTime"),a.max||(a.max=20),this._functionPerfProps(a,b,c)},funcPerfAfterCheckpoint:function(a){var b,c;return b=["KPath","IsolatedTime_Checkpoint","WholeTime_Checkpoint","CallCount_Checkpoint","AvgIsolatedTime_Checkpoint","AvgWholeTime_Checkpoint","MaxIsolatedTime_Checkpoint","MaxWholeTime_Checkpoint"],c=["IsolatedTime_Checkpoint","CallCount_Checkpoint"],Kojak.instrumentor.getLastCheckpointTime()?(a||(a={}),a.sortBy||(a.sortBy="IsolatedTime_Checkpoint"),a.max||(a.max=20),console.log("Results since checkpoint taken: "+new Date(Kojak.instrumentor.getLastCheckpointTime()).toString("hh:mm:ss tt")),this._functionPerfProps(a,b,c),void 0):(console.warn("You have not taken any checkpoints yet to report on. First run Kojak.takeCheckpoint() and invoke some of your code to test."),void 0)},_functionPerfProps:function(a,b,c){var d,e,f,g,h=[],i=[],j={},k=[];if(!Kojak.instrumentor.hasInstrumented())return console.warn("You have not ran Kojak.instrumentor.instrument() yet."),void 0;try{for(a.filter&&Kojak.Core.assert(Kojak.Core.isString(a.filter)||Kojak.Core.isStringArray(a.filter),"filter must be a string or an array of strings"),a.max&&Kojak.Core.assert(Kojak.Core.isNumber(a.max)&&a.max>0,"max should be a number greater than 0"),Kojak.instrumentor.getFunctionProfiles().forEach(function(b){(!a.filter||this._matchesAnyFilter(a.filter,b.getKPath()))&&h.push(b)}.bind(this)),h.sort(function(b,c){return c.getProperty(a.sortBy)-b.getProperty(a.sortBy)}),d=[],b.forEach(function(a){d.push("--"+a.replace("_Checkpoint","")+"--")}),i.push(d),e=0;e<h.length&&e<a.max;e++){for(f=h[e],d=[],g=0;g<b.length;g++)d.push(f.getProperty(b[g]));i.push(d)}Kojak.instrumentor.getFunctionProfiles().forEach(function(a){c.forEach(function(b){var c=a.getProperty(b);Kojak.Core.isNumber(c)&&(j[b]||(j[b]=0),j[b]+=c)}.bind(this))}.bind(this)),b.forEach(function(a){"KPath"===a?k.push("--Totals across all instrumented functions: "):j[a]?k.push(j[a]):k.push("-")}),i.push(k),console.log("Top "+a.max+" functions displayed sorted by "+a.sortBy+(a.filter?" based on your filter: '"+a.filter:"'")),Kojak.Formatter.formatReport(i)}catch(l){console.error("Error, Kojak.Report.funcPerf has failed ",l),l.stack&&console.error("Stack:\n",l.stack)}},callPaths:function(a){var b,c,d,e,f,g=[],h=[],i=[];if(!Kojak.instrumentor.hasInstrumented())return console.warn("You have not ran Kojak.instrumentor.instrument() yet."),void 0;b=Kojak.Core.isString(a)?Kojak.Core.getContext(a):a,Kojak.Core.assert(b,"Function not found."),c=b._kFProfile,Kojak.Core.assert(c,"Function profile not found. Are you sure it was included to be profiled?"),d=c.getCallPaths();for(e in d)f=d[e],g.push({path:e,count:f});g=g.sort(function(a,b){return b.count-a.count}),h.push(["--Call Count--","--Call Path--"]),g.forEach(function(a){h.push([a.count,a.path])}.bind(this)),Kojak.Formatter.formatReport(h),console.log(),i.push(["IsolatedTime: ",c.getIsolatedTime()]),i.push(["WholeTime: ",c.getWholeTime()]),i.push(["CallCount: ",c.getCallCount()]),Kojak.Formatter.formatReport(i),console.log("\n Remember, only profiled functions show up in call paths."),console.log(" Anonymous functions with no references are never profiled.")},netCalls:function(){this._netCalls(Kojak.netWatcher.getNetProfiles())},netCallsAfterCheckpoint:function(){this._netCalls(Kojak.netWatcher.getNetProfiles_Checkpoint())},_netCalls:function(a){var b,c,d=[],e=[];if(!Kojak.netWatcher)return console.warn("The NetWatcher is not loaded. Have you set Kojak.Config.setEnableNetWatcher(true)?"),void 0;for(b in a)c=a[b],d.push({totalCallTime:c.getTotalCallTime(),netProfile:c});d=d.sort(function(a,b){return b.totalCallTime-a.totalCallTime}),e.push(["--urlBase--","--urlParameters--","--When Called--","--Call Time--","--Size (bytes)--","--Obj Count--"]),d.forEach(function(a){var b=!1;a.netProfile.getCallsSortedByDate().forEach(function(c){var d=[];b?d.push(""):(d.push(a.netProfile.getUrlBase()),b=!0),d.push(c.getUrlParams()),d.push(new Date(c.getDate()).toString("hh:mm:ss tt")),d.push(c.getCallTime()),d.push(c.getResponseSize()),d.push(c.getObjCount()),e.push(d)})}),Kojak.Formatter.formatReport(e)},randomKojakQuote:function(){var a=["Who loves ya, baby?","Counselor, you tell your client to make his mouth behave, or he's a prime candidate for a get well card.","Greeks don't threaten. They utter prophecies.","Dumb got him killed. Dead is not guts. Dead is dumb."];return a[Math.floor(Math.random()*a.length)]},_matchesAnyFilter:function(a){var b,c;return b=!1,c=Array.prototype.slice.call(arguments,1),Kojak.Core.isString(a)&&(a=[a]),Kojak.Core.assert(Kojak.Core.isArray(a),"filter should be a string or an array of strings"),a.forEach(function(a){c.forEach(function(c){c.contains(a)&&(b=!0)})}),b}},!Object&&Object.defineProperty)throw"Kojak requires the function Object.defineProperty";switch(Kojak.Config.load(),Kojak.instrumentor=new Kojak.Instrumentor,Kojak.Config.getAutoStartInstrumentation()){case Kojak.Config.AUTO_START_IMMEDIATE:console.log("Running Kojak.instrumentor.instrument() immediately. Kojak should have been the last included JavaScript code in the browser for this to work."),Kojak.instrumentor.instrument();break;case Kojak.Config.AUTO_ON_JQUERY_LOAD:window.jQuery&&window.jQuery.ready?jQuery(document).ready(function(){console.log("Running Kojak.instrumentor.instrument() in the jQuery.ready handler."),Kojak.instrumentor.instrument()}):console.log("Kojak autoStart set to Kojak.Config.AUTO_ON_JQUERY_LOAD but jQuery was not found.\nDid you forget to include jQuery?");break;case Kojak.Config.AUTO_START_DELAYED:setTimeout(function(){console.log("Running Kojak.instrumentor.instrument() after the auto delay of "+Kojak.Formatter.number(Kojak.Config.getAutoStartDelay())+" milliseconds."),Kojak.instrumentor.instrument()},Kojak.Config.getAutoStartDelay())}Kojak.Config.getEnableNetWatcher()&&(Kojak.netWatcher=new Kojak.NetWatcher,Kojak.netWatcher.start()),window.kConfig?console.warn("Warning, the window.kConfig variable already existed. Kojak shortcut will not exist."):window.kConfig=Kojak.Config,window.kInst?console.warn("Warning, the window.kInst variable already existed. Kojak shortcut will not exist."):window.kInst=Kojak.instrumentor,Kojak.netWatcher&&(window.kNetWatch?console.warn("Warning, the window.kNetWatch variable already existed. Kojak shortcut will not exist."):window.kNetWatch=Kojak.instrumentor),window.kRep?console.warn("Warning, the window.kRep variable already existed. Kojak shortcut will not exist."):window.kRep=Kojak.Report;