mini-mini-profiler 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/Ruby/CHANGELOG +135 -0
  2. data/Ruby/README.md +161 -0
  3. data/Ruby/lib/html/flamegraph.html +325 -0
  4. data/Ruby/lib/html/includes.css +451 -0
  5. data/Ruby/lib/html/includes.js +945 -0
  6. data/Ruby/lib/html/includes.less +471 -0
  7. data/Ruby/lib/html/includes.tmpl +108 -0
  8. data/Ruby/lib/html/jquery.1.7.1.js +4 -0
  9. data/Ruby/lib/html/jquery.tmpl.js +486 -0
  10. data/Ruby/lib/html/list.css +9 -0
  11. data/Ruby/lib/html/list.js +38 -0
  12. data/Ruby/lib/html/list.tmpl +34 -0
  13. data/Ruby/lib/html/profile_handler.js +1 -0
  14. data/Ruby/lib/html/share.html +11 -0
  15. data/Ruby/lib/mini_profiler/client_settings.rb +65 -0
  16. data/Ruby/lib/mini_profiler/client_timer_struct.rb +78 -0
  17. data/Ruby/lib/mini_profiler/config.rb +57 -0
  18. data/Ruby/lib/mini_profiler/context.rb +11 -0
  19. data/Ruby/lib/mini_profiler/custom_timer_struct.rb +22 -0
  20. data/Ruby/lib/mini_profiler/flame_graph.rb +54 -0
  21. data/Ruby/lib/mini_profiler/gc_profiler.rb +107 -0
  22. data/Ruby/lib/mini_profiler/page_timer_struct.rb +58 -0
  23. data/Ruby/lib/mini_profiler/profiler.rb +544 -0
  24. data/Ruby/lib/mini_profiler/profiling_methods.rb +133 -0
  25. data/Ruby/lib/mini_profiler/request_timer_struct.rb +115 -0
  26. data/Ruby/lib/mini_profiler/sql_timer_struct.rb +58 -0
  27. data/Ruby/lib/mini_profiler/storage/abstract_store.rb +31 -0
  28. data/Ruby/lib/mini_profiler/storage/file_store.rb +111 -0
  29. data/Ruby/lib/mini_profiler/storage/memcache_store.rb +53 -0
  30. data/Ruby/lib/mini_profiler/storage/memory_store.rb +65 -0
  31. data/Ruby/lib/mini_profiler/storage/redis_store.rb +54 -0
  32. data/Ruby/lib/mini_profiler/timer_struct.rb +33 -0
  33. data/Ruby/lib/mini_profiler/version.rb +5 -0
  34. data/Ruby/lib/mini_profiler_rails/railtie.rb +107 -0
  35. data/Ruby/lib/patches/net_patches.rb +14 -0
  36. data/Ruby/lib/patches/sql_patches.rb +272 -0
  37. data/Ruby/lib/rack-mini-profiler.rb +7 -0
  38. data/mini-mini-profiler.gemspec +26 -0
  39. metadata +154 -0
@@ -0,0 +1,451 @@
1
+ .profiler-result,
2
+ .profiler-queries {
3
+ color: #555;
4
+ line-height: 1;
5
+ font-size: 12px;
6
+ }
7
+ .profiler-result pre,
8
+ .profiler-queries pre,
9
+ .profiler-result code,
10
+ .profiler-queries code,
11
+ .profiler-result label,
12
+ .profiler-queries label,
13
+ .profiler-result table,
14
+ .profiler-queries table,
15
+ .profiler-result tbody,
16
+ .profiler-queries tbody,
17
+ .profiler-result thead,
18
+ .profiler-queries thead,
19
+ .profiler-result tfoot,
20
+ .profiler-queries tfoot,
21
+ .profiler-result tr,
22
+ .profiler-queries tr,
23
+ .profiler-result th,
24
+ .profiler-queries th,
25
+ .profiler-result td,
26
+ .profiler-queries td {
27
+ margin: 0;
28
+ padding: 0;
29
+ border: 0;
30
+ font-size: 100%;
31
+ font: inherit;
32
+ vertical-align: baseline;
33
+ background-color: transparent;
34
+ overflow: visible;
35
+ max-height: none;
36
+ }
37
+ .profiler-result table,
38
+ .profiler-queries table {
39
+ border-collapse: collapse;
40
+ border-spacing: 0;
41
+ }
42
+ .profiler-result a,
43
+ .profiler-queries a,
44
+ .profiler-result a:hover,
45
+ .profiler-queries a:hover {
46
+ cursor: pointer;
47
+ color: #0077cc;
48
+ }
49
+ .profiler-result a,
50
+ .profiler-queries a {
51
+ text-decoration: none;
52
+ }
53
+ .profiler-result a:hover,
54
+ .profiler-queries a:hover {
55
+ text-decoration: underline;
56
+ }
57
+ .profiler-result {
58
+ font-family: Helvetica, Arial, sans-serif;
59
+ }
60
+ .profiler-result .profiler-toggle-duration-with-children {
61
+ float: right;
62
+ }
63
+ .profiler-result table.profiler-client-timings {
64
+ margin-top: 10px;
65
+ }
66
+ .profiler-result .profiler-label {
67
+ color: #555555;
68
+ overflow: hidden;
69
+ text-overflow: ellipsis;
70
+ }
71
+ .profiler-result .profiler-unit {
72
+ color: #aaaaaa;
73
+ }
74
+ .profiler-result .profiler-trivial {
75
+ display: none;
76
+ }
77
+ .profiler-result .profiler-trivial td,
78
+ .profiler-result .profiler-trivial td * {
79
+ color: #aaaaaa !important;
80
+ }
81
+ .profiler-result pre,
82
+ .profiler-result code,
83
+ .profiler-result .profiler-number,
84
+ .profiler-result .profiler-unit {
85
+ font-family: Consolas, monospace, serif;
86
+ }
87
+ .profiler-result .profiler-number {
88
+ color: #111111;
89
+ }
90
+ .profiler-result .profiler-info {
91
+ text-align: right;
92
+ }
93
+ .profiler-result .profiler-info .profiler-name {
94
+ float: left;
95
+ }
96
+ .profiler-result .profiler-info .profiler-server-time {
97
+ white-space: nowrap;
98
+ }
99
+ .profiler-result .profiler-timings th {
100
+ background-color: #fff;
101
+ color: #aaaaaa;
102
+ text-align: right;
103
+ }
104
+ .profiler-result .profiler-timings th,
105
+ .profiler-result .profiler-timings td {
106
+ white-space: nowrap;
107
+ }
108
+ .profiler-result .profiler-timings .profiler-duration-with-children {
109
+ display: none;
110
+ }
111
+ .profiler-result .profiler-timings .profiler-duration {
112
+ font-family: Consolas, monospace, serif;
113
+ color: #111111;
114
+ text-align: right;
115
+ }
116
+ .profiler-result .profiler-timings .profiler-indent {
117
+ letter-spacing: 4px;
118
+ }
119
+ .profiler-result .profiler-timings .profiler-queries-show .profiler-number,
120
+ .profiler-result .profiler-timings .profiler-queries-show .profiler-unit {
121
+ color: #0077cc;
122
+ }
123
+ .profiler-result .profiler-timings .profiler-queries-duration {
124
+ padding-left: 6px;
125
+ }
126
+ .profiler-result .profiler-timings .profiler-percent-in-sql {
127
+ white-space: nowrap;
128
+ text-align: right;
129
+ }
130
+ .profiler-result .profiler-timings tfoot td {
131
+ padding-top: 10px;
132
+ text-align: right;
133
+ }
134
+ .profiler-result .profiler-timings tfoot td a {
135
+ font-size: 95%;
136
+ display: inline-block;
137
+ margin-left: 12px;
138
+ }
139
+ .profiler-result .profiler-timings tfoot td a:first-child {
140
+ float: left;
141
+ margin-left: 0px;
142
+ }
143
+ .profiler-result .profiler-timings tfoot td a.profiler-custom-link {
144
+ float: left;
145
+ }
146
+ .profiler-result .profiler-queries {
147
+ font-family: Helvetica, Arial, sans-serif;
148
+ }
149
+ .profiler-result .profiler-queries .profiler-stack-trace {
150
+ margin-bottom: 15px;
151
+ }
152
+ .profiler-result .profiler-queries pre {
153
+ font-family: Consolas, monospace, serif;
154
+ white-space: pre-wrap;
155
+ }
156
+ .profiler-result .profiler-queries th {
157
+ background-color: #fff;
158
+ border-bottom: 1px solid #555;
159
+ font-weight: bold;
160
+ padding: 15px;
161
+ white-space: nowrap;
162
+ }
163
+ .profiler-result .profiler-queries td {
164
+ padding: 15px;
165
+ text-align: left;
166
+ background-color: #fff;
167
+ }
168
+ .profiler-result .profiler-queries td:last-child {
169
+ padding-right: 25px;
170
+ }
171
+ .profiler-result .profiler-queries .profiler-odd td {
172
+ background-color: #e5e5e5;
173
+ }
174
+ .profiler-result .profiler-queries .profiler-since-start,
175
+ .profiler-result .profiler-queries .profiler-duration {
176
+ text-align: right;
177
+ }
178
+ .profiler-result .profiler-queries .profiler-info div {
179
+ text-align: right;
180
+ margin-bottom: 5px;
181
+ }
182
+ .profiler-result .profiler-queries .profiler-gap-info,
183
+ .profiler-result .profiler-queries .profiler-gap-info td {
184
+ background-color: #ccc;
185
+ }
186
+ .profiler-result .profiler-queries .profiler-gap-info .profiler-unit {
187
+ color: #777;
188
+ }
189
+ .profiler-result .profiler-queries .profiler-gap-info .profiler-info {
190
+ text-align: right;
191
+ }
192
+ .profiler-result .profiler-queries .profiler-gap-info.profiler-trivial-gaps {
193
+ display: none;
194
+ }
195
+ .profiler-result .profiler-queries .profiler-trivial-gap-container {
196
+ text-align: center;
197
+ }
198
+ .profiler-result .profiler-queries .str {
199
+ color: #800000;
200
+ }
201
+ .profiler-result .profiler-queries .kwd {
202
+ color: #00008b;
203
+ }
204
+ .profiler-result .profiler-queries .com {
205
+ color: #808080;
206
+ }
207
+ .profiler-result .profiler-queries .typ {
208
+ color: #2b91af;
209
+ }
210
+ .profiler-result .profiler-queries .lit {
211
+ color: #800000;
212
+ }
213
+ .profiler-result .profiler-queries .pun {
214
+ color: #000000;
215
+ }
216
+ .profiler-result .profiler-queries .pln {
217
+ color: #000000;
218
+ }
219
+ .profiler-result .profiler-queries .tag {
220
+ color: #800000;
221
+ }
222
+ .profiler-result .profiler-queries .atn {
223
+ color: #ff0000;
224
+ }
225
+ .profiler-result .profiler-queries .atv {
226
+ color: #0000ff;
227
+ }
228
+ .profiler-result .profiler-queries .dec {
229
+ color: #800080;
230
+ }
231
+ .profiler-result .profiler-warning,
232
+ .profiler-result .profiler-warning *,
233
+ .profiler-result .profiler-warning .profiler-queries-show,
234
+ .profiler-result .profiler-warning .profiler-queries-show .profiler-unit {
235
+ color: #f00;
236
+ }
237
+ .profiler-result .profiler-warning:hover,
238
+ .profiler-result .profiler-warning *:hover,
239
+ .profiler-result .profiler-warning .profiler-queries-show:hover,
240
+ .profiler-result .profiler-warning .profiler-queries-show .profiler-unit:hover {
241
+ color: #f00;
242
+ }
243
+ .profiler-result .profiler-nuclear {
244
+ color: #f00;
245
+ font-weight: bold;
246
+ padding-right: 2px;
247
+ }
248
+ .profiler-result .profiler-nuclear:hover {
249
+ color: #f00;
250
+ }
251
+ .profiler-results {
252
+ z-index: 2147483643;
253
+ position: fixed;
254
+ top: 0px;
255
+ }
256
+ .profiler-results.profiler-left {
257
+ left: 0px;
258
+ }
259
+ .profiler-results.profiler-left.profiler-no-controls .profiler-result:last-child .profiler-button,
260
+ .profiler-results.profiler-left .profiler-controls {
261
+ -webkit-border-bottom-right-radius: 10px;
262
+ -moz-border-radius-bottomright: 10px;
263
+ border-bottom-right-radius: 10px;
264
+ }
265
+ .profiler-results.profiler-left .profiler-button,
266
+ .profiler-results.profiler-left .profiler-controls {
267
+ border-right: 1px solid #888888;
268
+ }
269
+ .profiler-results.profiler-right {
270
+ right: 0px;
271
+ }
272
+ .profiler-results.profiler-right.profiler-no-controls .profiler-result:last-child .profiler-button,
273
+ .profiler-results.profiler-right .profiler-controls {
274
+ -webkit-border-bottom-left-radius: 10px;
275
+ -moz-border-radius-bottomleft: 10px;
276
+ border-bottom-left-radius: 10px;
277
+ }
278
+ .profiler-results.profiler-right .profiler-button,
279
+ .profiler-results.profiler-right .profiler-controls {
280
+ border-left: 1px solid #888888;
281
+ }
282
+ .profiler-results .profiler-button,
283
+ .profiler-results .profiler-controls {
284
+ display: none;
285
+ z-index: 2147483640;
286
+ border-bottom: 1px solid #888888;
287
+ background-color: #fff;
288
+ padding: 4px 7px;
289
+ text-align: right;
290
+ cursor: pointer;
291
+ }
292
+ .profiler-results .profiler-button.profiler-button-active,
293
+ .profiler-results .profiler-controls.profiler-button-active {
294
+ background-color: maroon;
295
+ }
296
+ .profiler-results .profiler-button.profiler-button-active .profiler-number,
297
+ .profiler-results .profiler-controls.profiler-button-active .profiler-number,
298
+ .profiler-results .profiler-button.profiler-button-active .profiler-nuclear,
299
+ .profiler-results .profiler-controls.profiler-button-active .profiler-nuclear {
300
+ color: #fff;
301
+ font-weight: bold;
302
+ }
303
+ .profiler-results .profiler-button.profiler-button-active .profiler-unit,
304
+ .profiler-results .profiler-controls.profiler-button-active .profiler-unit {
305
+ color: #fff;
306
+ font-weight: normal;
307
+ }
308
+ .profiler-results .profiler-controls {
309
+ display: block;
310
+ font-size: 12px;
311
+ font-family: Consolas, monospace, serif;
312
+ cursor: default;
313
+ text-align: center;
314
+ }
315
+ .profiler-results .profiler-controls span {
316
+ border-right: 1px solid #aaaaaa;
317
+ padding-right: 5px;
318
+ margin-right: 5px;
319
+ cursor: pointer;
320
+ }
321
+ .profiler-results .profiler-controls span:last-child {
322
+ border-right: none;
323
+ }
324
+ .profiler-results .profiler-popup {
325
+ display: none;
326
+ z-index: 2147483641;
327
+ position: absolute;
328
+ background-color: #fff;
329
+ border: 1px solid #aaa;
330
+ padding: 5px 10px;
331
+ text-align: left;
332
+ line-height: 18px;
333
+ overflow: auto;
334
+ -moz-box-shadow: 0px 1px 15px #555555;
335
+ -webkit-box-shadow: 0px 1px 15px #555555;
336
+ box-shadow: 0px 1px 15px #555555;
337
+ }
338
+ .profiler-results .profiler-popup .profiler-info {
339
+ margin-bottom: 3px;
340
+ padding-bottom: 2px;
341
+ border-bottom: 1px solid #ddd;
342
+ }
343
+ .profiler-results .profiler-popup .profiler-info .profiler-name {
344
+ font-size: 110%;
345
+ font-weight: bold;
346
+ }
347
+ .profiler-results .profiler-popup .profiler-info .profiler-name .profiler-overall-duration {
348
+ display: none;
349
+ }
350
+ .profiler-results .profiler-popup .profiler-info .profiler-server-time {
351
+ font-size: 95%;
352
+ }
353
+ .profiler-results .profiler-popup .profiler-timings th,
354
+ .profiler-results .profiler-popup .profiler-timings td {
355
+ padding-left: 6px;
356
+ padding-right: 6px;
357
+ }
358
+ .profiler-results .profiler-popup .profiler-timings th {
359
+ font-size: 95%;
360
+ padding-bottom: 3px;
361
+ }
362
+ .profiler-results .profiler-popup .profiler-timings .profiler-label {
363
+ max-width: 275px;
364
+ }
365
+ .profiler-results .profiler-queries {
366
+ display: none;
367
+ z-index: 2147483643;
368
+ position: absolute;
369
+ overflow-y: auto;
370
+ overflow-x: auto;
371
+ background-color: #fff;
372
+ }
373
+ .profiler-results .profiler-queries th {
374
+ font-size: 17px;
375
+ }
376
+ .profiler-results.profiler-min .profiler-result {
377
+ display: none;
378
+ }
379
+ .profiler-results.profiler-min .profiler-controls span {
380
+ display: none;
381
+ }
382
+ .profiler-results.profiler-min .profiler-controls .profiler-min-max {
383
+ border-right: none;
384
+ padding: 0px;
385
+ margin: 0px;
386
+ }
387
+ .profiler-queries-bg {
388
+ z-index: 2147483642;
389
+ display: none;
390
+ background: #000;
391
+ opacity: 0.7;
392
+ position: absolute;
393
+ top: 0px;
394
+ left: 0px;
395
+ min-width: 100%;
396
+ }
397
+ .profiler-result-full .profiler-result {
398
+ width: 950px;
399
+ margin: 30px auto;
400
+ }
401
+ .profiler-result-full .profiler-result .profiler-button {
402
+ display: none;
403
+ }
404
+ .profiler-result-full .profiler-result .profiler-popup .profiler-info {
405
+ font-size: 25px;
406
+ border-bottom: 1px solid #aaaaaa;
407
+ padding-bottom: 3px;
408
+ margin-bottom: 25px;
409
+ }
410
+ .profiler-result-full .profiler-result .profiler-popup .profiler-info .profiler-overall-duration {
411
+ padding-right: 20px;
412
+ font-size: 80%;
413
+ color: #888;
414
+ }
415
+ .profiler-result-full .profiler-result .profiler-popup .profiler-timings td,
416
+ .profiler-result-full .profiler-result .profiler-popup .profiler-timings th {
417
+ padding-left: 8px;
418
+ padding-right: 8px;
419
+ }
420
+ .profiler-result-full .profiler-result .profiler-popup .profiler-timings th {
421
+ padding-bottom: 7px;
422
+ }
423
+ .profiler-result-full .profiler-result .profiler-popup .profiler-timings td {
424
+ font-size: 14px;
425
+ padding-bottom: 4px;
426
+ }
427
+ .profiler-result-full .profiler-result .profiler-popup .profiler-timings td:first-child {
428
+ padding-left: 10px;
429
+ }
430
+ .profiler-result-full .profiler-result .profiler-popup .profiler-timings .profiler-label {
431
+ max-width: 550px;
432
+ }
433
+ .profiler-result-full .profiler-result .profiler-queries {
434
+ margin: 25px 0;
435
+ }
436
+ .profiler-result-full .profiler-result .profiler-queries table {
437
+ width: 100%;
438
+ }
439
+ .profiler-result-full .profiler-result .profiler-queries th {
440
+ font-size: 16px;
441
+ color: #555;
442
+ line-height: 20px;
443
+ }
444
+ .profiler-result-full .profiler-result .profiler-queries td {
445
+ padding: 15px 10px;
446
+ text-align: left;
447
+ }
448
+ .profiler-result-full .profiler-result .profiler-queries .profiler-info div {
449
+ text-align: right;
450
+ margin-bottom: 5px;
451
+ }
@@ -0,0 +1,945 @@
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
+ ;
12
+
13
+ var hasLocalStorage = function () {
14
+ try {
15
+ return 'localStorage' in window && window['localStorage'] !== null;
16
+ } catch (e) {
17
+ return false;
18
+ }
19
+ };
20
+
21
+ var getVersionedKey = function (keyPrefix) {
22
+ return keyPrefix + '-' + options.version;
23
+ }
24
+
25
+ var save = function (keyPrefix, value) {
26
+ if (!hasLocalStorage()) { return; }
27
+
28
+ // clear old keys with this prefix, if any
29
+ for (var i = 0; i < localStorage.length; i++) {
30
+ if ((localStorage.key(i) || '').indexOf(keyPrefix) > -1) {
31
+ localStorage.removeItem(localStorage.key(i));
32
+ }
33
+ }
34
+
35
+ // save under this version
36
+ localStorage[getVersionedKey(keyPrefix)] = value;
37
+ };
38
+
39
+ var load = function (keyPrefix) {
40
+ if (!hasLocalStorage()) { return null; }
41
+
42
+ return localStorage[getVersionedKey(keyPrefix)];
43
+ };
44
+
45
+ var fetchTemplates = function (success) {
46
+ var key = 'templates',
47
+ // cached = load(key);
48
+ cached = false
49
+
50
+ if (cached) {
51
+ $('body').append(cached);
52
+ success();
53
+ }
54
+ else {
55
+ $.get(options.path + 'includes.tmpl?v=' + options.version, function (data) {
56
+ if (data) {
57
+ save(key, data);
58
+ $('body').append(data);
59
+ success();
60
+ }
61
+ });
62
+ }
63
+ };
64
+
65
+ var getClientPerformance = function() {
66
+ return window.performance == null ? null : window.performance;
67
+ };
68
+
69
+ var fetchResults = function (ids) {
70
+ var clientPerformance, clientProbes, i, j, p, id, idx;
71
+
72
+ for (i = 0; i < ids.length; i++) {
73
+ id = ids[i];
74
+
75
+ clientPerformance = null;
76
+ clientProbes = null;
77
+
78
+ if (window.mPt) {
79
+ clientProbes = mPt.results();
80
+ for (j = 0; j < clientProbes.length; j++) {
81
+ clientProbes[j].d = clientProbes[j].d.getTime();
82
+ }
83
+ mPt.flush();
84
+ }
85
+
86
+ if (id == options.currentId) {
87
+
88
+ clientPerformance = getClientPerformance();
89
+
90
+ if (clientPerformance != null) {
91
+ // ie is buggy strip out functions
92
+ var copy = { navigation: {}, timing: {} };
93
+
94
+ var timing = $.extend({}, clientPerformance.timing);
95
+
96
+ for (p in timing) {
97
+ if (timing.hasOwnProperty(p) && !$.isFunction(timing[p])) {
98
+ copy.timing[p] = timing[p];
99
+ }
100
+ }
101
+ if (clientPerformance.navigation) {
102
+ copy.navigation.redirectCount = clientPerformance.navigation.redirectCount;
103
+ }
104
+ clientPerformance = copy;
105
+
106
+ // hack to add chrome timings
107
+ if (window.chrome && window.chrome.loadTimes) {
108
+ var chromeTimes = window.chrome.loadTimes();
109
+ if (chromeTimes.firstPaintTime) {
110
+ clientPerformance.timing["First Paint Time"] = Math.round(chromeTimes.firstPaintTime * 1000);
111
+ }
112
+ if (chromeTimes.firstPaintTime) {
113
+ clientPerformance.timing["First Paint After Load Time"] = Math.round(chromeTimes.firstPaintAfterLoadTime * 1000);
114
+ }
115
+
116
+ }
117
+ }
118
+ } else if (ajaxStartTime != null && clientProbes && clientProbes.length > 0) {
119
+ clientPerformance = { timing: { navigationStart: ajaxStartTime.getTime() } };
120
+ ajaxStartTime = null;
121
+ }
122
+
123
+ if ($.inArray(id, fetchedIds) < 0 && $.inArray(id, fetchingIds) < 0) {
124
+ idx = fetchingIds.push(id) - 1;
125
+
126
+ $.ajax({
127
+ url: options.path + 'results',
128
+ data: { id: id, clientPerformance: clientPerformance, clientProbes: clientProbes, popup: 1 },
129
+ dataType: 'json',
130
+ type: 'POST',
131
+ success: function (json) {
132
+ fetchedIds.push(id);
133
+ if (json != "hidden") {
134
+ buttonShow(json);
135
+ }
136
+ },
137
+ complete: function () {
138
+ fetchingIds.splice(idx, 1);
139
+ }
140
+ });
141
+ }
142
+ }
143
+ };
144
+
145
+ var renderTemplate = function (json) {
146
+ return $('#profilerTemplate').tmpl(json);
147
+ };
148
+
149
+ var buttonShow = function (json) {
150
+ var result = renderTemplate(json);
151
+
152
+ if (controls)
153
+ result.insertBefore(controls);
154
+ else
155
+ result.appendTo(container);
156
+
157
+ var button = result.find('.profiler-button'),
158
+ popup = result.find('.profiler-popup');
159
+
160
+ // button will appear in corner with the total profiling duration - click to show details
161
+ button.click(function () { buttonClick(button, popup); });
162
+
163
+ // small duration steps and the column with aggregate durations are hidden by default; allow toggling
164
+ toggleHidden(popup);
165
+
166
+ // lightbox in the queries
167
+ popup.find('.profiler-queries-show').click(function () { queriesShow($(this), result); });
168
+
169
+ // limit count
170
+ if (container.find('.profiler-result').length > options.maxTracesToShow)
171
+ container.find('.profiler-result').first().remove();
172
+ button.show();
173
+ };
174
+
175
+ var toggleHidden = function (popup) {
176
+ var trivial = popup.find('.profiler-toggle-trivial');
177
+ var childrenTime = popup.find('.profiler-toggle-duration-with-children');
178
+ var trivialGaps = popup.parent().find('.profiler-toggle-trivial-gaps');
179
+
180
+ var toggleIt = function (node) {
181
+ var link = $(node),
182
+ klass = "profiler-" + link.attr('class').substr('profiler-toggle-'.length),
183
+ isHidden = link.text().indexOf('show') > -1;
184
+
185
+ popup.parent().find('.' + klass).toggle(isHidden);
186
+ link.text(link.text().replace(isHidden ? 'show' : 'hide', isHidden ? 'hide' : 'show'));
187
+
188
+ popupPreventHorizontalScroll(popup);
189
+ };
190
+
191
+ childrenTime.add(trivial).add(trivialGaps).click(function () {
192
+ toggleIt(this);
193
+ });
194
+
195
+ // if option is set or all our timings are trivial, go ahead and show them
196
+ if (options.showTrivial || trivial.data('show-on-load')) {
197
+ toggleIt(trivial);
198
+ }
199
+ // if option is set, go ahead and show time with children
200
+ if (options.showChildrenTime) {
201
+ toggleIt(childrenTime);
202
+ }
203
+ };
204
+
205
+ var buttonClick = function (button, popup) {
206
+ // we're toggling this button/popup
207
+ if (popup.is(':visible')) {
208
+ popupHide(button, popup);
209
+ }
210
+ else {
211
+ var visiblePopups = container.find('.profiler-popup:visible'),
212
+ theirButtons = visiblePopups.siblings('.profiler-button');
213
+
214
+ // hide any other popups
215
+ popupHide(theirButtons, visiblePopups);
216
+
217
+ // before showing the one we clicked
218
+ popupShow(button, popup);
219
+ }
220
+ };
221
+
222
+ var popupShow = function (button, popup) {
223
+ button.addClass('profiler-button-active');
224
+
225
+ popupSetDimensions(button, popup);
226
+
227
+ popup.show();
228
+
229
+ popupPreventHorizontalScroll(popup);
230
+ };
231
+
232
+ var popupSetDimensions = function (button, popup) {
233
+ var top = button.position().top - 1, // position next to the button we clicked
234
+ windowHeight = $(window).height(),
235
+ maxHeight = windowHeight - top - 40; // make sure the popup doesn't extend below the fold
236
+
237
+ popup
238
+ .css({ 'top': top, 'max-height': maxHeight })
239
+ .css(options.renderPosition, button.outerWidth() - 3); // move left or right, based on config
240
+ };
241
+
242
+ var popupPreventHorizontalScroll = function (popup) {
243
+ var childrenHeight = 0;
244
+
245
+ popup.children().each(function () { childrenHeight += $(this).height(); });
246
+
247
+ popup.css({ 'padding-right': childrenHeight > popup.height() ? 40 : 10 });
248
+ }
249
+
250
+ var popupHide = function (button, popup) {
251
+ button.removeClass('profiler-button-active');
252
+ popup.hide();
253
+ };
254
+
255
+ var queriesShow = function (link, result) {
256
+
257
+ var px = 30,
258
+ win = $(window),
259
+ width = win.width() - 2 * px,
260
+ height = win.height() - 2 * px,
261
+ queries = result.find('.profiler-queries');
262
+
263
+ // opaque background
264
+ $('<div class="profiler-queries-bg"/>').appendTo('body').css({ 'height': $(document).height() }).show();
265
+
266
+ // center the queries and ensure long content is scrolled
267
+ queries.css({ 'top': px, 'max-height': height, 'width': width }).css(options.renderPosition, px)
268
+ .find('table').css({ 'width': width });
269
+
270
+ // have to show everything before we can get a position for the first query
271
+ queries.show();
272
+
273
+ queriesScrollIntoView(link, queries, queries);
274
+
275
+ // syntax highlighting
276
+ prettyPrint();
277
+ };
278
+
279
+ var queriesScrollIntoView = function (link, queries, whatToScroll) {
280
+ var id = link.closest('tr').attr('data-timing-id'),
281
+ cells = queries.find('tr[data-timing-id="' + id + '"] td');
282
+
283
+ // ensure they're in view
284
+ whatToScroll.scrollTop(whatToScroll.scrollTop() + cells.first().position().top - 100);
285
+
286
+ // 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
287
+ cells.each(function () {
288
+ var cell = $(this),
289
+ highlightHex = '#FFFFBB',
290
+ highlightRgb = getRGB(highlightHex),
291
+ originalRgb = getRGB(cell.css('background-color')),
292
+ getColorDiff = function (fx, i) {
293
+ // adapted from John Resig's color plugin: http://plugins.jquery.com/project/color
294
+ return Math.max(Math.min(parseInt((fx.pos * (originalRgb[i] - highlightRgb[i])) + highlightRgb[i]), 255), 0);
295
+ };
296
+
297
+ // we need to animate some other property to piggy-back on the step function, so I choose you, opacity!
298
+ cell.css({ 'opacity': 1, 'background-color': highlightHex })
299
+ .animate({ 'opacity': 1 }, { duration: 2000, step: function (now, fx) {
300
+ fx.elem.style['backgroundColor'] = "rgb(" + [getColorDiff(fx, 0), getColorDiff(fx, 1), getColorDiff(fx, 2)].join(",") + ")";
301
+ }
302
+ });
303
+ });
304
+ };
305
+
306
+ // Color Conversion functions from highlightFade
307
+ // By Blair Mitchelmore
308
+ // http://jquery.offput.ca/highlightFade/
309
+ // Parse strings looking for color tuples [255,255,255]
310
+ var getRGB = function (color) {
311
+ var result;
312
+
313
+ // Check if we're already dealing with an array of colors
314
+ if (color && color.constructor == Array && color.length == 3) return color;
315
+
316
+ // Look for rgb(num,num,num)
317
+ 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])];
318
+
319
+ // Look for rgb(num%,num%,num%)
320
+ 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];
321
+
322
+ // Look for #a0b1c2
323
+ 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)];
324
+
325
+ // Look for #fff
326
+ 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)];
327
+
328
+ // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
329
+ if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) return colors['transparent'];
330
+
331
+ return null;
332
+ };
333
+
334
+ var bindDocumentEvents = function () {
335
+ $(document).bind('click keyup', function (e) {
336
+
337
+ // this happens on every keystroke, and :visible is crazy expensive in IE <9
338
+ // and in this case, the display:none check is sufficient.
339
+ var popup = $('.profiler-popup').filter(function () { return $(this).css("display") !== "none"; });
340
+
341
+ if (!popup.length) {
342
+ return;
343
+ }
344
+
345
+ var button = popup.siblings('.profiler-button'),
346
+ queries = popup.closest('.profiler-result').find('.profiler-queries'),
347
+ bg = $('.profiler-queries-bg'),
348
+ isEscPress = e.type == 'keyup' && e.which == 27,
349
+ hidePopup = false,
350
+ hideQueries = false;
351
+
352
+ if (bg.is(':visible')) {
353
+ hideQueries = isEscPress || (e.type == 'click' && !$.contains(queries[0], e.target) && !$.contains(popup[0], e.target));
354
+ }
355
+ else if (popup.is(':visible')) {
356
+ hidePopup = isEscPress || (e.type == 'click' && !$.contains(popup[0], e.target) && !$.contains(button[0], e.target) && button[0] != e.target);
357
+ }
358
+
359
+ if (hideQueries) {
360
+ bg.remove();
361
+ queries.hide();
362
+ }
363
+
364
+ if (hidePopup) {
365
+ popupHide(button, popup);
366
+ }
367
+ });
368
+ $(document).bind('keydown', options.toggleShortcut, function(e) {
369
+ $('.profiler-results').toggle();
370
+ });
371
+ };
372
+
373
+ var initFullView = function () {
374
+
375
+ // first, get jquery tmpl, then render and bind handlers
376
+ fetchTemplates(function () {
377
+
378
+ // profiler will be defined in the full page's head
379
+ renderTemplate(profiler).appendTo(container);
380
+
381
+ var popup = $('.profiler-popup');
382
+
383
+ toggleHidden(popup);
384
+
385
+ prettyPrint();
386
+
387
+ // since queries are already shown, just highlight and scroll when clicking a "1 sql" link
388
+ popup.find('.profiler-queries-show').click(function () {
389
+ queriesScrollIntoView($(this), $('.profiler-queries'), $(document));
390
+ });
391
+ });
392
+ };
393
+
394
+ var initControls = function (container) {
395
+ if (options.showControls) {
396
+ controls = $('<div class="profiler-controls"><span class="profiler-min-max">m</span><span class="profiler-clear">c</span></div>').appendTo(container);
397
+
398
+ $('.profiler-controls .profiler-min-max').click(function () {
399
+ container.toggleClass('profiler-min');
400
+ });
401
+
402
+ container.hover(function () {
403
+ if ($(this).hasClass('profiler-min')) {
404
+ $(this).find('.profiler-min-max').show();
405
+ }
406
+ },
407
+ function () {
408
+ if ($(this).hasClass('profiler-min')) {
409
+ $(this).find('.profiler-min-max').hide();
410
+ }
411
+ });
412
+
413
+ $('.profiler-controls .profiler-clear').click(function () {
414
+ container.find('.profiler-result').remove();
415
+ });
416
+ }
417
+ else {
418
+ container.addClass('profiler-no-controls');
419
+ }
420
+ };
421
+
422
+ var initPopupView = function () {
423
+
424
+ if (options.authorized) {
425
+ // all fetched profilings will go in here
426
+ container = $('<div class="profiler-results"/>').appendTo('body');
427
+
428
+ // MiniProfiler.RenderIncludes() sets which corner to render in - default is upper left
429
+ container.addClass("profiler-" + options.renderPosition);
430
+
431
+ //initialize the controls
432
+ initControls(container);
433
+
434
+ // we'll render results json via a jquery.tmpl - after we get the templates, we'll fetch the initial json to populate it
435
+ fetchTemplates(function () {
436
+ // get master page profiler results
437
+ fetchResults(options.ids);
438
+ });
439
+ if (options.startHidden) container.hide();
440
+ }
441
+ else {
442
+ fetchResults(options.ids);
443
+ }
444
+
445
+ var jQueryAjaxComplete = function (e, xhr, settings) {
446
+ if (xhr) {
447
+ // should be an array of strings, e.g. ["008c4813-9bd7-443d-9376-9441ec4d6a8c","16ff377b-8b9c-4c20-a7b5-97cd9fa7eea7"]
448
+ var stringIds = xhr.getResponseHeader('X-MiniProfiler-Ids');
449
+ if (stringIds) {
450
+ var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
451
+ fetchResults(ids);
452
+ }
453
+ }
454
+ };
455
+
456
+ // fetch profile results for any ajax calls
457
+ // note, this does not use $ cause we want to hook into the main jQuery
458
+ if (jQuery && jQuery(document) && jQuery(document).ajaxComplete) {
459
+ jQuery(document).ajaxComplete(jQueryAjaxComplete);
460
+ }
461
+
462
+ if (jQuery && jQuery(document).ajaxStart)
463
+ jQuery(document).ajaxStart(function () { ajaxStartTime = new Date(); });
464
+
465
+ // fetch results after ASP Ajax calls
466
+ if (typeof (Sys) != 'undefined' && typeof (Sys.WebForms) != 'undefined' && typeof (Sys.WebForms.PageRequestManager) != 'undefined') {
467
+ // Get the instance of PageRequestManager.
468
+ var PageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
469
+
470
+ PageRequestManager.add_endRequest(function (sender, args) {
471
+ if (args) {
472
+ var response = args.get_response();
473
+ if (response.get_responseAvailable() && response._xmlHttpRequest != null) {
474
+ var stringIds = args.get_response().getResponseHeader('X-MiniProfiler-Ids');
475
+ if (stringIds) {
476
+ var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
477
+ fetchResults(ids);
478
+ }
479
+ }
480
+ }
481
+ });
482
+ }
483
+
484
+ // more Asp.Net callbacks
485
+ if (typeof (WebForm_ExecuteCallback) == "function") {
486
+ WebForm_ExecuteCallback = (function (callbackObject) {
487
+ // Store original function
488
+ var original = WebForm_ExecuteCallback;
489
+
490
+ return function (callbackObject) {
491
+ original(callbackObject);
492
+
493
+ var stringIds = callbackObject.xmlRequest.getResponseHeader('X-MiniProfiler-Ids');
494
+ if (stringIds) {
495
+ var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
496
+ fetchResults(ids);
497
+ }
498
+ }
499
+
500
+ })();
501
+ }
502
+
503
+ // also fetch results after ExtJS requests, in case it is being used
504
+ if (typeof (Ext) != 'undefined' && typeof (Ext.Ajax) != 'undefined' && typeof (Ext.Ajax.on) != 'undefined') {
505
+ // Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
506
+ Ext.Ajax.on('requestcomplete', function(e, xhr, settings) {
507
+ var stringIds = xhr.getResponseHeader('X-MiniProfiler-Ids');
508
+ if (stringIds) {
509
+ var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
510
+ fetchResults(ids);
511
+ }
512
+ });
513
+ }
514
+
515
+ if (typeof (MooTools) != 'undefined' && typeof (Request) != 'undefined') {
516
+ Request.prototype.addEvents({
517
+ onComplete: function() {
518
+ var stringIds = this.xhr.getResponseHeader('X-MiniProfiler-Ids');
519
+ if (stringIds) {
520
+ var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
521
+ fetchResults(ids);
522
+ }
523
+ }
524
+ });
525
+ }
526
+
527
+ // add support for AngularJS, which use the basic XMLHttpRequest object.
528
+ if (window.angular && typeof (XMLHttpRequest) != 'undefined') {
529
+ var _send = XMLHttpRequest.prototype.send;
530
+
531
+ XMLHttpRequest.prototype.send = function sendReplacement(data) {
532
+ this._onreadystatechange = this.onreadystatechange;
533
+
534
+ this.onreadystatechange = function onReadyStateChangeReplacement() {
535
+ if (this.readyState == 4) {
536
+ var stringIds = this.getResponseHeader('X-MiniProfiler-Ids');
537
+ if (stringIds) {
538
+ var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
539
+ fetchResults(ids);
540
+ }
541
+ }
542
+
543
+ return this._onreadystatechange.apply(this, arguments);
544
+ }
545
+
546
+ return _send.apply(this, arguments);
547
+ }
548
+ }
549
+
550
+ // some elements want to be hidden on certain doc events
551
+ bindDocumentEvents();
552
+ };
553
+
554
+ return {
555
+
556
+ init: function () {
557
+ var script = document.getElementById('mini-profiler');
558
+ if (!script || !script.getAttribute) return;
559
+
560
+ options = (function () {
561
+ var version = script.getAttribute('data-version');
562
+ var path = script.getAttribute('data-path');
563
+
564
+ var currentId = script.getAttribute('data-current-id');
565
+
566
+ var ids = script.getAttribute('data-ids');
567
+ if (ids) ids = ids.split(',');
568
+
569
+ var position = script.getAttribute('data-position');
570
+
571
+ var toggleShortcut = script.getAttribute('data-toggle-shortcut');
572
+
573
+ if (script.getAttribute('data-max-traces'))
574
+ var maxTraces = parseInt(script.getAttribute('data-max-traces'));
575
+
576
+ if (script.getAttribute('data-trivial') === 'true') var trivial = true;
577
+ if (script.getAttribute('data-children') == 'true') var children = true;
578
+ if (script.getAttribute('data-controls') == 'true') var controls = true;
579
+ if (script.getAttribute('data-authorized') == 'true') var authorized = true;
580
+ if (script.getAttribute('data-start-hidden') == 'true') var startHidden = true;
581
+
582
+ return {
583
+ ids: ids,
584
+ path: path,
585
+ version: version,
586
+ renderPosition: position,
587
+ showTrivial: trivial,
588
+ showChildrenTime: children,
589
+ maxTracesToShow: maxTraces,
590
+ showControls: controls,
591
+ currentId: currentId,
592
+ authorized: authorized,
593
+ toggleShortcut: toggleShortcut,
594
+ startHidden: startHidden
595
+ }
596
+ })();
597
+
598
+ var doInit = function () {
599
+ // when rendering a shared, full page, this div will exist
600
+ container = $('.profiler-result-full');
601
+ if (container.length) {
602
+ if (window.location.href.indexOf("&trivial=1") > 0) {
603
+ options.showTrivial = true
604
+ }
605
+ initFullView();
606
+ }
607
+ else {
608
+ initPopupView();
609
+ }
610
+ };
611
+
612
+ // this preserves debugging
613
+ var load = function (s, f) {
614
+ var sc = document.createElement("script");
615
+ sc.async = "async";
616
+ sc.type = "text/javascript";
617
+ sc.src = s;
618
+ var done = false;
619
+ sc.onload = sc.onreadystatechange = function (_, abort) {
620
+ if (!sc.readyState || /loaded|complete/.test(sc.readyState)) {
621
+ if (!abort && !done) { done = true; f(); }
622
+ }
623
+ };
624
+ document.getElementsByTagName('head')[0].appendChild(sc);
625
+ };
626
+
627
+ var wait = 0;
628
+ var finish = false;
629
+ var deferInit = function() {
630
+ if (finish) return;
631
+ if (window.performance && window.performance.timing && window.performance.timing.loadEventEnd == 0 && wait < 10000) {
632
+ setTimeout(deferInit, 100);
633
+ wait += 100;
634
+ } else {
635
+ finish = true;
636
+ init();
637
+ }
638
+ };
639
+
640
+ var init = function() {
641
+ if (options.authorized) {
642
+ var url = options.path + "includes.css?v=" + options.version;
643
+ if (document.createStyleSheet) {
644
+ document.createStyleSheet(url);
645
+ } else {
646
+ $('head').append($('<link rel="stylesheet" type="text/css" href="' + url + '" />'));
647
+ }
648
+ if (!$.tmpl) {
649
+ load(options.path + 'jquery.tmpl.js?v=' + options.version, doInit);
650
+ } else {
651
+ doInit();
652
+ }
653
+ } else {
654
+ doInit();
655
+ }
656
+ };
657
+
658
+ if (typeof(jQuery) == 'function') {
659
+ var jQueryVersion = jQuery.fn.jquery.split('.');
660
+ }
661
+ if (jQueryVersion && parseInt(jQueryVersion[0]) < 2 && parseInt(jQueryVersion[1]) >= 7) {
662
+ MiniProfiler.jQuery = $ = jQuery;
663
+ $(deferInit);
664
+ } else {
665
+ load(options.path + "jquery.1.7.1.js?v=" + options.version, function() {
666
+ MiniProfiler.jQuery = $ = jQuery.noConflict(true);
667
+ $(deferInit);
668
+ });
669
+ }
670
+ },
671
+
672
+ getClientTimingByName: function (clientTiming, name) {
673
+
674
+ for (var i = 0; i < clientTiming.Timings.length; i++) {
675
+ if (clientTiming.Timings[i].Name == name) {
676
+ return clientTiming.Timings[i];
677
+ }
678
+ }
679
+ return { Name: name, Duration: "", Start: "" };
680
+ },
681
+
682
+ renderDate: function (jsonDate) { // JavaScriptSerializer sends dates as /Date(1308024322065)/
683
+ if (jsonDate) {
684
+ return (typeof jsonDate === 'string') ? new Date(parseInt(jsonDate.replace("/Date(", "").replace(")/", ""), 10)).toUTCString() : jsonDate;
685
+ }
686
+ },
687
+
688
+ renderIndent: function (depth) {
689
+ var result = '';
690
+ for (var i = 0; i < depth; i++) {
691
+ result += '&nbsp;';
692
+ }
693
+ return result;
694
+ },
695
+
696
+ renderExecuteType: function (typeId) {
697
+ // see StackExchange.Profiling.ExecuteType enum
698
+ switch (typeId) {
699
+ case 0: return 'None';
700
+ case 1: return 'NonQuery';
701
+ case 2: return 'Scalar';
702
+ case 3: return 'Reader';
703
+ }
704
+ },
705
+
706
+ shareUrl: function (id) {
707
+ return options.path + 'results?id=' + id;
708
+ },
709
+
710
+ getClientTimings: function (clientTimings) {
711
+ var list = [];
712
+ var t;
713
+
714
+ if (!clientTimings.Timings) return [];
715
+
716
+ for (var i = 0; i < clientTimings.Timings.length; i++) {
717
+ t = clientTimings.Timings[i];
718
+ var trivial = t.Name != "Dom Complete" && t.Name != "Response" && t.Name != "First Paint Time";
719
+ trivial = t.Duration < 2 ? trivial : false;
720
+ list.push(
721
+ {
722
+ isTrivial: trivial,
723
+ name: t.Name,
724
+ duration: t.Duration,
725
+ start: t.Start
726
+ });
727
+ }
728
+
729
+ list.sort(function (a, b) { return a.start - b.start; });
730
+ return list;
731
+ },
732
+
733
+ getSqlTimings: function (root) {
734
+ var result = [],
735
+ addToResults = function (timing) {
736
+ if (timing.SqlTimings) {
737
+ for (var i = 0, sqlTiming; i < timing.SqlTimings.length; i++) {
738
+ sqlTiming = timing.SqlTimings[i];
739
+
740
+ // HACK: add info about the parent Timing to each SqlTiming so UI can render
741
+ sqlTiming.ParentTimingName = timing.Name;
742
+ result.push(sqlTiming);
743
+ }
744
+ }
745
+
746
+ if (timing.Children) {
747
+ for (var i = 0; i < timing.Children.length; i++) {
748
+ addToResults(timing.Children[i]);
749
+ }
750
+ }
751
+ };
752
+
753
+ // start adding at the root and recurse down
754
+ addToResults(root);
755
+
756
+ var removeDuration = function(list, duration) {
757
+
758
+ var newList = [];
759
+ for (var i = 0; i < list.length; i++) {
760
+
761
+ var item = list[i];
762
+ if (duration.start > item.start) {
763
+ if (duration.start > item.finish) {
764
+ newList.push(item);
765
+ continue;
766
+ }
767
+ newList.push({ start: item.start, finish: duration.start });
768
+ }
769
+
770
+ if (duration.finish < item.finish) {
771
+ if (duration.finish < item.start) {
772
+ newList.push(item);
773
+ continue;
774
+ }
775
+ newList.push({ start: duration.finish, finish: item.finish });
776
+ }
777
+ }
778
+
779
+ return newList;
780
+ };
781
+
782
+ var processTimes = function (elem, parent) {
783
+ var duration = { start: elem.StartMilliseconds, finish: (elem.StartMilliseconds + elem.DurationMilliseconds) };
784
+ elem.richTiming = [duration];
785
+ if (parent != null) {
786
+ elem.parent = parent;
787
+ elem.parent.richTiming = removeDuration(elem.parent.richTiming, duration);
788
+ }
789
+
790
+ if (elem.Children) {
791
+ for (var i = 0; i < elem.Children.length; i++) {
792
+ processTimes(elem.Children[i], elem);
793
+ }
794
+ }
795
+ };
796
+
797
+ processTimes(root, null);
798
+
799
+ // sort results by time
800
+ result.sort(function (a, b) { return a.StartMilliseconds - b.StartMilliseconds; });
801
+
802
+ var determineOverlap = function(gap, node) {
803
+ var overlap = 0;
804
+ for (var i = 0; i < node.richTiming.length; i++) {
805
+ var current = node.richTiming[i];
806
+ if (current.start > gap.finish) {
807
+ break;
808
+ }
809
+ if (current.finish < gap.start) {
810
+ continue;
811
+ }
812
+
813
+ overlap += Math.min(gap.finish, current.finish) - Math.max(gap.start, current.start);
814
+ }
815
+ return overlap;
816
+ };
817
+
818
+ var determineGap = function (gap, node, match) {
819
+ var overlap = determineOverlap(gap, node);
820
+ if (match == null || overlap > match.duration) {
821
+ match = { name: node.Name, duration: overlap };
822
+ }
823
+ else if (match.name == node.Name) {
824
+ match.duration += overlap;
825
+ }
826
+
827
+ if (node.Children) {
828
+ for (var i = 0; i < node.Children.length; i++) {
829
+ match = determineGap(gap, node.Children[i], match);
830
+ }
831
+ }
832
+ return match;
833
+ };
834
+
835
+ var time = 0;
836
+ var prev = null;
837
+ $.each(result, function () {
838
+ this.prevGap = {
839
+ duration: (this.StartMilliseconds - time).toFixed(2),
840
+ start: time,
841
+ finish: this.StartMilliseconds
842
+ };
843
+
844
+ this.prevGap.topReason = determineGap(this.prevGap, root, null);
845
+
846
+ time = this.StartMilliseconds + this.DurationMilliseconds;
847
+ prev = this;
848
+ });
849
+
850
+
851
+ if (result.length > 0) {
852
+ var me = result[result.length - 1];
853
+ me.nextGap = {
854
+ duration: (root.DurationMilliseconds - time).toFixed(2),
855
+ start: time,
856
+ finish: root.DurationMilliseconds
857
+ };
858
+ me.nextGap.topReason = determineGap(me.nextGap, root, null);
859
+ }
860
+
861
+ return result;
862
+ },
863
+
864
+ getSqlTimingsCount: function (root) {
865
+ var result = 0,
866
+ countSql = function (timing) {
867
+ if (timing.SqlTimings) {
868
+ result += timing.SqlTimings.length;
869
+ }
870
+
871
+ if (timing.Children) {
872
+ for (var i = 0; i < timing.Children.length; i++) {
873
+ countSql(timing.Children[i]);
874
+ }
875
+ }
876
+ };
877
+ countSql(root);
878
+ return result;
879
+ },
880
+
881
+ fetchResultsExposed: function (ids) {
882
+ return fetchResults(ids);
883
+ },
884
+
885
+ formatDuration: function (duration) {
886
+ return (duration || 0).toFixed(1);
887
+ }
888
+ };
889
+ })();
890
+
891
+ MiniProfiler.init();
892
+
893
+ // jquery.hotkeys.js
894
+ // https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js
895
+
896
+ (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]=
897
+ !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:"+",
898
+ 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}})})(jQuery);
899
+
900
+ // prettify.js
901
+ // http://code.google.com/p/google-code-prettify/
902
+
903
+ 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};
904
+ (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(">");
905
+ 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),
906
+ 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);
907
+ 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("-");
908
+ 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("\\"===
909
+ 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,
910
+ ""))){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,
911
+ 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)];
912
+ 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])*(?:\"|$))/,
913
+ 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*)>/,
914
+ 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]*/,
915
+ 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,
916
+ 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;
917
+ 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]}
918
+ 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&&
919
+ 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,
920
+ "&")}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=["!","!=","!==","#","%","%=","&","&&","&&=","&=","(","*","*=","+=",",","-=","->","/","/=",":","::",";","<","<<","<<=","<=","=","==","===",">",">=",">>",">>=",">>>",">>>=","?","@","[","^","^=","^^","^^=","{","|","|=","||","||=",
921
+ "~","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]*)/,
922
+ 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 ",
923
+ 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",
924
+ "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],
925
+ ["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 ",
926
+ 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 ",
927
+ 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 ",
928
+ 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"]);
929
+ 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,
930
+ 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]+/]]),
931
+ ["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")>=
932
+ 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,
933
+ " "))}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"),
934
+ 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,
935
+ PR_TAG:"tag",PR_TYPE:S}})()
936
+
937
+ ;
938
+
939
+ // lang-sql.js
940
+ // http://code.google.com/p/google-code-prettify/
941
+
942
+ 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,
943
+ 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"])
944
+
945
+ ;