##// END OF EJS Templates
Merge pull request #3605 from ellisonbg/newux...
Brian E. Granger -
r14101:59235449 merge
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

This diff has been collapsed as it changes many lines, (683 lines changed) Show them Hide them
@@ -0,0 +1,683 b''
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2011 The IPython Development Team
3 //
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
7
8 //============================================================================
9 // Keyboard management
10 //============================================================================
11
12 var IPython = (function (IPython) {
13 "use strict";
14
15 // Setup global keycodes and inverse keycodes.
16
17 // See http://unixpapa.com/js/key.html for a complete description. The short of
18 // it is that there are different keycode sets. Firefox uses the "Mozilla keycodes"
19 // and Webkit/IE use the "IE keycodes". These keycode sets are mostly the same
20 // but have minor differences.
21
22 // These apply to Firefox, (Webkit and IE)
23 var _keycodes = {
24 'a': 65, 'b': 66, 'c': 67, 'd': 68, 'e': 69, 'f': 70, 'g': 71, 'h': 72, 'i': 73,
25 'j': 74, 'k': 75, 'l': 76, 'm': 77, 'n': 78, 'o': 79, 'p': 80, 'q': 81, 'r': 82,
26 's': 83, 't': 84, 'u': 85, 'v': 86, 'w': 87, 'x': 88, 'y': 89, 'z': 90,
27 '1 !': 49, '2 @': 50, '3 #': 51, '4 $': 52, '5 %': 53, '6 ^': 54,
28 '7 &': 55, '8 *': 56, '9 (': 57, '0 )': 48,
29 '[ {': 219, '] }': 221, '` ~': 192, ', <': 188, '. >': 190, '/ ?': 191,
30 '\\ |': 220, '\' "': 222,
31 'numpad0': 96, 'numpad1': 97, 'numpad2': 98, 'numpad3': 99, 'numpad4': 100,
32 'numpad5': 101, 'numpad6': 102, 'numpad7': 103, 'numpad8': 104, 'numpad9': 105,
33 'multiply': 106, 'add': 107, 'subtract': 109, 'decimal': 110, 'divide': 111,
34 'f1': 112, 'f2': 113, 'f3': 114, 'f4': 115, 'f5': 116, 'f6': 117, 'f7': 118,
35 'f8': 119, 'f9': 120, 'f11': 122, 'f12': 123, 'f13': 124, 'f14': 125, 'f15': 126,
36 'backspace': 8, 'tab': 9, 'enter': 13, 'shift': 16, 'ctrl': 17, 'alt': 18,
37 'meta': 91, 'capslock': 20, 'esc': 27, 'space': 32, 'pageup': 33, 'pagedown': 34,
38 'end': 35, 'home': 36, 'left': 37, 'up': 38, 'right': 39, 'down': 40,
39 'insert': 45, 'delete': 46, 'numlock': 144,
40 };
41
42 // These apply to Firefox and Opera
43 var _mozilla_keycodes = {
44 '; :': 59, '= +': 61, '- _': 173, 'meta': 224
45 }
46
47 // This apply to Webkit and IE
48 var _ie_keycodes = {
49 '; :': 186, '= +': 187, '- _': 189,
50 }
51
52 var browser = IPython.utils.browser[0];
53
54 if (browser === 'Firefox' || browser === 'Opera') {
55 $.extend(_keycodes, _mozilla_keycodes);
56 } else if (browser === 'Safari' || browser === 'Chrome' || browser === 'MSIE') {
57 $.extend(_keycodes, _ie_keycodes);
58 }
59
60 var keycodes = {};
61 var inv_keycodes = {};
62 for (var name in _keycodes) {
63 var names = name.split(' ');
64 if (names.length === 1) {
65 var n = names[0]
66 keycodes[n] = _keycodes[n]
67 inv_keycodes[_keycodes[n]] = n
68 } else {
69 var primary = names[0];
70 var secondary = names[1];
71 keycodes[primary] = _keycodes[name]
72 keycodes[secondary] = _keycodes[name]
73 inv_keycodes[_keycodes[name]] = primary
74 }
75 }
76
77
78 // Default keyboard shortcuts
79
80 var default_common_shortcuts = {
81 'meta+s' : {
82 help : 'save notebook',
83 help_index : 'fb',
84 handler : function (event) {
85 IPython.notebook.save_checkpoint();
86 event.preventDefault();
87 return false;
88 }
89 },
90 'ctrl+s' : {
91 help : 'save notebook',
92 help_index : 'fc',
93 handler : function (event) {
94 IPython.notebook.save_checkpoint();
95 event.preventDefault();
96 return false;
97 }
98 },
99 'shift' : {
100 help : '',
101 help_index : '',
102 handler : function (event) {
103 // ignore shift keydown
104 return true;
105 }
106 },
107 'shift+enter' : {
108 help : 'run cell',
109 help_index : 'ba',
110 handler : function (event) {
111 IPython.notebook.execute_cell();
112 return false;
113 }
114 },
115 'ctrl+enter' : {
116 help : 'run cell, select below',
117 help_index : 'bb',
118 handler : function (event) {
119 IPython.notebook.execute_cell_and_select_below();
120 return false;
121 }
122 },
123 'alt+enter' : {
124 help : 'run cell, insert below',
125 help_index : 'bc',
126 handler : function (event) {
127 IPython.notebook.execute_cell_and_insert_below();
128 return false;
129 }
130 }
131 }
132
133 // Edit mode defaults
134
135 var default_edit_shortcuts = {
136 'esc' : {
137 help : 'command mode',
138 help_index : 'aa',
139 handler : function (event) {
140 IPython.notebook.command_mode();
141 IPython.notebook.focus_cell();
142 return false;
143 }
144 },
145 'ctrl+m' : {
146 help : 'command mode',
147 help_index : 'ab',
148 handler : function (event) {
149 IPython.notebook.command_mode();
150 IPython.notebook.focus_cell();
151 return false;
152 }
153 },
154 'up' : {
155 help : '',
156 help_index : '',
157 handler : function (event) {
158 var cell = IPython.notebook.get_selected_cell();
159 if (cell && cell.at_top()) {
160 event.preventDefault();
161 IPython.notebook.command_mode()
162 IPython.notebook.select_prev();
163 IPython.notebook.edit_mode();
164 return false;
165 };
166 }
167 },
168 'down' : {
169 help : '',
170 help_index : '',
171 handler : function (event) {
172 var cell = IPython.notebook.get_selected_cell();
173 if (cell && cell.at_bottom()) {
174 event.preventDefault();
175 IPython.notebook.command_mode()
176 IPython.notebook.select_next();
177 IPython.notebook.edit_mode();
178 return false;
179 };
180 }
181 },
182 'alt+-' : {
183 help : 'split cell',
184 help_index : 'ea',
185 handler : function (event) {
186 IPython.notebook.split_cell();
187 return false;
188 }
189 },
190 'alt+subtract' : {
191 help : '',
192 help_index : 'eb',
193 handler : function (event) {
194 IPython.notebook.split_cell();
195 return false;
196 }
197 },
198 }
199
200 // Command mode defaults
201
202 var default_command_shortcuts = {
203 'enter' : {
204 help : 'edit mode',
205 help_index : 'aa',
206 handler : function (event) {
207 IPython.notebook.edit_mode();
208 return false;
209 }
210 },
211 'up' : {
212 help : 'select previous cell',
213 help_index : 'da',
214 handler : function (event) {
215 var index = IPython.notebook.get_selected_index();
216 if (index !== 0 && index !== null) {
217 IPython.notebook.select_prev();
218 var cell = IPython.notebook.get_selected_cell();
219 cell.focus_cell();
220 };
221 return false;
222 }
223 },
224 'down' : {
225 help : 'select next cell',
226 help_index : 'db',
227 handler : function (event) {
228 var index = IPython.notebook.get_selected_index();
229 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
230 IPython.notebook.select_next();
231 var cell = IPython.notebook.get_selected_cell();
232 cell.focus_cell();
233 };
234 return false;
235 }
236 },
237 'k' : {
238 help : 'select previous cell',
239 help_index : 'dc',
240 handler : function (event) {
241 var index = IPython.notebook.get_selected_index();
242 if (index !== 0 && index !== null) {
243 IPython.notebook.select_prev();
244 var cell = IPython.notebook.get_selected_cell();
245 cell.focus_cell();
246 };
247 return false;
248 }
249 },
250 'j' : {
251 help : 'select next cell',
252 help_index : 'dd',
253 handler : function (event) {
254 var index = IPython.notebook.get_selected_index();
255 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
256 IPython.notebook.select_next();
257 var cell = IPython.notebook.get_selected_cell();
258 cell.focus_cell();
259 };
260 return false;
261 }
262 },
263 'x' : {
264 help : 'cut cell',
265 help_index : 'ee',
266 handler : function (event) {
267 IPython.notebook.cut_cell();
268 return false;
269 }
270 },
271 'c' : {
272 help : 'copy cell',
273 help_index : 'ef',
274 handler : function (event) {
275 IPython.notebook.copy_cell();
276 return false;
277 }
278 },
279 'v' : {
280 help : 'paste cell below',
281 help_index : 'eg',
282 handler : function (event) {
283 IPython.notebook.paste_cell_below();
284 return false;
285 }
286 },
287 'd' : {
288 help : 'delete cell (press twice)',
289 help_index : 'ei',
290 handler : function (event) {
291 var dc = IPython.keyboard_manager._delete_count;
292 if (dc === 0) {
293 IPython.keyboard_manager._delete_count = 1;
294 setTimeout(function () {
295 IPython.keyboard_manager._delete_count = 0;
296 }, 800);
297 } else if (dc === 1) {
298 IPython.notebook.delete_cell();
299 IPython.keyboard_manager._delete_count = 0;
300 }
301 return false;
302 }
303 },
304 'a' : {
305 help : 'insert cell above',
306 help_index : 'ec',
307 handler : function (event) {
308 IPython.notebook.insert_cell_above('code');
309 IPython.notebook.select_prev();
310 IPython.notebook.focus_cell();
311 return false;
312 }
313 },
314 'b' : {
315 help : 'insert cell below',
316 help_index : 'ed',
317 handler : function (event) {
318 IPython.notebook.insert_cell_below('code');
319 IPython.notebook.select_next();
320 IPython.notebook.focus_cell();
321 return false;
322 }
323 },
324 'y' : {
325 help : 'to code',
326 help_index : 'ca',
327 handler : function (event) {
328 IPython.notebook.to_code();
329 return false;
330 }
331 },
332 'm' : {
333 help : 'to markdown',
334 help_index : 'cb',
335 handler : function (event) {
336 IPython.notebook.to_markdown();
337 return false;
338 }
339 },
340 't' : {
341 help : 'to raw',
342 help_index : 'cc',
343 handler : function (event) {
344 IPython.notebook.to_raw();
345 return false;
346 }
347 },
348 '1' : {
349 help : 'to heading 1',
350 help_index : 'cd',
351 handler : function (event) {
352 IPython.notebook.to_heading(undefined, 1);
353 return false;
354 }
355 },
356 '2' : {
357 help : 'to heading 2',
358 help_index : 'ce',
359 handler : function (event) {
360 IPython.notebook.to_heading(undefined, 2);
361 return false;
362 }
363 },
364 '3' : {
365 help : 'to heading 3',
366 help_index : 'cf',
367 handler : function (event) {
368 IPython.notebook.to_heading(undefined, 3);
369 return false;
370 }
371 },
372 '4' : {
373 help : 'to heading 4',
374 help_index : 'cg',
375 handler : function (event) {
376 IPython.notebook.to_heading(undefined, 4);
377 return false;
378 }
379 },
380 '5' : {
381 help : 'to heading 5',
382 help_index : 'ch',
383 handler : function (event) {
384 IPython.notebook.to_heading(undefined, 5);
385 return false;
386 }
387 },
388 '6' : {
389 help : 'to heading 6',
390 help_index : 'ci',
391 handler : function (event) {
392 IPython.notebook.to_heading(undefined, 6);
393 return false;
394 }
395 },
396 'o' : {
397 help : 'toggle output',
398 help_index : 'gb',
399 handler : function (event) {
400 IPython.notebook.toggle_output();
401 return false;
402 }
403 },
404 'shift+o' : {
405 help : 'toggle output',
406 help_index : 'gc',
407 handler : function (event) {
408 IPython.notebook.toggle_output_scroll();
409 return false;
410 }
411 },
412 's' : {
413 help : 'save notebook',
414 help_index : 'fa',
415 handler : function (event) {
416 IPython.notebook.save_checkpoint();
417 return false;
418 }
419 },
420 'ctrl+j' : {
421 help : 'move cell down',
422 help_index : 'eb',
423 handler : function (event) {
424 IPython.notebook.move_cell_down();
425 return false;
426 }
427 },
428 'ctrl+k' : {
429 help : 'move cell up',
430 help_index : 'ea',
431 handler : function (event) {
432 IPython.notebook.move_cell_up();
433 return false;
434 }
435 },
436 'l' : {
437 help : 'toggle line numbers',
438 help_index : 'ga',
439 handler : function (event) {
440 IPython.notebook.cell_toggle_line_numbers();
441 return false;
442 }
443 },
444 'i' : {
445 help : 'interrupt kernel',
446 help_index : 'ha',
447 handler : function (event) {
448 IPython.notebook.kernel.interrupt();
449 return false;
450 }
451 },
452 '.' : {
453 help : 'restart kernel',
454 help_index : 'hb',
455 handler : function (event) {
456 IPython.notebook.restart_kernel();
457 return false;
458 }
459 },
460 'h' : {
461 help : 'keyboard shortcuts',
462 help_index : 'gd',
463 handler : function (event) {
464 IPython.quick_help.show_keyboard_shortcuts();
465 return false;
466 }
467 },
468 'z' : {
469 help : 'undo last delete',
470 help_index : 'eh',
471 handler : function (event) {
472 IPython.notebook.undelete_cell();
473 return false;
474 }
475 },
476 'shift+=' : {
477 help : 'merge cell below',
478 help_index : 'ej',
479 handler : function (event) {
480 IPython.notebook.merge_cell_below();
481 return false;
482 }
483 },
484 }
485
486
487 // Shortcut manager class
488
489 var ShortcutManager = function () {
490 this._shortcuts = {}
491 }
492
493 ShortcutManager.prototype.help = function () {
494 var help = [];
495 for (var shortcut in this._shortcuts) {
496 var help_string = this._shortcuts[shortcut]['help'];
497 var help_index = this._shortcuts[shortcut]['help_index'];
498 if (help_string) {
499 help.push({
500 shortcut: shortcut,
501 help: help_string,
502 help_index: help_index}
503 );
504 }
505 }
506 help.sort(function (a, b) {
507 if (a.help_index > b.help_index)
508 return 1;
509 if (a.help_index < b.help_index)
510 return -1;
511 return 0;
512 });
513 return help;
514 }
515
516 ShortcutManager.prototype.normalize_key = function (key) {
517 return inv_keycodes[keycodes[key]];
518 }
519
520 ShortcutManager.prototype.normalize_shortcut = function (shortcut) {
521 // Sort a sequence of + separated modifiers into the order alt+ctrl+meta+shift
522 var values = shortcut.split("+");
523 if (values.length === 1) {
524 return this.normalize_key(values[0])
525 } else {
526 var modifiers = values.slice(0,-1);
527 var key = this.normalize_key(values[values.length-1]);
528 modifiers.sort();
529 return modifiers.join('+') + '+' + key;
530 }
531 }
532
533 ShortcutManager.prototype.event_to_shortcut = function (event) {
534 // Convert a jQuery keyboard event to a strong based keyboard shortcut
535 var shortcut = '';
536 var key = inv_keycodes[event.which]
537 if (event.altKey && key !== 'alt') {shortcut += 'alt+';}
538 if (event.ctrlKey && key !== 'ctrl') {shortcut += 'ctrl+';}
539 if (event.metaKey && key !== 'meta') {shortcut += 'meta+';}
540 if (event.shiftKey && key !== 'shift') {shortcut += 'shift+';}
541 shortcut += key;
542 return shortcut
543 }
544
545 ShortcutManager.prototype.clear_shortcuts = function () {
546 this._shortcuts = {};
547 }
548
549 ShortcutManager.prototype.add_shortcut = function (shortcut, data) {
550 if (typeof(data) === 'function') {
551 data = {help: '', help_index: '', handler: data}
552 }
553 data.help_index = data.help_index || '';
554 data.help = data.help || '';
555 if (data.help_index === '') {
556 data.help_index = 'zz';
557 }
558 shortcut = this.normalize_shortcut(shortcut);
559 this._shortcuts[shortcut] = data;
560 }
561
562 ShortcutManager.prototype.add_shortcuts = function (data) {
563 for (var shortcut in data) {
564 this.add_shortcut(shortcut, data[shortcut]);
565 }
566 }
567
568 ShortcutManager.prototype.remove_shortcut = function (shortcut) {
569 shortcut = this.normalize_shortcut(shortcut);
570 delete this._shortcuts[shortcut];
571 }
572
573 ShortcutManager.prototype.call_handler = function (event) {
574 var shortcut = this.event_to_shortcut(event);
575 var data = this._shortcuts[shortcut];
576 if (data !== undefined) {
577 var handler = data['handler'];
578 if (handler !== undefined) {
579 return handler(event);
580 }
581 }
582 return true;
583 }
584
585
586
587 // Main keyboard manager for the notebook
588
589 var KeyboardManager = function () {
590 this.mode = 'command';
591 this.enabled = true;
592 this._delete_count = 0;
593 this.bind_events();
594 this.command_shortcuts = new ShortcutManager();
595 this.command_shortcuts.add_shortcuts(default_common_shortcuts);
596 this.command_shortcuts.add_shortcuts(default_command_shortcuts);
597 this.edit_shortcuts = new ShortcutManager();
598 this.edit_shortcuts.add_shortcuts(default_common_shortcuts);
599 this.edit_shortcuts.add_shortcuts(default_edit_shortcuts);
600 };
601
602 KeyboardManager.prototype.bind_events = function () {
603 var that = this;
604 $(document).keydown(function (event) {
605 return that.handle_keydown(event);
606 });
607 };
608
609 KeyboardManager.prototype.handle_keydown = function (event) {
610 var notebook = IPython.notebook;
611
612 if (event.which === keycodes['esc']) {
613 // Intercept escape at highest level to avoid closing
614 // websocket connection with firefox
615 event.preventDefault();
616 }
617
618 if (!this.enabled) {
619 if (event.which === keycodes['esc']) {
620 // ESC
621 notebook.command_mode();
622 return false;
623 }
624 return true;
625 }
626
627 if (this.mode === 'edit') {
628 return this.edit_shortcuts.call_handler(event);
629 } else if (this.mode === 'command') {
630 return this.command_shortcuts.call_handler(event);
631 }
632 return true;
633 }
634
635 KeyboardManager.prototype.edit_mode = function () {
636 this.last_mode = this.mode;
637 this.mode = 'edit';
638 }
639
640 KeyboardManager.prototype.command_mode = function () {
641 this.last_mode = this.mode;
642 this.mode = 'command';
643 }
644
645 KeyboardManager.prototype.enable = function () {
646 this.enabled = true;
647 }
648
649 KeyboardManager.prototype.disable = function () {
650 this.enabled = false;
651 }
652
653 KeyboardManager.prototype.register_events = function (e) {
654 var that = this;
655 e.on('focusin', function () {
656 that.command_mode();
657 that.disable();
658 });
659 e.on('focusout', function () {
660 that.command_mode();
661 that.enable();
662 });
663 // There are times (raw_input) where we remove the element from the DOM before
664 // focusout is called. In this case we bind to the remove event of jQueryUI,
665 // which gets triggered upon removal.
666 e.on('remove', function () {
667 that.command_mode();
668 that.enable();
669 });
670 }
671
672
673 IPython.keycodes = keycodes;
674 IPython.inv_keycodes = inv_keycodes;
675 IPython.default_common_shortcuts = default_common_shortcuts;
676 IPython.default_edit_shortcuts = default_edit_shortcuts;
677 IPython.default_command_shortcuts = default_command_shortcuts;
678 IPython.ShortcutManager = ShortcutManager;
679 IPython.KeyboardManager = KeyboardManager;
680
681 return IPython;
682
683 }(IPython));
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
@@ -1,143 +1,147 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2013 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Utility for modal dialogs with bootstrap
10 10 //============================================================================
11 11
12 12 IPython.namespace('IPython.dialog');
13 13
14 14 IPython.dialog = (function (IPython) {
15 15 "use strict";
16 16
17 17 var modal = function (options) {
18 18 var dialog = $("<div/>").addClass("modal").attr("role", "dialog");
19 19 dialog.append(
20 20 $("<div/>")
21 21 .addClass("modal-header")
22 22 .append($("<button>")
23 23 .addClass("close")
24 24 .attr("data-dismiss", "modal")
25 25 .html("&times;")
26 26 ).append(
27 27 $("<h3/>").text(options.title || "")
28 28 )
29 29 ).append(
30 30 $("<div/>").addClass("modal-body").append(
31 31 options.body || $("<p/>")
32 32 )
33 33 );
34 34
35 35 var footer = $("<div/>").addClass("modal-footer");
36 36
37 37 for (var label in options.buttons) {
38 38 var btn_opts = options.buttons[label];
39 39 var button = $("<button/>")
40 40 .addClass("btn")
41 41 .attr("data-dismiss", "modal")
42 42 .text(label);
43 43 if (btn_opts.click) {
44 44 button.click($.proxy(btn_opts.click, dialog));
45 45 }
46 46 if (btn_opts.class) {
47 47 button.addClass(btn_opts.class);
48 48 }
49 49 footer.append(button);
50 50 }
51 51 dialog.append(footer);
52 52 // hook up on-open event
53 53 dialog.on("shown", function() {
54 54 setTimeout(function() {
55 55 footer.find("button").last().focus();
56 56 if (options.open) {
57 57 $.proxy(options.open, dialog)();
58 58 }
59 59 }, 0);
60 60 });
61 61
62 62 // destroy dialog on hide, unless explicitly asked not to
63 63 if (options.destroy === undefined || options.destroy) {
64 64 dialog.on("hidden", function () {
65 65 dialog.remove();
66 66 });
67 67 }
68 if (options.reselect_cell !== false) {
69 dialog.on("hidden", function () {
70 if (IPython.notebook) {
71 var cell = IPython.notebook.get_selected_cell();
72 if (cell) cell.select();
73 }
74 });
68 dialog.on("hidden", function () {
69 if (IPython.notebook) {
70 var cell = IPython.notebook.get_selected_cell();
71 if (cell) cell.select();
72 IPython.keyboard_manager.enable();
73 IPython.keyboard_manager.command_mode();
74 }
75 });
76
77 if (IPython.keyboard_manager) {
78 IPython.keyboard_manager.disable();
75 79 }
76 80
77 81 return dialog.modal(options);
78 82 };
79 83
80 84 var edit_metadata = function (md, callback, name) {
81 85 name = name || "Cell";
82 86 var error_div = $('<div/>').css('color', 'red');
83 87 var message =
84 88 "Manually edit the JSON below to manipulate the metadata for this " + name + "." +
85 89 " We recommend putting custom metadata attributes in an appropriately named sub-structure," +
86 90 " so they don't conflict with those of others.";
87 91
88 92 var textarea = $('<textarea/>')
89 93 .attr('rows', '13')
90 94 .attr('cols', '80')
91 95 .attr('name', 'metadata')
92 96 .text(JSON.stringify(md || {}, null, 2));
93 97
94 98 var dialogform = $('<div/>').attr('title', 'Edit the metadata')
95 99 .append(
96 100 $('<form/>').append(
97 101 $('<fieldset/>').append(
98 102 $('<label/>')
99 103 .attr('for','metadata')
100 104 .text(message)
101 105 )
102 106 .append(error_div)
103 107 .append($('<br/>'))
104 108 .append(textarea)
105 109 )
106 110 );
107 111 var editor = CodeMirror.fromTextArea(textarea[0], {
108 112 lineNumbers: true,
109 113 matchBrackets: true,
110 114 indentUnit: 2,
111 115 autoIndent: true,
112 116 mode: 'application/json',
113 117 });
114 118 IPython.dialog.modal({
115 119 title: "Edit " + name + " Metadata",
116 120 body: dialogform,
117 121 buttons: {
118 122 OK: { class : "btn-primary",
119 123 click: function() {
120 124 // validate json and set it
121 125 var new_md;
122 126 try {
123 127 new_md = JSON.parse(editor.getValue());
124 128 } catch(e) {
125 129 console.log(e);
126 130 error_div.text('WARNING: Could not save invalid JSON.');
127 131 return false;
128 132 }
129 133 callback(new_md);
130 134 }
131 135 },
132 136 Cancel: {}
133 137 }
134 138 });
135 139 editor.refresh();
136 140 };
137 141
138 142 return {
139 143 modal : modal,
140 144 edit_metadata : edit_metadata,
141 145 };
142 146
143 147 }(IPython));
@@ -1,482 +1,504 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2012 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Utilities
10 10 //============================================================================
11 11 IPython.namespace('IPython.utils');
12 12
13 13 IPython.utils = (function (IPython) {
14 14 "use strict";
15 15
16 16 //============================================================================
17 17 // Cross-browser RegEx Split
18 18 //============================================================================
19 19
20 20 // This code has been MODIFIED from the code licensed below to not replace the
21 21 // default browser split. The license is reproduced here.
22 22
23 23 // see http://blog.stevenlevithan.com/archives/cross-browser-split for more info:
24 24 /*!
25 25 * Cross-Browser Split 1.1.1
26 26 * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
27 27 * Available under the MIT License
28 28 * ECMAScript compliant, uniform cross-browser split method
29 29 */
30 30
31 31 /**
32 32 * Splits a string into an array of strings using a regex or string
33 33 * separator. Matches of the separator are not included in the result array.
34 34 * However, if `separator` is a regex that contains capturing groups,
35 35 * backreferences are spliced into the result each time `separator` is
36 36 * matched. Fixes browser bugs compared to the native
37 37 * `String.prototype.split` and can be used reliably cross-browser.
38 38 * @param {String} str String to split.
39 39 * @param {RegExp|String} separator Regex or string to use for separating
40 40 * the string.
41 41 * @param {Number} [limit] Maximum number of items to include in the result
42 42 * array.
43 43 * @returns {Array} Array of substrings.
44 44 * @example
45 45 *
46 46 * // Basic use
47 47 * regex_split('a b c d', ' ');
48 48 * // -> ['a', 'b', 'c', 'd']
49 49 *
50 50 * // With limit
51 51 * regex_split('a b c d', ' ', 2);
52 52 * // -> ['a', 'b']
53 53 *
54 54 * // Backreferences in result array
55 55 * regex_split('..word1 word2..', /([a-z]+)(\d+)/i);
56 56 * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
57 57 */
58 58 var regex_split = function (str, separator, limit) {
59 59 // If `separator` is not a regex, use `split`
60 60 if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
61 61 return split.call(str, separator, limit);
62 62 }
63 63 var output = [],
64 64 flags = (separator.ignoreCase ? "i" : "") +
65 65 (separator.multiline ? "m" : "") +
66 66 (separator.extended ? "x" : "") + // Proposed for ES6
67 67 (separator.sticky ? "y" : ""), // Firefox 3+
68 68 lastLastIndex = 0,
69 69 // Make `global` and avoid `lastIndex` issues by working with a copy
70 70 separator = new RegExp(separator.source, flags + "g"),
71 71 separator2, match, lastIndex, lastLength;
72 72 str += ""; // Type-convert
73 73
74 74 var compliantExecNpcg = typeof(/()??/.exec("")[1]) === "undefined";
75 75 if (!compliantExecNpcg) {
76 76 // Doesn't need flags gy, but they don't hurt
77 77 separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
78 78 }
79 79 /* Values for `limit`, per the spec:
80 80 * If undefined: 4294967295 // Math.pow(2, 32) - 1
81 81 * If 0, Infinity, or NaN: 0
82 82 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
83 83 * If negative number: 4294967296 - Math.floor(Math.abs(limit))
84 84 * If other: Type-convert, then use the above rules
85 85 */
86 86 limit = typeof(limit) === "undefined" ?
87 87 -1 >>> 0 : // Math.pow(2, 32) - 1
88 88 limit >>> 0; // ToUint32(limit)
89 89 while (match = separator.exec(str)) {
90 90 // `separator.lastIndex` is not reliable cross-browser
91 91 lastIndex = match.index + match[0].length;
92 92 if (lastIndex > lastLastIndex) {
93 93 output.push(str.slice(lastLastIndex, match.index));
94 94 // Fix browsers whose `exec` methods don't consistently return `undefined` for
95 95 // nonparticipating capturing groups
96 96 if (!compliantExecNpcg && match.length > 1) {
97 97 match[0].replace(separator2, function () {
98 98 for (var i = 1; i < arguments.length - 2; i++) {
99 99 if (typeof(arguments[i]) === "undefined") {
100 100 match[i] = undefined;
101 101 }
102 102 }
103 103 });
104 104 }
105 105 if (match.length > 1 && match.index < str.length) {
106 106 Array.prototype.push.apply(output, match.slice(1));
107 107 }
108 108 lastLength = match[0].length;
109 109 lastLastIndex = lastIndex;
110 110 if (output.length >= limit) {
111 111 break;
112 112 }
113 113 }
114 114 if (separator.lastIndex === match.index) {
115 115 separator.lastIndex++; // Avoid an infinite loop
116 116 }
117 117 }
118 118 if (lastLastIndex === str.length) {
119 119 if (lastLength || !separator.test("")) {
120 120 output.push("");
121 121 }
122 122 } else {
123 123 output.push(str.slice(lastLastIndex));
124 124 }
125 125 return output.length > limit ? output.slice(0, limit) : output;
126 126 };
127 127
128 128 //============================================================================
129 129 // End contributed Cross-browser RegEx Split
130 130 //============================================================================
131 131
132 132
133 133 var uuid = function () {
134 134 // http://www.ietf.org/rfc/rfc4122.txt
135 135 var s = [];
136 136 var hexDigits = "0123456789ABCDEF";
137 137 for (var i = 0; i < 32; i++) {
138 138 s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
139 139 }
140 140 s[12] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
141 141 s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
142 142
143 143 var uuid = s.join("");
144 144 return uuid;
145 145 };
146 146
147 147
148 148 //Fix raw text to parse correctly in crazy XML
149 149 function xmlencode(string) {
150 150 return string.replace(/\&/g,'&'+'amp;')
151 151 .replace(/</g,'&'+'lt;')
152 152 .replace(/>/g,'&'+'gt;')
153 153 .replace(/\'/g,'&'+'apos;')
154 154 .replace(/\"/g,'&'+'quot;')
155 155 .replace(/`/g,'&'+'#96;');
156 156 }
157 157
158 158
159 159 //Map from terminal commands to CSS classes
160 160 var ansi_colormap = {
161 161 "01":"ansibold",
162 162
163 163 "30":"ansiblack",
164 164 "31":"ansired",
165 165 "32":"ansigreen",
166 166 "33":"ansiyellow",
167 167 "34":"ansiblue",
168 168 "35":"ansipurple",
169 169 "36":"ansicyan",
170 170 "37":"ansigray",
171 171
172 172 "40":"ansibgblack",
173 173 "41":"ansibgred",
174 174 "42":"ansibggreen",
175 175 "43":"ansibgyellow",
176 176 "44":"ansibgblue",
177 177 "45":"ansibgpurple",
178 178 "46":"ansibgcyan",
179 179 "47":"ansibggray"
180 180 };
181 181
182 182 function _process_numbers(attrs, numbers) {
183 183 // process ansi escapes
184 184 var n = numbers.shift();
185 185 if (ansi_colormap[n]) {
186 186 if ( ! attrs["class"] ) {
187 187 attrs["class"] = ansi_colormap[n];
188 188 } else {
189 189 attrs["class"] += " " + ansi_colormap[n];
190 190 }
191 191 } else if (n == "38" || n == "48") {
192 192 // VT100 256 color or 24 bit RGB
193 193 if (numbers.length < 2) {
194 194 console.log("Not enough fields for VT100 color", numbers);
195 195 return;
196 196 }
197 197
198 198 var index_or_rgb = numbers.shift();
199 199 var r,g,b;
200 200 if (index_or_rgb == "5") {
201 201 // 256 color
202 202 var idx = parseInt(numbers.shift());
203 203 if (idx < 16) {
204 204 // indexed ANSI
205 205 // ignore bright / non-bright distinction
206 206 idx = idx % 8;
207 207 var ansiclass = ansi_colormap[n[0] + (idx % 8).toString()];
208 208 if ( ! attrs["class"] ) {
209 209 attrs["class"] = ansiclass;
210 210 } else {
211 211 attrs["class"] += " " + ansiclass;
212 212 }
213 213 return;
214 214 } else if (idx < 232) {
215 215 // 216 color 6x6x6 RGB
216 216 idx = idx - 16;
217 217 b = idx % 6;
218 218 g = Math.floor(idx / 6) % 6;
219 219 r = Math.floor(idx / 36) % 6;
220 220 // convert to rgb
221 221 r = (r * 51);
222 222 g = (g * 51);
223 223 b = (b * 51);
224 224 } else {
225 225 // grayscale
226 226 idx = idx - 231;
227 227 // it's 1-24 and should *not* include black or white,
228 228 // so a 26 point scale
229 229 r = g = b = Math.floor(idx * 256 / 26);
230 230 }
231 231 } else if (index_or_rgb == "2") {
232 232 // Simple 24 bit RGB
233 233 if (numbers.length > 3) {
234 234 console.log("Not enough fields for RGB", numbers);
235 235 return;
236 236 }
237 237 r = numbers.shift();
238 238 g = numbers.shift();
239 239 b = numbers.shift();
240 240 } else {
241 241 console.log("unrecognized control", numbers);
242 242 return;
243 243 }
244 244 if (r !== undefined) {
245 245 // apply the rgb color
246 246 var line;
247 247 if (n == "38") {
248 248 line = "color: ";
249 249 } else {
250 250 line = "background-color: ";
251 251 }
252 252 line = line + "rgb(" + r + "," + g + "," + b + ");"
253 253 if ( !attrs["style"] ) {
254 254 attrs["style"] = line;
255 255 } else {
256 256 attrs["style"] += " " + line;
257 257 }
258 258 }
259 259 }
260 260 }
261 261
262 262 function ansispan(str) {
263 263 // ansispan function adapted from github.com/mmalecki/ansispan (MIT License)
264 264 // regular ansi escapes (using the table above)
265 265 return str.replace(/\033\[(0?[01]|22|39)?([;\d]+)?m/g, function(match, prefix, pattern) {
266 266 if (!pattern) {
267 267 // [(01|22|39|)m close spans
268 268 return "</span>";
269 269 }
270 270 // consume sequence of color escapes
271 271 var numbers = pattern.match(/\d+/g);
272 272 var attrs = {};
273 273 while (numbers.length > 0) {
274 274 _process_numbers(attrs, numbers);
275 275 }
276 276
277 277 var span = "<span ";
278 278 for (var attr in attrs) {
279 279 var value = attrs[attr];
280 280 span = span + " " + attr + '="' + attrs[attr] + '"';
281 281 }
282 282 return span + ">";
283 283 });
284 284 };
285 285
286 286 // Transform ANSI color escape codes into HTML <span> tags with css
287 287 // classes listed in the above ansi_colormap object. The actual color used
288 288 // are set in the css file.
289 289 function fixConsole(txt) {
290 290 txt = xmlencode(txt);
291 291 var re = /\033\[([\dA-Fa-f;]*?)m/;
292 292 var opened = false;
293 293 var cmds = [];
294 294 var opener = "";
295 295 var closer = "";
296 296
297 297 // Strip all ANSI codes that are not color related. Matches
298 298 // all ANSI codes that do not end with "m".
299 299 var ignored_re = /(?=(\033\[[\d;=]*[a-ln-zA-Z]{1}))\1(?!m)/g;
300 300 txt = txt.replace(ignored_re, "");
301 301
302 302 // color ansi codes
303 303 txt = ansispan(txt);
304 304 return txt;
305 305 }
306 306
307 307 // Remove chunks that should be overridden by the effect of
308 308 // carriage return characters
309 309 function fixCarriageReturn(txt) {
310 310 var tmp = txt;
311 311 do {
312 312 txt = tmp;
313 313 tmp = txt.replace(/\r+\n/gm, '\n'); // \r followed by \n --> newline
314 314 tmp = tmp.replace(/^.*\r+/gm, ''); // Other \r --> clear line
315 315 } while (tmp.length < txt.length);
316 316 return txt;
317 317 }
318 318
319 319 // Locate any URLs and convert them to a anchor tag
320 320 function autoLinkUrls(txt) {
321 321 return txt.replace(/(^|\s)(https?|ftp)(:[^'">\s]+)/gi,
322 322 "$1<a target=\"_blank\" href=\"$2$3\">$2$3</a>");
323 323 }
324 324
325 325 // some keycodes that seem to be platform/browser independent
326 326 var keycodes = {
327 327 BACKSPACE: 8,
328 328 TAB : 9,
329 329 ENTER : 13,
330 330 SHIFT : 16,
331 331 CTRL : 17,
332 332 CONTROL : 17,
333 333 ALT : 18,
334 334 CAPS_LOCK: 20,
335 335 ESC : 27,
336 336 SPACE : 32,
337 337 PGUP : 33,
338 338 PGDOWN : 34,
339 339 END : 35,
340 340 HOME : 36,
341 341 LEFT_ARROW: 37,
342 342 LEFTARROW: 37,
343 343 LEFT : 37,
344 344 UP_ARROW : 38,
345 345 UPARROW : 38,
346 346 UP : 38,
347 347 RIGHT_ARROW:39,
348 348 RIGHTARROW:39,
349 349 RIGHT : 39,
350 350 DOWN_ARROW: 40,
351 351 DOWNARROW: 40,
352 352 DOWN : 40,
353 353 I : 73,
354 354 M : 77,
355 355 // all three of these keys may be COMMAND on OS X:
356 356 LEFT_SUPER : 91,
357 357 RIGHT_SUPER : 92,
358 358 COMMAND : 93,
359 359 };
360 360
361 361 // trigger a key press event
362 362 var press = function (key) {
363 363 var key_press = $.Event('keydown', {which: key});
364 364 $(document).trigger(key_press);
365 365 }
366 366
367 367 var press_up = function() { press(keycodes.UP); };
368 368 var press_down = function() { press(keycodes.DOWN); };
369 369
370 370 var press_ctrl_enter = function() {
371 371 $(document).trigger($.Event('keydown', {which: keycodes.ENTER, ctrlKey: true}));
372 372 };
373 373
374 374 var press_shift_enter = function() {
375 375 $(document).trigger($.Event('keydown', {which: keycodes.ENTER, shiftKey: true}));
376 376 };
377 377
378 378 // trigger the ctrl-m shortcut followed by one of our keys
379 379 var press_ghetto = function(key) {
380 380 $(document).trigger($.Event('keydown', {which: keycodes.M, ctrlKey: true}));
381 381 press(key);
382 382 };
383 383
384 384
385 385 var points_to_pixels = function (points) {
386 386 // A reasonably good way of converting between points and pixels.
387 387 var test = $('<div style="display: none; width: 10000pt; padding:0; border:0;"></div>');
388 388 $(body).append(test);
389 389 var pixel_per_point = test.width()/10000;
390 390 test.remove();
391 391 return Math.floor(points*pixel_per_point);
392 392 };
393 393
394 394 var always_new = function (constructor) {
395 395 // wrapper around contructor to avoid requiring `var a = new constructor()`
396 396 // useful for passing constructors as callbacks,
397 397 // not for programmer laziness.
398 398 // from http://programmers.stackexchange.com/questions/118798
399 399 return function () {
400 400 var obj = Object.create(constructor.prototype);
401 401 constructor.apply(obj, arguments);
402 402 return obj;
403 403 };
404 404 };
405 405
406 406
407 407 var url_path_join = function () {
408 408 // join a sequence of url components with '/'
409 409 var url = '';
410 410 for (var i = 0; i < arguments.length; i++) {
411 411 if (arguments[i] === '') {
412 412 continue;
413 413 }
414 414 if (url.length > 0 && url[url.length-1] != '/') {
415 415 url = url + '/' + arguments[i];
416 416 } else {
417 417 url = url + arguments[i];
418 418 }
419 419 }
420 420 return url;
421 421 };
422 422
423 423
424 424 var encode_uri_components = function (uri) {
425 425 // encode just the components of a multi-segment uri,
426 426 // leaving '/' separators
427 427 return uri.split('/').map(encodeURIComponent).join('/');
428 428 }
429 429
430 430 var url_join_encode = function () {
431 431 // join a sequence of url components with '/',
432 432 // encoding each component with encodeURIComponent
433 433 return encode_uri_components(url_path_join.apply(null, arguments));
434 434 };
435 435
436 436
437 437 var splitext = function (filename) {
438 438 // mimic Python os.path.splitext
439 439 // Returns ['base', '.ext']
440 440 var idx = filename.lastIndexOf('.');
441 441 if (idx > 0) {
442 442 return [filename.slice(0, idx), filename.slice(idx)];
443 443 } else {
444 444 return [filename, ''];
445 445 }
446 446 }
447 447
448 448
449 449 // http://stackoverflow.com/questions/2400935/browser-detection-in-javascript
450 450 var browser = (function() {
451 451 var N= navigator.appName, ua= navigator.userAgent, tem;
452 452 var M= ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
453 453 if (M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
454 454 M= M? [M[1], M[2]]: [N, navigator.appVersion,'-?'];
455 455 return M;
456 456 })();
457 457
458 var is_or_has = function (a, b) {
459 // Is b a child of a or a itself?
460 return a.has(b).length !==0 || a.is(b);
461 }
462
463 var is_focused = function (e) {
464 // Is element e, or one of its children focused?
465 e = $(e);
466 var target = $(document.activeElement);
467 if (target.length > 0) {
468 if (is_or_has(e, target)) {
469 return true;
470 } else {
471 return false;
472 }
473 } else {
474 return false;
475 }
476 }
477
458 478
459 479 return {
460 480 regex_split : regex_split,
461 481 uuid : uuid,
462 482 fixConsole : fixConsole,
463 483 keycodes : keycodes,
464 484 press : press,
465 485 press_up : press_up,
466 486 press_down : press_down,
467 487 press_ctrl_enter : press_ctrl_enter,
468 488 press_shift_enter : press_shift_enter,
469 489 press_ghetto : press_ghetto,
470 490 fixCarriageReturn : fixCarriageReturn,
471 491 autoLinkUrls : autoLinkUrls,
472 492 points_to_pixels : points_to_pixels,
473 493 url_path_join : url_path_join,
474 494 url_join_encode : url_join_encode,
475 495 encode_uri_components : encode_uri_components,
476 496 splitext : splitext,
477 497 always_new : always_new,
478 browser : browser
498 browser : browser,
499 is_or_has : is_or_has,
500 is_focused : is_focused
479 501 };
480 502
481 503 }(IPython));
482 504
@@ -1,372 +1,494 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Cell
10 10 //============================================================================
11 11 /**
12 12 * An extendable module that provide base functionnality to create cell for notebook.
13 13 * @module IPython
14 14 * @namespace IPython
15 15 * @submodule Cell
16 16 */
17 17
18 18 var IPython = (function (IPython) {
19 19 "use strict";
20 20
21 21 var utils = IPython.utils;
22 22
23 23 /**
24 24 * The Base `Cell` class from which to inherit
25 25 * @class Cell
26 26 **/
27 27
28 28 /*
29 29 * @constructor
30 30 *
31 31 * @param {object|undefined} [options]
32 32 * @param [options.cm_config] {object} config to pass to CodeMirror, will extend default parameters
33 33 */
34 34 var Cell = function (options) {
35 35
36 36 options = this.mergeopt(Cell, options);
37 37 // superclass default overwrite our default
38 38
39 39 this.placeholder = options.placeholder || '';
40 40 this.read_only = options.cm_config.readOnly;
41 41 this.selected = false;
42 this.rendered = false;
43 this.mode = 'command';
42 44 this.metadata = {};
43 45 // load this from metadata later ?
44 46 this.user_highlight = 'auto';
45 47 this.cm_config = options.cm_config;
46 48 this.cell_id = utils.uuid();
47 49 this._options = options;
48 50
49 51 // For JS VM engines optimisation, attributes should be all set (even
50 52 // to null) in the constructor, and if possible, if different subclass
51 53 // have new attributes with same name, they should be created in the
52 54 // same order. Easiest is to create and set to null in parent class.
53 55
54 56 this.element = null;
55 57 this.cell_type = this.cell_type || null;
56 58 this.code_mirror = null;
57 59
58 60
59 61 this.create_element();
60 62 if (this.element !== null) {
61 63 this.element.data("cell", this);
62 64 this.bind_events();
65 this.init_classes();
63 66 }
64 67 };
65 68
66 69 Cell.options_default = {
67 70 cm_config : {
68 71 indentUnit : 4,
69 72 readOnly: false,
70 73 theme: "default"
71 74 }
72 75 };
73 76
74 77 // FIXME: Workaround CM Bug #332 (Safari segfault on drag)
75 78 // by disabling drag/drop altogether on Safari
76 79 // https://github.com/marijnh/CodeMirror/issues/332
77 80
78 81 if (utils.browser[0] == "Safari") {
79 82 Cell.options_default.cm_config.dragDrop = false;
80 83 }
81 84
82 85 Cell.prototype.mergeopt = function(_class, options, overwrite){
83 86 options = options || {};
84 87 overwrite = overwrite || {};
85 88 return $.extend(true, {}, _class.options_default, options, overwrite)
86 89
87 90 }
88 91
89 92
90 93
91 94 /**
92 95 * Empty. Subclasses must implement create_element.
93 96 * This should contain all the code to create the DOM element in notebook
94 97 * and will be called by Base Class constructor.
95 98 * @method create_element
96 99 */
97 100 Cell.prototype.create_element = function () {
98 101 };
99 102
103 Cell.prototype.init_classes = function () {
104 // Call after this.element exists to initialize the css classes
105 // related to selected, rendered and mode.
106 if (this.selected) {
107 this.element.addClass('selected');
108 } else {
109 this.element.addClass('unselected');
110 }
111 if (this.rendered) {
112 this.element.addClass('rendered');
113 } else {
114 this.element.addClass('unrendered');
115 }
116 if (this.mode === 'edit') {
117 this.element.addClass('edit_mode');
118 } else {
119 this.element.addClass('command_mode');
120 }
121 }
122
100 123
101 124 /**
102 125 * Subclasses can implement override bind_events.
103 126 * Be carefull to call the parent method when overwriting as it fires event.
104 127 * this will be triggerd after create_element in constructor.
105 128 * @method bind_events
106 129 */
107 130 Cell.prototype.bind_events = function () {
108 131 var that = this;
109 132 // We trigger events so that Cell doesn't have to depend on Notebook.
110 133 that.element.click(function (event) {
111 if (that.selected === false) {
134 if (!that.selected) {
112 135 $([IPython.events]).trigger('select.Cell', {'cell':that});
113 }
136 };
114 137 });
115 138 that.element.focusin(function (event) {
116 if (that.selected === false) {
139 if (!that.selected) {
117 140 $([IPython.events]).trigger('select.Cell', {'cell':that});
118 }
141 };
119 142 });
120 143 if (this.code_mirror) {
121 144 this.code_mirror.on("change", function(cm, change) {
122 145 $([IPython.events]).trigger("set_dirty.Notebook", {value: true});
123 146 });
124 147 }
148 if (this.code_mirror) {
149 this.code_mirror.on('focus', function(cm, change) {
150 $([IPython.events]).trigger('edit_mode.Cell', {cell: that});
151 });
152 }
153 if (this.code_mirror) {
154 this.code_mirror.on('blur', function(cm, change) {
155 if (that.mode === 'edit') {
156 setTimeout(function () {
157 var isf = IPython.utils.is_focused;
158 var trigger = true;
159 if (isf('div#tooltip') || isf('div.completions')) {
160 trigger = false;
161 }
162 if (trigger) {
163 $([IPython.events]).trigger('command_mode.Cell', {cell: that});
164 }
165 }, 1);
166 }
167 });
168 }
125 169 };
126 170
127 171 /**
128 172 * Triger typsetting of math by mathjax on current cell element
129 173 * @method typeset
130 174 */
131 175 Cell.prototype.typeset = function () {
132 if (window.MathJax){
176 if (window.MathJax) {
133 177 var cell_math = this.element.get(0);
134 178 MathJax.Hub.Queue(["Typeset", MathJax.Hub, cell_math]);
135 179 }
136 180 };
137 181
138 182 /**
139 * should be triggerd when cell is selected
183 * handle cell level logic when a cell is selected
140 184 * @method select
185 * @return is the action being taken
141 186 */
142 187 Cell.prototype.select = function () {
143 this.element.addClass('selected');
144 this.selected = true;
188 if (!this.selected) {
189 this.element.addClass('selected');
190 this.element.removeClass('unselected');
191 this.selected = true;
192 return true;
193 } else {
194 return false;
195 }
145 196 };
146 197
147
148 198 /**
149 * should be triggerd when cell is unselected
199 * handle cell level logic when a cell is unselected
150 200 * @method unselect
201 * @return is the action being taken
151 202 */
152 203 Cell.prototype.unselect = function () {
153 this.element.removeClass('selected');
154 this.selected = false;
204 if (this.selected) {
205 this.element.addClass('unselected');
206 this.element.removeClass('selected');
207 this.selected = false;
208 return true;
209 } else {
210 return false;
211 }
155 212 };
156 213
157 214 /**
158 * should be overritten by subclass
159 * @method get_text
215 * handle cell level logic when a cell is rendered
216 * @method render
217 * @return is the action being taken
160 218 */
161 Cell.prototype.get_text = function () {
219 Cell.prototype.render = function () {
220 if (!this.rendered) {
221 this.element.addClass('rendered');
222 this.element.removeClass('unrendered');
223 this.rendered = true;
224 return true;
225 } else {
226 return false;
227 }
162 228 };
163 229
164 230 /**
165 * should be overritten by subclass
166 * @method set_text
167 * @param {string} text
231 * handle cell level logic when a cell is unrendered
232 * @method unrender
233 * @return is the action being taken
168 234 */
169 Cell.prototype.set_text = function (text) {
235 Cell.prototype.unrender = function () {
236 if (this.rendered) {
237 this.element.addClass('unrendered');
238 this.element.removeClass('rendered');
239 this.rendered = false;
240 return true;
241 } else {
242 return false;
243 }
244 };
245
246 /**
247 * enter the command mode for the cell
248 * @method command_mode
249 * @return is the action being taken
250 */
251 Cell.prototype.command_mode = function () {
252 if (this.mode !== 'command') {
253 this.element.addClass('command_mode');
254 this.element.removeClass('edit_mode');
255 this.mode = 'command';
256 return true;
257 } else {
258 return false;
259 }
170 260 };
171 261
172 262 /**
263 * enter the edit mode for the cell
264 * @method command_mode
265 * @return is the action being taken
266 */
267 Cell.prototype.edit_mode = function () {
268 if (this.mode !== 'edit') {
269 this.element.addClass('edit_mode');
270 this.element.removeClass('command_mode');
271 this.mode = 'edit';
272 return true;
273 } else {
274 return false;
275 }
276 }
277
278 /**
279 * Focus the cell in the DOM sense
280 * @method focus_cell
281 */
282 Cell.prototype.focus_cell = function () {
283 this.element.focus();
284 }
285
286 /**
287 * Focus the editor area so a user can type
288 * @method focus_editor
289 */
290 Cell.prototype.focus_editor = function () {
291 this.refresh();
292 this.code_mirror.focus();
293 }
294
295 /**
173 296 * Refresh codemirror instance
174 297 * @method refresh
175 298 */
176 299 Cell.prototype.refresh = function () {
177 300 this.code_mirror.refresh();
178 301 };
179 302
180
181 303 /**
182 304 * should be overritten by subclass
183 * @method edit
184 **/
185 Cell.prototype.edit = function () {
305 * @method get_text
306 */
307 Cell.prototype.get_text = function () {
186 308 };
187 309
188
189 310 /**
190 311 * should be overritten by subclass
191 * @method render
192 **/
193 Cell.prototype.render = function () {
312 * @method set_text
313 * @param {string} text
314 */
315 Cell.prototype.set_text = function (text) {
194 316 };
195 317
196 318 /**
197 319 * should be overritten by subclass
198 320 * serialise cell to json.
199 321 * @method toJSON
200 322 **/
201 323 Cell.prototype.toJSON = function () {
202 324 var data = {};
203 325 data.metadata = this.metadata;
204 326 data.cell_type = this.cell_type;
205 327 return data;
206 328 };
207 329
208 330
209 331 /**
210 332 * should be overritten by subclass
211 333 * @method fromJSON
212 334 **/
213 335 Cell.prototype.fromJSON = function (data) {
214 336 if (data.metadata !== undefined) {
215 337 this.metadata = data.metadata;
216 338 }
217 339 this.celltoolbar.rebuild();
218 340 };
219 341
220 342
221 343 /**
222 344 * can the cell be split into two cells
223 345 * @method is_splittable
224 346 **/
225 347 Cell.prototype.is_splittable = function () {
226 348 return true;
227 349 };
228 350
229 351
230 352 /**
231 353 * can the cell be merged with other cells
232 354 * @method is_mergeable
233 355 **/
234 356 Cell.prototype.is_mergeable = function () {
235 357 return true;
236 358 };
237 359
238 360
239 361 /**
240 362 * @return {String} - the text before the cursor
241 363 * @method get_pre_cursor
242 364 **/
243 365 Cell.prototype.get_pre_cursor = function () {
244 366 var cursor = this.code_mirror.getCursor();
245 367 var text = this.code_mirror.getRange({line:0, ch:0}, cursor);
246 368 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
247 369 return text;
248 370 }
249 371
250 372
251 373 /**
252 374 * @return {String} - the text after the cursor
253 375 * @method get_post_cursor
254 376 **/
255 377 Cell.prototype.get_post_cursor = function () {
256 378 var cursor = this.code_mirror.getCursor();
257 379 var last_line_num = this.code_mirror.lineCount()-1;
258 380 var last_line_len = this.code_mirror.getLine(last_line_num).length;
259 381 var end = {line:last_line_num, ch:last_line_len}
260 382 var text = this.code_mirror.getRange(cursor, end);
261 383 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
262 384 return text;
263 385 };
264 386
265 387 /**
266 388 * Show/Hide CodeMirror LineNumber
267 389 * @method show_line_numbers
268 390 *
269 391 * @param value {Bool} show (true), or hide (false) the line number in CodeMirror
270 392 **/
271 393 Cell.prototype.show_line_numbers = function (value) {
272 394 this.code_mirror.setOption('lineNumbers', value);
273 395 this.code_mirror.refresh();
274 396 };
275 397
276 398 /**
277 399 * Toggle CodeMirror LineNumber
278 400 * @method toggle_line_numbers
279 401 **/
280 402 Cell.prototype.toggle_line_numbers = function () {
281 403 var val = this.code_mirror.getOption('lineNumbers');
282 404 this.show_line_numbers(!val);
283 405 };
284 406
285 407 /**
286 408 * Force codemirror highlight mode
287 409 * @method force_highlight
288 410 * @param {object} - CodeMirror mode
289 411 **/
290 412 Cell.prototype.force_highlight = function(mode) {
291 413 this.user_highlight = mode;
292 414 this.auto_highlight();
293 415 };
294 416
295 417 /**
296 418 * Try to autodetect cell highlight mode, or use selected mode
297 419 * @methods _auto_highlight
298 420 * @private
299 421 * @param {String|object|undefined} - CodeMirror mode | 'auto'
300 422 **/
301 423 Cell.prototype._auto_highlight = function (modes) {
302 424 //Here we handle manually selected modes
303 425 if( this.user_highlight != undefined && this.user_highlight != 'auto' )
304 426 {
305 427 var mode = this.user_highlight;
306 428 CodeMirror.autoLoadMode(this.code_mirror, mode);
307 429 this.code_mirror.setOption('mode', mode);
308 430 return;
309 431 }
310 432 var current_mode = this.code_mirror.getOption('mode', mode);
311 433 var first_line = this.code_mirror.getLine(0);
312 434 // loop on every pairs
313 435 for( var mode in modes) {
314 436 var regs = modes[mode]['reg'];
315 437 // only one key every time but regexp can't be keys...
316 438 for(var reg in regs ) {
317 439 // here we handle non magic_modes
318 440 if(first_line.match(regs[reg]) != null) {
319 441 if(current_mode == mode){
320 442 return;
321 443 }
322 444 if (mode.search('magic_') != 0) {
323 445 this.code_mirror.setOption('mode', mode);
324 446 CodeMirror.autoLoadMode(this.code_mirror, mode);
325 447 return;
326 448 }
327 449 var open = modes[mode]['open']|| "%%";
328 450 var close = modes[mode]['close']|| "%%end";
329 451 var mmode = mode;
330 452 mode = mmode.substr(6);
331 453 if(current_mode == mode){
332 454 return;
333 455 }
334 456 CodeMirror.autoLoadMode(this.code_mirror, mode);
335 457 // create on the fly a mode that swhitch between
336 458 // plain/text and smth else otherwise `%%` is
337 459 // source of some highlight issues.
338 460 // we use patchedGetMode to circumvent a bug in CM
339 461 CodeMirror.defineMode(mmode , function(config) {
340 462 return CodeMirror.multiplexingMode(
341 463 CodeMirror.patchedGetMode(config, 'text/plain'),
342 464 // always set someting on close
343 465 {open: open, close: close,
344 466 mode: CodeMirror.patchedGetMode(config, mode),
345 467 delimStyle: "delimit"
346 468 }
347 469 );
348 470 });
349 471 this.code_mirror.setOption('mode', mmode);
350 472 return;
351 473 }
352 474 }
353 475 }
354 476 // fallback on default
355 477 var default_mode
356 478 try {
357 479 default_mode = this._options.cm_config.mode;
358 480 } catch(e) {
359 481 default_mode = 'text/plain';
360 482 }
361 483 if( current_mode === default_mode){
362 484 return
363 485 }
364 486 this.code_mirror.setOption('mode', default_mode);
365 487 };
366 488
367 489 IPython.Cell = Cell;
368 490
369 491 return IPython;
370 492
371 493 }(IPython));
372 494
@@ -1,463 +1,525 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // CodeCell
10 10 //============================================================================
11 11 /**
12 12 * An extendable module that provide base functionnality to create cell for notebook.
13 13 * @module IPython
14 14 * @namespace IPython
15 15 * @submodule CodeCell
16 16 */
17 17
18 18
19 19 /* local util for codemirror */
20 20 var posEq = function(a, b) {return a.line == b.line && a.ch == b.ch;};
21 21
22 22 /**
23 23 *
24 24 * function to delete until previous non blanking space character
25 25 * or first multiple of 4 tabstop.
26 26 * @private
27 27 */
28 28 CodeMirror.commands.delSpaceToPrevTabStop = function(cm){
29 29 var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
30 30 if (!posEq(from, to)) { cm.replaceRange("", from, to); return; }
31 31 var cur = cm.getCursor(), line = cm.getLine(cur.line);
32 32 var tabsize = cm.getOption('tabSize');
33 33 var chToPrevTabStop = cur.ch-(Math.ceil(cur.ch/tabsize)-1)*tabsize;
34 34 from = {ch:cur.ch-chToPrevTabStop,line:cur.line};
35 35 var select = cm.getRange(from,cur);
36 36 if( select.match(/^\ +$/) !== null){
37 37 cm.replaceRange("",from,cur);
38 38 } else {
39 39 cm.deleteH(-1,"char");
40 40 }
41 41 };
42 42
43 43
44 44 var IPython = (function (IPython) {
45 45 "use strict";
46 46
47 47 var utils = IPython.utils;
48 48 var key = IPython.utils.keycodes;
49 49
50 50 /**
51 51 * A Cell conceived to write code.
52 52 *
53 53 * The kernel doesn't have to be set at creation time, in that case
54 54 * it will be null and set_kernel has to be called later.
55 55 * @class CodeCell
56 56 * @extends IPython.Cell
57 57 *
58 58 * @constructor
59 59 * @param {Object|null} kernel
60 60 * @param {object|undefined} [options]
61 61 * @param [options.cm_config] {object} config to pass to CodeMirror
62 62 */
63 63 var CodeCell = function (kernel, options) {
64 64 this.kernel = kernel || null;
65 65 this.collapsed = false;
66 66
67 67 // create all attributed in constructor function
68 68 // even if null for V8 VM optimisation
69 69 this.input_prompt_number = null;
70 70 this.celltoolbar = null;
71 71 this.output_area = null;
72 72 this.last_msg_id = null;
73 73 this.completer = null;
74 74
75 75
76 76 var cm_overwrite_options = {
77 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
77 onKeyEvent: $.proxy(this.handle_keyevent,this)
78 78 };
79 79
80 80 options = this.mergeopt(CodeCell, options, {cm_config:cm_overwrite_options});
81 81
82 82 IPython.Cell.apply(this,[options]);
83 83
84 84 // Attributes we want to override in this subclass.
85 85 this.cell_type = "code";
86 86
87 87 var that = this;
88 88 this.element.focusout(
89 89 function() { that.auto_highlight(); }
90 90 );
91 91 };
92 92
93 93 CodeCell.options_default = {
94 94 cm_config : {
95 95 extraKeys: {
96 96 "Tab" : "indentMore",
97 97 "Shift-Tab" : "indentLess",
98 98 "Backspace" : "delSpaceToPrevTabStop",
99 99 "Cmd-/" : "toggleComment",
100 100 "Ctrl-/" : "toggleComment"
101 101 },
102 102 mode: 'ipython',
103 103 theme: 'ipython',
104 104 matchBrackets: true
105 105 }
106 106 };
107 107
108 108
109 109 CodeCell.prototype = new IPython.Cell();
110 110
111 111 /**
112 112 * @method auto_highlight
113 113 */
114 114 CodeCell.prototype.auto_highlight = function () {
115 115 this._auto_highlight(IPython.config.cell_magic_highlight);
116 116 };
117 117
118 118 /** @method create_element */
119 119 CodeCell.prototype.create_element = function () {
120 120 IPython.Cell.prototype.create_element.apply(this, arguments);
121 121
122 122 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell');
123 123 cell.attr('tabindex','2');
124 124
125 125 var input = $('<div></div>').addClass('input');
126 126 var prompt = $('<div/>').addClass('prompt input_prompt');
127 127 var inner_cell = $('<div/>').addClass('inner_cell');
128 128 this.celltoolbar = new IPython.CellToolbar(this);
129 129 inner_cell.append(this.celltoolbar.element);
130 130 var input_area = $('<div/>').addClass('input_area');
131 131 this.code_mirror = CodeMirror(input_area.get(0), this.cm_config);
132 132 $(this.code_mirror.getInputField()).attr("spellcheck", "false");
133 133 inner_cell.append(input_area);
134 134 input.append(prompt).append(inner_cell);
135 135 var output = $('<div></div>');
136 136 cell.append(input).append(output);
137 137 this.element = cell;
138 138 this.output_area = new IPython.OutputArea(output, true);
139 139 this.completer = new IPython.Completer(this);
140 140 };
141 141
142 /** @method bind_events */
143 CodeCell.prototype.bind_events = function () {
144 IPython.Cell.prototype.bind_events.apply(this);
145 var that = this;
146
147 this.element.focusout(
148 function() { that.auto_highlight(); }
149 );
150 };
151
152 CodeCell.prototype.handle_keyevent = function (editor, event) {
153
154 // console.log('CM', this.mode, event.which, event.type)
155
156 if (this.mode === 'command') {
157 return true;
158 } else if (this.mode === 'edit') {
159 return this.handle_codemirror_keyevent(editor, event);
160 }
161 };
162
142 163 /**
143 164 * This method gets called in CodeMirror's onKeyDown/onKeyPress
144 165 * handlers and is used to provide custom key handling. Its return
145 166 * value is used to determine if CodeMirror should ignore the event:
146 167 * true = ignore, false = don't ignore.
147 168 * @method handle_codemirror_keyevent
148 169 */
149 170 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
150 171
151 172 var that = this;
152 173 // whatever key is pressed, first, cancel the tooltip request before
153 174 // they are sent, and remove tooltip if any, except for tab again
175 var tooltip_closed = null;
154 176 if (event.type === 'keydown' && event.which != key.TAB ) {
155 IPython.tooltip.remove_and_cancel_tooltip();
177 tooltip_closed = IPython.tooltip.remove_and_cancel_tooltip();
156 178 }
157 179
158 180 var cur = editor.getCursor();
159 181 if (event.keyCode === key.ENTER){
160 182 this.auto_highlight();
161 183 }
162 184
163 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
185 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey || event.altKey)) {
164 186 // Always ignore shift-enter in CodeMirror as we handle it.
165 187 return true;
166 188 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
167 189 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
168 190 // browser and keyboard layout !
169 191 // Pressing '(' , request tooltip, don't forget to reappend it
170 192 // The second argument says to hide the tooltip if the docstring
171 193 // is actually empty
172 194 IPython.tooltip.pending(that, true);
173 195 } else if (event.which === key.UPARROW && event.type === 'keydown') {
174 196 // If we are not at the top, let CM handle the up arrow and
175 197 // prevent the global keydown handler from handling it.
176 198 if (!that.at_top()) {
177 199 event.stop();
178 200 return false;
179 201 } else {
180 202 return true;
181 203 }
182 } else if (event.which === key.ESC) {
183 return IPython.tooltip.remove_and_cancel_tooltip(true);
204 } else if (event.which === key.ESC && event.type === 'keydown') {
205 // First see if the tooltip is active and if so cancel it.
206 if (tooltip_closed) {
207 // The call to remove_and_cancel_tooltip above in L177 doesn't pass
208 // force=true. Because of this it won't actually close the tooltip
209 // if it is in sticky mode. Thus, we have to check again if it is open
210 // and close it with force=true.
211 if (!IPython.tooltip._hidden) {
212 IPython.tooltip.remove_and_cancel_tooltip(true);
213 }
214 // If we closed the tooltip, don't let CM or the global handlers
215 // handle this event.
216 event.stop();
217 return true;
218 }
219 if (that.code_mirror.options.keyMap === "vim-insert") {
220 // vim keyMap is active and in insert mode. In this case we leave vim
221 // insert mode, but remain in notebook edit mode.
222 // Let' CM handle this event and prevent global handling.
223 event.stop();
224 return false;
225 } else {
226 // vim keyMap is not active. Leave notebook edit mode.
227 // Don't let CM handle the event, defer to global handling.
228 return true;
229 }
184 230 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
185 231 // If we are not at the bottom, let CM handle the down arrow and
186 232 // prevent the global keydown handler from handling it.
187 233 if (!that.at_bottom()) {
188 234 event.stop();
189 235 return false;
190 236 } else {
191 237 return true;
192 238 }
193 } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) {
239 } else if (event.keyCode === key.TAB && event.type === 'keydown' && event.shiftKey) {
194 240 if (editor.somethingSelected()){
195 241 var anchor = editor.getCursor("anchor");
196 242 var head = editor.getCursor("head");
197 243 if( anchor.line != head.line){
198 244 return false;
199 245 }
200 246 }
201 247 IPython.tooltip.request(that);
202 248 event.stop();
203 249 return true;
204 250 } else if (event.keyCode === key.TAB && event.type == 'keydown') {
205 251 // Tab completion.
206 252 IPython.tooltip.remove_and_cancel_tooltip();
207 253 if (editor.somethingSelected()) {
208 254 return false;
209 255 }
210 256 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur);
211 257 if (pre_cursor.trim() === "") {
212 258 // Don't autocomplete if the part of the line before the cursor
213 259 // is empty. In this case, let CodeMirror handle indentation.
214 260 return false;
215 261 } else {
216 262 event.stop();
217 263 this.completer.startCompletion();
218 264 return true;
219 265 }
220 266 } else {
221 267 // keypress/keyup also trigger on TAB press, and we don't want to
222 268 // use those to disable tab completion.
223 269 return false;
224 270 }
225 271 return false;
226 272 };
227 273
228
229 274 // Kernel related calls.
230 275
231 276 CodeCell.prototype.set_kernel = function (kernel) {
232 277 this.kernel = kernel;
233 278 };
234 279
235 280 /**
236 281 * Execute current code cell to the kernel
237 282 * @method execute
238 283 */
239 284 CodeCell.prototype.execute = function () {
240 285 this.output_area.clear_output();
241 286 this.set_input_prompt('*');
242 287 this.element.addClass("running");
243 288 if (this.last_msg_id) {
244 289 this.kernel.clear_callbacks_for_msg(this.last_msg_id);
245 290 }
246 291 var callbacks = this.get_callbacks();
247 292
248 293 this.last_msg_id = this.kernel.execute(this.get_text(), callbacks, {silent: false, store_history: true});
249 294 };
250 295
251 296 /**
252 297 * Construct the default callbacks for
253 298 * @method get_callbacks
254 299 */
255 300 CodeCell.prototype.get_callbacks = function () {
256 301 return {
257 302 shell : {
258 303 reply : $.proxy(this._handle_execute_reply, this),
259 304 payload : {
260 305 set_next_input : $.proxy(this._handle_set_next_input, this),
261 306 page : $.proxy(this._open_with_pager, this)
262 307 }
263 308 },
264 309 iopub : {
265 310 output : $.proxy(this.output_area.handle_output, this.output_area),
266 311 clear_output : $.proxy(this.output_area.handle_clear_output, this.output_area),
267 312 },
268 313 input : $.proxy(this._handle_input_request, this)
269 314 };
270 315 };
271 316
272 317 CodeCell.prototype._open_with_pager = function (payload) {
273 318 $([IPython.events]).trigger('open_with_text.Pager', payload);
274 319 };
275 320
276 321 /**
277 322 * @method _handle_execute_reply
278 323 * @private
279 324 */
280 325 CodeCell.prototype._handle_execute_reply = function (msg) {
281 326 this.set_input_prompt(msg.content.execution_count);
282 327 this.element.removeClass("running");
283 328 $([IPython.events]).trigger('set_dirty.Notebook', {value: true});
284 329 };
285 330
286 331 /**
287 332 * @method _handle_set_next_input
288 333 * @private
289 334 */
290 335 CodeCell.prototype._handle_set_next_input = function (payload) {
291 336 var data = {'cell': this, 'text': payload.text};
292 337 $([IPython.events]).trigger('set_next_input.Notebook', data);
293 338 };
294 339
295 340 /**
296 341 * @method _handle_input_request
297 342 * @private
298 343 */
299 344 CodeCell.prototype._handle_input_request = function (msg) {
300 345 this.output_area.append_raw_input(msg);
301 346 };
302 347
303 348
304 349 // Basic cell manipulation.
305 350
306 351 CodeCell.prototype.select = function () {
307 IPython.Cell.prototype.select.apply(this);
308 this.code_mirror.refresh();
309 this.code_mirror.focus();
310 this.auto_highlight();
311 // We used to need an additional refresh() after the focus, but
312 // it appears that this has been fixed in CM. This bug would show
313 // up on FF when a newly loaded markdown cell was edited.
352 var cont = IPython.Cell.prototype.select.apply(this);
353 if (cont) {
354 this.code_mirror.refresh();
355 this.auto_highlight();
356 }
357 return cont;
358 };
359
360 CodeCell.prototype.render = function () {
361 var cont = IPython.Cell.prototype.render.apply(this);
362 // Always execute, even if we are already in the rendered state
363 return cont;
364 };
365
366 CodeCell.prototype.unrender = function () {
367 // CodeCell is always rendered
368 return false;
314 369 };
315 370
371 CodeCell.prototype.edit_mode = function () {
372 var cont = IPython.Cell.prototype.edit_mode.apply(this);
373 if (cont) {
374 this.focus_editor();
375 }
376 return cont;
377 }
316 378
317 379 CodeCell.prototype.select_all = function () {
318 380 var start = {line: 0, ch: 0};
319 381 var nlines = this.code_mirror.lineCount();
320 382 var last_line = this.code_mirror.getLine(nlines-1);
321 383 var end = {line: nlines-1, ch: last_line.length};
322 384 this.code_mirror.setSelection(start, end);
323 385 };
324 386
325 387
326 388 CodeCell.prototype.collapse = function () {
327 389 this.collapsed = true;
328 390 this.output_area.collapse();
329 391 };
330 392
331 393
332 394 CodeCell.prototype.expand = function () {
333 395 this.collapsed = false;
334 396 this.output_area.expand();
335 397 };
336 398
337 399
338 400 CodeCell.prototype.toggle_output = function () {
339 401 this.collapsed = Boolean(1 - this.collapsed);
340 402 this.output_area.toggle_output();
341 403 };
342 404
343 405
344 406 CodeCell.prototype.toggle_output_scroll = function () {
345 407 this.output_area.toggle_scroll();
346 408 };
347 409
348 410
349 411 CodeCell.input_prompt_classical = function (prompt_value, lines_number) {
350 412 var ns = prompt_value || "&nbsp;";
351 413 return 'In&nbsp;[' + ns + ']:';
352 414 };
353 415
354 416 CodeCell.input_prompt_continuation = function (prompt_value, lines_number) {
355 417 var html = [CodeCell.input_prompt_classical(prompt_value, lines_number)];
356 418 for(var i=1; i < lines_number; i++) {
357 419 html.push(['...:']);
358 420 }
359 421 return html.join('<br/>');
360 422 };
361 423
362 424 CodeCell.input_prompt_function = CodeCell.input_prompt_classical;
363 425
364 426
365 427 CodeCell.prototype.set_input_prompt = function (number) {
366 428 var nline = 1;
367 429 if (this.code_mirror !== undefined) {
368 430 nline = this.code_mirror.lineCount();
369 431 }
370 432 this.input_prompt_number = number;
371 433 var prompt_html = CodeCell.input_prompt_function(this.input_prompt_number, nline);
372 434 this.element.find('div.input_prompt').html(prompt_html);
373 435 };
374 436
375 437
376 438 CodeCell.prototype.clear_input = function () {
377 439 this.code_mirror.setValue('');
378 440 };
379 441
380 442
381 443 CodeCell.prototype.get_text = function () {
382 444 return this.code_mirror.getValue();
383 445 };
384 446
385 447
386 448 CodeCell.prototype.set_text = function (code) {
387 449 return this.code_mirror.setValue(code);
388 450 };
389 451
390 452
391 453 CodeCell.prototype.at_top = function () {
392 454 var cursor = this.code_mirror.getCursor();
393 455 if (cursor.line === 0 && cursor.ch === 0) {
394 456 return true;
395 457 } else {
396 458 return false;
397 459 }
398 460 };
399 461
400 462
401 463 CodeCell.prototype.at_bottom = function () {
402 464 var cursor = this.code_mirror.getCursor();
403 465 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
404 466 return true;
405 467 } else {
406 468 return false;
407 469 }
408 470 };
409 471
410 472
411 473 CodeCell.prototype.clear_output = function (wait) {
412 474 this.output_area.clear_output(wait);
413 475 };
414 476
415 477
416 478 // JSON serialization
417 479
418 480 CodeCell.prototype.fromJSON = function (data) {
419 481 IPython.Cell.prototype.fromJSON.apply(this, arguments);
420 482 if (data.cell_type === 'code') {
421 483 if (data.input !== undefined) {
422 484 this.set_text(data.input);
423 485 // make this value the starting point, so that we can only undo
424 486 // to this state, instead of a blank cell
425 487 this.code_mirror.clearHistory();
426 488 this.auto_highlight();
427 489 }
428 490 if (data.prompt_number !== undefined) {
429 491 this.set_input_prompt(data.prompt_number);
430 492 } else {
431 493 this.set_input_prompt();
432 494 }
433 495 this.output_area.fromJSON(data.outputs);
434 496 if (data.collapsed !== undefined) {
435 497 if (data.collapsed) {
436 498 this.collapse();
437 499 } else {
438 500 this.expand();
439 501 }
440 502 }
441 503 }
442 504 };
443 505
444 506
445 507 CodeCell.prototype.toJSON = function () {
446 508 var data = IPython.Cell.prototype.toJSON.apply(this);
447 509 data.input = this.get_text();
448 510 // is finite protect against undefined and '*' value
449 511 if (isFinite(this.input_prompt_number)) {
450 512 data.prompt_number = this.input_prompt_number;
451 513 }
452 514 var outputs = this.output_area.toJSON();
453 515 data.outputs = outputs;
454 516 data.language = 'python';
455 517 data.collapsed = this.collapsed;
456 518 return data;
457 519 };
458 520
459 521
460 522 IPython.CodeCell = CodeCell;
461 523
462 524 return IPython;
463 525 }(IPython));
@@ -1,353 +1,357 b''
1 1 // function completer.
2 2 //
3 3 // completer should be a class that takes an cell instance
4 4 var IPython = (function (IPython) {
5 5 // that will prevent us from misspelling
6 6 "use strict";
7 7
8 8 // easier key mapping
9 9 var key = IPython.utils.keycodes;
10 10
11 11 function prepend_n_prc(str, n) {
12 12 for( var i =0 ; i< n ; i++){
13 13 str = '%'+str ;
14 14 }
15 15 return str;
16 16 }
17 17
18 18 function _existing_completion(item, completion_array){
19 19 for( var c in completion_array ) {
20 20 if(completion_array[c].trim().substr(-item.length) == item)
21 21 { return true; }
22 22 }
23 23 return false;
24 24 }
25 25
26 26 // what is the common start of all completions
27 27 function shared_start(B, drop_prct) {
28 28 if (B.length == 1) {
29 29 return B[0];
30 30 }
31 31 var A = new Array();
32 32 var common;
33 33 var min_lead_prct = 10;
34 34 for (var i = 0; i < B.length; i++) {
35 35 var str = B[i].str;
36 36 var localmin = 0;
37 37 if(drop_prct === true){
38 38 while ( str.substr(0, 1) == '%') {
39 39 localmin = localmin+1;
40 40 str = str.substring(1);
41 41 }
42 42 }
43 43 min_lead_prct = Math.min(min_lead_prct, localmin);
44 44 A.push(str);
45 45 }
46 46
47 47 if (A.length > 1) {
48 48 var tem1, tem2, s;
49 49 A = A.slice(0).sort();
50 50 tem1 = A[0];
51 51 s = tem1.length;
52 52 tem2 = A.pop();
53 53 while (s && tem2.indexOf(tem1) == -1) {
54 54 tem1 = tem1.substring(0, --s);
55 55 }
56 56 if (tem1 === "" || tem2.indexOf(tem1) !== 0) {
57 57 return {
58 58 str:prepend_n_prc('', min_lead_prct),
59 59 type: "computed",
60 60 from: B[0].from,
61 61 to: B[0].to
62 62 };
63 63 }
64 64 return {
65 65 str: prepend_n_prc(tem1, min_lead_prct),
66 66 type: "computed",
67 67 from: B[0].from,
68 68 to: B[0].to
69 69 };
70 70 }
71 71 return null;
72 72 }
73 73
74 74
75 75 var Completer = function (cell) {
76 76 this.cell = cell;
77 77 this.editor = cell.code_mirror;
78 78 var that = this;
79 79 $([IPython.events]).on('status_busy.Kernel', function () {
80 80 that.skip_kernel_completion = true;
81 81 });
82 82 $([IPython.events]).on('status_idle.Kernel', function () {
83 83 that.skip_kernel_completion = false;
84 84 });
85 85 };
86 86
87 87
88 88 Completer.prototype.startCompletion = function () {
89 89 // call for a 'first' completion, that will set the editor and do some
90 90 // special behaviour like autopicking if only one completion availlable
91 91 //
92 92 if (this.editor.somethingSelected()) return;
93 93 this.done = false;
94 94 // use to get focus back on opera
95 95 this.carry_on_completion(true);
96 96 };
97 97
98 98
99 99 // easy access for julia to monkeypatch
100 100 //
101 101 Completer.reinvoke_re = /[%0-9a-z._/\\:~-]/i;
102 102
103 103 Completer.prototype.reinvoke= function(pre_cursor, block, cursor){
104 104 return Completer.reinvoke_re.test(pre_cursor);
105 105 }
106 106
107 107 /**
108 108 *
109 109 * pass true as parameter if this is the first invocation of the completer
110 110 * this will prevent the completer to dissmiss itself if it is not on a
111 111 * word boundary like pressing tab after a space, and make it autopick the
112 112 * only choice if there is only one which prevent from popping the UI. as
113 113 * well as fast-forwarding the typing if all completion have a common
114 114 * shared start
115 115 **/
116 116 Completer.prototype.carry_on_completion = function (first_invocation) {
117 117 // Pass true as parameter if you want the completer to autopick when
118 118 // only one completion. This function is automatically reinvoked at
119 119 // each keystroke with first_invocation = false
120 120 var cur = this.editor.getCursor();
121 121 var line = this.editor.getLine(cur.line);
122 122 var pre_cursor = this.editor.getRange({
123 123 line: cur.line,
124 124 ch: cur.ch - 1
125 125 }, cur);
126 126
127 127 // we need to check that we are still on a word boundary
128 128 // because while typing the completer is still reinvoking itself
129 129 // so dismiss if we are on a "bad" caracter
130 130 if (!this.reinvoke(pre_cursor) && !first_invocation) {
131 131 this.close();
132 132 return;
133 133 }
134 134
135 135 this.autopick = false;
136 136 if (first_invocation) {
137 137 this.autopick = true;
138 138 }
139 139
140 140 // We want a single cursor position.
141 141 if (this.editor.somethingSelected()) {
142 142 return;
143 143 };
144 144
145 145 // one kernel completion came back, finish_completing will be called with the results
146 146 // we fork here and directly call finish completing if kernel is busy
147 147 if (this.skip_kernel_completion == true) {
148 148 this.finish_completing({
149 149 'matches': [],
150 150 matched_text: ""
151 151 })
152 152 } else {
153 153 this.cell.kernel.complete(line, cur.ch, $.proxy(this.finish_completing, this));
154 154 }
155 155 };
156 156
157 157 Completer.prototype.finish_completing = function (msg) {
158 158 // let's build a function that wrap all that stuff into what is needed
159 159 // for the new completer:
160 160 var content = msg.content;
161 161 var matched_text = content.matched_text;
162 162 var matches = content.matches;
163 163
164 164 var cur = this.editor.getCursor();
165 165 var results = CodeMirror.contextHint(this.editor);
166 166 var filterd_results = Array();
167 167 //remove results from context completion
168 168 //that are already in kernel completion
169 169 for(var elm in results) {
170 170 if(_existing_completion(results[elm]['str'], matches) == false)
171 171 { filterd_results.push(results[elm]); }
172 172 }
173 173
174 174 // append the introspection result, in order, at at the beginning of
175 175 // the table and compute the replacement range from current cursor
176 176 // positon and matched_text length.
177 177 for (var i = matches.length - 1; i >= 0; --i) {
178 178 filterd_results.unshift({
179 179 str: matches[i],
180 180 type: "introspection",
181 181 from: {
182 182 line: cur.line,
183 183 ch: cur.ch - matched_text.length
184 184 },
185 185 to: {
186 186 line: cur.line,
187 187 ch: cur.ch
188 188 }
189 189 });
190 190 }
191 191
192 192 // one the 2 sources results have been merge, deal with it
193 193 this.raw_result = filterd_results;
194 194
195 195 // if empty result return
196 196 if (!this.raw_result || !this.raw_result.length) return;
197 197
198 198 // When there is only one completion, use it directly.
199 199 if (this.autopick == true && this.raw_result.length == 1) {
200 200 this.insert(this.raw_result[0]);
201 201 return;
202 202 }
203 203
204 204 if (this.raw_result.length == 1) {
205 205 // test if first and only completion totally matches
206 206 // what is typed, in this case dismiss
207 207 var str = this.raw_result[0].str;
208 208 var pre_cursor = this.editor.getRange({
209 209 line: cur.line,
210 210 ch: cur.ch - str.length
211 211 }, cur);
212 212 if (pre_cursor == str) {
213 213 this.close();
214 214 return;
215 215 }
216 216 }
217 217
218 218 this.complete = $('<div/>').addClass('completions');
219 219 this.complete.attr('id', 'complete');
220 220
221 // Currently webkit doesn't use the size attr correctly. See:
222 // https://code.google.com/p/chromium/issues/detail?id=4579
221 223 this.sel = $('<select style="width: auto"/>')
222 224 .attr('multiple', 'true')
223 225 .attr('size', Math.min(10, this.raw_result.length));
224 226 this.complete.append(this.sel);
225 227 $('body').append(this.complete);
226 228
227 229 // After everything is on the page, compute the postion.
228 230 // We put it above the code if it is too close to the bottom of the page.
229 231 var cur = this.editor.getCursor();
230 232 cur.ch = cur.ch-matched_text.length;
231 233 var pos = this.editor.cursorCoords(cur);
232 234 var left = pos.left-3;
233 235 var top;
234 236 var cheight = this.complete.height();
235 237 var wheight = $(window).height();
236 238 if (pos.bottom+cheight+5 > wheight) {
237 239 top = pos.top-cheight-4;
238 240 } else {
239 241 top = pos.bottom+1;
240 242 }
241 243 this.complete.css('left', left + 'px');
242 244 this.complete.css('top', top + 'px');
243 245
244 246
245 247 //build the container
246 248 var that = this;
247 249 this.sel.dblclick(function () {
248 250 that.pick();
249 251 });
250 252 this.sel.blur(this.close);
251 253 this.sel.keydown(function (event) {
252 254 that.keydown(event);
253 255 });
254 256
255 257 this.build_gui_list(this.raw_result);
256 258
257 259 this.sel.focus();
260 IPython.keyboard_manager.disable();
258 261 // Opera sometimes ignores focusing a freshly created node
259 262 if (window.opera) setTimeout(function () {
260 263 if (!this.done) this.sel.focus();
261 264 }, 100);
262 265 return true;
263 266 }
264 267
265 268 Completer.prototype.insert = function (completion) {
266 269 this.editor.replaceRange(completion.str, completion.from, completion.to);
267 270 }
268 271
269 272 Completer.prototype.build_gui_list = function (completions) {
270 273 for (var i = 0; i < completions.length; ++i) {
271 274 var opt = $('<option/>').text(completions[i].str).addClass(completions[i].type);
272 275 this.sel.append(opt);
273 276 }
274 277 this.sel.children().first().attr('selected', 'true');
275 278 this.sel.scrollTop(0);
276 279 }
277 280
278 281 Completer.prototype.close = function () {
279 282 if (this.done) return;
280 283 this.done = true;
281 284 $('.completions').remove();
285 IPython.keyboard_manager.enable();
282 286 }
283 287
284 288 Completer.prototype.pick = function () {
285 289 this.insert(this.raw_result[this.sel[0].selectedIndex]);
286 290 this.close();
287 291 var that = this;
288 292 setTimeout(function () {
289 293 that.editor.focus();
290 294 }, 50);
291 295 }
292 296
293 297
294 298 Completer.prototype.keydown = function (event) {
295 299 var code = event.keyCode;
296 300 var that = this;
297 301 var special_key = false;
298 302
299 303 // detect special keys like SHIFT,PGUP,...
300 304 for( var _key in key ) {
301 305 if (code == key[_key] ) {
302 306 special_key = true;
303 307 }
304 308 };
305 309
306 310 // Enter
307 311 if (code == key.ENTER) {
308 312 CodeMirror.e_stop(event);
309 313 this.pick();
310 314 }
311 315 // Escape or backspace
312 316 else if (code == key.ESC) {
313 317 CodeMirror.e_stop(event);
314 318 this.close();
315 319 this.editor.focus();
316 320 } else if (code == key.SPACE || code == key.BACKSPACE) {
317 321 this.close();
318 322 this.editor.focus();
319 323 } else if (code == key.TAB) {
320 324 //all the fastforwarding operation,
321 325 //Check that shared start is not null which can append with prefixed completion
322 326 // like %pylab , pylab have no shred start, and ff will result in py<tab><tab>
323 327 // to erase py
324 328 var sh = shared_start(this.raw_result, true);
325 329 if (sh) {
326 330 this.insert(sh);
327 331 }
328 332 this.close();
329 333 CodeMirror.e_stop(event);
330 334 this.editor.focus();
331 335 //reinvoke self
332 336 setTimeout(function () {
333 337 that.carry_on_completion();
334 338 }, 50);
335 339 } else if (code == key.UPARROW || code == key.DOWNARROW) {
336 340 // need to do that to be able to move the arrow
337 341 // when on the first or last line ofo a code cell
338 342 event.stopPropagation();
339 343 } else if (special_key != true) {
340 344 this.close();
341 345 this.editor.focus();
342 346 //we give focus to the editor immediately and call sell in 50 ms
343 347 setTimeout(function () {
344 348 that.carry_on_completion();
345 349 }, 50);
346 350 }
347 351 }
348 352
349 353
350 354 IPython.Completer = Completer;
351 355
352 356 return IPython;
353 357 }(IPython));
@@ -1,126 +1,127 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // On document ready
10 10 //============================================================================
11 11 "use strict";
12 12
13 13 // for the time beeing, we have to pass marked as a parameter here,
14 14 // as injecting require.js make marked not to put itself in the globals,
15 15 // which make both this file fail at setting marked configuration, and textcell.js
16 16 // which search marked into global.
17 17 require(['components/marked/lib/marked'],
18 18
19 19 function (marked) {
20 20
21 21 window.marked = marked
22 22
23 23 // monkey patch CM to be able to syntax highlight cell magics
24 24 // bug reported upstream,
25 25 // see https://github.com/marijnh/CodeMirror2/issues/670
26 26 if(CodeMirror.getMode(1,'text/plain').indent == undefined ){
27 27 console.log('patching CM for undefined indent');
28 28 CodeMirror.modes.null = function() {
29 29 return {token: function(stream) {stream.skipToEnd();},indent : function(){return 0}}
30 30 }
31 31 }
32 32
33 33 CodeMirror.patchedGetMode = function(config, mode){
34 34 var cmmode = CodeMirror.getMode(config, mode);
35 35 if(cmmode.indent == null)
36 36 {
37 37 console.log('patch mode "' , mode, '" on the fly');
38 38 cmmode.indent = function(){return 0};
39 39 }
40 40 return cmmode;
41 41 }
42 42 // end monkey patching CodeMirror
43 43
44 44 IPython.mathjaxutils.init();
45 45
46 46 $('#ipython-main-app').addClass('border-box-sizing');
47 47 $('div#notebook_panel').addClass('border-box-sizing');
48 48
49 49 var baseProjectUrl = $('body').data('baseProjectUrl');
50 50 var notebookPath = $('body').data('notebookPath');
51 51 var notebookName = $('body').data('notebookName');
52 52 notebookName = decodeURIComponent(notebookName);
53 53 notebookPath = decodeURIComponent(notebookPath);
54 54 console.log(notebookName);
55 55 if (notebookPath == 'None'){
56 56 notebookPath = "";
57 57 }
58 58
59 59 IPython.page = new IPython.Page();
60 60 IPython.layout_manager = new IPython.LayoutManager();
61 61 IPython.pager = new IPython.Pager('div#pager', 'div#pager_splitter');
62 62 IPython.quick_help = new IPython.QuickHelp();
63 63 IPython.login_widget = new IPython.LoginWidget('span#login_widget',{baseProjectUrl:baseProjectUrl});
64 64 IPython.notebook = new IPython.Notebook('div#notebook',{baseProjectUrl:baseProjectUrl, notebookPath:notebookPath, notebookName:notebookName});
65 IPython.keyboard_manager = new IPython.KeyboardManager();
65 66 IPython.save_widget = new IPython.SaveWidget('span#save_widget');
66 67 IPython.menubar = new IPython.MenuBar('#menubar',{baseProjectUrl:baseProjectUrl, notebookPath: notebookPath})
67 68 IPython.toolbar = new IPython.MainToolBar('#maintoolbar-container')
68 69 IPython.tooltip = new IPython.Tooltip()
69 70 IPython.notification_area = new IPython.NotificationArea('#notification_area')
70 71 IPython.notification_area.init_notification_widgets();
71 72
72 73 IPython.layout_manager.do_resize();
73 74
74 75 $('body').append('<div id="fonttest"><pre><span id="test1">x</span>'+
75 76 '<span id="test2" style="font-weight: bold;">x</span>'+
76 77 '<span id="test3" style="font-style: italic;">x</span></pre></div>')
77 78 var nh = $('#test1').innerHeight();
78 79 var bh = $('#test2').innerHeight();
79 80 var ih = $('#test3').innerHeight();
80 81 if(nh != bh || nh != ih) {
81 82 $('head').append('<style>.CodeMirror span { vertical-align: bottom; }</style>');
82 83 }
83 84 $('#fonttest').remove();
84 85
85 86 IPython.page.show();
86 87
87 88 IPython.layout_manager.do_resize();
88 89 var first_load = function () {
89 90 IPython.layout_manager.do_resize();
90 91 var hash = document.location.hash;
91 92 if (hash) {
92 93 document.location.hash = '';
93 94 document.location.hash = hash;
94 95 }
95 96 IPython.notebook.set_autosave_interval(IPython.notebook.minimum_autosave_interval);
96 97 // only do this once
97 98 $([IPython.events]).off('notebook_loaded.Notebook', first_load);
98 99 };
99 100
100 101 $([IPython.events]).on('notebook_loaded.Notebook', first_load);
101 102 $([IPython.events]).trigger('app_initialized.NotebookApp');
102 103 IPython.notebook.load_notebook(notebookName, notebookPath);
103 104
104 105 if (marked) {
105 106 marked.setOptions({
106 107 gfm : true,
107 108 tables: true,
108 109 langPrefix: "language-",
109 110 highlight: function(code, lang) {
110 111 if (!lang) {
111 112 // no language, no highlight
112 113 return code;
113 114 }
114 115 var highlighted;
115 116 try {
116 117 highlighted = hljs.highlight(lang, code, false);
117 118 } catch(err) {
118 119 highlighted = hljs.highlightAuto(code);
119 120 }
120 121 return highlighted.value;
121 122 }
122 123 })
123 124 }
124 125 }
125 126
126 127 );
@@ -1,203 +1,205 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // ToolBar
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13 "use strict";
14 14
15 15 var MainToolBar = function (selector) {
16 16 IPython.ToolBar.apply(this, arguments);
17 17 this.construct();
18 18 this.add_celltype_list();
19 19 this.add_celltoolbar_list();
20 20 this.bind_events();
21 21 };
22 22
23 23 MainToolBar.prototype = new IPython.ToolBar();
24 24
25 25 MainToolBar.prototype.construct = function () {
26 26 this.add_buttons_group([
27 27 {
28 28 id : 'save_b',
29 29 label : 'Save and Checkpoint',
30 30 icon : 'icon-save',
31 31 callback : function () {
32 32 IPython.notebook.save_checkpoint();
33 33 }
34 34 }
35 35 ]);
36 36
37 37 this.add_buttons_group([
38 38 {
39 39 id : 'insert_below_b',
40 40 label : 'Insert Cell Below',
41 41 icon : 'icon-plus-sign',
42 42 callback : function () {
43 43 IPython.notebook.insert_cell_below('code');
44 IPython.notebook.select_next();
45 IPython.notebook.focus_cell();
44 46 }
45 47 }
46 48 ],'insert_above_below');
47 49
48 50 this.add_buttons_group([
49 51 {
50 52 id : 'cut_b',
51 53 label : 'Cut Cell',
52 54 icon : 'icon-cut',
53 55 callback : function () {
54 56 IPython.notebook.cut_cell();
55 57 }
56 58 },
57 59 {
58 60 id : 'copy_b',
59 61 label : 'Copy Cell',
60 62 icon : 'icon-copy',
61 63 callback : function () {
62 64 IPython.notebook.copy_cell();
63 65 }
64 66 },
65 67 {
66 68 id : 'paste_b',
67 69 label : 'Paste Cell Below',
68 70 icon : 'icon-paste',
69 71 callback : function () {
70 72 IPython.notebook.paste_cell_below();
71 73 }
72 74 }
73 75 ],'cut_copy_paste');
74 76
75 77 this.add_buttons_group([
76 78 {
77 79 id : 'move_up_b',
78 80 label : 'Move Cell Up',
79 81 icon : 'icon-arrow-up',
80 82 callback : function () {
81 83 IPython.notebook.move_cell_up();
82 84 }
83 85 },
84 86 {
85 87 id : 'move_down_b',
86 88 label : 'Move Cell Down',
87 89 icon : 'icon-arrow-down',
88 90 callback : function () {
89 91 IPython.notebook.move_cell_down();
90 92 }
91 93 }
92 94 ],'move_up_down');
93 95
94 96
95 97 this.add_buttons_group([
96 98 {
97 99 id : 'run_b',
98 100 label : 'Run Cell',
99 101 icon : 'icon-play',
100 102 callback : function () {
101 IPython.notebook.execute_selected_cell();
103 IPython.notebook.execute_cell();
102 104 }
103 105 },
104 106 {
105 107 id : 'interrupt_b',
106 108 label : 'Interrupt',
107 109 icon : 'icon-stop',
108 110 callback : function () {
109 111 IPython.notebook.session.interrupt_kernel();
110 112 }
111 113 }
112 114 ],'run_int');
113 115 };
114 116
115 117 MainToolBar.prototype.add_celltype_list = function () {
116 118 this.element
117 119 .append($('<select/>')
118 120 .attr('id','cell_type')
119 121 // .addClass('ui-widget-content')
120 122 .append($('<option/>').attr('value','code').text('Code'))
121 123 .append($('<option/>').attr('value','markdown').text('Markdown'))
122 124 .append($('<option/>').attr('value','raw').text('Raw NBConvert'))
123 125 .append($('<option/>').attr('value','heading1').text('Heading 1'))
124 126 .append($('<option/>').attr('value','heading2').text('Heading 2'))
125 127 .append($('<option/>').attr('value','heading3').text('Heading 3'))
126 128 .append($('<option/>').attr('value','heading4').text('Heading 4'))
127 129 .append($('<option/>').attr('value','heading5').text('Heading 5'))
128 130 .append($('<option/>').attr('value','heading6').text('Heading 6'))
129 131 );
130 132 };
131 133
132 134
133 135 MainToolBar.prototype.add_celltoolbar_list = function () {
134 136 var label = $('<span/>').addClass("navbar-text").text('Cell Toolbar:');
135 137 var select = $('<select/>')
136 138 // .addClass('ui-widget-content')
137 139 .attr('id', 'ctb_select')
138 140 .append($('<option/>').attr('value', '').text('None'));
139 141 this.element.append(label).append(select);
140 142 select.change(function() {
141 143 var val = $(this).val()
142 144 if (val =='') {
143 145 IPython.CellToolbar.global_hide();
144 146 delete IPython.notebook.metadata.celltoolbar;
145 147 } else {
146 148 IPython.CellToolbar.global_show();
147 149 IPython.CellToolbar.activate_preset(val);
148 150 IPython.notebook.metadata.celltoolbar = val;
149 151 }
150 152 });
151 153 // Setup the currently registered presets.
152 154 var presets = IPython.CellToolbar.list_presets();
153 155 for (var i=0; i<presets.length; i++) {
154 156 var name = presets[i];
155 157 select.append($('<option/>').attr('value', name).text(name));
156 158 }
157 159 // Setup future preset registrations.
158 160 $([IPython.events]).on('preset_added.CellToolbar', function (event, data) {
159 161 var name = data.name;
160 162 select.append($('<option/>').attr('value', name).text(name));
161 163 });
162 164 };
163 165
164 166
165 167 MainToolBar.prototype.bind_events = function () {
166 168 var that = this;
167 169
168 170 this.element.find('#cell_type').change(function () {
169 171 var cell_type = $(this).val();
170 172 if (cell_type === 'code') {
171 173 IPython.notebook.to_code();
172 174 } else if (cell_type === 'markdown') {
173 175 IPython.notebook.to_markdown();
174 176 } else if (cell_type === 'raw') {
175 177 IPython.notebook.to_raw();
176 178 } else if (cell_type === 'heading1') {
177 179 IPython.notebook.to_heading(undefined, 1);
178 180 } else if (cell_type === 'heading2') {
179 181 IPython.notebook.to_heading(undefined, 2);
180 182 } else if (cell_type === 'heading3') {
181 183 IPython.notebook.to_heading(undefined, 3);
182 184 } else if (cell_type === 'heading4') {
183 185 IPython.notebook.to_heading(undefined, 4);
184 186 } else if (cell_type === 'heading5') {
185 187 IPython.notebook.to_heading(undefined, 5);
186 188 } else if (cell_type === 'heading6') {
187 189 IPython.notebook.to_heading(undefined, 6);
188 190 }
189 191 });
190 192 $([IPython.events]).on('selected_cell_type_changed.Notebook', function (event, data) {
191 193 if (data.cell_type === 'heading') {
192 194 that.element.find('#cell_type').val(data.cell_type+data.level);
193 195 } else {
194 196 that.element.find('#cell_type').val(data.cell_type);
195 197 }
196 198 });
197 199 };
198 200
199 201 IPython.MainToolBar = MainToolBar;
200 202
201 203 return IPython;
202 204
203 205 }(IPython));
@@ -1,322 +1,327 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // MenuBar
10 10 //============================================================================
11 11
12 12 /**
13 13 * @module IPython
14 14 * @namespace IPython
15 15 * @submodule MenuBar
16 16 */
17 17
18 18
19 19 var IPython = (function (IPython) {
20 20 "use strict";
21 21
22 22 var utils = IPython.utils;
23 23
24 24 /**
25 25 * A MenuBar Class to generate the menubar of IPython notebook
26 26 * @Class MenuBar
27 27 *
28 28 * @constructor
29 29 *
30 30 *
31 31 * @param selector {string} selector for the menubar element in DOM
32 32 * @param {object} [options]
33 33 * @param [options.baseProjectUrl] {String} String to use for the
34 34 * Base Project url, default would be to inspect
35 35 * $('body').data('baseProjectUrl');
36 36 * does not support change for now is set through this option
37 37 */
38 38 var MenuBar = function (selector, options) {
39 39 options = options || {};
40 40 if (options.baseProjectUrl !== undefined) {
41 41 this._baseProjectUrl = options.baseProjectUrl;
42 42 }
43 43 this.selector = selector;
44 44 if (this.selector !== undefined) {
45 45 this.element = $(selector);
46 46 this.style();
47 47 this.bind_events();
48 48 }
49 49 };
50 50
51 51 MenuBar.prototype.baseProjectUrl = function(){
52 52 return this._baseProjectUrl || $('body').data('baseProjectUrl');
53 53 };
54 54
55 55 MenuBar.prototype.notebookPath = function() {
56 56 var path = $('body').data('notebookPath');
57 57 path = decodeURIComponent(path);
58 58 return path;
59 59 };
60 60
61 61 MenuBar.prototype.style = function () {
62 62 this.element.addClass('border-box-sizing');
63 63 this.element.find("li").click(function (event, ui) {
64 64 // The selected cell loses focus when the menu is entered, so we
65 65 // re-select it upon selection.
66 66 var i = IPython.notebook.get_selected_index();
67 67 IPython.notebook.select(i);
68 68 }
69 69 );
70 70 };
71 71
72 72 MenuBar.prototype._nbconvert = function (format, download) {
73 73 download = download || false;
74 74 var notebook_name = IPython.notebook.get_notebook_name();
75 75 if (IPython.notebook.dirty) {
76 76 IPython.notebook.save_notebook({async : false});
77 77 }
78 78 var url = utils.url_path_join(
79 79 this.baseProjectUrl(),
80 80 'nbconvert',
81 81 format,
82 82 this.notebookPath(),
83 83 notebook_name + '.ipynb'
84 84 ) + "?download=" + download.toString();
85 85
86 86 window.open(url);
87 87 }
88 88
89 89 MenuBar.prototype.bind_events = function () {
90 90 // File
91 91 var that = this;
92 92 this.element.find('#new_notebook').click(function () {
93 93 IPython.notebook.new_notebook();
94 94 });
95 95 this.element.find('#open_notebook').click(function () {
96 96 window.open(utils.url_join_encode(
97 97 that.baseProjectUrl(),
98 98 'tree',
99 99 that.notebookPath()
100 100 ));
101 101 });
102 102 this.element.find('#copy_notebook').click(function () {
103 103 IPython.notebook.copy_notebook();
104 104 return false;
105 105 });
106 106 this.element.find('#download_ipynb').click(function () {
107 107 var notebook_name = IPython.notebook.get_notebook_name();
108 108 if (IPython.notebook.dirty) {
109 109 IPython.notebook.save_notebook({async : false});
110 110 }
111 111
112 112 var url = utils.url_join_encode(
113 113 that.baseProjectUrl(),
114 114 'files',
115 115 that.notebookPath(),
116 116 notebook_name + '.ipynb'
117 117 );
118 118 window.location.assign(url);
119 119 });
120 120
121 121 this.element.find('#print_preview').click(function () {
122 122 that._nbconvert('html', false);
123 123 });
124 124
125 125 this.element.find('#download_py').click(function () {
126 126 that._nbconvert('python', true);
127 127 });
128 128
129 129 this.element.find('#download_html').click(function () {
130 130 that._nbconvert('html', true);
131 131 });
132 132
133 133 this.element.find('#download_rst').click(function () {
134 134 that._nbconvert('rst', true);
135 135 });
136 136
137 137 this.element.find('#rename_notebook').click(function () {
138 138 IPython.save_widget.rename_notebook();
139 139 });
140 140 this.element.find('#save_checkpoint').click(function () {
141 141 IPython.notebook.save_checkpoint();
142 142 });
143 143 this.element.find('#restore_checkpoint').click(function () {
144 144 });
145 145 this.element.find('#kill_and_exit').click(function () {
146 146 IPython.notebook.session.delete();
147 147 setTimeout(function(){
148 148 // allow closing of new tabs in Chromium, impossible in FF
149 149 window.open('', '_self', '');
150 150 window.close();
151 151 }, 500);
152 152 });
153 153 // Edit
154 154 this.element.find('#cut_cell').click(function () {
155 155 IPython.notebook.cut_cell();
156 156 });
157 157 this.element.find('#copy_cell').click(function () {
158 158 IPython.notebook.copy_cell();
159 159 });
160 160 this.element.find('#delete_cell').click(function () {
161 161 IPython.notebook.delete_cell();
162 162 });
163 163 this.element.find('#undelete_cell').click(function () {
164 IPython.notebook.undelete();
164 IPython.notebook.undelete_cell();
165 165 });
166 166 this.element.find('#split_cell').click(function () {
167 167 IPython.notebook.split_cell();
168 168 });
169 169 this.element.find('#merge_cell_above').click(function () {
170 170 IPython.notebook.merge_cell_above();
171 171 });
172 172 this.element.find('#merge_cell_below').click(function () {
173 173 IPython.notebook.merge_cell_below();
174 174 });
175 175 this.element.find('#move_cell_up').click(function () {
176 176 IPython.notebook.move_cell_up();
177 177 });
178 178 this.element.find('#move_cell_down').click(function () {
179 179 IPython.notebook.move_cell_down();
180 180 });
181 181 this.element.find('#select_previous').click(function () {
182 182 IPython.notebook.select_prev();
183 183 });
184 184 this.element.find('#select_next').click(function () {
185 185 IPython.notebook.select_next();
186 186 });
187 187 this.element.find('#edit_nb_metadata').click(function () {
188 188 IPython.notebook.edit_metadata();
189 189 });
190 190
191 191 // View
192 192 this.element.find('#toggle_header').click(function () {
193 193 $('div#header').toggle();
194 194 IPython.layout_manager.do_resize();
195 195 });
196 196 this.element.find('#toggle_toolbar').click(function () {
197 197 $('div#maintoolbar').toggle();
198 198 IPython.layout_manager.do_resize();
199 199 });
200 200 // Insert
201 201 this.element.find('#insert_cell_above').click(function () {
202 202 IPython.notebook.insert_cell_above('code');
203 IPython.notebook.select_prev();
203 204 });
204 205 this.element.find('#insert_cell_below').click(function () {
205 206 IPython.notebook.insert_cell_below('code');
207 IPython.notebook.select_next();
206 208 });
207 209 // Cell
208 210 this.element.find('#run_cell').click(function () {
209 IPython.notebook.execute_selected_cell();
211 IPython.notebook.execute_cell();
212 });
213 this.element.find('#run_cell_select_below').click(function () {
214 IPython.notebook.execute_cell_and_select_below();
210 215 });
211 this.element.find('#run_cell_in_place').click(function () {
212 IPython.notebook.execute_selected_cell({terminal:true});
216 this.element.find('#run_cell_insert_below').click(function () {
217 IPython.notebook.execute_cell_and_insert_below();
213 218 });
214 219 this.element.find('#run_all_cells').click(function () {
215 220 IPython.notebook.execute_all_cells();
216 221 });
217 222 this.element.find('#run_all_cells_above').click(function () {
218 223 IPython.notebook.execute_cells_above();
219 224 });
220 225 this.element.find('#run_all_cells_below').click(function () {
221 226 IPython.notebook.execute_cells_below();
222 227 });
223 228 this.element.find('#to_code').click(function () {
224 229 IPython.notebook.to_code();
225 230 });
226 231 this.element.find('#to_markdown').click(function () {
227 232 IPython.notebook.to_markdown();
228 233 });
229 234 this.element.find('#to_raw').click(function () {
230 235 IPython.notebook.to_raw();
231 236 });
232 237 this.element.find('#to_heading1').click(function () {
233 238 IPython.notebook.to_heading(undefined, 1);
234 239 });
235 240 this.element.find('#to_heading2').click(function () {
236 241 IPython.notebook.to_heading(undefined, 2);
237 242 });
238 243 this.element.find('#to_heading3').click(function () {
239 244 IPython.notebook.to_heading(undefined, 3);
240 245 });
241 246 this.element.find('#to_heading4').click(function () {
242 247 IPython.notebook.to_heading(undefined, 4);
243 248 });
244 249 this.element.find('#to_heading5').click(function () {
245 250 IPython.notebook.to_heading(undefined, 5);
246 251 });
247 252 this.element.find('#to_heading6').click(function () {
248 253 IPython.notebook.to_heading(undefined, 6);
249 254 });
250 255 this.element.find('#toggle_output').click(function () {
251 256 IPython.notebook.toggle_output();
252 257 });
253 258 this.element.find('#collapse_all_output').click(function () {
254 259 IPython.notebook.collapse_all_output();
255 260 });
256 261 this.element.find('#scroll_all_output').click(function () {
257 262 IPython.notebook.scroll_all_output();
258 263 });
259 264 this.element.find('#expand_all_output').click(function () {
260 265 IPython.notebook.expand_all_output();
261 266 });
262 267 this.element.find('#clear_all_output').click(function () {
263 268 IPython.notebook.clear_all_output();
264 269 });
265 270 // Kernel
266 271 this.element.find('#int_kernel').click(function () {
267 272 IPython.notebook.session.interrupt_kernel();
268 273 });
269 274 this.element.find('#restart_kernel').click(function () {
270 275 IPython.notebook.restart_kernel();
271 276 });
272 277 // Help
273 278 this.element.find('#keyboard_shortcuts').click(function () {
274 279 IPython.quick_help.show_keyboard_shortcuts();
275 280 });
276 281
277 282 this.update_restore_checkpoint(null);
278 283
279 284 $([IPython.events]).on('checkpoints_listed.Notebook', function (event, data) {
280 285 that.update_restore_checkpoint(IPython.notebook.checkpoints);
281 286 });
282 287
283 288 $([IPython.events]).on('checkpoint_created.Notebook', function (event, data) {
284 289 that.update_restore_checkpoint(IPython.notebook.checkpoints);
285 290 });
286 291 };
287 292
288 293 MenuBar.prototype.update_restore_checkpoint = function(checkpoints) {
289 294 var ul = this.element.find("#restore_checkpoint").find("ul");
290 295 ul.empty();
291 296 if (!checkpoints || checkpoints.length === 0) {
292 297 ul.append(
293 298 $("<li/>")
294 299 .addClass("disabled")
295 300 .append(
296 301 $("<a/>")
297 302 .text("No checkpoints")
298 303 )
299 304 );
300 305 return;
301 306 }
302 307
303 308 checkpoints.map(function (checkpoint) {
304 309 var d = new Date(checkpoint.last_modified);
305 310 ul.append(
306 311 $("<li/>").append(
307 312 $("<a/>")
308 313 .attr("href", "#")
309 314 .text(d.format("mmm dd HH:MM:ss"))
310 315 .click(function () {
311 316 IPython.notebook.restore_checkpoint_dialog(checkpoint);
312 317 })
313 318 )
314 319 );
315 320 });
316 321 };
317 322
318 323 IPython.MenuBar = MenuBar;
319 324
320 325 return IPython;
321 326
322 327 }(IPython));
This diff has been collapsed as it changes many lines, (538 lines changed) Show them Hide them
@@ -1,2267 +1,2213 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Notebook
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13 "use strict";
14 14
15 15 var utils = IPython.utils;
16 var key = IPython.utils.keycodes;
17 16
18 17 /**
19 18 * A notebook contains and manages cells.
20 19 *
21 20 * @class Notebook
22 21 * @constructor
23 22 * @param {String} selector A jQuery selector for the notebook's DOM element
24 23 * @param {Object} [options] A config object
25 24 */
26 25 var Notebook = function (selector, options) {
27 26 var options = options || {};
28 27 this._baseProjectUrl = options.baseProjectUrl;
29 28 this.notebook_path = options.notebookPath;
30 29 this.notebook_name = options.notebookName;
31 30 this.element = $(selector);
32 31 this.element.scroll();
33 32 this.element.data("notebook", this);
34 33 this.next_prompt_number = 1;
35 34 this.session = null;
36 35 this.kernel = null;
37 36 this.clipboard = null;
38 37 this.undelete_backup = null;
39 38 this.undelete_index = null;
40 39 this.undelete_below = false;
41 40 this.paste_enabled = false;
41 // It is important to start out in command mode to match the intial mode
42 // of the KeyboardManager.
43 this.mode = 'command';
42 44 this.set_dirty(false);
43 45 this.metadata = {};
44 46 this._checkpoint_after_save = false;
45 47 this.last_checkpoint = null;
46 48 this.checkpoints = [];
47 49 this.autosave_interval = 0;
48 50 this.autosave_timer = null;
49 51 // autosave *at most* every two minutes
50 52 this.minimum_autosave_interval = 120000;
51 53 // single worksheet for now
52 54 this.worksheet_metadata = {};
53 this.control_key_active = false;
54 55 this.notebook_name_blacklist_re = /[\/\\:]/;
55 56 this.nbformat = 3 // Increment this when changing the nbformat
56 57 this.nbformat_minor = 0 // Increment this when changing the nbformat
57 58 this.style();
58 59 this.create_elements();
59 60 this.bind_events();
60 61 };
61 62
62 63 /**
63 64 * Tweak the notebook's CSS style.
64 65 *
65 66 * @method style
66 67 */
67 68 Notebook.prototype.style = function () {
68 69 $('div#notebook').addClass('border-box-sizing');
69 70 };
70 71
71 72 /**
72 73 * Get the root URL of the notebook server.
73 74 *
74 75 * @method baseProjectUrl
75 76 * @return {String} The base project URL
76 77 */
77 Notebook.prototype.baseProjectUrl = function(){
78 Notebook.prototype.baseProjectUrl = function() {
78 79 return this._baseProjectUrl || $('body').data('baseProjectUrl');
79 80 };
80 81
81 82 Notebook.prototype.notebookName = function() {
82 83 return $('body').data('notebookName');
83 84 };
84 85
85 86 Notebook.prototype.notebookPath = function() {
86 87 return $('body').data('notebookPath');
87 88 };
88 89
89 90 /**
90 91 * Create an HTML and CSS representation of the notebook.
91 92 *
92 93 * @method create_elements
93 94 */
94 95 Notebook.prototype.create_elements = function () {
96 var that = this;
97 this.element.attr('tabindex','-1');
98 this.container = $("<div/>").addClass("container").attr("id", "notebook-container");
95 99 // We add this end_space div to the end of the notebook div to:
96 100 // i) provide a margin between the last cell and the end of the notebook
97 101 // ii) to prevent the div from scrolling up when the last cell is being
98 102 // edited, but is too low on the page, which browsers will do automatically.
99 var that = this;
100 this.container = $("<div/>").addClass("container").attr("id", "notebook-container");
101 103 var end_space = $('<div/>').addClass('end_space');
102 104 end_space.dblclick(function (e) {
103 105 var ncells = that.ncells();
104 106 that.insert_cell_below('code',ncells-1);
105 107 });
106 108 this.element.append(this.container);
107 109 this.container.append(end_space);
108 $('div#notebook').addClass('border-box-sizing');
109 110 };
110 111
111 112 /**
112 113 * Bind JavaScript events: key presses and custom IPython events.
113 114 *
114 115 * @method bind_events
115 116 */
116 117 Notebook.prototype.bind_events = function () {
117 118 var that = this;
118 119
119 120 $([IPython.events]).on('set_next_input.Notebook', function (event, data) {
120 121 var index = that.find_cell_index(data.cell);
121 122 var new_cell = that.insert_cell_below('code',index);
122 123 new_cell.set_text(data.text);
123 124 that.dirty = true;
124 125 });
125 126
126 127 $([IPython.events]).on('set_dirty.Notebook', function (event, data) {
127 128 that.dirty = data.value;
128 129 });
129 130
130 131 $([IPython.events]).on('select.Cell', function (event, data) {
131 132 var index = that.find_cell_index(data.cell);
132 133 that.select(index);
133 134 });
134
135
136 $([IPython.events]).on('edit_mode.Cell', function (event, data) {
137 var index = that.find_cell_index(data.cell);
138 that.select(index);
139 that.edit_mode();
140 });
141
142 $([IPython.events]).on('command_mode.Cell', function (event, data) {
143 that.command_mode();
144 });
145
135 146 $([IPython.events]).on('status_autorestarting.Kernel', function () {
136 147 IPython.dialog.modal({
137 148 title: "Kernel Restarting",
138 149 body: "The kernel appears to have died. It will restart automatically.",
139 150 buttons: {
140 151 OK : {
141 152 class : "btn-primary"
142 153 }
143 154 }
144 155 });
145 156 });
146 157
147
148 $(document).keydown(function (event) {
149
150 // Save (CTRL+S) or (AppleKey+S)
151 //metaKey = applekey on mac
152 if ((event.ctrlKey || event.metaKey) && event.keyCode==83) {
153 that.save_checkpoint();
154 event.preventDefault();
155 return false;
156 } else if (event.which === key.ESC) {
157 // Intercept escape at highest level to avoid closing
158 // websocket connection with firefox
159 IPython.pager.collapse();
160 event.preventDefault();
161 } else if (event.which === key.SHIFT) {
162 // ignore shift keydown
163 return true;
164 }
165 if (event.which === key.UPARROW && !event.shiftKey) {
166 var cell = that.get_selected_cell();
167 if (cell && cell.at_top()) {
168 event.preventDefault();
169 that.select_prev();
170 };
171 } else if (event.which === key.DOWNARROW && !event.shiftKey) {
172 var cell = that.get_selected_cell();
173 if (cell && cell.at_bottom()) {
174 event.preventDefault();
175 that.select_next();
176 };
177 } else if (event.which === key.ENTER && event.shiftKey) {
178 that.execute_selected_cell();
179 return false;
180 } else if (event.which === key.ENTER && event.altKey) {
181 // Execute code cell, and insert new in place
182 that.execute_selected_cell();
183 // Only insert a new cell, if we ended up in an already populated cell
184 if (/\S/.test(that.get_selected_cell().get_text()) == true) {
185 that.insert_cell_above('code');
186 }
187 return false;
188 } else if (event.which === key.ENTER && event.ctrlKey) {
189 that.execute_selected_cell({terminal:true});
190 return false;
191 } else if (event.which === 77 && event.ctrlKey && that.control_key_active == false) {
192 that.control_key_active = true;
193 return false;
194 } else if (event.which === 88 && that.control_key_active) {
195 // Cut selected cell = x
196 that.cut_cell();
197 that.control_key_active = false;
198 return false;
199 } else if (event.which === 67 && that.control_key_active) {
200 // Copy selected cell = c
201 that.copy_cell();
202 that.control_key_active = false;
203 return false;
204 } else if (event.which === 86 && that.control_key_active) {
205 // Paste below selected cell = v
206 that.paste_cell_below();
207 that.control_key_active = false;
208 return false;
209 } else if (event.which === 68 && that.control_key_active) {
210 // Delete selected cell = d
211 that.delete_cell();
212 that.control_key_active = false;
213 return false;
214 } else if (event.which === 65 && that.control_key_active) {
215 // Insert code cell above selected = a
216 that.insert_cell_above('code');
217 that.control_key_active = false;
218 return false;
219 } else if (event.which === 66 && that.control_key_active) {
220 // Insert code cell below selected = b
221 that.insert_cell_below('code');
222 that.control_key_active = false;
223 return false;
224 } else if (event.which === 89 && that.control_key_active) {
225 // To code = y
226 that.to_code();
227 that.control_key_active = false;
228 return false;
229 } else if (event.which === 77 && that.control_key_active) {
230 // To markdown = m
231 that.to_markdown();
232 that.control_key_active = false;
233 return false;
234 } else if (event.which === 84 && that.control_key_active) {
235 // To Raw = t
236 that.to_raw();
237 that.control_key_active = false;
238 return false;
239 } else if (event.which === 49 && that.control_key_active) {
240 // To Heading 1 = 1
241 that.to_heading(undefined, 1);
242 that.control_key_active = false;
243 return false;
244 } else if (event.which === 50 && that.control_key_active) {
245 // To Heading 2 = 2
246 that.to_heading(undefined, 2);
247 that.control_key_active = false;
248 return false;
249 } else if (event.which === 51 && that.control_key_active) {
250 // To Heading 3 = 3
251 that.to_heading(undefined, 3);
252 that.control_key_active = false;
253 return false;
254 } else if (event.which === 52 && that.control_key_active) {
255 // To Heading 4 = 4
256 that.to_heading(undefined, 4);
257 that.control_key_active = false;
258 return false;
259 } else if (event.which === 53 && that.control_key_active) {
260 // To Heading 5 = 5
261 that.to_heading(undefined, 5);
262 that.control_key_active = false;
263 return false;
264 } else if (event.which === 54 && that.control_key_active) {
265 // To Heading 6 = 6
266 that.to_heading(undefined, 6);
267 that.control_key_active = false;
268 return false;
269 } else if (event.which === 79 && that.control_key_active) {
270 // Toggle output = o
271 if (event.shiftKey){
272 that.toggle_output_scroll();
273 } else {
274 that.toggle_output();
275 }
276 that.control_key_active = false;
277 return false;
278 } else if (event.which === 83 && that.control_key_active) {
279 // Save notebook = s
280 that.save_checkpoint();
281 that.control_key_active = false;
282 return false;
283 } else if (event.which === 74 && that.control_key_active) {
284 // Move cell down = j
285 that.move_cell_down();
286 that.control_key_active = false;
287 return false;
288 } else if (event.which === 75 && that.control_key_active) {
289 // Move cell up = k
290 that.move_cell_up();
291 that.control_key_active = false;
292 return false;
293 } else if (event.which === 80 && that.control_key_active) {
294 // Select previous = p
295 that.select_prev();
296 that.control_key_active = false;
297 return false;
298 } else if (event.which === 78 && that.control_key_active) {
299 // Select next = n
300 that.select_next();
301 that.control_key_active = false;
302 return false;
303 } else if (event.which === 76 && that.control_key_active) {
304 // Toggle line numbers = l
305 that.cell_toggle_line_numbers();
306 that.control_key_active = false;
307 return false;
308 } else if (event.which === 73 && that.control_key_active) {
309 // Interrupt kernel = i
310 that.session.interrupt_kernel();
311 that.control_key_active = false;
312 return false;
313 } else if (event.which === 190 && that.control_key_active) {
314 // Restart kernel = . # matches qt console
315 that.restart_kernel();
316 that.control_key_active = false;
317 return false;
318 } else if (event.which === 72 && that.control_key_active) {
319 // Show keyboard shortcuts = h
320 IPython.quick_help.show_keyboard_shortcuts();
321 that.control_key_active = false;
322 return false;
323 } else if (event.which === 90 && that.control_key_active) {
324 // Undo last cell delete = z
325 that.undelete();
326 that.control_key_active = false;
327 return false;
328 } else if ((event.which === 189 || event.which === 173) &&
329 that.control_key_active) {
330 // how fun! '-' is 189 in Chrome, but 173 in FF and Opera
331 // Split cell = -
332 that.split_cell();
333 that.control_key_active = false;
334 return false;
335 } else if (that.control_key_active) {
336 that.control_key_active = false;
337 return true;
338 }
339 return true;
340 });
341
342 var collapse_time = function(time){
158 var collapse_time = function (time) {
343 159 var app_height = $('#ipython-main-app').height(); // content height
344 160 var splitter_height = $('div#pager_splitter').outerHeight(true);
345 161 var new_height = app_height - splitter_height;
346 162 that.element.animate({height : new_height + 'px'}, time);
347 }
163 };
348 164
349 this.element.bind('collapse_pager', function (event,extrap) {
165 this.element.bind('collapse_pager', function (event, extrap) {
350 166 var time = (extrap != undefined) ? ((extrap.duration != undefined ) ? extrap.duration : 'fast') : 'fast';
351 167 collapse_time(time);
352 168 });
353 169
354 var expand_time = function(time) {
170 var expand_time = function (time) {
355 171 var app_height = $('#ipython-main-app').height(); // content height
356 172 var splitter_height = $('div#pager_splitter').outerHeight(true);
357 173 var pager_height = $('div#pager').outerHeight(true);
358 174 var new_height = app_height - pager_height - splitter_height;
359 175 that.element.animate({height : new_height + 'px'}, time);
360 }
176 };
361 177
362 178 this.element.bind('expand_pager', function (event, extrap) {
363 179 var time = (extrap != undefined) ? ((extrap.duration != undefined ) ? extrap.duration : 'fast') : 'fast';
364 180 expand_time(time);
365 181 });
366 182
367 183 // Firefox 22 broke $(window).on("beforeunload")
368 184 // I'm not sure why or how.
369 185 window.onbeforeunload = function (e) {
370 186 // TODO: Make killing the kernel configurable.
371 187 var kill_kernel = false;
372 188 if (kill_kernel) {
373 189 that.session.kill_kernel();
374 190 }
375 191 // if we are autosaving, trigger an autosave on nav-away.
376 192 // still warn, because if we don't the autosave may fail.
377 193 if (that.dirty) {
378 194 if ( that.autosave_interval ) {
379 195 // schedule autosave in a timeout
380 196 // this gives you a chance to forcefully discard changes
381 197 // by reloading the page if you *really* want to.
382 198 // the timer doesn't start until you *dismiss* the dialog.
383 199 setTimeout(function () {
384 200 if (that.dirty) {
385 201 that.save_notebook();
386 202 }
387 203 }, 1000);
388 204 return "Autosave in progress, latest changes may be lost.";
389 205 } else {
390 206 return "Unsaved changes will be lost.";
391 207 }
392 208 };
393 209 // Null is the *only* return value that will make the browser not
394 210 // pop up the "don't leave" dialog.
395 211 return null;
396 212 };
397 213 };
398 214
399 215 /**
400 216 * Set the dirty flag, and trigger the set_dirty.Notebook event
401 217 *
402 218 * @method set_dirty
403 219 */
404 220 Notebook.prototype.set_dirty = function (value) {
405 221 if (value === undefined) {
406 222 value = true;
407 223 }
408 224 if (this.dirty == value) {
409 225 return;
410 226 }
411 227 $([IPython.events]).trigger('set_dirty.Notebook', {value: value});
412 228 };
413 229
414 230 /**
415 231 * Scroll the top of the page to a given cell.
416 232 *
417 233 * @method scroll_to_cell
418 234 * @param {Number} cell_number An index of the cell to view
419 235 * @param {Number} time Animation time in milliseconds
420 236 * @return {Number} Pixel offset from the top of the container
421 237 */
422 238 Notebook.prototype.scroll_to_cell = function (cell_number, time) {
423 239 var cells = this.get_cells();
424 240 var time = time || 0;
425 241 cell_number = Math.min(cells.length-1,cell_number);
426 242 cell_number = Math.max(0 ,cell_number);
427 243 var scroll_value = cells[cell_number].element.position().top-cells[0].element.position().top ;
428 244 this.element.animate({scrollTop:scroll_value}, time);
429 245 return scroll_value;
430 246 };
431 247
432 248 /**
433 249 * Scroll to the bottom of the page.
434 250 *
435 251 * @method scroll_to_bottom
436 252 */
437 253 Notebook.prototype.scroll_to_bottom = function () {
438 254 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
439 255 };
440 256
441 257 /**
442 258 * Scroll to the top of the page.
443 259 *
444 260 * @method scroll_to_top
445 261 */
446 262 Notebook.prototype.scroll_to_top = function () {
447 263 this.element.animate({scrollTop:0}, 0);
448 264 };
449 265
450 266 // Edit Notebook metadata
451 267
452 268 Notebook.prototype.edit_metadata = function () {
453 269 var that = this;
454 270 IPython.dialog.edit_metadata(this.metadata, function (md) {
455 271 that.metadata = md;
456 272 }, 'Notebook');
457 273 };
458 274
459 275 // Cell indexing, retrieval, etc.
460 276
461 277 /**
462 278 * Get all cell elements in the notebook.
463 279 *
464 280 * @method get_cell_elements
465 281 * @return {jQuery} A selector of all cell elements
466 282 */
467 283 Notebook.prototype.get_cell_elements = function () {
468 284 return this.container.children("div.cell");
469 285 };
470 286
471 287 /**
472 288 * Get a particular cell element.
473 289 *
474 290 * @method get_cell_element
475 291 * @param {Number} index An index of a cell to select
476 292 * @return {jQuery} A selector of the given cell.
477 293 */
478 294 Notebook.prototype.get_cell_element = function (index) {
479 295 var result = null;
480 296 var e = this.get_cell_elements().eq(index);
481 297 if (e.length !== 0) {
482 298 result = e;
483 299 }
484 300 return result;
485 301 };
486 302
487 303 /**
488 304 * Count the cells in this notebook.
489 305 *
490 306 * @method ncells
491 307 * @return {Number} The number of cells in this notebook
492 308 */
493 309 Notebook.prototype.ncells = function () {
494 310 return this.get_cell_elements().length;
495 311 };
496 312
497 313 /**
498 314 * Get all Cell objects in this notebook.
499 315 *
500 316 * @method get_cells
501 317 * @return {Array} This notebook's Cell objects
502 318 */
503 319 // TODO: we are often calling cells as cells()[i], which we should optimize
504 320 // to cells(i) or a new method.
505 321 Notebook.prototype.get_cells = function () {
506 322 return this.get_cell_elements().toArray().map(function (e) {
507 323 return $(e).data("cell");
508 324 });
509 325 };
510 326
511 327 /**
512 328 * Get a Cell object from this notebook.
513 329 *
514 330 * @method get_cell
515 331 * @param {Number} index An index of a cell to retrieve
516 332 * @return {Cell} A particular cell
517 333 */
518 334 Notebook.prototype.get_cell = function (index) {
519 335 var result = null;
520 336 var ce = this.get_cell_element(index);
521 337 if (ce !== null) {
522 338 result = ce.data('cell');
523 339 }
524 340 return result;
525 341 }
526 342
527 343 /**
528 344 * Get the cell below a given cell.
529 345 *
530 346 * @method get_next_cell
531 347 * @param {Cell} cell The provided cell
532 348 * @return {Cell} The next cell
533 349 */
534 350 Notebook.prototype.get_next_cell = function (cell) {
535 351 var result = null;
536 352 var index = this.find_cell_index(cell);
537 353 if (this.is_valid_cell_index(index+1)) {
538 354 result = this.get_cell(index+1);
539 355 }
540 356 return result;
541 357 }
542 358
543 359 /**
544 360 * Get the cell above a given cell.
545 361 *
546 362 * @method get_prev_cell
547 363 * @param {Cell} cell The provided cell
548 364 * @return {Cell} The previous cell
549 365 */
550 366 Notebook.prototype.get_prev_cell = function (cell) {
551 367 // TODO: off-by-one
552 368 // nb.get_prev_cell(nb.get_cell(1)) is null
553 369 var result = null;
554 370 var index = this.find_cell_index(cell);
555 371 if (index !== null && index > 1) {
556 372 result = this.get_cell(index-1);
557 373 }
558 374 return result;
559 375 }
560 376
561 377 /**
562 378 * Get the numeric index of a given cell.
563 379 *
564 380 * @method find_cell_index
565 381 * @param {Cell} cell The provided cell
566 382 * @return {Number} The cell's numeric index
567 383 */
568 384 Notebook.prototype.find_cell_index = function (cell) {
569 385 var result = null;
570 386 this.get_cell_elements().filter(function (index) {
571 387 if ($(this).data("cell") === cell) {
572 388 result = index;
573 389 };
574 390 });
575 391 return result;
576 392 };
577 393
578 394 /**
579 395 * Get a given index , or the selected index if none is provided.
580 396 *
581 397 * @method index_or_selected
582 398 * @param {Number} index A cell's index
583 399 * @return {Number} The given index, or selected index if none is provided.
584 400 */
585 401 Notebook.prototype.index_or_selected = function (index) {
586 402 var i;
587 403 if (index === undefined || index === null) {
588 404 i = this.get_selected_index();
589 405 if (i === null) {
590 406 i = 0;
591 407 }
592 408 } else {
593 409 i = index;
594 410 }
595 411 return i;
596 412 };
597 413
598 414 /**
599 415 * Get the currently selected cell.
600 416 * @method get_selected_cell
601 417 * @return {Cell} The selected cell
602 418 */
603 419 Notebook.prototype.get_selected_cell = function () {
604 420 var index = this.get_selected_index();
605 421 return this.get_cell(index);
606 422 };
607 423
608 424 /**
609 425 * Check whether a cell index is valid.
610 426 *
611 427 * @method is_valid_cell_index
612 428 * @param {Number} index A cell index
613 429 * @return True if the index is valid, false otherwise
614 430 */
615 431 Notebook.prototype.is_valid_cell_index = function (index) {
616 432 if (index !== null && index >= 0 && index < this.ncells()) {
617 433 return true;
618 434 } else {
619 435 return false;
620 436 };
621 437 }
622 438
623 439 /**
624 440 * Get the index of the currently selected cell.
625 441
626 442 * @method get_selected_index
627 443 * @return {Number} The selected cell's numeric index
628 444 */
629 445 Notebook.prototype.get_selected_index = function () {
630 446 var result = null;
631 447 this.get_cell_elements().filter(function (index) {
632 448 if ($(this).data("cell").selected === true) {
633 449 result = index;
634 450 };
635 451 });
636 452 return result;
637 453 };
638 454
639 455
640 456 // Cell selection.
641 457
642 458 /**
643 459 * Programmatically select a cell.
644 460 *
645 461 * @method select
646 462 * @param {Number} index A cell's index
647 463 * @return {Notebook} This notebook
648 464 */
649 465 Notebook.prototype.select = function (index) {
650 466 if (this.is_valid_cell_index(index)) {
651 467 var sindex = this.get_selected_index()
652 468 if (sindex !== null && index !== sindex) {
469 this.command_mode();
653 470 this.get_cell(sindex).unselect();
654 471 };
655 472 var cell = this.get_cell(index);
656 473 cell.select();
657 474 if (cell.cell_type === 'heading') {
658 475 $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
659 476 {'cell_type':cell.cell_type,level:cell.level}
660 477 );
661 478 } else {
662 479 $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
663 480 {'cell_type':cell.cell_type}
664 481 );
665 482 };
666 483 };
667 484 return this;
668 485 };
669 486
670 487 /**
671 488 * Programmatically select the next cell.
672 489 *
673 490 * @method select_next
674 491 * @return {Notebook} This notebook
675 492 */
676 493 Notebook.prototype.select_next = function () {
677 494 var index = this.get_selected_index();
678 495 this.select(index+1);
679 496 return this;
680 497 };
681 498
682 499 /**
683 500 * Programmatically select the previous cell.
684 501 *
685 502 * @method select_prev
686 503 * @return {Notebook} This notebook
687 504 */
688 505 Notebook.prototype.select_prev = function () {
689 506 var index = this.get_selected_index();
690 507 this.select(index-1);
691 508 return this;
692 509 };
693 510
694 511
512 // Edit/Command mode
513
514 Notebook.prototype.get_edit_index = function () {
515 var result = null;
516 this.get_cell_elements().filter(function (index) {
517 if ($(this).data("cell").mode === 'edit') {
518 result = index;
519 };
520 });
521 return result;
522 };
523
524 Notebook.prototype.command_mode = function () {
525 if (this.mode !== 'command') {
526 var index = this.get_edit_index();
527 var cell = this.get_cell(index);
528 if (cell) {
529 cell.command_mode();
530 };
531 this.mode = 'command';
532 IPython.keyboard_manager.command_mode();
533 };
534 };
535
536 Notebook.prototype.edit_mode = function () {
537 if (this.mode !== 'edit') {
538 var cell = this.get_selected_cell();
539 if (cell === null) {return;} // No cell is selected
540 // We need to set the mode to edit to prevent reentering this method
541 // when cell.edit_mode() is called below.
542 this.mode = 'edit';
543 IPython.keyboard_manager.edit_mode();
544 cell.edit_mode();
545 };
546 };
547
548 Notebook.prototype.focus_cell = function () {
549 var cell = this.get_selected_cell();
550 if (cell === null) {return;} // No cell is selected
551 cell.focus_cell();
552 };
553
695 554 // Cell movement
696 555
697 556 /**
698 557 * Move given (or selected) cell up and select it.
699 558 *
700 559 * @method move_cell_up
701 560 * @param [index] {integer} cell index
702 561 * @return {Notebook} This notebook
703 562 **/
704 563 Notebook.prototype.move_cell_up = function (index) {
705 564 var i = this.index_or_selected(index);
706 565 if (this.is_valid_cell_index(i) && i > 0) {
707 566 var pivot = this.get_cell_element(i-1);
708 567 var tomove = this.get_cell_element(i);
709 568 if (pivot !== null && tomove !== null) {
710 569 tomove.detach();
711 570 pivot.before(tomove);
712 571 this.select(i-1);
572 var cell = this.get_selected_cell();
573 cell.focus_cell();
713 574 };
714 575 this.set_dirty(true);
715 576 };
716 577 return this;
717 578 };
718 579
719 580
720 581 /**
721 582 * Move given (or selected) cell down and select it
722 583 *
723 584 * @method move_cell_down
724 585 * @param [index] {integer} cell index
725 586 * @return {Notebook} This notebook
726 587 **/
727 588 Notebook.prototype.move_cell_down = function (index) {
728 589 var i = this.index_or_selected(index);
729 if ( this.is_valid_cell_index(i) && this.is_valid_cell_index(i+1)) {
590 if (this.is_valid_cell_index(i) && this.is_valid_cell_index(i+1)) {
730 591 var pivot = this.get_cell_element(i+1);
731 592 var tomove = this.get_cell_element(i);
732 593 if (pivot !== null && tomove !== null) {
733 594 tomove.detach();
734 595 pivot.after(tomove);
735 596 this.select(i+1);
597 var cell = this.get_selected_cell();
598 cell.focus_cell();
736 599 };
737 600 };
738 601 this.set_dirty();
739 602 return this;
740 603 };
741 604
742 605
743 606 // Insertion, deletion.
744 607
745 608 /**
746 609 * Delete a cell from the notebook.
747 610 *
748 611 * @method delete_cell
749 612 * @param [index] A cell's numeric index
750 613 * @return {Notebook} This notebook
751 614 */
752 615 Notebook.prototype.delete_cell = function (index) {
753 616 var i = this.index_or_selected(index);
754 617 var cell = this.get_selected_cell();
755 618 this.undelete_backup = cell.toJSON();
756 619 $('#undelete_cell').removeClass('disabled');
757 620 if (this.is_valid_cell_index(i)) {
621 var old_ncells = this.ncells();
758 622 var ce = this.get_cell_element(i);
759 623 ce.remove();
760 if (i === (this.ncells())) {
624 if (i === 0) {
625 // Always make sure we have at least one cell.
626 if (old_ncells === 1) {
627 this.insert_cell_below('code');
628 }
629 this.select(0);
630 this.undelete_index = 0;
631 this.undelete_below = false;
632 } else if (i === old_ncells-1 && i !== 0) {
761 633 this.select(i-1);
762 634 this.undelete_index = i - 1;
763 635 this.undelete_below = true;
764 636 } else {
765 637 this.select(i);
766 638 this.undelete_index = i;
767 639 this.undelete_below = false;
768 640 };
769 641 $([IPython.events]).trigger('delete.Cell', {'cell': cell, 'index': i});
770 642 this.set_dirty(true);
771 643 };
772 644 return this;
773 645 };
774 646
775 647 /**
648 * Restore the most recently deleted cell.
649 *
650 * @method undelete
651 */
652 Notebook.prototype.undelete_cell = function() {
653 if (this.undelete_backup !== null && this.undelete_index !== null) {
654 var current_index = this.get_selected_index();
655 if (this.undelete_index < current_index) {
656 current_index = current_index + 1;
657 }
658 if (this.undelete_index >= this.ncells()) {
659 this.select(this.ncells() - 1);
660 }
661 else {
662 this.select(this.undelete_index);
663 }
664 var cell_data = this.undelete_backup;
665 var new_cell = null;
666 if (this.undelete_below) {
667 new_cell = this.insert_cell_below(cell_data.cell_type);
668 } else {
669 new_cell = this.insert_cell_above(cell_data.cell_type);
670 }
671 new_cell.fromJSON(cell_data);
672 if (this.undelete_below) {
673 this.select(current_index+1);
674 } else {
675 this.select(current_index);
676 }
677 this.undelete_backup = null;
678 this.undelete_index = null;
679 }
680 $('#undelete_cell').addClass('disabled');
681 }
682
683 /**
776 684 * Insert a cell so that after insertion the cell is at given index.
777 685 *
778 686 * Similar to insert_above, but index parameter is mandatory
779 687 *
780 688 * Index will be brought back into the accissible range [0,n]
781 689 *
782 690 * @method insert_cell_at_index
783 691 * @param type {string} in ['code','markdown','heading']
784 692 * @param [index] {int} a valid index where to inser cell
785 693 *
786 694 * @return cell {cell|null} created cell or null
787 695 **/
788 696 Notebook.prototype.insert_cell_at_index = function(type, index){
789 697
790 698 var ncells = this.ncells();
791 699 var index = Math.min(index,ncells);
792 700 index = Math.max(index,0);
793 701 var cell = null;
794 702
795 703 if (ncells === 0 || this.is_valid_cell_index(index) || index === ncells) {
796 704 if (type === 'code') {
797 705 cell = new IPython.CodeCell(this.kernel);
798 706 cell.set_input_prompt();
799 707 } else if (type === 'markdown') {
800 708 cell = new IPython.MarkdownCell();
801 709 } else if (type === 'raw') {
802 710 cell = new IPython.RawCell();
803 711 } else if (type === 'heading') {
804 712 cell = new IPython.HeadingCell();
805 713 }
806 714
807 if(this._insert_element_at_index(cell.element,index)){
715 if(this._insert_element_at_index(cell.element,index)) {
808 716 cell.render();
809 this.select(this.find_cell_index(cell));
810 717 $([IPython.events]).trigger('create.Cell', {'cell': cell, 'index': index});
718 cell.refresh();
719 // We used to select the cell after we refresh it, but there
720 // are now cases were this method is called where select is
721 // not appropriate. The selection logic should be handled by the
722 // caller of the the top level insert_cell methods.
811 723 this.set_dirty(true);
812 724 }
813 725 }
814 726 return cell;
815 727
816 728 };
817 729
818 730 /**
819 731 * Insert an element at given cell index.
820 732 *
821 733 * @method _insert_element_at_index
822 734 * @param element {dom element} a cell element
823 735 * @param [index] {int} a valid index where to inser cell
824 736 * @private
825 737 *
826 738 * return true if everything whent fine.
827 739 **/
828 740 Notebook.prototype._insert_element_at_index = function(element, index){
829 741 if (element === undefined){
830 742 return false;
831 743 }
832 744
833 745 var ncells = this.ncells();
834 746
835 747 if (ncells === 0) {
836 748 // special case append if empty
837 749 this.element.find('div.end_space').before(element);
838 750 } else if ( ncells === index ) {
839 751 // special case append it the end, but not empty
840 752 this.get_cell_element(index-1).after(element);
841 753 } else if (this.is_valid_cell_index(index)) {
842 754 // otherwise always somewhere to append to
843 755 this.get_cell_element(index).before(element);
844 756 } else {
845 757 return false;
846 758 }
847 759
848 760 if (this.undelete_index !== null && index <= this.undelete_index) {
849 761 this.undelete_index = this.undelete_index + 1;
850 762 this.set_dirty(true);
851 763 }
852 764 return true;
853 765 };
854 766
855 767 /**
856 768 * Insert a cell of given type above given index, or at top
857 769 * of notebook if index smaller than 0.
858 770 *
859 771 * default index value is the one of currently selected cell
860 772 *
861 773 * @method insert_cell_above
862 774 * @param type {string} cell type
863 775 * @param [index] {integer}
864 776 *
865 777 * @return handle to created cell or null
866 778 **/
867 779 Notebook.prototype.insert_cell_above = function (type, index) {
868 780 index = this.index_or_selected(index);
869 781 return this.insert_cell_at_index(type, index);
870 782 };
871 783
872 784 /**
873 785 * Insert a cell of given type below given index, or at bottom
874 786 * of notebook if index greater thatn number of cell
875 787 *
876 788 * default index value is the one of currently selected cell
877 789 *
878 790 * @method insert_cell_below
879 791 * @param type {string} cell type
880 792 * @param [index] {integer}
881 793 *
882 794 * @return handle to created cell or null
883 795 *
884 796 **/
885 797 Notebook.prototype.insert_cell_below = function (type, index) {
886 798 index = this.index_or_selected(index);
887 799 return this.insert_cell_at_index(type, index+1);
888 800 };
889 801
890 802
891 803 /**
892 804 * Insert cell at end of notebook
893 805 *
894 806 * @method insert_cell_at_bottom
895 807 * @param {String} type cell type
896 808 *
897 809 * @return the added cell; or null
898 810 **/
899 811 Notebook.prototype.insert_cell_at_bottom = function (type){
900 812 var len = this.ncells();
901 813 return this.insert_cell_below(type,len-1);
902 814 };
903 815
904 816 /**
905 817 * Turn a cell into a code cell.
906 818 *
907 819 * @method to_code
908 820 * @param {Number} [index] A cell's index
909 821 */
910 822 Notebook.prototype.to_code = function (index) {
911 823 var i = this.index_or_selected(index);
912 824 if (this.is_valid_cell_index(i)) {
913 825 var source_element = this.get_cell_element(i);
914 826 var source_cell = source_element.data("cell");
915 827 if (!(source_cell instanceof IPython.CodeCell)) {
916 828 var target_cell = this.insert_cell_below('code',i);
917 829 var text = source_cell.get_text();
918 830 if (text === source_cell.placeholder) {
919 831 text = '';
920 832 }
921 833 target_cell.set_text(text);
922 834 // make this value the starting point, so that we can only undo
923 835 // to this state, instead of a blank cell
924 836 target_cell.code_mirror.clearHistory();
925 837 source_element.remove();
838 this.select(i);
839 this.edit_mode();
926 840 this.set_dirty(true);
927 841 };
928 842 };
929 843 };
930 844
931 845 /**
932 846 * Turn a cell into a Markdown cell.
933 847 *
934 848 * @method to_markdown
935 849 * @param {Number} [index] A cell's index
936 850 */
937 851 Notebook.prototype.to_markdown = function (index) {
938 852 var i = this.index_or_selected(index);
939 853 if (this.is_valid_cell_index(i)) {
940 854 var source_element = this.get_cell_element(i);
941 855 var source_cell = source_element.data("cell");
942 856 if (!(source_cell instanceof IPython.MarkdownCell)) {
943 857 var target_cell = this.insert_cell_below('markdown',i);
944 858 var text = source_cell.get_text();
945 859 if (text === source_cell.placeholder) {
946 860 text = '';
947 861 };
948 // The edit must come before the set_text.
949 target_cell.edit();
862 // We must show the editor before setting its contents
863 target_cell.unrender();
950 864 target_cell.set_text(text);
951 865 // make this value the starting point, so that we can only undo
952 866 // to this state, instead of a blank cell
953 867 target_cell.code_mirror.clearHistory();
954 868 source_element.remove();
869 this.select(i);
870 this.edit_mode();
955 871 this.set_dirty(true);
956 872 };
957 873 };
958 874 };
959 875
960 876 /**
961 877 * Turn a cell into a raw text cell.
962 878 *
963 879 * @method to_raw
964 880 * @param {Number} [index] A cell's index
965 881 */
966 882 Notebook.prototype.to_raw = function (index) {
967 883 var i = this.index_or_selected(index);
968 884 if (this.is_valid_cell_index(i)) {
969 885 var source_element = this.get_cell_element(i);
970 886 var source_cell = source_element.data("cell");
971 887 var target_cell = null;
972 888 if (!(source_cell instanceof IPython.RawCell)) {
973 889 target_cell = this.insert_cell_below('raw',i);
974 890 var text = source_cell.get_text();
975 891 if (text === source_cell.placeholder) {
976 892 text = '';
977 893 };
978 // The edit must come before the set_text.
979 target_cell.edit();
894 // We must show the editor before setting its contents
895 target_cell.unrender();
980 896 target_cell.set_text(text);
981 897 // make this value the starting point, so that we can only undo
982 898 // to this state, instead of a blank cell
983 899 target_cell.code_mirror.clearHistory();
984 900 source_element.remove();
901 this.select(i);
902 this.edit_mode();
985 903 this.set_dirty(true);
986 904 };
987 905 };
988 906 };
989 907
990 908 /**
991 909 * Turn a cell into a heading cell.
992 910 *
993 911 * @method to_heading
994 912 * @param {Number} [index] A cell's index
995 913 * @param {Number} [level] A heading level (e.g., 1 becomes &lt;h1&gt;)
996 914 */
997 915 Notebook.prototype.to_heading = function (index, level) {
998 916 level = level || 1;
999 917 var i = this.index_or_selected(index);
1000 918 if (this.is_valid_cell_index(i)) {
1001 919 var source_element = this.get_cell_element(i);
1002 920 var source_cell = source_element.data("cell");
1003 921 var target_cell = null;
1004 922 if (source_cell instanceof IPython.HeadingCell) {
1005 923 source_cell.set_level(level);
1006 924 } else {
1007 925 target_cell = this.insert_cell_below('heading',i);
1008 926 var text = source_cell.get_text();
1009 927 if (text === source_cell.placeholder) {
1010 928 text = '';
1011 929 };
1012 // The edit must come before the set_text.
930 // We must show the editor before setting its contents
1013 931 target_cell.set_level(level);
1014 target_cell.edit();
932 target_cell.unrender();
1015 933 target_cell.set_text(text);
1016 934 // make this value the starting point, so that we can only undo
1017 935 // to this state, instead of a blank cell
1018 936 target_cell.code_mirror.clearHistory();
1019 937 source_element.remove();
1020 this.set_dirty(true);
938 this.select(i);
1021 939 };
940 this.edit_mode();
941 this.set_dirty(true);
1022 942 $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
1023 943 {'cell_type':'heading',level:level}
1024 944 );
1025 945 };
1026 946 };
1027 947
1028 948
1029 949 // Cut/Copy/Paste
1030 950
1031 951 /**
1032 952 * Enable UI elements for pasting cells.
1033 953 *
1034 954 * @method enable_paste
1035 955 */
1036 956 Notebook.prototype.enable_paste = function () {
1037 957 var that = this;
1038 958 if (!this.paste_enabled) {
1039 959 $('#paste_cell_replace').removeClass('disabled')
1040 960 .on('click', function () {that.paste_cell_replace();});
1041 961 $('#paste_cell_above').removeClass('disabled')
1042 962 .on('click', function () {that.paste_cell_above();});
1043 963 $('#paste_cell_below').removeClass('disabled')
1044 964 .on('click', function () {that.paste_cell_below();});
1045 965 this.paste_enabled = true;
1046 966 };
1047 967 };
1048 968
1049 969 /**
1050 970 * Disable UI elements for pasting cells.
1051 971 *
1052 972 * @method disable_paste
1053 973 */
1054 974 Notebook.prototype.disable_paste = function () {
1055 975 if (this.paste_enabled) {
1056 976 $('#paste_cell_replace').addClass('disabled').off('click');
1057 977 $('#paste_cell_above').addClass('disabled').off('click');
1058 978 $('#paste_cell_below').addClass('disabled').off('click');
1059 979 this.paste_enabled = false;
1060 980 };
1061 981 };
1062 982
1063 983 /**
1064 984 * Cut a cell.
1065 985 *
1066 986 * @method cut_cell
1067 987 */
1068 988 Notebook.prototype.cut_cell = function () {
1069 989 this.copy_cell();
1070 990 this.delete_cell();
1071 991 }
1072 992
1073 993 /**
1074 994 * Copy a cell.
1075 995 *
1076 996 * @method copy_cell
1077 997 */
1078 998 Notebook.prototype.copy_cell = function () {
1079 999 var cell = this.get_selected_cell();
1080 1000 this.clipboard = cell.toJSON();
1081 1001 this.enable_paste();
1082 1002 };
1083 1003
1084 1004 /**
1085 1005 * Replace the selected cell with a cell in the clipboard.
1086 1006 *
1087 1007 * @method paste_cell_replace
1088 1008 */
1089 1009 Notebook.prototype.paste_cell_replace = function () {
1090 1010 if (this.clipboard !== null && this.paste_enabled) {
1091 1011 var cell_data = this.clipboard;
1092 1012 var new_cell = this.insert_cell_above(cell_data.cell_type);
1093 1013 new_cell.fromJSON(cell_data);
1094 1014 var old_cell = this.get_next_cell(new_cell);
1095 1015 this.delete_cell(this.find_cell_index(old_cell));
1096 1016 this.select(this.find_cell_index(new_cell));
1097 1017 };
1098 1018 };
1099 1019
1100 1020 /**
1101 1021 * Paste a cell from the clipboard above the selected cell.
1102 1022 *
1103 1023 * @method paste_cell_above
1104 1024 */
1105 1025 Notebook.prototype.paste_cell_above = function () {
1106 1026 if (this.clipboard !== null && this.paste_enabled) {
1107 1027 var cell_data = this.clipboard;
1108 1028 var new_cell = this.insert_cell_above(cell_data.cell_type);
1109 1029 new_cell.fromJSON(cell_data);
1110 1030 };
1111 1031 };
1112 1032
1113 1033 /**
1114 1034 * Paste a cell from the clipboard below the selected cell.
1115 1035 *
1116 1036 * @method paste_cell_below
1117 1037 */
1118 1038 Notebook.prototype.paste_cell_below = function () {
1119 1039 if (this.clipboard !== null && this.paste_enabled) {
1120 1040 var cell_data = this.clipboard;
1121 1041 var new_cell = this.insert_cell_below(cell_data.cell_type);
1122 1042 new_cell.fromJSON(cell_data);
1123 1043 };
1124 1044 };
1125 1045
1126 // Cell undelete
1127
1128 /**
1129 * Restore the most recently deleted cell.
1130 *
1131 * @method undelete
1132 */
1133 Notebook.prototype.undelete = function() {
1134 if (this.undelete_backup !== null && this.undelete_index !== null) {
1135 var current_index = this.get_selected_index();
1136 if (this.undelete_index < current_index) {
1137 current_index = current_index + 1;
1138 }
1139 if (this.undelete_index >= this.ncells()) {
1140 this.select(this.ncells() - 1);
1141 }
1142 else {
1143 this.select(this.undelete_index);
1144 }
1145 var cell_data = this.undelete_backup;
1146 var new_cell = null;
1147 if (this.undelete_below) {
1148 new_cell = this.insert_cell_below(cell_data.cell_type);
1149 } else {
1150 new_cell = this.insert_cell_above(cell_data.cell_type);
1151 }
1152 new_cell.fromJSON(cell_data);
1153 this.select(current_index);
1154 this.undelete_backup = null;
1155 this.undelete_index = null;
1156 }
1157 $('#undelete_cell').addClass('disabled');
1158 }
1159
1160 1046 // Split/merge
1161 1047
1162 1048 /**
1163 1049 * Split the selected cell into two, at the cursor.
1164 1050 *
1165 1051 * @method split_cell
1166 1052 */
1167 1053 Notebook.prototype.split_cell = function () {
1168 // Todo: implement spliting for other cell types.
1054 var mdc = IPython.MarkdownCell;
1055 var rc = IPython.RawCell;
1169 1056 var cell = this.get_selected_cell();
1170 1057 if (cell.is_splittable()) {
1171 1058 var texta = cell.get_pre_cursor();
1172 1059 var textb = cell.get_post_cursor();
1173 1060 if (cell instanceof IPython.CodeCell) {
1061 // In this case the operations keep the notebook in its existing mode
1062 // so we don't need to do any post-op mode changes.
1174 1063 cell.set_text(textb);
1175 1064 var new_cell = this.insert_cell_above('code');
1176 1065 new_cell.set_text(texta);
1177 this.select_next();
1178 } else if (cell instanceof IPython.MarkdownCell) {
1066 } else if ((cell instanceof mdc && !cell.rendered) || (cell instanceof rc)) {
1067 // We know cell is !rendered so we can use set_text.
1179 1068 cell.set_text(textb);
1180 cell.render();
1181 var new_cell = this.insert_cell_above('markdown');
1182 new_cell.edit(); // editor must be visible to call set_text
1069 var new_cell = this.insert_cell_above(cell.cell_type);
1070 // Unrender the new cell so we can call set_text.
1071 new_cell.unrender();
1183 1072 new_cell.set_text(texta);
1184 new_cell.render();
1185 this.select_next();
1186 1073 }
1187 1074 };
1188 1075 };
1189 1076
1190 1077 /**
1191 1078 * Combine the selected cell into the cell above it.
1192 1079 *
1193 1080 * @method merge_cell_above
1194 1081 */
1195 1082 Notebook.prototype.merge_cell_above = function () {
1083 var mdc = IPython.MarkdownCell;
1084 var rc = IPython.RawCell;
1196 1085 var index = this.get_selected_index();
1197 1086 var cell = this.get_cell(index);
1087 var render = cell.rendered;
1198 1088 if (!cell.is_mergeable()) {
1199 1089 return;
1200 1090 }
1201 1091 if (index > 0) {
1202 1092 var upper_cell = this.get_cell(index-1);
1203 1093 if (!upper_cell.is_mergeable()) {
1204 1094 return;
1205 1095 }
1206 1096 var upper_text = upper_cell.get_text();
1207 1097 var text = cell.get_text();
1208 1098 if (cell instanceof IPython.CodeCell) {
1209 1099 cell.set_text(upper_text+'\n'+text);
1210 } else if (cell instanceof IPython.MarkdownCell) {
1211 cell.edit();
1212 cell.set_text(upper_text+'\n'+text);
1213 cell.render();
1100 } else if ((cell instanceof mdc) || (cell instanceof rc)) {
1101 cell.unrender(); // Must unrender before we set_text.
1102 cell.set_text(upper_text+'\n\n'+text);
1103 if (render) {
1104 // The rendered state of the final cell should match
1105 // that of the original selected cell;
1106 cell.render();
1107 }
1214 1108 };
1215 1109 this.delete_cell(index-1);
1216 1110 this.select(this.find_cell_index(cell));
1217 1111 };
1218 1112 };
1219 1113
1220 1114 /**
1221 1115 * Combine the selected cell into the cell below it.
1222 1116 *
1223 1117 * @method merge_cell_below
1224 1118 */
1225 1119 Notebook.prototype.merge_cell_below = function () {
1120 var mdc = IPython.MarkdownCell;
1121 var rc = IPython.RawCell;
1226 1122 var index = this.get_selected_index();
1227 1123 var cell = this.get_cell(index);
1124 var render = cell.rendered;
1228 1125 if (!cell.is_mergeable()) {
1229 1126 return;
1230 1127 }
1231 1128 if (index < this.ncells()-1) {
1232 1129 var lower_cell = this.get_cell(index+1);
1233 1130 if (!lower_cell.is_mergeable()) {
1234 1131 return;
1235 1132 }
1236 1133 var lower_text = lower_cell.get_text();
1237 1134 var text = cell.get_text();
1238 1135 if (cell instanceof IPython.CodeCell) {
1239 1136 cell.set_text(text+'\n'+lower_text);
1240 } else if (cell instanceof IPython.MarkdownCell) {
1241 cell.edit();
1242 cell.set_text(text+'\n'+lower_text);
1243 cell.render();
1137 } else if ((cell instanceof mdc) || (cell instanceof rc)) {
1138 cell.unrender(); // Must unrender before we set_text.
1139 cell.set_text(text+'\n\n'+lower_text);
1140 if (render) {
1141 // The rendered state of the final cell should match
1142 // that of the original selected cell;
1143 cell.render();
1144 }
1244 1145 };
1245 1146 this.delete_cell(index+1);
1246 1147 this.select(this.find_cell_index(cell));
1247 1148 };
1248 1149 };
1249 1150
1250 1151
1251 1152 // Cell collapsing and output clearing
1252 1153
1253 1154 /**
1254 1155 * Hide a cell's output.
1255 1156 *
1256 1157 * @method collapse
1257 1158 * @param {Number} index A cell's numeric index
1258 1159 */
1259 1160 Notebook.prototype.collapse = function (index) {
1260 1161 var i = this.index_or_selected(index);
1261 1162 this.get_cell(i).collapse();
1262 1163 this.set_dirty(true);
1263 1164 };
1264 1165
1265 1166 /**
1266 1167 * Show a cell's output.
1267 1168 *
1268 1169 * @method expand
1269 1170 * @param {Number} index A cell's numeric index
1270 1171 */
1271 1172 Notebook.prototype.expand = function (index) {
1272 1173 var i = this.index_or_selected(index);
1273 1174 this.get_cell(i).expand();
1274 1175 this.set_dirty(true);
1275 1176 };
1276 1177
1277 1178 /** Toggle whether a cell's output is collapsed or expanded.
1278 1179 *
1279 1180 * @method toggle_output
1280 1181 * @param {Number} index A cell's numeric index
1281 1182 */
1282 1183 Notebook.prototype.toggle_output = function (index) {
1283 1184 var i = this.index_or_selected(index);
1284 1185 this.get_cell(i).toggle_output();
1285 1186 this.set_dirty(true);
1286 1187 };
1287 1188
1288 1189 /**
1289 1190 * Toggle a scrollbar for long cell outputs.
1290 1191 *
1291 1192 * @method toggle_output_scroll
1292 1193 * @param {Number} index A cell's numeric index
1293 1194 */
1294 1195 Notebook.prototype.toggle_output_scroll = function (index) {
1295 1196 var i = this.index_or_selected(index);
1296 1197 this.get_cell(i).toggle_output_scroll();
1297 1198 };
1298 1199
1299 1200 /**
1300 1201 * Hide each code cell's output area.
1301 1202 *
1302 1203 * @method collapse_all_output
1303 1204 */
1304 1205 Notebook.prototype.collapse_all_output = function () {
1305 1206 var ncells = this.ncells();
1306 1207 var cells = this.get_cells();
1307 1208 for (var i=0; i<ncells; i++) {
1308 1209 if (cells[i] instanceof IPython.CodeCell) {
1309 1210 cells[i].output_area.collapse();
1310 1211 }
1311 1212 };
1312 1213 // this should not be set if the `collapse` key is removed from nbformat
1313 1214 this.set_dirty(true);
1314 1215 };
1315 1216
1316 1217 /**
1317 1218 * Expand each code cell's output area, and add a scrollbar for long output.
1318 1219 *
1319 1220 * @method scroll_all_output
1320 1221 */
1321 1222 Notebook.prototype.scroll_all_output = function () {
1322 1223 var ncells = this.ncells();
1323 1224 var cells = this.get_cells();
1324 1225 for (var i=0; i<ncells; i++) {
1325 1226 if (cells[i] instanceof IPython.CodeCell) {
1326 1227 cells[i].output_area.expand();
1327 1228 cells[i].output_area.scroll_if_long();
1328 1229 }
1329 1230 };
1330 1231 // this should not be set if the `collapse` key is removed from nbformat
1331 1232 this.set_dirty(true);
1332 1233 };
1333 1234
1334 1235 /**
1335 1236 * Expand each code cell's output area, and remove scrollbars.
1336 1237 *
1337 1238 * @method expand_all_output
1338 1239 */
1339 1240 Notebook.prototype.expand_all_output = function () {
1340 1241 var ncells = this.ncells();
1341 1242 var cells = this.get_cells();
1342 1243 for (var i=0; i<ncells; i++) {
1343 1244 if (cells[i] instanceof IPython.CodeCell) {
1344 1245 cells[i].output_area.expand();
1345 1246 cells[i].output_area.unscroll_area();
1346 1247 }
1347 1248 };
1348 1249 // this should not be set if the `collapse` key is removed from nbformat
1349 1250 this.set_dirty(true);
1350 1251 };
1351 1252
1352 1253 /**
1353 1254 * Clear each code cell's output area.
1354 1255 *
1355 1256 * @method clear_all_output
1356 1257 */
1357 1258 Notebook.prototype.clear_all_output = function () {
1358 1259 var ncells = this.ncells();
1359 1260 var cells = this.get_cells();
1360 1261 for (var i=0; i<ncells; i++) {
1361 1262 if (cells[i] instanceof IPython.CodeCell) {
1362 1263 cells[i].clear_output();
1363 1264 // Make all In[] prompts blank, as well
1364 1265 // TODO: make this configurable (via checkbox?)
1365 1266 cells[i].set_input_prompt();
1366 1267 }
1367 1268 };
1368 1269 this.set_dirty(true);
1369 1270 };
1370 1271
1371 1272
1372 1273 // Other cell functions: line numbers, ...
1373 1274
1374 1275 /**
1375 1276 * Toggle line numbers in the selected cell's input area.
1376 1277 *
1377 1278 * @method cell_toggle_line_numbers
1378 1279 */
1379 1280 Notebook.prototype.cell_toggle_line_numbers = function() {
1380 1281 this.get_selected_cell().toggle_line_numbers();
1381 1282 };
1382 1283
1383 1284 // Session related things
1384 1285
1385 1286 /**
1386 1287 * Start a new session and set it on each code cell.
1387 1288 *
1388 1289 * @method start_session
1389 1290 */
1390 1291 Notebook.prototype.start_session = function () {
1391 1292 this.session = new IPython.Session(this.notebook_name, this.notebook_path, this);
1392 1293 this.session.start($.proxy(this._session_started, this));
1393 1294 };
1394 1295
1395 1296
1396 1297 /**
1397 1298 * Once a session is started, link the code cells to the kernel
1398 1299 *
1399 1300 */
1400 1301 Notebook.prototype._session_started = function(){
1401 1302 this.kernel = this.session.kernel;
1402 1303 var ncells = this.ncells();
1403 1304 for (var i=0; i<ncells; i++) {
1404 1305 var cell = this.get_cell(i);
1405 1306 if (cell instanceof IPython.CodeCell) {
1406 1307 cell.set_kernel(this.session.kernel);
1407 1308 };
1408 1309 };
1409 1310 };
1410 1311
1411 1312 /**
1412 1313 * Prompt the user to restart the IPython kernel.
1413 1314 *
1414 1315 * @method restart_kernel
1415 1316 */
1416 1317 Notebook.prototype.restart_kernel = function () {
1417 1318 var that = this;
1418 1319 IPython.dialog.modal({
1419 1320 title : "Restart kernel or continue running?",
1420 1321 body : $("<p/>").html(
1421 1322 'Do you want to restart the current kernel? You will lose all variables defined in it.'
1422 1323 ),
1423 1324 buttons : {
1424 1325 "Continue running" : {},
1425 1326 "Restart" : {
1426 1327 "class" : "btn-danger",
1427 1328 "click" : function() {
1428 1329 that.session.restart_kernel();
1429 1330 }
1430 1331 }
1431 1332 }
1432 1333 });
1433 1334 };
1434 1335
1435 1336 /**
1436 * Run the selected cell.
1337 * Execute or render cell outputs and go into command mode.
1437 1338 *
1438 * Execute or render cell outputs.
1339 * @method execute_cell
1340 */
1341 Notebook.prototype.execute_cell = function () {
1342 // mode = shift, ctrl, alt
1343 var cell = this.get_selected_cell();
1344 var cell_index = this.find_cell_index(cell);
1345
1346 cell.execute();
1347 this.command_mode();
1348 cell.focus_cell();
1349 this.set_dirty(true);
1350 }
1351
1352 /**
1353 * Execute or render cell outputs and insert a new cell below.
1439 1354 *
1440 * @method execute_selected_cell
1441 * @param {Object} options Customize post-execution behavior
1355 * @method execute_cell_and_insert_below
1442 1356 */
1443 Notebook.prototype.execute_selected_cell = function (options) {
1444 // add_new: should a new cell be added if we are at the end of the nb
1445 // terminal: execute in terminal mode, which stays in the current cell
1446 var default_options = {terminal: false, add_new: true};
1447 $.extend(default_options, options);
1448 var that = this;
1449 var cell = that.get_selected_cell();
1450 var cell_index = that.find_cell_index(cell);
1451 if (cell instanceof IPython.CodeCell) {
1452 cell.execute();
1357 Notebook.prototype.execute_cell_and_insert_below = function () {
1358 var cell = this.get_selected_cell();
1359 var cell_index = this.find_cell_index(cell);
1360
1361 cell.execute();
1362
1363 // If we are at the end always insert a new cell and return
1364 if (cell_index === (this.ncells()-1)) {
1365 this.insert_cell_below('code');
1366 this.select(cell_index+1);
1367 this.edit_mode();
1368 this.scroll_to_bottom();
1369 this.set_dirty(true);
1370 return;
1453 1371 }
1454 if (default_options.terminal) {
1455 cell.select_all();
1456 } else {
1457 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
1458 that.insert_cell_below('code');
1459 // If we are adding a new cell at the end, scroll down to show it.
1460 that.scroll_to_bottom();
1461 } else {
1462 that.select(cell_index+1);
1463 };
1464 };
1372
1373 // Only insert a new cell, if we ended up in an already populated cell
1374 var next_text = this.get_cell(cell_index+1).get_text();
1375 if (/\S/.test(next_text) === true) {
1376 this.insert_cell_below('code');
1377 }
1378 this.select(cell_index+1);
1379 this.edit_mode();
1380 this.set_dirty(true);
1381 };
1382
1383 /**
1384 * Execute or render cell outputs and select the next cell.
1385 *
1386 * @method execute_cell_and_select_below
1387 */
1388 Notebook.prototype.execute_cell_and_select_below = function () {
1389
1390 var cell = this.get_selected_cell();
1391 var cell_index = this.find_cell_index(cell);
1392
1393 cell.execute();
1394
1395 // If we are at the end always insert a new cell and return
1396 if (cell_index === (this.ncells()-1)) {
1397 this.insert_cell_below('code');
1398 this.select(cell_index+1);
1399 this.edit_mode();
1400 this.scroll_to_bottom();
1401 this.set_dirty(true);
1402 return;
1403 }
1404
1405 this.select(cell_index+1);
1406 this.get_cell(cell_index+1).focus_cell();
1465 1407 this.set_dirty(true);
1466 1408 };
1467 1409
1468 1410 /**
1469 1411 * Execute all cells below the selected cell.
1470 1412 *
1471 1413 * @method execute_cells_below
1472 1414 */
1473 1415 Notebook.prototype.execute_cells_below = function () {
1474 1416 this.execute_cell_range(this.get_selected_index(), this.ncells());
1475 1417 this.scroll_to_bottom();
1476 1418 };
1477 1419
1478 1420 /**
1479 1421 * Execute all cells above the selected cell.
1480 1422 *
1481 1423 * @method execute_cells_above
1482 1424 */
1483 1425 Notebook.prototype.execute_cells_above = function () {
1484 1426 this.execute_cell_range(0, this.get_selected_index());
1485 1427 };
1486 1428
1487 1429 /**
1488 1430 * Execute all cells.
1489 1431 *
1490 1432 * @method execute_all_cells
1491 1433 */
1492 1434 Notebook.prototype.execute_all_cells = function () {
1493 1435 this.execute_cell_range(0, this.ncells());
1494 1436 this.scroll_to_bottom();
1495 1437 };
1496 1438
1497 1439 /**
1498 1440 * Execute a contiguous range of cells.
1499 1441 *
1500 1442 * @method execute_cell_range
1501 1443 * @param {Number} start Index of the first cell to execute (inclusive)
1502 1444 * @param {Number} end Index of the last cell to execute (exclusive)
1503 1445 */
1504 1446 Notebook.prototype.execute_cell_range = function (start, end) {
1505 1447 for (var i=start; i<end; i++) {
1506 1448 this.select(i);
1507 this.execute_selected_cell({add_new:false});
1449 this.execute_cell();
1508 1450 };
1509 1451 };
1510 1452
1511 1453 // Persistance and loading
1512 1454
1513 1455 /**
1514 1456 * Getter method for this notebook's name.
1515 1457 *
1516 1458 * @method get_notebook_name
1517 1459 * @return {String} This notebook's name
1518 1460 */
1519 1461 Notebook.prototype.get_notebook_name = function () {
1520 1462 var nbname = this.notebook_name.substring(0,this.notebook_name.length-6);
1521 1463 return nbname;
1522 1464 };
1523 1465
1524 1466 /**
1525 1467 * Setter method for this notebook's name.
1526 1468 *
1527 1469 * @method set_notebook_name
1528 1470 * @param {String} name A new name for this notebook
1529 1471 */
1530 1472 Notebook.prototype.set_notebook_name = function (name) {
1531 1473 this.notebook_name = name;
1532 1474 };
1533 1475
1534 1476 /**
1535 1477 * Check that a notebook's name is valid.
1536 1478 *
1537 1479 * @method test_notebook_name
1538 1480 * @param {String} nbname A name for this notebook
1539 1481 * @return {Boolean} True if the name is valid, false if invalid
1540 1482 */
1541 1483 Notebook.prototype.test_notebook_name = function (nbname) {
1542 1484 nbname = nbname || '';
1543 1485 if (this.notebook_name_blacklist_re.test(nbname) == false && nbname.length>0) {
1544 1486 return true;
1545 1487 } else {
1546 1488 return false;
1547 1489 };
1548 1490 };
1549 1491
1550 1492 /**
1551 1493 * Load a notebook from JSON (.ipynb).
1552 1494 *
1553 1495 * This currently handles one worksheet: others are deleted.
1554 1496 *
1555 1497 * @method fromJSON
1556 1498 * @param {Object} data JSON representation of a notebook
1557 1499 */
1558 1500 Notebook.prototype.fromJSON = function (data) {
1559 1501 var content = data.content;
1560 1502 var ncells = this.ncells();
1561 1503 var i;
1562 1504 for (i=0; i<ncells; i++) {
1563 1505 // Always delete cell 0 as they get renumbered as they are deleted.
1564 1506 this.delete_cell(0);
1565 1507 };
1566 1508 // Save the metadata and name.
1567 1509 this.metadata = content.metadata;
1568 1510 this.notebook_name = data.name;
1569 1511 // Only handle 1 worksheet for now.
1570 1512 var worksheet = content.worksheets[0];
1571 1513 if (worksheet !== undefined) {
1572 1514 if (worksheet.metadata) {
1573 1515 this.worksheet_metadata = worksheet.metadata;
1574 1516 }
1575 1517 var new_cells = worksheet.cells;
1576 1518 ncells = new_cells.length;
1577 1519 var cell_data = null;
1578 1520 var new_cell = null;
1579 1521 for (i=0; i<ncells; i++) {
1580 1522 cell_data = new_cells[i];
1581 1523 // VERSIONHACK: plaintext -> raw
1582 1524 // handle never-released plaintext name for raw cells
1583 1525 if (cell_data.cell_type === 'plaintext'){
1584 1526 cell_data.cell_type = 'raw';
1585 1527 }
1586 1528
1587 new_cell = this.insert_cell_at_bottom(cell_data.cell_type);
1529 new_cell = this.insert_cell_at_index(cell_data.cell_type, i);
1588 1530 new_cell.fromJSON(cell_data);
1589 1531 };
1590 1532 };
1591 1533 if (content.worksheets.length > 1) {
1592 1534 IPython.dialog.modal({
1593 1535 title : "Multiple worksheets",
1594 1536 body : "This notebook has " + data.worksheets.length + " worksheets, " +
1595 1537 "but this version of IPython can only handle the first. " +
1596 1538 "If you save this notebook, worksheets after the first will be lost.",
1597 1539 buttons : {
1598 1540 OK : {
1599 1541 class : "btn-danger"
1600 1542 }
1601 1543 }
1602 1544 });
1603 1545 }
1604 1546 };
1605 1547
1606 1548 /**
1607 1549 * Dump this notebook into a JSON-friendly object.
1608 1550 *
1609 1551 * @method toJSON
1610 1552 * @return {Object} A JSON-friendly representation of this notebook.
1611 1553 */
1612 1554 Notebook.prototype.toJSON = function () {
1613 1555 var cells = this.get_cells();
1614 1556 var ncells = cells.length;
1615 1557 var cell_array = new Array(ncells);
1616 1558 for (var i=0; i<ncells; i++) {
1617 1559 cell_array[i] = cells[i].toJSON();
1618 1560 };
1619 1561 var data = {
1620 1562 // Only handle 1 worksheet for now.
1621 1563 worksheets : [{
1622 1564 cells: cell_array,
1623 1565 metadata: this.worksheet_metadata
1624 1566 }],
1625 1567 metadata : this.metadata
1626 1568 };
1627 1569 return data;
1628 1570 };
1629 1571
1630 1572 /**
1631 1573 * Start an autosave timer, for periodically saving the notebook.
1632 1574 *
1633 1575 * @method set_autosave_interval
1634 1576 * @param {Integer} interval the autosave interval in milliseconds
1635 1577 */
1636 1578 Notebook.prototype.set_autosave_interval = function (interval) {
1637 1579 var that = this;
1638 1580 // clear previous interval, so we don't get simultaneous timers
1639 1581 if (this.autosave_timer) {
1640 1582 clearInterval(this.autosave_timer);
1641 1583 }
1642 1584
1643 1585 this.autosave_interval = this.minimum_autosave_interval = interval;
1644 1586 if (interval) {
1645 1587 this.autosave_timer = setInterval(function() {
1646 1588 if (that.dirty) {
1647 1589 that.save_notebook();
1648 1590 }
1649 1591 }, interval);
1650 1592 $([IPython.events]).trigger("autosave_enabled.Notebook", interval);
1651 1593 } else {
1652 1594 this.autosave_timer = null;
1653 1595 $([IPython.events]).trigger("autosave_disabled.Notebook");
1654 1596 };
1655 1597 };
1656 1598
1657 1599 /**
1658 1600 * Save this notebook on the server.
1659 1601 *
1660 1602 * @method save_notebook
1661 1603 */
1662 1604 Notebook.prototype.save_notebook = function (extra_settings) {
1663 1605 // Create a JSON model to be sent to the server.
1664 1606 var model = {};
1665 1607 model.name = this.notebook_name;
1666 1608 model.path = this.notebook_path;
1667 1609 model.content = this.toJSON();
1668 1610 model.content.nbformat = this.nbformat;
1669 1611 model.content.nbformat_minor = this.nbformat_minor;
1670 1612 // time the ajax call for autosave tuning purposes.
1671 1613 var start = new Date().getTime();
1672 1614 // We do the call with settings so we can set cache to false.
1673 1615 var settings = {
1674 1616 processData : false,
1675 1617 cache : false,
1676 1618 type : "PUT",
1677 1619 data : JSON.stringify(model),
1678 1620 headers : {'Content-Type': 'application/json'},
1679 1621 success : $.proxy(this.save_notebook_success, this, start),
1680 1622 error : $.proxy(this.save_notebook_error, this)
1681 1623 };
1682 1624 if (extra_settings) {
1683 1625 for (var key in extra_settings) {
1684 1626 settings[key] = extra_settings[key];
1685 1627 }
1686 1628 }
1687 1629 $([IPython.events]).trigger('notebook_saving.Notebook');
1688 1630 var url = utils.url_join_encode(
1689 1631 this._baseProjectUrl,
1690 1632 'api/notebooks',
1691 1633 this.notebook_path,
1692 1634 this.notebook_name
1693 1635 );
1694 1636 $.ajax(url, settings);
1695 1637 };
1696 1638
1697 1639 /**
1698 1640 * Success callback for saving a notebook.
1699 1641 *
1700 1642 * @method save_notebook_success
1701 1643 * @param {Integer} start the time when the save request started
1702 1644 * @param {Object} data JSON representation of a notebook
1703 1645 * @param {String} status Description of response status
1704 1646 * @param {jqXHR} xhr jQuery Ajax object
1705 1647 */
1706 1648 Notebook.prototype.save_notebook_success = function (start, data, status, xhr) {
1707 1649 this.set_dirty(false);
1708 1650 $([IPython.events]).trigger('notebook_saved.Notebook');
1709 1651 this._update_autosave_interval(start);
1710 1652 if (this._checkpoint_after_save) {
1711 1653 this.create_checkpoint();
1712 1654 this._checkpoint_after_save = false;
1713 1655 };
1714 1656 };
1715 1657
1716 1658 /**
1717 1659 * update the autosave interval based on how long the last save took
1718 1660 *
1719 1661 * @method _update_autosave_interval
1720 1662 * @param {Integer} timestamp when the save request started
1721 1663 */
1722 1664 Notebook.prototype._update_autosave_interval = function (start) {
1723 1665 var duration = (new Date().getTime() - start);
1724 1666 if (this.autosave_interval) {
1725 1667 // new save interval: higher of 10x save duration or parameter (default 30 seconds)
1726 1668 var interval = Math.max(10 * duration, this.minimum_autosave_interval);
1727 1669 // round to 10 seconds, otherwise we will be setting a new interval too often
1728 1670 interval = 10000 * Math.round(interval / 10000);
1729 1671 // set new interval, if it's changed
1730 1672 if (interval != this.autosave_interval) {
1731 1673 this.set_autosave_interval(interval);
1732 1674 }
1733 1675 }
1734 1676 };
1735 1677
1736 1678 /**
1737 1679 * Failure callback for saving a notebook.
1738 1680 *
1739 1681 * @method save_notebook_error
1740 1682 * @param {jqXHR} xhr jQuery Ajax object
1741 1683 * @param {String} status Description of response status
1742 1684 * @param {String} error HTTP error message
1743 1685 */
1744 1686 Notebook.prototype.save_notebook_error = function (xhr, status, error) {
1745 1687 $([IPython.events]).trigger('notebook_save_failed.Notebook', [xhr, status, error]);
1746 1688 };
1747 1689
1748 1690 Notebook.prototype.new_notebook = function(){
1749 1691 var path = this.notebook_path;
1750 1692 var base_project_url = this._baseProjectUrl;
1751 1693 var settings = {
1752 1694 processData : false,
1753 1695 cache : false,
1754 1696 type : "POST",
1755 1697 dataType : "json",
1756 1698 async : false,
1757 1699 success : function (data, status, xhr){
1758 1700 var notebook_name = data.name;
1759 1701 window.open(
1760 1702 utils.url_join_encode(
1761 1703 base_project_url,
1762 1704 'notebooks',
1763 1705 path,
1764 1706 notebook_name
1765 1707 ),
1766 1708 '_blank'
1767 1709 );
1768 1710 }
1769 1711 };
1770 1712 var url = utils.url_join_encode(
1771 1713 base_project_url,
1772 1714 'api/notebooks',
1773 1715 path
1774 1716 );
1775 1717 $.ajax(url,settings);
1776 1718 };
1777 1719
1778 1720
1779 1721 Notebook.prototype.copy_notebook = function(){
1780 1722 var path = this.notebook_path;
1781 1723 var base_project_url = this._baseProjectUrl;
1782 1724 var settings = {
1783 1725 processData : false,
1784 1726 cache : false,
1785 1727 type : "POST",
1786 1728 dataType : "json",
1787 1729 data : JSON.stringify({copy_from : this.notebook_name}),
1788 1730 async : false,
1789 1731 success : function (data, status, xhr) {
1790 1732 window.open(utils.url_join_encode(
1791 1733 base_project_url,
1792 1734 'notebooks',
1793 1735 data.path,
1794 1736 data.name
1795 1737 ), '_blank');
1796 1738 }
1797 1739 };
1798 1740 var url = utils.url_join_encode(
1799 1741 base_project_url,
1800 1742 'api/notebooks',
1801 1743 path
1802 1744 );
1803 1745 $.ajax(url,settings);
1804 1746 };
1805 1747
1806 1748 Notebook.prototype.rename = function (nbname) {
1807 1749 var that = this;
1808 1750 var data = {name: nbname + '.ipynb'};
1809 1751 var settings = {
1810 1752 processData : false,
1811 1753 cache : false,
1812 1754 type : "PATCH",
1813 1755 data : JSON.stringify(data),
1814 1756 dataType: "json",
1815 1757 headers : {'Content-Type': 'application/json'},
1816 1758 success : $.proxy(that.rename_success, this),
1817 1759 error : $.proxy(that.rename_error, this)
1818 1760 };
1819 1761 $([IPython.events]).trigger('rename_notebook.Notebook', data);
1820 1762 var url = utils.url_join_encode(
1821 1763 this._baseProjectUrl,
1822 1764 'api/notebooks',
1823 1765 this.notebook_path,
1824 1766 this.notebook_name
1825 1767 );
1826 1768 $.ajax(url, settings);
1827 1769 };
1828 1770
1829 1771
1830 1772 Notebook.prototype.rename_success = function (json, status, xhr) {
1831 1773 this.notebook_name = json.name;
1832 1774 var name = this.notebook_name;
1833 1775 var path = json.path;
1834 1776 this.session.rename_notebook(name, path);
1835 1777 $([IPython.events]).trigger('notebook_renamed.Notebook', json);
1836 1778 }
1837 1779
1838 1780 Notebook.prototype.rename_error = function (xhr, status, error) {
1839 1781 var that = this;
1840 1782 var dialog = $('<div/>').append(
1841 1783 $("<p/>").addClass("rename-message")
1842 1784 .html('This notebook name already exists.')
1843 1785 )
1844 1786 $([IPython.events]).trigger('notebook_rename_failed.Notebook', [xhr, status, error]);
1845 1787 IPython.dialog.modal({
1846 1788 title: "Notebook Rename Error!",
1847 1789 body: dialog,
1848 1790 buttons : {
1849 1791 "Cancel": {},
1850 1792 "OK": {
1851 1793 class: "btn-primary",
1852 1794 click: function () {
1853 1795 IPython.save_widget.rename_notebook();
1854 1796 }}
1855 1797 },
1856 1798 open : function (event, ui) {
1857 1799 var that = $(this);
1858 1800 // Upon ENTER, click the OK button.
1859 1801 that.find('input[type="text"]').keydown(function (event, ui) {
1860 1802 if (event.which === utils.keycodes.ENTER) {
1861 1803 that.find('.btn-primary').first().click();
1862 1804 }
1863 1805 });
1864 1806 that.find('input[type="text"]').focus();
1865 1807 }
1866 1808 });
1867 1809 }
1868 1810
1869 1811 /**
1870 1812 * Request a notebook's data from the server.
1871 1813 *
1872 1814 * @method load_notebook
1873 1815 * @param {String} notebook_name and path A notebook to load
1874 1816 */
1875 1817 Notebook.prototype.load_notebook = function (notebook_name, notebook_path) {
1876 1818 var that = this;
1877 1819 this.notebook_name = notebook_name;
1878 1820 this.notebook_path = notebook_path;
1879 1821 // We do the call with settings so we can set cache to false.
1880 1822 var settings = {
1881 1823 processData : false,
1882 1824 cache : false,
1883 1825 type : "GET",
1884 1826 dataType : "json",
1885 1827 success : $.proxy(this.load_notebook_success,this),
1886 1828 error : $.proxy(this.load_notebook_error,this),
1887 1829 };
1888 1830 $([IPython.events]).trigger('notebook_loading.Notebook');
1889 1831 var url = utils.url_join_encode(
1890 1832 this._baseProjectUrl,
1891 1833 'api/notebooks',
1892 1834 this.notebook_path,
1893 1835 this.notebook_name
1894 1836 );
1895 1837 $.ajax(url, settings);
1896 1838 };
1897 1839
1898 1840 /**
1899 1841 * Success callback for loading a notebook from the server.
1900 1842 *
1901 1843 * Load notebook data from the JSON response.
1902 1844 *
1903 1845 * @method load_notebook_success
1904 1846 * @param {Object} data JSON representation of a notebook
1905 1847 * @param {String} status Description of response status
1906 1848 * @param {jqXHR} xhr jQuery Ajax object
1907 1849 */
1908 1850 Notebook.prototype.load_notebook_success = function (data, status, xhr) {
1909 1851 this.fromJSON(data);
1910 1852 if (this.ncells() === 0) {
1911 1853 this.insert_cell_below('code');
1854 this.select(0);
1855 this.edit_mode();
1856 } else {
1857 this.select(0);
1858 this.command_mode();
1912 1859 };
1913 1860 this.set_dirty(false);
1914 this.select(0);
1915 1861 this.scroll_to_top();
1916 1862 if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) {
1917 1863 var msg = "This notebook has been converted from an older " +
1918 1864 "notebook format (v"+data.orig_nbformat+") to the current notebook " +
1919 1865 "format (v"+data.nbformat+"). The next time you save this notebook, the " +
1920 1866 "newer notebook format will be used and older versions of IPython " +
1921 1867 "may not be able to read it. To keep the older version, close the " +
1922 1868 "notebook without saving it.";
1923 1869 IPython.dialog.modal({
1924 1870 title : "Notebook converted",
1925 1871 body : msg,
1926 1872 buttons : {
1927 1873 OK : {
1928 1874 class : "btn-primary"
1929 1875 }
1930 1876 }
1931 1877 });
1932 1878 } else if (data.orig_nbformat_minor !== undefined && data.nbformat_minor !== data.orig_nbformat_minor) {
1933 1879 var that = this;
1934 1880 var orig_vs = 'v' + data.nbformat + '.' + data.orig_nbformat_minor;
1935 1881 var this_vs = 'v' + data.nbformat + '.' + this.nbformat_minor;
1936 1882 var msg = "This notebook is version " + orig_vs + ", but we only fully support up to " +
1937 1883 this_vs + ". You can still work with this notebook, but some features " +
1938 1884 "introduced in later notebook versions may not be available."
1939 1885
1940 1886 IPython.dialog.modal({
1941 1887 title : "Newer Notebook",
1942 1888 body : msg,
1943 1889 buttons : {
1944 1890 OK : {
1945 1891 class : "btn-danger"
1946 1892 }
1947 1893 }
1948 1894 });
1949 1895
1950 1896 }
1951 1897
1952 1898 // Create the session after the notebook is completely loaded to prevent
1953 1899 // code execution upon loading, which is a security risk.
1954 1900 if (this.session == null) {
1955 1901 this.start_session();
1956 1902 }
1957 1903 // load our checkpoint list
1958 1904 this.list_checkpoints();
1959 1905
1960 1906 // load toolbar state
1961 1907 if (this.metadata.celltoolbar) {
1962 1908 IPython.CellToolbar.global_show();
1963 1909 IPython.CellToolbar.activate_preset(this.metadata.celltoolbar);
1964 1910 }
1965 1911
1966 1912 $([IPython.events]).trigger('notebook_loaded.Notebook');
1967 1913 };
1968 1914
1969 1915 /**
1970 1916 * Failure callback for loading a notebook from the server.
1971 1917 *
1972 1918 * @method load_notebook_error
1973 1919 * @param {jqXHR} xhr jQuery Ajax object
1974 1920 * @param {String} status Description of response status
1975 1921 * @param {String} error HTTP error message
1976 1922 */
1977 1923 Notebook.prototype.load_notebook_error = function (xhr, status, error) {
1978 1924 $([IPython.events]).trigger('notebook_load_failed.Notebook', [xhr, status, error]);
1979 1925 if (xhr.status === 400) {
1980 1926 var msg = error;
1981 1927 } else if (xhr.status === 500) {
1982 1928 var msg = "An unknown error occurred while loading this notebook. " +
1983 1929 "This version can load notebook formats " +
1984 1930 "v" + this.nbformat + " or earlier.";
1985 1931 }
1986 1932 IPython.dialog.modal({
1987 1933 title: "Error loading notebook",
1988 1934 body : msg,
1989 1935 buttons : {
1990 1936 "OK": {}
1991 1937 }
1992 1938 });
1993 1939 }
1994 1940
1995 1941 /********************* checkpoint-related *********************/
1996 1942
1997 1943 /**
1998 1944 * Save the notebook then immediately create a checkpoint.
1999 1945 *
2000 1946 * @method save_checkpoint
2001 1947 */
2002 1948 Notebook.prototype.save_checkpoint = function () {
2003 1949 this._checkpoint_after_save = true;
2004 1950 this.save_notebook();
2005 1951 };
2006 1952
2007 1953 /**
2008 1954 * Add a checkpoint for this notebook.
2009 1955 * for use as a callback from checkpoint creation.
2010 1956 *
2011 1957 * @method add_checkpoint
2012 1958 */
2013 1959 Notebook.prototype.add_checkpoint = function (checkpoint) {
2014 1960 var found = false;
2015 1961 for (var i = 0; i < this.checkpoints.length; i++) {
2016 1962 var existing = this.checkpoints[i];
2017 1963 if (existing.id == checkpoint.id) {
2018 1964 found = true;
2019 1965 this.checkpoints[i] = checkpoint;
2020 1966 break;
2021 1967 }
2022 1968 }
2023 1969 if (!found) {
2024 1970 this.checkpoints.push(checkpoint);
2025 1971 }
2026 1972 this.last_checkpoint = this.checkpoints[this.checkpoints.length - 1];
2027 1973 };
2028 1974
2029 1975 /**
2030 1976 * List checkpoints for this notebook.
2031 1977 *
2032 1978 * @method list_checkpoints
2033 1979 */
2034 1980 Notebook.prototype.list_checkpoints = function () {
2035 1981 var url = utils.url_join_encode(
2036 1982 this._baseProjectUrl,
2037 1983 'api/notebooks',
2038 1984 this.notebook_path,
2039 1985 this.notebook_name,
2040 1986 'checkpoints'
2041 1987 );
2042 1988 $.get(url).done(
2043 1989 $.proxy(this.list_checkpoints_success, this)
2044 1990 ).fail(
2045 1991 $.proxy(this.list_checkpoints_error, this)
2046 1992 );
2047 1993 };
2048 1994
2049 1995 /**
2050 1996 * Success callback for listing checkpoints.
2051 1997 *
2052 1998 * @method list_checkpoint_success
2053 1999 * @param {Object} data JSON representation of a checkpoint
2054 2000 * @param {String} status Description of response status
2055 2001 * @param {jqXHR} xhr jQuery Ajax object
2056 2002 */
2057 2003 Notebook.prototype.list_checkpoints_success = function (data, status, xhr) {
2058 2004 var data = $.parseJSON(data);
2059 2005 this.checkpoints = data;
2060 2006 if (data.length) {
2061 2007 this.last_checkpoint = data[data.length - 1];
2062 2008 } else {
2063 2009 this.last_checkpoint = null;
2064 2010 }
2065 2011 $([IPython.events]).trigger('checkpoints_listed.Notebook', [data]);
2066 2012 };
2067 2013
2068 2014 /**
2069 2015 * Failure callback for listing a checkpoint.
2070 2016 *
2071 2017 * @method list_checkpoint_error
2072 2018 * @param {jqXHR} xhr jQuery Ajax object
2073 2019 * @param {String} status Description of response status
2074 2020 * @param {String} error_msg HTTP error message
2075 2021 */
2076 2022 Notebook.prototype.list_checkpoints_error = function (xhr, status, error_msg) {
2077 2023 $([IPython.events]).trigger('list_checkpoints_failed.Notebook');
2078 2024 };
2079 2025
2080 2026 /**
2081 2027 * Create a checkpoint of this notebook on the server from the most recent save.
2082 2028 *
2083 2029 * @method create_checkpoint
2084 2030 */
2085 2031 Notebook.prototype.create_checkpoint = function () {
2086 2032 var url = utils.url_join_encode(
2087 2033 this._baseProjectUrl,
2088 2034 'api/notebooks',
2089 2035 this.notebookPath(),
2090 2036 this.notebook_name,
2091 2037 'checkpoints'
2092 2038 );
2093 2039 $.post(url).done(
2094 2040 $.proxy(this.create_checkpoint_success, this)
2095 2041 ).fail(
2096 2042 $.proxy(this.create_checkpoint_error, this)
2097 2043 );
2098 2044 };
2099 2045
2100 2046 /**
2101 2047 * Success callback for creating a checkpoint.
2102 2048 *
2103 2049 * @method create_checkpoint_success
2104 2050 * @param {Object} data JSON representation of a checkpoint
2105 2051 * @param {String} status Description of response status
2106 2052 * @param {jqXHR} xhr jQuery Ajax object
2107 2053 */
2108 2054 Notebook.prototype.create_checkpoint_success = function (data, status, xhr) {
2109 2055 var data = $.parseJSON(data);
2110 2056 this.add_checkpoint(data);
2111 2057 $([IPython.events]).trigger('checkpoint_created.Notebook', data);
2112 2058 };
2113 2059
2114 2060 /**
2115 2061 * Failure callback for creating a checkpoint.
2116 2062 *
2117 2063 * @method create_checkpoint_error
2118 2064 * @param {jqXHR} xhr jQuery Ajax object
2119 2065 * @param {String} status Description of response status
2120 2066 * @param {String} error_msg HTTP error message
2121 2067 */
2122 2068 Notebook.prototype.create_checkpoint_error = function (xhr, status, error_msg) {
2123 2069 $([IPython.events]).trigger('checkpoint_failed.Notebook');
2124 2070 };
2125 2071
2126 2072 Notebook.prototype.restore_checkpoint_dialog = function (checkpoint) {
2127 2073 var that = this;
2128 2074 var checkpoint = checkpoint || this.last_checkpoint;
2129 2075 if ( ! checkpoint ) {
2130 2076 console.log("restore dialog, but no checkpoint to restore to!");
2131 2077 return;
2132 2078 }
2133 2079 var body = $('<div/>').append(
2134 2080 $('<p/>').addClass("p-space").text(
2135 2081 "Are you sure you want to revert the notebook to " +
2136 2082 "the latest checkpoint?"
2137 2083 ).append(
2138 2084 $("<strong/>").text(
2139 2085 " This cannot be undone."
2140 2086 )
2141 2087 )
2142 2088 ).append(
2143 2089 $('<p/>').addClass("p-space").text("The checkpoint was last updated at:")
2144 2090 ).append(
2145 2091 $('<p/>').addClass("p-space").text(
2146 2092 Date(checkpoint.last_modified)
2147 2093 ).css("text-align", "center")
2148 2094 );
2149 2095
2150 2096 IPython.dialog.modal({
2151 2097 title : "Revert notebook to checkpoint",
2152 2098 body : body,
2153 2099 buttons : {
2154 2100 Revert : {
2155 2101 class : "btn-danger",
2156 2102 click : function () {
2157 2103 that.restore_checkpoint(checkpoint.id);
2158 2104 }
2159 2105 },
2160 2106 Cancel : {}
2161 2107 }
2162 2108 });
2163 2109 }
2164 2110
2165 2111 /**
2166 2112 * Restore the notebook to a checkpoint state.
2167 2113 *
2168 2114 * @method restore_checkpoint
2169 2115 * @param {String} checkpoint ID
2170 2116 */
2171 2117 Notebook.prototype.restore_checkpoint = function (checkpoint) {
2172 2118 $([IPython.events]).trigger('notebook_restoring.Notebook', checkpoint);
2173 2119 var url = utils.url_join_encode(
2174 2120 this._baseProjectUrl,
2175 2121 'api/notebooks',
2176 2122 this.notebookPath(),
2177 2123 this.notebook_name,
2178 2124 'checkpoints',
2179 2125 checkpoint
2180 2126 );
2181 2127 $.post(url).done(
2182 2128 $.proxy(this.restore_checkpoint_success, this)
2183 2129 ).fail(
2184 2130 $.proxy(this.restore_checkpoint_error, this)
2185 2131 );
2186 2132 };
2187 2133
2188 2134 /**
2189 2135 * Success callback for restoring a notebook to a checkpoint.
2190 2136 *
2191 2137 * @method restore_checkpoint_success
2192 2138 * @param {Object} data (ignored, should be empty)
2193 2139 * @param {String} status Description of response status
2194 2140 * @param {jqXHR} xhr jQuery Ajax object
2195 2141 */
2196 2142 Notebook.prototype.restore_checkpoint_success = function (data, status, xhr) {
2197 2143 $([IPython.events]).trigger('checkpoint_restored.Notebook');
2198 2144 this.load_notebook(this.notebook_name, this.notebook_path);
2199 2145 };
2200 2146
2201 2147 /**
2202 2148 * Failure callback for restoring a notebook to a checkpoint.
2203 2149 *
2204 2150 * @method restore_checkpoint_error
2205 2151 * @param {jqXHR} xhr jQuery Ajax object
2206 2152 * @param {String} status Description of response status
2207 2153 * @param {String} error_msg HTTP error message
2208 2154 */
2209 2155 Notebook.prototype.restore_checkpoint_error = function (xhr, status, error_msg) {
2210 2156 $([IPython.events]).trigger('checkpoint_restore_failed.Notebook');
2211 2157 };
2212 2158
2213 2159 /**
2214 2160 * Delete a notebook checkpoint.
2215 2161 *
2216 2162 * @method delete_checkpoint
2217 2163 * @param {String} checkpoint ID
2218 2164 */
2219 2165 Notebook.prototype.delete_checkpoint = function (checkpoint) {
2220 2166 $([IPython.events]).trigger('notebook_restoring.Notebook', checkpoint);
2221 2167 var url = utils.url_join_encode(
2222 2168 this._baseProjectUrl,
2223 2169 'api/notebooks',
2224 2170 this.notebookPath(),
2225 2171 this.notebook_name,
2226 2172 'checkpoints',
2227 2173 checkpoint
2228 2174 );
2229 2175 $.ajax(url, {
2230 2176 type: 'DELETE',
2231 2177 success: $.proxy(this.delete_checkpoint_success, this),
2232 2178 error: $.proxy(this.delete_notebook_error,this)
2233 2179 });
2234 2180 };
2235 2181
2236 2182 /**
2237 2183 * Success callback for deleting a notebook checkpoint
2238 2184 *
2239 2185 * @method delete_checkpoint_success
2240 2186 * @param {Object} data (ignored, should be empty)
2241 2187 * @param {String} status Description of response status
2242 2188 * @param {jqXHR} xhr jQuery Ajax object
2243 2189 */
2244 2190 Notebook.prototype.delete_checkpoint_success = function (data, status, xhr) {
2245 2191 $([IPython.events]).trigger('checkpoint_deleted.Notebook', data);
2246 2192 this.load_notebook(this.notebook_name, this.notebook_path);
2247 2193 };
2248 2194
2249 2195 /**
2250 2196 * Failure callback for deleting a notebook checkpoint.
2251 2197 *
2252 2198 * @method delete_checkpoint_error
2253 2199 * @param {jqXHR} xhr jQuery Ajax object
2254 2200 * @param {String} status Description of response status
2255 2201 * @param {String} error_msg HTTP error message
2256 2202 */
2257 2203 Notebook.prototype.delete_checkpoint_error = function (xhr, status, error_msg) {
2258 2204 $([IPython.events]).trigger('checkpoint_delete_failed.Notebook');
2259 2205 };
2260 2206
2261 2207
2262 2208 IPython.Notebook = Notebook;
2263 2209
2264 2210
2265 2211 return IPython;
2266 2212
2267 2213 }(IPython));
@@ -1,730 +1,739 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // OutputArea
10 10 //============================================================================
11 11
12 12 /**
13 13 * @module IPython
14 14 * @namespace IPython
15 15 * @submodule OutputArea
16 16 */
17 17 var IPython = (function (IPython) {
18 18 "use strict";
19 19
20 20 var utils = IPython.utils;
21 21
22 22 /**
23 23 * @class OutputArea
24 24 *
25 25 * @constructor
26 26 */
27 27
28 28 var OutputArea = function (selector, prompt_area) {
29 29 this.selector = selector;
30 30 this.wrapper = $(selector);
31 31 this.outputs = [];
32 32 this.collapsed = false;
33 33 this.scrolled = false;
34 34 this.clear_queued = null;
35 35 if (prompt_area === undefined) {
36 36 this.prompt_area = true;
37 37 } else {
38 38 this.prompt_area = prompt_area;
39 39 }
40 40 this.create_elements();
41 41 this.style();
42 42 this.bind_events();
43 43 };
44 44
45 45 OutputArea.prototype.create_elements = function () {
46 46 this.element = $("<div/>");
47 47 this.collapse_button = $("<div/>");
48 48 this.prompt_overlay = $("<div/>");
49 49 this.wrapper.append(this.prompt_overlay);
50 50 this.wrapper.append(this.element);
51 51 this.wrapper.append(this.collapse_button);
52 52 };
53 53
54 54
55 55 OutputArea.prototype.style = function () {
56 56 this.collapse_button.hide();
57 57 this.prompt_overlay.hide();
58 58
59 59 this.wrapper.addClass('output_wrapper');
60 60 this.element.addClass('output');
61 61
62 62 this.collapse_button.addClass("btn output_collapsed");
63 63 this.collapse_button.attr('title', 'click to expand output');
64 64 this.collapse_button.html('. . .');
65 65
66 66 this.prompt_overlay.addClass('out_prompt_overlay prompt');
67 67 this.prompt_overlay.attr('title', 'click to expand output; double click to hide output');
68 68
69 69 this.collapse();
70 70 };
71 71
72 72 /**
73 73 * Should the OutputArea scroll?
74 74 * Returns whether the height (in lines) exceeds a threshold.
75 75 *
76 76 * @private
77 77 * @method _should_scroll
78 78 * @param [lines=100]{Integer}
79 79 * @return {Bool}
80 80 *
81 81 */
82 82 OutputArea.prototype._should_scroll = function (lines) {
83 83 if (lines <=0 ){ return }
84 84 if (!lines) {
85 85 lines = 100;
86 86 }
87 87 // line-height from http://stackoverflow.com/questions/1185151
88 88 var fontSize = this.element.css('font-size');
89 89 var lineHeight = Math.floor(parseInt(fontSize.replace('px','')) * 1.5);
90 90
91 91 return (this.element.height() > lines * lineHeight);
92 92 };
93 93
94 94
95 95 OutputArea.prototype.bind_events = function () {
96 96 var that = this;
97 97 this.prompt_overlay.dblclick(function () { that.toggle_output(); });
98 98 this.prompt_overlay.click(function () { that.toggle_scroll(); });
99 99
100 100 this.element.resize(function () {
101 101 // FIXME: Firefox on Linux misbehaves, so automatic scrolling is disabled
102 102 if ( IPython.utils.browser[0] === "Firefox" ) {
103 103 return;
104 104 }
105 105 // maybe scroll output,
106 106 // if it's grown large enough and hasn't already been scrolled.
107 107 if ( !that.scrolled && that._should_scroll(OutputArea.auto_scroll_threshold)) {
108 108 that.scroll_area();
109 109 }
110 110 });
111 111 this.collapse_button.click(function () {
112 112 that.expand();
113 113 });
114 114 };
115 115
116 116
117 117 OutputArea.prototype.collapse = function () {
118 118 if (!this.collapsed) {
119 119 this.element.hide();
120 120 this.prompt_overlay.hide();
121 121 if (this.element.html()){
122 122 this.collapse_button.show();
123 123 }
124 124 this.collapsed = true;
125 125 }
126 126 };
127 127
128 128
129 129 OutputArea.prototype.expand = function () {
130 130 if (this.collapsed) {
131 131 this.collapse_button.hide();
132 132 this.element.show();
133 133 this.prompt_overlay.show();
134 134 this.collapsed = false;
135 135 }
136 136 };
137 137
138 138
139 139 OutputArea.prototype.toggle_output = function () {
140 140 if (this.collapsed) {
141 141 this.expand();
142 142 } else {
143 143 this.collapse();
144 144 }
145 145 };
146 146
147 147
148 148 OutputArea.prototype.scroll_area = function () {
149 149 this.element.addClass('output_scroll');
150 150 this.prompt_overlay.attr('title', 'click to unscroll output; double click to hide');
151 151 this.scrolled = true;
152 152 };
153 153
154 154
155 155 OutputArea.prototype.unscroll_area = function () {
156 156 this.element.removeClass('output_scroll');
157 157 this.prompt_overlay.attr('title', 'click to scroll output; double click to hide');
158 158 this.scrolled = false;
159 159 };
160 160
161 161 /**
162 162 * Threshold to trigger autoscroll when the OutputArea is resized,
163 163 * typically when new outputs are added.
164 164 *
165 165 * Behavior is undefined if autoscroll is lower than minimum_scroll_threshold,
166 166 * unless it is < 0, in which case autoscroll will never be triggered
167 167 *
168 168 * @property auto_scroll_threshold
169 169 * @type Number
170 170 * @default 100
171 171 *
172 172 **/
173 173 OutputArea.auto_scroll_threshold = 100;
174 174
175 175
176 176 /**
177 177 * Lower limit (in lines) for OutputArea to be made scrollable. OutputAreas
178 178 * shorter than this are never scrolled.
179 179 *
180 180 * @property minimum_scroll_threshold
181 181 * @type Number
182 182 * @default 20
183 183 *
184 184 **/
185 185 OutputArea.minimum_scroll_threshold = 20;
186 186
187 187
188 188 /**
189 189 *
190 190 * Scroll OutputArea if height supperior than a threshold (in lines).
191 191 *
192 192 * Threshold is a maximum number of lines. If unspecified, defaults to
193 193 * OutputArea.minimum_scroll_threshold.
194 194 *
195 195 * Negative threshold will prevent the OutputArea from ever scrolling.
196 196 *
197 197 * @method scroll_if_long
198 198 *
199 199 * @param [lines=20]{Number} Default to 20 if not set,
200 200 * behavior undefined for value of `0`.
201 201 *
202 202 **/
203 203 OutputArea.prototype.scroll_if_long = function (lines) {
204 204 var n = lines | OutputArea.minimum_scroll_threshold;
205 205 if(n <= 0){
206 206 return
207 207 }
208 208
209 209 if (this._should_scroll(n)) {
210 210 // only allow scrolling long-enough output
211 211 this.scroll_area();
212 212 }
213 213 };
214 214
215 215
216 216 OutputArea.prototype.toggle_scroll = function () {
217 217 if (this.scrolled) {
218 218 this.unscroll_area();
219 219 } else {
220 220 // only allow scrolling long-enough output
221 221 this.scroll_if_long();
222 222 }
223 223 };
224 224
225 225
226 226 // typeset with MathJax if MathJax is available
227 227 OutputArea.prototype.typeset = function () {
228 228 if (window.MathJax){
229 229 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
230 230 }
231 231 };
232 232
233 233
234 234 OutputArea.prototype.handle_output = function (msg) {
235 235 var json = {};
236 236 var msg_type = json.output_type = msg.header.msg_type;
237 237 var content = msg.content;
238 238 if (msg_type === "stream") {
239 239 json.text = content.data;
240 240 json.stream = content.name;
241 241 } else if (msg_type === "display_data") {
242 242 json = this.convert_mime_types(json, content.data);
243 243 json.metadata = this.convert_mime_types({}, content.metadata);
244 244 } else if (msg_type === "pyout") {
245 245 json.prompt_number = content.execution_count;
246 246 json = this.convert_mime_types(json, content.data);
247 247 json.metadata = this.convert_mime_types({}, content.metadata);
248 248 } else if (msg_type === "pyerr") {
249 249 json.ename = content.ename;
250 250 json.evalue = content.evalue;
251 251 json.traceback = content.traceback;
252 252 }
253 253 // append with dynamic=true
254 254 this.append_output(json, true);
255 255 };
256 256
257 257
258 258 OutputArea.prototype.convert_mime_types = function (json, data) {
259 259 if (data === undefined) {
260 260 return json;
261 261 }
262 262 if (data['text/plain'] !== undefined) {
263 263 json.text = data['text/plain'];
264 264 }
265 265 if (data['text/html'] !== undefined) {
266 266 json.html = data['text/html'];
267 267 }
268 268 if (data['image/svg+xml'] !== undefined) {
269 269 json.svg = data['image/svg+xml'];
270 270 }
271 271 if (data['image/png'] !== undefined) {
272 272 json.png = data['image/png'];
273 273 }
274 274 if (data['image/jpeg'] !== undefined) {
275 275 json.jpeg = data['image/jpeg'];
276 276 }
277 277 if (data['text/latex'] !== undefined) {
278 278 json.latex = data['text/latex'];
279 279 }
280 280 if (data['application/json'] !== undefined) {
281 281 json.json = data['application/json'];
282 282 }
283 283 if (data['application/javascript'] !== undefined) {
284 284 json.javascript = data['application/javascript'];
285 285 }
286 286 return json;
287 287 };
288 288
289 289
290 290 OutputArea.prototype.append_output = function (json, dynamic) {
291 291 // If dynamic is true, javascript output will be eval'd.
292 292 this.expand();
293 293 // Clear the output if clear is queued.
294 294 var needs_height_reset = false;
295 295 if (this.clear_queued) {
296 296 this.clear_output(false);
297 297 needs_height_reset = true;
298 298 }
299 299
300 300 if (json.output_type === 'pyout') {
301 301 this.append_pyout(json, dynamic);
302 302 } else if (json.output_type === 'pyerr') {
303 303 this.append_pyerr(json);
304 304 } else if (json.output_type === 'display_data') {
305 305 this.append_display_data(json, dynamic);
306 306 } else if (json.output_type === 'stream') {
307 307 this.append_stream(json);
308 308 }
309 309 this.outputs.push(json);
310 310
311 311 // Only reset the height to automatic if the height is currently
312 312 // fixed (done by wait=True flag on clear_output).
313 313 if (needs_height_reset) {
314 314 this.element.height('');
315 315 }
316 316
317 317 var that = this;
318 318 setTimeout(function(){that.element.trigger('resize');}, 100);
319 319 };
320 320
321 321
322 322 OutputArea.prototype.create_output_area = function () {
323 323 var oa = $("<div/>").addClass("output_area");
324 324 if (this.prompt_area) {
325 325 oa.append($('<div/>').addClass('prompt'));
326 326 }
327 327 return oa;
328 328 };
329 329
330 330
331 331 OutputArea.prototype.create_output_subarea = function(md, classes) {
332 332 var subarea = $('<div/>').addClass('output_subarea').addClass(classes);
333 333 if (md['isolated']) {
334 334 // Create an iframe to isolate the subarea from the rest of the
335 335 // document
336 336 var iframe = $('<iframe/>').addClass('box-flex1');
337 337 iframe.css({'height':1, 'width':'100%', 'display':'block'});
338 338 iframe.attr('frameborder', 0);
339 339 iframe.attr('scrolling', 'auto');
340 340
341 341 // Once the iframe is loaded, the subarea is dynamically inserted
342 342 iframe.on('load', function() {
343 343 // Workaround needed by Firefox, to properly render svg inside
344 344 // iframes, see http://stackoverflow.com/questions/10177190/
345 345 // svg-dynamically-added-to-iframe-does-not-render-correctly
346 346 this.contentDocument.open();
347 347
348 348 // Insert the subarea into the iframe
349 349 // We must directly write the html. When using Jquery's append
350 350 // method, javascript is evaluated in the parent document and
351 351 // not in the iframe document.
352 352 this.contentDocument.write(subarea.html());
353 353
354 354 this.contentDocument.close();
355 355
356 356 var body = this.contentDocument.body;
357 357 // Adjust the iframe height automatically
358 358 iframe.height(body.scrollHeight + 'px');
359 359 });
360 360
361 361 // Elements should be appended to the inner subarea and not to the
362 362 // iframe
363 363 iframe.append = function(that) {
364 364 subarea.append(that);
365 365 };
366 366
367 367 return iframe;
368 368 } else {
369 369 return subarea;
370 370 }
371 371 }
372 372
373 373
374 374 OutputArea.prototype._append_javascript_error = function (err, element) {
375 375 // display a message when a javascript error occurs in display output
376 376 var msg = "Javascript error adding output!"
377 377 if ( element === undefined ) return;
378 378 element.append(
379 379 $('<div/>').html(msg + "<br/>" +
380 380 err.toString() +
381 381 '<br/>See your browser Javascript console for more details.'
382 382 ).addClass('js-error')
383 383 );
384 384 };
385 385
386 386 OutputArea.prototype._safe_append = function (toinsert) {
387 387 // safely append an item to the document
388 388 // this is an object created by user code,
389 389 // and may have errors, which should not be raised
390 390 // under any circumstances.
391 391 try {
392 392 this.element.append(toinsert);
393 393 } catch(err) {
394 394 console.log(err);
395 395 // Create an actual output_area and output_subarea, which creates
396 396 // the prompt area and the proper indentation.
397 397 var toinsert = this.create_output_area();
398 398 var subarea = $('<div/>').addClass('output_subarea');
399 399 toinsert.append(subarea);
400 400 this._append_javascript_error(err, subarea);
401 401 this.element.append(toinsert);
402 402 }
403 403 };
404 404
405 405
406 406 OutputArea.prototype.append_pyout = function (json, dynamic) {
407 407 var n = json.prompt_number || ' ';
408 408 var toinsert = this.create_output_area();
409 409 if (this.prompt_area) {
410 410 toinsert.find('div.prompt').addClass('output_prompt').html('Out[' + n + ']:');
411 411 }
412 412 this.append_mime_type(json, toinsert, dynamic);
413 413 this._safe_append(toinsert);
414 414 // If we just output latex, typeset it.
415 415 if ((json.latex !== undefined) || (json.html !== undefined)) {
416 416 this.typeset();
417 417 }
418 418 };
419 419
420 420
421 421 OutputArea.prototype.append_pyerr = function (json) {
422 422 var tb = json.traceback;
423 423 if (tb !== undefined && tb.length > 0) {
424 424 var s = '';
425 425 var len = tb.length;
426 426 for (var i=0; i<len; i++) {
427 427 s = s + tb[i] + '\n';
428 428 }
429 429 s = s + '\n';
430 430 var toinsert = this.create_output_area();
431 431 this.append_text(s, {}, toinsert);
432 432 this._safe_append(toinsert);
433 433 }
434 434 };
435 435
436 436
437 437 OutputArea.prototype.append_stream = function (json) {
438 438 // temporary fix: if stream undefined (json file written prior to this patch),
439 439 // default to most likely stdout:
440 440 if (json.stream == undefined){
441 441 json.stream = 'stdout';
442 442 }
443 443 var text = json.text;
444 444 var subclass = "output_"+json.stream;
445 445 if (this.outputs.length > 0){
446 446 // have at least one output to consider
447 447 var last = this.outputs[this.outputs.length-1];
448 448 if (last.output_type == 'stream' && json.stream == last.stream){
449 449 // latest output was in the same stream,
450 450 // so append directly into its pre tag
451 451 // escape ANSI & HTML specials:
452 452 var pre = this.element.find('div.'+subclass).last().find('pre');
453 453 var html = utils.fixCarriageReturn(
454 454 pre.html() + utils.fixConsole(text));
455 455 pre.html(html);
456 456 return;
457 457 }
458 458 }
459 459
460 460 if (!text.replace("\r", "")) {
461 461 // text is nothing (empty string, \r, etc.)
462 462 // so don't append any elements, which might add undesirable space
463 463 return;
464 464 }
465 465
466 466 // If we got here, attach a new div
467 467 var toinsert = this.create_output_area();
468 468 this.append_text(text, {}, toinsert, "output_stream "+subclass);
469 469 this._safe_append(toinsert);
470 470 };
471 471
472 472
473 473 OutputArea.prototype.append_display_data = function (json, dynamic) {
474 474 var toinsert = this.create_output_area();
475 475 if (this.append_mime_type(json, toinsert, dynamic)) {
476 476 this._safe_append(toinsert);
477 477 // If we just output latex, typeset it.
478 478 if ( (json.latex !== undefined) || (json.html !== undefined) ) {
479 479 this.typeset();
480 480 }
481 481 }
482 482 };
483 483
484 484 OutputArea.display_order = ['javascript','html','latex','svg','png','jpeg','text'];
485 485
486 486 OutputArea.prototype.append_mime_type = function (json, element, dynamic) {
487 487 for(var type_i in OutputArea.display_order){
488 488 var type = OutputArea.display_order[type_i];
489 489 if(json[type] != undefined ){
490 490 var md = {};
491 491 if (json.metadata && json.metadata[type]) {
492 492 md = json.metadata[type];
493 493 };
494 494 if(type == 'javascript'){
495 495 if (dynamic) {
496 496 this.append_javascript(json.javascript, md, element, dynamic);
497 497 return true;
498 498 }
499 499 } else {
500 500 this['append_'+type](json[type], md, element);
501 501 return true;
502 502 }
503 503 return false;
504 504 }
505 505 }
506 506 return false;
507 507 };
508 508
509 509
510 510 OutputArea.prototype.append_html = function (html, md, element) {
511 511 var toinsert = this.create_output_subarea(md, "output_html rendered_html");
512 IPython.keyboard_manager.register_events(toinsert);
512 513 toinsert.append(html);
513 514 element.append(toinsert);
514 515 };
515 516
516 517
517 518 OutputArea.prototype.append_javascript = function (js, md, container) {
518 519 // We just eval the JS code, element appears in the local scope.
519 520 var element = this.create_output_subarea(md, "output_javascript");
521 IPython.keyboard_manager.register_events(element);
520 522 container.append(element);
521 523 try {
522 524 eval(js);
523 525 } catch(err) {
524 526 console.log(err);
525 527 this._append_javascript_error(err, element);
526 528 }
527 529 };
528 530
529 531
530 532 OutputArea.prototype.append_text = function (data, md, element, extra_class) {
531 533 var toinsert = this.create_output_subarea(md, "output_text");
532 534 // escape ANSI & HTML specials in plaintext:
533 535 data = utils.fixConsole(data);
534 536 data = utils.fixCarriageReturn(data);
535 537 data = utils.autoLinkUrls(data);
536 538 if (extra_class){
537 539 toinsert.addClass(extra_class);
538 540 }
539 541 toinsert.append($("<pre/>").html(data));
540 542 element.append(toinsert);
541 543 };
542 544
543 545
544 546 OutputArea.prototype.append_svg = function (svg, md, element) {
545 547 var toinsert = this.create_output_subarea(md, "output_svg");
546 548 toinsert.append(svg);
547 549 element.append(toinsert);
548 550 };
549 551
550 552
551 553 OutputArea.prototype._dblclick_to_reset_size = function (img) {
552 554 // schedule wrapping image in resizable after a delay,
553 555 // so we don't end up calling resize on a zero-size object
554 556 var that = this;
555 557 setTimeout(function () {
556 558 var h0 = img.height();
557 559 var w0 = img.width();
558 560 if (!(h0 && w0)) {
559 561 // zero size, schedule another timeout
560 562 that._dblclick_to_reset_size(img);
561 563 return;
562 564 }
563 565 img.resizable({
564 566 aspectRatio: true,
565 567 autoHide: true
566 568 });
567 569 img.dblclick(function () {
568 570 // resize wrapper & image together for some reason:
569 571 img.parent().height(h0);
570 572 img.height(h0);
571 573 img.parent().width(w0);
572 574 img.width(w0);
573 575 });
574 576 }, 250);
575 577 };
576 578
577 579
578 580 OutputArea.prototype.append_png = function (png, md, element) {
579 581 var toinsert = this.create_output_subarea(md, "output_png");
580 582 var img = $("<img/>");
581 583 img[0].setAttribute('src','data:image/png;base64,'+png);
582 584 if (md['height']) {
583 585 img[0].setAttribute('height', md['height']);
584 586 }
585 587 if (md['width']) {
586 588 img[0].setAttribute('width', md['width']);
587 589 }
588 590 this._dblclick_to_reset_size(img);
589 591 toinsert.append(img);
590 592 element.append(toinsert);
591 593 };
592 594
593 595
594 596 OutputArea.prototype.append_jpeg = function (jpeg, md, element) {
595 597 var toinsert = this.create_output_subarea(md, "output_jpeg");
596 598 var img = $("<img/>").attr('src','data:image/jpeg;base64,'+jpeg);
597 599 if (md['height']) {
598 600 img.attr('height', md['height']);
599 601 }
600 602 if (md['width']) {
601 603 img.attr('width', md['width']);
602 604 }
603 605 this._dblclick_to_reset_size(img);
604 606 toinsert.append(img);
605 607 element.append(toinsert);
606 608 };
607 609
608 610
609 611 OutputArea.prototype.append_latex = function (latex, md, element) {
610 612 // This method cannot do the typesetting because the latex first has to
611 613 // be on the page.
612 614 var toinsert = this.create_output_subarea(md, "output_latex");
613 615 toinsert.append(latex);
614 616 element.append(toinsert);
615 617 };
616 618
617 619 OutputArea.prototype.append_raw_input = function (msg) {
618 620 var that = this;
619 621 this.expand();
620 622 var content = msg.content;
621 623 var area = this.create_output_area();
622 624
623 625 // disable any other raw_inputs, if they are left around
624 626 $("div.output_subarea.raw_input").remove();
625 627
626 628 area.append(
627 629 $("<div/>")
628 630 .addClass("box-flex1 output_subarea raw_input")
629 631 .append(
630 632 $("<span/>")
631 633 .addClass("input_prompt")
632 634 .text(content.prompt)
633 635 )
634 636 .append(
635 637 $("<input/>")
636 638 .addClass("raw_input")
637 639 .attr('type', 'text')
638 640 .attr("size", 47)
639 641 .keydown(function (event, ui) {
640 642 // make sure we submit on enter,
641 643 // and don't re-execute the *cell* on shift-enter
642 644 if (event.which === utils.keycodes.ENTER) {
643 645 that._submit_raw_input();
644 646 return false;
645 647 }
646 648 })
647 649 )
648 650 );
651
649 652 this.element.append(area);
650 // weirdly need double-focus now,
651 // otherwise only the cell will be focused
652 area.find("input.raw_input").focus().focus();
653 var raw_input = area.find('input.raw_input');
654 // Register events that enable/disable the keyboard manager while raw
655 // input is focused.
656 IPython.keyboard_manager.register_events(raw_input);
657 // Note, the following line used to read raw_input.focus().focus().
658 // This seemed to be needed otherwise only the cell would be focused.
659 // But with the modal UI, this seems to work fine with one call to focus().
660 raw_input.focus();
653 661 }
662
654 663 OutputArea.prototype._submit_raw_input = function (evt) {
655 664 var container = this.element.find("div.raw_input");
656 665 var theprompt = container.find("span.input_prompt");
657 666 var theinput = container.find("input.raw_input");
658 667 var value = theinput.val();
659 668 var content = {
660 669 output_type : 'stream',
661 670 name : 'stdout',
662 671 text : theprompt.text() + value + '\n'
663 672 }
664 673 // remove form container
665 674 container.parent().remove();
666 675 // replace with plaintext version in stdout
667 676 this.append_output(content, false);
668 677 $([IPython.events]).trigger('send_input_reply.Kernel', value);
669 678 }
670 679
671 680
672 681 OutputArea.prototype.handle_clear_output = function (msg) {
673 682 this.clear_output(msg.content.wait);
674 683 };
675 684
676 685
677 686 OutputArea.prototype.clear_output = function(wait) {
678 687 if (wait) {
679 688
680 689 // If a clear is queued, clear before adding another to the queue.
681 690 if (this.clear_queued) {
682 691 this.clear_output(false);
683 692 };
684 693
685 694 this.clear_queued = true;
686 695 } else {
687 696
688 697 // Fix the output div's height if the clear_output is waiting for
689 698 // new output (it is being used in an animation).
690 699 if (this.clear_queued) {
691 700 var height = this.element.height();
692 701 this.element.height(height);
693 702 this.clear_queued = false;
694 703 }
695 704
696 705 // clear all, no need for logic
697 706 this.element.html("");
698 707 this.outputs = [];
699 708 this.unscroll_area();
700 709 return;
701 710 };
702 711 };
703 712
704 713
705 714 // JSON serialization
706 715
707 716 OutputArea.prototype.fromJSON = function (outputs) {
708 717 var len = outputs.length;
709 718 for (var i=0; i<len; i++) {
710 719 // append with dynamic=false.
711 720 this.append_output(outputs[i], false);
712 721 }
713 722 };
714 723
715 724
716 725 OutputArea.prototype.toJSON = function () {
717 726 var outputs = [];
718 727 var len = this.outputs.length;
719 728 for (var i=0; i<len; i++) {
720 729 outputs[i] = this.outputs[i];
721 730 }
722 731 return outputs;
723 732 };
724 733
725 734
726 735 IPython.OutputArea = OutputArea;
727 736
728 737 return IPython;
729 738
730 739 }(IPython));
@@ -1,76 +1,133 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // QuickHelp button
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13 "use strict";
14 14
15 15 var QuickHelp = function (selector) {
16 16 };
17 17
18 18 QuickHelp.prototype.show_keyboard_shortcuts = function () {
19 19 // toggles display of keyboard shortcut dialog
20 20 var that = this;
21 21 if ( this.shortcut_dialog ){
22 22 // if dialog is already shown, close it
23 23 $(this.shortcut_dialog).modal("toggle");
24 24 return;
25 25 }
26 var body = $('<div/>');
27 var shortcuts = [
28 {key: 'Shift-Enter', help: 'run cell'},
29 {key: 'Ctrl-Enter', help: 'run cell in-place'},
30 {key: 'Alt-Enter', help: 'run cell, insert below'},
31 {key: 'Ctrl-m x', help: 'cut cell'},
32 {key: 'Ctrl-m c', help: 'copy cell'},
33 {key: 'Ctrl-m v', help: 'paste cell'},
34 {key: 'Ctrl-m d', help: 'delete cell'},
35 {key: 'Ctrl-m z', help: 'undo last cell deletion'},
36 {key: 'Ctrl-m -', help: 'split cell'},
37 {key: 'Ctrl-m a', help: 'insert cell above'},
38 {key: 'Ctrl-m b', help: 'insert cell below'},
39 {key: 'Ctrl-m o', help: 'toggle output'},
40 {key: 'Ctrl-m O', help: 'toggle output scroll'},
41 {key: 'Ctrl-m l', help: 'toggle line numbers'},
42 {key: 'Ctrl-m s', help: 'save notebook'},
43 {key: 'Ctrl-m j', help: 'move cell down'},
44 {key: 'Ctrl-m k', help: 'move cell up'},
45 {key: 'Ctrl-m y', help: 'code cell'},
46 {key: 'Ctrl-m m', help: 'markdown cell'},
47 {key: 'Ctrl-m t', help: 'raw cell'},
48 {key: 'Ctrl-m 1-6', help: 'heading 1-6 cell'},
49 {key: 'Ctrl-m p', help: 'select previous'},
50 {key: 'Ctrl-m n', help: 'select next'},
51 {key: 'Ctrl-m i', help: 'interrupt kernel'},
52 {key: 'Ctrl-m .', help: 'restart kernel'},
53 {key: 'Ctrl-m h', help: 'show keyboard shortcuts'}
54 ];
55 for (var i=0; i<shortcuts.length; i++) {
56 body.append($('<div>').addClass('quickhelp').
57 append($('<span/>').addClass('shortcut_key').html(shortcuts[i].key)).
58 append($('<span/>').addClass('shortcut_descr').html(' : ' + shortcuts[i].help))
59 );
60 };
26 var command_shortcuts = IPython.keyboard_manager.command_shortcuts.help();
27 var edit_shortcuts = IPython.keyboard_manager.edit_shortcuts.help();
28 var help, shortcut;
29 var i, half, n;
30 var element = $('<div/>');
31
32 // The documentation
33 var doc = $('<div/>').addClass('alert');
34 doc.append(
35 $('<button/>').addClass('close').attr('data-dismiss','alert').html('&times')
36 ).append(
37 'The IPython Notebook has two different keyboard input modes. <b>Edit mode</b> '+
38 'allow you the type code/text into a cell and is indicated by a green cell '+
39 'border. <b>Command mode</b> binds the keyboard to notebook level actions '+
40 'and is indicated by a grey cell border.'
41 )
42 element.append(doc);
43
44 // Command mode
45 var cmd_div = this.build_command_help();
46 element.append(cmd_div);
47
48 // Edit mode
49 var edit_div = this.build_edit_help();
50 element.append(edit_div);
51
61 52 this.shortcut_dialog = IPython.dialog.modal({
62 53 title : "Keyboard shortcuts",
63 body : body,
54 body : element,
64 55 destroy : false,
65 56 buttons : {
66 57 Close : {}
67 58 }
68 59 });
69 60 };
70 61
62 QuickHelp.prototype.build_command_help = function () {
63 var command_shortcuts = IPython.keyboard_manager.command_shortcuts.help();
64 var help, shortcut;
65 var i, half, n;
66
67 // Command mode
68 var cmd_div = $('<div/>').append($('<h4>Command Mode (press ESC to enable)</h4>'));
69 var cmd_sub_div = $('<div/>').addClass('hbox');
70 var cmd_col1 = $('<div/>').addClass('box-flex0');
71 var cmd_col2 = $('<div/>').addClass('box-flex0');
72 n = command_shortcuts.length;
73 half = ~~(n/2); // Truncate :)
74 for (i=0; i<half; i++) {
75 help = command_shortcuts[i]['help'];
76 shortcut = command_shortcuts[i]['shortcut'];
77 cmd_col1.append($('<div>').addClass('quickhelp').
78 append($('<span/>').addClass('shortcut_key').html(shortcut)).
79 append($('<span/>').addClass('shortcut_descr').html(' : ' + help))
80 );
81 };
82 for (i=half; i<n; i++) {
83 help = command_shortcuts[i]['help'];
84 shortcut = command_shortcuts[i]['shortcut'];
85 cmd_col2.append($('<div>').addClass('quickhelp').
86 append($('<span/>').addClass('shortcut_key').html(shortcut)).
87 append($('<span/>').addClass('shortcut_descr').html(' : ' + help))
88 );
89 };
90 cmd_sub_div.append(cmd_col1).append(cmd_col2);
91 cmd_div.append(cmd_sub_div);
92 return cmd_div;
93 }
94
95 QuickHelp.prototype.build_edit_help = function () {
96 var edit_shortcuts = IPython.keyboard_manager.edit_shortcuts.help();
97 var help, shortcut;
98 var i, half, n;
99
100 // Edit mode
101 var edit_div = $('<div/>').append($('<h4>Edit Mode (press ENTER to enable)</h4>'));
102 var edit_sub_div = $('<div/>').addClass('hbox');
103 var edit_col1 = $('<div/>').addClass('box-flex0');
104 var edit_col2 = $('<div/>').addClass('box-flex0');
105 n = edit_shortcuts.length;
106 half = ~~(n/2); // Truncate :)
107 for (i=0; i<half; i++) {
108 help = edit_shortcuts[i]['help'];
109 shortcut = edit_shortcuts[i]['shortcut'];
110 edit_col1.append($('<div>').addClass('quickhelp').
111 append($('<span/>').addClass('shortcut_key').html(shortcut)).
112 append($('<span/>').addClass('shortcut_descr').html(' : ' + help))
113 );
114 };
115 for (i=half; i<n; i++) {
116 help = edit_shortcuts[i]['help'];
117 shortcut = edit_shortcuts[i]['shortcut'];
118 edit_col2.append($('<div>').addClass('quickhelp').
119 append($('<span/>').addClass('shortcut_key').html(shortcut)).
120 append($('<span/>').addClass('shortcut_descr').html(' : ' + help))
121 );
122 };
123 edit_sub_div.append(edit_col1).append(edit_col2);
124 edit_div.append(edit_sub_div);
125 return edit_div;
126 }
127
71 128 // Set module variables
72 129 IPython.QuickHelp = QuickHelp;
73 130
74 131 return IPython;
75 132
76 133 }(IPython));
@@ -1,580 +1,560 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2012 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // TextCell
10 10 //============================================================================
11 11
12 12
13 13
14 14 /**
15 15 A module that allow to create different type of Text Cell
16 16 @module IPython
17 17 @namespace IPython
18 18 */
19 19 var IPython = (function (IPython) {
20 20 "use strict";
21 21
22 22 // TextCell base class
23 23 var key = IPython.utils.keycodes;
24 24
25 25 /**
26 26 * Construct a new TextCell, codemirror mode is by default 'htmlmixed', and cell type is 'text'
27 27 * cell start as not redered.
28 28 *
29 29 * @class TextCell
30 30 * @constructor TextCell
31 31 * @extend IPython.Cell
32 32 * @param {object|undefined} [options]
33 33 * @param [options.cm_config] {object} config to pass to CodeMirror, will extend/overwrite default config
34 34 * @param [options.placeholder] {string} default string to use when souce in empty for rendering (only use in some TextCell subclass)
35 35 */
36 36 var TextCell = function (options) {
37 37 // in all TextCell/Cell subclasses
38 38 // do not assign most of members here, just pass it down
39 39 // in the options dict potentially overwriting what you wish.
40 40 // they will be assigned in the base class.
41 41
42 42 // we cannot put this as a class key as it has handle to "this".
43 43 var cm_overwrite_options = {
44 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
44 onKeyEvent: $.proxy(this.handle_keyevent,this)
45 45 };
46 46
47 47 options = this.mergeopt(TextCell,options,{cm_config:cm_overwrite_options});
48 48
49 49 this.cell_type = this.cell_type || 'text';
50 50
51 51 IPython.Cell.apply(this, [options]);
52 52
53 53 this.rendered = false;
54 54 };
55 55
56 56 TextCell.prototype = new IPython.Cell();
57 57
58 58 TextCell.options_default = {
59 59 cm_config : {
60 60 extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess"},
61 61 mode: 'htmlmixed',
62 62 lineWrapping : true,
63 63 }
64 64 };
65 65
66 66
67
68 67 /**
69 68 * Create the DOM element of the TextCell
70 69 * @method create_element
71 70 * @private
72 71 */
73 72 TextCell.prototype.create_element = function () {
74 73 IPython.Cell.prototype.create_element.apply(this, arguments);
75 74
76 75 var cell = $("<div>").addClass('cell text_cell border-box-sizing');
77 76 cell.attr('tabindex','2');
78 77
79 78 var prompt = $('<div/>').addClass('prompt input_prompt');
80 79 cell.append(prompt);
81 80 var inner_cell = $('<div/>').addClass('inner_cell');
82 81 this.celltoolbar = new IPython.CellToolbar(this);
83 82 inner_cell.append(this.celltoolbar.element);
84 83 var input_area = $('<div/>').addClass('text_cell_input border-box-sizing');
85 84 this.code_mirror = CodeMirror(input_area.get(0), this.cm_config);
86 85 // The tabindex=-1 makes this div focusable.
87 86 var render_area = $('<div/>').addClass('text_cell_render border-box-sizing').
88 87 addClass('rendered_html').attr('tabindex','-1');
89 88 inner_cell.append(input_area).append(render_area);
90 89 cell.append(inner_cell);
91 90 this.element = cell;
92 91 };
93 92
94 93
95 94 /**
96 95 * Bind the DOM evet to cell actions
97 96 * Need to be called after TextCell.create_element
98 97 * @private
99 98 * @method bind_event
100 99 */
101 100 TextCell.prototype.bind_events = function () {
102 101 IPython.Cell.prototype.bind_events.apply(this);
103 102 var that = this;
104 this.element.keydown(function (event) {
105 if (event.which === 13 && !event.shiftKey) {
106 if (that.rendered) {
107 that.edit();
108 return false;
109 };
110 };
111 });
103
112 104 this.element.dblclick(function () {
113 that.edit();
105 if (that.selected === false) {
106 $([IPython.events]).trigger('select.Cell', {'cell':that});
107 };
108 $([IPython.events]).trigger('edit_mode.Cell', {cell: that});
114 109 });
115 110 };
116 111
112 TextCell.prototype.handle_keyevent = function (editor, event) {
113
114 // console.log('CM', this.mode, event.which, event.type)
115
116 if (this.mode === 'command') {
117 return true;
118 } else if (this.mode === 'edit') {
119 return this.handle_codemirror_keyevent(editor, event);
120 }
121 };
122
117 123 /**
118 124 * This method gets called in CodeMirror's onKeyDown/onKeyPress
119 125 * handlers and is used to provide custom key handling.
120 126 *
121 127 * Subclass should override this method to have custom handeling
122 128 *
123 129 * @method handle_codemirror_keyevent
124 130 * @param {CodeMirror} editor - The codemirror instance bound to the cell
125 131 * @param {event} event -
126 132 * @return {Boolean} `true` if CodeMirror should ignore the event, `false` Otherwise
127 133 */
128 134 TextCell.prototype.handle_codemirror_keyevent = function (editor, event) {
135 var that = this;
129 136
130 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
137 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey || event.altKey)) {
131 138 // Always ignore shift-enter in CodeMirror as we handle it.
132 139 return true;
140 } else if (event.which === key.UPARROW && event.type === 'keydown') {
141 // If we are not at the top, let CM handle the up arrow and
142 // prevent the global keydown handler from handling it.
143 if (!that.at_top()) {
144 event.stop();
145 return false;
146 } else {
147 return true;
148 };
149 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
150 // If we are not at the bottom, let CM handle the down arrow and
151 // prevent the global keydown handler from handling it.
152 if (!that.at_bottom()) {
153 event.stop();
154 return false;
155 } else {
156 return true;
157 };
158 } else if (event.which === key.ESC && event.type === 'keydown') {
159 if (that.code_mirror.options.keyMap === "vim-insert") {
160 // vim keyMap is active and in insert mode. In this case we leave vim
161 // insert mode, but remain in notebook edit mode.
162 // Let' CM handle this event and prevent global handling.
163 event.stop();
164 return false;
165 } else {
166 // vim keyMap is not active. Leave notebook edit mode.
167 // Don't let CM handle the event, defer to global handling.
168 return true;
169 }
133 170 }
134 171 return false;
135 172 };
136 173
137 /**
138 * Select the current cell and trigger 'focus'
139 * @method select
140 */
174 // Cell level actions
175
141 176 TextCell.prototype.select = function () {
142 IPython.Cell.prototype.select.apply(this);
143 var output = this.element.find("div.text_cell_render");
144 output.trigger('focus');
145 };
146
147 /**
148 * unselect the current cell and `render` it
149 * @method unselect
150 */
151 TextCell.prototype.unselect = function() {
152 // render on selection of another cell
153 this.render();
154 IPython.Cell.prototype.unselect.apply(this);
177 var cont = IPython.Cell.prototype.select.apply(this);
178 if (cont) {
179 if (this.mode === 'edit') {
180 this.code_mirror.refresh();
181 }
182 };
183 return cont;
155 184 };
156 185
157 /**
158 *
159 * put the current cell in edition mode
160 * @method edit
161 */
162 TextCell.prototype.edit = function () {
163 if (this.rendered === true) {
186 TextCell.prototype.unrender = function () {
187 if (this.read_only) return;
188 var cont = IPython.Cell.prototype.unrender.apply(this);
189 if (cont) {
164 190 var text_cell = this.element;
165 191 var output = text_cell.find("div.text_cell_render");
166 192 output.hide();
167 193 text_cell.find('div.text_cell_input').show();
168 this.code_mirror.refresh();
169 this.code_mirror.focus();
170 // We used to need an additional refresh() after the focus, but
171 // it appears that this has been fixed in CM. This bug would show
172 // up on FF when a newly loaded markdown cell was edited.
173 this.rendered = false;
174 194 if (this.get_text() === this.placeholder) {
175 195 this.set_text('');
176 196 this.refresh();
177 197 }
178 }
179 };
180 198
199 };
200 return cont;
201 };
181 202
182 /**
183 * Empty, Subclasses must define render.
184 * @method render
185 */
186 TextCell.prototype.render = function () {};
203 TextCell.prototype.execute = function () {
204 this.render();
205 };
187 206
207 TextCell.prototype.edit_mode = function () {
208 var cont = IPython.Cell.prototype.edit_mode.apply(this);
209 if (cont) {
210 this.unrender();
211 this.focus_editor();
212 };
213 return cont;
214 }
188 215
189 216 /**
190 217 * setter: {{#crossLink "TextCell/set_text"}}{{/crossLink}}
191 218 * @method get_text
192 219 * @retrun {string} CodeMirror current text value
193 220 */
194 221 TextCell.prototype.get_text = function() {
195 222 return this.code_mirror.getValue();
196 223 };
197 224
198 225 /**
199 226 * @param {string} text - Codemiror text value
200 227 * @see TextCell#get_text
201 228 * @method set_text
202 229 * */
203 230 TextCell.prototype.set_text = function(text) {
204 231 this.code_mirror.setValue(text);
205 232 this.code_mirror.refresh();
206 233 };
207 234
208 235 /**
209 236 * setter :{{#crossLink "TextCell/set_rendered"}}{{/crossLink}}
210 237 * @method get_rendered
211 238 * @return {html} html of rendered element
212 239 * */
213 240 TextCell.prototype.get_rendered = function() {
214 241 return this.element.find('div.text_cell_render').html();
215 242 };
216 243
217 244 /**
218 245 * @method set_rendered
219 246 */
220 247 TextCell.prototype.set_rendered = function(text) {
221 248 this.element.find('div.text_cell_render').html(text);
222 249 };
223 250
224 251 /**
225 * not deprecated, but implementation wrong
226 252 * @method at_top
227 * @deprecated
228 * @return {Boolean} true is cell rendered, false otherwise
229 * I doubt this is what it is supposed to do
230 * this implementation is completly false
253 * @return {Boolean}
231 254 */
232 255 TextCell.prototype.at_top = function () {
233 256 if (this.rendered) {
234 257 return true;
235 258 } else {
236 return false;
237 }
259 var cursor = this.code_mirror.getCursor();
260 if (cursor.line === 0 && cursor.ch === 0) {
261 return true;
262 } else {
263 return false;
264 };
265 };
238 266 };
239 267
240
241 268 /**
242 * not deprecated, but implementation wrong
243 269 * @method at_bottom
244 * @deprecated
245 * @return {Boolean} true is cell rendered, false otherwise
246 * I doubt this is what it is supposed to do
247 * this implementation is completly false
270 * @return {Boolean}
248 271 * */
249 272 TextCell.prototype.at_bottom = function () {
250 273 if (this.rendered) {
251 274 return true;
252 275 } else {
253 return false;
254 }
276 var cursor = this.code_mirror.getCursor();
277 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
278 return true;
279 } else {
280 return false;
281 };
282 };
255 283 };
256 284
257 285 /**
258 286 * Create Text cell from JSON
259 287 * @param {json} data - JSON serialized text-cell
260 288 * @method fromJSON
261 289 */
262 290 TextCell.prototype.fromJSON = function (data) {
263 291 IPython.Cell.prototype.fromJSON.apply(this, arguments);
264 292 if (data.cell_type === this.cell_type) {
265 293 if (data.source !== undefined) {
266 294 this.set_text(data.source);
267 295 // make this value the starting point, so that we can only undo
268 296 // to this state, instead of a blank cell
269 297 this.code_mirror.clearHistory();
270 298 this.set_rendered(data.rendered || '');
271 299 this.rendered = false;
272 300 this.render();
273 301 }
274 302 }
275 303 };
276 304
277 305 /** Generate JSON from cell
278 306 * @return {object} cell data serialised to json
279 307 */
280 308 TextCell.prototype.toJSON = function () {
281 309 var data = IPython.Cell.prototype.toJSON.apply(this);
282 310 data.source = this.get_text();
283 311 if (data.source == this.placeholder) {
284 312 data.source = "";
285 313 }
286 314 return data;
287 315 };
288 316
289 317
290 318 /**
291 319 * @class MarkdownCell
292 320 * @constructor MarkdownCell
293 321 * @extends IPython.HTMLCell
294 322 */
295 323 var MarkdownCell = function (options) {
296 324 options = this.mergeopt(MarkdownCell, options);
297 325
298 326 this.cell_type = 'markdown';
299 327 TextCell.apply(this, [options]);
300 328 };
301 329
302 330 MarkdownCell.options_default = {
303 331 cm_config: {
304 332 mode: 'gfm'
305 333 },
306 334 placeholder: "Type *Markdown* and LaTeX: $\\alpha^2$"
307 335 }
308 336
309
310
311
312 337 MarkdownCell.prototype = new TextCell();
313 338
314 339 /**
315 340 * @method render
316 341 */
317 342 MarkdownCell.prototype.render = function () {
318 if (this.rendered === false) {
343 var cont = IPython.TextCell.prototype.render.apply(this);
344 if (cont) {
319 345 var text = this.get_text();
320 346 var math = null;
321 347 if (text === "") { text = this.placeholder; }
322 348 var text_and_math = IPython.mathjaxutils.remove_math(text);
323 349 text = text_and_math[0];
324 350 math = text_and_math[1];
325 351 var html = marked.parser(marked.lexer(text));
326 352 html = $(IPython.mathjaxutils.replace_math(html, math));
327 353 // links in markdown cells should open in new tabs
328 354 html.find("a[href]").not('[href^="#"]').attr("target", "_blank");
329 355 try {
330 356 this.set_rendered(html);
331 357 } catch (e) {
332 358 console.log("Error running Javascript in Markdown:");
333 359 console.log(e);
334 360 this.set_rendered($("<div/>").addClass("js-error").html(
335 361 "Error rendering Markdown!<br/>" + e.toString())
336 362 );
337 363 }
338 364 this.element.find('div.text_cell_input').hide();
339 365 this.element.find("div.text_cell_render").show();
340 this.typeset();
341 this.rendered = true;
342 }
366 this.typeset()
367 };
368 return cont;
343 369 };
344 370
345 371
346 372 // RawCell
347 373
348 374 /**
349 375 * @class RawCell
350 376 * @constructor RawCell
351 377 * @extends IPython.TextCell
352 378 */
353 379 var RawCell = function (options) {
354 options = this.mergeopt(RawCell, options);
355
356 this.cell_type = 'raw';
357 TextCell.apply(this, [options]);
358 380
359 var that = this;
360 this.element.focusout(
361 function() { that.auto_highlight(); }
362 );
381 options = this.mergeopt(RawCell,options)
382 TextCell.apply(this, [options]);
383 this.cell_type = 'raw';
384 // RawCell should always hide its rendered div
385 this.element.find('div.text_cell_render').hide();
363 386 };
364 387
365 388 RawCell.options_default = {
366 389 placeholder : "Write raw LaTeX or other formats here, for use with nbconvert.\n" +
367 390 "It will not be rendered in the notebook.\n" +
368 391 "When passing through nbconvert, a Raw Cell's content is added to the output unmodified."
369 392 };
370 393
371
372
373 394 RawCell.prototype = new TextCell();
374 395
396 /** @method bind_events **/
397 RawCell.prototype.bind_events = function () {
398 TextCell.prototype.bind_events.apply(this);
399 var that = this
400 this.element.focusout(function() {
401 that.auto_highlight();
402 });
403 };
404
375 405 /**
376 406 * Trigger autodetection of highlight scheme for current cell
377 407 * @method auto_highlight
378 408 */
379 409 RawCell.prototype.auto_highlight = function () {
380 410 this._auto_highlight(IPython.config.raw_cell_highlight);
381 411 };
382 412
383 413 /** @method render **/
384 414 RawCell.prototype.render = function () {
385 this.rendered = true;
415 // Make sure that this cell type can never be rendered
416 if (this.rendered) {
417 this.unrender();
418 }
386 419 var text = this.get_text();
387 420 if (text === "") { text = this.placeholder; }
388 console.log('rendering', text);
389 421 this.set_text(text);
390 422 };
391 423
392 424
393 /** @method handle_codemirror_keyevent **/
394 RawCell.prototype.handle_codemirror_keyevent = function (editor, event) {
395
396 var that = this;
397 if (event.which === key.UPARROW && event.type === 'keydown') {
398 // If we are not at the top, let CM handle the up arrow and
399 // prevent the global keydown handler from handling it.
400 if (!that.at_top()) {
401 event.stop();
402 return false;
403 } else {
404 return true;
405 };
406 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
407 // If we are not at the bottom, let CM handle the down arrow and
408 // prevent the global keydown handler from handling it.
409 if (!that.at_bottom()) {
410 event.stop();
411 return false;
412 } else {
413 return true;
414 };
415 };
416 return false;
417 };
418
419 /** @method select **/
420 RawCell.prototype.select = function () {
421 IPython.Cell.prototype.select.apply(this);
422 this.edit();
423 };
424
425 /** @method at_top **/
426 RawCell.prototype.at_top = function () {
427 var cursor = this.code_mirror.getCursor();
428 if (cursor.line === 0 && cursor.ch === 0) {
429 return true;
430 } else {
431 return false;
432 }
433 };
434
435
436 /** @method at_bottom **/
437 RawCell.prototype.at_bottom = function () {
438 var cursor = this.code_mirror.getCursor();
439 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
440 return true;
441 } else {
442 return false;
443 }
444 };
445
446
447 425 /**
448 426 * @class HeadingCell
449 427 * @extends IPython.TextCell
450 428 */
451 429
452 430 /**
453 431 * @constructor HeadingCell
454 432 * @extends IPython.TextCell
455 433 */
456 434 var HeadingCell = function (options) {
457 435 options = this.mergeopt(HeadingCell, options);
458 436
459 437 this.level = 1;
460 438 this.cell_type = 'heading';
461 439 TextCell.apply(this, [options]);
462 440
463 441 /**
464 442 * heading level of the cell, use getter and setter to access
465 443 * @property level
466 444 */
467 445 };
468 446
469 447 HeadingCell.options_default = {
470 448 placeholder: "Type Heading Here"
471 449 };
472 450
473 451 HeadingCell.prototype = new TextCell();
474 452
475 453 /** @method fromJSON */
476 454 HeadingCell.prototype.fromJSON = function (data) {
477 455 if (data.level != undefined){
478 456 this.level = data.level;
479 457 }
480 458 TextCell.prototype.fromJSON.apply(this, arguments);
481 459 };
482 460
483 461
484 462 /** @method toJSON */
485 463 HeadingCell.prototype.toJSON = function () {
486 464 var data = TextCell.prototype.toJSON.apply(this);
487 465 data.level = this.get_level();
488 466 return data;
489 467 };
490 468
491 469 /**
492 470 * can the cell be split into two cells
493 471 * @method is_splittable
494 472 **/
495 473 HeadingCell.prototype.is_splittable = function () {
496 474 return false;
497 475 };
498 476
499 477
500 478 /**
501 479 * can the cell be merged with other cells
502 480 * @method is_mergeable
503 481 **/
504 482 HeadingCell.prototype.is_mergeable = function () {
505 483 return false;
506 484 };
507 485
508 486 /**
509 487 * Change heading level of cell, and re-render
510 488 * @method set_level
511 489 */
512 490 HeadingCell.prototype.set_level = function (level) {
513 491 this.level = level;
514 492 if (this.rendered) {
515 493 this.rendered = false;
516 494 this.render();
517 495 };
518 496 };
519 497
520 498 /** The depth of header cell, based on html (h1 to h6)
521 499 * @method get_level
522 500 * @return {integer} level - for 1 to 6
523 501 */
524 502 HeadingCell.prototype.get_level = function () {
525 503 return this.level;
526 504 };
527 505
528 506
529 507 HeadingCell.prototype.set_rendered = function (html) {
530 508 this.element.find("div.text_cell_render").html(html);
531 509 };
532 510
533 511
534 512 HeadingCell.prototype.get_rendered = function () {
535 513 var r = this.element.find("div.text_cell_render");
536 514 return r.children().first().html();
537 515 };
538 516
539 517
540 518 HeadingCell.prototype.render = function () {
541 if (this.rendered === false) {
519 var cont = IPython.TextCell.prototype.render.apply(this);
520 if (cont) {
542 521 var text = this.get_text();
543 522 var math = null;
544 523 // Markdown headings must be a single line
545 524 text = text.replace(/\n/g, ' ');
546 525 if (text === "") { text = this.placeholder; }
547 526 text = Array(this.level + 1).join("#") + " " + text;
548 527 var text_and_math = IPython.mathjaxutils.remove_math(text);
549 528 text = text_and_math[0];
550 529 math = text_and_math[1];
551 530 var html = marked.parser(marked.lexer(text));
552 531 var h = $(IPython.mathjaxutils.replace_math(html, math));
553 532 // add id and linkback anchor
554 533 var hash = h.text().replace(/ /g, '-');
555 534 h.attr('id', hash);
556 535 h.append(
557 536 $('<a/>')
558 537 .addClass('anchor-link')
559 538 .attr('href', '#' + hash)
560 539 .text('¶')
561 540 );
562 541
563 542 this.set_rendered(h);
564 543 this.typeset();
565 544 this.element.find('div.text_cell_input').hide();
566 545 this.element.find("div.text_cell_render").show();
567 this.rendered = true;
546
568 547 };
548 return cont;
569 549 };
570 550
571 551 IPython.TextCell = TextCell;
572 552 IPython.MarkdownCell = MarkdownCell;
573 553 IPython.RawCell = RawCell;
574 554 IPython.HeadingCell = HeadingCell;
575 555
576 556
577 557 return IPython;
578 558
579 559 }(IPython));
580 560
@@ -1,39 +1,47 b''
1 1 div.cell {
2 2 border: 1px solid transparent;
3 3 .vbox();
4 4
5 5 &.selected {
6 6 .corner-all;
7 7 border : thin @border_color solid;
8 8 }
9
10 &.edit_mode {
11 .corner-all;
12 border : thin green solid;
13 }
14 }
15
16 div.cell {
9 17 width: 100%;
10 18 padding: 5px 5px 5px 0px;
11 19 /* This acts as a spacer between cells, that is outside the border */
12 20 margin: 0px;
13 21 outline: none;
14 22 }
15 23
16 24 div.prompt {
17 25 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
18 26 min-width: 11ex;
19 27 /* This padding is tuned to match the padding on the CodeMirror editor. */
20 28 padding: @code_padding;
21 29 margin: 0px;
22 30 font-family: @monoFontFamily;
23 31 text-align: right;
24 32 /* This has to match that of the the CodeMirror class line-height below */
25 33 line-height: @code_line_height;
26 34 }
27 35
28 36 div.inner_cell {
29 37 .vbox();
30 38 .box-flex1();
31 39 }
32 40
33 41 /* This is needed so that empty prompt areas can collapse to zero height when there
34 42 is no content in the output_subarea and the prompt. The main purpose of this is
35 43 to make sure that empty JavaScript output_subareas have no height. */
36 44 div.prompt:empty {
37 45 padding-top: 0;
38 46 padding-bottom: 0;
39 47 }
@@ -1,65 +1,67 b''
1 1
2 2 body {
3 3 background-color: @bodyBackground;
4 4 }
5 5
6 6 body.notebook_app {
7 7 overflow: hidden;
8 8 }
9 9
10 10 span#notebook_name {
11 11 height: 1em;
12 12 line-height: 1em;
13 13 padding: 3px;
14 14 border: none;
15 15 font-size: 146.5%;
16 16 }
17 17
18 18 div#notebook_panel {
19 19 margin: 0px 0px 0px 0px;
20 20 padding: 0px;
21 21 .box-shadow(0 -1px 10px rgba(0,0,0,.1));
22 22 }
23 23 div#notebook {
24 24 overflow-y: scroll;
25 25 overflow-x: auto;
26 26 width: 100%;
27 27 /* This spaces the cell away from the edge of the notebook area */
28 28 padding: 5px 5px 15px 5px;
29 29 margin: 0px;
30 30 border-top: 1px solid @border_color;
31 outline: none;
32 .border-box-sizing();
31 33 }
32 34
33 35 div.ui-widget-content {
34 36 border: 1px solid @border_color;
35 37 outline: none;
36 38 }
37 39
38 40 pre.dialog {
39 41 background-color: @cell_background;
40 42 border: 1px solid #ddd;
41 43 .corner-all;
42 44 padding: 0.4em;
43 45 padding-left: 2em;
44 46 }
45 47
46 48 p.dialog {
47 49 padding : 0.2em;
48 50 }
49 51
50 52 /* Word-wrap output correctly. This is the CSS3 spelling, though Firefox seems
51 53 to not honor it correctly. Webkit browsers (Chrome, rekonq, Safari) do.
52 54 */
53 55 pre, code, kbd, samp { white-space: pre-wrap; }
54 56
55 57 #fonttest {
56 58 font-family: @monoFontFamily;
57 59 }
58 60
59 61 p {
60 62 margin-bottom:0;
61 63 }
62 64
63 65 .end_space {
64 66 height: 200px;
65 67 }
@@ -1,15 +1,11 b''
1 1 .shortcut_key {
2 2 display: inline-block;
3 3 width: 15ex;
4 4 text-align: right;
5 5 font-family: @monoFontFamily;
6 6 }
7 7
8 8 .shortcut_descr {
9 9 display: inline-block;
10 10 }
11 11
12 div.quickhelp {
13 float: left;
14 width: 50%;
15 }
@@ -1,152 +1,154 b''
1 1 .clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;}
2 2 .clearfix:after{clear:both;}
3 3 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}
4 4 .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
5 5 .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;}
6 6 .corner-all{border-radius:4px;}
7 7 .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}
8 8 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;}
9 9 .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}
10 10 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;}
11 11 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;}
12 12 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;}
13 13 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
14 14 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
15 15 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;}
16 16 .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1;}
17 17 .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2;}
18 18 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;}
19 19 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;}
20 20 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;}
21 21 div.error{margin:2em;text-align:center;}
22 22 div.error>h1{font-size:500%;line-height:normal;}
23 23 div.error>p{font-size:200%;line-height:normal;}
24 24 div.traceback-wrapper{text-align:left;max-width:800px;margin:auto;}
25 25 .center-nav{display:inline-block;margin-bottom:-4px;}
26 26 .alternate_upload{background-color:none;display:inline;}
27 27 .alternate_upload.form{padding:0;margin:0;}
28 28 .alternate_upload input.fileinput{background-color:red;position:relative;opacity:0;z-index:2;width:295px;margin-left:163px;cursor:pointer;}
29 29 .list_toolbar{padding:5px;height:25px;line-height:25px;}
30 30 .toolbar_info{float:left;}
31 31 .toolbar_buttons{float:right;}
32 32 .list_header{font-weight:bold;}
33 33 .list_container{margin-top:16px;margin-bottom:16px;border:1px solid #ababab;border-radius:4px;}
34 34 .list_container>div{border-bottom:1px solid #ababab;}.list_container>div:hover .list-item{background-color:red;}
35 35 .list_container>div:last-child{border:none;}
36 36 .list_item:hover .list_item{background-color:#ddd;}
37 37 .item_name{line-height:24px;}
38 38 .list_container>div>span,.list_container>div>div{padding:8px;}
39 39 .list_item a{text-decoration:none;}
40 40 input.nbname_input{height:15px;}
41 41 .highlight_text{color:blue;}
42 42 #project_name>.breadcrumb{padding:0px;margin-bottom:0px;background-color:transparent;font-weight:bold;}
43 43 input.engine_num_input{height:20px;margin-bottom:2px;padding-top:0;padding-bottom:0;width:60px;}
44 44 .ansibold{font-weight:bold;}
45 45 .ansiblack{color:black;}
46 46 .ansired{color:darkred;}
47 47 .ansigreen{color:darkgreen;}
48 48 .ansiyellow{color:brown;}
49 49 .ansiblue{color:darkblue;}
50 50 .ansipurple{color:darkviolet;}
51 51 .ansicyan{color:steelblue;}
52 52 .ansigray{color:gray;}
53 53 .ansibgblack{background-color:black;}
54 54 .ansibgred{background-color:red;}
55 55 .ansibggreen{background-color:green;}
56 56 .ansibgyellow{background-color:yellow;}
57 57 .ansibgblue{background-color:blue;}
58 58 .ansibgpurple{background-color:magenta;}
59 59 .ansibgcyan{background-color:cyan;}
60 60 .ansibggray{background-color:gray;}
61 div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
61 div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
62 div.cell.edit_mode{border-radius:4px;border:thin green solid;}
63 div.cell{width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}
62 64 div.prompt{min-width:11ex;padding:0.4em;margin:0px;font-family:monospace;text-align:right;line-height:1.231em;}
63 65 div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
64 66 div.prompt:empty{padding-top:0;padding-bottom:0;}
65 67 div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}
66 68 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7;}
67 69 div.input_prompt{color:navy;border-top:1px solid transparent;}
68 70 .CodeMirror{line-height:1.231em;height:auto;background:none;}
69 71 .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto;}
70 72 @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden;}}.CodeMirror-lines{padding:0.4em;}
71 73 .CodeMirror-linenumber{padding:0 8px 0 4px;}
72 74 .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px;}
73 75 .CodeMirror pre{padding:0;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
74 76 pre code{display:block;padding:0.5em;}
75 77 .highlight-base,pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure .built_in,pre .nginx .title{color:black;}
76 78 .highlight-string,pre .string,pre .constant,pre .parent,pre .tag .value,pre .rules .value,pre .rules .value .number,pre .preprocessor,pre .ruby .symbol,pre .ruby .symbol .string,pre .aggregate,pre .template_tag,pre .django .variable,pre .smalltalk .class,pre .addition,pre .flow,pre .stream,pre .bash .variable,pre .apache .tag,pre .apache .cbracket,pre .tex .command,pre .tex .special,pre .erlang_repl .function_or_atom,pre .markdown .header{color:#BA2121;}
77 79 .highlight-comment,pre .comment,pre .annotation,pre .template_comment,pre .diff .header,pre .chunk,pre .markdown .blockquote{color:#408080;font-style:italic;}
78 80 .highlight-number,pre .number,pre .date,pre .regexp,pre .literal,pre .smalltalk .symbol,pre .smalltalk .char,pre .go .constant,pre .change,pre .markdown .bullet,pre .markdown .link_url{color:#080;}
79 81 pre .label,pre .javadoc,pre .ruby .string,pre .decorator,pre .filter .argument,pre .localvars,pre .array,pre .attr_selector,pre .important,pre .pseudo,pre .pi,pre .doctype,pre .deletion,pre .envvar,pre .shebang,pre .apache .sqbracket,pre .nginx .built_in,pre .tex .formula,pre .erlang_repl .reserved,pre .prompt,pre .markdown .link_label,pre .vhdl .attribute,pre .clojure .attribute,pre .coffeescript .property{color:#8888ff;}
80 82 .highlight-keyword,pre .keyword,pre .id,pre .phpdoc,pre .aggregate,pre .css .tag,pre .javadoctag,pre .phpdoc,pre .yardoctag,pre .smalltalk .class,pre .winutils,pre .bash .variable,pre .apache .tag,pre .go .typename,pre .tex .command,pre .markdown .strong,pre .request,pre .status{color:#008000;font-weight:bold;}
81 83 .highlight-builtin,pre .built_in{color:#008000;}
82 84 pre .markdown .emphasis{font-style:italic;}
83 85 pre .nginx .built_in{font-weight:normal;}
84 86 pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .javascript,pre .xml .vbscript,pre .xml .css,pre .xml .cdata{opacity:0.5;}
85 87 .cm-s-ipython span.cm-variable{color:black;}
86 88 .cm-s-ipython span.cm-keyword{color:#008000;font-weight:bold;}
87 89 .cm-s-ipython span.cm-number{color:#080;}
88 90 .cm-s-ipython span.cm-comment{color:#408080;font-style:italic;}
89 91 .cm-s-ipython span.cm-string{color:#BA2121;}
90 92 .cm-s-ipython span.cm-builtin{color:#008000;}
91 93 .cm-s-ipython span.cm-error{color:#f00;}
92 94 .cm-s-ipython span.cm-operator{color:#AA22FF;font-weight:bold;}
93 95 .cm-s-ipython span.cm-meta{color:#AA22FF;}
94 96 .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat;}
95 97 div.output_wrapper{position:relative;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}
96 98 div.output_scroll{height:24em;width:100%;overflow:auto;border-radius:4px;-webkit-box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);-moz-box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);}
97 99 div.output_collapsed{margin:0px;padding:0px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}
98 100 div.out_prompt_overlay{height:100%;padding:0px 0.4em;position:absolute;border-radius:4px;}
99 101 div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000000;-moz-box-shadow:inset 0 0 1px #000000;box-shadow:inset 0 0 1px #000000;background:rgba(240, 240, 240, 0.5);}
100 102 div.output_prompt{color:darkred;}
101 103 div.output_area{padding:0px;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}div.output_area .MathJax_Display{text-align:left !important;}
102 104 div.output_area .rendered_html table{margin-left:0;margin-right:0;}
103 105 div.output_area .rendered_html img{margin-left:0;margin-right:0;}
104 106 .output{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}
105 107 div.output_area pre{font-family:monospace;margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:black;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit;}
106 108 div.output_subarea{padding:0.4em 0.4em 0em 0.4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
107 109 div.output_text{text-align:left;color:#000000;font-family:monospace;line-height:1.231em;}
108 110 div.output_stderr{background:#fdd;}
109 111 div.output_latex{text-align:left;}
110 112 div.output_javascript:empty{padding:0;}
111 113 .js-error{color:darkred;}
112 114 div.raw_input{padding-top:0px;padding-bottom:0px;height:1em;line-height:1em;font-family:monospace;}
113 115 span.input_prompt{font-family:inherit;}
114 116 input.raw_input{font-family:inherit;font-size:inherit;color:inherit;width:auto;margin:-2px 0px 0px 1px;padding-left:1px;padding-top:2px;height:1em;}
115 117 p.p-space{margin-bottom:10px;}
116 118 .rendered_html{color:black;}.rendered_html em{font-style:italic;}
117 119 .rendered_html strong{font-weight:bold;}
118 120 .rendered_html u{text-decoration:underline;}
119 121 .rendered_html :link{text-decoration:underline;}
120 122 .rendered_html :visited{text-decoration:underline;}
121 123 .rendered_html h1{font-size:197%;margin:.65em 0;font-weight:bold;}
122 124 .rendered_html h2{font-size:153.9%;margin:.75em 0;font-weight:bold;}
123 125 .rendered_html h3{font-size:123.1%;margin:.85em 0;font-weight:bold;}
124 126 .rendered_html h4{font-size:100%;margin:0.95em 0;font-weight:bold;}
125 127 .rendered_html h5{font-size:85%;margin:1.5em 0;font-weight:bold;}
126 128 .rendered_html h6{font-size:77%;margin:1.65em 0;font-weight:bold;}
127 129 .rendered_html ul{list-style:disc;margin:1em 2em;}
128 130 .rendered_html ul ul{list-style:square;margin:0em 2em;}
129 131 .rendered_html ul ul ul{list-style:circle;margin:0em 2em;}
130 132 .rendered_html ol{list-style:decimal;margin:1em 2em;}
131 133 .rendered_html ol ol{list-style:upper-alpha;margin:0em 2em;}
132 134 .rendered_html ol ol ol{list-style:lower-alpha;margin:0em 2em;}
133 135 .rendered_html ol ol ol ol{list-style:lower-roman;margin:0em 2em;}
134 136 .rendered_html ol ol ol ol ol{list-style:decimal;margin:0em 2em;}
135 137 .rendered_html hr{color:black;background-color:black;}
136 138 .rendered_html pre{margin:1em 2em;}
137 139 .rendered_html pre,.rendered_html code{border:0;background-color:#ffffff;color:#000000;font-size:100%;padding:0px;}
138 140 .rendered_html blockquote{margin:1em 2em;}
139 141 .rendered_html table{margin-left:auto;margin-right:auto;border:1px solid black;border-collapse:collapse;}
140 142 .rendered_html tr,.rendered_html th,.rendered_html td{border:1px solid black;border-collapse:collapse;margin:1em 2em;}
141 143 .rendered_html td,.rendered_html th{text-align:left;vertical-align:middle;padding:4px;}
142 144 .rendered_html th{font-weight:bold;}
143 145 .rendered_html p{text-align:justify;}
144 146 .rendered_html img{display:block;margin-left:auto;margin-right:auto;}
145 147 .rendered_html *+p{margin-top:1em;}
146 148 .rendered_html *+table{margin-top:1em;}
147 149 .rendered_html *+img{margin-top:1em;}
148 150 div.text_cell{padding:5px 5px 5px 0px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}
149 151 div.text_cell_input{color:#000000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7;}
150 152 div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:5px;color:#000000;}
151 153 a.anchor-link:link{text-decoration:none;padding:0px 20px;visibility:hidden;}
152 154 h1:hover .anchor-link,h2:hover .anchor-link,h3:hover .anchor-link,h4:hover .anchor-link,h5:hover .anchor-link,h6:hover .anchor-link{visibility:visible;}
@@ -1,1585 +1,1586 b''
1 1 .clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;}
2 2 .clearfix:after{clear:both;}
3 3 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}
4 4 .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
5 5 article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}
6 6 audio,canvas,video{display:inline-block;*display:inline;*zoom:1;}
7 7 audio:not([controls]){display:none;}
8 8 html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}
9 9 a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
10 10 a:hover,a:active{outline:0;}
11 11 sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;}
12 12 sup{top:-0.5em;}
13 13 sub{bottom:-0.25em;}
14 14 img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic;}
15 15 #map_canvas img,.google-maps img{max-width:none;}
16 16 button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}
17 17 button,input{*overflow:visible;line-height:normal;}
18 18 button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}
19 19 button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}
20 20 label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer;}
21 21 input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield;}
22 22 input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;}
23 23 textarea{overflow:auto;vertical-align:top;}
24 24 @media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important;} a,a:visited{text-decoration:underline;} a[href]:after{content:" (" attr(href) ")";} abbr[title]:after{content:" (" attr(title) ")";} .ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:"";} pre,blockquote{border:1px solid #999;page-break-inside:avoid;} thead{display:table-header-group;} tr,img{page-break-inside:avoid;} img{max-width:100% !important;} @page {margin:0.5cm;}p,h2,h3{orphans:3;widows:3;} h2,h3{page-break-after:avoid;}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:20px;color:#000000;background-color:#ffffff;}
25 25 a{color:#0088cc;text-decoration:none;}
26 26 a:hover,a:focus{color:#005580;text-decoration:underline;}
27 27 .img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
28 28 .img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);}
29 29 .img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px;}
30 30 .row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;}
31 31 .row:after{clear:both;}
32 32 .row:before,.row:after{display:table;content:"";line-height:0;}
33 33 .row:after{clear:both;}
34 34 [class*="span"]{float:left;min-height:1px;margin-left:20px;}
35 35 .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}
36 36 .span12{width:940px;}
37 37 .span11{width:860px;}
38 38 .span10{width:780px;}
39 39 .span9{width:700px;}
40 40 .span8{width:620px;}
41 41 .span7{width:540px;}
42 42 .span6{width:460px;}
43 43 .span5{width:380px;}
44 44 .span4{width:300px;}
45 45 .span3{width:220px;}
46 46 .span2{width:140px;}
47 47 .span1{width:60px;}
48 48 .offset12{margin-left:980px;}
49 49 .offset11{margin-left:900px;}
50 50 .offset10{margin-left:820px;}
51 51 .offset9{margin-left:740px;}
52 52 .offset8{margin-left:660px;}
53 53 .offset7{margin-left:580px;}
54 54 .offset6{margin-left:500px;}
55 55 .offset5{margin-left:420px;}
56 56 .offset4{margin-left:340px;}
57 57 .offset3{margin-left:260px;}
58 58 .offset2{margin-left:180px;}
59 59 .offset1{margin-left:100px;}
60 60 .row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;}
61 61 .row:after{clear:both;}
62 62 .row:before,.row:after{display:table;content:"";line-height:0;}
63 63 .row:after{clear:both;}
64 64 [class*="span"]{float:left;min-height:1px;margin-left:20px;}
65 65 .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}
66 66 .span12{width:940px;}
67 67 .span11{width:860px;}
68 68 .span10{width:780px;}
69 69 .span9{width:700px;}
70 70 .span8{width:620px;}
71 71 .span7{width:540px;}
72 72 .span6{width:460px;}
73 73 .span5{width:380px;}
74 74 .span4{width:300px;}
75 75 .span3{width:220px;}
76 76 .span2{width:140px;}
77 77 .span1{width:60px;}
78 78 .offset12{margin-left:980px;}
79 79 .offset11{margin-left:900px;}
80 80 .offset10{margin-left:820px;}
81 81 .offset9{margin-left:740px;}
82 82 .offset8{margin-left:660px;}
83 83 .offset7{margin-left:580px;}
84 84 .offset6{margin-left:500px;}
85 85 .offset5{margin-left:420px;}
86 86 .offset4{margin-left:340px;}
87 87 .offset3{margin-left:260px;}
88 88 .offset2{margin-left:180px;}
89 89 .offset1{margin-left:100px;}
90 90 .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}
91 91 .row-fluid:after{clear:both;}
92 92 .row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}
93 93 .row-fluid:after{clear:both;}
94 94 .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;}
95 95 .row-fluid [class*="span"]:first-child{margin-left:0;}
96 96 .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%;}
97 97 .row-fluid .span12{width:100%;*width:99.94680851063829%;}
98 98 .row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%;}
99 99 .row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%;}
100 100 .row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%;}
101 101 .row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%;}
102 102 .row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%;}
103 103 .row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%;}
104 104 .row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%;}
105 105 .row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%;}
106 106 .row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%;}
107 107 .row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%;}
108 108 .row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%;}
109 109 .row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%;}
110 110 .row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%;}
111 111 .row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%;}
112 112 .row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%;}
113 113 .row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%;}
114 114 .row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%;}
115 115 .row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%;}
116 116 .row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%;}
117 117 .row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%;}
118 118 .row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%;}
119 119 .row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%;}
120 120 .row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%;}
121 121 .row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%;}
122 122 .row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%;}
123 123 .row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%;}
124 124 .row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%;}
125 125 .row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%;}
126 126 .row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%;}
127 127 .row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%;}
128 128 .row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%;}
129 129 .row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%;}
130 130 .row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%;}
131 131 .row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%;}
132 132 .row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%;}
133 133 .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}
134 134 .row-fluid:after{clear:both;}
135 135 .row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}
136 136 .row-fluid:after{clear:both;}
137 137 .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;}
138 138 .row-fluid [class*="span"]:first-child{margin-left:0;}
139 139 .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%;}
140 140 .row-fluid .span12{width:100%;*width:99.94680851063829%;}
141 141 .row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%;}
142 142 .row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%;}
143 143 .row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%;}
144 144 .row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%;}
145 145 .row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%;}
146 146 .row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%;}
147 147 .row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%;}
148 148 .row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%;}
149 149 .row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%;}
150 150 .row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%;}
151 151 .row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%;}
152 152 .row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%;}
153 153 .row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%;}
154 154 .row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%;}
155 155 .row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%;}
156 156 .row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%;}
157 157 .row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%;}
158 158 .row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%;}
159 159 .row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%;}
160 160 .row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%;}
161 161 .row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%;}
162 162 .row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%;}
163 163 .row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%;}
164 164 .row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%;}
165 165 .row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%;}
166 166 .row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%;}
167 167 .row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%;}
168 168 .row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%;}
169 169 .row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%;}
170 170 .row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%;}
171 171 .row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%;}
172 172 .row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%;}
173 173 .row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%;}
174 174 .row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%;}
175 175 .row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%;}
176 176 [class*="span"].hide,.row-fluid [class*="span"].hide{display:none;}
177 177 [class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right;}
178 178 .container{margin-right:auto;margin-left:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";line-height:0;}
179 179 .container:after{clear:both;}
180 180 .container:before,.container:after{display:table;content:"";line-height:0;}
181 181 .container:after{clear:both;}
182 182 .container:before,.container:after{display:table;content:"";line-height:0;}
183 183 .container:after{clear:both;}
184 184 .container:before,.container:after{display:table;content:"";line-height:0;}
185 185 .container:after{clear:both;}
186 186 .container-fluid{padding-right:20px;padding-left:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0;}
187 187 .container-fluid:after{clear:both;}
188 188 .container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0;}
189 189 .container-fluid:after{clear:both;}
190 190 p{margin:0 0 10px;}
191 191 .lead{margin-bottom:20px;font-size:19.5px;font-weight:200;line-height:30px;}
192 192 small{font-size:85%;}
193 193 strong{font-weight:bold;}
194 194 em{font-style:italic;}
195 195 cite{font-style:normal;}
196 196 .muted{color:#999999;}
197 197 a.muted:hover,a.muted:focus{color:#808080;}
198 198 .text-warning{color:#c09853;}
199 199 a.text-warning:hover,a.text-warning:focus{color:#a47e3c;}
200 200 .text-error{color:#b94a48;}
201 201 a.text-error:hover,a.text-error:focus{color:#953b39;}
202 202 .text-info{color:#3a87ad;}
203 203 a.text-info:hover,a.text-info:focus{color:#2d6987;}
204 204 .text-success{color:#468847;}
205 205 a.text-success:hover,a.text-success:focus{color:#356635;}
206 206 .text-left{text-align:left;}
207 207 .text-right{text-align:right;}
208 208 .text-center{text-align:center;}
209 209 h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999999;}
210 210 h1,h2,h3{line-height:40px;}
211 211 h1{font-size:35.75px;}
212 212 h2{font-size:29.25px;}
213 213 h3{font-size:22.75px;}
214 214 h4{font-size:16.25px;}
215 215 h5{font-size:13px;}
216 216 h6{font-size:11.049999999999999px;}
217 217 h1 small{font-size:22.75px;}
218 218 h2 small{font-size:16.25px;}
219 219 h3 small{font-size:13px;}
220 220 h4 small{font-size:13px;}
221 221 .page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eeeeee;}
222 222 ul,ol{padding:0;margin:0 0 10px 25px;}
223 223 ul ul,ul ol,ol ol,ol ul{margin-bottom:0;}
224 224 li{line-height:20px;}
225 225 ul.unstyled,ol.unstyled{margin-left:0;list-style:none;}
226 226 ul.inline,ol.inline{margin-left:0;list-style:none;}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;*zoom:1;padding-left:5px;padding-right:5px;}
227 227 dl{margin-bottom:20px;}
228 228 dt,dd{line-height:20px;}
229 229 dt{font-weight:bold;}
230 230 dd{margin-left:10px;}
231 231 .dl-horizontal{*zoom:1;}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0;}
232 232 .dl-horizontal:after{clear:both;}
233 233 .dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0;}
234 234 .dl-horizontal:after{clear:both;}
235 235 .dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
236 236 .dl-horizontal dd{margin-left:180px;}
237 237 hr{margin:20px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;}
238 238 abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999;}
239 239 abbr.initialism{font-size:90%;text-transform:uppercase;}
240 240 blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16.25px;font-weight:300;line-height:1.25;}
241 241 blockquote small{display:block;line-height:20px;color:#999999;}blockquote small:before{content:'\2014 \00A0';}
242 242 blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;}
243 243 blockquote.pull-right small:before{content:'';}
244 244 blockquote.pull-right small:after{content:'\00A0 \2014';}
245 245 q:before,q:after,blockquote:before,blockquote:after{content:"";}
246 246 address{display:block;margin-bottom:20px;font-style:normal;line-height:20px;}
247 247 code,pre{padding:0 3px 2px;font-family:monospace;font-size:11px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
248 248 code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;white-space:nowrap;}
249 249 pre{display:block;padding:9.5px;margin:0 0 10px;font-size:12px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}pre.prettyprint{margin-bottom:20px;}
250 250 pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0;}
251 251 .pre-scrollable{max-height:340px;overflow-y:scroll;}
252 252 form{margin:0 0 20px;}
253 253 fieldset{padding:0;margin:0;border:0;}
254 254 legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:19.5px;line-height:40px;color:#333333;border:0;border-bottom:1px solid #e5e5e5;}legend small{font-size:15px;color:#999999;}
255 255 label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:20px;}
256 256 input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;}
257 257 label{display:block;margin-bottom:5px;}
258 258 select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:13px;line-height:20px;color:#555555;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;vertical-align:middle;}
259 259 input,textarea,.uneditable-input{width:206px;}
260 260 textarea{height:auto;}
261 261 textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#ffffff;border:1px solid #cccccc;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear .2s, box-shadow linear .2s;-moz-transition:border linear .2s, box-shadow linear .2s;-o-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82, 168, 236, 0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);}
262 262 input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal;}
263 263 input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto;}
264 264 select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px;}
265 265 select{width:220px;border:1px solid #cccccc;background-color:#ffffff;}
266 266 select[multiple],select[size]{height:auto;}
267 267 select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
268 268 .uneditable-input,.uneditable-textarea{color:#999999;background-color:#fcfcfc;border-color:#cccccc;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;}
269 269 .uneditable-input{overflow:hidden;white-space:nowrap;}
270 270 .uneditable-textarea{width:auto;height:auto;}
271 271 input:-moz-placeholder,textarea:-moz-placeholder{color:#999999;}
272 272 input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999999;}
273 273 input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999999;}
274 274 input:-moz-placeholder,textarea:-moz-placeholder{color:#999999;}
275 275 input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999999;}
276 276 input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999999;}
277 277 .radio,.checkbox{min-height:20px;padding-left:20px;}
278 278 .radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px;}
279 279 .controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;}
280 280 .radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;}
281 281 .radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;}
282 282 .input-mini{width:60px;}
283 283 .input-small{width:90px;}
284 284 .input-medium{width:150px;}
285 285 .input-large{width:210px;}
286 286 .input-xlarge{width:270px;}
287 287 .input-xxlarge{width:530px;}
288 288 input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0;}
289 289 .input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block;}
290 290 input,textarea,.uneditable-input{margin-left:0;}
291 291 .controls-row [class*="span"]+[class*="span"]{margin-left:20px;}
292 292 input.span12,textarea.span12,.uneditable-input.span12{width:926px;}
293 293 input.span11,textarea.span11,.uneditable-input.span11{width:846px;}
294 294 input.span10,textarea.span10,.uneditable-input.span10{width:766px;}
295 295 input.span9,textarea.span9,.uneditable-input.span9{width:686px;}
296 296 input.span8,textarea.span8,.uneditable-input.span8{width:606px;}
297 297 input.span7,textarea.span7,.uneditable-input.span7{width:526px;}
298 298 input.span6,textarea.span6,.uneditable-input.span6{width:446px;}
299 299 input.span5,textarea.span5,.uneditable-input.span5{width:366px;}
300 300 input.span4,textarea.span4,.uneditable-input.span4{width:286px;}
301 301 input.span3,textarea.span3,.uneditable-input.span3{width:206px;}
302 302 input.span2,textarea.span2,.uneditable-input.span2{width:126px;}
303 303 input.span1,textarea.span1,.uneditable-input.span1{width:46px;}
304 304 input,textarea,.uneditable-input{margin-left:0;}
305 305 .controls-row [class*="span"]+[class*="span"]{margin-left:20px;}
306 306 input.span12,textarea.span12,.uneditable-input.span12{width:926px;}
307 307 input.span11,textarea.span11,.uneditable-input.span11{width:846px;}
308 308 input.span10,textarea.span10,.uneditable-input.span10{width:766px;}
309 309 input.span9,textarea.span9,.uneditable-input.span9{width:686px;}
310 310 input.span8,textarea.span8,.uneditable-input.span8{width:606px;}
311 311 input.span7,textarea.span7,.uneditable-input.span7{width:526px;}
312 312 input.span6,textarea.span6,.uneditable-input.span6{width:446px;}
313 313 input.span5,textarea.span5,.uneditable-input.span5{width:366px;}
314 314 input.span4,textarea.span4,.uneditable-input.span4{width:286px;}
315 315 input.span3,textarea.span3,.uneditable-input.span3{width:206px;}
316 316 input.span2,textarea.span2,.uneditable-input.span2{width:126px;}
317 317 input.span1,textarea.span1,.uneditable-input.span1{width:46px;}
318 318 .controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0;}
319 319 .controls-row:after{clear:both;}
320 320 .controls-row:before,.controls-row:after{display:table;content:"";line-height:0;}
321 321 .controls-row:after{clear:both;}
322 322 .controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left;}
323 323 .controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px;}
324 324 input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;}
325 325 input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent;}
326 326 .control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;}
327 327 .control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;}
328 328 .control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;}
329 329 .control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;}
330 330 .control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;}
331 331 .control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;}
332 332 .control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;}
333 333 .control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;}
334 334 .control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;}
335 335 .control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;}
336 336 .control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;}
337 337 .control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;}
338 338 .control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;}
339 339 .control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;}
340 340 .control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;}
341 341 .control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;}
342 342 .control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;}
343 343 .control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;}
344 344 .control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;}
345 345 .control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;}
346 346 .control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;}
347 347 .control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;}
348 348 .control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;}
349 349 .control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;}
350 350 .control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;}
351 351 .control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;}
352 352 .control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;}
353 353 .control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;}
354 354 .control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;}
355 355 .control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;}
356 356 .control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;}
357 357 .control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;}
358 358 input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;}
359 359 .form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0;}
360 360 .form-actions:after{clear:both;}
361 361 .form-actions:before,.form-actions:after{display:table;content:"";line-height:0;}
362 362 .form-actions:after{clear:both;}
363 363 .help-block,.help-inline{color:#262626;}
364 364 .help-block{display:block;margin-bottom:10px;}
365 365 .help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;}
366 366 .input-append,.input-prepend{display:inline-block;margin-bottom:10px;vertical-align:middle;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:13px;}
367 367 .input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;}
368 368 .input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:13px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;}
369 369 .input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
370 370 .input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546;}
371 371 .input-prepend .add-on,.input-prepend .btn{margin-right:-1px;}
372 372 .input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
373 373 .input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
374 374 .input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;}
375 375 .input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
376 376 .input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
377 377 .input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
378 378 .input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
379 379 .input-prepend.input-append .btn-group:first-child{margin-left:0;}
380 380 input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
381 381 .form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
382 382 .form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;}
383 383 .form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;}
384 384 .form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;}
385 385 .form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;}
386 386 .form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle;}
387 387 .form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;}
388 388 .form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block;}
389 389 .form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;}
390 390 .form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;}
391 391 .form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0;}
392 392 .control-group{margin-bottom:10px;}
393 393 legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;}
394 394 .form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;}
395 395 .form-horizontal .control-group:after{clear:both;}
396 396 .form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;}
397 397 .form-horizontal .control-group:after{clear:both;}
398 398 .form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;}
399 399 .form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;}
400 400 .form-horizontal .help-block{margin-bottom:0;}
401 401 .form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px;}
402 402 .form-horizontal .form-actions{padding-left:180px;}
403 403 table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0;}
404 404 .table{width:100%;margin-bottom:20px;}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #dddddd;}
405 405 .table th{font-weight:bold;}
406 406 .table thead th{vertical-align:bottom;}
407 407 .table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0;}
408 408 .table tbody+tbody{border-top:2px solid #dddddd;}
409 409 .table .table{background-color:#ffffff;}
410 410 .table-condensed th,.table-condensed td{padding:4px 5px;}
411 411 .table-bordered{border:1px solid #dddddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th,.table-bordered td{border-left:1px solid #dddddd;}
412 412 .table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;}
413 413 .table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;}
414 414 .table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;}
415 415 .table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
416 416 .table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}
417 417 .table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;}
418 418 .table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;}
419 419 .table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;}
420 420 .table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;}
421 421 .table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9;}
422 422 .table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5;}
423 423 table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0;}
424 424 .table td.span1,.table th.span1{float:none;width:44px;margin-left:0;}
425 425 .table td.span2,.table th.span2{float:none;width:124px;margin-left:0;}
426 426 .table td.span3,.table th.span3{float:none;width:204px;margin-left:0;}
427 427 .table td.span4,.table th.span4{float:none;width:284px;margin-left:0;}
428 428 .table td.span5,.table th.span5{float:none;width:364px;margin-left:0;}
429 429 .table td.span6,.table th.span6{float:none;width:444px;margin-left:0;}
430 430 .table td.span7,.table th.span7{float:none;width:524px;margin-left:0;}
431 431 .table td.span8,.table th.span8{float:none;width:604px;margin-left:0;}
432 432 .table td.span9,.table th.span9{float:none;width:684px;margin-left:0;}
433 433 .table td.span10,.table th.span10{float:none;width:764px;margin-left:0;}
434 434 .table td.span11,.table th.span11{float:none;width:844px;margin-left:0;}
435 435 .table td.span12,.table th.span12{float:none;width:924px;margin-left:0;}
436 436 .table tbody tr.success>td{background-color:#dff0d8;}
437 437 .table tbody tr.error>td{background-color:#f2dede;}
438 438 .table tbody tr.warning>td{background-color:#fcf8e3;}
439 439 .table tbody tr.info>td{background-color:#d9edf7;}
440 440 .table-hover tbody tr.success:hover>td{background-color:#d0e9c6;}
441 441 .table-hover tbody tr.error:hover>td{background-color:#ebcccc;}
442 442 .table-hover tbody tr.warning:hover>td{background-color:#faf2cc;}
443 443 .table-hover tbody tr.info:hover>td{background-color:#c4e3f3;}
444 444 [class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;margin-top:1px;}
445 445 .icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png");}
446 446 .icon-glass{background-position:0 0;}
447 447 .icon-music{background-position:-24px 0;}
448 448 .icon-search{background-position:-48px 0;}
449 449 .icon-envelope{background-position:-72px 0;}
450 450 .icon-heart{background-position:-96px 0;}
451 451 .icon-star{background-position:-120px 0;}
452 452 .icon-star-empty{background-position:-144px 0;}
453 453 .icon-user{background-position:-168px 0;}
454 454 .icon-film{background-position:-192px 0;}
455 455 .icon-th-large{background-position:-216px 0;}
456 456 .icon-th{background-position:-240px 0;}
457 457 .icon-th-list{background-position:-264px 0;}
458 458 .icon-ok{background-position:-288px 0;}
459 459 .icon-remove{background-position:-312px 0;}
460 460 .icon-zoom-in{background-position:-336px 0;}
461 461 .icon-zoom-out{background-position:-360px 0;}
462 462 .icon-off{background-position:-384px 0;}
463 463 .icon-signal{background-position:-408px 0;}
464 464 .icon-cog{background-position:-432px 0;}
465 465 .icon-trash{background-position:-456px 0;}
466 466 .icon-home{background-position:0 -24px;}
467 467 .icon-file{background-position:-24px -24px;}
468 468 .icon-time{background-position:-48px -24px;}
469 469 .icon-road{background-position:-72px -24px;}
470 470 .icon-download-alt{background-position:-96px -24px;}
471 471 .icon-download{background-position:-120px -24px;}
472 472 .icon-upload{background-position:-144px -24px;}
473 473 .icon-inbox{background-position:-168px -24px;}
474 474 .icon-play-circle{background-position:-192px -24px;}
475 475 .icon-repeat{background-position:-216px -24px;}
476 476 .icon-refresh{background-position:-240px -24px;}
477 477 .icon-list-alt{background-position:-264px -24px;}
478 478 .icon-lock{background-position:-287px -24px;}
479 479 .icon-flag{background-position:-312px -24px;}
480 480 .icon-headphones{background-position:-336px -24px;}
481 481 .icon-volume-off{background-position:-360px -24px;}
482 482 .icon-volume-down{background-position:-384px -24px;}
483 483 .icon-volume-up{background-position:-408px -24px;}
484 484 .icon-qrcode{background-position:-432px -24px;}
485 485 .icon-barcode{background-position:-456px -24px;}
486 486 .icon-tag{background-position:0 -48px;}
487 487 .icon-tags{background-position:-25px -48px;}
488 488 .icon-book{background-position:-48px -48px;}
489 489 .icon-bookmark{background-position:-72px -48px;}
490 490 .icon-print{background-position:-96px -48px;}
491 491 .icon-camera{background-position:-120px -48px;}
492 492 .icon-font{background-position:-144px -48px;}
493 493 .icon-bold{background-position:-167px -48px;}
494 494 .icon-italic{background-position:-192px -48px;}
495 495 .icon-text-height{background-position:-216px -48px;}
496 496 .icon-text-width{background-position:-240px -48px;}
497 497 .icon-align-left{background-position:-264px -48px;}
498 498 .icon-align-center{background-position:-288px -48px;}
499 499 .icon-align-right{background-position:-312px -48px;}
500 500 .icon-align-justify{background-position:-336px -48px;}
501 501 .icon-list{background-position:-360px -48px;}
502 502 .icon-indent-left{background-position:-384px -48px;}
503 503 .icon-indent-right{background-position:-408px -48px;}
504 504 .icon-facetime-video{background-position:-432px -48px;}
505 505 .icon-picture{background-position:-456px -48px;}
506 506 .icon-pencil{background-position:0 -72px;}
507 507 .icon-map-marker{background-position:-24px -72px;}
508 508 .icon-adjust{background-position:-48px -72px;}
509 509 .icon-tint{background-position:-72px -72px;}
510 510 .icon-edit{background-position:-96px -72px;}
511 511 .icon-share{background-position:-120px -72px;}
512 512 .icon-check{background-position:-144px -72px;}
513 513 .icon-move{background-position:-168px -72px;}
514 514 .icon-step-backward{background-position:-192px -72px;}
515 515 .icon-fast-backward{background-position:-216px -72px;}
516 516 .icon-backward{background-position:-240px -72px;}
517 517 .icon-play{background-position:-264px -72px;}
518 518 .icon-pause{background-position:-288px -72px;}
519 519 .icon-stop{background-position:-312px -72px;}
520 520 .icon-forward{background-position:-336px -72px;}
521 521 .icon-fast-forward{background-position:-360px -72px;}
522 522 .icon-step-forward{background-position:-384px -72px;}
523 523 .icon-eject{background-position:-408px -72px;}
524 524 .icon-chevron-left{background-position:-432px -72px;}
525 525 .icon-chevron-right{background-position:-456px -72px;}
526 526 .icon-plus-sign{background-position:0 -96px;}
527 527 .icon-minus-sign{background-position:-24px -96px;}
528 528 .icon-remove-sign{background-position:-48px -96px;}
529 529 .icon-ok-sign{background-position:-72px -96px;}
530 530 .icon-question-sign{background-position:-96px -96px;}
531 531 .icon-info-sign{background-position:-120px -96px;}
532 532 .icon-screenshot{background-position:-144px -96px;}
533 533 .icon-remove-circle{background-position:-168px -96px;}
534 534 .icon-ok-circle{background-position:-192px -96px;}
535 535 .icon-ban-circle{background-position:-216px -96px;}
536 536 .icon-arrow-left{background-position:-240px -96px;}
537 537 .icon-arrow-right{background-position:-264px -96px;}
538 538 .icon-arrow-up{background-position:-289px -96px;}
539 539 .icon-arrow-down{background-position:-312px -96px;}
540 540 .icon-share-alt{background-position:-336px -96px;}
541 541 .icon-resize-full{background-position:-360px -96px;}
542 542 .icon-resize-small{background-position:-384px -96px;}
543 543 .icon-plus{background-position:-408px -96px;}
544 544 .icon-minus{background-position:-433px -96px;}
545 545 .icon-asterisk{background-position:-456px -96px;}
546 546 .icon-exclamation-sign{background-position:0 -120px;}
547 547 .icon-gift{background-position:-24px -120px;}
548 548 .icon-leaf{background-position:-48px -120px;}
549 549 .icon-fire{background-position:-72px -120px;}
550 550 .icon-eye-open{background-position:-96px -120px;}
551 551 .icon-eye-close{background-position:-120px -120px;}
552 552 .icon-warning-sign{background-position:-144px -120px;}
553 553 .icon-plane{background-position:-168px -120px;}
554 554 .icon-calendar{background-position:-192px -120px;}
555 555 .icon-random{background-position:-216px -120px;width:16px;}
556 556 .icon-comment{background-position:-240px -120px;}
557 557 .icon-magnet{background-position:-264px -120px;}
558 558 .icon-chevron-up{background-position:-288px -120px;}
559 559 .icon-chevron-down{background-position:-313px -119px;}
560 560 .icon-retweet{background-position:-336px -120px;}
561 561 .icon-shopping-cart{background-position:-360px -120px;}
562 562 .icon-folder-close{background-position:-384px -120px;width:16px;}
563 563 .icon-folder-open{background-position:-408px -120px;width:16px;}
564 564 .icon-resize-vertical{background-position:-432px -119px;}
565 565 .icon-resize-horizontal{background-position:-456px -118px;}
566 566 .icon-hdd{background-position:0 -144px;}
567 567 .icon-bullhorn{background-position:-24px -144px;}
568 568 .icon-bell{background-position:-48px -144px;}
569 569 .icon-certificate{background-position:-72px -144px;}
570 570 .icon-thumbs-up{background-position:-96px -144px;}
571 571 .icon-thumbs-down{background-position:-120px -144px;}
572 572 .icon-hand-right{background-position:-144px -144px;}
573 573 .icon-hand-left{background-position:-168px -144px;}
574 574 .icon-hand-up{background-position:-192px -144px;}
575 575 .icon-hand-down{background-position:-216px -144px;}
576 576 .icon-circle-arrow-right{background-position:-240px -144px;}
577 577 .icon-circle-arrow-left{background-position:-264px -144px;}
578 578 .icon-circle-arrow-up{background-position:-288px -144px;}
579 579 .icon-circle-arrow-down{background-position:-312px -144px;}
580 580 .icon-globe{background-position:-336px -144px;}
581 581 .icon-wrench{background-position:-360px -144px;}
582 582 .icon-tasks{background-position:-384px -144px;}
583 583 .icon-filter{background-position:-408px -144px;}
584 584 .icon-briefcase{background-position:-432px -144px;}
585 585 .icon-fullscreen{background-position:-456px -144px;}
586 586 .dropup,.dropdown{position:relative;}
587 587 .dropdown-toggle{*margin-bottom:-3px;}
588 588 .dropdown-toggle:active,.open .dropdown-toggle{outline:0;}
589 589 .caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";}
590 590 .dropdown .caret{margin-top:8px;margin-left:2px;}
591 591 .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#ffffff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;}
592 592 .dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;}
593 593 .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333333;white-space:nowrap;}
594 594 .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{text-decoration:none;color:#ffffff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);}
595 595 .dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);}
596 596 .dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999999;}
597 597 .dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:default;}
598 598 .open{*z-index:1000;}.open>.dropdown-menu{display:block;}
599 599 .dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990;}
600 600 .pull-right>.dropdown-menu{right:0;left:auto;}
601 601 .dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"";}
602 602 .dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;}
603 603 .dropdown-submenu{position:relative;}
604 604 .dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;}
605 605 .dropdown-submenu:hover>.dropdown-menu{display:block;}
606 606 .dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0;}
607 607 .dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;}
608 608 .dropdown-submenu:hover>a:after{border-left-color:#ffffff;}
609 609 .dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}
610 610 .dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px;}
611 611 .typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
612 612 .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}
613 613 .well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
614 614 .well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
615 615 .fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;}.fade.in{opacity:1;}
616 616 .collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;}
617 617 .close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);}
618 618 button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;}
619 619 .btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:13px;line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #cccccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;}
620 620 .btn:active,.btn.active{background-color:#cccccc \9;}
621 621 .btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;}
622 622 .btn:active,.btn.active{background-color:#cccccc \9;}
623 623 .btn:first-child{*margin-left:0;}
624 624 .btn:first-child{*margin-left:0;}
625 625 .btn:hover,.btn:focus{color:#333333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;}
626 626 .btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
627 627 .btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);}
628 628 .btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
629 629 .btn-large{padding:11px 19px;font-size:16.25px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
630 630 .btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px;}
631 631 .btn-small{padding:2px 10px;font-size:11.049999999999999px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
632 632 .btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0;}
633 633 .btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px;}
634 634 .btn-mini{padding:0 6px;font-size:9.75px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
635 635 .btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
636 636 .btn-block+.btn-block{margin-top:5px;}
637 637 input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;}
638 638 .btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);}
639 639 .btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(to bottom, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0044cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;}
640 640 .btn-primary:active,.btn-primary.active{background-color:#003399 \9;}
641 641 .btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;}
642 642 .btn-primary:active,.btn-primary.active{background-color:#003399 \9;}
643 643 .btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;}
644 644 .btn-warning:active,.btn-warning.active{background-color:#c67605 \9;}
645 645 .btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;}
646 646 .btn-warning:active,.btn-warning.active{background-color:#c67605 \9;}
647 647 .btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;}
648 648 .btn-danger:active,.btn-danger.active{background-color:#942a25 \9;}
649 649 .btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;}
650 650 .btn-danger:active,.btn-danger.active{background-color:#942a25 \9;}
651 651 .btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;}
652 652 .btn-success:active,.btn-success.active{background-color:#408140 \9;}
653 653 .btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;}
654 654 .btn-success:active,.btn-success.active{background-color:#408140 \9;}
655 655 .btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;}
656 656 .btn-info:active,.btn-info.active{background-color:#24748c \9;}
657 657 .btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;}
658 658 .btn-info:active,.btn-info.active{background-color:#24748c \9;}
659 659 .btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;}
660 660 .btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;}
661 661 .btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;}
662 662 .btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;}
663 663 button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;}
664 664 button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;}
665 665 button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;}
666 666 button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;}
667 667 .btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
668 668 .btn-link{border-color:transparent;cursor:pointer;color:#0088cc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
669 669 .btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent;}
670 670 .btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333333;text-decoration:none;}
671 671 .btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em;}.btn-group:first-child{*margin-left:0;}
672 672 .btn-group:first-child{*margin-left:0;}
673 673 .btn-group+.btn-group{margin-left:5px;}
674 674 .btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px;}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px;}
675 675 .btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
676 676 .btn-group>.btn+.btn{margin-left:-1px;}
677 677 .btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:13px;}
678 678 .btn-group>.btn-mini{font-size:9.75px;}
679 679 .btn-group>.btn-small{font-size:11.049999999999999px;}
680 680 .btn-group>.btn-large{font-size:16.25px;}
681 681 .btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
682 682 .btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}
683 683 .btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;}
684 684 .btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;}
685 685 .btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2;}
686 686 .btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;}
687 687 .btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px;}
688 688 .btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px;}
689 689 .btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px;}
690 690 .btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px;}
691 691 .btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);}
692 692 .btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;}
693 693 .btn-group.open .btn-primary.dropdown-toggle{background-color:#0044cc;}
694 694 .btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406;}
695 695 .btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f;}
696 696 .btn-group.open .btn-success.dropdown-toggle{background-color:#51a351;}
697 697 .btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4;}
698 698 .btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;}
699 699 .btn .caret{margin-top:8px;margin-left:0;}
700 700 .btn-large .caret{margin-top:6px;}
701 701 .btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px;}
702 702 .btn-mini .caret,.btn-small .caret{margin-top:8px;}
703 703 .dropup .btn-large .caret{border-bottom-width:5px;}
704 704 .btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;}
705 705 .btn-group-vertical{display:inline-block;*display:inline;*zoom:1;}
706 706 .btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
707 707 .btn-group-vertical>.btn+.btn{margin-left:0;margin-top:-1px;}
708 708 .btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}
709 709 .btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}
710 710 .btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0;}
711 711 .btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;}
712 712 .alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
713 713 .alert,.alert h4{color:#c09853;}
714 714 .alert h4{margin:0;}
715 715 .alert .close{position:relative;top:-2px;right:-21px;line-height:20px;}
716 716 .alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;}
717 717 .alert-success h4{color:#468847;}
718 718 .alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;}
719 719 .alert-danger h4,.alert-error h4{color:#b94a48;}
720 720 .alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;}
721 721 .alert-info h4{color:#3a87ad;}
722 722 .alert-block{padding-top:14px;padding-bottom:14px;}
723 723 .alert-block>p,.alert-block>ul{margin-bottom:0;}
724 724 .alert-block p+p{margin-top:5px;}
725 725 .nav{margin-left:0;margin-bottom:20px;list-style:none;}
726 726 .nav>li>a{display:block;}
727 727 .nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eeeeee;}
728 728 .nav>li>a>img{max-width:none;}
729 729 .nav>.pull-right{float:right;}
730 730 .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;}
731 731 .nav li+.nav-header{margin-top:9px;}
732 732 .nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;}
733 733 .nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);}
734 734 .nav-list>li>a{padding:3px 15px;}
735 735 .nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;}
736 736 .nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px;}
737 737 .nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;}
738 738 .nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0;}
739 739 .nav-tabs:after,.nav-pills:after{clear:both;}
740 740 .nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0;}
741 741 .nav-tabs:after,.nav-pills:after{clear:both;}
742 742 .nav-tabs>li,.nav-pills>li{float:left;}
743 743 .nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;}
744 744 .nav-tabs{border-bottom:1px solid #ddd;}
745 745 .nav-tabs>li{margin-bottom:-1px;}
746 746 .nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eeeeee #eeeeee #dddddd;}
747 747 .nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;}
748 748 .nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
749 749 .nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#ffffff;background-color:#0088cc;}
750 750 .nav-stacked>li{float:none;}
751 751 .nav-stacked>li>a{margin-right:0;}
752 752 .nav-tabs.nav-stacked{border-bottom:0;}
753 753 .nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
754 754 .nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;}
755 755 .nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
756 756 .nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{border-color:#ddd;z-index:2;}
757 757 .nav-pills.nav-stacked>li>a{margin-bottom:3px;}
758 758 .nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;}
759 759 .nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;}
760 760 .nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
761 761 .nav .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;}
762 762 .nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580;}
763 763 .nav-tabs .dropdown-toggle .caret{margin-top:8px;}
764 764 .nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff;}
765 765 .nav-tabs .active .dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;}
766 766 .nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer;}
767 767 .nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#ffffff;background-color:#999999;border-color:#999999;}
768 768 .nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);}
769 769 .tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999999;}
770 770 .tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0;}
771 771 .tabbable:after{clear:both;}
772 772 .tabbable:before,.tabbable:after{display:table;content:"";line-height:0;}
773 773 .tabbable:after{clear:both;}
774 774 .tab-content{overflow:auto;}
775 775 .tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0;}
776 776 .tab-content>.tab-pane,.pill-content>.pill-pane{display:none;}
777 777 .tab-content>.active,.pill-content>.active{display:block;}
778 778 .tabs-below>.nav-tabs{border-top:1px solid #ddd;}
779 779 .tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0;}
780 780 .tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-bottom-color:transparent;border-top-color:#ddd;}
781 781 .tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd;}
782 782 .tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none;}
783 783 .tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;}
784 784 .tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;}
785 785 .tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
786 786 .tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eeeeee #dddddd #eeeeee #eeeeee;}
787 787 .tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;}
788 788 .tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;}
789 789 .tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
790 790 .tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eeeeee #eeeeee #eeeeee #dddddd;}
791 791 .tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;}
792 792 .nav>.disabled>a{color:#999999;}
793 793 .nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;background-color:transparent;cursor:default;}
794 794 .navbar{overflow:visible;margin-bottom:20px;*position:relative;*z-index:2;}
795 795 .navbar-inner{min-height:36px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #ffffff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #ffffff, #f2f2f2);background-image:-o-linear-gradient(top, #ffffff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;}
796 796 .navbar-inner:after{clear:both;}
797 797 .navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;}
798 798 .navbar-inner:after{clear:both;}
799 799 .navbar .container{width:auto;}
800 800 .nav-collapse.collapse{height:auto;overflow:visible;}
801 801 .navbar .brand{float:left;display:block;padding:8px 20px 8px;margin-left:-20px;font-size:20px;font-weight:200;color:#777777;text-shadow:0 1px 0 #ffffff;}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none;}
802 802 .navbar-text{margin-bottom:0;line-height:36px;color:#777777;}
803 803 .navbar-link{color:#777777;}.navbar-link:hover,.navbar-link:focus{color:#333333;}
804 804 .navbar .divider-vertical{height:36px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #ffffff;}
805 805 .navbar .btn,.navbar .btn-group{margin-top:3px;}
806 806 .navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0;}
807 807 .navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0;}
808 808 .navbar-form:after{clear:both;}
809 809 .navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0;}
810 810 .navbar-form:after{clear:both;}
811 811 .navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:3px;}
812 812 .navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0;}
813 813 .navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;}
814 814 .navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;}
815 815 .navbar-search{position:relative;float:left;margin-top:3px;margin-bottom:0;}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
816 816 .navbar-static-top{position:static;margin-bottom:0;}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
817 817 .navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;}
818 818 .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px;}
819 819 .navbar-fixed-bottom .navbar-inner{border-width:1px 0 0;}
820 820 .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
821 821 .navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}
822 822 .navbar-fixed-top{top:0;}
823 823 .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1);}
824 824 .navbar-fixed-bottom{bottom:0;}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1);}
825 825 .navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;}
826 826 .navbar .nav.pull-right{float:right;margin-right:0;}
827 827 .navbar .nav>li{float:left;}
828 828 .navbar .nav>li>a{float:none;padding:8px 15px 8px;color:#777777;text-decoration:none;text-shadow:0 1px 0 #ffffff;}
829 829 .navbar .nav .dropdown-toggle .caret{margin-top:8px;}
830 830 .navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333333;text-decoration:none;}
831 831 .navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);-moz-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);}
832 832 .navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;}
833 833 .navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \9;}
834 834 .navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;}
835 835 .navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \9;}
836 836 .navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);}
837 837 .btn-navbar .icon-bar+.icon-bar{margin-top:3px;}
838 838 .navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;}
839 839 .navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;}
840 840 .navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;}
841 841 .navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;}
842 842 .navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333333;border-bottom-color:#333333;}
843 843 .navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555555;}
844 844 .navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777777;border-bottom-color:#777777;}
845 845 .navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;}
846 846 .navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px;}
847 847 .navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px;}
848 848 .navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}
849 849 .navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222222, #111111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));background-image:-webkit-linear-gradient(top, #222222, #111111);background-image:-o-linear-gradient(top, #222222, #111111);background-image:linear-gradient(to bottom, #222222, #111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525;}
850 850 .navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999999;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#ffffff;}
851 851 .navbar-inverse .brand{color:#999999;}
852 852 .navbar-inverse .navbar-text{color:#999999;}
853 853 .navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#ffffff;}
854 854 .navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#ffffff;background-color:#111111;}
855 855 .navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#ffffff;}
856 856 .navbar-inverse .divider-vertical{border-left-color:#111111;border-right-color:#222222;}
857 857 .navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111111;color:#ffffff;}
858 858 .navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;}
859 859 .navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999999;border-bottom-color:#999999;}
860 860 .navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;}
861 861 .navbar-inverse .navbar-search .search-query{color:#ffffff;background-color:#515151;border-color:#111111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;}
862 862 .navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;}
863 863 .navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;}
864 864 .navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;}
865 865 .navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;}
866 866 .navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;}
867 867 .navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;}
868 868 .navbar-inverse .btn-navbar{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;}
869 869 .navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000000 \9;}
870 870 .navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;}
871 871 .navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000000 \9;}
872 872 .breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.breadcrumb>li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;}.breadcrumb>li>.divider{padding:0 5px;color:#ccc;}
873 873 .breadcrumb>.active{color:#999999;}
874 874 .pagination{margin:20px 0;}
875 875 .pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);}
876 876 .pagination ul>li{display:inline;}
877 877 .pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;border-left-width:0;}
878 878 .pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5;}
879 879 .pagination ul>.active>a,.pagination ul>.active>span{color:#999999;cursor:default;}
880 880 .pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999999;background-color:transparent;cursor:default;}
881 881 .pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
882 882 .pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}
883 883 .pagination-centered{text-align:center;}
884 884 .pagination-right{text-align:right;}
885 885 .pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:16.25px;}
886 886 .pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;}
887 887 .pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;}
888 888 .pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px;}
889 889 .pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px;}
890 890 .pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.049999999999999px;}
891 891 .pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:9.75px;}
892 892 .pager{margin:20px 0;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";line-height:0;}
893 893 .pager:after{clear:both;}
894 894 .pager:before,.pager:after{display:table;content:"";line-height:0;}
895 895 .pager:after{clear:both;}
896 896 .pager li{display:inline;}
897 897 .pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
898 898 .pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5;}
899 899 .pager .next>a,.pager .next>span{float:right;}
900 900 .pager .previous>a,.pager .previous>span{float:left;}
901 901 .pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999999;background-color:#fff;cursor:default;}
902 902 .modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;}
903 903 .modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);}
904 904 .modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;}
905 905 .modal.fade.in{top:10%;}
906 906 .modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;}
907 907 .modal-header h3{margin:0;line-height:30px;}
908 908 .modal-body{position:relative;overflow-y:auto;max-height:400px;padding:15px;}
909 909 .modal-form{margin-bottom:0;}
910 910 .modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0;}
911 911 .modal-footer:after{clear:both;}
912 912 .modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0;}
913 913 .modal-footer:after{clear:both;}
914 914 .modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;}
915 915 .modal-footer .btn-group .btn+.btn{margin-left:-1px;}
916 916 .modal-footer .btn-block+.btn-block{margin-left:0;}
917 917 .tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);}
918 918 .tooltip.top{margin-top:-3px;padding:5px 0;}
919 919 .tooltip.right{margin-left:3px;padding:0 5px;}
920 920 .tooltip.bottom{margin-top:3px;padding:5px 0;}
921 921 .tooltip.left{margin-left:-3px;padding:0 5px;}
922 922 .tooltip-inner{max-width:200px;padding:8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
923 923 .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;}
924 924 .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;}
925 925 .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;}
926 926 .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;}
927 927 .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;}
928 928 .popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#ffffff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);white-space:normal;}.popover.top{margin-top:-10px;}
929 929 .popover.right{margin-left:10px;}
930 930 .popover.bottom{margin-top:10px;}
931 931 .popover.left{margin-left:-10px;}
932 932 .popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;}.popover-title:empty{display:none;}
933 933 .popover-content{padding:9px 14px;}
934 934 .popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid;}
935 935 .popover .arrow{border-width:11px;}
936 936 .popover .arrow:after{border-width:10px;content:"";}
937 937 .popover.top .arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0, 0, 0, 0.25);bottom:-11px;}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#ffffff;}
938 938 .popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0, 0, 0, 0.25);}.popover.right .arrow:after{left:1px;bottom:-10px;border-left-width:0;border-right-color:#ffffff;}
939 939 .popover.bottom .arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0, 0, 0, 0.25);top:-11px;}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#ffffff;}
940 940 .popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0, 0, 0, 0.25);}.popover.left .arrow:after{right:1px;border-right-width:0;border-left-color:#ffffff;bottom:-10px;}
941 941 .thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0;}
942 942 .thumbnails:after{clear:both;}
943 943 .thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0;}
944 944 .thumbnails:after{clear:both;}
945 945 .row-fluid .thumbnails{margin-left:0;}
946 946 .thumbnails>li{float:left;margin-bottom:20px;margin-left:20px;}
947 947 .thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;}
948 948 a.thumbnail:hover,a.thumbnail:focus{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);}
949 949 .thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;}
950 950 .thumbnail .caption{padding:9px;color:#555555;}
951 951 .media,.media-body{overflow:hidden;*overflow:visible;zoom:1;}
952 952 .media,.media .media{margin-top:15px;}
953 953 .media:first-child{margin-top:0;}
954 954 .media-object{display:block;}
955 955 .media-heading{margin:0 0 5px;}
956 956 .media>.pull-left{margin-right:10px;}
957 957 .media>.pull-right{margin-left:10px;}
958 958 .media-list{margin-left:0;list-style:none;}
959 959 .label,.badge{display:inline-block;padding:2px 4px;font-size:10.998px;font-weight:bold;line-height:14px;color:#ffffff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;}
960 960 .label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
961 961 .badge{padding-left:9px;padding-right:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;}
962 962 .label:empty,.badge:empty{display:none;}
963 963 a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer;}
964 964 .label-important,.badge-important{background-color:#b94a48;}
965 965 .label-important[href],.badge-important[href]{background-color:#953b39;}
966 966 .label-warning,.badge-warning{background-color:#f89406;}
967 967 .label-warning[href],.badge-warning[href]{background-color:#c67605;}
968 968 .label-success,.badge-success{background-color:#468847;}
969 969 .label-success[href],.badge-success[href]{background-color:#356635;}
970 970 .label-info,.badge-info{background-color:#3a87ad;}
971 971 .label-info[href],.badge-info[href]{background-color:#2d6987;}
972 972 .label-inverse,.badge-inverse{background-color:#333333;}
973 973 .label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a;}
974 974 .btn .label,.btn .badge{position:relative;top:-1px;}
975 975 .btn-mini .label,.btn-mini .badge{top:0;}
976 976 @-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
977 977 .progress .bar{width:0%;height:100%;color:#ffffff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;}
978 978 .progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);}
979 979 .progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;}
980 980 .progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;}
981 981 .progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);}
982 982 .progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
983 983 .progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);}
984 984 .progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
985 985 .progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);}
986 986 .progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
987 987 .progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);}
988 988 .progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
989 989 .accordion{margin-bottom:20px;}
990 990 .accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
991 991 .accordion-heading{border-bottom:0;}
992 992 .accordion-heading .accordion-toggle{display:block;padding:8px 15px;}
993 993 .accordion-toggle{cursor:pointer;}
994 994 .accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;}
995 995 .carousel{position:relative;margin-bottom:20px;line-height:1;}
996 996 .carousel-inner{overflow:hidden;width:100%;position:relative;}
997 997 .carousel-inner>.item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1;}
998 998 .carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block;}
999 999 .carousel-inner>.active{left:0;}
1000 1000 .carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%;}
1001 1001 .carousel-inner>.next{left:100%;}
1002 1002 .carousel-inner>.prev{left:-100%;}
1003 1003 .carousel-inner>.next.left,.carousel-inner>.prev.right{left:0;}
1004 1004 .carousel-inner>.active.left{left:-100%;}
1005 1005 .carousel-inner>.active.right{left:100%;}
1006 1006 .carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;}
1007 1007 .carousel-control:hover,.carousel-control:focus{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);}
1008 1008 .carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none;}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255, 255, 255, 0.25);border-radius:5px;}
1009 1009 .carousel-indicators .active{background-color:#fff;}
1010 1010 .carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333333;background:rgba(0, 0, 0, 0.75);}
1011 1011 .carousel-caption h4,.carousel-caption p{color:#ffffff;line-height:20px;}
1012 1012 .carousel-caption h4{margin:0 0 5px;}
1013 1013 .carousel-caption p{margin-bottom:0;}
1014 1014 .hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;}
1015 1015 .hero-unit li{line-height:30px;}
1016 1016 .pull-right{float:right;}
1017 1017 .pull-left{float:left;}
1018 1018 .hide{display:none;}
1019 1019 .show{display:block;}
1020 1020 .invisible{visibility:hidden;}
1021 1021 .affix{position:fixed;}
1022 1022 .clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;}
1023 1023 .clearfix:after{clear:both;}
1024 1024 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}
1025 1025 .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
1026 1026 @-ms-viewport{width:device-width;}.hidden{display:none;visibility:hidden;}
1027 1027 .visible-phone{display:none !important;}
1028 1028 .visible-tablet{display:none !important;}
1029 1029 .hidden-desktop{display:none !important;}
1030 1030 .visible-desktop{display:inherit !important;}
1031 1031 @media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}.visible-print{display:none !important;}
1032 1032 @media print{.visible-print{display:inherit !important;} .hidden-print{display:none !important;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} .row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} .row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12,textarea.span12,.uneditable-input.span12{width:1156px;} input.span11,textarea.span11,.uneditable-input.span11{width:1056px;} input.span10,textarea.span10,.uneditable-input.span10{width:956px;} input.span9,textarea.span9,.uneditable-input.span9{width:856px;} input.span8,textarea.span8,.uneditable-input.span8{width:756px;} input.span7,textarea.span7,.uneditable-input.span7{width:656px;} input.span6,textarea.span6,.uneditable-input.span6{width:556px;} input.span5,textarea.span5,.uneditable-input.span5{width:456px;} input.span4,textarea.span4,.uneditable-input.span4{width:356px;} input.span3,textarea.span3,.uneditable-input.span3{width:256px;} input.span2,textarea.span2,.uneditable-input.span2{width:156px;} input.span1,textarea.span1,.uneditable-input.span1{width:56px;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12,textarea.span12,.uneditable-input.span12{width:1156px;} input.span11,textarea.span11,.uneditable-input.span11{width:1056px;} input.span10,textarea.span10,.uneditable-input.span10{width:956px;} input.span9,textarea.span9,.uneditable-input.span9{width:856px;} input.span8,textarea.span8,.uneditable-input.span8{width:756px;} input.span7,textarea.span7,.uneditable-input.span7{width:656px;} input.span6,textarea.span6,.uneditable-input.span6{width:556px;} input.span5,textarea.span5,.uneditable-input.span5{width:456px;} input.span4,textarea.span4,.uneditable-input.span4{width:356px;} input.span3,textarea.span3,.uneditable-input.span3{width:256px;} input.span2,textarea.span2,.uneditable-input.span2{width:156px;} input.span1,textarea.span1,.uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} .row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} .row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:20px;} input.span12,textarea.span12,.uneditable-input.span12{width:710px;} input.span11,textarea.span11,.uneditable-input.span11{width:648px;} input.span10,textarea.span10,.uneditable-input.span10{width:586px;} input.span9,textarea.span9,.uneditable-input.span9{width:524px;} input.span8,textarea.span8,.uneditable-input.span8{width:462px;} input.span7,textarea.span7,.uneditable-input.span7{width:400px;} input.span6,textarea.span6,.uneditable-input.span6{width:338px;} input.span5,textarea.span5,.uneditable-input.span5{width:276px;} input.span4,textarea.span4,.uneditable-input.span4{width:214px;} input.span3,textarea.span3,.uneditable-input.span3{width:152px;} input.span2,textarea.span2,.uneditable-input.span2{width:90px;} input.span1,textarea.span1,.uneditable-input.span1{width:28px;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:20px;} input.span12,textarea.span12,.uneditable-input.span12{width:710px;} input.span11,textarea.span11,.uneditable-input.span11{width:648px;} input.span10,textarea.span10,.uneditable-input.span10{width:586px;} input.span9,textarea.span9,.uneditable-input.span9{width:524px;} input.span8,textarea.span8,.uneditable-input.span8{width:462px;} input.span7,textarea.span7,.uneditable-input.span7{width:400px;} input.span6,textarea.span6,.uneditable-input.span6{width:338px;} input.span5,textarea.span5,.uneditable-input.span5{width:276px;} input.span4,textarea.span4,.uneditable-input.span4{width:214px;} input.span3,textarea.span3,.uneditable-input.span3{width:152px;} input.span2,textarea.span2,.uneditable-input.span2{width:90px;} input.span1,textarea.span1,.uneditable-input.span1{width:28px;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} .thumbnails>li{float:none;margin-left:0;} [class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .row-fluid [class*="offset"]:first-child{margin-left:0;} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto;} .controls-row [class*="span"]+[class*="span"]{margin-left:0;} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;}.modal.fade{top:-100px;} .modal.fade.in{top:20px;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:20px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px;} .media-object{margin-right:0;margin-left:0;} .modal{top:10px;left:10px;right:10px;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:20px;} .navbar-fixed-bottom{margin-top:20px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 10px;} .nav-collapse .nav>li{float:none;} .nav-collapse .nav>li>a{margin-bottom:2px;} .nav-collapse .nav>.divider-vertical{display:none;} .nav-collapse .nav .nav-header{color:#777777;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} .nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2;} .navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999999;} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111111;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .nav-collapse .open>.dropdown-menu{display:block;} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} .nav-collapse .dropdown-menu .divider{display:none;} .nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);} .navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111111;border-bottom-color:#111111;} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}}@font-face{font-family:'FontAwesome';src:url('../components/font-awesome/build/assets/font-awesome/font/fontawesome-webfont.eot?v=3.1.0');src:url('../components/font-awesome/build/assets/font-awesome/font/fontawesome-webfont.eot?#iefix&v=3.1.0') format('embedded-opentype'),url('../components/font-awesome/build/assets/font-awesome/font/fontawesome-webfont.woff?v=3.1.0') format('woff'),url('../components/font-awesome/build/assets/font-awesome/font/fontawesome-webfont.ttf?v=3.1.0') format('truetype'),url('../components/font-awesome/build/assets/font-awesome/font/fontawesome-webfont.svg#fontawesomeregular?v=3.1.0') format('svg');font-weight:normal;font-style:normal;}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;}
1033 1033 [class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none;}
1034 1034 .icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em;}
1035 1035 a [class^="icon-"],a [class*=" icon-"],a [class^="icon-"]:before,a [class*=" icon-"]:before{display:inline;}
1036 1036 [class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.2857142857142858em;text-align:center;}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.5714285714285714em;}
1037 1037 ul.icons-ul{list-style-type:none;text-indent:-0.7142857142857143em;margin-left:2.142857142857143em;}ul.icons-ul>li .icon-li{width:0.7142857142857143em;display:inline-block;text-align:center;}
1038 1038 [class^="icon-"].hide,[class*=" icon-"].hide{display:none;}
1039 1039 .icon-muted{color:#eeeeee;}
1040 1040 .icon-light{color:#ffffff;}
1041 1041 .icon-dark{color:#333333;}
1042 1042 .icon-border{border:solid 1px #eeeeee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
1043 1043 .icon-2x{font-size:2em;}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
1044 1044 .icon-3x{font-size:3em;}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
1045 1045 .icon-4x{font-size:4em;}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
1046 1046 .icon-5x{font-size:5em;}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;}
1047 1047 .pull-right{float:right;}
1048 1048 .pull-left{float:left;}
1049 1049 [class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em;}
1050 1050 [class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em;}
1051 1051 [class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0;}
1052 1052 .icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none;}
1053 1053 .btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em;}
1054 1054 .btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block;}
1055 1055 .nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em;}
1056 1056 .btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em;}
1057 1057 .btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em;}
1058 1058 .btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em;}
1059 1059 .btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0;}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em;}
1060 1060 .btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em;}
1061 1061 .btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em;}
1062 1062 .icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%;}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em;}
1063 1063 .icon-stack .icon-stack-base{font-size:2em;*line-height:1em;}
1064 1064 .icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;}
1065 1065 @-moz-keyframes spin{0%{-moz-transform:rotate(0deg);} 100%{-moz-transform:rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(359deg);}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);} 100%{-o-transform:rotate(359deg);}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg);} 100%{-ms-transform:rotate(359deg);}}@keyframes spin{0%{transform:rotate(0deg);} 100%{transform:rotate(359deg);}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);}
1066 1066 .icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);}
1067 1067 .icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);}
1068 1068 .icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1);}
1069 1069 .icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1);}
1070 1070 .icon-glass:before{content:"\f000";}
1071 1071 .icon-music:before{content:"\f001";}
1072 1072 .icon-search:before{content:"\f002";}
1073 1073 .icon-envelope:before{content:"\f003";}
1074 1074 .icon-heart:before{content:"\f004";}
1075 1075 .icon-star:before{content:"\f005";}
1076 1076 .icon-star-empty:before{content:"\f006";}
1077 1077 .icon-user:before{content:"\f007";}
1078 1078 .icon-film:before{content:"\f008";}
1079 1079 .icon-th-large:before{content:"\f009";}
1080 1080 .icon-th:before{content:"\f00a";}
1081 1081 .icon-th-list:before{content:"\f00b";}
1082 1082 .icon-ok:before{content:"\f00c";}
1083 1083 .icon-remove:before{content:"\f00d";}
1084 1084 .icon-zoom-in:before{content:"\f00e";}
1085 1085 .icon-zoom-out:before{content:"\f010";}
1086 1086 .icon-off:before{content:"\f011";}
1087 1087 .icon-signal:before{content:"\f012";}
1088 1088 .icon-cog:before{content:"\f013";}
1089 1089 .icon-trash:before{content:"\f014";}
1090 1090 .icon-home:before{content:"\f015";}
1091 1091 .icon-file:before{content:"\f016";}
1092 1092 .icon-time:before{content:"\f017";}
1093 1093 .icon-road:before{content:"\f018";}
1094 1094 .icon-download-alt:before{content:"\f019";}
1095 1095 .icon-download:before{content:"\f01a";}
1096 1096 .icon-upload:before{content:"\f01b";}
1097 1097 .icon-inbox:before{content:"\f01c";}
1098 1098 .icon-play-circle:before{content:"\f01d";}
1099 1099 .icon-repeat:before,.icon-rotate-right:before{content:"\f01e";}
1100 1100 .icon-refresh:before{content:"\f021";}
1101 1101 .icon-list-alt:before{content:"\f022";}
1102 1102 .icon-lock:before{content:"\f023";}
1103 1103 .icon-flag:before{content:"\f024";}
1104 1104 .icon-headphones:before{content:"\f025";}
1105 1105 .icon-volume-off:before{content:"\f026";}
1106 1106 .icon-volume-down:before{content:"\f027";}
1107 1107 .icon-volume-up:before{content:"\f028";}
1108 1108 .icon-qrcode:before{content:"\f029";}
1109 1109 .icon-barcode:before{content:"\f02a";}
1110 1110 .icon-tag:before{content:"\f02b";}
1111 1111 .icon-tags:before{content:"\f02c";}
1112 1112 .icon-book:before{content:"\f02d";}
1113 1113 .icon-bookmark:before{content:"\f02e";}
1114 1114 .icon-print:before{content:"\f02f";}
1115 1115 .icon-camera:before{content:"\f030";}
1116 1116 .icon-font:before{content:"\f031";}
1117 1117 .icon-bold:before{content:"\f032";}
1118 1118 .icon-italic:before{content:"\f033";}
1119 1119 .icon-text-height:before{content:"\f034";}
1120 1120 .icon-text-width:before{content:"\f035";}
1121 1121 .icon-align-left:before{content:"\f036";}
1122 1122 .icon-align-center:before{content:"\f037";}
1123 1123 .icon-align-right:before{content:"\f038";}
1124 1124 .icon-align-justify:before{content:"\f039";}
1125 1125 .icon-list:before{content:"\f03a";}
1126 1126 .icon-indent-left:before{content:"\f03b";}
1127 1127 .icon-indent-right:before{content:"\f03c";}
1128 1128 .icon-facetime-video:before{content:"\f03d";}
1129 1129 .icon-picture:before{content:"\f03e";}
1130 1130 .icon-pencil:before{content:"\f040";}
1131 1131 .icon-map-marker:before{content:"\f041";}
1132 1132 .icon-adjust:before{content:"\f042";}
1133 1133 .icon-tint:before{content:"\f043";}
1134 1134 .icon-edit:before{content:"\f044";}
1135 1135 .icon-share:before{content:"\f045";}
1136 1136 .icon-check:before{content:"\f046";}
1137 1137 .icon-move:before{content:"\f047";}
1138 1138 .icon-step-backward:before{content:"\f048";}
1139 1139 .icon-fast-backward:before{content:"\f049";}
1140 1140 .icon-backward:before{content:"\f04a";}
1141 1141 .icon-play:before{content:"\f04b";}
1142 1142 .icon-pause:before{content:"\f04c";}
1143 1143 .icon-stop:before{content:"\f04d";}
1144 1144 .icon-forward:before{content:"\f04e";}
1145 1145 .icon-fast-forward:before{content:"\f050";}
1146 1146 .icon-step-forward:before{content:"\f051";}
1147 1147 .icon-eject:before{content:"\f052";}
1148 1148 .icon-chevron-left:before{content:"\f053";}
1149 1149 .icon-chevron-right:before{content:"\f054";}
1150 1150 .icon-plus-sign:before{content:"\f055";}
1151 1151 .icon-minus-sign:before{content:"\f056";}
1152 1152 .icon-remove-sign:before{content:"\f057";}
1153 1153 .icon-ok-sign:before{content:"\f058";}
1154 1154 .icon-question-sign:before{content:"\f059";}
1155 1155 .icon-info-sign:before{content:"\f05a";}
1156 1156 .icon-screenshot:before{content:"\f05b";}
1157 1157 .icon-remove-circle:before{content:"\f05c";}
1158 1158 .icon-ok-circle:before{content:"\f05d";}
1159 1159 .icon-ban-circle:before{content:"\f05e";}
1160 1160 .icon-arrow-left:before{content:"\f060";}
1161 1161 .icon-arrow-right:before{content:"\f061";}
1162 1162 .icon-arrow-up:before{content:"\f062";}
1163 1163 .icon-arrow-down:before{content:"\f063";}
1164 1164 .icon-share-alt:before,.icon-mail-forward:before{content:"\f064";}
1165 1165 .icon-resize-full:before{content:"\f065";}
1166 1166 .icon-resize-small:before{content:"\f066";}
1167 1167 .icon-plus:before{content:"\f067";}
1168 1168 .icon-minus:before{content:"\f068";}
1169 1169 .icon-asterisk:before{content:"\f069";}
1170 1170 .icon-exclamation-sign:before{content:"\f06a";}
1171 1171 .icon-gift:before{content:"\f06b";}
1172 1172 .icon-leaf:before{content:"\f06c";}
1173 1173 .icon-fire:before{content:"\f06d";}
1174 1174 .icon-eye-open:before{content:"\f06e";}
1175 1175 .icon-eye-close:before{content:"\f070";}
1176 1176 .icon-warning-sign:before{content:"\f071";}
1177 1177 .icon-plane:before{content:"\f072";}
1178 1178 .icon-calendar:before{content:"\f073";}
1179 1179 .icon-random:before{content:"\f074";}
1180 1180 .icon-comment:before{content:"\f075";}
1181 1181 .icon-magnet:before{content:"\f076";}
1182 1182 .icon-chevron-up:before{content:"\f077";}
1183 1183 .icon-chevron-down:before{content:"\f078";}
1184 1184 .icon-retweet:before{content:"\f079";}
1185 1185 .icon-shopping-cart:before{content:"\f07a";}
1186 1186 .icon-folder-close:before{content:"\f07b";}
1187 1187 .icon-folder-open:before{content:"\f07c";}
1188 1188 .icon-resize-vertical:before{content:"\f07d";}
1189 1189 .icon-resize-horizontal:before{content:"\f07e";}
1190 1190 .icon-bar-chart:before{content:"\f080";}
1191 1191 .icon-twitter-sign:before{content:"\f081";}
1192 1192 .icon-facebook-sign:before{content:"\f082";}
1193 1193 .icon-camera-retro:before{content:"\f083";}
1194 1194 .icon-key:before{content:"\f084";}
1195 1195 .icon-cogs:before{content:"\f085";}
1196 1196 .icon-comments:before{content:"\f086";}
1197 1197 .icon-thumbs-up:before{content:"\f087";}
1198 1198 .icon-thumbs-down:before{content:"\f088";}
1199 1199 .icon-star-half:before{content:"\f089";}
1200 1200 .icon-heart-empty:before{content:"\f08a";}
1201 1201 .icon-signout:before{content:"\f08b";}
1202 1202 .icon-linkedin-sign:before{content:"\f08c";}
1203 1203 .icon-pushpin:before{content:"\f08d";}
1204 1204 .icon-external-link:before{content:"\f08e";}
1205 1205 .icon-signin:before{content:"\f090";}
1206 1206 .icon-trophy:before{content:"\f091";}
1207 1207 .icon-github-sign:before{content:"\f092";}
1208 1208 .icon-upload-alt:before{content:"\f093";}
1209 1209 .icon-lemon:before{content:"\f094";}
1210 1210 .icon-phone:before{content:"\f095";}
1211 1211 .icon-check-empty:before{content:"\f096";}
1212 1212 .icon-bookmark-empty:before{content:"\f097";}
1213 1213 .icon-phone-sign:before{content:"\f098";}
1214 1214 .icon-twitter:before{content:"\f099";}
1215 1215 .icon-facebook:before{content:"\f09a";}
1216 1216 .icon-github:before{content:"\f09b";}
1217 1217 .icon-unlock:before{content:"\f09c";}
1218 1218 .icon-credit-card:before{content:"\f09d";}
1219 1219 .icon-rss:before{content:"\f09e";}
1220 1220 .icon-hdd:before{content:"\f0a0";}
1221 1221 .icon-bullhorn:before{content:"\f0a1";}
1222 1222 .icon-bell:before{content:"\f0a2";}
1223 1223 .icon-certificate:before{content:"\f0a3";}
1224 1224 .icon-hand-right:before{content:"\f0a4";}
1225 1225 .icon-hand-left:before{content:"\f0a5";}
1226 1226 .icon-hand-up:before{content:"\f0a6";}
1227 1227 .icon-hand-down:before{content:"\f0a7";}
1228 1228 .icon-circle-arrow-left:before{content:"\f0a8";}
1229 1229 .icon-circle-arrow-right:before{content:"\f0a9";}
1230 1230 .icon-circle-arrow-up:before{content:"\f0aa";}
1231 1231 .icon-circle-arrow-down:before{content:"\f0ab";}
1232 1232 .icon-globe:before{content:"\f0ac";}
1233 1233 .icon-wrench:before{content:"\f0ad";}
1234 1234 .icon-tasks:before{content:"\f0ae";}
1235 1235 .icon-filter:before{content:"\f0b0";}
1236 1236 .icon-briefcase:before{content:"\f0b1";}
1237 1237 .icon-fullscreen:before{content:"\f0b2";}
1238 1238 .icon-group:before{content:"\f0c0";}
1239 1239 .icon-link:before{content:"\f0c1";}
1240 1240 .icon-cloud:before{content:"\f0c2";}
1241 1241 .icon-beaker:before{content:"\f0c3";}
1242 1242 .icon-cut:before{content:"\f0c4";}
1243 1243 .icon-copy:before{content:"\f0c5";}
1244 1244 .icon-paper-clip:before{content:"\f0c6";}
1245 1245 .icon-save:before{content:"\f0c7";}
1246 1246 .icon-sign-blank:before{content:"\f0c8";}
1247 1247 .icon-reorder:before{content:"\f0c9";}
1248 1248 .icon-list-ul:before{content:"\f0ca";}
1249 1249 .icon-list-ol:before{content:"\f0cb";}
1250 1250 .icon-strikethrough:before{content:"\f0cc";}
1251 1251 .icon-underline:before{content:"\f0cd";}
1252 1252 .icon-table:before{content:"\f0ce";}
1253 1253 .icon-magic:before{content:"\f0d0";}
1254 1254 .icon-truck:before{content:"\f0d1";}
1255 1255 .icon-pinterest:before{content:"\f0d2";}
1256 1256 .icon-pinterest-sign:before{content:"\f0d3";}
1257 1257 .icon-google-plus-sign:before{content:"\f0d4";}
1258 1258 .icon-google-plus:before{content:"\f0d5";}
1259 1259 .icon-money:before{content:"\f0d6";}
1260 1260 .icon-caret-down:before{content:"\f0d7";}
1261 1261 .icon-caret-up:before{content:"\f0d8";}
1262 1262 .icon-caret-left:before{content:"\f0d9";}
1263 1263 .icon-caret-right:before{content:"\f0da";}
1264 1264 .icon-columns:before{content:"\f0db";}
1265 1265 .icon-sort:before{content:"\f0dc";}
1266 1266 .icon-sort-down:before{content:"\f0dd";}
1267 1267 .icon-sort-up:before{content:"\f0de";}
1268 1268 .icon-envelope-alt:before{content:"\f0e0";}
1269 1269 .icon-linkedin:before{content:"\f0e1";}
1270 1270 .icon-undo:before,.icon-rotate-left:before{content:"\f0e2";}
1271 1271 .icon-legal:before{content:"\f0e3";}
1272 1272 .icon-dashboard:before{content:"\f0e4";}
1273 1273 .icon-comment-alt:before{content:"\f0e5";}
1274 1274 .icon-comments-alt:before{content:"\f0e6";}
1275 1275 .icon-bolt:before{content:"\f0e7";}
1276 1276 .icon-sitemap:before{content:"\f0e8";}
1277 1277 .icon-umbrella:before{content:"\f0e9";}
1278 1278 .icon-paste:before{content:"\f0ea";}
1279 1279 .icon-lightbulb:before{content:"\f0eb";}
1280 1280 .icon-exchange:before{content:"\f0ec";}
1281 1281 .icon-cloud-download:before{content:"\f0ed";}
1282 1282 .icon-cloud-upload:before{content:"\f0ee";}
1283 1283 .icon-user-md:before{content:"\f0f0";}
1284 1284 .icon-stethoscope:before{content:"\f0f1";}
1285 1285 .icon-suitcase:before{content:"\f0f2";}
1286 1286 .icon-bell-alt:before{content:"\f0f3";}
1287 1287 .icon-coffee:before{content:"\f0f4";}
1288 1288 .icon-food:before{content:"\f0f5";}
1289 1289 .icon-file-alt:before{content:"\f0f6";}
1290 1290 .icon-building:before{content:"\f0f7";}
1291 1291 .icon-hospital:before{content:"\f0f8";}
1292 1292 .icon-ambulance:before{content:"\f0f9";}
1293 1293 .icon-medkit:before{content:"\f0fa";}
1294 1294 .icon-fighter-jet:before{content:"\f0fb";}
1295 1295 .icon-beer:before{content:"\f0fc";}
1296 1296 .icon-h-sign:before{content:"\f0fd";}
1297 1297 .icon-plus-sign-alt:before{content:"\f0fe";}
1298 1298 .icon-double-angle-left:before{content:"\f100";}
1299 1299 .icon-double-angle-right:before{content:"\f101";}
1300 1300 .icon-double-angle-up:before{content:"\f102";}
1301 1301 .icon-double-angle-down:before{content:"\f103";}
1302 1302 .icon-angle-left:before{content:"\f104";}
1303 1303 .icon-angle-right:before{content:"\f105";}
1304 1304 .icon-angle-up:before{content:"\f106";}
1305 1305 .icon-angle-down:before{content:"\f107";}
1306 1306 .icon-desktop:before{content:"\f108";}
1307 1307 .icon-laptop:before{content:"\f109";}
1308 1308 .icon-tablet:before{content:"\f10a";}
1309 1309 .icon-mobile-phone:before{content:"\f10b";}
1310 1310 .icon-circle-blank:before{content:"\f10c";}
1311 1311 .icon-quote-left:before{content:"\f10d";}
1312 1312 .icon-quote-right:before{content:"\f10e";}
1313 1313 .icon-spinner:before{content:"\f110";}
1314 1314 .icon-circle:before{content:"\f111";}
1315 1315 .icon-reply:before,.icon-mail-reply:before{content:"\f112";}
1316 1316 .icon-folder-close-alt:before{content:"\f114";}
1317 1317 .icon-folder-open-alt:before{content:"\f115";}
1318 1318 .icon-expand-alt:before{content:"\f116";}
1319 1319 .icon-collapse-alt:before{content:"\f117";}
1320 1320 .icon-smile:before{content:"\f118";}
1321 1321 .icon-frown:before{content:"\f119";}
1322 1322 .icon-meh:before{content:"\f11a";}
1323 1323 .icon-gamepad:before{content:"\f11b";}
1324 1324 .icon-keyboard:before{content:"\f11c";}
1325 1325 .icon-flag-alt:before{content:"\f11d";}
1326 1326 .icon-flag-checkered:before{content:"\f11e";}
1327 1327 .icon-terminal:before{content:"\f120";}
1328 1328 .icon-code:before{content:"\f121";}
1329 1329 .icon-reply-all:before{content:"\f122";}
1330 1330 .icon-mail-reply-all:before{content:"\f122";}
1331 1331 .icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123";}
1332 1332 .icon-location-arrow:before{content:"\f124";}
1333 1333 .icon-crop:before{content:"\f125";}
1334 1334 .icon-code-fork:before{content:"\f126";}
1335 1335 .icon-unlink:before{content:"\f127";}
1336 1336 .icon-question:before{content:"\f128";}
1337 1337 .icon-info:before{content:"\f129";}
1338 1338 .icon-exclamation:before{content:"\f12a";}
1339 1339 .icon-superscript:before{content:"\f12b";}
1340 1340 .icon-subscript:before{content:"\f12c";}
1341 1341 .icon-eraser:before{content:"\f12d";}
1342 1342 .icon-puzzle-piece:before{content:"\f12e";}
1343 1343 .icon-microphone:before{content:"\f130";}
1344 1344 .icon-microphone-off:before{content:"\f131";}
1345 1345 .icon-shield:before{content:"\f132";}
1346 1346 .icon-calendar-empty:before{content:"\f133";}
1347 1347 .icon-fire-extinguisher:before{content:"\f134";}
1348 1348 .icon-rocket:before{content:"\f135";}
1349 1349 .icon-maxcdn:before{content:"\f136";}
1350 1350 .icon-chevron-sign-left:before{content:"\f137";}
1351 1351 .icon-chevron-sign-right:before{content:"\f138";}
1352 1352 .icon-chevron-sign-up:before{content:"\f139";}
1353 1353 .icon-chevron-sign-down:before{content:"\f13a";}
1354 1354 .icon-html5:before{content:"\f13b";}
1355 1355 .icon-css3:before{content:"\f13c";}
1356 1356 .icon-anchor:before{content:"\f13d";}
1357 1357 .icon-unlock-alt:before{content:"\f13e";}
1358 1358 .icon-bullseye:before{content:"\f140";}
1359 1359 .icon-ellipsis-horizontal:before{content:"\f141";}
1360 1360 .icon-ellipsis-vertical:before{content:"\f142";}
1361 1361 .icon-rss-sign:before{content:"\f143";}
1362 1362 .icon-play-sign:before{content:"\f144";}
1363 1363 .icon-ticket:before{content:"\f145";}
1364 1364 .icon-minus-sign-alt:before{content:"\f146";}
1365 1365 .icon-check-minus:before{content:"\f147";}
1366 1366 .icon-level-up:before{content:"\f148";}
1367 1367 .icon-level-down:before{content:"\f149";}
1368 1368 .icon-check-sign:before{content:"\f14a";}
1369 1369 .icon-edit-sign:before{content:"\f14b";}
1370 1370 .icon-external-link-sign:before{content:"\f14c";}
1371 1371 .icon-share-sign:before{content:"\f14d";}
1372 1372 .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;}
1373 1373 .corner-all{border-radius:4px;}
1374 1374 .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}
1375 1375 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;}
1376 1376 .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}
1377 1377 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;}
1378 1378 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;}
1379 1379 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;}
1380 1380 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
1381 1381 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
1382 1382 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;}
1383 1383 .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1;}
1384 1384 .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2;}
1385 1385 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;}
1386 1386 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;}
1387 1387 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;}
1388 1388 div.error{margin:2em;text-align:center;}
1389 1389 div.error>h1{font-size:500%;line-height:normal;}
1390 1390 div.error>p{font-size:200%;line-height:normal;}
1391 1391 div.traceback-wrapper{text-align:left;max-width:800px;margin:auto;}
1392 1392 body{background-color:white;position:absolute;left:0px;right:0px;top:0px;bottom:0px;overflow:visible;}
1393 1393 div#header{display:none;}
1394 1394 #ipython_notebook{padding-left:16px;}
1395 1395 #noscript{width:auto;padding-top:16px;padding-bottom:16px;text-align:center;font-size:22px;color:red;font-weight:bold;}
1396 1396 #ipython_notebook img{font-family:Verdana,"Helvetica Neue",Arial,Helvetica,Geneva,sans-serif;height:24px;text-decoration:none;color:black;}
1397 1397 #site{width:100%;display:none;}
1398 1398 .ui-button .ui-button-text{padding:0.2em 0.8em;font-size:77%;}
1399 1399 input.ui-button{padding:0.3em 0.9em;}
1400 1400 .navbar span{margin-top:3px;}
1401 1401 span#login_widget{float:right;}
1402 1402 .nav-header{text-transform:none;}
1403 1403 .navbar-nobg{background-color:transparent;background-image:none;}
1404 1404 #header>span{margin-top:10px;}
1405 1405 .modal-body{max-height:500px;}
1406 1406 .center-nav{display:inline-block;margin-bottom:-4px;}
1407 1407 .alternate_upload{background-color:none;display:inline;}
1408 1408 .alternate_upload.form{padding:0;margin:0;}
1409 1409 .alternate_upload input.fileinput{background-color:red;position:relative;opacity:0;z-index:2;width:295px;margin-left:163px;cursor:pointer;}
1410 1410 .list_toolbar{padding:5px;height:25px;line-height:25px;}
1411 1411 .toolbar_info{float:left;}
1412 1412 .toolbar_buttons{float:right;}
1413 1413 .list_header{font-weight:bold;}
1414 1414 .list_container{margin-top:16px;margin-bottom:16px;border:1px solid #ababab;border-radius:4px;}
1415 1415 .list_container>div{border-bottom:1px solid #ababab;}.list_container>div:hover .list-item{background-color:red;}
1416 1416 .list_container>div:last-child{border:none;}
1417 1417 .list_item:hover .list_item{background-color:#ddd;}
1418 1418 .item_name{line-height:24px;}
1419 1419 .list_container>div>span,.list_container>div>div{padding:8px;}
1420 1420 .list_item a{text-decoration:none;}
1421 1421 input.nbname_input{height:15px;}
1422 1422 .highlight_text{color:blue;}
1423 1423 #project_name>.breadcrumb{padding:0px;margin-bottom:0px;background-color:transparent;font-weight:bold;}
1424 1424 input.engine_num_input{height:20px;margin-bottom:2px;padding-top:0;padding-bottom:0;width:60px;}
1425 1425 .ansibold{font-weight:bold;}
1426 1426 .ansiblack{color:black;}
1427 1427 .ansired{color:darkred;}
1428 1428 .ansigreen{color:darkgreen;}
1429 1429 .ansiyellow{color:brown;}
1430 1430 .ansiblue{color:darkblue;}
1431 1431 .ansipurple{color:darkviolet;}
1432 1432 .ansicyan{color:steelblue;}
1433 1433 .ansigray{color:gray;}
1434 1434 .ansibgblack{background-color:black;}
1435 1435 .ansibgred{background-color:red;}
1436 1436 .ansibggreen{background-color:green;}
1437 1437 .ansibgyellow{background-color:yellow;}
1438 1438 .ansibgblue{background-color:blue;}
1439 1439 .ansibgpurple{background-color:magenta;}
1440 1440 .ansibgcyan{background-color:cyan;}
1441 1441 .ansibggray{background-color:gray;}
1442 div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
1442 div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
1443 div.cell.edit_mode{border-radius:4px;border:thin green solid;}
1444 div.cell{width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}
1443 1445 div.prompt{min-width:11ex;padding:0.4em;margin:0px;font-family:monospace;text-align:right;line-height:1.231em;}
1444 1446 div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
1445 1447 div.prompt:empty{padding-top:0;padding-bottom:0;}
1446 1448 div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}
1447 1449 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7;}
1448 1450 div.input_prompt{color:navy;border-top:1px solid transparent;}
1449 1451 .CodeMirror{line-height:1.231em;height:auto;background:none;}
1450 1452 .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto;}
1451 1453 @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden;}}.CodeMirror-lines{padding:0.4em;}
1452 1454 .CodeMirror-linenumber{padding:0 8px 0 4px;}
1453 1455 .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px;}
1454 1456 .CodeMirror pre{padding:0;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
1455 1457 pre code{display:block;padding:0.5em;}
1456 1458 .highlight-base,pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure .built_in,pre .nginx .title{color:black;}
1457 1459 .highlight-string,pre .string,pre .constant,pre .parent,pre .tag .value,pre .rules .value,pre .rules .value .number,pre .preprocessor,pre .ruby .symbol,pre .ruby .symbol .string,pre .aggregate,pre .template_tag,pre .django .variable,pre .smalltalk .class,pre .addition,pre .flow,pre .stream,pre .bash .variable,pre .apache .tag,pre .apache .cbracket,pre .tex .command,pre .tex .special,pre .erlang_repl .function_or_atom,pre .markdown .header{color:#BA2121;}
1458 1460 .highlight-comment,pre .comment,pre .annotation,pre .template_comment,pre .diff .header,pre .chunk,pre .markdown .blockquote{color:#408080;font-style:italic;}
1459 1461 .highlight-number,pre .number,pre .date,pre .regexp,pre .literal,pre .smalltalk .symbol,pre .smalltalk .char,pre .go .constant,pre .change,pre .markdown .bullet,pre .markdown .link_url{color:#080;}
1460 1462 pre .label,pre .javadoc,pre .ruby .string,pre .decorator,pre .filter .argument,pre .localvars,pre .array,pre .attr_selector,pre .important,pre .pseudo,pre .pi,pre .doctype,pre .deletion,pre .envvar,pre .shebang,pre .apache .sqbracket,pre .nginx .built_in,pre .tex .formula,pre .erlang_repl .reserved,pre .prompt,pre .markdown .link_label,pre .vhdl .attribute,pre .clojure .attribute,pre .coffeescript .property{color:#8888ff;}
1461 1463 .highlight-keyword,pre .keyword,pre .id,pre .phpdoc,pre .aggregate,pre .css .tag,pre .javadoctag,pre .phpdoc,pre .yardoctag,pre .smalltalk .class,pre .winutils,pre .bash .variable,pre .apache .tag,pre .go .typename,pre .tex .command,pre .markdown .strong,pre .request,pre .status{color:#008000;font-weight:bold;}
1462 1464 .highlight-builtin,pre .built_in{color:#008000;}
1463 1465 pre .markdown .emphasis{font-style:italic;}
1464 1466 pre .nginx .built_in{font-weight:normal;}
1465 1467 pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .javascript,pre .xml .vbscript,pre .xml .css,pre .xml .cdata{opacity:0.5;}
1466 1468 .cm-s-ipython span.cm-variable{color:black;}
1467 1469 .cm-s-ipython span.cm-keyword{color:#008000;font-weight:bold;}
1468 1470 .cm-s-ipython span.cm-number{color:#080;}
1469 1471 .cm-s-ipython span.cm-comment{color:#408080;font-style:italic;}
1470 1472 .cm-s-ipython span.cm-string{color:#BA2121;}
1471 1473 .cm-s-ipython span.cm-builtin{color:#008000;}
1472 1474 .cm-s-ipython span.cm-error{color:#f00;}
1473 1475 .cm-s-ipython span.cm-operator{color:#AA22FF;font-weight:bold;}
1474 1476 .cm-s-ipython span.cm-meta{color:#AA22FF;}
1475 1477 .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat;}
1476 1478 div.output_wrapper{position:relative;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}
1477 1479 div.output_scroll{height:24em;width:100%;overflow:auto;border-radius:4px;-webkit-box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);-moz-box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);}
1478 1480 div.output_collapsed{margin:0px;padding:0px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}
1479 1481 div.out_prompt_overlay{height:100%;padding:0px 0.4em;position:absolute;border-radius:4px;}
1480 1482 div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000000;-moz-box-shadow:inset 0 0 1px #000000;box-shadow:inset 0 0 1px #000000;background:rgba(240, 240, 240, 0.5);}
1481 1483 div.output_prompt{color:darkred;}
1482 1484 div.output_area{padding:0px;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}div.output_area .MathJax_Display{text-align:left !important;}
1483 1485 div.output_area .rendered_html table{margin-left:0;margin-right:0;}
1484 1486 div.output_area .rendered_html img{margin-left:0;margin-right:0;}
1485 1487 .output{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}
1486 1488 div.output_area pre{font-family:monospace;margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:black;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit;}
1487 1489 div.output_subarea{padding:0.4em 0.4em 0em 0.4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
1488 1490 div.output_text{text-align:left;color:#000000;font-family:monospace;line-height:1.231em;}
1489 1491 div.output_stderr{background:#fdd;}
1490 1492 div.output_latex{text-align:left;}
1491 1493 div.output_javascript:empty{padding:0;}
1492 1494 .js-error{color:darkred;}
1493 1495 div.raw_input{padding-top:0px;padding-bottom:0px;height:1em;line-height:1em;font-family:monospace;}
1494 1496 span.input_prompt{font-family:inherit;}
1495 1497 input.raw_input{font-family:inherit;font-size:inherit;color:inherit;width:auto;margin:-2px 0px 0px 1px;padding-left:1px;padding-top:2px;height:1em;}
1496 1498 p.p-space{margin-bottom:10px;}
1497 1499 .rendered_html{color:black;}.rendered_html em{font-style:italic;}
1498 1500 .rendered_html strong{font-weight:bold;}
1499 1501 .rendered_html u{text-decoration:underline;}
1500 1502 .rendered_html :link{text-decoration:underline;}
1501 1503 .rendered_html :visited{text-decoration:underline;}
1502 1504 .rendered_html h1{font-size:197%;margin:.65em 0;font-weight:bold;}
1503 1505 .rendered_html h2{font-size:153.9%;margin:.75em 0;font-weight:bold;}
1504 1506 .rendered_html h3{font-size:123.1%;margin:.85em 0;font-weight:bold;}
1505 1507 .rendered_html h4{font-size:100%;margin:0.95em 0;font-weight:bold;}
1506 1508 .rendered_html h5{font-size:85%;margin:1.5em 0;font-weight:bold;}
1507 1509 .rendered_html h6{font-size:77%;margin:1.65em 0;font-weight:bold;}
1508 1510 .rendered_html ul{list-style:disc;margin:1em 2em;}
1509 1511 .rendered_html ul ul{list-style:square;margin:0em 2em;}
1510 1512 .rendered_html ul ul ul{list-style:circle;margin:0em 2em;}
1511 1513 .rendered_html ol{list-style:decimal;margin:1em 2em;}
1512 1514 .rendered_html ol ol{list-style:upper-alpha;margin:0em 2em;}
1513 1515 .rendered_html ol ol ol{list-style:lower-alpha;margin:0em 2em;}
1514 1516 .rendered_html ol ol ol ol{list-style:lower-roman;margin:0em 2em;}
1515 1517 .rendered_html ol ol ol ol ol{list-style:decimal;margin:0em 2em;}
1516 1518 .rendered_html hr{color:black;background-color:black;}
1517 1519 .rendered_html pre{margin:1em 2em;}
1518 1520 .rendered_html pre,.rendered_html code{border:0;background-color:#ffffff;color:#000000;font-size:100%;padding:0px;}
1519 1521 .rendered_html blockquote{margin:1em 2em;}
1520 1522 .rendered_html table{margin-left:auto;margin-right:auto;border:1px solid black;border-collapse:collapse;}
1521 1523 .rendered_html tr,.rendered_html th,.rendered_html td{border:1px solid black;border-collapse:collapse;margin:1em 2em;}
1522 1524 .rendered_html td,.rendered_html th{text-align:left;vertical-align:middle;padding:4px;}
1523 1525 .rendered_html th{font-weight:bold;}
1524 1526 .rendered_html p{text-align:justify;}
1525 1527 .rendered_html img{display:block;margin-left:auto;margin-right:auto;}
1526 1528 .rendered_html *+p{margin-top:1em;}
1527 1529 .rendered_html *+table{margin-top:1em;}
1528 1530 .rendered_html *+img{margin-top:1em;}
1529 1531 div.text_cell{padding:5px 5px 5px 0px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}
1530 1532 div.text_cell_input{color:#000000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7;}
1531 1533 div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:5px;color:#000000;}
1532 1534 a.anchor-link:link{text-decoration:none;padding:0px 20px;visibility:hidden;}
1533 1535 h1:hover .anchor-link,h2:hover .anchor-link,h3:hover .anchor-link,h4:hover .anchor-link,h5:hover .anchor-link,h6:hover .anchor-link{visibility:visible;}
1534 1536 body{background-color:#ffffff;}
1535 1537 body.notebook_app{overflow:hidden;}
1536 1538 span#notebook_name{height:1em;line-height:1em;padding:3px;border:none;font-size:146.5%;}
1537 1539 div#notebook_panel{margin:0px 0px 0px 0px;padding:0px;-webkit-box-shadow:0 -1px 10px rgba(0, 0, 0, 0.1);-moz-box-shadow:0 -1px 10px rgba(0, 0, 0, 0.1);box-shadow:0 -1px 10px rgba(0, 0, 0, 0.1);}
1538 div#notebook{overflow-y:scroll;overflow-x:auto;width:100%;padding:5px 5px 15px 5px;margin:0px;border-top:1px solid #ababab;}
1540 div#notebook{overflow-y:scroll;overflow-x:auto;width:100%;padding:5px 5px 15px 5px;margin:0px;border-top:1px solid #ababab;outline:none;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;}
1539 1541 div.ui-widget-content{border:1px solid #ababab;outline:none;}
1540 1542 pre.dialog{background-color:#f7f7f7;border:1px solid #ddd;border-radius:4px;padding:0.4em;padding-left:2em;}
1541 1543 p.dialog{padding:0.2em;}
1542 1544 pre,code,kbd,samp{white-space:pre-wrap;}
1543 1545 #fonttest{font-family:monospace;}
1544 1546 p{margin-bottom:0;}
1545 1547 .end_space{height:200px;}
1546 1548 .celltoolbar{border:thin solid #CFCFCF;border-bottom:none;background:#EEE;border-radius:3px 3px 0px 0px;width:100%;-webkit-box-pack:end;height:22px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;}
1547 1549 .ctb_hideshow{display:none;vertical-align:bottom;padding-right:2px;}
1548 1550 .celltoolbar>div{padding-top:0px;}
1549 1551 .ctb_global_show .ctb_show.ctb_hideshow{display:block;}
1550 1552 .ctb_global_show .ctb_show+.input_area,.ctb_global_show .ctb_show+div.text_cell_input{border-top-right-radius:0px;border-top-left-radius:0px;}
1551 1553 .celltoolbar .button_container select{margin:10px;margin-top:1px;margin-bottom:0px;padding:0;font-size:87%;width:auto;display:inline-block;height:18px;line-height:18px;vertical-align:top;}
1552 1554 .celltoolbar label{display:inline-block;height:15px;line-height:15px;vertical-align:top;}
1553 1555 .celltoolbar label span{font-size:85%;}
1554 1556 .celltoolbar input[type=checkbox]{margin:0px;margin-left:4px;margin-right:4px;}
1555 1557 .celltoolbar .ui-button{border:none;vertical-align:top;height:20px;min-width:30px;}
1556 1558 .completions{position:absolute;z-index:10;overflow:hidden;border:1px solid #ababab;border-radius:4px;-webkit-box-shadow:0px 6px 10px -1px #adadad;-moz-box-shadow:0px 6px 10px -1px #adadad;box-shadow:0px 6px 10px -1px #adadad;}
1557 1559 .completions select{background:white;outline:none;border:none;padding:0px;margin:0px;overflow:auto;font-family:monospace;font-size:110%;color:#000000;}
1558 1560 .completions select option.context{color:#0064cd;}
1559 1561 #menubar .navbar-inner{min-height:28px;border-top:1px;border-radius:0px 0px 4px 4px;}
1560 1562 #menubar .navbar{margin-bottom:8px;}
1561 1563 .nav-wrapper{border-bottom:1px solid #d4d4d4;}
1562 1564 #menubar li.dropdown{line-height:12px;}
1563 1565 #notification_area{z-index:10;}
1564 1566 .notification_widget{color:#777777;padding:1px 12px;margin:2px 4px;z-index:10;border:1px solid #ccc;border-radius:4px;background:rgba(240, 240, 240, 0.5);}
1565 1567 div#pager_splitter{height:8px;}
1566 1568 #pager-container{position:relative;padding:15px 0px;}
1567 1569 div#pager{overflow:auto;display:none;}div#pager pre{font-size:13px;line-height:1.231em;color:#000000;background-color:#f7f7f7;padding:0.4em;}
1568 1570 .shortcut_key{display:inline-block;width:15ex;text-align:right;font-family:monospace;}
1569 1571 .shortcut_descr{display:inline-block;}
1570 div.quickhelp{float:left;width:50%;}
1571 1572 span#save_widget{padding:0px 5px;margin-top:12px;}
1572 1573 span#checkpoint_status,span#autosave_status{font-size:small;}
1573 1574 @media (max-width:767px){span#save_widget{font-size:small;} span#checkpoint_status,span#autosave_status{font-size:x-small;}}@media (max-width:767px){span#checkpoint_status,span#autosave_status{display:none;}}@media (min-width:768px) and (max-width:979px){span#checkpoint_status{display:none;} span#autosave_status{font-size:x-small;}}.toolbar{padding:0px 10px;margin-top:-5px;}.toolbar select,.toolbar label{width:auto;height:26px;vertical-align:middle;margin-right:2px;margin-bottom:0px;display:inline;font-size:92%;margin-left:0.3em;margin-right:0.3em;padding:0px;padding-top:3px;}
1574 1575 .toolbar .btn{padding:2px 8px;}
1575 1576 .toolbar .btn-group{margin-top:0px;}
1576 1577 .toolbar-inner{border:none !important;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;box-shadow:none !important;}
1577 1578 #maintoolbar{margin-bottom:0px;}
1578 1579 @-moz-keyframes fadeOut{from{opacity:1;} to{opacity:0;}}@-webkit-keyframes fadeOut{from{opacity:1;} to{opacity:0;}}@-moz-keyframes fadeIn{from{opacity:0;} to{opacity:1;}}@-webkit-keyframes fadeIn{from{opacity:0;} to{opacity:1;}}.bigtooltip{overflow:auto;height:200px;-webkit-transition-property:height;-webkit-transition-duration:500ms;-moz-transition-property:height;-moz-transition-duration:500ms;transition-property:height;transition-duration:500ms;}
1579 1580 .smalltooltip{-webkit-transition-property:height;-webkit-transition-duration:500ms;-moz-transition-property:height;-moz-transition-duration:500ms;transition-property:height;transition-duration:500ms;text-overflow:ellipsis;overflow:hidden;height:80px;}
1580 1581 .tooltipbuttons{position:absolute;padding-right:15px;top:0px;right:0px;}
1581 1582 .tooltiptext{padding-right:30px;}
1582 1583 .ipython_tooltip{max-width:700px;-webkit-animation:fadeOut 400ms;-moz-animation:fadeOut 400ms;animation:fadeOut 400ms;-webkit-animation:fadeIn 400ms;-moz-animation:fadeIn 400ms;animation:fadeIn 400ms;vertical-align:middle;background-color:#f7f7f7;overflow:visible;border:#ababab 1px solid;outline:none;padding:3px;margin:0px;padding-left:7px;font-family:monospace;min-height:50px;-moz-box-shadow:0px 6px 10px -1px #adadad;-webkit-box-shadow:0px 6px 10px -1px #adadad;box-shadow:0px 6px 10px -1px #adadad;border-radius:4px;position:absolute;z-index:2;}.ipython_tooltip a{float:right;}
1583 1584 .ipython_tooltip .tooltiptext pre{border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;font-size:100%;background-color:#f7f7f7;}
1584 1585 .pretooltiparrow{left:0px;margin:0px;top:-16px;width:40px;height:16px;overflow:hidden;position:absolute;}
1585 1586 .pretooltiparrow:before{background-color:#f7f7f7;border:1px #ababab solid;z-index:11;content:"";position:absolute;left:15px;top:10px;width:25px;height:25px;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);}
@@ -1,306 +1,309 b''
1 1 {% extends "page.html" %}
2 2
3 3 {% block stylesheet %}
4 4
5 5 {% if mathjax_url %}
6 6 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML-full&delayStartupUntil=configured" charset="utf-8"></script>
7 7 {% endif %}
8 8 <script type="text/javascript">
9 9 // MathJax disabled, set as null to distingish from *missing* MathJax,
10 10 // where it will be undefined, and should prompt a dialog later.
11 11 window.mathjax_url = "{{mathjax_url}}";
12 12 </script>
13 13
14 14 <link rel="stylesheet" href="{{ static_url("components/codemirror/lib/codemirror.css") }}">
15 15
16 16 {{super()}}
17 17
18 18 <link rel="stylesheet" href="{{ static_url("notebook/css/override.css") }}" type="text/css" />
19 19
20 20 {% endblock %}
21 21
22 22 {% block params %}
23 23
24 24 data-project="{{project}}"
25 25 data-base-project-url="{{base_project_url}}"
26 26 data-base-kernel-url="{{base_kernel_url}}"
27 27 data-notebook-name="{{notebook_name}}"
28 28 data-notebook-path="{{notebook_path}}"
29 29 class="notebook_app"
30 30
31 31 {% endblock %}
32 32
33 33
34 34 {% block header %}
35 35
36 36 <span id="save_widget" class="nav pull-left">
37 37 <span id="notebook_name"></span>
38 38 <span id="checkpoint_status"></span>
39 39 <span id="autosave_status"></span>
40 40 </span>
41 41
42 42 {% endblock %}
43 43
44 44
45 45 {% block site %}
46 46
47 47 <div id="menubar-container" class="container">
48 48 <div id="menubar">
49 49 <div class="navbar">
50 50 <div class="navbar-inner">
51 51 <div class="container">
52 52 <ul id="menus" class="nav">
53 53 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">File</a>
54 54 <ul class="dropdown-menu">
55 55 <li id="new_notebook"
56 56 title="Make a new notebook (Opens a new window)">
57 57 <a href="#">New</a></li>
58 58 <li id="open_notebook"
59 59 title="Opens a new window with the Dashboard view">
60 60 <a href="#">Open...</a></li>
61 61 <!-- <hr/> -->
62 62 <li class="divider"></li>
63 63 <li id="copy_notebook"
64 64 title="Open a copy of this notebook's contents and start a new kernel">
65 65 <a href="#">Make a Copy...</a></li>
66 66 <li id="rename_notebook"><a href="#">Rename...</a></li>
67 67 <li id="save_checkpoint"><a href="#">Save and Checkpoint</a></li>
68 68 <!-- <hr/> -->
69 69 <li class="divider"></li>
70 70 <li id="restore_checkpoint" class="dropdown-submenu"><a href="#">Revert to Checkpoint</a>
71 71 <ul class="dropdown-menu">
72 72 <li><a href="#"></a></li>
73 73 <li><a href="#"></a></li>
74 74 <li><a href="#"></a></li>
75 75 <li><a href="#"></a></li>
76 76 <li><a href="#"></a></li>
77 77 </ul>
78 78 </li>
79 79 <li class="divider"></li>
80 80 <li id="print_preview"><a href="#">Print Preview</a></li>
81 81 <li class="dropdown-submenu"><a href="#">Download as</a>
82 82 <ul class="dropdown-menu">
83 83 <li id="download_ipynb"><a href="#">IPython Notebook (.ipynb)</a></li>
84 84 <li id="download_py"><a href="#">Python (.py)</a></li>
85 85 <li id="download_html"><a href="#">HTML (.html)</a></li>
86 86 <li id="download_rst"><a href="#">reST (.rst)</a></li>
87 87 </ul>
88 88 </li>
89 89 <li class="divider"></li>
90 90
91 91 <li id="kill_and_exit"
92 92 title="Shutdown this notebook's kernel, and close this window">
93 93 <a href="#" >Close and halt</a></li>
94 94 </ul>
95 95 </li>
96 96 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Edit</a>
97 97 <ul class="dropdown-menu">
98 98 <li id="cut_cell"><a href="#">Cut Cell</a></li>
99 99 <li id="copy_cell"><a href="#">Copy Cell</a></li>
100 100 <li id="paste_cell_above" class="disabled"><a href="#">Paste Cell Above</a></li>
101 101 <li id="paste_cell_below" class="disabled"><a href="#">Paste Cell Below</a></li>
102 102 <li id="paste_cell_replace" class="disabled"><a href="#">Paste Cell &amp; Replace</a></li>
103 103 <li id="delete_cell"><a href="#">Delete Cell</a></li>
104 104 <li id="undelete_cell" class="disabled"><a href="#">Undo Delete Cell</a></li>
105 105 <li class="divider"></li>
106 106 <li id="split_cell"><a href="#">Split Cell</a></li>
107 107 <li id="merge_cell_above"><a href="#">Merge Cell Above</a></li>
108 108 <li id="merge_cell_below"><a href="#">Merge Cell Below</a></li>
109 109 <li class="divider"></li>
110 110 <li id="move_cell_up"><a href="#">Move Cell Up</a></li>
111 111 <li id="move_cell_down"><a href="#">Move Cell Down</a></li>
112 112 <li class="divider"></li>
113 113 <li id="select_previous"><a href="#">Select Previous Cell</a></li>
114 114 <li id="select_next"><a href="#">Select Next Cell</a></li>
115 115 <li class="divider"></li>
116 116 <li id="edit_nb_metadata"><a href="#">Edit Notebook Metadata</a></li>
117 117 </ul>
118 118 </li>
119 119 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">View</a>
120 120 <ul class="dropdown-menu">
121 121 <li id="toggle_header"
122 122 title="Show/Hide the IPython Notebook logo and notebook title (above menu bar)">
123 123 <a href="#">Toggle Header</a></li>
124 124 <li id="toggle_toolbar"
125 125 title="Show/Hide the action icons (below menu bar)">
126 126 <a href="#">Toggle Toolbar</a></li>
127 127 </ul>
128 128 </li>
129 129 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Insert</a>
130 130 <ul class="dropdown-menu">
131 131 <li id="insert_cell_above"
132 132 title="Insert an empty Code cell above the currently active cell">
133 133 <a href="#">Insert Cell Above</a></li>
134 134 <li id="insert_cell_below"
135 135 title="Insert an empty Code cell below the currently active cell">
136 136 <a href="#">Insert Cell Below</a></li>
137 137 </ul>
138 138 </li>
139 139 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Cell</a>
140 140 <ul class="dropdown-menu">
141 141 <li id="run_cell" title="Run this cell, and move cursor to the next one">
142 142 <a href="#">Run</a></li>
143 <li id="run_cell_in_place" title="Run this cell, without moving to the next one">
144 <a href="#">Run in Place</a></li>
143 <li id="run_cell_select_below" title="Run this cell, select below">
144 <a href="#">Run and Select Below</a></li>
145 <li id="run_cell_insert_below" title="Run this cell, insert below">
146 <a href="#">Run and Insert Below</a></li>
145 147 <li id="run_all_cells" title="Run all cells in the notebook">
146 148 <a href="#">Run All</a></li>
147 149 <li id="run_all_cells_above" title="Run all cells above (but not including) this cell">
148 150 <a href="#">Run All Above</a></li>
149 151 <li id="run_all_cells_below" title="Run this cell and all cells below it">
150 152 <a href="#">Run All Below</a></li>
151 153 <li class="divider"></li>
152 154 <li id="change_cell_type" class="dropdown-submenu"
153 155 title="All cells in the notebook have a cell type. By default, new cells are created as 'Code' cells">
154 156 <a href="#">Cell Type</a>
155 157 <ul class="dropdown-menu">
156 158 <li id="to_code"
157 159 title="Contents will be sent to the kernel for execution, and output will display in the footer of cell">
158 160 <a href="#">Code</a></li>
159 161 <li id="to_markdown"
160 162 title="Contents will be rendered as HTML and serve as explanatory text">
161 163 <a href="#">Markdown</a></li>
162 164 <li id="to_raw"
163 165 title="Contents will pass through nbconvert unmodified">
164 166 <a href="#">Raw NBConvert</a></li>
165 167 <li id="to_heading1"><a href="#">Heading 1</a></li>
166 168 <li id="to_heading2"><a href="#">Heading 2</a></li>
167 169 <li id="to_heading3"><a href="#">Heading 3</a></li>
168 170 <li id="to_heading4"><a href="#">Heading 4</a></li>
169 171 <li id="to_heading5"><a href="#">Heading 5</a></li>
170 172 <li id="to_heading6"><a href="#">Heading 6</a></li>
171 173 </ul>
172 174 </li>
173 175 <li class="divider"></li>
174 176 <li id="toggle_output"
175 177 title="Show/Hide the output portion of a Code cell">
176 178 <a href="#">Toggle Current Output</a></li>
177 179 <li id="all_outputs" class="dropdown-submenu"><a href="#">All Output</a>
178 180 <ul class="dropdown-menu">
179 181 <li id="expand_all_output"><a href="#">Expand</a></li>
180 182 <li id="scroll_all_output"><a href="#">Scroll Long</a></li>
181 183 <li id="collapse_all_output"><a href="#">Collapse</a></li>
182 184 <li id="clear_all_output"
183 185 title="Remove the output portion of all Code cells">
184 186 <a href="#">Clear</a></li>
185 187 </ul>
186 188 </li>
187 189 </ul>
188 190 </li>
189 191 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Kernel</a>
190 192 <ul class="dropdown-menu">
191 193 <li id="int_kernel"
192 194 title="Send KeyboardInterrupt (CTRL-C) to the Kernel">
193 195 <a href="#">Interrupt</a></li>
194 196 <li id="restart_kernel"
195 197 title="Restart the Kernel">
196 198 <a href="#">Restart</a></li>
197 199 </ul>
198 200 </li>
199 201 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Help</a>
200 202 <ul class="dropdown-menu" title="Opens in a new window">
201 203 <li><a href="http://ipython.org/documentation.html" target="_blank">IPython Help</a></li>
202 204 <li><a href="http://ipython.org/ipython-doc/stable/interactive/notebook.html" target="_blank">Notebook Help</a></li>
203 205 <li id="keyboard_shortcuts" title="Opens a tooltip with all keyboard shortcuts"><a href="#">Keyboard Shortcuts</a></li>
204 206 <li><a href="http://ipython.org/ipython-doc/dev/interactive/cm_keyboard.html" target="_blank">Editor Shortcuts</a></li>
205 207 <li class="divider"></li>
206 208 <li><a href="http://docs.python.org" target="_blank">Python</a></li>
207 209 <li><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></li>
208 210 <li><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></li>
209 211 <li><a href="http://matplotlib.org/" target="_blank">Matplotlib</a></li>
210 212 <li><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></li>
211 213 <li><a href="http://pandas.pydata.org/pandas-docs/stable/" target="_blank">pandas</a></li>
212 214 </ul>
213 215 </li>
214 216 </ul>
215 217 <div id="notification_area"></div>
216 218 </div>
217 219 </div>
218 220 </div>
219 221 </div>
220 222 <div id="maintoolbar" class="navbar">
221 223 <div class="toolbar-inner navbar-inner navbar-nobg">
222 224 <div id="maintoolbar-container" class="container"></div>
223 225 </div>
224 226 </div>
225 227 </div>
226 228
227 229 <div id="ipython-main-app">
228 230
229 231 <div id="notebook_panel">
230 232 <div id="notebook"></div>
231 233 <div id="pager_splitter"></div>
232 234 <div id="pager">
233 235 <div id='pager_button_area'>
234 236 </div>
235 237 <div id="pager-container" class="container"></div>
236 238 </div>
237 239 </div>
238 240
239 241 </div>
240 242 <div id='tooltip' class='ipython_tooltip' style='display:none'></div>
241 243
242 244
243 245 {% endblock %}
244 246
245 247
246 248 {% block script %}
247 249
248 250 {{super()}}
249 251
250 252 <script src="{{ static_url("components/codemirror/lib/codemirror.js") }}" charset="utf-8"></script>
251 253 <script type="text/javascript">
252 254 CodeMirror.modeURL = "{{ static_url("components/codemirror/mode/%N/%N.js") }}";
253 255 </script>
254 256 <script src="{{ static_url("components/codemirror/addon/mode/loadmode.js") }}" charset="utf-8"></script>
255 257 <script src="{{ static_url("components/codemirror/addon/mode/multiplex.js") }}" charset="utf-8"></script>
256 258 <script src="{{ static_url("components/codemirror/addon/mode/overlay.js") }}" charset="utf-8"></script>
257 259 <script src="{{ static_url("components/codemirror/addon/edit/matchbrackets.js") }}" charset="utf-8"></script>
258 260 <script src="{{ static_url("components/codemirror/addon/comment/comment.js") }}" charset="utf-8"></script>
259 261 <script src="{{ static_url("components/codemirror/mode/htmlmixed/htmlmixed.js") }}" charset="utf-8"></script>
260 262 <script src="{{ static_url("components/codemirror/mode/xml/xml.js") }}" charset="utf-8"></script>
261 263 <script src="{{ static_url("components/codemirror/mode/javascript/javascript.js") }}" charset="utf-8"></script>
262 264 <script src="{{ static_url("components/codemirror/mode/css/css.js") }}" charset="utf-8"></script>
263 265 <script src="{{ static_url("components/codemirror/mode/rst/rst.js") }}" charset="utf-8"></script>
264 266 <script src="{{ static_url("components/codemirror/mode/markdown/markdown.js") }}" charset="utf-8"></script>
265 267 <script src="{{ static_url("components/codemirror/mode/gfm/gfm.js") }}" charset="utf-8"></script>
266 268 <script src="{{ static_url("components/codemirror/mode/python/python.js") }}" charset="utf-8"></script>
267 269 <script src="{{ static_url("notebook/js/codemirror-ipython.js") }}" charset="utf-8"></script>
268 270
269 271 <script src="{{ static_url("components/highlight.js/build/highlight.pack.js") }}" charset="utf-8"></script>
270 272
271 273 <script src="{{ static_url("dateformat/date.format.js") }}" charset="utf-8"></script>
272 274
273 275 <script src="{{ static_url("base/js/events.js") }}" type="text/javascript" charset="utf-8"></script>
274 276 <script src="{{ static_url("base/js/utils.js") }}" type="text/javascript" charset="utf-8"></script>
275 277 <script src="{{ static_url("base/js/dialog.js") }}" type="text/javascript" charset="utf-8"></script>
276 278 <script src="{{ static_url("services/kernels/js/kernel.js") }}" type="text/javascript" charset="utf-8"></script>
277 279 <script src="{{ static_url("services/kernels/js/comm.js") }}" type="text/javascript" charset="utf-8"></script>
278 280 <script src="{{ static_url("services/sessions/js/session.js") }}" type="text/javascript" charset="utf-8"></script>
279 281 <script src="{{ static_url("notebook/js/layoutmanager.js") }}" type="text/javascript" charset="utf-8"></script>
280 282 <script src="{{ static_url("notebook/js/mathjaxutils.js") }}" type="text/javascript" charset="utf-8"></script>
281 283 <script src="{{ static_url("notebook/js/outputarea.js") }}" type="text/javascript" charset="utf-8"></script>
282 284 <script src="{{ static_url("notebook/js/cell.js") }}" type="text/javascript" charset="utf-8"></script>
283 285 <script src="{{ static_url("notebook/js/celltoolbar.js") }}" type="text/javascript" charset="utf-8"></script>
284 286 <script src="{{ static_url("notebook/js/codecell.js") }}" type="text/javascript" charset="utf-8"></script>
285 287 <script src="{{ static_url("notebook/js/completer.js") }}" type="text/javascript" charset="utf-8"></script>
286 288 <script src="{{ static_url("notebook/js/textcell.js") }}" type="text/javascript" charset="utf-8"></script>
287 289 <script src="{{ static_url("notebook/js/savewidget.js") }}" type="text/javascript" charset="utf-8"></script>
288 290 <script src="{{ static_url("notebook/js/quickhelp.js") }}" type="text/javascript" charset="utf-8"></script>
289 291 <script src="{{ static_url("notebook/js/pager.js") }}" type="text/javascript" charset="utf-8"></script>
290 292 <script src="{{ static_url("notebook/js/menubar.js") }}" type="text/javascript" charset="utf-8"></script>
291 293 <script src="{{ static_url("notebook/js/toolbar.js") }}" type="text/javascript" charset="utf-8"></script>
292 294 <script src="{{ static_url("notebook/js/maintoolbar.js") }}" type="text/javascript" charset="utf-8"></script>
293 295 <script src="{{ static_url("notebook/js/notebook.js") }}" type="text/javascript" charset="utf-8"></script>
296 <script src="{{ static_url("notebook/js/keyboardmanager.js") }}" type="text/javascript" charset="utf-8"></script>
294 297 <script src="{{ static_url("notebook/js/notificationwidget.js") }}" type="text/javascript" charset="utf-8"></script>
295 298 <script src="{{ static_url("notebook/js/notificationarea.js") }}" type="text/javascript" charset="utf-8"></script>
296 299 <script src="{{ static_url("notebook/js/tooltip.js") }}" type="text/javascript" charset="utf-8"></script>
297 300 <script src="{{ static_url("notebook/js/config.js") }}" type="text/javascript" charset="utf-8"></script>
298 301 <script src="{{ static_url("notebook/js/main.js") }}" type="text/javascript" charset="utf-8"></script>
299 302
300 303 <script src="{{ static_url("notebook/js/contexthint.js") }}" charset="utf-8"></script>
301 304
302 305 <script src="{{ static_url("notebook/js/celltoolbarpresets/default.js") }}" type="text/javascript" charset="utf-8"></script>
303 306 <script src="{{ static_url("notebook/js/celltoolbarpresets/rawcell.js") }}" type="text/javascript" charset="utf-8"></script>
304 307 <script src="{{ static_url("notebook/js/celltoolbarpresets/slideshow.js") }}" type="text/javascript" charset="utf-8"></script>
305 308
306 309 {% endblock %}
@@ -1,69 +1,71 b''
1 1 //
2 2 // Test code cell execution.
3 3 //
4 4 casper.notebook_test(function () {
5 5 this.evaluate(function () {
6 6 var cell = IPython.notebook.get_cell(0);
7 7 cell.set_text('a=10; print(a)');
8 8 cell.execute();
9 9 });
10 10
11 11 this.wait_for_output(0);
12 12
13 13 // refactor this into just a get_output(0)
14 14 this.then(function () {
15 15 var result = this.get_output_cell(0);
16 16 this.test.assertEquals(result.text, '10\n', 'cell execute (using js)');
17 17 });
18 18
19 19
20 20 // do it again with the keyboard shortcut
21 21 this.thenEvaluate(function () {
22 22 var cell = IPython.notebook.get_cell(0);
23 23 cell.set_text('a=11; print(a)');
24 24 cell.clear_output();
25 25 IPython.utils.press_ctrl_enter();
26 26 });
27 27
28 28 this.wait_for_output(0);
29 29
30 30 this.then(function () {
31 31 var result = this.get_output_cell(0);
32 32 var num_cells = this.get_cells_length();
33 33 this.test.assertEquals(result.text, '11\n', 'cell execute (using ctrl-enter)');
34 this.test.assertEquals(num_cells, 1, ' ^--- does not add a new cell')
34 this.test.assertEquals(num_cells, 2, 'ctrl-enter adds a new cell at the bottom')
35 35 });
36 36
37 37 // do it again with the keyboard shortcut
38 38 this.thenEvaluate(function () {
39 IPython.notebook.select(1);
40 IPython.notebook.delete_cell();
39 41 var cell = IPython.notebook.get_cell(0);
40 42 cell.set_text('a=12; print(a)');
41 43 cell.clear_output();
42 44 IPython.utils.press_shift_enter();
43 45 });
44 46
45 47 this.wait_for_output(0);
46 48
47 49 this.then(function () {
48 50 var result = this.get_output_cell(0);
49 51 var num_cells = this.get_cells_length();
50 52 this.test.assertEquals(result.text, '12\n', 'cell execute (using shift-enter)');
51 this.test.assertEquals(num_cells, 2, ' ^--- adds a new cell')
53 this.test.assertEquals(num_cells, 1, 'shift-enter adds no new cell at the bottom')
52 54 });
53 55
54 56 // press the "play" triangle button in the toolbar
55 57 this.thenEvaluate(function () {
56 58 var cell = IPython.notebook.get_cell(0);
57 59 IPython.notebook.select(0);
58 60 cell.clear_output();
59 61 cell.set_text('a=13; print(a)');
60 62 $('#run_b').click();
61 63 });
62 64
63 65 this.wait_for_output(0);
64 66
65 67 this.then(function () {
66 68 var result = this.get_output_cell(0);
67 69 this.test.assertEquals(result.text, '13\n', 'cell execute (using "play" toolbar button)')
68 70 });
69 71 });
@@ -1,37 +1,38 b''
1 1 //
2 2 // Test merging two notebook cells.
3 3 //
4 4 casper.notebook_test(function() {
5 5 var output = this.evaluate(function () {
6 6 // Fill in test data.
7 IPython.notebook.command_mode();
7 8 var set_cell_text = function () {
8 9 var cell_one = IPython.notebook.get_selected_cell();
9 10 cell_one.set_text('a = 5');
10 11
11 IPython.notebook.insert_cell_below('code');
12 IPython.utils.press(IPython.keycodes.b)
12 13 var cell_two = IPython.notebook.get_selected_cell();
13 14 cell_two.set_text('print(a)');
14 15 };
15 16
16 17 // merge_cell_above()
17 18 set_cell_text();
18 19 IPython.notebook.merge_cell_above();
19 20 var merged_above = IPython.notebook.get_selected_cell();
20 21
21 22 // merge_cell_below()
22 23 set_cell_text();
23 24 IPython.notebook.select(0);
24 25 IPython.notebook.merge_cell_below();
25 26 var merged_below = IPython.notebook.get_selected_cell();
26 27
27 28 return {
28 29 above: merged_above.get_text(),
29 30 below: merged_below.get_text()
30 31 };
31 32 });
32 33
33 34 this.test.assertEquals(output.above, 'a = 5\nprint(a)',
34 'Successful insert_cell_above().');
35 'Successful merge_cell_above().');
35 36 this.test.assertEquals(output.below, 'a = 5\nprint(a)',
36 'Successful insert_cell_below().');
37 'Successful merge_cell_below().');
37 38 });
@@ -1,23 +1,24 b''
1 1 //
2 2 // Check for errors with up and down arrow presses in a non-empty notebook.
3 3 //
4 4 casper.notebook_test(function () {
5 5 var result = this.evaluate(function() {
6 IPython.notebook.command_mode();
6 7 pos0 = IPython.notebook.get_selected_index();
7 IPython.notebook.insert_cell_below('code');
8 IPython.utils.press(IPython.keycodes.b)
8 9 pos1 = IPython.notebook.get_selected_index();
9 IPython.notebook.insert_cell_below('code');
10 IPython.utils.press(IPython.keycodes.b)
10 11 pos2 = IPython.notebook.get_selected_index();
11 12 // Simulate the "up arrow" and "down arrow" keys.
12 13 IPython.utils.press_up();
13 14 pos3 = IPython.notebook.get_selected_index();
14 15 IPython.utils.press_down();
15 16 pos4 = IPython.notebook.get_selected_index();
16 17 return pos0 == 0 &&
17 18 pos1 == 1 &&
18 19 pos2 == 2 &&
19 20 pos3 == 1 &&
20 21 pos4 == 2;
21 22 });
22 23 this.test.assertTrue(result, 'Up/down arrow okay in non-empty notebook.');
23 24 });
General Comments 0
You need to be logged in to leave comments. Login now