rack-mini-profiler 1.0.1 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/html/includes.js CHANGED
@@ -1,1103 +1,1387 @@
1
1
  "use strict";
2
- var MiniProfiler = (function () {
3
- var $;
4
-
5
- var options,
6
- container,
7
- controls,
8
- fetchedIds = [],
9
- fetchingIds = [], // so we never pull down a profiler twice
10
- ajaxStartTime,
11
- totalsControl,
12
- reqs = 0,
13
- expandedResults = false,
14
- totalTime = 0,
15
- totalSqlCount = 0
16
- ;
17
-
18
- var hasLocalStorage = function (keyPrefix) {
19
- try {
20
- // attempt to save to localStorage as Safari private windows will throw an error
21
- localStorage[keyPrefix+'-test'] = '1';
22
- localStorage.removeItem(keyPrefix+'-test');
23
- return 'localStorage' in window && window['localStorage'] !== null ;
24
- } catch (e) {
25
- return false;
26
- }
27
- };
28
-
29
- var getVersionedKey = function (keyPrefix) {
30
- return keyPrefix + '-' + options.version;
31
- };
32
-
33
- var save = function (keyPrefix, value) {
34
- if (!hasLocalStorage(keyPrefix)) { return; }
35
2
 
36
- // clear old keys with this prefix, if any
37
- for (var i = 0; i < localStorage.length; i++) {
38
- if ((localStorage.key(i) || '').indexOf(keyPrefix) > -1) {
39
- localStorage.removeItem(localStorage.key(i));
40
- }
3
+ var MiniProfiler = (function() {
4
+ var _arguments = arguments;
5
+ var options,
6
+ container,
7
+ controls,
8
+ fetchedIds = [],
9
+ fetchingIds = [],
10
+ // so we never pull down a profiler twice
11
+ ajaxStartTime,
12
+ totalsControl,
13
+ reqs = 0,
14
+ expandedResults = false,
15
+ totalTime = 0,
16
+ totalSqlCount = 0;
17
+
18
+ var hasLocalStorage = function hasLocalStorage(keyPrefix) {
19
+ try {
20
+ // attempt to save to localStorage as Safari private windows will throw an error
21
+ localStorage[keyPrefix + "-test"] = "1";
22
+ localStorage.removeItem(keyPrefix + "-test");
23
+ return "localStorage" in window && window["localStorage"] !== null;
24
+ } catch (e) {
25
+ return false;
26
+ }
27
+ };
28
+
29
+ var getVersionedKey = function getVersionedKey(keyPrefix) {
30
+ return keyPrefix + "-" + options.version;
31
+ };
32
+
33
+ // polyfills as helper functions to avoid conflicts
34
+ // needed for IE11
35
+ // remove and replace with Element.closest when we drop IE11 support
36
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
37
+
38
+ var elementMatches =
39
+ Element.prototype.msMatchesSelector ||
40
+ Element.prototype.webkitMatchesSelector;
41
+
42
+ var elementClosest = function elementClosest(el, s) {
43
+ if (typeof el.closest === "function") {
44
+ return el.closest(s);
45
+ }
46
+
47
+ do {
48
+ if (typeof el.matches === "function") {
49
+ if (el.matches(s)) return el;
50
+ } else {
51
+ if (elementMatches.call(el, s)) return el;
52
+ }
53
+
54
+ el = el.parentElement || el.parentNode;
55
+ } while (el !== null && el.nodeType === 1);
56
+
57
+ return null;
58
+ };
59
+
60
+ var save = function save(keyPrefix, value) {
61
+ if (!hasLocalStorage(keyPrefix)) {
62
+ return;
63
+ } // clear old keys with this prefix, if any
64
+
65
+ for (var i = 0; i < localStorage.length; i++) {
66
+ if ((localStorage.key(i) || "").indexOf(keyPrefix) > -1) {
67
+ localStorage.removeItem(localStorage.key(i));
68
+ }
69
+ } // save under this version
70
+
71
+ localStorage[getVersionedKey(keyPrefix)] = value;
72
+ };
73
+
74
+ var load = function load(keyPrefix) {
75
+ if (!hasLocalStorage(keyPrefix)) {
76
+ return null;
77
+ }
78
+
79
+ return localStorage[getVersionedKey(keyPrefix)];
80
+ };
81
+
82
+ var getClientPerformance = function getClientPerformance() {
83
+ return window.performance === null ? null : window.performance;
84
+ };
85
+
86
+ var fetchResults = function fetchResults(ids) {
87
+ var clientPerformance, clientProbes, i, j, p, id, idx;
88
+
89
+ for (i = 0; i < ids.length; i++) {
90
+ id = ids[i];
91
+ clientPerformance = null;
92
+ clientProbes = null;
93
+
94
+ if (window.mPt) {
95
+ clientProbes = mPt.results();
96
+
97
+ for (j = 0; j < clientProbes.length; j++) {
98
+ clientProbes[j].d = clientProbes[j].d.getTime();
41
99
  }
42
100
 
43
- // save under this version
44
- localStorage[getVersionedKey(keyPrefix)] = value;
45
- };
46
-
47
- var load = function (keyPrefix) {
48
- if (!hasLocalStorage(keyPrefix)) { return null; }
49
-
50
- return localStorage[getVersionedKey(keyPrefix)];
51
- };
52
-
53
- var fetchTemplates = function (success) {
54
- var key = 'templates',
55
- cached = load(key);
56
-
57
- if (cached) {
58
- $('body').append(cached);
59
- success();
60
- }
61
- else {
62
- $.get(options.path + 'includes.tmpl?v=' + options.version, function (data) {
63
- if (data) {
64
- save(key, data);
65
- $('body').append(data);
66
- success();
67
- }
68
- }, "text");
69
- }
70
- };
71
-
72
- var getClientPerformance = function() {
73
- return window.performance === null ? null : window.performance;
74
- };
75
-
76
- var fetchResults = function (ids) {
77
- var clientPerformance, clientProbes, i, j, p, id, idx;
78
-
79
- for (i = 0; i < ids.length; i++) {
80
- id = ids[i];
81
-
82
- clientPerformance = null;
83
- clientProbes = null;
84
-
85
- if (window.mPt) {
86
- clientProbes = mPt.results();
87
- for (j = 0; j < clientProbes.length; j++) {
88
- clientProbes[j].d = clientProbes[j].d.getTime();
89
- }
90
- mPt.flush();
91
- }
92
-
93
- if (id == options.currentId) {
94
-
95
- clientPerformance = getClientPerformance();
101
+ mPt.flush();
102
+ }
96
103
 
97
- if (clientPerformance !== null) {
98
- // ie is buggy strip out functions
99
- var copy = { navigation: {}, timing: {} };
104
+ if (id == options.currentId) {
105
+ clientPerformance = getClientPerformance();
100
106
 
101
- var timing = $.extend({}, clientPerformance.timing);
102
-
103
- for (p in timing) {
104
- if (timing.hasOwnProperty(p) && !$.isFunction(timing[p])) {
105
- copy.timing[p] = timing[p];
106
- }
107
- }
108
- if (clientPerformance.navigation) {
109
- copy.navigation.redirectCount = clientPerformance.navigation.redirectCount;
110
- }
111
- clientPerformance = copy;
112
- }
113
- } else if (ajaxStartTime !== null && clientProbes && clientProbes.length > 0) {
114
- clientPerformance = { timing: { navigationStart: ajaxStartTime.getTime() } };
115
- ajaxStartTime = null;
116
- }
117
-
118
- if ($.inArray(id, fetchedIds) < 0 && $.inArray(id, fetchingIds) < 0) {
119
- idx = fetchingIds.push(id) - 1;
120
-
121
- $.ajax({
122
- url: options.path + 'results',
123
- data: { id: id, clientPerformance: clientPerformance, clientProbes: clientProbes, popup: 1 },
124
- dataType: 'json',
125
- global: false,
126
- type: 'POST',
127
- success: function (json) {
128
- fetchedIds.push(id);
129
- if (json != "hidden") {
130
- buttonShow(json);
131
- }
132
- },
133
- complete: function () {
134
- fetchingIds.splice(idx, 1);
135
- }
136
- });
107
+ if (clientPerformance !== null) {
108
+ // ie is buggy strip out functions
109
+ var copy = {
110
+ navigation: {},
111
+ timing: {}
112
+ };
113
+ var timing = extend({}, clientPerformance.timing);
114
+
115
+ for (p in timing) {
116
+ if (
117
+ timing.hasOwnProperty(p) &&
118
+ !(typeof timing[p] === "function")
119
+ ) {
120
+ copy.timing[p] = timing[p];
137
121
  }
138
- }
139
- };
140
-
141
- var renderTemplate = function (json) {
142
- return $('#profilerTemplate').tmpl(json);
143
- };
144
-
145
-
146
- var buttonShow = function (json) {
147
- var result = renderTemplate(json);
148
-
149
- totalTime += parseFloat(json.duration_milliseconds, 10);
150
- totalSqlCount += parseInt(json.sql_count);
151
- reqs++;
152
-
153
- if (!controls && reqs > 1 && options.collapseResults && !expandedResults) {
154
- if (!totalsControl) {
155
- container.find('.profiler-result').hide();
156
-
157
- totalsControl = $("<div class='profiler-result'><div class='profiler-button profiler-totals'></div></div>");
158
- totalsControl.appendTo(container);
159
- totalsControl.on('click', function(){
160
- totalsControl.parent().find('.profiler-result').show();
161
- totalsControl.hide();
162
- expandedResults = true;
163
- });
164
-
165
- totalsControl.find('.profiler-button').show();
166
122
  }
167
123
 
168
- var reqsHtml = reqs > 1 ? ("<span class='profiler-reqs'>" + reqs + "</span>") : "";
169
- var sqlHtml = options.showTotalSqlCount && totalSqlCount > 0 ? (" / <span class='profiler-number'>" + totalSqlCount + "</span> <span class='profiler-unit'>sql</span>") : "";
170
- totalsControl.find('.profiler-button').html("<span class='profiler-number'>" +
171
- totalTime.toFixed(1) + "</span> <span class='profiler-unit'>ms</span>" +
172
- sqlHtml +
173
- reqsHtml);
124
+ if (clientPerformance.navigation) {
125
+ copy.navigation.redirectCount =
126
+ clientPerformance.navigation.redirectCount;
127
+ }
174
128
 
175
- result.hide();
129
+ clientPerformance = copy;
176
130
  }
177
-
178
- if (controls)
179
- result.insertBefore(controls);
180
- else
181
- result.appendTo(container);
182
-
183
- var button = result.find('.profiler-button'),
184
- popup = result.find('.profiler-popup');
185
-
186
- // button will appear in corner with the total profiling duration - click to show details
187
- button.on('click', function () { buttonClick(button, popup); });
188
-
189
- // small duration steps and the column with aggregate durations are hidden by default; allow toggling
190
- toggleHidden(popup);
191
-
192
- // lightbox in the queries
193
- popup.find('.profiler-queries-show').on('click', function () { queriesShow($(this), result); });
194
-
195
- // limit count
196
- if (container.find('.profiler-result').length > options.maxTracesToShow)
197
- container.find('.profiler-result').first().remove();
198
- button.show();
199
- };
200
-
201
- var toggleHidden = function (popup) {
202
- var trivial = popup.find('.profiler-toggle-trivial');
203
- var childrenTime = popup.find('.profiler-toggle-duration-with-children');
204
- var trivialGaps = popup.parent().find('.profiler-toggle-trivial-gaps');
205
-
206
- var toggleIt = function (node) {
207
- var link = $(node),
208
- klass = "profiler-" + link.attr('class').substr('profiler-toggle-'.length),
209
- isHidden = link.text().indexOf('show') > -1;
210
-
211
- popup.parent().find('.' + klass).toggle(isHidden);
212
- link.text(link.text().replace(isHidden ? 'show' : 'hide', isHidden ? 'hide' : 'show'));
213
-
214
- popupPreventHorizontalScroll(popup);
131
+ } else if (
132
+ ajaxStartTime !== null &&
133
+ clientProbes &&
134
+ clientProbes.length > 0
135
+ ) {
136
+ clientPerformance = {
137
+ timing: {
138
+ navigationStart: ajaxStartTime.getTime()
139
+ }
215
140
  };
141
+ ajaxStartTime = null;
142
+ }
143
+
144
+ if (fetchedIds.indexOf(id) < 0 && fetchingIds.indexOf(id) < 0) {
145
+ idx = fetchingIds.push(id) - 1;
146
+
147
+ (function() {
148
+ var request = new XMLHttpRequest();
149
+ var url = options.path + "results";
150
+ var params = "id="
151
+ .concat(id, "&clientPerformance=")
152
+ .concat(clientPerformance, "&clientProbes=")
153
+ .concat(clientProbes, "&popup=1");
154
+ request.open("POST", url, true);
155
+
156
+ request.onload = function() {
157
+ if (request.status >= 200 && request.status < 400) {
158
+ var json = JSON.parse(request.responseText);
159
+ fetchedIds.push(id);
160
+
161
+ if (json != "hidden" && MiniProfiler.templates) {
162
+ buttonShow(json);
163
+ }
164
+ }
216
165
 
217
- childrenTime.add(trivial).add(trivialGaps).on('click', function () {
218
- toggleIt(this);
219
- });
220
-
221
- // if option is set or all our timings are trivial, go ahead and show them
222
- if (options.showTrivial || trivial.data('show-on-load')) {
223
- toggleIt(trivial);
224
- }
225
- // if option is set, go ahead and show time with children
226
- if (options.showChildrenTime) {
227
- toggleIt(childrenTime);
228
- }
229
- };
230
-
231
- var buttonClick = function (button, popup) {
232
- // we're toggling this button/popup
233
- if (popup.is(':visible')) {
234
- popupHide(button, popup);
235
- }
236
- else {
237
- var visiblePopups = container.find('.profiler-popup:visible'),
238
- theirButtons = visiblePopups.siblings('.profiler-button');
239
-
240
- // hide any other popups
241
- popupHide(theirButtons, visiblePopups);
242
-
243
- // before showing the one we clicked
244
- popupShow(button, popup);
245
- }
246
- };
247
-
248
- var popupShow = function (button, popup) {
249
- button.addClass('profiler-button-active');
250
-
251
- popupSetDimensions(button, popup);
252
-
253
- popup.show();
254
-
255
- popupPreventHorizontalScroll(popup);
256
- };
257
-
258
- var popupSetDimensions = function (button, popup) {
259
- var px = button.position().top - 1, // position next to the button we clicked
260
- windowHeight = $(window).height(),
261
- maxHeight = windowHeight - 40; // make sure the popup doesn't extend below the fold
262
-
263
- popup
264
- .css(options.renderVerticalPosition, px)
265
- .css('max-height', maxHeight)
266
- .css(options.renderHorizontalPosition, button.outerWidth() - 3); // move left or right, based on config
267
- };
268
-
269
- var popupPreventHorizontalScroll = function (popup) {
270
- var childrenHeight = 0;
271
-
272
- popup.children().each(function () { childrenHeight += $(this).height(); });
273
-
274
- popup.css({ 'padding-right': childrenHeight > popup.height() ? 40 : 10 });
275
- };
276
-
277
- var popupHide = function (button, popup) {
278
- button.removeClass('profiler-button-active');
279
- popup.hide();
280
- };
281
-
282
- var queriesShow = function (link, result) {
283
-
284
- var px = 30,
285
- win = $(window),
286
- width = win.width() - 2 * px,
287
- height = win.height() - 2 * px,
288
- queries = result.find('.profiler-queries');
289
-
290
- // opaque background
291
- $('<div class="profiler-queries-bg"/>').appendTo('body').css({ 'height': $(document).height() }).show();
292
-
293
- // center the queries and ensure long content is scrolled
294
- queries.css(options.renderVerticalPosition, px).css({'max-height': height, 'width': width }).css(options.renderHorizontalPosition, px)
295
- .find('table').css({ 'width': width });
296
-
297
- // have to show everything before we can get a position for the first query
298
- queries.show();
299
-
300
- queriesScrollIntoView(link, queries, queries);
301
-
302
- // syntax highlighting
303
- prettyPrint();
304
- };
166
+ fetchingIds.splice(idx, 1);
167
+ };
305
168
 
306
- var queriesScrollIntoView = function (link, queries, whatToScroll) {
307
- var id = link.closest('tr').attr('data-timing-id'),
308
- cells = queries.find('tr[data-timing-id="' + id + '"]');
309
-
310
- // ensure they're in view
311
- whatToScroll.scrollTop(whatToScroll.scrollTop() + cells.first().position().top - 100);
312
-
313
- // highlight and then fade back to original bg color; do it ourselves to prevent any conflicts w/ jquery.UI or other implementations of Resig's color plugin
314
- cells.each(function () {
315
- var cell = $(this),
316
- highlightHex = '#FFFFBB',
317
- highlightRgb = getRGB(highlightHex),
318
- originalRgb = getRGB(cell.css('background-color')),
319
- getColorDiff = function (fx, i) {
320
- // adapted from John Resig's color plugin: http://plugins.jquery.com/project/color
321
- return Math.max(Math.min(parseInt((fx.pos * (originalRgb[i] - highlightRgb[i])) + highlightRgb[i], 10), 255), 0);
322
- };
323
-
324
- // we need to animate some other property to piggy-back on the step function, so I choose you, opacity!
325
- cell.css({ 'opacity': 1, 'background-color': highlightHex })
326
- .animate({ 'opacity': 1 }, { duration: 2000, step: function (now, fx) {
327
- fx.elem.style.backgroundColor = "rgb(" + [getColorDiff(fx, 0), getColorDiff(fx, 1), getColorDiff(fx, 2)].join(",") + ")";
328
- }
329
- });
169
+ request.setRequestHeader("Accept", "application/json");
170
+ request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
171
+ request.setRequestHeader(
172
+ "Content-Type",
173
+ "application/x-www-form-urlencoded"
174
+ );
175
+ request.send(params);
176
+ })();
177
+ }
178
+ }
179
+ };
180
+
181
+ var extend = function extend(out) {
182
+ out = out || {};
183
+
184
+ for (var i = 1; i < _arguments.length; i++) {
185
+ if (!_arguments[i]) continue;
186
+
187
+ for (var key in _arguments[i]) {
188
+ if (_arguments[i].hasOwnProperty(key)) out[key] = _arguments[i][key];
189
+ }
190
+ }
191
+
192
+ return out;
193
+ };
194
+
195
+ var renderTemplate = function renderTemplate(json) {
196
+ var textDom = MiniProfiler.templates.profilerTemplate(json);
197
+ var tempElement = document.createElement("DIV");
198
+ tempElement.innerHTML = textDom;
199
+ return tempElement.children[0];
200
+ };
201
+
202
+ var buttonShow = function buttonShow(json) {
203
+ var result = renderTemplate(json);
204
+ totalTime += parseFloat(json.duration_milliseconds, 10);
205
+ totalSqlCount += parseInt(json.sql_count);
206
+ reqs++;
207
+
208
+ if (!controls && reqs > 1 && options.collapseResults && !expandedResults) {
209
+ if (!totalsControl) {
210
+ toArray(container.querySelectorAll(".profiler-result")).forEach(
211
+ function(el) {
212
+ return (el.style.display = "none");
213
+ }
214
+ );
215
+ totalsControl = document.createElement("div");
216
+ totalsControl.setAttribute("class", "profiler-result");
217
+ totalsControl.innerHTML =
218
+ "<div class='profiler-button profiler-totals'></div>";
219
+ container.appendChild(totalsControl);
220
+ totalsControl.addEventListener("click", function() {
221
+ toArray(
222
+ totalsControl.parentNode.querySelectorAll(".profiler-result")
223
+ ).forEach(function(el) {
224
+ return (el.style.display = "block");
225
+ });
226
+ totalsControl.style.display = "none";
227
+ expandedResults = true;
330
228
  });
229
+ toArray(totalsControl.querySelectorAll(".profiler-button")).forEach(
230
+ function(el) {
231
+ return (el.style.display = "block");
232
+ }
233
+ );
234
+ }
235
+
236
+ var reqsHtml =
237
+ reqs > 1 ? "<span class='profiler-reqs'>" + reqs + "</span>" : "";
238
+ var sqlHtml =
239
+ options.showTotalSqlCount && totalSqlCount > 0
240
+ ? " / <span class='profiler-number'>" +
241
+ totalSqlCount +
242
+ "</span> <span class='profiler-unit'>sql</span>"
243
+ : "";
244
+ totalsControl.querySelector(".profiler-button").innerHTML =
245
+ "<span class='profiler-number'>" +
246
+ totalTime.toFixed(1) +
247
+ "</span> <span class='profiler-unit'>ms</span>" +
248
+ sqlHtml +
249
+ reqsHtml;
250
+ result.style.display = "none";
251
+ }
252
+
253
+ if (controls) result.insertBefore(controls);
254
+ else container.appendChild(result);
255
+ var button = result.querySelector(".profiler-button"),
256
+ popup = result.querySelector(".profiler-popup"); // button will appear in corner with the total profiling duration - click to show details
257
+
258
+ button.addEventListener("click", function() {
259
+ buttonClick(button, popup);
260
+ }); // small duration steps and the column with aggregate durations are hidden by default; allow toggling
261
+
262
+ toggleHidden(popup); // lightbox in the queries
263
+
264
+ toArray(popup.querySelectorAll(".profiler-queries-show")).forEach(function(
265
+ el
266
+ ) {
267
+ el.addEventListener("click", function() {
268
+ queriesShow(this, result);
269
+ });
270
+ }); // limit count
271
+
272
+ if (
273
+ container.querySelectorAll(".profiler-result").length >
274
+ options.maxTracesToShow
275
+ ) {
276
+ var elem = container.querySelector(".profiler-result");
277
+
278
+ if (elem) {
279
+ elem.parentElement.removeChild(elem);
280
+ }
281
+ }
282
+
283
+ button.style.display = "block";
284
+ };
285
+
286
+ var toggleHidden = function toggleHidden(popup) {
287
+ var trivial = popup.querySelector(".profiler-toggle-trivial");
288
+ var childrenTime = popup.querySelector(
289
+ ".profiler-toggle-duration-with-children"
290
+ );
291
+ var trivialGaps = popup.parentNode.querySelector(
292
+ ".profiler-toggle-trivial-gaps"
293
+ );
294
+
295
+ var toggleIt = function toggleIt(node) {
296
+ var link = node,
297
+ klass =
298
+ "profiler-" +
299
+ link.getAttribute("class").substr("profiler-toggle-".length),
300
+ isHidden = link.textContent.indexOf("show") > -1;
301
+ var elements = toArray(popup.parentNode.querySelectorAll("." + klass));
302
+
303
+ if (isHidden) {
304
+ elements.forEach(function(el) {
305
+ return (el.style.display = "table-row");
306
+ });
307
+ } else {
308
+ elements.forEach(function(el) {
309
+ return (el.style.display = "none");
310
+ });
311
+ }
312
+
313
+ var text = link.textContent;
314
+ link.textContent = text.replace(
315
+ isHidden ? "show" : "hide",
316
+ isHidden ? "hide" : "show"
317
+ );
318
+ popupPreventHorizontalScroll(popup);
331
319
  };
332
320
 
333
- // Color Conversion functions from highlightFade
334
- // By Blair Mitchelmore
335
- // http://jquery.offput.ca/highlightFade/
336
- // Parse strings looking for color tuples [255,255,255]
337
- var getRGB = function (color) {
338
- var result;
339
-
340
- // Check if we're already dealing with an array of colors
341
- if (color && color.constructor == Array && color.length == 3) return color;
342
-
343
- // Look for rgb(num,num,num)
344
- if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
345
-
346
- // Look for rgb(num%,num%,num%)
347
- if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55];
348
-
349
- // Look for #a0b1c2
350
- if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];
351
-
352
- // Look for #fff
353
- if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)];
354
-
355
- // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
356
- if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) return [0,0,0,0];
357
-
358
- return null;
359
- };
360
-
361
- var bindDocumentEvents = function () {
362
- $(document).on('click.mini-profiler keyup.mini-profiler', function (e) {
363
-
364
- // this happens on every keystroke, and :visible is crazy expensive in IE <9
365
- // and in this case, the display:none check is sufficient.
366
- var popup = $('.profiler-popup').filter(function () { return $(this).css("display") !== "none"; });
367
-
368
- if (!popup.length) {
369
- return;
370
- }
371
-
372
- var button = popup.siblings('.profiler-button'),
373
- queries = popup.closest('.profiler-result').find('.profiler-queries'),
374
- bg = $('.profiler-queries-bg'),
375
- isEscPress = e.type == 'keyup' && e.which == 27,
376
- hidePopup = false,
377
- hideQueries = false;
378
-
379
- if (bg.is(':visible')) {
380
- hideQueries = isEscPress || (e.type == 'click' && !$.contains(queries[0], e.target) && !$.contains(popup[0], e.target));
381
- }
382
- else if (popup.is(':visible')) {
383
- hidePopup = isEscPress || (e.type == 'click' && !$.contains(popup[0], e.target) && !$.contains(button[0], e.target) && button[0] != e.target);
384
- }
385
-
386
- if (hideQueries) {
387
- bg.remove();
388
- queries.hide();
389
- }
390
-
391
- if (hidePopup) {
392
- popupHide(button, popup);
393
- }
321
+ [childrenTime, trivial, trivialGaps].forEach(function(el) {
322
+ if (el) {
323
+ el.addEventListener("click", function() {
324
+ toggleIt(this);
394
325
  });
395
- $(document).on('keydown.mini-profiler', null, options.toggleShortcut, function(e) {
396
- $('.profiler-results').toggle();
397
- sessionStorage['rack-mini-profiler-start-hidden'] = $('.profiler-results').is(':hidden');
326
+ }
327
+ }); // if option is set or all our timings are trivial, go ahead and show them
328
+
329
+ if (
330
+ trivial &&
331
+ (options.showTrivial || trivial.getAttribute("show-on-load"))
332
+ ) {
333
+ toggleIt(trivial);
334
+ } // if option is set, go ahead and show time with children
335
+
336
+ if (childrenTime && options.showChildrenTime) {
337
+ toggleIt(childrenTime);
338
+ }
339
+ };
340
+
341
+ var toArray = function toArray(list) {
342
+ var arr = [];
343
+
344
+ if (!list) {
345
+ return arr;
346
+ }
347
+
348
+ for (var i = 0; i < list.length; i++) {
349
+ arr.push(list[i]);
350
+ }
351
+
352
+ return arr;
353
+ };
354
+
355
+ var buttonClick = function buttonClick(button, popup) {
356
+ // we're toggling this button/popup
357
+ if (popup.offsetWidth > 0 || popup.offsetHeight > 0) {
358
+ // if visible
359
+ popupHide(button, popup);
360
+ } else {
361
+ var visiblePopups = toArray(
362
+ container.querySelectorAll(".profiler-popup")
363
+ ).filter(function(el) {
364
+ return el.offsetWidth > 0 || el.offsetHeight > 0;
365
+ }); // theirButtons = visiblePopups.siblings(".profiler-button");
366
+
367
+ var theirButtons = [];
368
+ visiblePopups.forEach(function(el) {
369
+ theirButtons.push(el.parentNode.querySelector(".profiler-button"));
370
+ }); // hide any other popups
371
+
372
+ popupHide(theirButtons, visiblePopups); // before showing the one we clicked
373
+
374
+ popupShow(button, popup);
375
+ }
376
+ };
377
+
378
+ var popupShow = function popupShow(button, popup) {
379
+ button.classList.add("profiler-button-active");
380
+ popupSetDimensions(button, popup);
381
+ popup.style.display = "block";
382
+ popupPreventHorizontalScroll(popup);
383
+ };
384
+
385
+ var popupSetDimensions = function popupSetDimensions(button, popup) {
386
+ var px = button.offsetTop - 1,
387
+ // position next to the button we clicked
388
+ windowHeight = window.innerHeight,
389
+ maxHeight = windowHeight - 40; // make sure the popup doesn't extend below the fold
390
+
391
+ popup.style[options.renderVerticalPosition] = "".concat(px, "px");
392
+ popup.style.maxHeight = "".concat(maxHeight, "px");
393
+ popup.style[options.renderHorizontalPosition] = "".concat(
394
+ button.offsetWidth - 3,
395
+ "px"
396
+ ); // move left or right, based on config
397
+ };
398
+
399
+ var popupPreventHorizontalScroll = function popupPreventHorizontalScroll(
400
+ popup
401
+ ) {
402
+ var childrenHeight = 0;
403
+ toArray(popup.children).forEach(function(el) {
404
+ childrenHeight += el.offsetHeight;
405
+ });
406
+ popup.style.paddingRight = "".concat(
407
+ childrenHeight > popup.offsetHeight ? 40 : 10,
408
+ "px"
409
+ );
410
+ };
411
+
412
+ var popupHide = function popupHide(button, popup) {
413
+ if (button) {
414
+ if (Array.isArray(button)) {
415
+ button.forEach(function(el) {
416
+ return el.classList.remove("profiler-button-active");
398
417
  });
399
-
400
- if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {
401
- $(document).on('page:change.mini-profiler turbolinks:load.mini-profiler', function() {
402
- unbindDocumentEvents();
403
- });
404
- }
418
+ } else {
419
+ button.classList.remove("profiler-button-active");
420
+ }
421
+ }
422
+
423
+ if (popup) {
424
+ if (Array.isArray(popup)) {
425
+ popup.forEach(function(el) {
426
+ return (el.style.display = "none");
427
+ });
428
+ } else {
429
+ popup.style.display = "none";
430
+ }
431
+ }
432
+ };
433
+
434
+ var queriesShow = function queriesShow(link, result) {
435
+ result = result;
436
+ var px = 30,
437
+ win = window,
438
+ width = win.innerWidth - 2 * px,
439
+ height = win.innerHeight - 2 * px,
440
+ queries = result.querySelector(".profiler-queries"); // opaque background
441
+
442
+ var background = document.createElement("div");
443
+ background.classList.add("profiler-queries-bg");
444
+ document.body.appendChild(background);
445
+ background.style.height = "".concat(window.innerHeight, "px");
446
+ background.style.display = "block"; // center the queries and ensure long content is scrolled
447
+
448
+ queries.style[options.renderVerticalPosition] = "".concat(px, "px");
449
+ queries.style.maxHeight = "".concat(height, "px");
450
+ queries.style.width = "".concat(width, "px");
451
+ queries.style[options.renderHorizontalPosition] = "".concat(px, "px");
452
+ queries.querySelector("table").style.width = "".concat(width, "px"); // have to show everything before we can get a position for the first query
453
+
454
+ queries.style.display = "block";
455
+ queriesScrollIntoView(link, queries, queries); // syntax highlighting
456
+
457
+ prettyPrint();
458
+ };
459
+
460
+ var queriesScrollIntoView = function queriesScrollIntoView(
461
+ link,
462
+ queries,
463
+ whatToScroll
464
+ ) {
465
+ var id = elementClosest(link, "tr").getAttribute("data-timing-id"),
466
+ cells = toArray(
467
+ queries.querySelectorAll('tr[data-timing-id="' + id + '"]')
468
+ ); // ensure they're in view
469
+
470
+ whatToScroll.scrollTop =
471
+ (whatToScroll.scrollTop || 0) + cells[0].offsetTop - 100; // highlight and then fade back to original bg color; do it ourselves to prevent any conflicts w/ jquery.UI or other implementations of Resig's color plugin
472
+
473
+ cells.forEach(function(el) {
474
+ el.classList.add("higlight-animate");
475
+ });
476
+ setTimeout(function() {
477
+ cells.forEach(function(el) {
478
+ return el.classList.remove("higlight-animate");
479
+ });
480
+ }, 3000);
481
+ };
482
+
483
+ var onClickEvents = function onClickEvents(e) {
484
+ // this happens on every keystroke, and :visible is crazy expensive in IE <9
485
+ // and in this case, the display:none check is sufficient.
486
+ var popup = toArray(document.querySelectorAll(".profiler-popup")).filter(
487
+ function(el) {
488
+ return el.style.display === "block";
489
+ }
490
+ );
491
+
492
+ if (!popup.length) {
493
+ return;
494
+ }
495
+
496
+ popup = popup[0];
497
+ var button = popup.parentNode.querySelector(".profiler-button"),
498
+ queries = elementClosest(popup, ".profiler-result").querySelector(
499
+ ".profiler-queries"
500
+ ),
501
+ bg = document.querySelector(".profiler-queries-bg"),
502
+ isEscPress = e.type == "keyup" && e.which == 27,
503
+ hidePopup = false,
504
+ hideQueries = false;
505
+
506
+ if (bg && bg.style.display === "block") {
507
+ hideQueries =
508
+ isEscPress ||
509
+ (e.type == "click" &&
510
+ !(queries !== e.target && queries.contains(e.target)) &&
511
+ !(popup !== e.target && popup.contains(e.target)));
512
+ } else if (popup.style.display === "block") {
513
+ hidePopup =
514
+ isEscPress ||
515
+ (e.type == "click" &&
516
+ !(popup !== e.target && popup.contains(e.target)) &&
517
+ !(button !== e.target && button.contains(e.target)) &&
518
+ button != e.target);
519
+ }
520
+
521
+ if (hideQueries) {
522
+ bg.parentElement.removeChild(bg);
523
+ queries.style.display = "none";
524
+ }
525
+
526
+ if (hidePopup) {
527
+ popupHide(button, popup);
528
+ }
529
+ };
530
+
531
+ var keydownEvent = function keydownEvent() {
532
+ var results = document.querySelector(".profiler-results");
533
+
534
+ if (results.style.display === "none") {
535
+ results.style.display = "block";
536
+ } else {
537
+ results.style.display = "none";
538
+ }
539
+
540
+ sessionStorage["rack-mini-profiler-start-hidden"] =
541
+ results.style.display === "none";
542
+ };
543
+
544
+ var toggleShortcutEvent = function toggleShortcutEvent(e) {
545
+ // simplified version of https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js
546
+ var shortcut = options.toggleShortcut.toLowerCase();
547
+ var modifier = "";
548
+ ["alt", "ctrl", "shift"].forEach(function(k) {
549
+ if (e[k + "Key"]) {
550
+ modifier += "".concat(k, "+");
551
+ }
552
+ });
553
+ var specialKeys = {
554
+ 8: "backspace",
555
+ 9: "tab",
556
+ 10: "return",
557
+ 13: "return",
558
+ 16: "shift",
559
+ 17: "ctrl",
560
+ 18: "alt",
561
+ 27: "esc",
562
+ 32: "space",
563
+ 59: ";",
564
+ 61: "=",
565
+ 96: "0",
566
+ 97: "1",
567
+ 98: "2",
568
+ 99: "3",
569
+ 100: "4",
570
+ 101: "5",
571
+ 102: "6",
572
+ 103: "7",
573
+ 104: "8",
574
+ 105: "9",
575
+ 106: "*",
576
+ 107: "+",
577
+ 109: "-",
578
+ 110: ".",
579
+ 173: "-",
580
+ 186: ";",
581
+ 187: "="
405
582
  };
406
-
407
- var unbindDocumentEvents = function() {
408
- $(document).off('.mini-profiler');
583
+ var shiftNums = {
584
+ "`": "~",
585
+ "1": "!",
586
+ "2": "@",
587
+ "3": "#",
588
+ "4": "$",
589
+ "5": "%",
590
+ "6": "^",
591
+ "7": "&",
592
+ "8": "*",
593
+ "9": "(",
594
+ "0": ")",
595
+ "-": "_",
596
+ "=": "+",
597
+ ";": ": ",
598
+ "'": '"',
599
+ ",": "<",
600
+ ".": ">",
601
+ "/": "?",
602
+ "\\": "|"
409
603
  };
410
-
411
- var initFullView = function () {
412
-
413
- // first, get jquery tmpl, then render and bind handlers
414
- fetchTemplates(function () {
415
-
416
- // profiler will be defined in the full page's head
417
- renderTemplate(profiler).appendTo(container);
418
-
419
- var popup = $('.profiler-popup');
420
-
421
- toggleHidden(popup);
422
-
423
- prettyPrint();
424
-
425
- // since queries are already shown, just highlight and scroll when clicking a "1 sql" link
426
- popup.find('.profiler-queries-show').on('click', function () {
427
- queriesScrollIntoView($(this), $('.profiler-queries'), $(document));
428
- });
604
+ var character = String.fromCharCode(e.which).toLowerCase();
605
+ var special = specialKeys[e.which];
606
+ var keys = [];
607
+
608
+ if (special) {
609
+ keys.push(special);
610
+ } else {
611
+ keys.push(character);
612
+ keys.push(shiftNums[character]);
613
+ }
614
+
615
+ for (var i = 0; i < keys.length; i++) {
616
+ if (modifier + keys[i] === shortcut) {
617
+ keydownEvent();
618
+ break;
619
+ }
620
+ }
621
+ };
622
+
623
+ var bindDocumentEvents = function bindDocumentEvents() {
624
+ document.addEventListener("click", onClickEvents);
625
+ document.addEventListener("keyup", onClickEvents);
626
+ document.addEventListener("keyup", toggleShortcutEvent);
627
+
628
+ if (typeof Turbolinks !== "undefined" && Turbolinks.supported) {
629
+ document.addEventListener("page:change", unbindDocumentEvents);
630
+ document.addEventListener("turbolinks:load", unbindDocumentEvents);
631
+ }
632
+ };
633
+
634
+ var unbindDocumentEvents = function unbindDocumentEvents() {
635
+ document.removeEventListener("click", onClickEvents);
636
+ document.removeEventListener("keyup", onClickEvents);
637
+ document.removeEventListener("keyup", toggleShortcutEvent);
638
+ document.removeEventListener("page:change", unbindDocumentEvents);
639
+ document.removeEventListener("turbolinks:load", unbindDocumentEvents);
640
+ };
641
+
642
+ var initFullView = function initFullView() {
643
+ // profiler will be defined in the full page's head
644
+ container[0].appendChild(renderTemplate(profiler));
645
+ var popup = document.querySelector(".profiler-popup");
646
+ toggleHidden(popup);
647
+ prettyPrint(); // since queries are already shown, just highlight and scroll when clicking a "1 sql" link
648
+
649
+ toArray(popup.querySelectorAll(".profiler-queries-show")).forEach(function(
650
+ el
651
+ ) {
652
+ el.addEventListener("click", function() {
653
+ queriesScrollIntoView(
654
+ this,
655
+ document.querySelector(".profiler-queries"),
656
+ document.body
657
+ );
658
+ });
659
+ });
660
+ };
661
+
662
+ var initControls = function initControls(container) {
663
+ if (options.showControls) {
664
+ var _controls = document.createElement("div");
665
+
666
+ _controls.classList.add("profiler-controls");
667
+
668
+ _controls.innerHTML =
669
+ '<span class="profiler-min-max">m</span><span class="profiler-clear">c</span>';
670
+ container.appendChild(_controls);
671
+ document
672
+ .querySelector(".profiler-controls .profiler-min-max")
673
+ .addEventListener("click", function() {
674
+ return toggleClass(container, "profiler-min");
429
675
  });
430
- };
431
-
432
- var initControls = function (container) {
433
- if (options.showControls) {
434
- controls = $('<div class="profiler-controls"><span class="profiler-min-max">m</span><span class="profiler-clear">c</span></div>').appendTo(container);
435
-
436
- $('.profiler-controls .profiler-min-max').on('click', function () {
437
- container.toggleClass('profiler-min');
438
- });
439
-
440
- container.hover(function () {
441
- if ($(this).hasClass('profiler-min')) {
442
- $(this).find('.profiler-min-max').show();
443
- }
444
- },
445
- function () {
446
- if ($(this).hasClass('profiler-min')) {
447
- $(this).find('.profiler-min-max').hide();
448
- }
449
- });
450
-
451
- $('.profiler-controls .profiler-clear').on('click', function () {
452
- container.find('.profiler-result').remove();
453
- });
676
+ container.addEventListener("mouseenter", function() {
677
+ if (this.classList.contains("profiler-min")) {
678
+ this.querySelector(".profiler-min-max").style.display = "block";
454
679
  }
455
- else {
456
- container.addClass('profiler-no-controls');
680
+ });
681
+ container.addEventListener("mouseleave", function() {
682
+ if (this.classList.contains("profiler-min")) {
683
+ this.querySelector(".profiler-min-max").style.display = "none";
457
684
  }
458
- };
459
-
460
- var initPopupView = function () {
461
-
462
- if (options.authorized) {
463
- // all fetched profilings will go in here
464
- container = $('<div class="profiler-results"/>').appendTo(options.htmlContainer);
465
-
466
- // MiniProfiler.RenderIncludes() sets which corner to render in - default is upper left
467
- container.addClass("profiler-" + options.renderHorizontalPosition);
468
- container.addClass("profiler-" + options.renderVerticalPosition);
469
-
470
- //initialize the controls
471
- initControls(container);
472
-
473
- // we'll render results json via a jquery.tmpl - after we get the templates, we'll fetch the initial json to populate it
474
- fetchTemplates(function () {
475
- // get master page profiler results
476
- fetchResults(options.ids);
477
- });
478
- if (options.startHidden) container.hide();
685
+ });
686
+ document
687
+ .querySelector(".profiler-controls .profiler-clear")
688
+ .addEventListener("click", function() {
689
+ toArray(container.querySelectorAll(".profiler-result")).forEach(
690
+ function(el) {
691
+ return el.parentElement.removeChild(el);
692
+ }
693
+ );
694
+ });
695
+ } else {
696
+ container.classList.add("profiler-no-controls");
697
+ }
698
+ };
699
+
700
+ var toggleClass = function toggleClass(el, className) {
701
+ if (el.classList) {
702
+ el.classList.toggle(className);
703
+ } else {
704
+ var classes = el.className.split(" ");
705
+ var existingIndex = classes.indexOf(className);
706
+ if (existingIndex >= 0) classes.splice(existingIndex, 1);
707
+ else classes.push(className);
708
+ el.className = classes.join(" ");
709
+ }
710
+ };
711
+
712
+ var initPopupView = function initPopupView() {
713
+ if (options.authorized) {
714
+ // all fetched profilings will go in here
715
+ container = document.createElement("div");
716
+ container.className = "profiler-results";
717
+ document.querySelector(options.htmlContainer).appendChild(container); // MiniProfiler.RenderIncludes() sets which corner to render in - default is upper left
718
+
719
+ container.classList.add("profiler-" + options.renderHorizontalPosition);
720
+ container.classList.add("profiler-" + options.renderVerticalPosition); //initialize the controls
721
+
722
+ initControls(container);
723
+ fetchResults(options.ids);
724
+
725
+ if (options.startHidden) container.style.display = "none";
726
+ } else {
727
+ fetchResults(options.ids);
728
+ }
729
+
730
+ var send = XMLHttpRequest.prototype.send;
731
+
732
+ XMLHttpRequest.prototype.send = function(data) {
733
+ ajaxStartTime = new Date();
734
+ this.addEventListener("load", function() {
735
+ // responseURL isn't available in IE11
736
+ if (
737
+ this.responseURL &&
738
+ this.responseURL.indexOf(window.location.origin) !== 0
739
+ ) {
740
+ return;
479
741
  }
480
- else {
481
- fetchResults(options.ids);
742
+ // getAllResponseHeaders isn't available in Edge.
743
+ var allHeaders = this.getAllResponseHeaders
744
+ ? this.getAllResponseHeaders()
745
+ : null;
746
+ if (
747
+ allHeaders &&
748
+ allHeaders.toLowerCase().indexOf("x-miniprofiler-ids") === -1
749
+ ) {
750
+ return;
482
751
  }
752
+ // should be a string of comma-separated ids
753
+ var stringIds = this.getResponseHeader("X-MiniProfiler-Ids");
483
754
 
484
- var jQueryAjaxComplete = function (e, xhr, settings) {
485
- if (xhr) {
486
- // should be an array of strings, e.g. ["008c4813-9bd7-443d-9376-9441ec4d6a8c","16ff377b-8b9c-4c20-a7b5-97cd9fa7eea7"]
487
- var stringIds = xhr.getResponseHeader('X-MiniProfiler-Ids');
488
- if (stringIds) {
489
- var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
490
- fetchResults(ids);
491
- }
755
+ if (stringIds) {
756
+ var ids = stringIds.split(",");
757
+ fetchResults(ids);
758
+ }
759
+ });
760
+ send.call(this, data);
761
+ }; // fetch results after ASP Ajax calls
762
+
763
+ if (
764
+ typeof Sys != "undefined" &&
765
+ typeof Sys.WebForms != "undefined" &&
766
+ typeof Sys.WebForms.PageRequestManager != "undefined"
767
+ ) {
768
+ // Get the instance of PageRequestManager.
769
+ var PageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
770
+ PageRequestManager.add_endRequest(function(sender, args) {
771
+ if (args) {
772
+ var response = args.get_response();
773
+
774
+ if (
775
+ response.get_responseAvailable() &&
776
+ response._xmlHttpRequest !== null
777
+ ) {
778
+ var stringIds = args
779
+ .get_response()
780
+ .getResponseHeader("X-MiniProfiler-Ids");
781
+
782
+ if (stringIds) {
783
+ var ids = stringIds.split(",");
784
+ fetchResults(ids);
492
785
  }
493
- };
494
-
495
- // fetch profile results for any ajax calls
496
- // note, this does not use $ cause we want to hook into the main jQuery
497
- if (jQuery && jQuery(document) && jQuery(document).ajaxComplete) {
498
- jQuery(document).on('ajaxComplete.mini-profiler', jQueryAjaxComplete);
786
+ }
499
787
  }
500
-
501
- if (jQuery && jQuery(document).ajaxStart)
502
- jQuery(document).on('ajaxStart.mini-profiler', function () { ajaxStartTime = new Date(); });
503
-
504
- // fetch results after ASP Ajax calls
505
- if (typeof (Sys) != 'undefined' && typeof (Sys.WebForms) != 'undefined' && typeof (Sys.WebForms.PageRequestManager) != 'undefined') {
506
- // Get the instance of PageRequestManager.
507
- var PageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
508
-
509
- PageRequestManager.add_endRequest(function (sender, args) {
510
- if (args) {
511
- var response = args.get_response();
512
- if (response.get_responseAvailable() && response._xmlHttpRequest !== null) {
513
- var stringIds = args.get_response().getResponseHeader('X-MiniProfiler-Ids');
514
- if (stringIds) {
515
- var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
516
- fetchResults(ids);
517
- }
518
- }
519
- }
520
- });
788
+ });
789
+ } // more Asp.Net callbacks
790
+
791
+ if (typeof WebForm_ExecuteCallback == "function") {
792
+ WebForm_ExecuteCallback = (function(callbackObject) {
793
+ // Store original function
794
+ var original = WebForm_ExecuteCallback;
795
+ return function(callbackObject) {
796
+ original(callbackObject);
797
+ var stringIds = callbackObject.xmlRequest.getResponseHeader(
798
+ "X-MiniProfiler-Ids"
799
+ );
800
+
801
+ if (stringIds) {
802
+ var ids = stringIds.split(",");
803
+ fetchResults(ids);
804
+ }
805
+ };
806
+ })();
807
+ } // also fetch results after ExtJS requests, in case it is being used
808
+
809
+ if (
810
+ typeof Ext != "undefined" &&
811
+ typeof Ext.Ajax != "undefined" &&
812
+ typeof Ext.Ajax.on != "undefined"
813
+ ) {
814
+ // Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
815
+ Ext.Ajax.on("requestcomplete", function(e, xhr, settings) {
816
+ //iframed file uploads don't have headers
817
+ if (!xhr || !xhr.getResponseHeader) {
818
+ return;
521
819
  }
522
820
 
523
- // more Asp.Net callbacks
524
- if (typeof (WebForm_ExecuteCallback) == "function") {
525
- WebForm_ExecuteCallback = (function (callbackObject) {
526
- // Store original function
527
- var original = WebForm_ExecuteCallback;
821
+ var stringIds = xhr.getResponseHeader("X-MiniProfiler-Ids");
528
822
 
529
- return function (callbackObject) {
530
- original(callbackObject);
823
+ if (stringIds) {
824
+ var ids = stringIds.split(",");
825
+ fetchResults(ids);
826
+ }
827
+ });
828
+ }
531
829
 
532
- var stringIds = callbackObject.xmlRequest.getResponseHeader('X-MiniProfiler-Ids');
533
- if (stringIds) {
534
- var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
535
- fetchResults(ids);
536
- }
537
- };
830
+ if (typeof MooTools != "undefined" && typeof Request != "undefined") {
831
+ Request.prototype.addEvents({
832
+ onComplete: function onComplete() {
833
+ var stringIds = this.xhr.getResponseHeader("X-MiniProfiler-Ids");
538
834
 
539
- })();
835
+ if (stringIds) {
836
+ var ids = stringIds.split(",");
837
+ fetchResults(ids);
838
+ }
540
839
  }
840
+ });
841
+ } // add support for AngularJS, which use the basic XMLHttpRequest object.
842
+
843
+ if (window.angular && typeof XMLHttpRequest != "undefined") {
844
+ var _send = XMLHttpRequest.prototype.send;
845
+
846
+ XMLHttpRequest.prototype.send = function sendReplacement(data) {
847
+ if (this.onreadystatechange) {
848
+ if (
849
+ typeof this.miniprofiler == "undefined" ||
850
+ typeof this.miniprofiler.prev_onreadystatechange == "undefined"
851
+ ) {
852
+ this.miniprofiler = {
853
+ prev_onreadystatechange: this.onreadystatechange
854
+ };
541
855
 
542
- // also fetch results after ExtJS requests, in case it is being used
543
- if (typeof (Ext) != 'undefined' && typeof (Ext.Ajax) != 'undefined' && typeof (Ext.Ajax.on) != 'undefined') {
544
- // Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
545
- Ext.Ajax.on('requestcomplete', function (e, xhr, settings) {
546
- //iframed file uploads don't have headers
547
- if (!xhr || !xhr.getResponseHeader) {
548
- return;
549
- }
856
+ this.onreadystatechange = function onReadyStateChangeReplacement() {
857
+ if (this.readyState == 4) {
858
+ var stringIds = this.getResponseHeader("X-MiniProfiler-Ids");
550
859
 
551
- var stringIds = xhr.getResponseHeader('X-MiniProfiler-Ids');
552
860
  if (stringIds) {
553
- var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
554
- fetchResults(ids);
861
+ var ids = stringIds.split(",");
862
+ fetchResults(ids);
555
863
  }
556
- });
557
- }
558
-
559
- if (typeof (MooTools) != 'undefined' && typeof (Request) != 'undefined') {
560
- Request.prototype.addEvents({
561
- onComplete: function() {
562
- var stringIds = this.xhr.getResponseHeader('X-MiniProfiler-Ids');
563
- if (stringIds) {
564
- var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
565
- fetchResults(ids);
566
- }
567
- }
568
- });
569
- }
570
-
571
- // add support for AngularJS, which use the basic XMLHttpRequest object.
572
- if (window.angular && typeof (XMLHttpRequest) != 'undefined') {
573
- var _send = XMLHttpRequest.prototype.send;
574
-
575
- XMLHttpRequest.prototype.send = function sendReplacement(data) {
576
- if (this.onreadystatechange) {
577
- if (typeof (this.miniprofiler) == 'undefined' || typeof (this.miniprofiler.prev_onreadystatechange) == 'undefined') {
578
- this.miniprofiler = { prev_onreadystatechange: this.onreadystatechange };
579
-
580
- this.onreadystatechange = function onReadyStateChangeReplacement() {
581
- if (this.readyState == 4) {
582
- var stringIds = this.getResponseHeader('X-MiniProfiler-Ids');
583
- if (stringIds) {
584
- var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
585
- fetchResults(ids);
586
- }
587
- }
588
-
589
- if (this.miniprofiler.prev_onreadystatechange !== null)
590
- return this.miniprofiler.prev_onreadystatechange.apply(this, arguments);
591
- };
592
864
  }
593
- }
594
865
 
595
- return _send.apply(this, arguments);
596
- };
866
+ if (this.miniprofiler.prev_onreadystatechange !== null)
867
+ return this.miniprofiler.prev_onreadystatechange.apply(
868
+ this,
869
+ arguments
870
+ );
871
+ };
872
+ }
597
873
  }
598
874
 
599
- // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
600
- if(typeof(window.fetch) === 'function' && window.fetch.__patchedByMiniProfiler === undefined) {
601
- var __originalFetch = window.fetch;
602
-
603
- window.fetch = function(input,init) {
604
- return new Promise(function(resolve,reject) {
605
- __originalFetch(input,init).then(function(response) {
606
- // look for x-mini-profile-ids
607
- var entries = response.headers.entries();
608
- for (var i = 0; i < entries.length; i++) {
609
- var pair = entries[i];
610
- if(pair[0] && (pair[0].toLowerCase() == 'x-miniprofiler-ids')) {
611
- var ids = JSON.parse(pair[1]);
612
- fetchResults(ids);
613
- }
875
+ return _send.apply(this, arguments);
876
+ };
877
+ } // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
878
+
879
+ if (
880
+ typeof window.fetch === "function" &&
881
+ window.fetch.__patchedByMiniProfiler === undefined
882
+ ) {
883
+ var __originalFetch = window.fetch;
884
+
885
+ window.fetch = function(input, init) {
886
+ var originalFetchRun = __originalFetch(input, init);
887
+
888
+ originalFetchRun.then(function(response) {
889
+ try {
890
+ // look for x-mini-profile-ids
891
+ var entries = response.headers.entries();
892
+ var _iteratorNormalCompletion = true;
893
+ var _didIteratorError = false;
894
+ var _iteratorError = undefined;
895
+
896
+ try {
897
+ for (
898
+ var _iterator = entries[Symbol.iterator](), _step;
899
+ !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
900
+ _iteratorNormalCompletion = true
901
+ ) {
902
+ var pair = _step.value;
903
+
904
+ if (pair[0] && pair[0].toLowerCase() == "x-miniprofiler-ids") {
905
+ var ids = pair[1].split(",");
906
+ fetchResults(ids);
614
907
  }
615
- resolve(response);
616
- }).catch(function(error) {
617
- reject(error);
618
- });
619
- });
908
+ }
909
+ } catch (err) {
910
+ _didIteratorError = true;
911
+ _iteratorError = err;
912
+ } finally {
913
+ try {
914
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
915
+ _iterator.return();
916
+ }
917
+ } finally {
918
+ if (_didIteratorError) {
919
+ throw _iteratorError;
920
+ }
921
+ }
922
+ }
923
+ } catch (e) {
924
+ console.error(e);
620
925
  }
621
- window.fetch.__patchedByMiniProfiler = true;
926
+ });
927
+ return originalFetchRun;
928
+ };
929
+
930
+ window.fetch.__patchedByMiniProfiler = true;
931
+ } // some elements want to be hidden on certain doc events
932
+
933
+ bindDocumentEvents();
934
+ };
935
+
936
+ return {
937
+ init: function init() {
938
+ var script = document.getElementById("mini-profiler");
939
+ if (!script || !script.getAttribute) return;
940
+
941
+ options = (function() {
942
+ var version = script.getAttribute("data-version");
943
+ var path = script.getAttribute("data-path");
944
+ var currentId = script.getAttribute("data-current-id");
945
+ var ids = script.getAttribute("data-ids");
946
+ if (ids) ids = ids.split(",");
947
+ var horizontal_position = script.getAttribute(
948
+ "data-horizontal-position"
949
+ );
950
+ var vertical_position = script.getAttribute("data-vertical-position");
951
+ var toggleShortcut = script.getAttribute("data-toggle-shortcut");
952
+
953
+ if (script.getAttribute("data-max-traces")) {
954
+ var maxTraces = parseInt(script.getAttribute("data-max-traces"), 10);
622
955
  }
623
956
 
624
- // some elements want to be hidden on certain doc events
625
- bindDocumentEvents();
626
- };
627
-
628
- return {
629
-
630
- init: function () {
631
- var script = document.getElementById('mini-profiler');
632
- if (!script || !script.getAttribute) return;
633
-
634
- options = (function () {
635
- var version = script.getAttribute('data-version');
636
- var path = script.getAttribute('data-path');
637
-
638
- var currentId = script.getAttribute('data-current-id');
639
-
640
- var ids = script.getAttribute('data-ids');
641
- if (ids) ids = ids.split(',');
642
-
643
- var horizontal_position = script.getAttribute('data-horizontal-position');
644
- var vertical_position = script.getAttribute('data-vertical-position');
957
+ var collapseResults =
958
+ script.getAttribute("data-collapse-results") === "true";
959
+ var trivial = script.getAttribute("data-trivial") === "true";
960
+ var children = script.getAttribute("data-children") === "true";
961
+ var controls = script.getAttribute("data-controls") === "true";
962
+ var totalSqlCount =
963
+ script.getAttribute("data-total-sql-count") === "true";
964
+ var authorized = script.getAttribute("data-authorized") === "true";
965
+ var startHidden =
966
+ script.getAttribute("data-start-hidden") === "true" ||
967
+ sessionStorage["rack-mini-profiler-start-hidden"] === "true";
968
+ var htmlContainer = script.getAttribute("data-html-container");
969
+ return {
970
+ ids: ids,
971
+ path: path,
972
+ version: version,
973
+ renderHorizontalPosition: horizontal_position,
974
+ renderVerticalPosition: vertical_position,
975
+ showTrivial: trivial,
976
+ showChildrenTime: children,
977
+ maxTracesToShow: maxTraces,
978
+ showControls: controls,
979
+ showTotalSqlCount: totalSqlCount,
980
+ currentId: currentId,
981
+ authorized: authorized,
982
+ toggleShortcut: toggleShortcut,
983
+ startHidden: startHidden,
984
+ collapseResults: collapseResults,
985
+ htmlContainer: htmlContainer
986
+ };
987
+ })();
645
988
 
646
- var toggleShortcut = script.getAttribute('data-toggle-shortcut');
989
+ var doInit = function doInit() {
990
+ // when rendering a shared, full page, this div will exist
991
+ container = document.querySelectorAll(".profiler-result-full");
647
992
 
648
- if (script.getAttribute('data-max-traces')) {
649
- var maxTraces = parseInt(script.getAttribute('data-max-traces'), 10);
650
- }
993
+ if (container.length) {
994
+ if (window.location.href.indexOf("&trivial=1") > 0) {
995
+ options.showTrivial = true;
996
+ }
651
997
 
652
- var collapseResults = script.getAttribute('data-collapse-results') === 'true';
653
- var trivial = script.getAttribute('data-trivial') === 'true';
654
- var children = script.getAttribute('data-children') === 'true';
655
- var controls = script.getAttribute('data-controls') === 'true';
656
- var totalSqlCount = script.getAttribute('data-total-sql-count') === 'true';
657
- var authorized = script.getAttribute('data-authorized') === 'true';
658
- var startHidden = script.getAttribute('data-start-hidden') === 'true' || sessionStorage['rack-mini-profiler-start-hidden'] === 'true';
659
- var htmlContainer = script.getAttribute('data-html-container');
660
-
661
- return {
662
- ids: ids,
663
- path: path,
664
- version: version,
665
- renderHorizontalPosition: horizontal_position,
666
- renderVerticalPosition: vertical_position,
667
- showTrivial: trivial,
668
- showChildrenTime: children,
669
- maxTracesToShow: maxTraces,
670
- showControls: controls,
671
- showTotalSqlCount: totalSqlCount,
672
- currentId: currentId,
673
- authorized: authorized,
674
- toggleShortcut: toggleShortcut,
675
- startHidden: startHidden,
676
- collapseResults: collapseResults,
677
- htmlContainer: htmlContainer
678
- };
679
- })();
680
-
681
- var doInit = function () {
682
- // when rendering a shared, full page, this div will exist
683
- container = $('.profiler-result-full');
684
- if (container.length) {
685
- if (window.location.href.indexOf("&trivial=1") > 0) {
686
- options.showTrivial = true;
687
- }
688
- initFullView();
689
- }
690
- else {
691
- initPopupView();
692
- }
693
- };
998
+ initFullView();
999
+ } else {
1000
+ initPopupView();
1001
+ }
1002
+ }; // this preserves debugging
1003
+
1004
+ var load = function load(s, f) {
1005
+ var sc = document.createElement("script");
1006
+ sc.async = "async";
1007
+ sc.type = "text/javascript";
1008
+ sc.src = s;
1009
+ var done = false;
1010
+
1011
+ sc.onload = sc.onreadystatechange = function(_, abort) {
1012
+ if (!sc.readyState || /loaded|complete/.test(sc.readyState)) {
1013
+ if (!abort && !done) {
1014
+ done = true;
1015
+ f();
1016
+ }
1017
+ }
1018
+ };
694
1019
 
695
- // this preserves debugging
696
- var load = function (s, f) {
697
- var sc = document.createElement("script");
698
- sc.async = "async";
699
- sc.type = "text/javascript";
700
- sc.src = s;
701
- var done = false;
702
- sc.onload = sc.onreadystatechange = function (_, abort) {
703
- if (!sc.readyState || /loaded|complete/.test(sc.readyState)) {
704
- if (!abort && !done) { done = true; f(); }
705
- }
706
- };
707
- document.getElementsByTagName('head')[0].appendChild(sc);
708
- };
1020
+ document.getElementsByTagName("head")[0].appendChild(sc);
1021
+ };
1022
+
1023
+ var wait = 0;
1024
+ var finish = false;
1025
+
1026
+ var deferInit = function deferInit() {
1027
+ if (finish) return;
1028
+
1029
+ if (
1030
+ window.performance &&
1031
+ window.performance.timing &&
1032
+ window.performance.timing.loadEventEnd === 0 &&
1033
+ wait < 10000
1034
+ ) {
1035
+ setTimeout(deferInit, 100);
1036
+ wait += 100;
1037
+ } else {
1038
+ finish = true;
1039
+ init();
1040
+ }
1041
+ };
709
1042
 
710
- var wait = 0;
711
- var finish = false;
712
- var deferInit = function() {
713
- if (finish) return;
714
- if (window.performance && window.performance.timing && window.performance.timing.loadEventEnd === 0 && wait < 10000) {
715
- setTimeout(deferInit, 100);
716
- wait += 100;
717
- } else {
718
- finish = true;
719
- init();
720
- }
721
- };
1043
+ var init = function init() {
1044
+ if (options.authorized) {
1045
+ var url = options.path + "includes.css?v=" + options.version;
1046
+
1047
+ if (document.createStyleSheet) {
1048
+ document.createStyleSheet(url);
1049
+ } else {
1050
+ var head = document.querySelector("head");
1051
+ var link = document.createElement("link");
1052
+ link.rel = "stylesheet";
1053
+ link.type = "text/css";
1054
+ link.href = url;
1055
+ head.appendChild(link);
1056
+ }
722
1057
 
723
- var init = function() {
1058
+ if (!MiniProfiler.loadedVendor) {
1059
+ load(options.path + "vendor.js?v=" + options.version, doInit);
1060
+ } else {
1061
+ doInit();
1062
+ }
1063
+ } else {
1064
+ doInit();
1065
+ }
1066
+ };
1067
+
1068
+ deferInit();
1069
+ },
1070
+ cleanUp: function cleanUp() {
1071
+ unbindDocumentEvents();
1072
+ },
1073
+ pageTransition: function pageTransition() {
1074
+ if (totalsControl) {
1075
+ if (totalsControl.parentElement) {
1076
+ totalsControl.parentElement.removeChild(totalsControl);
1077
+ }
1078
+ totalsControl = null;
1079
+ }
1080
+
1081
+ reqs = 0;
1082
+ totalTime = 0;
1083
+ expandedResults = false;
1084
+ toArray(
1085
+ document.querySelectorAll(".profiler-results .profiler-result")
1086
+ ).forEach(function(el) {
1087
+ return el.parentElement.removeChild(el);
1088
+ });
1089
+ },
1090
+ getClientTimingByName: function getClientTimingByName(clientTiming, name) {
1091
+ for (var i = 0; i < clientTiming.timings.length; i++) {
1092
+ if (clientTiming.timings[i].name == name) {
1093
+ return clientTiming.timings[i];
1094
+ }
1095
+ }
1096
+
1097
+ return {
1098
+ Name: name,
1099
+ Duration: "",
1100
+ Start: ""
1101
+ };
1102
+ },
1103
+ renderDate: function renderDate(jsonDate) {
1104
+ // JavaScriptSerializer sends dates as /Date(1308024322065)/
1105
+ if (jsonDate) {
1106
+ return typeof jsonDate === "string"
1107
+ ? new Date(
1108
+ parseInt(jsonDate.replace("/Date(", "").replace(")/", ""), 10)
1109
+ ).toUTCString()
1110
+ : jsonDate;
1111
+ }
1112
+ },
1113
+ renderIndent: function renderIndent(depth) {
1114
+ var result = "";
1115
+
1116
+ for (var i = 0; i < depth; i++) {
1117
+ result += "&nbsp;";
1118
+ }
1119
+
1120
+ return result;
1121
+ },
1122
+ renderExecuteType: function renderExecuteType(typeId) {
1123
+ // see StackExchange.Profiling.ExecuteType enum
1124
+ switch (typeId) {
1125
+ case 0:
1126
+ return "None";
1127
+
1128
+ case 1:
1129
+ return "NonQuery";
1130
+
1131
+ case 2:
1132
+ return "Scalar";
1133
+
1134
+ case 3:
1135
+ return "Reader";
1136
+ }
1137
+ },
1138
+ shareUrl: function shareUrl(id) {
1139
+ return options.path + "results?id=" + id;
1140
+ },
1141
+ moreUrl: function moreUrl(requestName) {
1142
+ var requestParts = requestName.split(" ");
1143
+ var linkSrc =
1144
+ requestParts[0] == "GET" ? requestParts[1] : window.location.href;
1145
+ var linkSuffix = linkSrc.indexOf("?") > 0 ? "&pp=help" : "?pp=help";
1146
+ return linkSrc + linkSuffix;
1147
+ },
1148
+ getClientTimings: function getClientTimings(clientTimings) {
1149
+ var list = [];
1150
+ var t;
1151
+ if (!clientTimings.timings) return [];
1152
+
1153
+ for (var i = 0; i < clientTimings.timings.length; i++) {
1154
+ t = clientTimings.timings[i];
1155
+ var trivial = t.Name != "Dom Complete" && t.Name != "Response";
1156
+ trivial = t.Duration < 2 ? trivial : false;
1157
+ list.push({
1158
+ isTrivial: trivial,
1159
+ name: t.Name,
1160
+ duration: t.Duration,
1161
+ start: t.Start
1162
+ });
1163
+ } // Use the Paint Timing API for render performance.
724
1164
 
725
- // jquery.hotkeys.js
726
- // https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js
1165
+ if (window.performance && window.performance.getEntriesByName) {
1166
+ var firstPaint = window.performance.getEntriesByName("first-paint");
727
1167
 
728
- if (MiniProfiler.jQuery.hotkeys === undefined) {
729
- (function(d){function h(g){if("string"===typeof g.data){var h=g.handler,j=g.data.toLowerCase().split(" ");g.handler=function(b){if(!(this!==b.target&&(/textarea|select/i.test(b.target.nodeName)||"text"===b.target.type))){var c="keypress"!==b.type&&d.hotkeys.specialKeys[b.which],e=String.fromCharCode(b.which).toLowerCase(),a="",f={};b.altKey&&"alt"!==c&&(a+="alt+");b.ctrlKey&&"ctrl"!==c&&(a+="ctrl+");b.metaKey&&(!b.ctrlKey&&"meta"!==c)&&(a+="meta+");b.shiftKey&&"shift"!==c&&(a+="shift+");c?f[a+c]=
730
- !0:(f[a+e]=!0,f[a+d.hotkeys.shiftNums[e]]=!0,"shift+"===a&&(f[d.hotkeys.shiftNums[e]]=!0));c=0;for(e=j.length;c<e;c++)if(f[j[c]])return h.apply(this,arguments)}}}}d.hotkeys={version:"0.8",specialKeys:{8:"backspace",9:"tab",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",
731
- 109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",191:"/",224:"meta"},shiftNums:{"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(","0":")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"}};d.each(["keydown","keyup","keypress"],function(){d.event.special[this]={add:h}})})(MiniProfiler.jQuery);
732
- }
1168
+ if (firstPaint !== undefined && firstPaint.length >= 1) {
1169
+ list.push({
1170
+ isTrivial: false,
1171
+ name: "First Paint Time",
1172
+ duration: firstPaint[0].duration,
1173
+ start: firstPaint[0].startTime
1174
+ });
1175
+ }
1176
+ }
1177
+
1178
+ list.sort(function(a, b) {
1179
+ return a.start - b.start;
1180
+ });
1181
+ return list;
1182
+ },
1183
+ getSqlTimings: function getSqlTimings(root) {
1184
+ var result = [],
1185
+ addToResults = function addToResults(timing) {
1186
+ if (timing.sql_timings) {
1187
+ for (var i = 0, sqlTiming; i < timing.sql_timings.length; i++) {
1188
+ sqlTiming = timing.sql_timings[i]; // HACK: add info about the parent Timing to each SqlTiming so UI can render
1189
+
1190
+ sqlTiming.parent_timing_name = timing.name;
1191
+
1192
+ if (sqlTiming.duration_milliseconds > 50) {
1193
+ sqlTiming.row_class = "slow";
1194
+ }
733
1195
 
734
- if (options.authorized) {
735
- var url = options.path + "includes.css?v=" + options.version;
736
- if (document.createStyleSheet) {
737
- document.createStyleSheet(url);
738
- } else {
739
- $('head').append($('<link rel="stylesheet" type="text/css" href="' + url + '" />'));
740
- }
741
- if (!$.tmpl) {
742
- load(options.path + 'jquery.tmpl.js?v=' + options.version, doInit);
743
- } else {
744
- doInit();
745
- }
746
- } else {
747
- doInit();
748
- }
1196
+ if (sqlTiming.duration_milliseconds > 200) {
1197
+ sqlTiming.row_class = "very-slow";
1198
+ }
749
1199
 
750
- };
1200
+ if (sqlTiming.duration_milliseconds > 400) {
1201
+ sqlTiming.row_class = "very-very-slow";
1202
+ }
751
1203
 
752
- var major, minor;
753
- if (typeof(jQuery) == 'function') {
754
- var jQueryVersion = jQuery.fn.jquery.split('.');
755
- major = parseInt(jQueryVersion[0], 10);
756
- minor = parseInt(jQueryVersion[1], 10);
1204
+ result.push(sqlTiming);
757
1205
  }
1206
+ }
758
1207
 
759
-
760
- if (major === 3 || major === 2 || (major === 1 && minor >= 7)) {
761
- MiniProfiler.jQuery = $ = jQuery;
762
- $(deferInit);
763
- } else {
764
- load(options.path + "jquery.1.7.1.js?v=" + options.version, function() {
765
- MiniProfiler.jQuery = $ = jQuery.noConflict(true);
766
- $(deferInit);
767
- });
1208
+ if (timing.children) {
1209
+ for (var i = 0; i < timing.children.length; i++) {
1210
+ addToResults(timing.children[i]);
768
1211
  }
769
- },
1212
+ }
1213
+ }; // start adding at the root and recurse down
770
1214
 
771
- cleanUp: function() {
772
- unbindDocumentEvents();
773
- },
1215
+ addToResults(root);
774
1216
 
775
- pageTransition: function() {
776
- if (totalsControl) {
777
- totalsControl.remove();
778
- totalsControl = null;
779
- }
780
- reqs = 0;
781
- totalTime = 0;
782
- expandedResults = false;
783
- $('.profiler-results .profiler-result').remove();
784
- },
1217
+ var removeDuration = function removeDuration(list, duration) {
1218
+ var newList = [];
785
1219
 
786
- getClientTimingByName: function (clientTiming, name) {
1220
+ for (var i = 0; i < list.length; i++) {
1221
+ var item = list[i];
787
1222
 
788
- for (var i = 0; i < clientTiming.timings.length; i++) {
789
- if (clientTiming.timings[i].name == name) {
790
- return clientTiming.timings[i];
791
- }
1223
+ if (duration.start > item.start) {
1224
+ if (duration.start > item.finish) {
1225
+ newList.push(item);
1226
+ continue;
792
1227
  }
793
- return { Name: name, Duration: "", Start: "" };
794
- },
795
1228
 
796
- renderDate: function (jsonDate) { // JavaScriptSerializer sends dates as /Date(1308024322065)/
797
- if (jsonDate) {
798
- return (typeof jsonDate === 'string') ? new Date(parseInt(jsonDate.replace("/Date(", "").replace(")/", ""), 10)).toUTCString() : jsonDate;
799
- }
800
- },
1229
+ newList.push({
1230
+ start: item.start,
1231
+ finish: duration.start
1232
+ });
1233
+ }
801
1234
 
802
- renderIndent: function (depth) {
803
- var result = '';
804
- for (var i = 0; i < depth; i++) {
805
- result += '&nbsp;';
806
- }
807
- return result;
808
- },
809
-
810
- renderExecuteType: function (typeId) {
811
- // see StackExchange.Profiling.ExecuteType enum
812
- switch (typeId) {
813
- case 0: return 'None';
814
- case 1: return 'NonQuery';
815
- case 2: return 'Scalar';
816
- case 3: return 'Reader';
1235
+ if (duration.finish < item.finish) {
1236
+ if (duration.finish < item.start) {
1237
+ newList.push(item);
1238
+ continue;
817
1239
  }
818
- },
819
-
820
- shareUrl: function (id) {
821
- return options.path + 'results?id=' + id;
822
- },
823
-
824
- moreUrl: function () {
825
- var loc = window.location.href;
826
- loc = loc.indexOf("?") > 0 ? loc + "&pp=help" : "?pp=help";
827
- return loc;
828
- },
829
-
830
- getClientTimings: function (clientTimings) {
831
- var list = [];
832
- var t;
833
-
834
- if (!clientTimings.timings) return [];
835
-
836
- for (var i = 0; i < clientTimings.timings.length; i++) {
837
- t = clientTimings.timings[i];
838
- var trivial = t.Name != "Dom Complete" && t.Name != "Response"
839
- trivial = t.Duration < 2 ? trivial : false;
840
- list.push(
841
- {
842
- isTrivial: trivial,
843
- name: t.Name,
844
- duration: t.Duration,
845
- start: t.Start
846
- });
847
- }
848
-
849
1240
 
850
- // Use the Paint Timing API for render performance.
851
- if (window.performance && window.performance.getEntriesByName) {
852
- var firstPaint = window.performance.getEntriesByName("first-paint");
1241
+ newList.push({
1242
+ start: duration.finish,
1243
+ finish: item.finish
1244
+ });
1245
+ }
1246
+ }
853
1247
 
854
- if(firstPaint !== undefined && firstPaint.length >= 1){
855
- list.push(
856
- {
857
- isTrivial: false,
858
- name: "First Paint Time",
859
- duration: firstPaint[0].duration,
860
- start: firstPaint[0].startTime
861
- });
862
- }
863
- }
1248
+ return newList;
1249
+ };
864
1250
 
865
- list.sort(function (a, b) { return a.start - b.start; });
866
- return list;
867
- },
868
-
869
- getSqlTimings: function (root) {
870
- var result = [],
871
- addToResults = function (timing) {
872
- if (timing.sql_timings) {
873
- for (var i = 0, sqlTiming; i < timing.sql_timings.length; i++) {
874
- sqlTiming = timing.sql_timings[i];
875
-
876
- // HACK: add info about the parent Timing to each SqlTiming so UI can render
877
- sqlTiming.parent_timing_name = timing.name;
878
-
879
- if(sqlTiming.duration_milliseconds > 50) {
880
- sqlTiming.row_class = "slow";
881
- }
882
-
883
- if(sqlTiming.duration_milliseconds > 200) {
884
- sqlTiming.row_class = "very-slow";
885
- }
886
-
887
- if(sqlTiming.duration_milliseconds > 400) {
888
- sqlTiming.row_class = "very-very-slow";
889
- }
890
-
891
- result.push(sqlTiming);
892
- }
893
- }
894
-
895
- if (timing.children) {
896
- for (var i = 0; i < timing.children.length; i++) {
897
- addToResults(timing.children[i]);
898
- }
899
- }
900
- };
901
-
902
- // start adding at the root and recurse down
903
- addToResults(root);
904
-
905
- var removeDuration = function(list, duration) {
906
-
907
- var newList = [];
908
- for (var i = 0; i < list.length; i++) {
909
-
910
- var item = list[i];
911
- if (duration.start > item.start) {
912
- if (duration.start > item.finish) {
913
- newList.push(item);
914
- continue;
915
- }
916
- newList.push({ start: item.start, finish: duration.start });
917
- }
918
-
919
- if (duration.finish < item.finish) {
920
- if (duration.finish < item.start) {
921
- newList.push(item);
922
- continue;
923
- }
924
- newList.push({ start: duration.finish, finish: item.finish });
925
- }
926
- }
1251
+ var processTimes = function processTimes(elem, parent) {
1252
+ var duration = {
1253
+ start: elem.start_milliseconds,
1254
+ finish: elem.start_milliseconds + elem.duration_milliseconds
1255
+ };
1256
+ elem.richTiming = [duration];
1257
+
1258
+ if (parent !== null) {
1259
+ elem.parent = parent;
1260
+ elem.parent.richTiming = removeDuration(
1261
+ elem.parent.richTiming,
1262
+ duration
1263
+ );
1264
+ }
927
1265
 
928
- return newList;
929
- };
1266
+ if (elem.children) {
1267
+ for (var i = 0; i < elem.children.length; i++) {
1268
+ processTimes(elem.children[i], elem);
1269
+ }
1270
+ }
1271
+ };
930
1272
 
931
- var processTimes = function (elem, parent) {
932
- var duration = { start: elem.start_milliseconds, finish: (elem.start_milliseconds + elem.duration_milliseconds) };
933
- elem.richTiming = [duration];
934
- if (parent !== null) {
935
- elem.parent = parent;
936
- elem.parent.richTiming = removeDuration(elem.parent.richTiming, duration);
937
- }
1273
+ processTimes(root, null); // sort results by time
938
1274
 
939
- if (elem.children) {
940
- for (var i = 0; i < elem.children.length; i++) {
941
- processTimes(elem.children[i], elem);
942
- }
943
- }
944
- };
1275
+ result.sort(function(a, b) {
1276
+ return a.start_milliseconds - b.start_milliseconds;
1277
+ });
945
1278
 
946
- processTimes(root, null);
1279
+ var determineOverlap = function determineOverlap(gap, node) {
1280
+ var overlap = 0;
947
1281
 
948
- // sort results by time
949
- result.sort(function (a, b) { return a.start_milliseconds - b.start_milliseconds; });
1282
+ for (var i = 0; i < node.richTiming.length; i++) {
1283
+ var current = node.richTiming[i];
950
1284
 
951
- var determineOverlap = function(gap, node) {
952
- var overlap = 0;
953
- for (var i = 0; i < node.richTiming.length; i++) {
954
- var current = node.richTiming[i];
955
- if (current.start > gap.finish) {
956
- break;
957
- }
958
- if (current.finish < gap.start) {
959
- continue;
960
- }
1285
+ if (current.start > gap.finish) {
1286
+ break;
1287
+ }
961
1288
 
962
- overlap += Math.min(gap.finish, current.finish) - Math.max(gap.start, current.start);
963
- }
964
- return overlap;
965
- };
1289
+ if (current.finish < gap.start) {
1290
+ continue;
1291
+ }
966
1292
 
967
- var determineGap = function (gap, node, match) {
968
- var overlap = determineOverlap(gap, node);
969
- if (match === null || overlap > match.duration) {
970
- match = { name: node.name, duration: overlap };
971
- }
972
- else if (match.name == node.name) {
973
- match.duration += overlap;
974
- }
1293
+ overlap +=
1294
+ Math.min(gap.finish, current.finish) -
1295
+ Math.max(gap.start, current.start);
1296
+ }
975
1297
 
976
- if (node.children) {
977
- for (var i = 0; i < node.children.length; i++) {
978
- match = determineGap(gap, node.children[i], match);
979
- }
980
- }
981
- return match;
982
- };
1298
+ return overlap;
1299
+ };
983
1300
 
984
- var time = 0;
985
- var prev = null;
986
- $.each(result, function () {
987
- this.prevGap = {
988
- duration: (this.start_milliseconds - time).toFixed(2),
989
- start: time,
990
- finish: this.start_milliseconds
991
- };
1301
+ var determineGap = function determineGap(gap, node, match) {
1302
+ var overlap = determineOverlap(gap, node);
992
1303
 
993
- this.prevGap.topReason = determineGap(this.prevGap, root, null);
1304
+ if (match === null || overlap > match.duration) {
1305
+ match = {
1306
+ name: node.name,
1307
+ duration: overlap
1308
+ };
1309
+ } else if (match.name == node.name) {
1310
+ match.duration += overlap;
1311
+ }
994
1312
 
995
- time = this.start_milliseconds + this.duration_milliseconds;
996
- prev = this;
997
- });
1313
+ if (node.children) {
1314
+ for (var i = 0; i < node.children.length; i++) {
1315
+ match = determineGap(gap, node.children[i], match);
1316
+ }
1317
+ }
998
1318
 
1319
+ return match;
1320
+ };
999
1321
 
1000
- if (result.length > 0) {
1001
- var me = result[result.length - 1];
1002
- me.nextGap = {
1003
- duration: (root.duration_milliseconds - time).toFixed(2),
1004
- start: time,
1005
- finish: root.duration_milliseconds
1006
- };
1007
- me.nextGap.topReason = determineGap(me.nextGap, root, null);
1008
- }
1322
+ var time = 0;
1323
+ var prev = null;
1324
+ result.forEach(function(r) {
1325
+ r.prevGap = {
1326
+ duration: (r.start_milliseconds - time).toFixed(2),
1327
+ start: time,
1328
+ finish: r.start_milliseconds
1329
+ };
1330
+ r.prevGap.topReason = determineGap(r.prevGap, root, null);
1331
+ time = r.start_milliseconds + r.duration_milliseconds;
1332
+ prev = r;
1333
+ });
1334
+
1335
+ if (result.length > 0) {
1336
+ var me = result[result.length - 1];
1337
+ me.nextGap = {
1338
+ duration: (root.duration_milliseconds - time).toFixed(2),
1339
+ start: time,
1340
+ finish: root.duration_milliseconds
1341
+ };
1342
+ me.nextGap.topReason = determineGap(me.nextGap, root, null);
1343
+ }
1344
+
1345
+ return result;
1346
+ },
1347
+ getSqlTimingsCount: function getSqlTimingsCount(root) {
1348
+ var result = 0,
1349
+ countSql = function countSql(timing) {
1350
+ if (timing.sql_timings) {
1351
+ result += timing.sql_timings.length;
1352
+ }
1009
1353
 
1010
- return result;
1011
- },
1012
-
1013
- getSqlTimingsCount: function (root) {
1014
- var result = 0,
1015
- countSql = function (timing) {
1016
- if (timing.sql_timings) {
1017
- result += timing.sql_timings.length;
1018
- }
1019
-
1020
- if (timing.children) {
1021
- for (var i = 0; i < timing.children.length; i++) {
1022
- countSql(timing.children[i]);
1023
- }
1024
- }
1025
- };
1026
- countSql(root);
1027
- return result;
1028
- },
1029
-
1030
- fetchResultsExposed: function (ids) {
1031
- return fetchResults(ids);
1032
- },
1033
-
1034
- formatParameters: function (parameters) {
1035
- if (parameters != null) {
1036
- return parameters.map(function(item, index){ return "["+item[0]+", "+ item[1] +"]";}).join(', ');
1037
- }
1038
- else {
1039
- return '';
1354
+ if (timing.children) {
1355
+ for (var i = 0; i < timing.children.length; i++) {
1356
+ countSql(timing.children[i]);
1040
1357
  }
1041
- },
1042
-
1043
- formatDuration: function (duration) {
1044
- return (duration || 0).toFixed(1);
1045
- },
1358
+ }
1359
+ };
1046
1360
 
1047
- showTotalSqlCount: function () {
1048
- return options.showTotalSqlCount
1049
- }
1050
- };
1361
+ countSql(root);
1362
+ return result;
1363
+ },
1364
+ fetchResultsExposed: function fetchResultsExposed(ids) {
1365
+ return fetchResults(ids);
1366
+ },
1367
+ formatParameters: function formatParameters(parameters) {
1368
+ if (parameters != null) {
1369
+ return parameters
1370
+ .map(function(item, index) {
1371
+ return "[" + item[0] + ", " + item[1] + "]";
1372
+ })
1373
+ .join(", ");
1374
+ } else {
1375
+ return "";
1376
+ }
1377
+ },
1378
+ formatDuration: function formatDuration(duration) {
1379
+ return (duration || 0).toFixed(1);
1380
+ },
1381
+ showTotalSqlCount: function showTotalSqlCount() {
1382
+ return options.showTotalSqlCount;
1383
+ }
1384
+ };
1051
1385
  })();
1052
1386
 
1053
1387
  MiniProfiler.init();
1054
-
1055
- if (typeof prettyPrint === "undefined") {
1056
-
1057
- // prettify.js
1058
- // http://code.google.com/p/google-code-prettify/
1059
-
1060
- window.PR_SHOULD_USE_CONTINUATION=true;window.PR_TAB_WIDTH=8;window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void 0;window._pr_isIE6=function(){var y=navigator&&navigator.userAgent&&navigator.userAgent.match(/\bMSIE ([678])\./);y=y?+y[1]:false;window._pr_isIE6=function(){return y};return y};
1061
- (function(){function y(b){return b.replace(L,"&amp;").replace(M,"&lt;").replace(N,"&gt;")}function H(b,f,i){switch(b.nodeType){case 1:var o=b.tagName.toLowerCase();f.push("<",o);var l=b.attributes,n=l.length;if(n){if(i){for(var r=[],j=n;--j>=0;)r[j]=l[j];r.sort(function(q,m){return q.name<m.name?-1:q.name===m.name?0:1});l=r}for(j=0;j<n;++j){r=l[j];r.specified&&f.push(" ",r.name.toLowerCase(),'="',r.value.replace(L,"&amp;").replace(M,"&lt;").replace(N,"&gt;").replace(X,"&quot;"),'"')}}f.push(">");
1062
- for(l=b.firstChild;l;l=l.nextSibling)H(l,f,i);if(b.firstChild||!/^(?:br|link|img)$/.test(o))f.push("</",o,">");break;case 3:case 4:f.push(y(b.nodeValue));break}}function O(b){function f(c){if(c.charAt(0)!=="\\")return c.charCodeAt(0);switch(c.charAt(1)){case "b":return 8;case "t":return 9;case "n":return 10;case "v":return 11;case "f":return 12;case "r":return 13;case "u":case "x":return parseInt(c.substring(2),16)||c.charCodeAt(1);case "0":case "1":case "2":case "3":case "4":case "5":case "6":case "7":return parseInt(c.substring(1),
1063
- 8);default:return c.charCodeAt(1)}}function i(c){if(c<32)return(c<16?"\\x0":"\\x")+c.toString(16);c=String.fromCharCode(c);if(c==="\\"||c==="-"||c==="["||c==="]")c="\\"+c;return c}function o(c){var d=c.substring(1,c.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));c=[];for(var a=[],k=d[0]==="^",e=k?1:0,h=d.length;e<h;++e){var g=d[e];switch(g){case "\\B":case "\\b":case "\\D":case "\\d":case "\\S":case "\\s":case "\\W":case "\\w":c.push(g);
1064
- continue}g=f(g);var s;if(e+2<h&&"-"===d[e+1]){s=f(d[e+2]);e+=2}else s=g;a.push([g,s]);if(!(s<65||g>122)){s<65||g>90||a.push([Math.max(65,g)|32,Math.min(s,90)|32]);s<97||g>122||a.push([Math.max(97,g)&-33,Math.min(s,122)&-33])}}a.sort(function(v,w){return v[0]-w[0]||w[1]-v[1]});d=[];g=[NaN,NaN];for(e=0;e<a.length;++e){h=a[e];if(h[0]<=g[1]+1)g[1]=Math.max(g[1],h[1]);else d.push(g=h)}a=["["];k&&a.push("^");a.push.apply(a,c);for(e=0;e<d.length;++e){h=d[e];a.push(i(h[0]));if(h[1]>h[0]){h[1]+1>h[0]&&a.push("-");
1065
- a.push(i(h[1]))}}a.push("]");return a.join("")}function l(c){for(var d=c.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g")),a=d.length,k=[],e=0,h=0;e<a;++e){var g=d[e];if(g==="(")++h;else if("\\"===g.charAt(0))if((g=+g.substring(1))&&g<=h)k[g]=-1}for(e=1;e<k.length;++e)if(-1===k[e])k[e]=++n;for(h=e=0;e<a;++e){g=d[e];if(g==="("){++h;if(k[h]===undefined)d[e]="(?:"}else if("\\"===
1066
- g.charAt(0))if((g=+g.substring(1))&&g<=h)d[e]="\\"+k[h]}for(h=e=0;e<a;++e)if("^"===d[e]&&"^"!==d[e+1])d[e]="";if(c.ignoreCase&&r)for(e=0;e<a;++e){g=d[e];c=g.charAt(0);if(g.length>=2&&c==="[")d[e]=o(g);else if(c!=="\\")d[e]=g.replace(/[a-zA-Z]/g,function(s){s=s.charCodeAt(0);return"["+String.fromCharCode(s&-33,s|32)+"]"})}return d.join("")}for(var n=0,r=false,j=false,q=0,m=b.length;q<m;++q){var t=b[q];if(t.ignoreCase)j=true;else if(/[a-z]/i.test(t.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,
1067
- ""))){r=true;j=false;break}}var p=[];q=0;for(m=b.length;q<m;++q){t=b[q];if(t.global||t.multiline)throw Error(""+t);p.push("(?:"+l(t)+")")}return RegExp(p.join("|"),j?"gi":"g")}function Y(b){var f=0;return function(i){for(var o=null,l=0,n=0,r=i.length;n<r;++n)switch(i.charAt(n)){case "\t":o||(o=[]);o.push(i.substring(l,n));l=b-f%b;for(f+=l;l>=0;l-=16)o.push(" ".substring(0,l));l=n+1;break;case "\n":f=0;break;default:++f}if(!o)return i;o.push(i.substring(l));return o.join("")}}function I(b,
1068
- f,i,o){if(f){b={source:f,c:b};i(b);o.push.apply(o,b.d)}}function B(b,f){var i={},o;(function(){for(var r=b.concat(f),j=[],q={},m=0,t=r.length;m<t;++m){var p=r[m],c=p[3];if(c)for(var d=c.length;--d>=0;)i[c.charAt(d)]=p;p=p[1];c=""+p;if(!q.hasOwnProperty(c)){j.push(p);q[c]=null}}j.push(/[\0-\uffff]/);o=O(j)})();var l=f.length;function n(r){for(var j=r.c,q=[j,z],m=0,t=r.source.match(o)||[],p={},c=0,d=t.length;c<d;++c){var a=t[c],k=p[a],e=void 0,h;if(typeof k==="string")h=false;else{var g=i[a.charAt(0)];
1069
- if(g){e=a.match(g[1]);k=g[0]}else{for(h=0;h<l;++h){g=f[h];if(e=a.match(g[1])){k=g[0];break}}e||(k=z)}if((h=k.length>=5&&"lang-"===k.substring(0,5))&&!(e&&typeof e[1]==="string")){h=false;k=P}h||(p[a]=k)}g=m;m+=a.length;if(h){h=e[1];var s=a.indexOf(h),v=s+h.length;if(e[2]){v=a.length-e[2].length;s=v-h.length}k=k.substring(5);I(j+g,a.substring(0,s),n,q);I(j+g+s,h,Q(k,h),q);I(j+g+v,a.substring(v),n,q)}else q.push(j+g,k)}r.d=q}return n}function x(b){var f=[],i=[];if(b.tripleQuotedStrings)f.push([A,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
1070
- null,"'\""]);else b.multiLineStrings?f.push([A,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):f.push([A,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);b.verbatimStrings&&i.push([A,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);if(b.hashComments)if(b.cStyleComments){f.push([C,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"]);i.push([A,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
1071
- null])}else f.push([C,/^#[^\r\n]*/,null,"#"]);if(b.cStyleComments){i.push([C,/^\/\/[^\r\n]*/,null]);i.push([C,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}b.regexLiterals&&i.push(["lang-regex",RegExp("^"+Z+"(/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/)")]);b=b.keywords.replace(/^\s+|\s+$/g,"");b.length&&i.push([R,RegExp("^(?:"+b.replace(/\s+/g,"|")+")\\b"),null]);f.push([z,/^\s+/,null," \r\n\t\u00a0"]);i.push([J,/^@[a-z_$][a-z_$@0-9]*/i,null],[S,/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/,
1072
- null],[z,/^[a-z_$][a-z_$@0-9]*/i,null],[J,/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],[E,/^.[^\s\w\.$@\'\"\`\/\#]*/,null]);return B(f,i)}function $(b){function f(D){if(D>r){if(j&&j!==q){n.push("</span>");j=null}if(!j&&q){j=q;n.push('<span class="',j,'">')}var T=y(p(i.substring(r,D))).replace(e?d:c,"$1&#160;");e=k.test(T);n.push(T.replace(a,s));r=D}}var i=b.source,o=b.g,l=b.d,n=[],r=0,j=null,q=null,m=0,t=0,p=Y(window.PR_TAB_WIDTH),c=/([\r\n ]) /g,
1073
- d=/(^| ) /gm,a=/\r\n?|\n/g,k=/[ \r\n]$/,e=true,h=window._pr_isIE6();h=h?b.b.tagName==="PRE"?h===6?"&#160;\r\n":h===7?"&#160;<br>\r":"&#160;\r":"&#160;<br />":"<br />";var g=b.b.className.match(/\blinenums\b(?::(\d+))?/),s;if(g){for(var v=[],w=0;w<10;++w)v[w]=h+'</li><li class="L'+w+'">';var F=g[1]&&g[1].length?g[1]-1:0;n.push('<ol class="linenums"><li class="L',F%10,'"');F&&n.push(' value="',F+1,'"');n.push(">");s=function(){var D=v[++F%10];return j?"</span>"+D+'<span class="'+j+'">':D}}else s=h;
1074
- for(;;)if(m<o.length?t<l.length?o[m]<=l[t]:true:false){f(o[m]);if(j){n.push("</span>");j=null}n.push(o[m+1]);m+=2}else if(t<l.length){f(l[t]);q=l[t+1];t+=2}else break;f(i.length);j&&n.push("</span>");g&&n.push("</li></ol>");b.a=n.join("")}function u(b,f){for(var i=f.length;--i>=0;){var o=f[i];if(G.hasOwnProperty(o))"console"in window&&console.warn("cannot override language handler %s",o);else G[o]=b}}function Q(b,f){b&&G.hasOwnProperty(b)||(b=/^\s*</.test(f)?"default-markup":"default-code");return G[b]}
1075
- function U(b){var f=b.f,i=b.e;b.a=f;try{var o,l=f.match(aa);f=[];var n=0,r=[];if(l)for(var j=0,q=l.length;j<q;++j){var m=l[j];if(m.length>1&&m.charAt(0)==="<"){if(!ba.test(m))if(ca.test(m)){f.push(m.substring(9,m.length-3));n+=m.length-12}else if(da.test(m)){f.push("\n");++n}else if(m.indexOf(V)>=0&&m.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)){var t=m.match(W)[2],p=1,c;c=j+1;a:for(;c<q;++c){var d=l[c].match(W);if(d&&
1076
- d[2]===t)if(d[1]==="/"){if(--p===0)break a}else++p}if(c<q){r.push(n,l.slice(j,c+1).join(""));j=c}else r.push(n,m)}else r.push(n,m)}else{var a;p=m;var k=p.indexOf("&");if(k<0)a=p;else{for(--k;(k=p.indexOf("&#",k+1))>=0;){var e=p.indexOf(";",k);if(e>=0){var h=p.substring(k+3,e),g=10;if(h&&h.charAt(0)==="x"){h=h.substring(1);g=16}var s=parseInt(h,g);isNaN(s)||(p=p.substring(0,k)+String.fromCharCode(s)+p.substring(e+1))}}a=p.replace(ea,"<").replace(fa,">").replace(ga,"'").replace(ha,'"').replace(ia," ").replace(ja,
1077
- "&")}f.push(a);n+=a.length}}o={source:f.join(""),h:r};var v=o.source;b.source=v;b.c=0;b.g=o.h;Q(i,v)(b);$(b)}catch(w){if("console"in window)console.log(w&&w.stack?w.stack:w)}}var A="str",R="kwd",C="com",S="typ",J="lit",E="pun",z="pln",P="src",V="nocode",Z=function(){for(var b=["!","!=","!==","#","%","%=","&","&&","&&=","&=","(","*","*=","+=",",","-=","->","/","/=",":","::",";","<","<<","<<=","<=","=","==","===",">",">=",">>",">>=",">>>",">>>=","?","@","[","^","^=","^^","^^=","{","|","|=","||","||=",
1078
- "~","break","case","continue","delete","do","else","finally","instanceof","return","throw","try","typeof"],f="(?:^^|[+-]",i=0;i<b.length;++i)f+="|"+b[i].replace(/([^=<>:&a-z])/g,"\\$1");f+=")\\s*";return f}(),L=/&/g,M=/</g,N=/>/g,X=/\"/g,ea=/&lt;/g,fa=/&gt;/g,ga=/&apos;/g,ha=/&quot;/g,ja=/&amp;/g,ia=/&nbsp;/g,ka=/[\r\n]/g,K=null,aa=RegExp("[^<]+|<!--[\\s\\S]*?--\>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|</?[a-zA-Z](?:[^>\"']|'[^']*'|\"[^\"]*\")*>|<","g"),ba=/^<\!--/,ca=/^<!\[CDATA\[/,da=/^<br\b/i,W=/^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/,
1079
- la=x({keywords:"break continue do else for if return while 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 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 wchar_t where break continue do else for if return while 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 abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending 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 break continue do else for if return while 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 debugger eval export function get null set undefined var with Infinity NaN 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 break continue do else for if return while 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 break continue do else for if return while 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 break continue do else for if return while case done elif esac eval fi function in local set then until ",
1080
- hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true}),G={};u(la,["default-code"]);u(B([],[[z,/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],[C,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[E,/^(?:<[%?]|[%?]>)/],["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",
1081
- "htm","html","mxml","xhtml","xml","xsl"]);u(B([[z,/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[E,/^[=<>\/]+/],["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],
1082
- ["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);u(B([],[["atv",/^[\s\S]+/]]),["uq.val"]);u(x({keywords:"break continue do else for if return while 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 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 wchar_t where ",
1083
- hashComments:true,cStyleComments:true}),["c","cc","cpp","cxx","cyc","m"]);u(x({keywords:"null true false"}),["json"]);u(x({keywords:"break continue do else for if return while 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 abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending 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 ",
1084
- hashComments:true,cStyleComments:true,verbatimStrings:true}),["cs"]);u(x({keywords:"break continue do else for if return while 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 abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ",
1085
- cStyleComments:true}),["java"]);u(x({keywords:"break continue do else for if return while case done elif esac eval fi function in local set then until ",hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);u(x({keywords:"break continue do else for if return while 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 ",hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);
1086
- u(x({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:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);u(x({keywords:"break continue do else for if return while 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 ",hashComments:true,
1087
- multiLineStrings:true,regexLiterals:true}),["rb"]);u(x({keywords:"break continue do else for if return while 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 debugger eval export function get null set undefined var with Infinity NaN ",cStyleComments:true,regexLiterals:true}),["js"]);u(B([],[[A,/^[\s\S]+/]]),
1088
- ["regex"]);window.PR_normalizedHtml=H;window.prettyPrintOne=function(b,f){var i={f:b,e:f};U(i);return i.a};window.prettyPrint=function(b){function f(){for(var t=window.PR_SHOULD_USE_CONTINUATION?j.now()+250:Infinity;q<o.length&&j.now()<t;q++){var p=o[q];if(p.className&&p.className.indexOf("prettyprint")>=0){var c=p.className.match(/\blang-(\w+)\b/);if(c)c=c[1];for(var d=false,a=p.parentNode;a;a=a.parentNode)if((a.tagName==="pre"||a.tagName==="code"||a.tagName==="xmp")&&a.className&&a.className.indexOf("prettyprint")>=
1089
- 0){d=true;break}if(!d){a=p;if(null===K){d=document.createElement("PRE");d.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));K=!/</.test(d.innerHTML)}if(K){d=a.innerHTML;if("XMP"===a.tagName)d=y(d);else{a=a;if("PRE"===a.tagName)a=true;else if(ka.test(d)){var k="";if(a.currentStyle)k=a.currentStyle.whiteSpace;else if(window.getComputedStyle)k=window.getComputedStyle(a,null).whiteSpace;a=!k||k==="pre"}else a=true;a||(d=d.replace(/(<br\s*\/?>)[\r\n]+/g,"$1").replace(/(?:[\r\n]+[ \t]*)+/g,
1090
- " "))}d=d}else{d=[];for(a=a.firstChild;a;a=a.nextSibling)H(a,d);d=d.join("")}d=d.replace(/(?:\r\n?|\n)$/,"");m={f:d,e:c,b:p};U(m);if(p=m.a){c=m.b;if("XMP"===c.tagName){d=document.createElement("PRE");for(a=0;a<c.attributes.length;++a){k=c.attributes[a];if(k.specified)if(k.name.toLowerCase()==="class")d.className=k.value;else d.setAttribute(k.name,k.value)}d.innerHTML=p;c.parentNode.replaceChild(d,c)}else c.innerHTML=p}}}}if(q<o.length)setTimeout(f,250);else b&&b()}for(var i=[document.getElementsByTagName("pre"),
1091
- document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],o=[],l=0;l<i.length;++l)for(var n=0,r=i[l].length;n<r;++n)o.push(i[l][n]);i=null;var j=Date;j.now||(j={now:function(){return(new Date).getTime()}});var q=0,m;f()};window.PR={combinePrefixPatterns:O,createSimpleLexer:B,registerLangHandler:u,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:C,PR_DECLARATION:"dec",PR_KEYWORD:R,PR_LITERAL:J,PR_NOCODE:V,PR_PLAIN:z,PR_PUNCTUATION:E,PR_SOURCE:P,PR_STRING:A,
1092
- PR_TAG:"tag",PR_TYPE:S}})()
1093
-
1094
- ;
1095
-
1096
- // lang-sql.js
1097
- // http://code.google.com/p/google-code-prettify/
1098
-
1099
- PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],["kwd",/^(?: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|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|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,
1100
- null],["lit",/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],["pln",/^[a-z_][\w-]*/i],["pun",/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),["sql"])
1101
-
1102
- ;
1103
- }