You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3745 lines
336 KiB

5 years ago
// jquery-1.8.0.min.js
/*! jQuery v@1.8.0 jquery.com | jquery.org/license */
(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bX(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bV.length;while(e--){b=bV[e]+c;if(b in a)return b}return d}function bY(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function bZ(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bY(c)&&(e[f]=p._data(c,"olddisplay",cb(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b$(a,b,c){var d=bO.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function b_(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bU[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bU[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bU[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bU[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bU[e]+"Width"))||0));return f}function ca(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bP.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+b_(a,b,c||(f?"border":"content"),e)+"px"}function cb(a){if(bR[a])return bR[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();
// uritemplate.min.js
if (!window.UriTemplate) {
!function(e){"use strict";function t(e){var n;if(null===e||void 0===e)return!1;if(r.isArray(e))return e.length>0;if("string"==typeof e||"number"==typeof e||"boolean"==typeof e)return!0;for(n in e)if(e.hasOwnProperty(n)&&t(e[n]))return!0;return!1}var n=function(){function e(e){this.options=e}return e.prototype.toString=function(){return JSON&&JSON.stringify?JSON.stringify(this.options):this.options},e}(),r=function(){function e(e){return"[object Array]"===Object.prototype.toString.apply(e)}function t(e){return"[object String]"===Object.prototype.toString.apply(e)}function n(e){return"[object Number]"===Object.prototype.toString.apply(e)}function r(e){return"[object Boolean]"===Object.prototype.toString.apply(e)}function i(e,t){var n,r="",i=!0;for(n=0;n<e.length;n+=1)i?i=!1:r+=t,r+=e[n];return r}function o(e,t){for(var n=[],r=0;r<e.length;r+=1)n.push(t(e[r]));return n}function s(e,t){for(var n=[],r=0;r<e.length;r+=1)t(e[r])&&n.push(e[r]);return n}function a(e){if("object"!=typeof e||null===e)return e;Object.freeze(e);var t,n;for(n in e)e.hasOwnProperty(n)&&(t=e[n],"object"==typeof t&&u(t));return e}function u(e){return"function"==typeof Object.freeze?a(e):e}return{isArray:e,isString:t,isNumber:n,isBoolean:r,join:i,map:o,filter:s,deepFreeze:u}}(),i=function(){function e(e){return e>="a"&&"z">=e||e>="A"&&"Z">=e}function t(e){return e>="0"&&"9">=e}function n(e){return t(e)||e>="a"&&"f">=e||e>="A"&&"F">=e}return{isAlpha:e,isDigit:t,isHexDigit:n}}(),o=function(){function e(e){var t,n,r="",i=s.encode(e);for(n=0;n<i.length;n+=1)t=i.charCodeAt(n),r+="%"+t.toString(16).toUpperCase();return r}function t(e,t){return"%"===e.charAt(t)&&i.isHexDigit(e.charAt(t+1))&&i.isHexDigit(e.charAt(t+2))}function n(e,t){return parseInt(e.substr(t,2),16)}function r(e){if(!t(e,0))return!1;var r=n(e,1),i=s.numBytes(r);if(0===i)return!1;for(var o=1;i>o;o+=1)if(!t(e,3*o)||!s.isValidFollowingCharCode(n(e,3*o+1)))return!1;return!0}function o(e,r){var i=e.charAt(r);if(!t(e,r))return i;var o=n(e,r+1),a=s.numBytes(o);if(0===a)return i;for(var u=1;a>u;u+=1)if(!t(e,r+3*u)||!s.isValidFollowingCharCode(n(e,r+3*u+1)))return i;return e.substr(r,3*a)}var s={encode:function(e){return unescape(encodeURIComponent(e))},numBytes:function(e){return 127>=e?1:e>=194&&223>=e?2:e>=224&&239>=e?3:e>=240&&244>=e?4:0},isValidFollowingCharCode:function(e){return e>=128&&191>=e}};return{encodeCharacter:e,isPctEncoded:r,pctCharAt:o}}(),s=function(){function e(e){return i.isAlpha(e)||i.isDigit(e)||"_"===e||o.isPctEncoded(e)}function t(e){return i.isAlpha(e)||i.isDigit(e)||"-"===e||"."===e||"_"===e||"~"===e}function n(e){return":"===e||"/"===e||"?"===e||"#"===e||"["===e||"]"===e||"@"===e||"!"===e||"$"===e||"&"===e||"("===e||")"===e||"*"===e||"+"===e||","===e||";"===e||"="===e||"'"===e}return{isVarchar:e,isUnreserved:t,isReserved:n}}(),a=function(){function e(e,t){var n,r="",i="";for(("number"==typeof e||"boolean"==typeof e)&&(e=e.toString()),n=0;n<e.length;n+=i.length)i=e.charAt(n),r+=s.isUnreserved(i)||t&&s.isReserved(i)?i:o.encodeCharacter(i);return r}function t(t){return e(t,!0)}function n(e,t){var n=o.pctCharAt(e,t);return n.length>1?n:s.isReserved(n)||s.isUnreserved(n)?n:o.encodeCharacter(n)}function r(e){var t,n="",r="";for(t=0;t<e.length;t+=r.length)r=o.pctCharAt(e,t),n+=r.length>1?r:s.isReserved(r)||s.isUnreserved(r)?r:o.encodeCharacter(r);return n}return{encode:e,encodePassReserved:t,encodeLiteral:r,encodeLiteralCharacter:n}}(),u=function(){function e(e){t[e]={symbol:e,separator:"?"===e?"&":""===e||"+"===e||"#"===e?",":e,named:";"===e||"&"===e||"?"===e,ifEmpty:"&"===e||"?"===e?"=":"",first:"+"===e?"":e,encode:"+"===e||"#"===e?a.encodePassReserved:a.encode,toString:function(){return this.symbol}}}var t={};return e(""),e("+"),e("#"),e("."),e("/"),e(";"),e("?"),e("&"),{valueOf:function(e){return t[e]?t[e]:"=,!@|".indexOf(e)>=0?null:t[""]}}}(),f=function(){function e(e){this.literal=a.encodeLiteral(e)}return e.prototype.expand=function(){return this.literal},e.prototype.toString=e.prototype.expand,e}(),p=function(){function e(e){function t(){var t=e.substring(h,f);if(0===t.leng
}
// glimpse.jquery.draggable.js
(function ($) {
var defaults = {
min: 50,
isUpDown: true,
valueStyle: 'height',
offset: -1,
getDimension: function() { return parseInt(this.resizeScope.css(this.valueStyle)); },
setDimension: function(value) { return this.resizeScope.css(this.valueStyle, value + 'px'); }
},
mousePosition = function(e) {
return e.data.settings.isUpDown ? e.clientY : e.clientX;
},
startDrag = function(e) {
var settings = e.data.settings;
if ($.isFunction(settings.dragging))
settings.dragging(settings);
settings._min = $.isFunction(settings.min) ? settings.min(settings) : settings.min;
settings._max = $.isFunction(settings.max) ? settings.max(settings) : settings.max;
settings._startMousePosition = mousePosition(e);
settings._startDimension = settings.getDimension.call(settings);
settings.opacityScope.css('opacity', 0.50);
$(document).bind('mousemove', { settings: settings }, performDrag).bind('mouseup', { settings: settings }, endDrag);
return false;
},
endDrag = function(e) {
var settings = e.data.settings;
settings.opacityScope.css('opacity', 1);
$(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag);
if ($.isFunction(settings.dragged))
settings.dragged(settings, settings.getDimension.call(settings));
return false;
},
performDrag = function (e) {
var settings = e.data.settings,
newDimension = settings._startDimension + ((mousePosition(e) - settings._startMousePosition) * settings.offset);
if (settings._min != null)
newDimension = Math.max(settings._min, newDimension);
if (settings._max != null)
newDimension = Math.min(settings._max, newDimension);
settings.setDimension.call(settings, newDimension);
return false;
};
$.draggable = function(settings) {
settings = $.extend(true, {}, defaults, settings);
settings.handelScope.bind("mousedown", { settings: settings }, startDrag);
return this;
};
})(jQueryGlimpse);
// glimpse.jquery.draggable.js
(function ($) {
$.fn.dropdown = function() {
var scope = $(this);
scope.find('.glimpse-drop').live('mouseenter', function() {
$(this).next().css('left', $(this).position().left).show();
});
scope.find('.glimpse-drop-over').live('mouseleave', function() {
$(this).fadeOut(100);
});
return scope;
};
})(jQueryGlimpse);
// glimpse.core.js
glimpse = (function($) {
return {};
})(jQueryGlimpse);
// glimpse.pubsub.js
glimpse.pubsub = (function() {
var messages = {},
lastUid = -1,
throwException = function(ex) {
return function() {
throw ex;
};
},
callSubscriber = function(subscriber, message, data) {
try {
subscriber(data, message);
} catch(ex) {
setTimeout(throwException(ex), 0);
}
},
deliverMessage = function(originalMessage, matchedMessage, data) {
var subscribers = messages[matchedMessage],
i, j;
if (!messages.hasOwnProperty(matchedMessage)) {
return;
}
for (i = 0, j = subscribers.length; i < j; i++) {
callSubscriber(subscribers[i].func, originalMessage, data);
}
},
createDeliveryFunction = function(message, data) {
return function() {
var topic = String(message),
position = topic.lastIndexOf('.');
// deliver the message as it is now
deliverMessage(message, message, data);
// trim the hierarchy and deliver message to each level
while (position !== -1) {
topic = topic.substr(0, position);
position = topic.lastIndexOf('.');
deliverMessage(message, topic, data);
}
};
},
messageHasSubscribers = function(message) {
var topic = String(message),
found = messages.hasOwnProperty(topic),
position = topic.lastIndexOf('.');
while (!found && position !== -1) {
topic = topic.substr(0, position);
position = topic.lastIndexOf('.');
found = messages.hasOwnProperty(topic);
}
return found;
},
publish = function(message, data, sync) {
var deliver = createDeliveryFunction(message, data),
hasSubscribers = messageHasSubscribers(message);
if (!hasSubscribers) {
return false;
}
if (sync === true) {
deliver();
} else {
setTimeout(deliver, 0);
}
return true;
};
return {
publishAsync: function(message, data) {
return publish(message, data, false);
},
publish: function(message, data) {
return publish(message, data, true);
},
subscribe: function(message, func) {
// message is not registered yet
if (!messages.hasOwnProperty(message)) {
messages[message] = [];
}
// forcing token as String, to allow for future expansions without breaking usage
// and allow for easy use as key names for the 'messages' object
var token = String(++lastUid);
messages[message].push({ token: token, func: func });
// return token for unsubscribing
return token;
},
unsubscribe: function(tokenOrFunction) {
var isToken = typeof tokenOrFunction === 'string',
key = isToken ? 'token' : 'func',
succesfulReturnValue = isToken ? tokenOrFunction : true,
result = false,
m, i;
for (m in messages) {
if (messages.hasOwnProperty(m)) {
for (i = messages[m].length - 1; i >= 0; i--) {
if (messages[m][i][key] === tokenOrFunction) {
messages[m].splice(i, 1);
result = succesfulReturnValue;
// tokens are unique, so we can just return here
if (isToken) {
return result;
}
}
}
}
}
return result;
}
};
})();
// glimpse.util.js
glimpse.util = (function($) {
var connectionNotice = function(scope) {
var that = (this === window) ? {} : this;
that.scope = scope;
that.text = scope.find('span');
return that;
};
connectionNotice.prototype = {
connected : false,
prePoll : function () {
var that = this;
if (!that.connected) {
that.text.text('Connecting...');
that.scope.removeClass('glimpse-connect').addClass('glimpse-disconnect');
}
},
complete : function (textStatus) {
var that = this;
if (textStatus != "success") {
that.connected = false;
that.text.text('Disconnected...');
that.scope.removeClass('glimpse-connect').addClass('glimpse-disconnect');
}
else {
that.connected = true;
that.text.text('Connected...');
that.scope.removeClass('glimpse-disconnect').addClass('glimpse-connect');
}
}
};
return {
cookie : function (key, value, days) {
if (arguments.length > 1) {
value = $.isPlainObject(value) ? JSON.stringify(value) : String(value);
var date = new Date();
date.setDate(date.getDate() + days || 1000);
document.cookie = key + "=" + encodeURIComponent(value) + "; expires=" + date.toGMTString() + "; path=/";
return;
}
key += "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ')
c = c.substring(1, c.length);
if (c.indexOf(key) == 0)
return JSON.parse(decodeURIComponent(c.substring(key.length, c.length)));
}
},
localStorage: function (key, value) {
if (arguments.length == 1)
return JSON.parse(localStorage.getItem(key));
localStorage.setItem(key, JSON.stringify(value));
},
htmlEncode: function (value) {
return !(value == null) ? value.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;') : '';
},
preserveWhitespace: function (value) {
if (value != null && typeof value !== "string")
value = value.toString();
if (!value)
return '';
return value.replace(/\r\n/g, '<br />').replace(/\n/g, '<br />').replace(/\t/g, '&nbsp; &nbsp; ').replace(/ /g, '&nbsp; ');
},
lengthJson: function (data) {
var count = 0;
if (data === Object(data))
for (var key in data) { count++; };
return count;
},
uriTemplate: function (uri, data) {
if (uri == null)
return '';
return UriTemplate.parse(uri).expand(data || {});
},
getDomain: function (uri) {
if (uri.indexOf('://') > -1)
uri = uri.split('://')[1];
return uri.split('/')[0];
},
sortTabs: function (data) {
var sorted = {},
i, temp = [];
for (i in data)
temp.push({ id: i, name: data[i].name });
temp.sort(function(a, b) {
return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
});
for (i = 0; i < temp.length; i++)
sorted[temp[i].id] = data[temp[i].id];
return sorted;
},
containsTokens: function(formatString) {
return formatString != null && !$.isNumeric(formatString) && formatString.indexOf('{{') > -1;
},
getTokens: function(formatString) {
var count = 0, working = '', result = [];
for (var i = 0; i < formatString.length; i++) {
var x = formatString[i];
if (count <= 2) {
if (x == '{')
count++;
else if (x == '}' && count > 0)
count--;
else if (count == 2)
working += '' + x;
else {
count = 0;
working = '';
}
if (count == 0 && working != '') {
result.push(working);
working = '';
}
}
}
return result;
},
connectionNotice: function(scope) {
return new connectionNotice(scope);
},
timeConvert : function(value) {
if (value < 1000)
return value.toFixed(1) + ' ms';
return Math.round(value / 10) / 100 + ' s';
}
};
})(jQueryGlimpse);
// glimpse.settings.js
glimpse.settings = (function($, pubsub, util) {
var globalSettings = {},
localStorage = {},
init = function () {
globalSettings = $.extend({}, util.cookie('glimpseOptions'));
localStorage = $.extend({}, util.localStorage('glimpseOptions'));
$(window).bind('storage', function(e) {
if (e.originalEvent.key == 'glimpseOptions')
localStorage = JSON.parse(e.originalEvent.newValue);
});
};
pubsub.subscribe('trigger.system.init', init);
return {
global: function (key, value) {
if (arguments.length == 1)
return globalSettings[key];
globalSettings[key] = value;
util.cookie('glimpseOptions', globalSettings);
},
local: function (key, value) {
if (arguments.length == 1)
return localStorage[key];
localStorage[key] = value;
util.localStorage('glimpseOptions', localStorage);
}
};
})(jQueryGlimpse, glimpse.pubsub, glimpse.util);
// glimpse.data.js
glimpse.data = (function($, pubsub, util) {
var innerBaseMetadata = { plugins : {}, resources : {} },
innerBaseData = { data : {}, metadata : innerBaseMetadata, uri : window.location.href },
innerCurrentData = innerBaseData,
generateRequestAddress = function (requestId) {
var current = currentMetadata();
return util.uriTemplate(current.resources.glimpse_request, { 'requestId': requestId, 'hash': current.hash });
},
validateMetadata = function () {
// Make sure that out data has metadata
if (!innerCurrentData.metadata)
innerCurrentData.metadata = { plugins : {} };
// Merge metadata from the base metadata, with the request metadata
var newMetadata = {};
$.extend(true, newMetadata, innerBaseMetadata, innerCurrentData.metadata);
innerCurrentData.metadata = newMetadata;
// Make sure that every plugin has metadata object
for (var key in innerCurrentData.data) {
if (!innerCurrentData.metadata.plugins[key])
innerCurrentData.metadata.plugins[key] = {};
}
},
copyPermanentData = function (newData) {
for (var key in innerBaseData.data) {
var current = innerBaseData.data[key];
if (current.isPermanent) {
newData.data[key] = current;
newData.metadata.plugins[key] = innerBaseData.metadata.plugins[key];
}
}
},
baseData = function () {
return innerBaseData;
},
currentData = function () {
return innerCurrentData;
},
currentMetadata = function () {
return innerCurrentData.metadata;
},
update = function (data, topic) {
var oldData = innerCurrentData;
pubsub.publish('action.data.refresh.changing', { oldData: oldData, newData: data, type: topic });
pubsub.publish('action.data.changing', { newData: data });
innerCurrentData = data;
validateMetadata();
copyPermanentData(data);
pubsub.publish('action.data.changed', { newData: data });
pubsub.publish('action.data.refresh.changed', { oldData: oldData, newData: data, type: topic });
pubsub.publish('trigger.system.update');
pubsub.publish('trigger.data.update');
},
reset = function () {
update(innerBaseData);
},
retrieve = function (requestId, topic) {
var parsedTopic = topic ? '.' + topic : '';
pubsub.publish('action.data.retrieve.starting' + parsedTopic, { requestId: requestId });
// Only need to do to the server if we dont have the data
if (requestId != innerBaseData.requestId) {
pubsub.publish('action.data.fetching' + parsedTopic, requestId);
$.ajax({
type: 'GET',
url: generateRequestAddress(requestId),
contentType: 'application/json',
success: function (result) {
pubsub.publish('action.data.fetched' + parsedTopic, { requestId: requestId, oldData: innerCurrentData, newData: result });
pubsub.publish('action.data.retrieve.succeeded' + parsedTopic, { requestId: requestId, oldData: innerCurrentData, newData: result });
update(result, topic);
},
complete: function (jqXhr, textStatus) {
pubsub.publish('action.data.retrieve.completed' + parsedTopic, { requestId: requestId, textStatus: textStatus });
}
});
}
else {
pubsub.publish('action.data.retrieve.succeeded' + parsedTopic, { requestId: requestId, oldData: innerCurrentData, newData: innerBaseData });
update(innerBaseData);
pubsub.publish('action.data.retrieve.completed' + parsedTopic, { requestId: requestId, textStatus: 'success' });
}
},
initMetadata = function (input) {
pubsub.publish('action.data.metadata.changing', { metadata: input });
innerBaseMetadata = input;
pubsub.publish('action.data.metadata.changed', { metadata: input });
},
initData = function (input) {
pubsub.publish('action.data.initial.changing', { newData: input });
pubsub.publish('action.data.changing', { newData: input });
innerCurrentData = input;
innerBaseData = input;
validateMetadata();
pubsub.publish('action.data.changed', { newData: input, metadata: input.metadata });
pubsub.publish('action.data.initial.changed', { newData: input, metadata: input.metadata });
pubsub.publish('trigger.data.init', { isInitial: true });
};
return {
baseData: baseData,
currentData: currentData,
currentMetadata: currentMetadata,
update: update,
reset: reset,
retrieve: retrieve,
initMetadata: initMetadata,
initData: initData
};
})(jQueryGlimpse, glimpse.pubsub, glimpse.util);
// glimpse.element.js
glimpse.elements = (function($) {
var scope = $(document),
holder, opener, pageSpacer, barHolder, panelHolder, tabHolder, tabInstanceHolder, tabPermanentHolder, titleHolder, notificationHolder, lightbox, optionsHolder;
return {
scope: function () {
return scope;
},
holder: function () {
return holder || (holder = scope.find('.glimpse-holder'));
},
opener: function () {
return opener || (opener = scope.find('.glimpse-open'));
},
pageSpacer: function () {
return pageSpacer || (pageSpacer = scope.find('.glimpse-spacer'));
},
barHolder: function () {
return barHolder || (barHolder = scope.find('.glimpse-bar'));
},
titleHolder: function () {
return titleHolder || (titleHolder = scope.find('.glimpse-title'));
},
tabHolder: function() {
return tabHolder || (tabHolder = scope.find('.glimpse-tabs ul'));
},
tabInstanceHolder: function() {
return tabInstanceHolder || (tabInstanceHolder = scope.find('.glimpse-tabs-instance ul'));
},
tabPermanentHolder: function() {
return tabPermanentHolder || (tabPermanentHolder = scope.find('.glimpse-tabs-permanent ul'));
},
panelHolder: function() {
return panelHolder || (panelHolder = scope.find('.glimpse-panel-holder'));
},
notificationHolder: function() {
return notificationHolder || (notificationHolder = scope.find('.glimpse-notification-holder'));
},
lightbox: function() {
return lightbox || (lightbox = scope.find('.glimpse-lightbox'));
},
panel: function(key) {
return this.panelHolder().find('.glimpse-panel[data-glimpseKey="' + key + '"]');
},
tab: function(key) {
return this.tabHolder().find('.glimpse-tab[data-glimpseKey="' + key + '"]');
},
panels: function() {
return this.panelHolder().find('.glimpse-panel');
},
optionsHolder: function() {
return optionsHolder || (optionsHolder = scope.find('.glimpse-options'));
}
};
})(jQueryGlimpse);
// glimpse.system.js
(function(pubsub) {
var start = function() {
pubsub.publish('trigger.system.init');
pubsub.publish('action.system.starting');
pubsub.publish('trigger.shell.init');
pubsub.publish('action.system.started');
pubsub.publish('trigger.system.ready');
},
dataStart = function() {
pubsub.publish('trigger.tab.render', { isInitial: true });
pubsub.publish('trigger.title.render');
},
update = function() {
pubsub.publish('trigger.system.refresh');
pubsub.publish('trigger.shell.refresh');
},
dataUpdate = function() {
pubsub.publish('trigger.tab.render', { isInitial: false });
pubsub.publish('trigger.title.render');
};
pubsub.subscribe('trigger.system.start', start);
pubsub.subscribe('trigger.data.init', dataStart);
pubsub.subscribe('trigger.system.update', update);
pubsub.subscribe('trigger.data.update', dataUpdate);
})(glimpse.pubsub);
// glimpse.render.js
glimpse.render = (function($, pubsub, util, data, settings) {
var templates = {
css: '.glimpse, .glimpse *, .glimpse a, .glimpse td, .glimpse th, .glimpse table {font-family: "Segoe UI Light", "Segoe UI Web Regular", "Segoe UI", "Helvetica Neue", Helvetica, Arial;background-color: transparent;border: 0px;text-align: left;padding: 0;margin: 0;-moz-box-sizing: content-box;-webkit-box-sizing: content-box;box-sizing: content-box;}.glimpse table {min-width: 0;border-collapse: collapse;border-spacing: 0;}.glimpse a, .glimpse a:hover, .glimpse a:visited, .glimpse-link {color: #2200C1;text-decoration: underline;font-weight: normal;cursor: pointer;-webkit-transition: color 0.3s ease;-moz-transition: color 0.3s ease;-o-transition: color 0.3s ease;transition: color 0.3s ease;}.glimpse a:active, .glimpse-link:active {color: #c11;text-decoration: underline;font-weight: normal;}.glimpse th {font-weight: bold;} .glimpse-open {z-index: 100010;position: fixed;right: 0;bottom: 0;height: 34px;min-width: 54px;background: #3c454f;color: #fff;white-space: nowrap;}.glimpse-open td, .glimpse-open span, .glimpse-open div {color: #fff;font-size: 13px;line-height: 13px;}.glimpse-icon {cursor: pointer;background: url() no-repeat -127px -38px;height: 30px;width: 39px;margin: 0 8px;}.glimpse-open .glimpse-icon {height: 34px;}.glimpse-holder {display: none;z-index: 100010 !important;height: 0;position: fixed;bottom: 0;left: 0;width: 100%;background-color: #fff;-moz-box-shadow: 0 0 5px #888;-webkit-box-shadow: 0 0 5px#888;box-shadow: 0 0 5px #888;}.glimpse-content {position: relative;font-size: 11px;line-height: 13px;}.glimpse-bar {background: #3c454f;color: #fff;height: 30px;position: relative;font-size: 13px;line-height: 15px;}.glimpse-bar .glimpse-icon {margin-left: 10px;float: left;}.glimpse-bar .glimpse-link, .glimpse-bar a, .glimpse-bar a:visited, .glimpse-bar a:hover {color: #fff;}.glimpse-bar .glimpse-link:active, .glimpse-bar a:active {color: #c11; } .glimpse-buttons {text-align: right;position: absolute;right: 0;top: 0;height: 17px;width: 250px;padding: 8px 12px 6px 6px;}.glimpse-hidden {display: none;}.glimpse-title {margin: 1px 0 0 15px;padding-top: 5px;font-weight: bold;display: inline-block;width: 75%;overflow: hidden;font-size: 13px;line-height: 15px;}.glimpse-title .glimpse-snapshot-name {display: inline-block;height: 20px;}.glimpse-title .glimpse-snapshot-path {font-weight:normal;} .glimpse-title .glimpse-enviro {padding-left: 10px;white-space: nowrap;height: 20px;}.glimpse-title .glimpse-correlation .glimpse-drop {padding-left: 10px;}.glimpse-title .glimpse-correlation .loading {margin: 5px 0 0;font-weight: normal;display: none;}.glimpse-title .glimpse-correlation .glimpse-drop-over {padding-left: 20px;padding-right: 20px;text-align: center;}.glimpse-title .glimpse-context-stack .glimpse-selectable {cursor:pointer;font-weight:bold;}.glimpse-drop {padding: 0 1px 0 8px;height: 16px;font-size: 12px;}.glimpse-drop, .glimpse-drop-over {font-weight: normal;background: #8bc441;margin: 0 5px 0 0;display: inline-block;}.glimpse-drop-over {position: absolute;display: none;top: 6px;padding: 1px 20px 10px 20px;z-index: 100; }.glimpse-drop-over div {text-align: center;font-weight: bold;margin: 5px 0;}.glimpse-drop-arrow-holder {margin: 3px 3px 3px 5px;padding-left: 3px;border-left: 1px solid #5f9a26;font-size: 9px;line-height: 11px;height: 9px;width: 10px;}.glimpse-drop-arrow {background: url() no-repeat -22px -18px;width: 7px;height: 4px;display: inline-block;}.glimpse .glimpse-button, .glimpse .glimpse-button:hover {cursor: pointer;background-image: url();background-repeat: no-repeat;height: 14px;width: 14px;margin-left: 10px;display: inline-block;}.glimpse .glimpse-meta-warning {background-position: -168px -1px;display: none;}.glimpse .glimpse-meta-warning:hover {background-position: -183px -1px;}.glimpse .glimpse-meta-help {background-position: -138px -1px;margin-right: 15px;}.glimpse .glimpse-meta-help:hover {background-position: -153px -1px;margin-right: 15px;}.glimpse .glimpse-meta-update {position: absolute;text-decoration: underline;top: 6px;left: 0;cursor: pointer;display: none;} .glimpse .glimpse-minim
html: '<div class=" glimpse"><div class="glimpse-spacer"></div><div class="glimpse-open glimpse"><div class="glimpse-icon"></div></div><div class="glimpse-holder glimpse"><div class="glimpse-notification-holder"></div><div class="glimpse-resizer"></div><div class="glimpse-bar"><div class="glimpse-icon" title="About Glimpse?"></div><div class="glimpse-title"><span class="glimpse-snapshot-name"></span><span class="glimpse-snapshot-path"></span><span><span class="glimpse-enviro"></span><span class="glimpse-context-stack"></span><span class="glimpse-uri"></span><span class="glimpse-correlation"></span></span></div><div class="glimpse-buttons"><span class="glimpse-meta-update" href="#" title="New Updates are available, take a look at what you are missing.">New update available!</span><a class="glimpse-meta-warning glimpse-button" href="#" title="Glimpse has some warnings!"></a><a class="glimpse-meta-help glimpse-button" href="#" title="Need some help?" target="_blank"></a><a class="glimpse-minimize glimpse-button" href="#" title="Close/Minimize"></a><a class="glimpse-popout glimpse-button glimpse-hidden" href="#" title="Pop Out"></a><a class="glimpse-close glimpse-button" href="#" title="Shutdown/Terminate"></a></div></div><div class="glimpse-content"><div class="glimpse-tabs glimpse-tabs-instance"><ul></ul></div><div class="glimpse-tabs glimpse-tabs-permanent"><ul></ul></div><div class="glimpse-panel-holder"><div class="glimpse-panel glimpse-active"><div class="glimpse-panel-message">No data has been found. This could be caused because:<br /><br />- the data is still loading by the client, or<br />- no data has been received from the server (check to see if the data &amp; metadata payloads are present), or<br />- no plugin has been loaded, or<br />- an error has been thrown in the client (please check your JavaScript console and let us know if anything is up).</div></div></div><div class="glimpse-options"></div></div></div><div class="glimpse-lightbox"><div class="glimpse-lightbox-inner"><div class="glimpse-lightbox-element"></div></div></div>'
},
generateSpriteAddress = function () {
var uri = settings.local('sprite') || 'http://getglimpse.com/content/_v1/app-sprite-new.png?version={version}',
version = settings.local('version') || '0.0',
hash = settings.local('hash') || '0.0';
return util.uriTemplate(uri, { 'version': version, 'hash': hash });
},
updateSpriteAddress = function (args) {
var uri = args.metadata.resources.glimpse_sprite,
version = args.metadata.version,
hash = args.metadata.hash;
if (uri)
settings.local('sprite', uri);
if (version)
settings.local('version', version);
if (hash)
settings.local('hash', hash);
},
getCss = function() {
var content = templates.css.replace(/url\(\)/gi, 'url(' + generateSpriteAddress() + ')');
return '<style type="text/css"> ' + content + ' </style>';
},
getHtml = function() {
return templates.html;
},
process = function(isInitial, topic) {
pubsub.publish(topic + '.rendering', { isInitial: isInitial });
pubsub.publish('action.shell.rendering', { isInitial: isInitial });
pubsub.publish('action.shell.rendered', { isInitial: isInitial });
pubsub.publish(topic + '.rendered', { isInitial: isInitial });
},
refresh = function() {
pubsub.publish('trigger.shell.clear');
process(false, 'action.shell.refresh');
},
init = function() {
pubsub.publish('action.template.processing', { templates: templates });
pubsub.publish('action.shell.loading');
$(getCss()).appendTo('head');
$(getHtml()).appendTo('body');
pubsub.publish('action.shell.loaded');
pubsub.publish('action.template.processed', { templates: templates });
pubsub.publish('trigger.shell.subscriptions');
process(true, 'action.shell.initial');
pubsub.publish('trigger.shell.ready');
};
pubsub.subscribe('action.data.metadata.changed', updateSpriteAddress);
pubsub.subscribe('trigger.shell.refresh', refresh);
pubsub.subscribe('trigger.shell.init', init);
return {};
})(jQueryGlimpse, glimpse.pubsub, glimpse.util, glimpse.data, glimpse.settings);
// glimpse.render.engine.js
glimpse.render.engine = (function($, pubsub) {
var providers = {},
addition = function (scope, data, metadata, insertType, targetType) {
var html = $('<div>' + build(data, metadata) + '</div>').find('.glimpse-row-holder:first > .glimpse-row'),
rowHolder = scope.find('.glimpse-row-holder:first'),
scopeTarget = rowHolder.find('> .glimpse-row:' + targetType);
// Catch the case when we don't have anything to action the insertType against
if (scopeTarget.length == 0) {
scopeTarget = rowHolder;
insertType = 'appendTo';
}
var elements = $(html)[insertType](scopeTarget);
pubsub.publish('trigger.panel.render.style', { scope: elements });
},
retrieve = function(name) {
return providers[name];
},
register = function(name, engine) {
providers[name] = engine;
},
build = function(data, metadata) {
return providers.master.build(data, 0, true, metadata, 1);
},
insert = function(scope, data, metadata) {
scope.html(build(data, metadata));
pubsub.publish('trigger.panel.render.style', { scope: scope });
},
append = function(scope, data, metadata) {
addition(scope, data, metadata, 'insertAfter', 'last');
},
prepend = function(scope, data, metadata) {
addition(scope, data, metadata, 'insertBefore', 'first');
};
return {
_providers: providers,
retrieve: retrieve,
register: register,
build: build,
insert: insert,
append: append,
prepend: prepend
};
})(jQueryGlimpse, glimpse.pubsub);
// glimpse.render.engine.util.js
glimpse.render.engine.util = (function($) {
return {
keyMetadata: function (key, metadata) {
return metadata && metadata.layout === Object(metadata.layout) ? metadata.layout[key] : null;
},
includeHeading: function(metadata) {
return !(metadata && metadata.suppressHeader);
},
shouldUsePreview: function(length, level, forceFull, limit, forceLimit, tolerance) {
if ($.isNumeric(forceLimit))
limit = forceLimit;
return !forceFull && ((level == 1 && length > (limit + tolerance)) || (level > 1 && (!forceLimit || length > (limit + tolerance))));
},
newItemSpacer: function(startingIndex, currentRow, rowLimit, dataLength) {
var html = '';
if (currentRow > startingIndex && (currentRow <= rowLimit || dataLength > rowLimit))
html += '<span class="rspace">,</span>';
if (currentRow > rowLimit && dataLength > rowLimit)
html += '<span class="small">length=' + dataLength + '</span>';
return html;
}
};
})(jQueryGlimpse);
// glimpse.render.engine.util.raw.js
glimpse.render.engine.util.raw = (function($, util) {
var scrub = function(d) {
return d.substr(1, d.length - 2);
};
return {
types: {
italics : {
match: function (d) { return d.match(/^\_[\w\D]+\_$/) != null; },
replace: function (d) { return '<u>' + util.htmlEncode(scrub(d)) + '</u>'; },
trimmable: true
},
underline : {
match: function (d) { return d.match(/^\\[\w\D]+\\$/) != null; },
replace: function (d) { return '<em>' + util.htmlEncode(scrub(d)) + '</em>'; },
trimmable: true
},
strong : {
match: function (d) { return d. match(/^\*[\w\D]+\*$/) != null; },
replace: function (d) { return '<strong>' + util.htmlEncode(scrub(d)) + '</strong>'; },
trimmable: true
},
sub: {
match: function (d) { return d.indexOf('|(') >= 0 && d.indexOf(')|') >= 0; },
replace: function (d) { return util.htmlEncode(d).replace('|()|', '').replace('|(', '<span class="glimpse-sub-text">(').replace(')|', ')</span>'); },
trimmable: true
},
raw : {
match: function (d) { return d.match(/^\![\w\D]+\!$/) != null; },
replace: function (d) { return scrub(d); },
trimmable: false
}
},
process: function (data, charMax, charOuterMax, wrapEllipsis, skipEncoding) {
var trimmable = true,
replace = function (d) { return util.htmlEncode(d); };
if (data == null)
return '--';
if (typeof data != 'string')
data = data + '';
if (!skipEncoding) {
for (var typeKey in this.types) {
var type = this.types[typeKey];
if (type.match(data)) {
replace = type.replace;
trimmable = type.trimmable;
break;
}
}
}
if (trimmable && charOuterMax && data.length > charOuterMax)
return replace(data.substr(0, charMax)) + (wrapEllipsis ? '<span>...</span>' : '...');
return replace(data);
}
};
})(jQueryGlimpse, glimpse.util);
// glimpse.render.engine.util.table.js
glimpse.render.engine.util.table = (function($) {
var factories = {
array: {
isHandled: function(data) {
return $.isArray(data[0]);
},
getHeader: function(data) {
return data[0];
},
getRowClass: function(data, rowIndex) {
return data[rowIndex].length > data[0].length ? ' ' + data[rowIndex][data[rowIndex].length - 1] : '';
},
getRowValue: function(dataRow, fieldIndex, header) {
return dataRow[fieldIndex];
},
startingIndex: function() {
return 1;
}
},
object: {
isHandled: function(data) {
return data[0] === Object(data[0]);
},
getHeader: function(data) {
var result = [];
for (var key in data[0]) {
if (key != "_metadata")
result.push(key);
}
return result;
},
getRowClass: function(data, rowIndex) {
return data[rowIndex]._metadata && data[rowIndex]._metadata.style ? ' ' + data[rowIndex]._metadata.style : '';
},
getRowValue: function(dataRow, fieldIndex, header) {
return dataRow[header[fieldIndex]];
},
startingIndex: function() {
return 0;
}
},
other: {
isHandled: function(data) {
return true;
},
getHeader: function(data) {
return ["Values"];
},
getRowClass: function(data, rowIndex) {
return '';
},
getRowValue: function(dataRow, fieldIndex, header) {
return dataRow;
},
startingIndex: function() {
return 0;
}
}
};
return {
findFactory: function(data) {
var match = null;
for (var key in factories) {
if (factories[key].isHandled(data)) {
match = factories[key];
break;
}
}
return match;
}
};
})(jQueryGlimpse);
// glimpse.render.engine.style.js
(function($, pubsub) {
var codeProcess = function(items) {
$.each(items, function() {
var item = $(this).addClass('prettyprint'),
codeType = item.hasClass('glimpse-code') ? item.attr('data-codeType') : item.closest('.glimpse-code').attr('data-codeType');
item.html(prettyPrintOne(item.html(), codeType));
});
},
apply = function(options) {
// Expand collapse
options.scope.find('.glimpse-expand').click(function() {
var toggle = $(this).toggleClass('glimpse-collapse'),
hasClass = toggle.hasClass('glimpse-collapse');
toggle.parent().next().children().first().toggle(!hasClass).next().toggle(hasClass);
});
// Alert state
options.scope.find('.info, .warn, .error, .fail, .loading, .ms')
.find('> td:first-child, > tr:first-child .glimpse-cell:first-child')
.not(':has(.icon)').prepend('<div class="icon"></div>');
;
// Code formatting
codeProcess(options.scope.find('.glimpse-code:not(:has(table)), .glimpse-code > table:not(:has(thead)) .glimpse-preview-show'));
// Open state
options.scope.find('.glimpse-start-open > td > .glimpse-expand:first-child').click();
};
pubsub.subscribe('trigger.panel.render.style', apply);
})(jQueryGlimpse, glimpse.pubsub);
// glimpse.render.engine.keyvalue.js
(function($, util, engine, engineUtil) {
var providers = engine._providers,
build = function (data, level, forceFull, metadata, forceLimit) {
var limit = !$.isNumeric(forceLimit) ? 3 : forceLimit;
if (engineUtil.shouldUsePreview(util.lengthJson(data), level, forceFull, limit, forceLimit, 1))
return buildPreview(data, level);
return buildOnly(data, level, metadata);
},
buildOnly = function(data, level, metadata) {
var html = '<table>';
if (engineUtil.includeHeading(metadata))
html += '<thead><tr class="glimpse-row-header glimpse-row-header-' + level + '"><th class="glimpse-key">Key</th><th class="glimpse-cell-value">Value</th></tr></thead>';
html += '<tbody class="glimpse-row-holder">';
for (var key in data)
html += '<tr class="glimpse-row"><th class="glimpse-key">' + engineUtil.raw.process(key) + '</th><td> ' + providers.master.build(data[key], level + 1, null, engineUtil.keyMetadata(key, metadata)) + '</td></tr>';
html += '</tbody></table>';
return html;
},
buildPreview = function (data, level) {
return '<table class="glimpse-preview-table"><tr><td class="glimpse-preview-cell"><div class="glimpse-expand"></div></td><td><div class="glimpse-preview-object">' + buildPreviewOnly(data, level) + '</div><div class="glimpse-preview-show">' + build(data, level, true) + '</div></td></tr></table>';
},
buildPreviewOnly = function (data, level) {
var rowMax = 2,
rowLength = util.lengthJson(data),
rowLimit = (rowMax < rowLength ? rowMax : rowLength),
i = 0,
html = '<span class="start">{</span>';
for (var key in data) {
html += engineUtil.newItemSpacer(0, i, rowLimit, rowLength);
if (i > rowLength || i++ > rowLimit)
break;
html += '<span>\'</span>' + providers.string.build(key, level + 1, false, 12) + '<span>\'</span><span class="mspace">:</span><span>\'</span>' + providers.string.build(data[key], level + 1, false, 12) + '<span>\'</span>';
}
html += '<span class="end">}</span>';
return html;
},
provider = {
build : build,
buildOnly : buildOnly,
buildPreview : buildPreview,
buildPreviewOnly : buildPreviewOnly
};
engine.register('keyValue', provider);
})(jQueryGlimpse, glimpse.util, glimpse.render.engine, glimpse.render.engine.util);
// glimpse.render.engine.empty.js
(function($, engine) {
var provider = {
build: function(data) {
if (data == null || data === '')
data = 'No data found for this plugin.';
return '<div class="glimpse-panel-message">' + data + '</div>';
}
};
engine.register('empty', provider);
})(jQueryGlimpse, glimpse.render.engine);
// glimpse.render.engine.master.js
(function($, engine) {
var providers = engine._providers,
stack = [],
provider = {
build: function(data, level, forceFull, metadata, forceLimit) {
var result = '',
isArray = $.isArray(data),
isObject = data === Object(data);
if (isObject || isArray) {
if (stack.indexOf(data) > -1)
return '<em>--Circular Reference Detected--</em>';
stack.push(data);
}
if (metadata) {
if (metadata.engine && providers[metadata.engine])
result = providers[metadata.engine].build(data, level, forceFull, metadata, forceLimit);
else if (metadata.layout && isArray)
result = providers.layout.build(data, level, forceFull, metadata, forceLimit);
else if (metadata.keysHeadings && isObject)
result = providers.heading.build(data, level, forceFull, metadata, forceLimit);
}
if (result === '') {
if (typeof data === 'function')
result = providers.func.build(data, level, forceFull, metadata, forceLimit);
else if (isArray)
result = providers.table.build(data, level, forceFull, metadata, forceLimit);
else if (isObject)
result = providers.keyValue.build(data, level, forceFull, metadata, forceLimit);
else if (level == 0)
result = providers.empty.build(data);
else
result = providers.string.build(data, level, forceFull, forceLimit);
}
if (isObject || isArray)
stack.pop();
return result;
}
};
engine.register('master', provider);
})(jQueryGlimpse, glimpse.render.engine);
// glimpse.render.engine.string.js
(function($, util, engine, engineUtil) {
var provider = {
build: function (data, level, forceFull, forceLimit) {
if (data == null)
return '--';
if ($.isArray(data))
return '[ ... ]';
if ($.isPlainObject(data))
return '{ ... }';
if (forceFull)
return util.preserveWhitespace(engineUtil.raw.process(data));
var charMax = $.isNumeric(forceLimit) ? forceLimit : (level > 1 ? 80 : 150),
charOuterMax = (charMax * 1.2),
content = engineUtil.raw.process(data, charMax, charOuterMax, true);
if (data.length > charOuterMax) {
content = '<span class="glimpse-preview-string" title="' + engineUtil.raw.process(data, charMax * 2, charMax * 2.1, false, true) + '">' + content + '</span>';
if (charMax >= 15)
content = '<table class="glimpse-preview-table"><tr><td class="glimpse-preview-cell"><div class="glimpse-expand"></div></td><td>' + content + '<span class="glimpse-preview-show">' + util.preserveWhitespace(engineUtil.raw.process(data)) + '</span></td></tr></table>';
}
else
content = util.preserveWhitespace(content);
return content;
}
};
engine.register('string', provider);
})(jQueryGlimpse, glimpse.util, glimpse.render.engine, glimpse.render.engine.util);
// glimpse.render.engine.layout.js
(function($, util, engine, engineUtil, engineUtilTable) {
var providers = engine._providers,
buildFormatString = function(content, data, indexs, isHeadingRow) {
for (var i = 0; i < indexs.length; i++) {
var pattern = "\\\{\\\{" + indexs[i] + "\\\}\\\}", regex = new RegExp(pattern, "g"),
value = isHeadingRow && !$.isNumeric(indexs[i]) ? indexs[i] : data[indexs[i]];
content = content.replace(regex, value);
}
return content;
},
buildCell = function(data, metadataItem, level, cellType, rowIndex, isHeadingRow) {
var html = '',
cellContent = '',
cellClass = '',
cellStyle = '',
cellAttr = '',
containsNestedData = $.isArray(metadataItem.data);
//Cell Content
if (containsNestedData) {
for (var i = 0; i < metadataItem.data.length; i++)
cellContent += buildCell(data, metadataItem.data[i], level, 'div', rowIndex, isHeadingRow);
}
else {
if (!metadataItem.indexs && util.containsTokens(metadataItem.data))
metadataItem.indexs = util.getTokens(metadataItem.data, data);
cellContent = metadataItem.indexs ? buildFormatString(metadataItem.data, data, metadataItem.indexs, isHeadingRow) : (isHeadingRow && !$.isNumeric(metadataItem.data) ? metadataItem.data : data[metadataItem.data]);
if (metadataItem.engine && !isHeadingRow) {
cellContent = providers.master.build(cellContent, level + 1, metadataItem.forceFull, metadataItem, isHeadingRow ? undefined : metadataItem.limit);
}
else {
//Get metadata for the new data
var newMetadataItem = metadataItem.layout;
if ($.isPlainObject(newMetadataItem))
newMetadataItem = newMetadataItem[rowIndex];
if (newMetadataItem || metadataItem.suppressHeader)
newMetadataItem = { layout: newMetadataItem, suppressHeader: metadataItem.suppressHeader };
//If minDisplay and we are in header or there is no data, we don't want to render anything
if (metadataItem.minDisplay && (isHeadingRow || cellContent == null))
return "";
//Work out what title we want
if (isHeadingRow && metadataItem.title)
cellContent = metadataItem.title;
cellContent = providers.master.build(cellContent, level + 1, metadataItem.forceFull, newMetadataItem, isHeadingRow ? undefined : metadataItem.limit);
//Content pre/post
if (!isHeadingRow) {
if (metadataItem.pre) { cellContent = '<span class="glimpse-soft">' + metadataItem.pre + '</span>' + cellContent; }
if (metadataItem.post) { cellContent = cellContent + '<span class="glimpse-soft">' + metadataItem.post + '</span>'; }
}
}
}
if (!isHeadingRow) {
if (!containsNestedData) { cellClass = 'glimpse-cell'; }
//Cell Class
if (metadataItem.key === true) { cellClass += ' glimpse-cell-key'; }
if (metadataItem.isCode === true) { cellClass += ' glimpse-code'; }
if (metadataItem.className) { cellClass += ' ' + metadataItem.className; }
//Cell Code
if (metadataItem.codeType) { cellAttr += ' data-codeType="' + metadataItem.codeType + '"'; };
}
if (cellClass) { cellAttr += ' class="' + cellClass + '"'; };
//Cell Style
if (metadataItem.width) { cellStyle += 'width:' + metadataItem.width + ';'; };
if (metadataItem.align) { cellStyle += 'text-align:' + metadataItem.align + ';'; };
if (cellStyle) { cellAttr += ' style="' + cellStyle + '"'; };
//Cell Span
if (metadataItem.span) { cellAttr += ' colspan="' + metadataItem.span + '"'; };
html += '<' + cellType + cellAttr + '>' + cellContent + '</' + cellType + '>';
return html;
},
buildCellRow = function (data, layout, level, cellType, rowIndex, isHeadingRow) {
var html = '';
for (var x = 0; x < layout.length; x++) {
var rowHtml = '';
for (var y = 0; y < layout[x].length; y++) {
var metadataItem = layout[x][y];
rowHtml += buildCell(data, metadataItem, level, cellType, rowIndex, isHeadingRow);
}
if (rowHtml != '') { html += '<tr>' + rowHtml + '</tr>'; };
}
return html;
},
build = function (data, level, forceFull, metadata, forceLimit) {
var limit = !$.isNumeric(forceLimit) ? 3 : forceLimit;
if (engineUtil.shouldUsePreview(data.length, level, forceFull, limit, forceLimit, 1))
return buildPreview(data, level, metadata);
return buildOnly(data, level, metadata);
},
buildOnly = function (data, level, metadata) {
var html = '<table class="glimpse-row-holder">',
layout = metadata.layout,
factory = engineUtilTable.findFactory(data),
headers = factory.getHeader(data);
if (engineUtil.includeHeading(metadata)) {
html += '<thead class="glimpse-row-header glimpse-row-header-' + level + '">';
html += buildCellRow(headers, layout, level, 'th', 0, true);
html += '</thead>';
}
for (var i = factory.startingIndex(); i < data.length; i++) {
html += '<tbody class="glimpse-row' + factory.getRowClass(data, i) + '">';
html += buildCellRow(data[i], layout, level, 'td', i, false);
html += '</tbody>';
}
html += '</table>';
return html;
},
buildPreview = function(data, level, metadata) {
return '<table class="glimpse-preview-table"><tr><td class="glimpse-preview-cell"><div class="glimpse-expand"></div></td><td><div class="glimpse-preview-object">' + buildPreviewOnly(data, level) + '</div><div class="glimpse-preview-show">' + buildOnly(data, level, metadata) + '</div></td></tr></table>';
},
buildPreviewOnly = function (data, level) {
return providers.table.buildPreviewOnly(data, level);
},
provider = {
build : build,
buildOnly : buildOnly,
buildPreview : buildPreview,
buildPreviewOnly : buildPreviewOnly
};
engine.register('layout', provider);
})(jQueryGlimpse, glimpse.util, glimpse.render.engine, glimpse.render.engine.util, glimpse.render.engine.util.table);
// glimpse.render.engine.table.js
(function($, util, engine, engineUtil, engineUtilTable) {
var providers = engine._providers,
build = function (data, level, forceFull, metadata, forceLimit) {
var limit = !$.isNumeric(forceLimit) ? 3 : forceLimit;
if (engineUtil.shouldUsePreview(data.length, level, forceFull, limit, forceLimit, 1))
return buildPreview(data, level);
return buildOnly(data, level, metadata);
},
buildOnly = function (data, level, metadata) {
var html = '<table>',
factory = engineUtilTable.findFactory(data),
headers = factory.getHeader(data);
if (engineUtil.includeHeading(metadata)) {
html += '<thead><tr class="glimpse-row-header glimpse-row-header-' + level + '">';
for (var x = 0; x < headers.length; x++)
html += '<th>' + engineUtil.raw.process(headers[x]) + '</th>';
html += '</tr></thead>';
}
html += '<tbody class="glimpse-row-holder">';
for (var i = factory.startingIndex(); i < data.length; i++) {
html += '<tr class="glimpse-row' + factory.getRowClass(data, i) + '">';
for (var x = 0; x < headers.length; x++)
html += '<td>' + providers.master.build(factory.getRowValue(data[i], x, headers), level + 1) + '</td>';
html += '</tr>';
}
html += '</tbody></table>';
return html;
},
buildPreview = function (data, level) {
var isComplex = ($.isArray(data[0]) || $.isPlainObject(data[0]));
if (isComplex && data.length == 1) //This exists to simplify visual layout if we only have one item
return providers.master.build(data[0], level);
if (isComplex || data.length > 1)
return '<table class="glimpse-preview-table"><tr><td class="glimpse-preview-cell"><div class="glimpse-expand"></div></td><td><div class="glimpse-preview-object">' + buildPreviewOnly(data, level) + '</div><div class="glimpse-preview-show">' + buildOnly(data, level) + '</div></td></tr></table>';
return providers.string.build(data[0], level + 1);
},
buildPreviewOnly = function (data, level) {
var html = '<span class="start">[</span>',
factory = engineUtilTable.findFactory(data),
headers = factory.getHeader(data),
startingIndex = factory.startingIndex(),
columnMax = 3,
columnLength = headers.length,
columnLimit = columnMax < columnLength ? columnMax : columnLength,
rowMax = 2 + startingIndex,
rowLength = data.length - startingIndex,
rowLimit = rowMax < rowLength ? rowMax : rowLength + startingIndex;
for (var i = startingIndex; i < rowLimit; i++) {
html += engineUtil.newItemSpacer(startingIndex, i, rowLimit, rowLength);
if (headers.length > 1)
html += '<span class="start">[</span>';
var spacer = '';
for (var x = 0; x < columnLimit; x++) {
html += spacer + '<span>\'</span>' + providers.string.build(factory.getRowValue(data[i], x, headers), level + 1, false, 12) + '<span>\'</span>';
spacer = '<span class="rspace">,</span>';
}
if (headers.length > 1) {
if (x < headers.length)
html += spacer + '<span>...</span>';
html += '<span class="end">]</span>';
}
}
html += engineUtil.newItemSpacer(startingIndex, ++i, rowLimit, rowLength);
html += '<span class="end">]</span>';
return html;
},
provider = {
build : build,
buildOnly : buildOnly,
buildPreview : buildPreview,
buildPreviewOnly : buildPreviewOnly
};
engine.register('table', provider);
})(jQueryGlimpse, glimpse.util, glimpse.render.engine, glimpse.render.engine.util, glimpse.render.engine.util.table);
// glimpse.render.engine.func.js
(function($, util, engine, engineUtil) {
var build = function (data, level, forceFull, metadata, forceLimit) {
if (!forceFull)
return buildPreview(data, level);
return buildOnly(data, level);
},
buildOnly = function (data, level) {
return util.htmlEncode(data.toString());
},
buildPreview = function (data, level) {
return '<table class="glimpse-preview-table"><tr><td class="glimpse-preview-cell"><div class="glimpse-expand"></div></td><td><div class="glimpse-preview-object">' + buildPreviewOnly(data, level) + '</div><div class="glimpse-preview-show glimpse-code" data-codeType="js">' + buildOnly(data, level) + '</div></td></tr></table>';
},
buildPreviewOnly = function (data, level) {
data = data.toString();
var name = data.substring(data.indexOf(' ') + 1, data.indexOf('(')),
args = data.substring(data.indexOf('(') + 1, data.indexOf(')')).split(', ').join('<span class="rspace">,</span>');
return '<span class="start">function</span>' + name + '<span>(</span>' + args + '<span>) { ... }</span>';
},
provider = {
build : build,
buildOnly : buildOnly,
buildPreview : buildPreview,
buildPreviewOnly : buildPreviewOnly
};
engine.register('func', provider);
})(jQueryGlimpse, glimpse.util, glimpse.render.engine, glimpse.render.engine.util);
// glimpse.render.engine.heading.js
(function($, util, engine, engineUtil) {
var providers = engine._providers,
build = function (data, level, forceFull, metadata, forceLimit) {
var html = '<div class="glimpse-row-holder glimpse-row-holder-suppress"><div class="glimpse-row">';
for (var key in data) {
var value = data[key];
html += '<div class="glimpse-header-item"><div class="glimpse-header">' + key + '</div>';
if ($.isArray(value) || value === Object(value))
html += providers.master.build(value, 0, null, engineUtil.keyMetadata(key, metadata));
else
html += '<div class="glimpse-header-content">' + (value != null ? util.preserveWhitespace(value) : '<em>null</em>') + '</div>';
html += '</div>';
}
html += '</div></div>';
return html;
},
provider = {
build : build
};
engine.register('heading', provider);
})(jQueryGlimpse, glimpse.util, glimpse.render.engine, glimpse.render.engine.util);
// glimpse.render.tab.js
(function($, data, elements, util, pubsub, settings) {
var wireListeners = function () {
var tabHolder = elements.tabHolder();
tabHolder.find('li:not(.glimpse-active, .glimpse-disabled)').live('click', function () {
var key = $(this).attr('data-glimpseKey');
pubsub.publish('trigger.tab.select.' + key, { key: key });
});
tabHolder.find('li:not(.glimpse-active, .glimpse-disabled)').live('mouseover mouseout', function (e) {
e.type == 'mouseover' ? $(this).addClass('glimpse-hover') : $(this).removeClass('glimpse-hover');
});
},
generateHtmlItem = function(key, pluginData) {
if (!pluginData.suppressTab) {
var disabled = pluginData.data == null ? ' glimpse-disabled' : '',
permanent = pluginData.isPermanent ? ' glimpse-permanent' : '';
return '<li class="glimpse-tab glimpse-tabitem-' + key + disabled + permanent + '" data-glimpseKey="' + key + '">' + pluginData.name + '</li>';
}
return '';
},
generateHtml = function(pluginDataSet) {
var html = { instance: '', permanent: '' };
for (var key in pluginDataSet) {
var pluginData = pluginDataSet[key],
itemHtml = generateHtmlItem(key, pluginData);
if (pluginData.isPermanent)
html.permanent += itemHtml;
else
html.instance += itemHtml;
}
return html;
},
render = function(args) {
pubsub.publish('action.tab.inserting.bulk');
var currentData = data.currentData(),
tabInstanceHolder = elements.tabInstanceHolder(),
tabPermanentHolder = elements.tabPermanentHolder();
// Make sure that the tabs are sorted
currentData.data = util.sortTabs(currentData.data);
// Add tabs to the dom
var tabHtml = generateHtml(currentData.data);
tabInstanceHolder.html(tabHtml.instance);
if (args.isInitial) {
tabPermanentHolder.append(tabHtml.permanent);
}
pubsub.publish('action.tab.inserted.bulk');
},
selected = function(options) {
var tabHolder = elements.tabHolder(),
tab = elements.tab(options.key);
tabHolder.find('.glimpse-active, .glimpse-hover').removeClass('glimpse-active').removeClass('glimpse-hover');
tab.addClass('glimpse-active');
},
clear = function() {
elements.tabInstanceHolder().empty();
},
insert = function(args) {
var key = args.key,
payload = args.payload,
itemHtml = generateHtmlItem(key, payload);
pubsub.publish('action.tab.inserting.single', { key: key });
if (payload.isPermanent)
elements.tabPermanentHolder().append(itemHtml);
else
elements.tabInstanceHolder().append(itemHtml);
pubsub.publish('action.tab.inserted.single', { key: key });
};
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
pubsub.subscribe('trigger.tab.render', render);
pubsub.subscribe('trigger.tab.select', selected);
pubsub.subscribe('trigger.shell.clear', clear);
pubsub.subscribe('trigger.tab.insert', insert);
})(jQueryGlimpse, glimpse.data, glimpse.elements, glimpse.util, glimpse.pubsub, glimpse.settings);
// glimpse.render.panel.js
(function($, data, elements, pubsub, renderEngine) {
var render = function (key, pluginData, pluginMetadata) {
pubsub.publish('action.panel.rendering.' + key, { key: key, pluginData: pluginData, pluginMetadata: pluginMetadata });
var panelHolder = elements.panelHolder(),
permanent = pluginData.isPermanent ? ' glimpse-permanent' : '',
html = '<div class="glimpse-panel glimpse-panelitem-' + key + permanent + '" data-glimpseKey="' + key + '"><div class="glimpse-panel-message">Loading data, please wait...</div></div>',
panel = $(html).appendTo(panelHolder);
if (!pluginData.dontRender)
renderEngine.insert(panel, pluginData.data, pluginMetadata);
pubsub.publish('action.panel.rendered.' + key, { key: key, panel: panel, pluginData: pluginData, pluginMetadata: pluginMetadata, panelHolder: panelHolder });
return panel;
},
selected = function(options) {
var pluginData = data.currentData().data[options.key],
pluginMetadata = data.currentMetadata().plugins[options.key],
panel = elements.panel(options.key),
currentSelection = elements.panelHolder().find('.glimpse-active');
// Raise an event that lets us know when we dont care about a panel any more
if (currentSelection.length > 0) {
currentSelection.removeClass('glimpse-active');
var oldKey = currentSelection.attr('data-glimpseKey');
pubsub.publish('action.panel.hiding.' + oldKey, { key: oldKey, newKey: options.key });
}
// Only run if we have data
if (pluginData != null) {
pubsub.publish('action.panel.showing.' + options.key, { key: options.key, panel: panel, pluginData: pluginData, pluginMetadata: pluginMetadata, oldKey: oldKey });
// Only render the content when we need to
if (panel.length == 0)
panel = render(options.key, pluginData, pluginMetadata);
panel.addClass('glimpse-active');
pubsub.publish('action.panel.showed.' + options.key, { key: options.key, panel: panel, pluginData: pluginData, pluginMetadata: pluginMetadata, oldKey: oldKey });
}
},
clear = function() {
elements.panelHolder().find('.glimpse-panel:not(.glimpse-permanent)').remove();
};
pubsub.subscribe('trigger.tab.select', selected);
pubsub.subscribe('trigger.shell.clear', clear);
})(jQueryGlimpse, glimpse.data, glimpse.elements, glimpse.pubsub, glimpse.render.engine);
// glimpse.render.lazy.js
(function($, data, util, elements, pubsub, renderEngine) {
var generateLazyAddress = function (key) {
var currentMetadata = data.currentMetadata();
return util.uriTemplate(currentMetadata.resources.glimpse_tab, { 'requestId': data.currentData().requestId, 'pluginKey': key, 'hash': currentMetadata.hash });
},
retrieveData = function(options) {
var resources = data.currentMetadata().resources;
if (resources.glimpse_tab) {
pubsub.publish('action.tab.lazy.fetching', { key: options.key });
$.ajax({
url: generateLazyAddress(options.key),
type: 'GET',
contentType: 'application/json',
success: function(result) {
processData(options.key, options.pluginData, options.pluginMetadata, result);
},
complete: function(xhr, status) {
pubsub.publish('action.tab.lazy.fetched', { key: options.key, status: status });
}
});
}
else
pubsub.publishAsync('trigger.notification.toast', { type: 'error', message: 'Lazy loading isn\'t currently supported by your server implementation. Sorry :(' });
},
processData = function (key, pluginData, pluginMetadata, result) {
pluginData.data = result;
renderEngine.insert(elements.panel(key), pluginData.data, pluginMetadata.structure);
},
rendering = function (options) {
if (options.pluginData.isLazy)
options.pluginData.dontRender = true;
},
rendered = function (options) {
if (options.pluginData.isLazy)
retrieveData(options);
};
pubsub.subscribe('action.panel.rendering', rendering);
pubsub.subscribe('action.panel.rendered', rendered);
})(jQueryGlimpse, glimpse.data, glimpse.util, glimpse.elements, glimpse.pubsub, glimpse.render.engine);
// glimpse.render.default.js
(function(settings, pubsub, elements) {
var readyOpen = function () {
var isOpen = settings.local('isOpen');
if (isOpen)
pubsub.publish('trigger.shell.open', { isInitial: true });
},
readySelect = function () {
var current = settings.local('view'),
tabElement = elements.tab(current),
forced = current != null;
if (!current || tabElement.length == 0) {
tabElement = elements.tabHolder().find('li:not(.glimpse-active, .glimpse-disabled):first');
current = tabElement.attr('data-glimpseKey');
}
if (tabElement.length > 0 && !tabElement.hasClass('glimpse-active'))
pubsub.publish('trigger.tab.select.' + current, { key: current, forced: forced });
},
selected = function (args) {
if (!args.forced)
settings.local('view', args.key);
};
pubsub.subscribe('trigger.shell.ready', readyOpen);
pubsub.subscribe('action.tab.inserted', readySelect);
pubsub.subscribe('trigger.tab.select', selected);
})(glimpse.settings, glimpse.pubsub, glimpse.elements);
// glimpse.shell.controls.js
(function($, pubsub, elements, settings) {
var wireListeners = function () {
elements.opener().find('.glimpse-icon').click(function () { pubsub.publish('trigger.shell.open', { isInitial: false }); });
elements.barHolder().find('.glimpse-minimize').click(function () { pubsub.publish('trigger.shell.minimize'); });
elements.barHolder().find('.glimpse-close').click(function () { pubsub.publish('trigger.shell.close'); });
},
open = function(args) {
if (!args.isInitial)
settings.local('hidden', false);
if (!settings.local('hidden') || args.force) {
settings.local('isOpen', true);
pubsub.publish('action.shell.opening', { isInitial: args.isInitial });
var height = settings.local('height') || 300,
body = $.fn.add.call(elements.holder(), elements.pageSpacer()).show();
settings.local('height', height);
settings.local('panelHeight', height - 52);
elements.opener().hide();
if (args.isInitial)
body.height(height);
else
body.animate({ height: settings.local('height') }, 'fast');
if (args.fullScreen) {
elements.pageSpacer().remove();
var holder = elements.holder();
holder.height('');
$(window).resize(function() {
var panelHeight = $(window).height() - 54;
elements.panels().height(panelHeight);
pubsub.publish('trigger.shell.fullScreen.resize', { panelHeight: panelHeight });
});
}
pubsub.publish('action.shell.opened', { isInitial: args.isInitial });
}
else
pubsub.publish('trigger.shell.suppressed.open');
},
minimize = function() {
settings.local('isOpen', false);
pubsub.publish('action.shell.minimizing');
var count = 0;
$.fn.add.call(elements.holder(), elements.pageSpacer())
.animate({ height : '0' }, 'fast', function() {
$(this).hide();
if (count++ == 1) {
elements.opener().show();
pubsub.publish('action.shell.minimized');
}
});
},
hide = function () {
settings.local('hidden', true);
elements.holder().hide();
elements.pageSpacer().hide();
elements.opener().show();
},
close = function() {
settings.local('isOpen', false);
settings.local('hidden', false);
settings.global('glimpsePolicy', null, -1);
pubsub.publish('action.shell.closeing');
elements.holder().remove();
elements.pageSpacer().remove();
elements.opener().remove();
pubsub.publish('action.shell.closed');
};
pubsub.subscribe('trigger.shell.open', open);
pubsub.subscribe('trigger.shell.minimize', minimize);
pubsub.subscribe('trigger.shell.close', close);
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
pubsub.subscribe('trigger.shell.hide', hide);
})(jQueryGlimpse, glimpse.pubsub, glimpse.elements, glimpse.settings);
// glimpse.shell.info.js
(function($, pubsub, elements, data, util) {
var wireListeners = function () {
elements.barHolder().find('.glimpse-icon').click(function () { pubsub.publish('trigger.tab.select.info', { key: 'info' }); });
},
buildHelp = function(options) {
var info = data.currentMetadata().plugins[options.key],
url = info && info.documentationUri;
elements.barHolder().find('.glimpse-meta-help').toggle(url != null).attr('href', url);
},
buildInfo = function(args) {
var metadata = data.currentMetadata();
args.panel.html('<div class="glimpse-info-title"><a href="http://getGlimpse.com/" target="_blank"><img border="0" src="' + util.uriTemplate(data.currentMetadata().resources.glimpse_logo) + '" /></a></div><div>v' + metadata.version + '</div><div class="glimpse-info-quote">"What Firebug is for the client, Glimpse is for the server"</div><div class="glimpse-info-more">Go to your Glimpse Config page <a href="' + util.uriTemplate(data.currentMetadata().resources.glimpse_config) + '" target="_blank">Glimpse.axd</a></div><div class="glimpse-info-more">For more info see <a href="http://getGlimpse.com" target="_blank">http://getGlimpse.com</a></div><div style="margin:1.5em 0 0.5em;">Created by <strong>Anthony van der Hoorn</strong> (<a href="http://twitter.com/anthony_vdh" target="_blank">@anthony_vdh</a>) and <strong>Nik Molnar</strong> (<a href="http://twitter.com/nikmd23" target="_blank">@nikmd23</a>) &nbsp; - &copy; getglimpse.com 2011</div><div>Have a <em>feature</em> request? <a href="http://getglimpse.uservoice.com" target="_blank">Submit the idea</a>. &nbsp; &nbsp;Found an <em>error</em>? <a href="https://github.com/glimpse/glimpse/issues" target="_blank">Help us improve</a>. &nbsp; &nbsp;Have a <em>question</em>? <a href="http://twitter.com/#search?q=%23glimpse" target="_blank">Tweet us using #glimpse</a>. &nbsp; &nbsp;Want to <em>help</em>? <a href="groups.google.com/group/getglimpse-dev" target="_blank">Join our developer mailing list</a>.</div>');
},
setupInfo = function(args) {
args.newData.data.info = { data: 'Loading...', suppressTab: true, isPermanent: true };
args.newData.metadata.plugins.info = {};
};
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
pubsub.subscribe('action.panel.rendered.info', buildInfo);
pubsub.subscribe('action.data.initial.changed', setupInfo);
pubsub.subscribe('action.panel.showing', buildHelp);
})(jQueryGlimpse, glimpse.pubsub, glimpse.elements, glimpse.data, glimpse.util);
// glimpse.shell.resize.js
(function($, pubsub, elements, settings, util) {
var wireListeners = function() {
$.draggable({
handelScope: elements.holder().find('.glimpse-resizer'),
opacityScope: elements.holder(),
resizeScope: elements.holder(),
dragged: shellResized
});
},
shellResized = function (args, height) {
var panelHeight = height - 52;
settings.local('height', height);
settings.local('panelHeight', panelHeight);
elements.pageSpacer().height(height);
elements.panels().height(panelHeight);
pubsub.publish('trigger.shell.resize', { height: height, panelHeight: panelHeight });
},
panelRendered = function (args) {
var height = settings.local('height');
elements.panel(args.key).height(height - 52);
};
pubsub.subscribe('action.panel.rendered', panelRendered);
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
})(jQueryGlimpse, glimpse.pubsub, glimpse.elements, glimpse.settings, glimpse.util);
// glimpse.shell.popup.js
(function($, pubsub, settings, data, elements, util) {
var wireListeners = function() {
elements.holder().find('.glimpse-popout').click(function() { pubsub.publish('trigger.shell.popup'); });
},
dataLoaded = function(args) {
var uri = args.metadata.resources.glimpse_popup;
if (uri) {
elements.barHolder().find('.glimpse-popout').removeClass('glimpse-hidden');
tryOpenPopup();
}
if (settings.local('popupOn')) {
$(window).unload(windowUnloading);
}
},
registerSuppressedOpen = function() {
registerSuppressedOpen = true;
},
generatePopupAddress = function() {
var currentMetadata = data.currentMetadata();
return util.uriTemplate(currentMetadata.resources.glimpse_popup, { 'requestId': data.currentData().requestId, 'hash': currentMetadata.hash });
},
isPopup = function() {
return data.currentMetadata().resources.glimpse_popup ? window.location.href.indexOf('n=glimpse_popup') > -1 : false;
},
openPopup = function() { //WHEN USE CLICKS OPEN BUTTON
settings.local('popupOn', true); //Indicates popup should be used
settings.local('popupKeep', true); //This second item is used to detect difference between user closing the page and a redirect
window.open(generatePopupAddress(), 'GlimpsePopup', 'width=1100,height=600,status=no,toolbar=no,menubar=no,location=no,resizable=yes,scrollbars=yes');
pubsub.publish('trigger.shell.hide');
},
tryOpenPopup = function() { //WHEN PARENT WINDOW IS LOADING AND DETECTS THAT IT HAS BEEN SUPPRESSED, IF POPUP ON, REDIRECT THE POPUP OR FORCE THE WINDOW OPEN
if (settings.local('popupOn')) {
if (!isPopup()) {
pubsub.publish('trigger.shell.popup');
}
else {
pubsub.publish('trigger.shell.open', { isInitial: true, force: true, fullScreen: true });
settings.local('popupKeep', false);
}
}
},
windowUnloading = function() { //WHEN USER CLOSES POPUP WE WANT TO TURN EVERYTHING OFF
if (isPopup() && !settings.local('popupKeep'))
settings.local('popupOn', false);
},
terminate = function() { //WHEN USER CLOSES OR OPENS SHELL IN THE MAIN WINDOW LETS KILL POPUP
if (!isPopup()) {
settings.local('popupOn', false);
settings.local('popupKeep', false);
}
};
pubsub.subscribe('trigger.shell.popup', openPopup);
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
pubsub.subscribe('action.shell.closed', terminate);
pubsub.subscribe('action.shell.opening', terminate);
pubsub.subscribe('action.data.initial.changed', dataLoaded);
pubsub.subscribe('trigger.shell.suppressed.open', registerSuppressedOpen);
})(jQueryGlimpse, glimpse.pubsub, glimpse.settings, glimpse.data, glimpse.elements, glimpse.util);
// glimpse.shell.title.js
(function($, pubsub, data, elements) {
var renderLayout = function() {
var requestData = data.currentData(),
name = requestData.clientId ? '"' + requestData.clientId + '"' : '&nbsp;';
elements.titleHolder().find('.glimpse-snapshot-name').html(name);
elements.titleHolder().find('.glimpse-uri').text(requestData.uri);
};
pubsub.subscribe('action.shell.rendering', renderLayout);
pubsub.subscribe('trigger.title.render', renderLayout);
})(jQueryGlimpse, glimpse.pubsub, glimpse.data, glimpse.elements);
// glimpse.shell.correlation.js
(function($, pubsub, data, elements) {
var wireListeners = function() {
elements.titleHolder().find('.glimpse-correlation .glimpse-link').live('click', function() { data.retrieve($(this).attr('data-requestId'), 'correlation'); });
elements.titleHolder().find('.glimpse-correlation').dropdown();
},
buildHtml = function(request, requestMetadata) {
var correlation = requestMetadata.correlation,
html = '';
if (correlation) {
var currentUri = request.uri,
currentLeg = '';
html = '<div>' + correlation.title + '</div>';
for (var i = 0; i < correlation.legs.length; i++) {
var leg = correlation.legs[i];
if (leg.uri == currentUri) {
currentLeg = leg.uri;
html += currentLeg + ' - <strong>' + leg.method + '</strong> (Current)<br />';
} else
html += '<span class="glimpse-link" title="Go to ' + leg.uri + '" href="#" data-requestId="' + leg.requestId + '" data-url="' + leg.uri + '">' + leg.uri + '</span> - <strong>' + leg.method + '</strong><br />';
}
html = '<span class="glimpse-drop">' + currentLeg + '<span class="glimpse-drop-arrow-holder"><span class="glimpse-drop-arrow"></span></span></span><div class="glimpse-drop-over">' + html + '<div class="loading"><span class="icon"></span><span>Loaded...</span></div></div>';
}
return html;
},
renderLayout = function() {
var html = buildHtml(data.currentData(), data.currentMetadata());
if (html) {
elements.titleHolder().find('.glimpse-uri').hide();
elements.titleHolder().find('.glimpse-correlation').html(html);
}
},
startingRetrieve = function() {
elements.titleHolder().find('.glimpse-correlation .loading').fadeIn();
},
completedRetrieve = function() {
elements.titleHolder().find('.glimpse-correlation .loading').fadeOut();
},
succeededRetrieve = function(options) {
options.newData.metadata.correlation = options.oldData.metadata.correlation;
};
pubsub.subscribe('trigger.title.render', renderLayout);
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
pubsub.subscribe('action.data.retrieve.starting.correlation', startingRetrieve);
pubsub.subscribe('action.data.retrieve.completed.correlation', completedRetrieve);
pubsub.subscribe('action.data.retrieve.succeeded.correlation', succeededRetrieve);
})(jQueryGlimpse, glimpse.pubsub, glimpse.data, glimpse.elements);
// glimpse.shell.environment.js
(function($, pubsub, data, elements, util) {
var wireListeners = function() {
elements.titleHolder().find('.glimpse-enviro').dropdown();
},
buildHtml = function(requestMetadata) {
var uris = requestMetadata.environmentUrls,
html = '';
if (uris) {
var currentName = 'Enviro',
currentDomain = util.getDomain(unescape(window.location.href));
for (var targetName in uris) {
if (util.getDomain(uris[targetName]) === currentDomain) {
currentName = targetName;
html += ' - ' + targetName + ' (Current)<br />';
}
else
html += ' - <a title="Go to - ' + uris[targetName] + '" href="' + uris[targetName] + '">' + targetName + '</a><br />';
}
html = '<span class="glimpse-drop">' + currentName + '<span class="glimpse-drop-arrow-holder"><span class="glimpse-drop-arrow"></span></span></span><div class="glimpse-drop-over"><div>Switch Servers</div>' + html + '</div>';
}
return html;
},
renderLayout = function() {
var html = buildHtml(data.currentMetadata());
elements.titleHolder().find('.glimpse-enviro').html(html);
};
pubsub.subscribe('trigger.title.render', renderLayout);
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
})(jQueryGlimpse, glimpse.pubsub, glimpse.data, glimpse.elements, glimpse.util);
// glimpse.shell.path.js
(function($, pubsub, data, elements) {
var wireListeners = function() {
elements.titleHolder().find('.glimpse-snapshot-path .glimpse-link').live('click', function() { pubsub.publish('trigger.data.context.switch', { requestId: $(this).attr('data-requestId'), type: 'path' }); });
},
buildHtml = function(currentData) {
var baseData = data.baseData(),
html = '';
if (currentData.isAjax)
html = ' &gt; Ajax';
if ((currentData.isAjax && baseData.requestId != currentData.parentRequestId) || (!currentData.isAjax && baseData.requestId != currentData.requestId)) {
if (html)
html = ' &gt; <span class="glimpse-link" data-requestId="' + (currentData.isAjax ? currentData.parentRequestId : currentData.requestId) + '">History</span>' + html;
else
html = ' &gt; History';
}
if (html)
html = ' (<span class="glimpse-link" data-requestId="' + baseData.requestId + '">Original</span>' + html + ')';
return html;
},
contextSwitch = function(args) {
var html = buildHtml(args.newData);
elements.titleHolder().find('.glimpse-snapshot-path').html(html);
},
selected = function(args) {
if (args.type == 'path')
data.retrieve(args.requestId, 'path');
};
pubsub.subscribe('action.data.refresh.changed', contextSwitch);
pubsub.subscribe('trigger.data.context.switch', selected);
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
})(jQueryGlimpse, glimpse.pubsub, glimpse.data, glimpse.elements);
// glimpse.shell.notification.js
(function($, pubsub, elements) {
var toast = function(options) {
var toast = $('<div class="glimpse-notification glimpse-notification-' + options.type + '">' + options.message + '</div>').appendTo(elements.notificationHolder());
setTimeout(function() {
toast.fadeOut(250, function() {
toast.remove();
});
}, 5000);
};
pubsub.subscribe('trigger.notification.toast', toast);
})(jQueryGlimpse, glimpse.pubsub, glimpse.elements)
// glimpse.version.check.js
glimpse.versionCheck = (function($, pubsub, settings, elements, data, util) {
var retrieveStamp = function() {
if (!settings.local('stamp'))
settings.local('stamp', (new Date()).getTime());
return settings.local('stamp');
},
generateVersionCheckAddress = function() {
var currentMetadata = data.currentMetadata();
return util.uriTemplate(currentMetadata.resources.glimpse_version_check, { stamp: retrieveStamp(), 'hash': currentMetadata.hash });
},
tryShow = function () {
var hasNewerVersion = settings.local('hasNewerVersion'),
versionCheckUri = settings.local('versionCheckUri') || '',
currentHash = settings.local('hash');
if (hasNewerVersion && versionCheckUri.indexOf('hash=' + currentHash) > -1)
elements.holder().find('.glimpse-meta-update').show();
},
ready = function() {
var nextChecked = settings.local('nextCheckedVersionTime'),
now = new Date();
tryShow();
// Only check if we need to
if (nextChecked) {
var nextCheckedTicks = parseInt(nextChecked),
currentTimeTicks = now.getTime();
if (nextCheckedTicks > currentTimeTicks)
return;
}
// Get the check uri and store checkUri for verification purposes
var versionCheckUri = generateVersionCheckAddress();
settings.local('versionCheckUri', versionCheckUri);
$.ajax({
url: versionCheckUri,
type: 'GET',
dataType: 'jsonp',
crossDomain: true,
jsonpCallback: 'glimpse.versionCheck.result'
});
settings.local('nextCheckedVersionTime', now.setDate(now.getDate() + 1));
},
result = function(data) {
settings.local('hasNewerVersion', data.hasNewer);
settings.local('versionViewUri', data.viewLink);
tryShow();
};
pubsub.subscribe('trigger.data.init', ready);
return {
result: result
};
})(jQueryGlimpse, glimpse.pubsub, glimpse.settings, glimpse.elements, glimpse.data, glimpse.util);
// glimpse.version.shell.js
(function($, pubsub, elements, util, settings) {
var wireListeners = function() {
elements.holder().find('.glimpse-meta-update').click(function() { pubsub.publish('trigger.shell.version.info.show'); });
elements.lightbox().find('.close').live('click', function() { pubsub.publish('trigger.shell.version.info.close'); });
},
retrieveStamp = function () {
if (!settings.local('stamp'))
settings.local('stamp', (new Date()).getTime());
return settings.local('stamp');
},
generateVersionDetailAddress = function () {
return settings.local('versionViewUri') + '&stamp=' + retrieveStamp();
},
show = function() {
var detailsUri = settings.local('versionViewUri');;
if (detailsUri) {
elements.lightbox().find('.glimpse-lightbox-element').html('<div class="close">[close]</div><iframe src="' + generateVersionDetailAddress() + '"></iframe>');
elements.lightbox().show();
}
else
pubsub.publishAsync('trigger.notification.toast', { type: 'error', message: 'Version check isn\'t currently supported by your server implementation. Sorry :(' });
},
close = function() {
elements.lightbox().find('.glimpse-lightbox-element').empty();
elements.lightbox().hide();
};
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
pubsub.subscribe('trigger.shell.version.info.show', show);
pubsub.subscribe('trigger.shell.version.info.close', close);
})(jQueryGlimpse, glimpse.pubsub, glimpse.elements, glimpse.util, glimpse.settings);
// glimpse.paging.js
glimpse.paging = (function($, pubsub, util, data, elements) {
var process = function(args) {
var key = args.key,
metadata = data.currentMetadata().plugins[key];
if (metadata && (metadata = metadata.pagingInfo)) {
var panelItem = elements.panel(key);
panelItem.find('.glimpse-pager').remove();
var pageIndex = metadata.pageIndex,
pageIndexLast = Math.floor((metadata.totalNumberOfRecords - 1) / metadata.pageSize),
pagerContainer = $('<div class="glimpse-pager"></div>').appendTo(panelItem);
pubsub.publish('trigger.paging.controls.render', { key: key, pagerContainer: pagerContainer, pagerKey: metadata.pagerKey, pagerType: metadata.pagerType, pageIndex: pageIndex, pageIndexLast: pageIndexLast });
}
};
pubsub.subscribe('trigger.tab.select', process);
pubsub.subscribe('trigger.tab.paging.refresh', process);
return {};
})(jQueryGlimpse, glimpse.pubsub, glimpse.util, glimpse.data, glimpse.elements);
// glimpse.paging.engine.js
glimpse.paging.engine = (function(pubsub) {
var providers = {},
retrieve = function(name) {
return providers[name];
},
register = function(name, engine) {
providers[name] = engine;
},
render = function(args) {
var pagerEngine = providers[args.pagerType];
pagerEngine.renderControls(args.key, args.pagerContainer, args.pagerKey, args.pagerType, args.pageIndex, args.pageIndexLast);
};
pubsub.subscribe('trigger.paging.controls.render', render);
return {
retrieve: retrieve,
register: register
};
})(glimpse.pubsub);
// glimpse.paging.engine.util.js
glimpse.paging.engine.util = (function($, pubsub, data, elements, util, renderEngine) {
var generatePagingAddress = function(pagerKey, pageIndex) {
return util.uriTemplate(data.currentMetadata().resources.glimpse_paging, { 'key': pagerKey, 'pageIndex': pageIndex });
},
requestStart = function(key) {
var pager = elements.panel(key).find('.glimpse-pager');
pager.html('<span class="glimpse-pager-message">Loading...</span>');
},
requestSuccess = function(key, pagerKey, pageIndex, method, result) {
var pagingInfo = data.currentMetadata().plugins[key].pagingInfo,
content = renderEngine.build(result, data.currentMetadata().plugins[key].structure),
scope = renderMethod[method](elements.panel(key), content);
pagingInfo.pageIndex = pageIndex;
pubsub.publish('trigger.panel.render.style', { scope: scope });
pubsub.publish('trigger.tab.paging.refresh', { key: key });
},
renderMethod = {
insert: function(panelItem, content) {
panelItem.find('> table').remove();
return $(content).appendTo(panelItem);
},
append: function (panelItem, content) {
var table = panelItem.find('> table'),
nodes = $(content.substring(content.indexOf('>') + 1, content.lastIndexOf('<')))[1];
table.find('> tbody:last-child > tr:last-child').addClass('glimpse-pager-separator');
return $(nodes).appendTo(table);
}
};
return {
load: (function() {
var isLoading = false;
return function(key, pagerKey, pageIndex, method) {
if (!isLoading) {
isLoading = true;
requestStart(key);
$.ajax({
url: generatePagingAddress(pagerKey, pageIndex),
type: 'GET',
contentType: 'application/json',
success: function(result) {
requestSuccess(key, pagerKey, pageIndex, method, result);
},
complete: function () {
isLoading = false;
}
});
}
};
})()
};
})(jQueryGlimpse, glimpse.pubsub, glimpse.data, glimpse.elements, glimpse.util, glimpse.render.engine);
// glimpse.paging.engine.continuous.js
(function($, util, engine, engineUtil) {
var provider = {
removeExistingResults: false,
renderControls: function (key, pagerContainer, pagerKey, pagerType, pageIndex, pageIndexLast) {
var pagerMessage = $('<span class="glimpse-pager-message">Showing ' + (pageIndex + 1) + ' page(s) of ' + (pageIndexLast + 1) + ' pages(s).</span>');
pagerContainer.append(pagerMessage);
if (pageIndex < pageIndexLast) {
var pagerNextPageLink = $('<span href="#" class="glimpse-pager-link">More</span>');
pagerNextPageLink.one('click', function() { engineUtil.load(key, pagerKey, pageIndex + 1, 'append'); });
pagerContainer.append(pagerNextPageLink);
}
}
};
engine.register('continuous', provider);
})(jQueryGlimpse, glimpse.util, glimpse.paging.engine, glimpse.paging.engine.util);
// glimpse.paging.engine.scrolling.js
(function($, pubsub, util, engine, engineUtil, elements, data) {
var provider = {
renderControls: function (key, pagerContainer, pagerKey, pagerType, pageIndex, pageIndexLast, suppressRecheck) {
var panelItem = elements.panel(key),
clientHeight = panelItem[0].clientHeight;
if (clientHeight == 0 && !suppressRecheck) {
var that = this;
//TODO: BAD CODE - Problem is that the height isn't avaiable until the panel is visable, this code runs before that time
setTimeout(function() {
that.renderControls(key, pagerContainer, pagerKey, pagerType, pageIndex, pageIndexLast, true);
}, 300);
return;
}
var pagerMessage = $('<span class="glimpse-pager-message">Showing ' + (pageIndex + 1) + ' page(s) of ' + (pageIndexLast + 1) + ' pages(s).</span>');
pagerContainer.append(pagerMessage);
if (pageIndex < pageIndexLast) {
if (clientHeight >= panelItem.find(':last').position().top)
engineUtil.load(key, pagerKey, pageIndex + 1, 'append');
else {
var scrollingCallback = function() {
if (panelItem[0].clientHeight >= panelItem.find(':last').position().top) {
engineUtil.load(key, pagerKey, pageIndex + 1, 'append');
panelItem.unbind('scroll');
}
};
panelItem.bind('scroll', scrollingCallback);
}
}
}
};
engine.register('scrolling', provider);
})(jQueryGlimpse, glimpse.pubsub, glimpse.util, glimpse.paging.engine, glimpse.paging.engine.util, glimpse.elements, glimpse.data);
// glimpse.paging.engine.traditional.js
(function($, util, engine, engineUtil) {
var provider = {
renderControls: function (key, pagerContainer, pagerKey, pagerType, pageIndex, pageIndexLast) {
var pagerFirstPageLink = $('<span href="#" class="glimpse-button glimpse-pager-link glimpse-pager-link-firstPage"></span>'),
pagerPreviousPageLink = $('<span href="#" class="glimpse-button glimpse-pager-link glimpse-pager-link-previousPage"></span>'),
pagerMessage = $('<span class="glimpse-pager-message">' + (pageIndex + 1) + ' / ' + (pageIndexLast + 1) + '</span>'),
pagerNextPageLink = $('<span href="#" class="glimpse-button glimpse-pager-link glimpse-pager-link-nextPage"></span>'),
pagerLastPageLink = $('<span href="#" class="glimpse-button glimpse-pager-link glimpse-pager-link-lastPage"></span>');
pagerContainer.append(pagerFirstPageLink);
pagerContainer.append(pagerPreviousPageLink);
pagerContainer.append(pagerMessage);
pagerContainer.append(pagerNextPageLink);
pagerContainer.append(pagerLastPageLink);
if (pageIndex > 0) {
pagerFirstPageLink.one('click', function() { engineUtil.load(key, pagerKey, 0, 'insert'); });
pagerPreviousPageLink.one('click', function() { engineUtil.load(key, pagerKey, pageIndex - 1, 'insert'); });
} else {
pagerFirstPageLink.addClass('glimpse-pager-link-firstPage-disabled');
pagerPreviousPageLink.addClass('glimpse-pager-link-previousPage-disabled');
}
if (pageIndex < pageIndexLast) {
pagerNextPageLink.one('click', function() { engineUtil.load(key, pagerKey, pageIndex + 1, 'insert'); });
pagerLastPageLink.one('click', function() { engineUtil.load(key, pagerKey, pageIndexLast, 'insert'); });
} else {
pagerNextPageLink.addClass('glimpse-pager-link-nextPage-disabled');
pagerLastPageLink.addClass('glimpse-pager-link-lastPage-disabled');
}
}
};
engine.register('traditional', provider);
})(jQueryGlimpse, glimpse.util, glimpse.paging.engine, glimpse.paging.engine.util);
// glimpse.tab.js
glimpse.tab = (function($, pubsub, data) {
var register = function(args) {
pubsub.publish('trigger.tab.register', args);
},
registerCore = function(args) {
//TODO: need to refactor this out as static plugins should not be stored in with the instance plugins
var currentData = data.currentData(),
currentMetadata = data.currentMetadata();
currentData.data[args.key] = args.payload;
currentMetadata.plugins[args.key] = args.metadata;
pubsub.publish('trigger.tab.insert', args);
};
pubsub.subscribe('trigger.tab.register', registerCore);
return {
register: register
};
})(jQueryGlimpse, glimpse.pubsub, glimpse.data);
// glimpse.ajax.js
(function($, pubsub, util, elements, data, renderEngine) {
var context = { resultCount : 0, notice: null, isActive: false, contextRequestId: null, isSelected: false },
generateAjaxAddress = function() {
var currentMetadata = data.currentMetadata();
return util.uriTemplate(currentMetadata.resources.glimpse_ajax, { 'parentRequestId': retrieveScopeId(), 'hash': currentMetadata.hash });
},
retrieveScopeId = function() {
var payload = data.currentData();
return payload.isAjax ? payload.parentRequestId : payload.requestId;
},
wireListeners = function() {
var panel = elements.panel('ajax');
elements.optionsHolder().find('.glimpse-clear-ajax').live('click', function() { pubsub.publish('trigger.shell.panel.clear.ajax'); });
panel.find('tbody a').live('click', function() { pubsub.publish('trigger.data.context.switch', { requestId: $(this).attr('data-requestId'), type: 'ajax' }); });
panel.find('.glimpse-head-message a').live('click', function() { pubsub.publish('trigger.data.context.reset', { type: 'ajax' }); });
},
setup = function(args) {
args.newData.data.ajax = { name: 'Ajax', data: 'No requests currently detected...', isPermanent: true };
args.newData.metadata.plugins.ajax = { documentationUri: 'http://getglimpse.com/Help/Ajax-Tab' };
},
activate = function() {
var options = elements.optionsHolder().html('<div class="glimpse-clear"><a href="#" class="glimpse-clear-ajax">Clear</a></div><div class="glimpse-notice glimpse-disconnect"><div class="icon"></div><span>Disconnected...</span></div>');
context.notice = util.connectionNotice(options.find('.glimpse-notice'));
context.isSelected = true;
listenStart();
},
deactivate = function() {
elements.optionsHolder().html('');
context.notice = null;
listenStop();
context.isSelected = false;
},
listenStart = function() {
if (context.isSelected) {
context.isActive = true;
fetch();
}
},
listenStop = function() {
if (context.isSelected) {
context.isActive = false;
}
},
contextSwitch = function(args) {
var newPayload = args.newData,
oldPayload = args.oldData,
newId = newPayload.isAjax ? newPayload.parentRequestId : newPayload.requestId,
oldId = oldPayload.isAjax ? oldPayload.parentRequestId : oldPayload.requestId;
if (oldId != newId) {
elements.panel('ajax').find('tbody').empty();
context.resultCount = 0;
}
},
fetch = function() {
if (!context.isActive)
return;
//Poll for updated summary data
context.notice.prePoll();
$.ajax({
url: generateAjaxAddress(),
type: 'GET',
contentType: 'application/json',
complete : function(jqXHR, textStatus) {
if (!context.isActive)
return;
context.notice.complete(textStatus);
setTimeout(fetch, 1000);
},
success: function(result) {
if (!context.isActive)
return;
layoutRender(result);
}
});
},
layoutRender = function(result) {
if (context.resultCount == result.length)
return;
layoutBuildShell();
layoutBuildContent(result);
},
layoutBuildShell = function() {
var panel = elements.panel('ajax'),
detailPanel = panel.find('table');
if (detailPanel.length == 0) {
var detailData = [['Request URL', 'Method', 'Duration', 'Date/Time', 'View']],
detailMetadata = { layout: [ [ { data : 0, key : true, width : '40%' }, { data : 1 }, { data : 2, width : '10%', className : 'mono', align : 'right' }, { data : 3, width : '20%' }, { data : 4, width : '100px' } ] ] };
panel.html(renderEngine.build(detailData, detailMetadata)).find('table').append('<tbody class="glimpse-row-holder"></tbody>');
panel.find('table').addClass('glimpse-ellipsis').find('thead').append('<tr class="glimpse-head-message" style="display:none"><td colspan="5"><a href="#">Reset context back to starting page</a></td></tr>');
}
},
layoutBuildContent = function(result) {
var panel = elements.panel('ajax'),
detailBody = panel.find('tbody'),
html = '';
for (var x = context.resultCount; x < result.length; x++) {
var item = result[x];
html = '<tr data-requestId="' + item.requestId + '" class="glimpse-row"><td><div class="glimpse-ellipsis" title="' + item.uri + '">' + item.uri + '</div></td><td>' + item.method + '</td><td class="mono" style="text-align:right">' + item.duration + '<span class="glimpse-soft"> ms</span></td><td>' + item.dateTime + '</td><td><a href="#" class="glimpse-ajax-link" data-requestId="' + item.requestId + '">Inspect</a></td></tr>' + html;
}
detailBody.prepend(html);
context.resultCount = result.length;
if (context.contextRequestId)
selectStart({ requestId: context.contextRequestId });
},
layoutClear = function() {
pubsub.publish('trigger.data.context.reset', { type: 'ajax' });
elements.panel('ajax').html('<div class="glimpse-panel-message">No requests currently detected...</div>');
},
selectClear = function(args) {
var panel = elements.panel('ajax'),
row = panel.find('.selected');
if (row.length > 0) {
panel.find('.glimpse-head-message').hide();
row.removeClass('selected');
if (args.type == 'ajax')
data.retrieve(data.currentData().parentRequestId);
}
},
selectStart = function(args) {
var link = elements.panel('ajax').find('.glimpse-ajax-link[data-requestId="' + args.requestId + '"]');
context.contextRequestId = args.requestId;
if (link.length > 0) {
if (args.type == 'ajax') {
link.hide().parent().append('<div class="loading glimpse-ajax-loading" data-requestId="' + args.requestId + '"><div class="icon"></div>Loading...</div>');
data.retrieve(args.requestId, 'ajax');
}
else
selectCore(args.requestId);
}
else
selectClear(args);
},
selectFinish = function(args) {
var panel = elements.panel('ajax');
panel.find('.glimpse-ajax-loading[data-requestId="' + args.requestId + '"]').fadeOut(100).delay(100).remove();
panel.find('.glimpse-ajax-link[data-requestId="' + args.requestId + '"]').delay(100).fadeIn();
selectCore(args.requestId);
},
selectCore = function(requestId) {
var panel = elements.panel('ajax'),
row = panel.find('tr[data-requestId="' + requestId + '"]');
panel.find('.glimpse-head-message').show();
panel.find('.selected').removeClass('selected');
row.addClass('selected');
context.contextRequestId = null;
};
var send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
this.setRequestHeader("Glimpse-Parent-RequestID", data.baseData().requestId);
pubsub.publish('trigger.ajax.request.send');
send.apply(this, arguments);
};
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
pubsub.subscribe('action.panel.hiding.ajax', deactivate);
pubsub.subscribe('action.panel.showing.ajax', activate);
pubsub.subscribe('action.data.fetched.ajax', selectFinish);
pubsub.subscribe('action.data.refresh.changed', contextSwitch);
pubsub.subscribe('action.data.initial.changed', setup);
pubsub.subscribe('trigger.data.context.reset', selectClear);
pubsub.subscribe('trigger.shell.panel.clear.ajax', layoutClear);
pubsub.subscribe('trigger.data.context.switch', selectStart);
pubsub.subscribe('action.shell.opening', listenStart);
pubsub.subscribe('action.shell.closeing', listenStop);
pubsub.subscribe('action.shell.minimizing', listenStop);
})(jQueryGlimpse, glimpse.pubsub, glimpse.util, glimpse.elements, glimpse.data, glimpse.render.engine);
// glimpse.history.js
(function($, pubsub, util, settings, elements, data, renderEngine) {
var context = { resultCount : 0, clientName : '', requestId : '', currentData: null, notice: null, isActive: false, isSelected: false, contextRequestId: undefined },
generateHistoryAddress = function() {
var currentMetadata = data.currentMetadata();
return util.uriTemplate(currentMetadata.resources.glimpse_history, { 'hash': currentMetadata.hash });
},
wireListeners = function() {
var panel = elements.panel('history');
elements.holder().find('.glimpse-clear-history').live('click', function() { pubsub.publish('trigger.shell.panel.clear.history'); });
panel.find('.glimpse-col-main tbody a').live('click', function() { pubsub.publish('trigger.data.context.switch', { requestId: $(this).attr('data-requestId'), type: 'history' }); });
panel.find('.glimpse-col-side tbody a').live('click', function() { selectSession($(this).attr('data-clientName')); });
panel.find('.glimpse-col-main .glimpse-head-message a').live('click', function() { pubsub.publish('trigger.data.context.reset', { type: 'history' }); });
},
setup = function(args) {
args.newData.data.history = { name: 'History', data: 'No requests currently detected...', isPermanent: true };
args.newData.metadata.plugins.history = { documentationUri: 'http://getglimpse.com/Help/History-Tab' };
},
activate = function() {
var options = elements.optionsHolder().html('<div class="glimpse-clear"><a href="#" class="glimpse-clear-history">Clear</a></div><div class="glimpse-notice glimpse-disconnect"><div class="icon"></div><span>Disconnected...</span></div>');
context.notice = util.connectionNotice(options.find('.glimpse-notice'));
context.isSelected = true;
listenStart();
},
deactivate = function() {
elements.optionsHolder().html('');
context.notice = null;
listenStop();
context.isSelected = false;
},
listenStart = function() {
if (context.isSelected) {
context.isActive = true;
fetch();
}
},
listenStop = function() {
if (context.isSelected) {
context.isActive = false;
}
},
fetch = function() {
if (!context.isActive)
return;
//Poll for updated summary data
context.notice.prePoll();
$.ajax({
url: generateHistoryAddress(),
type: 'GET',
contentType: 'application/json',
complete : function(jqXHR, textStatus) {
if (!context.isActive)
return;
context.notice.complete(textStatus);
setTimeout(fetch, 1000);
},
success: function(result) {
if (!context.isActive)
return;
layoutRender(result);
}
});
},
layoutRender = function(result) {
if ($.isEmptyObject(result))
return;
context.currentData = result;
layoutBuildShell();
layoutBuildContentMaster(result);
layoutBuildContentDetail(context.clientName, result[context.clientName]);
},
layoutBuildShell = function() {
var panel = elements.panel('history'),
masterPanel = panel.find('.glimpse-col-side');
if (masterPanel.length == 0) {
panel.html('<div class="glimpse-col-main"></div><div class="glimpse-col-side"></div>');
masterPanel = panel.find('.glimpse-col-side');
var detailPanel = panel.find('.glimpse-col-main'),
masterData = [ [ 'Client', 'Count', 'View' ] ],
detailData = [ [ 'Request URL', 'Method', 'Duration', 'Date/Time', 'Is Ajax', 'View' ] ],
detailMetadata = { layout: [ [ { data : 0, key : true, width : '30%' }, { data : 1 }, { data : 2, width : '10%', className : 'mono', align : 'right' }, { data : 3, width : '20%' }, { data : 4, width : '10%' }, { data : 5, width : '100px' } ] ] };
detailPanel.html(renderEngine.build(detailData, detailMetadata)).find('table').append('<tbody class="glimpse-row-holder"></tbody>');
detailPanel.find('table').addClass('glimpse-ellipsis').find('thead').append('<tr class="glimpse-head-message" style="display:none"><td colspan="6"><a href="#">Reset context back to starting page</a></td></tr>');
masterPanel.html(renderEngine.build(masterData));
}
},
layoutBuildContentDetail = function(clientName, clientData) {
var panel = elements.panel('history'),
detailBody = panel.find('.glimpse-col-main tbody'),
html = '';
if (context.clientName != clientName) {
context.resultCount = 0;
detailBody.empty();
}
for (var x = context.resultCount; x < clientData.length; x++) {
var item = clientData[x];
html = '<tr class="glimpse-row" data-requestId="' + item.requestId + '"><td><div class="glimpse-ellipsis" title="' + item.uri + '">' + item.uri + '</div></td><td>' + item.method + '</td><td class="mono" style="text-align:right">' + item.duration + '<span class="glimpse-soft"> ms</span></td><td>' + item.dateTime + '</td><td>' + item.isAjax + '</td><td><a href="#" class="glimpse-history-link" data-requestId="' + item.requestId + '">Inspect</a></td></tr>' + html;
}
detailBody.prepend(html);
context.resultCount = clientData.length;
context.clientName = clientName;
if (context.contextRequestId)
selectStart({ requestId: context.contextRequestId, suppressClear: true });
},
layoutBuildContentMaster = function(result) {
var selected = settings.local('historyClient'),
firstFound = '',
panel = elements.panel('history'),
masterBody = panel.find('.glimpse-col-side tbody');
for (var recordName in result) {
var masterRow = masterBody.find('a[data-clientName="' + recordName + '"]').parents('tr:first'),
rowCount = masterBody.find('tr').length;
if (masterRow.length == 0)
masterRow = $('<tr class="glimpse-row"><td>' + recordName + '</td><td class="glimpse-history-count">1</td><td><a href="#" class="glimpse-Client-link" data-clientName="' + recordName + '">Inspect</a></td></tr>').prependTo(masterBody);
masterRow.find('.glimpse-history-count').text(result[recordName].length);
if (rowCount == 0)
firstFound = recordName;
}
context.clientName = result[selected] ? selected : firstFound;
selectSession(context.clientName);
},
layoutClear = function() {
pubsub.publish('trigger.data.context.reset', { type: 'history' });
elements.panel('history').html('<div class="glimpse-panel-message">No requests currently detected...</div>');
},
selectClear = function(args) {
var panel = elements.panel('history'),
detailPanel = panel.find('.glimpse-col-main'),
row = detailPanel.find('.selected');
if (row.length > 0) {
if (row.attr('data-requestId') == context.contextRequestId)
context.contextRequestId = undefined;
panel.find('.glimpse-head-message').hide();
row.removeClass('selected');
if (args.type == 'history')
data.reset();
}
},
selectStart = function(args) {
var link = elements.panel('history').find('.glimpse-history-link[data-requestId="' + args.requestId + '"]');
context.contextRequestId = args.requestId;
if (link.length > 0) {
if (args.type == 'history') {
link.hide().parent().append('<div class="loading glimpse-history-loading" data-requestId="' + args.requestId + '"><div class="icon"></div>Loading...</div>');
data.retrieve(args.requestId, 'history');
}
else
selectCore(args.requestId);
}
else
selectClear(args);
},
selectFinish = function(args) {
var panel = elements.panel('history');
panel.find('.glimpse-history-loading[data-requestId="' + args.requestId + '"]').fadeOut(100).delay(100).remove();
panel.find('.glimpse-history-link[data-requestId="' + args.requestId + '"]').delay(100).fadeIn();
selectCore(args.requestId);
},
selectCore = function(requestId) {
var panel = elements.panel('history'),
detailPanel = panel.find('.glimpse-col-main'),
row = detailPanel.find('tr[data-requestId="' + requestId + '"]');
detailPanel.find('.glimpse-head-message').show();
detailPanel.find('.selected').removeClass('selected');
row.addClass('selected');
},
selectSession = function(clientName) {
var panel = elements.panel('history'),
masterPanel = panel.find('.glimpse-col-side'),
item = masterPanel.find('a[data-clientName="' + clientName + '"]'),
clientData = context.currentData[clientName];
settings.local('historyClient', clientName),
masterPanel.find('.selected').removeClass('selected');
item.parents('tr:first').addClass('selected');
layoutBuildContentDetail(clientName, clientData);
};
pubsub.subscribe('trigger.shell.subscriptions', wireListeners);
pubsub.subscribe('action.panel.hiding.history', deactivate);
pubsub.subscribe('action.panel.showing.history', activate);
pubsub.subscribe('action.data.retrieve.succeeded.history', selectFinish);
pubsub.subscribe('action.data.initial.changed', setup);
pubsub.subscribe('trigger.data.context.reset', selectClear);
pubsub.subscribe('trigger.shell.panel.clear.history', layoutClear);
pubsub.subscribe('trigger.data.context.switch', selectStart);
pubsub.subscribe('action.shell.opening', listenStart);
pubsub.subscribe('action.shell.closeing', listenStop);
pubsub.subscribe('action.shell.minimizing', listenStop);
})(jQueryGlimpse, glimpse.pubsub, glimpse.util, glimpse.settings, glimpse.elements, glimpse.data, glimpse.render.engine);
// glimpse.timeline.js
(function($, pubsub, settings, util, renderEngine) {
var timeline = {};
// Elements
timeline.elements = (function() {
var elements = {},
find = function() {
//Main elements
elements.scope = timeline.scope;
elements.contentRow = elements.scope.find('.glimpse-tl-row-content');
elements.summaryRow = elements.scope.find('.glimpse-tl-row-summary');
elements.resizer = elements.contentRow.find('.glimpse-tl-resizer');
//Event elements
elements.contentBandScroller = elements.contentRow.find('.glimpse-tl-content-scroll');
elements.contentBandHolder = elements.contentRow.find('.glimpse-tl-band-group');
elements.contentEventHolder = elements.contentRow.find('.glimpse-tl-event-group');
elements.contentDescHolder = elements.contentRow.find('.glimpse-tl-event-desc-group');
elements.contentTableHolder = elements.contentRow.find('.glimpse-tl-table-holder');
elements.summaryBandHolder = elements.summaryRow.find('.glimpse-tl-band-group');
elements.summaryEventHolder = elements.summaryRow.find('.glimpse-tl-event-group');
elements.summaryDescHolder = elements.summaryRow.find('.glimpse-tl-event-desc-group');
//Event info element
elements.eventInfo = elements.scope.find('.glimpse-tl-event-info');
//Zoom elements
elements.zoomHolder = elements.summaryRow.find('.glimpse-tl-resizer-holder');
elements.zoomLeftHandle = elements.summaryRow.find('.glimpse-tl-resizer:first-child');
elements.zoomRightHandle = elements.summaryRow.find('.glimpse-tl-resizer:last-child');
elements.zoomLeftPadding = elements.summaryRow.find('.glimpse-tl-padding:first-child');
elements.zoomRightPadding = elements.summaryRow.find('.glimpse-tl-padding:last-child');
//Divider elements
elements.contentDividerHolder = elements.contentRow.find('.glimpse-tl-divider-line-holder');
elements.summaryDividerHolder = elements.summaryRow.find('.glimpse-tl-divider-line-holder');
};
pubsub.subscribe('action.timeline.shell.loaded', find);
return elements;
})();
// Render Shell
(function() {
var templates = {
html: '<div class="glimpse-timeline"><div class="glimpse-tl-row-summary"><div class="glimpse-tl-content-scroll"><div class="glimpse-tl-event-desc-holder glimpse-tl-col-side"><div class="glimpse-tl-band glimpse-tl-band-title">Categories<span>[Switch view]</span></div><div class="glimpse-tl-event-desc-group"></div></div><div class="glimpse-tl-band-holder glimpse-tl-col-main"><div class="glimpse-tl-band glimpse-tl-band-title"></div><div class="glimpse-tl-band-group"></div></div><div class="glimpse-tl-event-holder glimpse-tl-col-main"><div class="glimpse-tl-band glimpse-tl-band-title"></div><div class="glimpse-tl-event-group"></div></div></div><div class="glimpse-tl-padding-holder glimpse-tl-col-main"><div class="glimpse-tl-padding glimpse-tl-padding-l glimpse-tl-summary-height"></div><div class="glimpse-tl-padding glimpse-tl-padding-r glimpse-tl-summary-height"></div></div><div class="glimpse-tl-divider-holder glimpse-tl-col-main"><div class="glimpse-tl-divider-title-bar"></div><div class="glimpse-tl-divider-line-holder"></div></div><div class="glimpse-tl-resizer-holder glimpse-tl-col-main"><div class="glimpse-tl-resizer glimpse-tl-resizer-l glimpse-tl-summary-height"><div class="glimpse-tl-resizer-bar"></div><div class="glimpse-tl-resizer-handle"></div></div><div class="glimpse-tl-resizer glimpse-tl-resizer-r glimpse-tl-summary-height"><div class="glimpse-tl-resizer-bar"></div><div class="glimpse-tl-resizer-handle"></div></div></div></div><div class="glimpse-tl-row-spacer"></div><div class="glimpse-tl-row-content"><div class="glimpse-tl-content-scroll"><div class="glimpse-tl-band-holder glimpse-tl-col-main"><div class="glimpse-tl-band glimpse-tl-band-title"></div><div class="glimpse-tl-band-group"></div></div><div class="glimpse-tl-divider-holder glimpse-tl-col-main"><div class="glimpse-tl-divider-zero-holder"><div class="glimpse-tl-divider"></div></div><div class="glimpse-tl-divider-line-holder"></div></div><div class="glimpse-tl-event-holder glimpse-tl-col-main"><div class="glimpse-tl-event-holder-inner"><div class="glimpse-tl-band glimpse-tl-band-title"></div><div class="glimpse-tl-event-group"></div></div></div><div class="glimpse-tl-event-desc-holder glimpse-tl-col-side"><div class="glimpse-tl-band glimpse-tl-band-title">Events</div><div class="glimpse-tl-event-desc-group"></div></div></div><div class="glimpse-tl-content-overlay"><div class="glimpse-tl-divider-holder glimpse-tl-col-main"><div class="glimpse-tl-divider-title-bar"></div><div class="glimpse-tl-divider-zero-holder"><div class="glimpse-tl-divider"><div>0</div></div></div><div class="glimpse-tl-divider-line-holder"></div></div></div><div class="glimpse-tl-resizer"><div></div></div><div class="glimpse-tl-content-scroll" style="display:none"><div class="glimpse-tl-table-holder"></div></div></div><div class="glimpse-tl-event-info"></div></div>'
},
setup = function() {
pubsub.publish('action.timeline.template.processing', { templates: templates });
pubsub.publish('action.timeline.shell.loading');
timeline.scope.html(templates.html);
pubsub.publish('action.timeline.shell.loaded');
pubsub.publish('action.timeline.template.processed', { templates: templates });
};
pubsub.subscribe('trigger.timeline.shell.init', setup);
})();
// Render Dividers
(function(elements) {
var wireListeners = function() {
//Window resize event
$(window).resize(function() { render({}); });
},
render = function(args) {
//Setup the dividers
renderDiverders(elements.summaryDividerHolder, { startTime : 0, endTime : timeline.data.duration}, args.force);
renderDiverders(elements.contentDividerHolder, { startTime : timeline.data.startTime, endTime : timeline.data.endTime }, args.force);
//Fix height
adjustHeight();
},
renderDiverders = function(scope, range, force) {
var x;
for (x = 0; x < scope.length; x += 1) {
var holder = $(scope[x]),
dividerCount = Math.round(holder.width() / 64),
currentDividerCount = holder.find('.glimpse-tl-divider').length;
if (!force && currentDividerCount === dividerCount) { return; }
var leftOffset = 100 / dividerCount,
timeSlice = (range.endTime - range.startTime) / dividerCount,
divider = holder.find('.glimpse-tl-divider:first-child');
for (var i = 0; i < dividerCount; i += 1) {
//Create divider if needed
if (divider.length == 0) {
divider = $('<div class="glimpse-tl-divider"><div></div></div>');
holder.append(divider);
}
//Position divider
divider.css('left', (leftOffset * (i + 1)) + '%');
//Set label of divider
var time = i == (dividerCount - 1) ? range.endTime : (timeSlice * (i + 1)) + range.startTime;
divider.find('div').text(util.timeConvert(parseFloat(time)));
//Move onto next
divider = divider.next();
}
while (divider.length == 1) {
var nextDivider = divider.next();
divider.remove();
divider = nextDivider;
}
}
},
adjustHeight = function() {
//Content row divider height
var innerHeight = Math.max(elements.contentBandScroller.height(), elements.contentBandScroller.find('.glimpse-tl-band-holder').height());
elements.contentBandScroller.find('.glimpse-tl-divider-holder').height(innerHeight);
//Summary row divider height
elements.summaryRow.find('.glimpse-tl-summary-height').height(elements.summaryRow.height());
};
pubsub.subscribe('trigger.timeline.shell.subscriptions', wireListeners);
pubsub.subscribe('trigger.timeline.divider.render', render);
pubsub.subscribe('trigger.timeline.filtered', adjustHeight);
})(timeline.elements);
// Render Events
(function(elements) {
var wireListeners = function() {
elements.summaryDescHolder
.delegate('.glimpse-tl-band', 'mouseenter', function() {
if ($(this).has('input:checked').length > 0) { $(this).find('input').stop(true, true).clearQueue().fadeIn(); }
})
.delegate('.glimpse-tl-band', 'mouseleave', function() {
if ($(this).has('input:checked').length > 0) { $(this).find('input').stop(true, true).clearQueue().fadeOut(); }
})
.delegate('input', 'click', function() { categoryEvents($(this)); });
//elements.summaryDescHolder.find('input').click(function() { /*filter.category();*/ pubsub.publish('trigger.timeline.search.category'); });
},
render = function() {
pubsub.publish('action.timeline.event.rendering');
processCategories();
processEvents();
processEventSummary();
processTableData();
//view.start();
pubsub.publish('action.timeline.event.rendered');
},
processTableData = function() {
var dataResult = [ [ 'Title', 'Description', 'Category', 'Timing', 'Start Point', 'Duration', 'w/out Children' ] ],
metadata = { layout: [ [ { data : '{{0}} |({{1}})|' }, { data : 2, width : '18%' }, { data : 3, width : '9%' }, { data : 4, align : 'right', pre : 'T+ ', post : ' ms', className : 'mono', width : '100px' }, { data : 5, align : 'right', post : ' ms', className : 'mono', width : '100px' }, { data : 6, align : 'right', post : ' ms', className : 'mono', width : '100px' } ] ] };
//Massage the data
for (var i = 0; i < timeline.data.events.length; i++) {
var event = timeline.data.events[i],
data = [ event.title, event.subText, event.category, '', event.startPoint, event.duration, event.childlessDuration ];
dataResult.push(data);
}
//Insert it into the document
var result = renderEngine.build(dataResult, metadata);
elements.contentTableHolder.append(result);
//Update the output
elements.contentTableHolder.find('tbody tr').each(function(i) {
var row = $(this),
event = timeline.data.events[i],
category = timeline.data.category[event.category];
row.find('td:first-child').prepend($('<div class="glimpse-tl-event"></div>').css({ 'backgroundColor' : category.eventColor, marginLeft : (15 * event.nesting) + 'px' }));
row.find('td:nth-child(3)').css('position', 'relative').prepend($('<div class="glimpse-tl-event"></div>').css({ 'backgroundColor' : category.eventColor, 'margin-left' : event.startPersent + '%', width : event.widthPersent + '%' }));
});
},
processCategories = function() {
for (var categoryName in timeline.data.category) {
var category = timeline.data.category[categoryName];
elements.summaryDescHolder.append('<div class="glimpse-tl-band glimpse-tl-category-selected"><input type="checkbox" value="' + categoryName +'" checked="checked" /><div class="glimpse-tl-event" style="background-color:' + category.eventColor + ';"></div>' + categoryName +'</div>');
elements.summaryBandHolder.append('<div class="glimpse-tl-band"></div>');
category.holder = $('<div class="glimpse-tl-band"></div>').appendTo(elements.summaryEventHolder);
category.events = {};
}
},
processEvents = function() {
var eventStack = [], lastEvent = { startPoint : 0, duration : 0, childlessDuration : 0, endPoint : 0 };
for (var i = 0; i < timeline.data.events.length; i += 1) {
var event = timeline.data.events[i],
topEvent = eventStack.length > 0 ? eventStack[eventStack.length - 1] : null,
category = timeline.data.category[event.category],
left = (event.startPoint / timeline.data.duration) * 100,
rLeft = Math.round(left),
actualWidth = (event.duration / timeline.data.duration) * 100,
width = actualWidth == 0 ? 0 : actualWidth,
rWidth = Math.round(width),
widthStyle = (width > 0 ? 'width:' + width + '%' : ''),
maxStyle = (width <= 0 ? 'max-width:6px;' : ''),
subTextPre = (event.subText ? '(' + event.subText + ')' : ''),
subText = (subTextPre ? '<span class="glimpse-tl-event-desc-sub">' + subTextPre + '</span>' : ''),
stackParsed = false;
event.endPoint = parseFloat((event.startPoint + event.duration).toFixed(2));
//Derive event nesting
while (!stackParsed) {
if (event.startPoint > lastEvent.startPoint && event.endPoint <= lastEvent.endPoint) {
eventStack.push(lastEvent);
stackParsed = true;
}
else if (topEvent != null && topEvent.endPoint < event.endPoint) {
eventStack.pop();
topEvent = eventStack.length > 0 ? eventStack[eventStack.length - 1] : null;
stackParsed = false;
}
else
stackParsed = true;
}
//Work out childless timings
var temp = eventStack.length > 0 ? eventStack[eventStack.length - 1] : undefined;
if (temp) {
temp.childlessDuration = parseFloat((temp.childlessDuration - event.duration).toFixed(2));
}
//Save calc data
event.childlessDuration = event.duration;
event.startPersent = left;
event.endPersent = left + width;
event.widthPersent = width;
event.nesting = eventStack.length;
//Build up the event decoration
var eventDecoration = '';
if (width >= 0)
eventDecoration = '<div class="glimpse-tl-event-overlay-lh"><div class="glimpse-tl-event-overlay-li"></div><div class="glimpse-tl-event-overlay-lt">' + event.startPoint + ' ms</div></div>';
if (width > 0)
eventDecoration += '<div class="glimpse-tl-event-overlay-rh"><div class="glimpse-tl-event-overlay-ri"></div><div class="glimpse-tl-event-overlay-rt">' + event.endPoint + ' ms</div></div><div class="glimpse-tl-event-overlay-c">' + (width < 3.5 ? '...' : (event.duration + ' ms')) + '</div>';
eventDecoration = '<div class="glimpse-tl-event-overlay" style="left:' + left + '%;' + widthStyle + maxStyle + '" data-timelineItemIndex="' + i + '">' + eventDecoration + '</div>';
//Add main event HTML to DOM
elements.contentBandHolder.append('<div class="glimpse-tl-band"></div>');
elements.contentEventHolder.append('<div class="glimpse-tl-band"><div class="glimpse-tl-event" style="background-color:' + category.eventColor + ';left:' + left + '%;' + widthStyle + maxStyle + '"></div>'+ eventDecoration +'</div>');
elements.contentDescHolder.append('<div class="glimpse-tl-band" title="' + event.title + ' ' + subTextPre + '"><div class="glimpse-tl-event" style="background-color:' + category.eventColor + ';"></div>' + event.title + subText +'</div>');
//Register events for summary
deriveEventSummary(category, left, rLeft, width, rWidth);
lastEvent = event;
}
},
deriveEventSummary = function(category, left, rLeft, width, rWidth) {
for (var j = rLeft; j <= (rLeft + rWidth); ++j) {
var data = category.events[j], right = left + width;
if (data) {
data.left = Math.min(left, data.left);
data.right = Math.max(right, data.right);
}
else
category.events[j] = { left : left, right : right }
}
},
processEventSummary = function() {
var addCategoryEvent = function(category, start, finish) {
var width = (finish - start),
widthStyle = (width > 0 ? 'width:' + width + '%' : ''),
maxStyle = (width <= 0 ? 'max-width:6px;' : '');
category.holder.append('<div class="glimpse-tl-event" style="background-color:' + category.eventColor + ';left:' + start + '%;' + widthStyle + maxStyle + '"></div>');
};
for (var categoryName in timeline.data.category) {
var category = timeline.data.category[categoryName],
events = category.events,
startData = null,
next = 0;
for (var currentPoint in events) {
var current = parseInt(currentPoint);
if (!startData) { //TODO: this needs to be cleanned up, duplicate logic here
startData = events[currentPoint];
next = current + 1;
}
else if (current != next) {
addCategoryEvent(category, startData.left, events[next - 1].right);
startData = events[currentPoint];
next = current + 1;
}
else
next++;
}
if (startData) { addCategoryEvent(category, startData.left, events[next - 1].right); }
}
},
colorRows = function(args) {
var filter = args.applyAll ? '' : ':visible';
colorElement(elements.contentBandHolder.find('> div'), filter, 'glimpse-row-');
colorElement(elements.contentDescHolder.find('> div'), filter, 'glimpse-row-alt-');
colorElement(elements.summaryBandHolder.find('> div'), filter, 'glimpse-row-');
colorElement(elements.summaryDescHolder.find('> div'), filter, 'glimpse-row-alt-');
colorElement(elements.contentTableHolder.find('tbody'), filter, 'glimpse-row-');
},
colorElement = function(scope, filter, baseClass) {
var odd = baseClass + 'odd',
even = baseClass + 'even';
scope.removeClass(odd).removeClass(even);
scope.filter(filter + ':even').addClass(odd);
scope.filter(filter + ':odd').addClass(even);
},
categoryEvents = function(item) {
//Handel how the UI will look
var isChecked = item[0].checked, parent = item.parent();
parent.animate({ 'opacity' : (isChecked ? 0.95 : 0.6) }, 200);
elements.summaryEventHolder.find('.glimpse-tl-band').eq(parent.index()).animate({ 'opacity' : (isChecked ? 1 : 0.7) }, 200);
//Trigger search
//filter.category();
pubsub.publish('trigger.timeline.search.category');
};
pubsub.subscribe('trigger.timeline.shell.subscriptions', wireListeners);
pubsub.subscribe('trigger.timeline.event.render', render);
pubsub.subscribe('trigger.timeline.filtered', colorRows);
pubsub.subscribe('action.timeline.shell.switched', colorRows);
})(timeline.elements),
// Zoom
(function(elements) {
var positionLeft = function() {
var persentLeft = (elements.zoomLeftHandle.position().left / elements.zoomHolder.width()) * 100,
persentRight = (elements.zoomRightPadding.width() / elements.zoomHolder.width()) * 100;
//Set left slider
elements.zoomLeftHandle.css('left', persentLeft + '%');
elements.zoomLeftPadding.css('width', persentLeft + '%');
timeline.data.startTime = timeline.data.duration * (persentLeft / 100);
//Force render
//dividerBuilder.render(true);
pubsub.publish('trigger.timeline.divider.render', { force: true });
//Zoom in on main line items
zoomEvents(persentLeft, persentRight);
//Manage zero display
toggleZeroLine(persentLeft == 0);
//Hide events that aren't needed
//filter.zoom(persentLeft, persentRight);
pubsub.publish('trigger.timeline.search.zoom', { persentLeft: persentLeft, persentRight: persentRight });
},
positionRight = function() {
var persentRight = ((elements.zoomHolder.width() - 4 - elements.zoomRightHandle.position().left) / elements.zoomHolder.width()) * 100,
persentLeft = (elements.zoomLeftPadding.width() / elements.zoomHolder.width()) * 100;
//Set right slider
elements.zoomRightHandle.css('right', persentRight + '%');
elements.zoomRightPadding.css('width', persentRight + '%');
timeline.data.endTime = timeline.data.duration - (timeline.data.duration * (persentRight / 100));
//Force render
//dividerBuilder.render(true);
pubsub.publish('trigger.timeline.divider.render', { force: true });
//Zoom in on main line items
zoomEvents(persentLeft, persentRight);
//Hide events that aren't needed
//filter.zoom(persentLeft, persentRight);
pubsub.publish('trigger.timeline.search.zoom', { persentLeft: persentLeft, persentRight: persentRight });
},
zoomEvents = function(persentLeft, persentRight) {
var offset = (100 / (100 - persentLeft - persentRight)) * -1,
lOffset = offset * persentLeft,
rOffset = offset * persentRight;
elements.contentRow.find('.glimpse-tl-event-holder-inner').css({ left : lOffset + '%', right : rOffset + '%' });
},
toggleZeroLine = function(show) {
elements.contentRow.find('.glimpse-tl-divider-zero-holder').toggle(show);
elements.contentRow.find('.glimpse-tl-divider-line-holder').css('left', (show ? '15' : '0') + 'px');
elements.contentRow.find('.glimpse-tl-event-holder').css('marginLeft', (show ? '15' : '0') + 'px');
},
wireListeners = function() {
jQueryGlimpse.draggable({
handelScope: elements.zoomLeftHandle,
opacityScope: elements.zoomLeftHandle,
resizeScope: elements.zoomLeftHandle,
valueStyle: 'left',
isUpDown: false,
offset: 1,
min: 0,
max: function() { return (elements.zoomRightHandle.position().left - 20); },
dragging: function() { elements.zoomLeftHandle.css('left', (elements.zoomLeftHandle.position().left) + 'px'); },
dragged: function() { positionLeft(); }
});
jQueryGlimpse.draggable({
handelScope: elements.zoomRightHandle,
opacityScope: elements.zoomRightHandle,
resizeScope: elements.zoomRightHandle,
valueStyle: 'right',
isUpDown: false,
min: 0,
max: function () { return (elements.zoomHolder.width() - elements.zoomLeftHandle.position().left) - 20; },
dragging: function() { elements.zoomRightHandle.css('right', (elements.zoomHolder.width() - elements.zoomRightHandle.position().left) + 'px'); },
dragged: function() { positionRight(); }
});
};
pubsub.subscribe('trigger.timeline.shell.subscriptions', wireListeners);
})(timeline.elements);
// Filter
(function(elements) {
var criteria = {
persentLeft : 0,
persentRightFromLeft : 100,
hiddenCategories : null
},
search = function(c) {
pubsub.publish('trigger.timeline.filtering', { criteria: c });
//Go through each event doing executing search
for (var i = 0; i < timeline.data.events.length; i += 1) {
var event = timeline.data.events[i],
show = !(c.persentLeft > event.endPersent
|| c.persentRightFromLeft < event.startPersent)
&& (c.hiddenCategories == null || c.hiddenCategories[event.category] == true);
//Timeline elements
elements.contentBandHolder.find('.glimpse-tl-band').eq(i).toggle(show);
elements.contentEventHolder.find('.glimpse-tl-band').eq(i).toggle(show);
elements.contentDescHolder.find('.glimpse-tl-band').eq(i).toggle(show);
//Table elements
elements.contentTableHolder.find('tbody').eq(i).toggle(show);
}
pubsub.publish('trigger.timeline.filtered', { criteria: c });
},
zoom = function(args) {
//Pull out current search
criteria.persentLeft = args.persentLeft;
criteria.persentRightFromLeft = 100 - args.persentRight;
//Execute search
search(criteria);
},
category = function() {
//Pull out current search
var hiddenCategoriesObj = {}, hiddenCategories = elements.summaryDescHolder.find('input:checked').map(function() { return $(this).val(); }).get(); //TODO: This shouldn't do this
for (var i = 0; i < hiddenCategories.length; i++)
hiddenCategoriesObj[hiddenCategories[i]] = true;
criteria.hiddenCategories = hiddenCategoriesObj;
//Execute search
search(criteria);
};
pubsub.subscribe('trigger.timeline.search.zoom', zoom);
pubsub.subscribe('trigger.timeline.search.category', category);
})(timeline.elements);
// Info
(function(elements) {
var wireListeners = function() {
elements.scope
.delegate('.glimpse-tl-event-info', 'mouseenter', function() { elements.eventInfo.stop(true, true).clearQueue(); })
.delegate('.glimpse-tl-event-info', 'mouseleave', function() { hideBubble(); });
elements.contentRow
.delegate('.glimpse-tl-event-overlay', 'mouseenter', function() { showBubble($(this)); })
.delegate('.glimpse-tl-event-overlay', 'mouseleave', function() { hideBubble($(this)); });
elements.contentEventHolder
.delegate('.glimpse-tl-band', 'mouseenter', function() { showTip($(this)); })
.delegate('.glimpse-tl-band', 'mouseleave', function() { hideTip($(this)); });
},
showTip = function(item) {
item.find('.glimpse-tl-event-overlay').stop(true, true).fadeIn();
},
hideTip = function(item) {
item.find('.glimpse-tl-event-overlay').stop(true, true).fadeOut();
},
buildBubbleDetails = function(event, category) {
var details = '', detailKey;
for (detailKey in event.details) {
details += '<tr><th>' + detailKey + '</th><td>' + event.details[detailKey] + '</td></tr>';
}
return '<table><tr><th colspan="2"><div class="glimpse-tl-event-info-title"><div class="glimpse-tl-event" style="background-color:' + category.eventColor + ';"></div>' + event.title + ' - Details</div></th></tr><tr><th>Duration</th><td>' + event.duration + ' ms (at ' + event.startPoint + ' ms' + ( + event.duration > 1 ? (' to ' + event.endPoint + ' ms') : '' ) +')</td></tr>' + (event.duration != event.childlessDuration ? '<tr><th>w/out Children</th><td>' + event.childlessDuration + ' ms</td></tr>' : '') + (event.subText ? '<tr><th>Details</th><td>' + event.subText + '</td></tr>' : '' ) + details + '</table>';
},
updateBubble = function(item) {
var eventOffset = item.offset(),
containerOffset = elements.eventInfo.parent().offset(),
eventSize = { height : item.height(), width : item.width() },
event = timeline.data.events[item.attr('data-timelineItemIndex')],
category = timeline.data.category[event.category],
content = buildBubbleDetails(event, category);
eventOffset.top -= containerOffset.top;
eventOffset.left -= containerOffset.left;
elements.eventInfo.html(content);
var detailSize = { height : elements.eventInfo.height(), width : elements.eventInfo.width() },
newDetailLeft = Math.min(Math.max((eventOffset.left + ((eventSize.width - detailSize.width) / 2)) - 15, 5), $(document).width() - detailSize.width - 30),
newDetailTop = eventOffset.top - detailSize.height - 20;
elements.eventInfo.css('left', newDetailLeft + 'px');
elements.eventInfo.css('top', newDetailTop + 'px');
},
showBubble = function(item) {
elements.eventInfo.stop(true, true).clearQueue().delay(500).queue(function() { updateBubble(item); elements.eventInfo.show(); });
},
hideBubble = function() {
elements.eventInfo.stop(true, true).clearQueue().delay(500).fadeOut();
};
pubsub.subscribe('trigger.timeline.shell.subscriptions', wireListeners);
})(timeline.elements);
// Resize
(function(elements) {
var wireListeners = function() {
jQueryGlimpse.draggable({
handelScope: elements.resizer,
opacityScope: elements.resizer,
resizeScope: elements.resizer,
valueStyle: 'left',
isUpDown: false,
offset: 1,
min: 50,
max: 300,
dragged: function(options, position) { columnResize(position); }
});
},
columnResize = function(position) {
elements.scope.find('.glimpse-tl-col-side').width(position + 'px');
elements.scope.find('.glimpse-tl-col-main').css('left', position + 'px');
//dividerBuilder.render(false);
pubsub.publish('trigger.timeline.divider.render', {});
},
panelResize = function(args) {
if (elements.scope) {
//Work out what height we can work with
var panelHeight = (args && args.panelHeight) || settings.local('panelHeight'),
contentHeight = panelHeight - (elements.summaryRow.height() + elements.scope.find('.glimpse-tl-row-spacer').height() + 2);
elements.contentRow.height(contentHeight + 'px');
//Render Divers
pubsub.publish('trigger.timeline.divider.render', {});
}
};
pubsub.subscribe('trigger.timeline.shell.subscriptions', wireListeners);
pubsub.subscribe('trigger.shell.resize', panelResize);
pubsub.subscribe('trigger.shell.fullScreen.resize', panelResize);
pubsub.subscribe('action.panel.showed.glimpse_timeline', function() { setTimeout(panelResize, 1); });
})(timeline.elements);
// View
(function(elements) {
var wireListeners = function() {
elements.summaryRow.find('.glimpse-tl-band-title span').click(function() {
toggle();
});
},
apply = function(showTimeline, isFirst) {
if (showTimeline == null)
showTimeline = false;
pubsub.publish('action.timeline.shell.switching', { applyAll: isFirst, showTimeline: showTimeline });
elements.contentTableHolder.parent().toggle(showTimeline);
elements.contentRow.find('.glimpse-tl-content-scroll:first-child').toggle(!showTimeline);
elements.contentRow.find('.glimpse-tl-resizer').toggle(!showTimeline);
elements.contentRow.find('.glimpse-tl-content-overlay').toggle(!showTimeline);
if (!showTimeline) {
//dividerBuilder.render();
pubsub.publish('trigger.timeline.divider.render', {});
}
//eventBuilder.colorRows(isFirst);
pubsub.publish('action.timeline.shell.switched', { applyAll: isFirst, showTimeline: showTimeline });
},
toggle = function() {
var showTimeline = !(settings.local('timelineView'));
apply(showTimeline);
//glimpse.timeline.data.timeView = showTimeline;
//glimpse.pubsub.publish('state.persist');
settings.local('timelineView', showTimeline);
},
start = function() {
//apply(glimpse.timeline.data.timeView, true);
apply(settings.local('timelineView'), true);
};
pubsub.subscribe('trigger.timeline.shell.subscriptions', wireListeners);
pubsub.subscribe('trigger.timeline.shell.toggle', toggle);
pubsub.subscribe('action.timeline.event.rendered', start);
})(timeline.elements);
// Timeline
(function() {
var init = function() {
//Set defaults
timeline.data.startTime = 0;
timeline.data.endTime = timeline.data.duration;
pubsub.publish('trigger.timeline.shell.init');
pubsub.publish('trigger.timeline.shell.subscriptions');
pubsub.publish('trigger.timeline.event.render');
},
modify = function(options) {
options.templates.css += '.glimpse-panel .glimpse-tl-resizer {position: absolute;width: 4px;height: 100%;cursor: col-resize;}.glimpse-panel .glimpse-tl-row-summary {position: relative;height: 100px;}.glimpse-panel .glimpse-tl-row-summary .glimpse-tl-resizer-bar {background-color: #404040;width: 1px;height: 100%;margin-left: 2px;}.glimpse-panel .glimpse-tl-row-summary .glimpse-tl-resizer-handle {background-color: #404040;width: 5px;height: 20px;top: 0;position: absolute;-webkit-border-radius: 2px;-moz-border-radius: 2px;border-radius: 2px;}.glimpse-panel .glimpse-tl-row-spacer {background: #cfcfcf;background: -moz-linear-gradient(top, #cfcfcf 0%, #dddddd 100%);background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#cfcfcf), color-stop(100%,#dddddd));background: -webkit-linear-gradient(top, #cfcfcf 0%,#dddddd 100%);background: -o-linear-gradient(top, #cfcfcf 0%,#dddddd 100%);background: -ms-linear-gradient(top, #cfcfcf 0%,#dddddd 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#cfcfcf\', endColorstr=\'#dddddd\',GradientType=0 );background: linear-gradient(top, #cfcfcf 0%,#dddddd 100%);-webkit-box-shadow: inset 0px 1px 0px 0px #E2E2E2;-moz-box-shadow: inset 0px 1px 0px 0px #E2E2E2;box-shadow: inset 0px 1px 0px 0px #E2E2E2;border-top: 1px solid #7A7A7A;border-bottom: 1px solid #7A7A7A;height: 5px;}.glimpse-panel .glimpse-tl-col-side {position: absolute;width: 200px;height: 100%;left: 0px;}.glimpse-panel .glimpse-tl-col-main {position: absolute;left: 200px;right: 0px;top: 0px;}.glimpse-panel .glimpse-tl-row-content .glimpse-tl-col-side {border-right: 1px solid #404040;}.glimpse-panel .glimpse-tl-row-content {position: relative;height: 400px;}.glimpse-panel .glimpse-tl-row-content .glimpse-tl-resizer {left: 200px;}.glimpse-panel .glimpse-tl-row-content .glimpse-tl-resizer div {background-color: #404040;width: 1px;height: 100%;}.glimpse-panel .glimpse-tl-band {padding-top: 2px;padding-bottom: 2px;}.glimpse-panel .glimpse-tl-col-side .glimpse-tl-band {padding-top: 2px;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;padding-left: 5px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;}.glimpse-panel .glimpse-tl-band {position: relative;height: 18px;padding: 0px;}.glimpse-panel .glimpse-tl-col-main .glimpse-tl-event {position: absolute;top: 4px;margin-left: -2px;}.glimpse-panel .glimpse-tl-band-title {height: 20px !important;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;font-weight: bold;padding-top: 4px;}.glimpse-panel .glimpse-tl-event {border-radius: 2px;width: 9px;height: 9px;display: inline-block;margin: 0 5px 0 2px;/*background: -moz-linear-gradient(top, rgba(255,255,255,0.7) 0%, rgba(255,255,255,0) 40%, rgba(255,255,255,0) 70%, rgba(0,0,0,0.5) 100%);background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.7)), color-stop(40%,rgba(255,255,255,0)), color-stop(70%,rgba(255,255,255,0)), color-stop(100%,rgba(0,0,0,0.5)));background: -webkit-linear-gradient(top, rgba(255,255,255,0.7) 0%,rgba(255,255,255,0) 40%,rgba(255,255,255,0) 70%,rgba(0,0,0,0.5) 100%);background: -o-linear-gradient(top, rgba(255,255,255,0.7) 0%,rgba(255,255,255,0) 40%,rgba(255,255,255,0) 70%,rgba(0,0,0,0.5) 100%);background: -ms-linear-gradient(top, rgba(255,255,255,0.7) 0%,rgba(255,255,255,0) 40%,rgba(255,255,255,0) 70%,rgba(0,0,0,0.5) 100%);background: linear-gradient(top, rgba(255,255,255,0.7) 0%,rgba(255,255,255,0) 40%,rgba(255,255,255,0) 70%,rgba(0,0,0,0.5) 100%);*/}.glimpse-panel .glimpse-tl-col-main .glimpse-tl-event {width: 1%;min-width: 3px;}.glimpse-panel .glimpse-tl-event-info {position: absolute;top: 1px;padding: 0.75em;border: 1px solid rgba(0, 0, 0, 0.3);background-color: #FCF7BD;display: none;-webkit-border-radius: 15px;-moz-border-radius: 15px;border-radius: 15px;-webkit-box-shadow: 0px 0px 8px 0px #696969;-moz-box-shadow: 0px 0px 8px 0px #696969;box-shadow: 0px 0px 8px 0px #696969;}.glimpse-panel .glimpse-tl-event-info th, .glimpse-panel .glimpse-tl-event-info td {pad
},
prerender = function(args) {
args.pluginData._data = args.pluginData.data;
args.pluginData.data = 'Loading data, please wait...';
},
postrender = function(args) {
args.pluginData.data = args.pluginData._data;
args.pluginData._data = null;
timeline.data = args.pluginData.data;
timeline.scope = args.panel;
pubsub.publishAsync('trigger.timeline.init');
};
pubsub.subscribe('action.template.processing', modify);
pubsub.subscribe('trigger.timeline.init', init);
pubsub.subscribe('action.panel.rendering.glimpse_timeline', prerender);
pubsub.subscribe('action.panel.rendered.glimpse_timeline', postrender);
})();
})(jQueryGlimpse, glimpse.pubsub, glimpse.settings, glimpse.util, glimpse.render.engine);
// glimpse.hud.js
(function($, pubsub, data, elements, util) {
var modify = function(options) {
options.templates.css += '.glimpse-open .glimpse-hud {padding: 0 5px 0 0;float: left; }.glimpse-open .glimpse-hud-section {float: left;-webkit-transition: all 0.3s ease;-moz-transition: all 0.3s ease;-o-transition: all 0.3s ease;transition: all 0.3s ease;border-left: 11px solid #71b1d1;height: 34px;position: relative;cursor: default;}.glimpse-open .glimpse-hud-title {position: absolute;line-height: 100%;font-size: 9px;top: 2px;font-family: "Segoe UI Semibold", "Segoe UI", "Helvetica Neue", Helvetica, Arial;color: white;text-transform: uppercase;-webkit-transform-origin: 10px 20px;-moz-transform-origin: 10px 20px;-ms-transform-origin: 10px 20px;-o-transform-origin: 10px 20px;-webkit-transform: rotate(270deg);-moz-transform: rotate(270deg);-ms-transform: rotate(270deg);-o-transform: rotate(270deg);cursor: pointer;font-weight: bold;}.glimpse-open .glimpse-hud-section-inner {-webkit-transition: all 0.3s ease;-moz-transition: all 0.3s ease;-o-transition: all 0.3s ease;transition: all 0.3s ease;max-width: 999px;margin-top: -1px;}.glimpse-open .glimpse-hud-section-input {display: none;font-size: 12px;}.glimpse-open .glimpse-hud-section-input:checked ~ .glimpse-hud-section-inner {max-width: 0px;overflow: hidden;} .glimpse-open .glimpse-hud-detail {display: inline-block;padding: 0 10px;}.glimpse-open .glimpse-hud-section-inner .glimpse-hud-detail:first-child {padding-left: 15px;}.glimpse-open .glimpse-hud-section-inner .glimpse-hud-detail:last-child {padding-right: 20px;}.glimpse-open .glimpse-hud-data {-webkit-transition: color 0.3s ease;-moz-transition: color 0.3s ease;-o-transition: color 0.3s ease;transition: color 0.3s ease;}.glimpse-open .glimpse-hud-value-update {color: #71b1d1;}.glimpse-open .glimpse-hud-detail-right .glimpse-hud-header {text-align: right;} .glimpse-open .glimpse-hud-detail-extra-large, .glimpse-hud-detail-extra-large span {font-size: 2em;line-height: 100%;}.glimpse-open .glimpse-hud-detail-large, .glimpse-hud-detail-large span {font-size: 1.45em;line-height: 100%;}.glimpse-open .glimpse-hud-detail-normal, .glimpse-hud-detail-normal span, .glimpse-hud-detail-normal div {font-size: 1.2em;line-height: 100%;}.glimpse-open .glimpse-hud-detail-small, .glimpse-hud-detail-small span, .glimpse-hud-detail-small div {font-size: 1.1em;} .glimpse-open .glimpse-hud-value {font-size: 1em;line-height: 100%;margin-top: -3px;}@media screen\0 {.glimpse-open .glimpse-hud-value { margin-top: -4px; }.glimpse-open .glimpse-hud-detail-normal .glimpse-hud-header { margin-bottom: 2px; }} .glimpse-open .glimpse-hud-header {opacity: 0.6;font-size: 0.7em;line-height: 100%;}.glimpse-open .glimpse-hud-detail-extra-large .glimpse-hud-header {font-size: 0.5em;}.glimpse-open .glimpse-hud-detail-large .glimpse-hud-header {font-size: 0.6em;}.glimpse-open .glimpse-hud-prefix, .glimpse-open .glimpse-hud-postfix, .glimpse-open .glimpse-hud-spacer, .glimpse-open .glimpse-hud-plain {opacity: 0.4;font-size: 0.9em;}.glimpse-open .glimpse-hud-postfix {padding-left: 2px;}.glimpse-open .glimpse-hud-prefix {padding-right: 2px;}.glimpse-open .glimpse-hud-spacer {padding: 0 10px;}.glimpse-open .glimpse-hud-quite, .glimpse-open .glimpse-hud-quite * {opacity: 0.6;}.glimpse-open .glimpse-hud-error, .glimpse-open .glimpse-hud-error * {color: #FF8C80;}.glimpse-open .glimpse-data-trivial {display: none;}.glimpse-open .glimpse-hud-section-inner:hover ~ .glimpse-hud-popup, .glimpse-open .glimpse-hud-popup:hover {max-height: 999px;}.glimpse-open .glimpse-hud-popup {background-color: #3c454f;border-left: 11px solid #71b1d1;position: absolute;left: -11px;right: 0;z-index: 1;bottom: 0px;max-height: 0px;-webkit-transition: max-height 0.3s ease 0.2s;-moz-transition: max-height 0.3s ease 0.2s;-o-transition: max-height 0.3s ease 0.2s;transition: max-height 0.3s ease 0.2s;}.glimpse-open .glimpse-hud-popup-clear {clear: both;}.glimpse-open .glimpse-hud-popup-header {margin-bottom: 5px;}.glimpse-open .glimpse-hud-popup .glimpse-hud-detail-extra-large {margin-left: -2px;}.glimpse-open .glimpse-hud-popup-inner {padding: 10px 15px;} .glimpse-open .glimpse-hud-p
},
loaded = function(args) {
var html = '',
details = args.newData.hud,
opened = state.current();
html += display.http.render(details, opened[0]);
if (details.mvc)
html += display.host.render(details, opened[1]);
html += display.ajax.render(details, opened[2]);
elements.opener().prepend('<div class="glimpse-hud">' + html + '</div>');
state.setup();
display.host.postRender();
display.ajax.postRender();
},
state = (function() {
return {
setup: function () {
var inputs = elements.opener().find('.glimpse-hud-section-input').change(function() {
var state = [];
inputs.each(function() { state.push(this.checked); });
util.localStorage('glimpseHudDisplay', state);
});
},
current: function () {
return util.localStorage('glimpseHudDisplay') || [];
}
};
})(),
display = function() {
var rendering = (function() {
var sizes = [ 'extra-large', 'large', 'normal', 'small' ],
position = [ 'top', 'bottom', 'left', 'right' ],
align = [ 'left', 'right' ],
shouldUse = function(isVisible, details) {
if (isVisible !== undefined && isVisible) {
var isFunction = $.isFunction(isVisible);
return (isFunction && isVisible(details)) || (!isFunction && isVisible);
}
return true;
},
popup = function(structure, details) {
return '<div class="glimpse-hud-popup" style="border-color:' + structure.color + ';"><div class="glimpse-hud-title">' + structure.title + '</div><div class="glimpse-hud-popup-inner">' + structure.popup.render(details) + '</div></div>';
},
section = function(structure, details, opened) {
var html = '<div class="glimpse-hud-section glimpse-hud-section-' + structure.id + '" style="border-color:' + structure.color + '">';
html += '<label class="glimpse-hud-title" for="glimpse-hud-section-input-' + structure.id + '">' + structure.title + '</label><input type="checkbox" class="glimpse-hud-section-input" id="glimpse-hud-section-input-' + structure.id + '"' + (opened ? ' checked="checked"' : '') + ' />';
html += '<div class="glimpse-hud-section-inner">';
for (var key in structure.layout.mini) {
html += item(structure.layout.mini[key], details);
}
html += '</div>';
if (!structure.popup.suppress) { html += popup(structure, details); }
return html + '</div>';
},
item = function(item, details) {
var html = '';
if (shouldUse(item.visible, details)) {
var title = '<div class="glimpse-hud-header">' + item.title + '</div>',
postfix = item.postfix ? '<span class="glimpse-hud-postfix">' + item.postfix + '</span>' : '',
value = item.getLayoutData ? item.getLayoutData(details) : '<span class="glimpse-hud-data">' + item.getData(details) + '</span>' + postfix,
id = item.id ? ' ' + item.id : '';
html += item.getLayout ? item.getLayout(details) : '<div class="glimpse-hud-detail glimpse-hud-detail-' + sizes[item.size] + ' glimpse-hud-detail-' + position[item.position] + ' glimpse-hud-detail-' + align[item.align] + id + '" title="' + item.description + '">' + (!item.position ? title : '') + '<div class="glimpse-hud-value">' + value + '</div>' + (item.position ? title : '') + '</div>';
}
return html;
};
return {
section: section,
item: item,
popup: popup
};
})(),
process = (function() {
var item = function(layout, defaults) {
for (var key in layout) {
layout[key] = $.extend(true, {}, defaults[key], layout[key]);
}
};
return {
init: function(payload) {
item(payload.layout.mini, payload.defaults);
item(payload.layout.popup, payload.defaults);
}
};
})();
return {
http: function() {
var timingsRaw = (window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {}).timing,
structure = {
title: 'HTTP',
id: 'http',
color: '#e2875e',
popup: {
render: function(details) {
var requestDetails = details.request.data,
html = '<div class="glimpse-hud-popup-header">Browser Request</div>';
html += '<div><div class="glimpse-hud-summary-left">' + rendering.item(structure.layout.popup.request, details) + '</div>';
html += '<table class="glimpse-hud-summary glimpse-hud-summary-right"><tr><td width="1" class="glimpse-hud-listing-overflow">' + rendering.item(structure.layout.popup.host, details) + '</td></tr><tr><td class="glimpse-hud-listing-overflow">' + rendering.item(structure.layout.popup.principle, details) + '</td></tr></table></div>';
html += '<div class="glimpse-hud-popup-clear"></div>';
html += '<div class="glimpse-data-request-parts"><table><tr><td colspan="3"><div class="glimpse-hud-bar glimpse-hud-tooltips-non"><div><div class="glimpse-hud-bar-item" style="width: 100%;background-color: ' + requestDetails.browser.categoryColor + '"></div><div class="glimpse-hud-bar-item" style="width: ' + requestDetails.server.percentage + '%;background-color: ' + requestDetails.server.categoryColor + ';"></div><div class="glimpse-hud-bar-item" style="width: ' + requestDetails.network.percentage + '%;background-color: ' + requestDetails.network.categoryColor + ';"></div></div></div></td></tr><tr><td class="glimpse-data-wire-part">' + rendering.item(structure.layout.popup.wire, details) + '</td><td class="glimpse-data-server-part">' + rendering.item(structure.layout.popup.server, details) + '</td><td class="glimpse-data-client-part">' + rendering.item(structure.layout.popup.client, details) + '</td></tr></table></div>';
return html;
}
},
defaults: {
request: { title: 'Request', description: 'Total request time from click to dom ready', visible: true, size: 1, position: 0, align: 0, postfix: 'ms', getData: function(details) { return details.request.data.total.duration; } },
wire: { title: 'Wire', description: 'Total time on the network', visible: true, size: 2, position: 0, align: 0, postfix: 'ms', getData: function(details) { return details.request.data.network.duration; } },
server: { title: 'Server', description: 'Total time on the server', visible: true, size: 2, position: 0, align: 0, postfix: 'ms', getData: function(details) { return details.request.data.server.duration; } },
client: { title: 'Client', description: 'Total time once client kicks in to dom ready', visible: true, size: 2, position: 0, align: 0, postfix: 'ms', getData: function(details) { return details.request.data.browser.duration; } },
host: { title: 'Host', description: 'Server that responded to the request', visible: true, size: 2, position: 1, align: 1, postfix: '', getLayoutData: function(details) { return '<div class="glimpse-hud-listing-overflow" style="max-width:120px;">' + details.environment.data.serverName + '</div>'; } },
principle: { title: 'Principle', description: 'Principle that is currently logged in for this session', visible: function(details) { return details.environment.data.user; }, size: 2, position: 1, align: 1, postfix: '', getLayoutData: function(details) { return '<div class="glimpse-hud-listing-overflow" style="max-width:120px;">' + details.environment.data.user + '</div>'; } }
},
layout: {
mini: {
request: {},
wire: {},
server: {},
client: {},
},
popup: {
request: { title: 'Total Request Time', size: 0, position: 1, align: 1 },
wire: { position: 1, align: 1 },
server: { position: 1, align: 1 },
client: { position: 1, align: 1 },
host: { },
principle: { },
}
}
},
processTimings = function(details) {
var result = { },
networkPre = calculateTimings('navigationStart', 'requestStart'),
networkPost = calculateTimings('responseStart', 'responseEnd'),
network = networkPre + networkPost,
server = calculateTimings('requestStart', 'responseStart'),
browser = calculateTimings('responseEnd', 'loadEventEnd'),
total = network + server + browser;
result.networkSending = { categoryColor: '#FDBF45', duration: networkPre, percentage: (networkPre / total) * 100 };
result.networkReceiving = { categoryColor: '#FDBF45', duration: networkPost, percentage: (networkPost / total) * 100 };
result.network = { categoryColor: '#FDBF45', duration: network, percentage: (network / total) * 100 };
result.server = { categoryColor: '#AF78DD', duration: server, percentage: (server / total) * 100 };
result.browser = { categoryColor: '#72A3E4', duration: browser, percentage: (browser / total) * 100 };
result.total = { categoryColor: '#10E309', duration: network + server + browser, percentage: 100 };
details.request = { data: result, name: 'Request' };
},
calculateTimings = function(startIndex, finishIndex) {
return timingsRaw[finishIndex] - timingsRaw[startIndex];
},
render = function(details, opened) {
var html = '';
if (timingsRaw) {
process.init(structure);
processTimings(details);
html = rendering.section(structure, details, opened);
}
return html;
};
return {
render: render
};
}(),
host: function() {
var structure = {
title: 'Host',
id: 'host',
color: '#6161e0',
popup: {
render: function(details) {
var hasTrivial = false,
html = '<div class="glimpse-hud-popup-header">Server Side</div>';
html += '<div><table class="glimpse-hud-summary glimpse-hud-summary-space glimpse-hud-summary-left"><tr><th>' + rendering.item(structure.layout.popup.server, details) + '</th></tr><tr><td>' + rendering.item(structure.layout.popup.controller, details) + '</td></tr></table>';
html += '<table class="glimpse-hud-summary glimpse-hud-summary-space glimpse-hud-summary-right"><tr><td width="1">' + rendering.item(structure.layout.popup.action, details) + '</td>' + (details.sql ? '<td width="40"></td><td>' + rendering.item(structure.layout.popup.connections, details) + '</td>' : '') + '</tr><tr><td>' + rendering.item(structure.layout.popup.view, details) + '</td>' + (details.sql ? '<td></td><td>' + rendering.item(structure.layout.popup.queries, details) + '</td>' : '') + '</tr></table></div>';
html += '<div class="glimpse-hud-popup-clear"></div>';
html += '<table class="glimpse-hud-listing" style="table-layout:fixed;"><thead><tr><th></th><th class="glimpse-hud-listing-value glimpse-data-childless-duration">duration (ms)</th><th class="glimpse-hud-listing-value glimpse-data-childless-start-point">from start (ms)</th></tr></thead>';
for (var i = 0; i < details.timings.data.length; i++) {
var item = details.timings.data[i],
isTrivial = item.childlessDuration < 2;
if (!item.suppress) {
var maxLength = (16 + (details.sql ? 10 : 0)) - item.nesting * 2;
html += '<tbody' + (isTrivial ? ' class="glimpse-data-trivial"' : '') + '>';
html += '<tr' + (isTrivial ? ' class="glimpse-hud-quite"' : '') + '><td class="glimpse-hud-listing-overflow" style="padding-left:' + (item.nesting * 15) + 'px;" ' + (item.description.length > maxLength ? 'title="' + item.description + '"' : '') +'>' + item.description + '</td><td class="glimpse-hud-listing-value glimpse-data-childless-duration">' + item.childlessDuration + '</td><td class="glimpse-hud-listing-value glimpse-data-childless-start-point"><span class="glimpse-hud-prefix">+</span>' + item.startPoint + '</td></tr>';
if (item.queries && item.queries.listing.length > 0) {
html += '<tr><td class="glimpse-data-query-summary" style="padding-left:' + ((item.nesting * 15) + 20) + 'px;"><span class="glimpse-hud-prefix">➥</span><span class="glimpse-hud-listing-value">' + item.queries.listing.length + '</span><span class="glimpse-hud-postfix">' + (item.queries.listing.length == 1 ? 'query' : 'queries') + '</span> <span class="glimpse-hud-listing-value">' + item.queries.durationSum.toFixed(2) + '</span><span class="glimpse-hud-postfix">ms</span></td><td></td><td></td></tr>';
}
html += '</tbody>';
if (isTrivial) { hasTrivial = true; }
}
}
html += '</table>';
if (hasTrivial) {
html += '<div class="glimpse-hud-controls"><span class="glimpse-control-trivial">Show Trivial</span><span class="glimpse-control-trivial" style="display:none">Hide Trivial</span></div>';
}
return html;
}
},
defaults: {
server: { title: 'Total Server Time', description: 'Total time on the server', visible: function (details) { return details.request; }, size: 0, position: 1, align: 1, postfix: 'ms', getData: function (details) { return details.request.data.server.duration; } },
action: { title: 'Action', description: 'How long root Action took to execute', visible: function(details) { return details.mvc && details.mvc.data.actionExecutionTime != null; }, size: 1, position: 0, align: 0, postfix: 'ms', getData: function(details) { return parseInt(details.mvc.data.actionExecutionTime); } },
view: { title: 'View', description: 'How long root View took to render', visible: function(details) { return details.mvc && details.mvc.data.viewRenderTime != null; }, size: 1, position: 0, align: 0, postfix: 'ms', getData: function(details) { return parseInt(details.mvc.data.viewRenderTime); } },
controller: { title: 'Controller/Action', description: 'Name of the root Controller and Action', visible: function(details) { return details.mvc; }, size: 2, position: 0, align: 0, postfix: 'ms', getLayoutData: function(details) { return '<span class="glimpse-hud-data">' + details.mvc.data.controllerName + '</span><span class="glimpse-hud-plain">.</span><span class="glimpse-hud-data">' + details.mvc.data.actionName + '</span><span class="glimpse-hud-plain">(...)</span>'; } },
queries: { title: 'DB Queries', description: 'Total query duration and number of all SQL queries', visible: function(details) { return details.sql; }, size: 1, position: 0, align: 0, getLayoutData: function(details) { return '<span class="glimpse-hud-data">' + parseInt(details.sql.data.queryExecutionTime) + '</span><span class="glimpse-hud-postfix">ms</span><span class="glimpse-hud-spacer">/</span><span class="glimpse-hud-data">' + details.sql.data.queryCount + '</span>'; } },
connections: { title: 'DB Connections', description: 'Total query duration and number of all SQL queries', visible: function(details) { return details.sql; }, size: 1, position: 1, align: 1, getLayoutData: function(details) { return '<span class="glimpse-hud-data">' + parseInt(details.sql.data.connectionOpenTime) + '</span><span class="glimpse-hud-postfix">ms</span><span class="glimpse-hud-spacer">/</span><span class="glimpse-hud-data">' + details.sql.data.connectionCount + '</span>'; } }
},
layout: {
mini: {
action: {},
view: {},
controller: {},
queries: {},
},
popup: {
server: {},
action: { position: 1, align: 1 },
view: { position: 1, align: 1 },
controller: { position: 1, align: 1 },
queries: { position: 1, align: 1 },
connections: {},
}
}
},
processEvents = function(details) {
var eventStack = [],
lastEvent = { startPoint : 0, duration : 0, childlessDuration : 0, endPoint : 0 },
lastControllerEvent = { },
rootDuration = details.request ? details.request.data.server.duration : 1,
rootChildlessDuration = rootDuration;
for (var i = 0; i < details.timings.data.length; i += 1) {
var event = details.timings.data[i],
topEvent = eventStack.length > 0 ? eventStack[eventStack.length - 1] : null,
left = (event.startPoint / rootDuration) * 100,
width = (event.duration / rootDuration) * 100,
stackParsed = false;
event.endPoint = parseFloat((event.startPoint + event.duration).toFixed(2));
//Work out how queries are to be parsed
if (event.category == "Controller" || event.category == "Request") {
lastControllerEvent = event;
lastControllerEvent.queries = { durationSum: 0, listing: [] };
}
else if (event.category == "Command" && lastControllerEvent.queries) {
lastControllerEvent.queries.listing.push(event);
lastControllerEvent.queries.durationSum += event.duration;
event.suppress = true;
}
//Derive event nesting
while (!stackParsed) {
if (event.startPoint > lastEvent.startPoint && event.endPoint <= lastEvent.endPoint) {
eventStack.push(lastEvent);
stackParsed = true;
}
else if (topEvent != null && topEvent.endPoint < event.endPoint) {
eventStack.pop();
topEvent = eventStack.length > 0 ? eventStack[eventStack.length - 1] : null;
stackParsed = false;
}
else
stackParsed = true;
}
//Work out childless timings
var temp = eventStack.length > 0 ? eventStack[eventStack.length - 1] : undefined;
if (temp) {
temp.childlessDuration = parseFloat((temp.childlessDuration - event.duration).toFixed(2));
}
//Work out root childless timings
if (eventStack.length == 0)
rootChildlessDuration -= event.duration;
//Save calculate data
event.childlessDuration = event.duration;
event.startPercent = left;
event.endPercent = left + width;
event.widthPercent = width;
event.nesting = eventStack.length + 1;
event.description = event.title;
lastEvent = event;
}
details.timings.data.unshift({
description: 'Request: ' + (window.location.pathname + window.location.search),
title: (window.location.pathname + window.location.search),
startTime: 'NOT SURE',
duration: rootDuration,
startPoint: '0.0',
category: 'Request',
childlessDuration: Math.round(rootChildlessDuration * 10) / 10,
startPercent: 0,
endPercent: 100,
widthPercent: 100,
nesting: 0
});
},
render = function(details, opened) {
var html = '';
if (details.mvc || details.sql) {
process.init(structure);
processEvents(details);
html = rendering.section(structure, details, opened);
}
return html;
},
postRender = function() {
$('.glimpse-hud .glimpse-control-trivial').click(function() { $('.glimpse-hud .glimpse-control-trivial, .glimpse-hud .glimpse-data-trivial').toggle(); });
};
return {
render: render,
postRender: postRender
};
}(),
ajax: function() {
var count = 0,
summaryStack = [],
detailStack = [],
structure = {
title: 'Ajax',
id: 'ajax',
color: '#559fdf',
popup: {
suppress: true,
render: function(details) {
var html = '<div class="glimpse-hud-popup-header">Ajax Requests</div>';
html += '<div>' + rendering.item(structure.layout.popup.requests, details) + '</div>';
html += '<div class="glimpse-hud-popup-clear"></div>';
html += '<table style="table-layout:fixed;" class="glimpse-hud-listing glimpse-data-ajax-detail"><thead><tr><th class="glimpse-data-content-method"></th><th></th><th class="glimpse-hud-listing-value glimpse-data-duration">duration (ms)</th><th class="glimpse-hud-listing-value glimpse-data-size">size (kb)</th></tr></thead>';
html += '</table>';
return html;
}
},
defaults: {
requests: { title: 'Count', id: 'glimpse-data-ajax-count', description: 'Total Ajax requests detected on this page', visible: true, size: 1, position: 0, align: 0, getData: function(details) { return 0; } }
},
layout: {
mini: {
requests: { }
},
popup: {
requests: { title: 'Total Ajax Requests', size: 0, position: 1, align: 1 },
}
}
},
processContentType = function(type) {
return type ? type.substring(0, type.indexOf(';')) : '';
},
render = function(details, opened) {
process.init(structure);
return rendering.section(structure, details, opened);
},
update = function(method, uri, duration, size, status, statusText, time, contentType) {
//Add it when needed
if (count == 0) {
var section = $('.glimpse-hud-section-ajax');
section.find('.glimpse-hud-section-inner').append('<div class="glimpse-hud-detail glimpse-hud-detail-small glimpse-hud-listing glimpse-data-ajax-summary"></div>');
section.append(rendering.popup(structure, { }));
}
//Set the counter
var counter = $('.glimpse-data-ajax-count .glimpse-hud-data').text(++count).addClass('glimpse-hud-value-update');
setTimeout(function() {
counter.removeClass('glimpse-hud-value-update');
}, 2000);
//Update data records
var rowClass = (status == 304 ? ' glimpse-hud-quite' : !(status >= 200 && status < 300) ? ' glimpse-hud-error' : '');
recordItem('<div class="glimpse-hud-listing-row glimpse-hud-value' + rowClass + '"><div class="glimpse-hud-data glimpse-hud-quite glimpse-data-ajax-method">' + method + '</div><div class="glimpse-hud-data glimpse-hud-listing-overflow glimpse-data-ajax-uri" title="' + uri + '">' + uri + '</div><div class="glimpse-data-ajax-duration"><span class="glimpse-hud-data">' + duration + '</span><span class="glimpse-hud-postfix">ms</span></div></div>', '.glimpse-hud-section-ajax .glimpse-data-ajax-summary', summaryStack, 2);
recordItem('<tbody class="' + rowClass + '"><tr><td class="glimpse-hud-listing-overflow" title="' + uri + '" colspan="2">' + uri + '</td><td class="glimpse-hud-listing-value glimpse-data-duration">' + duration + '</td><td class="glimpse-hud-listing-value glimpse-data-size">' + (Math.round((size / 1024) * 10) / 10) + '</td></tr><tr><td class="glimpse-hud-quite glimpse-data-content-method">' + method + '</td><td class="glimpse-hud-quite glimpse-hud-listing-overflow">' + status + ' - ' + statusText + '</td><td class="glimpse-hud-quite glimpse-data-content-type glimpse-hud-listing-overflow" title="' + contentType + '">' + processContentType(contentType) + '</td><td class="glimpse-hud-quite glimpse-data-content-time">' + time.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1") + '</td></tr></tbody>', '.glimpse-hud-section-ajax .glimpse-data-ajax-detail', detailStack, 6);
},
recordItem = function(html, selector, stack, length) {
//Set row
var row = $(html).prependTo(selector);
setTimeout(function() {
row.addClass('added');
}, 1);
//Track state of the details
if (stack.length >= length)
stack.shift().remove();
stack.push(row);
},
postRender = function() {
var open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, uri, async, user, pass) {
if (uri.indexOf('Glimpse.axd') === -1) {
var startTime = new Date().getTime();
this.addEventListener("readystatechange", function() {
if (this.readyState == 4) {
update(method, uri, new Date().getTime() - startTime, this.getResponseHeader("Content-Length"), this.status, this.statusText, new Date(), this.getResponseHeader("Content-Type"));
}
}, false);
}
open.apply(this, arguments);
};
};
return {
render: render,
postRender: postRender
};
}()
};
}();
pubsub.subscribe('action.template.processing', modify);
pubsub.subscribe('action.data.initial.changed', function(args) { $(window).load(function() { setTimeout(function() { loaded(args); }, 0); }); });
})(jQueryGlimpse, glimpse.pubsub, glimpse.data, glimpse.elements, glimpse.util);
// google-code-prettify.js
if (!window.PR_SHOULD_USE_CONTINUATION) {
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],[PR.PR_STRING,/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,"\"'"]],[[PR.PR_COMMENT,/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],[PR.PR_KEYWORD,/^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|MATCH|MERGE|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|USING|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,
null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_][\w-]*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),["sql"]);
}
(function ($, pubsub) {
var modify = function (options) {
options.templates.css += '.glimpse .pln{color:#000}.glimpse .str{color:#080}.glimpse .kwd{color:#008}.glimpse .com{color:#2F4F2F}.glimpse .typ{color:#606}.glimpse .lit{color:#800}.glimpse .pun,.glimpse .opn, .glimpse .clo{color:#660}.glimpse .tag{color:#008}.glimpse .atn{color:#606}.glimpse .atv{color:#080}.glimpse .dec, .glimpse .var{color:#606}.glimpse .fun{color:red}.glimpse .prettyprint span{font-family:Consolas, monospace, serif; font-size:1.1em;}.glimpse ol.linenums{margin-top:0;margin-bottom:0}.glimpse li.L0,.glimpse li.L1,.glimpse li.L2,.glimpse li.L3,.glimpse li.L5,.glimpse li.L6,.glimpse li.L7,.glimpse li.L8{list-style-type:none}.glimpse li.L1,.glimpse li.L3,.glimpse li.L5,.glimpse li.L7,.glimpse li.L9{background:#eee}';
};
pubsub.subscribe('action.template.processing', modify);
}(jQueryGlimpse, glimpse.pubsub));
glimpse.pubsub.publish('trigger.system.start');