Show More
The requested changes are too big and content was truncated. Show full diff
@@ -0,0 +1,78 b'' | |||
|
1 | // Test the notebook dual mode feature. | |
|
2 | ||
|
3 | // Test | |
|
4 | casper.notebook_test(function () { | |
|
5 | var a = 'print("a")'; | |
|
6 | var index = this.append_cell(a); | |
|
7 | this.execute_cell_then(index); | |
|
8 | ||
|
9 | var b = 'print("b")'; | |
|
10 | index = this.append_cell(b); | |
|
11 | this.execute_cell_then(index); | |
|
12 | ||
|
13 | var c = 'print("c")'; | |
|
14 | index = this.append_cell(c); | |
|
15 | this.execute_cell_then(index); | |
|
16 | ||
|
17 | this.then(function () { | |
|
18 | this.validate_notebook_state('initial state', 'edit', 0); | |
|
19 | this.trigger_keydown('esc'); | |
|
20 | this.validate_notebook_state('esc', 'command', 0); | |
|
21 | this.trigger_keydown('down'); | |
|
22 | this.validate_notebook_state('down', 'command', 1); | |
|
23 | this.trigger_keydown('enter'); | |
|
24 | this.validate_notebook_state('enter', 'edit', 1); | |
|
25 | this.trigger_keydown('j'); | |
|
26 | this.validate_notebook_state('j in edit mode', 'edit', 1); | |
|
27 | this.trigger_keydown('esc'); | |
|
28 | this.validate_notebook_state('esc', 'command', 1); | |
|
29 | this.trigger_keydown('j'); | |
|
30 | this.validate_notebook_state('j in command mode', 'command', 2); | |
|
31 | this.click_cell_editor(0); | |
|
32 | this.validate_notebook_state('click cell 0', 'edit', 0); | |
|
33 | this.click_cell_editor(3); | |
|
34 | this.validate_notebook_state('click cell 3', 'edit', 3); | |
|
35 | this.trigger_keydown('esc'); | |
|
36 | this.validate_notebook_state('esc', 'command', 3); | |
|
37 | ||
|
38 | // Open keyboard help | |
|
39 | this.evaluate(function(){ | |
|
40 | $('#keyboard_shortcuts a').click(); | |
|
41 | }, {}); | |
|
42 | ||
|
43 | this.trigger_keydown('k'); | |
|
44 | this.validate_notebook_state('k in command mode while keyboard help is up', 'command', 3); | |
|
45 | ||
|
46 | // Close keyboard help | |
|
47 | this.evaluate(function(){ | |
|
48 | $('div.modal button.close').click(); | |
|
49 | }, {}); | |
|
50 | ||
|
51 | this.trigger_keydown('k'); | |
|
52 | this.validate_notebook_state('k in command mode', 'command', 2); | |
|
53 | this.click_cell_editor(0); | |
|
54 | this.validate_notebook_state('click cell 0', 'edit', 0); | |
|
55 | this.focus_notebook(); | |
|
56 | this.validate_notebook_state('focus #notebook', 'command', 0); | |
|
57 | this.click_cell_editor(0); | |
|
58 | this.validate_notebook_state('click cell 0', 'edit', 0); | |
|
59 | this.focus_notebook(); | |
|
60 | this.validate_notebook_state('focus #notebook', 'command', 0); | |
|
61 | this.click_cell_editor(3); | |
|
62 | this.validate_notebook_state('click cell 3', 'edit', 3); | |
|
63 | ||
|
64 | // Cell deletion | |
|
65 | this.trigger_keydown('esc', 'd', 'd'); | |
|
66 | this.test.assertEquals(this.get_cells_length(), 3, 'dd actually deletes a cell'); | |
|
67 | this.validate_notebook_state('dd', 'command', 2); | |
|
68 | ||
|
69 | // Make sure that if the time between d presses is too long, nothing gets removed. | |
|
70 | this.trigger_keydown('d'); | |
|
71 | }); | |
|
72 | this.wait(1000); | |
|
73 | this.then(function () { | |
|
74 | this.trigger_keydown('d'); | |
|
75 | this.test.assertEquals(this.get_cells_length(), 3, "d, 1 second wait, d doesn't delete a cell"); | |
|
76 | this.validate_notebook_state('d, 1 second wait, d', 'command', 2); | |
|
77 | }); | |
|
78 | }); |
@@ -0,0 +1,51 b'' | |||
|
1 | ||
|
2 | // Test | |
|
3 | casper.notebook_test(function () { | |
|
4 | var a = 'print("a")'; | |
|
5 | var index = this.append_cell(a); | |
|
6 | this.execute_cell_then(index); | |
|
7 | ||
|
8 | var b = 'print("b")'; | |
|
9 | index = this.append_cell(b); | |
|
10 | this.execute_cell_then(index); | |
|
11 | ||
|
12 | var c = 'print("c")'; | |
|
13 | index = this.append_cell(c); | |
|
14 | this.execute_cell_then(index); | |
|
15 | ||
|
16 | this.then(function () { | |
|
17 | ||
|
18 | // Up and down in command mode | |
|
19 | this.select_cell(3); | |
|
20 | this.trigger_keydown('j'); | |
|
21 | this.validate_notebook_state('j at end of notebook', 'command', 3); | |
|
22 | this.trigger_keydown('down'); | |
|
23 | this.validate_notebook_state('down at end of notebook', 'command', 3); | |
|
24 | this.trigger_keydown('up'); | |
|
25 | this.validate_notebook_state('up', 'command', 2); | |
|
26 | this.select_cell(0); | |
|
27 | this.validate_notebook_state('select 0', 'command', 0); | |
|
28 | this.trigger_keydown('k'); | |
|
29 | this.validate_notebook_state('k at top of notebook', 'command', 0); | |
|
30 | this.trigger_keydown('up'); | |
|
31 | this.validate_notebook_state('up at top of notebook', 'command', 0); | |
|
32 | this.trigger_keydown('down'); | |
|
33 | this.validate_notebook_state('down', 'command', 1); | |
|
34 | ||
|
35 | // Up and down in edit mode | |
|
36 | this.click_cell_editor(3); | |
|
37 | this.validate_notebook_state('click cell 3', 'edit', 3); | |
|
38 | this.trigger_keydown('down'); | |
|
39 | this.validate_notebook_state('down at end of notebook', 'edit', 3); | |
|
40 | this.set_cell_editor_cursor(3, 0, 0); | |
|
41 | this.trigger_keydown('up'); | |
|
42 | this.validate_notebook_state('up', 'edit', 2); | |
|
43 | this.click_cell_editor(0); | |
|
44 | this.validate_notebook_state('click 0', 'edit', 0); | |
|
45 | this.trigger_keydown('up'); | |
|
46 | this.validate_notebook_state('up at top of notebook', 'edit', 0); | |
|
47 | this.set_cell_editor_cursor(0, 0, 10); | |
|
48 | this.trigger_keydown('down'); | |
|
49 | this.validate_notebook_state('down', 'edit', 1); | |
|
50 | }); | |
|
51 | }); |
@@ -0,0 +1,27 b'' | |||
|
1 | ||
|
2 | // Test | |
|
3 | casper.notebook_test(function () { | |
|
4 | var a = 'print("a")'; | |
|
5 | var index = this.append_cell(a); | |
|
6 | this.execute_cell_then(index); | |
|
7 | ||
|
8 | var b = 'print("b")'; | |
|
9 | index = this.append_cell(b); | |
|
10 | this.execute_cell_then(index); | |
|
11 | ||
|
12 | var c = 'print("c")'; | |
|
13 | index = this.append_cell(c); | |
|
14 | this.execute_cell_then(index); | |
|
15 | ||
|
16 | this.then(function () { | |
|
17 | // Cell insertion | |
|
18 | this.select_cell(2); | |
|
19 | this.trigger_keydown('a'); // Creates one cell | |
|
20 | this.test.assertEquals(this.get_cell_text(2), '', 'a; New cell 2 text is empty'); | |
|
21 | this.validate_notebook_state('a', 'command', 2); | |
|
22 | this.trigger_keydown('b'); // Creates one cell | |
|
23 | this.test.assertEquals(this.get_cell_text(2), '', 'b; Cell 2 text is still empty'); | |
|
24 | this.test.assertEquals(this.get_cell_text(3), '', 'b; New cell 3 text is empty'); | |
|
25 | this.validate_notebook_state('b', 'command', 3); | |
|
26 | }); | |
|
27 | }); No newline at end of file |
@@ -0,0 +1,28 b'' | |||
|
1 | // Test keyboard shortcuts that change the cell's mode. | |
|
2 | ||
|
3 | // Test | |
|
4 | casper.notebook_test(function () { | |
|
5 | this.then(function () { | |
|
6 | // Cell mode change | |
|
7 | this.select_cell(0); | |
|
8 | this.trigger_keydown('esc','r'); | |
|
9 | this.test.assertEquals(this.get_cell(0).cell_type, 'raw', 'r; cell is raw'); | |
|
10 | this.trigger_keydown('1'); | |
|
11 | this.test.assertEquals(this.get_cell(0).cell_type, 'heading', '1; cell is heading'); | |
|
12 | this.test.assertEquals(this.get_cell(0).level, 1, '1; cell is level 1 heading'); | |
|
13 | this.trigger_keydown('2'); | |
|
14 | this.test.assertEquals(this.get_cell(0).level, 2, '2; cell is level 2 heading'); | |
|
15 | this.trigger_keydown('3'); | |
|
16 | this.test.assertEquals(this.get_cell(0).level, 3, '3; cell is level 3 heading'); | |
|
17 | this.trigger_keydown('4'); | |
|
18 | this.test.assertEquals(this.get_cell(0).level, 4, '4; cell is level 4 heading'); | |
|
19 | this.trigger_keydown('5'); | |
|
20 | this.test.assertEquals(this.get_cell(0).level, 5, '5; cell is level 5 heading'); | |
|
21 | this.trigger_keydown('6'); | |
|
22 | this.test.assertEquals(this.get_cell(0).level, 6, '6; cell is level 6 heading'); | |
|
23 | this.trigger_keydown('m'); | |
|
24 | this.test.assertEquals(this.get_cell(0).cell_type, 'markdown', 'm; cell is markdown'); | |
|
25 | this.trigger_keydown('y'); | |
|
26 | this.test.assertEquals(this.get_cell(0).cell_type, 'code', 'y; cell is code'); | |
|
27 | }); | |
|
28 | }); No newline at end of file |
@@ -0,0 +1,55 b'' | |||
|
1 | ||
|
2 | ||
|
3 | // Test | |
|
4 | casper.notebook_test(function () { | |
|
5 | var a = 'print("a")'; | |
|
6 | var index = this.append_cell(a); | |
|
7 | this.execute_cell_then(index); | |
|
8 | ||
|
9 | var b = 'print("b")'; | |
|
10 | index = this.append_cell(b); | |
|
11 | this.execute_cell_then(index); | |
|
12 | ||
|
13 | var c = 'print("c")'; | |
|
14 | index = this.append_cell(c); | |
|
15 | this.execute_cell_then(index); | |
|
16 | ||
|
17 | this.then(function () { | |
|
18 | // Copy/paste/cut | |
|
19 | var num_cells = this.get_cells_length(); | |
|
20 | this.test.assertEquals(this.get_cell_text(1), a, 'Verify that cell 1 is a'); | |
|
21 | this.select_cell(1); | |
|
22 | this.trigger_keydown('x'); // Cut | |
|
23 | this.validate_notebook_state('x', 'command', 1); | |
|
24 | this.test.assertEquals(this.get_cells_length(), num_cells-1, 'Verify that a cell was removed.'); | |
|
25 | this.test.assertEquals(this.get_cell_text(1), b, 'Verify that cell 2 is now where cell 1 was.'); | |
|
26 | this.select_cell(2); | |
|
27 | this.trigger_keydown('v'); // Paste | |
|
28 | this.validate_notebook_state('v', 'command', 3); // Selection should move to pasted cell, below current cell. | |
|
29 | this.test.assertEquals(this.get_cell_text(3), a, 'Verify that cell 3 has the cut contents.'); | |
|
30 | this.test.assertEquals(this.get_cells_length(), num_cells, 'Verify a the cell was added.'); | |
|
31 | this.trigger_keydown('v'); // Paste | |
|
32 | this.validate_notebook_state('v', 'command', 4); // Selection should move to pasted cell, below current cell. | |
|
33 | this.test.assertEquals(this.get_cell_text(4), a, 'Verify that cell 4 has the cut contents.'); | |
|
34 | this.test.assertEquals(this.get_cells_length(), num_cells+1, 'Verify a the cell was added.'); | |
|
35 | this.select_cell(1); | |
|
36 | this.trigger_keydown('c'); // Copy | |
|
37 | this.validate_notebook_state('c', 'command', 1); | |
|
38 | this.test.assertEquals(this.get_cell_text(1), b, 'Verify that cell 1 is b'); | |
|
39 | this.select_cell(2); | |
|
40 | this.trigger_keydown('c'); // Copy | |
|
41 | this.validate_notebook_state('c', 'command', 2); | |
|
42 | this.test.assertEquals(this.get_cell_text(2), c, 'Verify that cell 2 is c'); | |
|
43 | this.select_cell(4); | |
|
44 | this.trigger_keydown('v'); // Paste | |
|
45 | this.validate_notebook_state('v', 'command', 5); | |
|
46 | this.test.assertEquals(this.get_cell_text(2), c, 'Verify that cell 2 still has the copied contents.'); | |
|
47 | this.test.assertEquals(this.get_cell_text(5), c, 'Verify that cell 5 has the copied contents.'); | |
|
48 | this.test.assertEquals(this.get_cells_length(), num_cells+2, 'Verify a the cell was added.'); | |
|
49 | this.select_cell(0); | |
|
50 | this.trigger_keydown('shift-v'); // Paste | |
|
51 | this.validate_notebook_state('shift-v', 'command', 0); | |
|
52 | this.test.assertEquals(this.get_cell_text(0), c, 'Verify that cell 0 has the copied contents.'); | |
|
53 | this.test.assertEquals(this.get_cells_length(), num_cells+3, 'Verify a the cell was added.'); | |
|
54 | }); | |
|
55 | }); No newline at end of file |
@@ -0,0 +1,72 b'' | |||
|
1 | // Test keyboard invoked execution. | |
|
2 | ||
|
3 | // Test | |
|
4 | casper.notebook_test(function () { | |
|
5 | var a = 'print("a")'; | |
|
6 | var index = this.append_cell(a); | |
|
7 | this.execute_cell_then(index); | |
|
8 | ||
|
9 | var b = 'print("b")'; | |
|
10 | index = this.append_cell(b); | |
|
11 | this.execute_cell_then(index); | |
|
12 | ||
|
13 | var c = 'print("c")'; | |
|
14 | index = this.append_cell(c); | |
|
15 | this.execute_cell_then(index); | |
|
16 | ||
|
17 | this.then(function () { | |
|
18 | ||
|
19 | // shift-enter | |
|
20 | // last cell in notebook | |
|
21 | var base_index = 3; | |
|
22 | this.select_cell(base_index); | |
|
23 | this.trigger_keydown('shift-enter'); // Creates one cell | |
|
24 | this.validate_notebook_state('shift-enter (no cell below)', 'edit', base_index + 1); | |
|
25 | // not last cell in notebook & starts in edit mode | |
|
26 | this.click_cell_editor(base_index); | |
|
27 | this.validate_notebook_state('click cell ' + base_index, 'edit', base_index); | |
|
28 | this.trigger_keydown('shift-enter'); | |
|
29 | this.validate_notebook_state('shift-enter (cell exists below)', 'command', base_index + 1); | |
|
30 | // starts in command mode | |
|
31 | this.trigger_keydown('k'); | |
|
32 | this.validate_notebook_state('k in comand mode', 'command', base_index); | |
|
33 | this.trigger_keydown('shift-enter'); | |
|
34 | this.validate_notebook_state('shift-enter (start in command mode)', 'command', base_index + 1); | |
|
35 | ||
|
36 | // ctrl-enter | |
|
37 | // last cell in notebook | |
|
38 | base_index++; | |
|
39 | this.trigger_keydown('ctrl-enter'); | |
|
40 | this.validate_notebook_state('ctrl-enter (no cell below)', 'command', base_index); | |
|
41 | // not last cell in notebook & starts in edit mode | |
|
42 | this.click_cell_editor(base_index-1); | |
|
43 | this.validate_notebook_state('click cell ' + (base_index-1), 'edit', base_index-1); | |
|
44 | this.trigger_keydown('ctrl-enter'); | |
|
45 | this.validate_notebook_state('ctrl-enter (cell exists below)', 'command', base_index-1); | |
|
46 | // starts in command mode | |
|
47 | this.trigger_keydown('j'); | |
|
48 | this.validate_notebook_state('j in comand mode', 'command', base_index); | |
|
49 | this.trigger_keydown('ctrl-enter'); | |
|
50 | this.validate_notebook_state('ctrl-enter (start in command mode)', 'command', base_index); | |
|
51 | ||
|
52 | // alt-enter | |
|
53 | // last cell in notebook | |
|
54 | this.trigger_keydown('alt-enter'); // Creates one cell | |
|
55 | this.validate_notebook_state('alt-enter (no cell below)', 'edit', base_index + 1); | |
|
56 | // not last cell in notebook & starts in edit mode | |
|
57 | this.click_cell_editor(base_index); | |
|
58 | this.validate_notebook_state('click cell ' + base_index, 'edit', base_index); | |
|
59 | this.trigger_keydown('alt-enter'); // Creates one cell | |
|
60 | this.validate_notebook_state('alt-enter (cell exists below)', 'edit', base_index + 1); | |
|
61 | // starts in command mode | |
|
62 | this.trigger_keydown('esc', 'k'); | |
|
63 | this.validate_notebook_state('k in comand mode', 'command', base_index); | |
|
64 | this.trigger_keydown('alt-enter'); // Creates one cell | |
|
65 | this.validate_notebook_state('alt-enter (start in command mode)', 'edit', base_index + 1); | |
|
66 | ||
|
67 | // Notebook will now have 8 cells, the index of the last cell will be 7. | |
|
68 | this.test.assertEquals(this.get_cells_length(), 8, '*-enter commands added cells where needed.'); | |
|
69 | this.select_cell(7); | |
|
70 | this.validate_notebook_state('click cell ' + 7 + ' and esc', 'command', 7); | |
|
71 | }); | |
|
72 | }); No newline at end of file |
|
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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
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 | |
The requested commit or file is too big and content was truncated. Show full diff |
@@ -1,85 +1,74 b'' | |||
|
1 | 1 | ============================= |
|
2 | 2 | The IPython licensing terms |
|
3 | 3 | ============================= |
|
4 | 4 | |
|
5 | 5 | IPython is licensed under the terms of the Modified BSD License (also known as |
|
6 | New or Revised BSD), as follows: | |
|
6 | New or Revised or 3-Clause BSD), as follows: | |
|
7 | 7 | |
|
8 |
Copyright (c) 2008-201 |
|
|
9 |
Copyright (c) 2001-2007, Fernando Perez |
|
|
10 | Copyright (c) 2001, Janko Hauser <jhauser@zscout.de> | |
|
11 | Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu> | |
|
8 | - Copyright (c) 2008-2014, IPython Development Team | |
|
9 | - Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu> | |
|
10 | - Copyright (c) 2001, Janko Hauser <jhauser@zscout.de> | |
|
11 | - Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu> | |
|
12 | 12 | |
|
13 | 13 | All rights reserved. |
|
14 | 14 | |
|
15 | 15 | Redistribution and use in source and binary forms, with or without |
|
16 | 16 | modification, are permitted provided that the following conditions are met: |
|
17 | 17 | |
|
18 | 18 | Redistributions of source code must retain the above copyright notice, this |
|
19 | 19 | list of conditions and the following disclaimer. |
|
20 | 20 | |
|
21 | 21 | Redistributions in binary form must reproduce the above copyright notice, this |
|
22 | 22 | list of conditions and the following disclaimer in the documentation and/or |
|
23 | 23 | other materials provided with the distribution. |
|
24 | 24 | |
|
25 | 25 | Neither the name of the IPython Development Team nor the names of its |
|
26 | 26 | contributors may be used to endorse or promote products derived from this |
|
27 | 27 | software without specific prior written permission. |
|
28 | 28 | |
|
29 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
|
30 | 30 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
31 | 31 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
32 | 32 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE |
|
33 | 33 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
34 | 34 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|
35 | 35 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
36 | 36 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|
37 | 37 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
38 | 38 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
39 | 39 | |
|
40 | 40 | About the IPython Development Team |
|
41 | 41 | ---------------------------------- |
|
42 | 42 | |
|
43 | 43 | Fernando Perez began IPython in 2001 based on code from Janko Hauser |
|
44 | 44 | <jhauser@zscout.de> and Nathaniel Gray <n8gray@caltech.edu>. Fernando is still |
|
45 | 45 | the project lead. |
|
46 | 46 | |
|
47 | 47 | The IPython Development Team is the set of all contributors to the IPython |
|
48 | 48 | project. This includes all of the IPython subprojects. A full list with |
|
49 | 49 | details is kept in the documentation directory, in the file |
|
50 | 50 | ``about/credits.txt``. |
|
51 | 51 | |
|
52 | 52 | The core team that coordinates development on GitHub can be found here: |
|
53 | http://github.com/ipython. As of late 2010, it consists of: | |
|
54 | ||
|
55 | * Brian E. Granger | |
|
56 | * Jonathan March | |
|
57 | * Evan Patterson | |
|
58 | * Fernando Perez | |
|
59 | * Min Ragan-Kelley | |
|
60 | * Robert Kern | |
|
61 | ||
|
53 | https://github.com/ipython/. | |
|
62 | 54 | |
|
63 | 55 | Our Copyright Policy |
|
64 | 56 | -------------------- |
|
65 | 57 | |
|
66 | 58 | IPython uses a shared copyright model. Each contributor maintains copyright |
|
67 | 59 | over their contributions to IPython. But, it is important to note that these |
|
68 | 60 | contributions are typically only changes to the repositories. Thus, the IPython |
|
69 | 61 | source code, in its entirety is not the copyright of any single person or |
|
70 | 62 | institution. Instead, it is the collective copyright of the entire IPython |
|
71 | 63 | Development Team. If individual contributors want to maintain a record of what |
|
72 | 64 | changes/contributions they have specific copyright on, they should indicate |
|
73 | 65 | their copyright in the commit message of the change, when they commit the |
|
74 | 66 | change to one of the IPython repositories. |
|
75 | 67 | |
|
76 | With this in mind, the following banner should be used in any source code file | |
|
68 | With this in mind, the following banner should be used in any source code file | |
|
77 | 69 | to indicate the copyright and license terms: |
|
78 | 70 | |
|
79 | #----------------------------------------------------------------------------- | |
|
80 | # Copyright (c) 2010, IPython Development Team. | |
|
81 | # | |
|
82 |
|
|
|
83 | # | |
|
84 | # The full license is in the file COPYING.txt, distributed with this software. | |
|
85 | #----------------------------------------------------------------------------- | |
|
71 | :: | |
|
72 | ||
|
73 | # Copyright (c) IPython Development Team. | |
|
74 | # Distributed under the terms of the Modified BSD License. |
@@ -1,811 +1,854 b'' | |||
|
1 | 1 | """ History related magics and functionality """ |
|
2 | 2 | #----------------------------------------------------------------------------- |
|
3 | 3 | # Copyright (C) 2010-2011 The IPython Development Team. |
|
4 | 4 | # |
|
5 | 5 | # Distributed under the terms of the BSD License. |
|
6 | 6 | # |
|
7 | 7 | # The full license is in the file COPYING.txt, distributed with this software. |
|
8 | 8 | #----------------------------------------------------------------------------- |
|
9 | 9 | |
|
10 | 10 | #----------------------------------------------------------------------------- |
|
11 | 11 | # Imports |
|
12 | 12 | #----------------------------------------------------------------------------- |
|
13 | 13 | from __future__ import print_function |
|
14 | 14 | |
|
15 | 15 | # Stdlib imports |
|
16 | 16 | import atexit |
|
17 | 17 | import datetime |
|
18 | 18 | import os |
|
19 | 19 | import re |
|
20 | 20 | try: |
|
21 | 21 | import sqlite3 |
|
22 | 22 | except ImportError: |
|
23 | 23 | try: |
|
24 | 24 | from pysqlite2 import dbapi2 as sqlite3 |
|
25 | 25 | except ImportError: |
|
26 | 26 | sqlite3 = None |
|
27 | 27 | import threading |
|
28 | 28 | |
|
29 | 29 | # Our own packages |
|
30 | 30 | from IPython.config.configurable import Configurable |
|
31 | 31 | from IPython.external.decorator import decorator |
|
32 | from IPython.utils.decorators import undoc | |
|
32 | 33 | from IPython.utils.path import locate_profile |
|
33 | 34 | from IPython.utils import py3compat |
|
34 | 35 | from IPython.utils.traitlets import ( |
|
35 | 36 | Any, Bool, Dict, Instance, Integer, List, Unicode, TraitError, |
|
36 | 37 | ) |
|
37 | 38 | from IPython.utils.warn import warn |
|
38 | 39 | |
|
39 | 40 | #----------------------------------------------------------------------------- |
|
40 | 41 | # Classes and functions |
|
41 | 42 | #----------------------------------------------------------------------------- |
|
42 | 43 | |
|
44 | @undoc | |
|
43 | 45 | class DummyDB(object): |
|
44 | 46 | """Dummy DB that will act as a black hole for history. |
|
45 | 47 | |
|
46 | 48 | Only used in the absence of sqlite""" |
|
47 | 49 | def execute(*args, **kwargs): |
|
48 | 50 | return [] |
|
49 | 51 | |
|
50 | 52 | def commit(self, *args, **kwargs): |
|
51 | 53 | pass |
|
52 | 54 | |
|
53 | 55 | def __enter__(self, *args, **kwargs): |
|
54 | 56 | pass |
|
55 | 57 | |
|
56 | 58 | def __exit__(self, *args, **kwargs): |
|
57 | 59 | pass |
|
58 | 60 | |
|
59 | 61 | |
|
60 | 62 | @decorator |
|
61 | 63 | def needs_sqlite(f, self, *a, **kw): |
|
62 | """return an empty list in the absence of sqlite""" | |
|
64 | """Decorator: return an empty list in the absence of sqlite.""" | |
|
63 | 65 | if sqlite3 is None or not self.enabled: |
|
64 | 66 | return [] |
|
65 | 67 | else: |
|
66 | 68 | return f(self, *a, **kw) |
|
67 | 69 | |
|
68 | 70 | |
|
69 | 71 | if sqlite3 is not None: |
|
70 | 72 | DatabaseError = sqlite3.DatabaseError |
|
71 | 73 | else: |
|
74 | @undoc | |
|
72 | 75 | class DatabaseError(Exception): |
|
73 | 76 | "Dummy exception when sqlite could not be imported. Should never occur." |
|
74 | 77 | |
|
75 | 78 | @decorator |
|
76 | 79 | def catch_corrupt_db(f, self, *a, **kw): |
|
77 | 80 | """A decorator which wraps HistoryAccessor method calls to catch errors from |
|
78 | 81 | a corrupt SQLite database, move the old database out of the way, and create |
|
79 | 82 | a new one. |
|
80 | 83 | """ |
|
81 | 84 | try: |
|
82 | 85 | return f(self, *a, **kw) |
|
83 | 86 | except DatabaseError: |
|
84 | 87 | if os.path.isfile(self.hist_file): |
|
85 | 88 | # Try to move the file out of the way |
|
86 | 89 | base,ext = os.path.splitext(self.hist_file) |
|
87 | 90 | newpath = base + '-corrupt' + ext |
|
88 | 91 | os.rename(self.hist_file, newpath) |
|
89 | 92 | self.init_db() |
|
90 | 93 | print("ERROR! History file wasn't a valid SQLite database.", |
|
91 | 94 | "It was moved to %s" % newpath, "and a new file created.") |
|
92 | 95 | return [] |
|
93 | 96 | |
|
94 | 97 | else: |
|
95 | 98 | # The hist_file is probably :memory: or something else. |
|
96 | 99 | raise |
|
97 | 100 | |
|
98 | 101 | |
|
99 | 102 | |
|
100 | 103 | class HistoryAccessor(Configurable): |
|
101 | 104 | """Access the history database without adding to it. |
|
102 | 105 | |
|
103 | 106 | This is intended for use by standalone history tools. IPython shells use |
|
104 | 107 | HistoryManager, below, which is a subclass of this.""" |
|
105 | 108 | |
|
106 | 109 | # String holding the path to the history file |
|
107 | 110 | hist_file = Unicode(config=True, |
|
108 | 111 | help="""Path to file to use for SQLite history database. |
|
109 | 112 | |
|
110 | 113 | By default, IPython will put the history database in the IPython |
|
111 | 114 | profile directory. If you would rather share one history among |
|
112 | 115 | profiles, you can set this value in each, so that they are consistent. |
|
113 | 116 | |
|
114 | 117 | Due to an issue with fcntl, SQLite is known to misbehave on some NFS |
|
115 | 118 | mounts. If you see IPython hanging, try setting this to something on a |
|
116 | 119 | local disk, e.g:: |
|
117 | 120 | |
|
118 | 121 | ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite |
|
119 | 122 | |
|
120 | 123 | """) |
|
121 | 124 | |
|
122 | 125 | enabled = Bool(True, config=True, |
|
123 | 126 | help="""enable the SQLite history |
|
124 | 127 | |
|
125 | 128 | set enabled=False to disable the SQLite history, |
|
126 | 129 | in which case there will be no stored history, no SQLite connection, |
|
127 | 130 | and no background saving thread. This may be necessary in some |
|
128 | 131 | threaded environments where IPython is embedded. |
|
129 | 132 | """ |
|
130 | 133 | ) |
|
131 | 134 | |
|
132 | 135 | connection_options = Dict(config=True, |
|
133 | 136 | help="""Options for configuring the SQLite connection |
|
134 | 137 | |
|
135 | 138 | These options are passed as keyword args to sqlite3.connect |
|
136 | 139 | when establishing database conenctions. |
|
137 | 140 | """ |
|
138 | 141 | ) |
|
139 | 142 | |
|
140 | 143 | # The SQLite database |
|
141 | 144 | db = Any() |
|
142 | 145 | def _db_changed(self, name, old, new): |
|
143 | 146 | """validate the db, since it can be an Instance of two different types""" |
|
144 | 147 | connection_types = (DummyDB,) |
|
145 | 148 | if sqlite3 is not None: |
|
146 | 149 | connection_types = (DummyDB, sqlite3.Connection) |
|
147 | 150 | if not isinstance(new, connection_types): |
|
148 | 151 | msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \ |
|
149 | 152 | (self.__class__.__name__, new) |
|
150 | 153 | raise TraitError(msg) |
|
151 | 154 | |
|
152 | 155 | def __init__(self, profile='default', hist_file=u'', **traits): |
|
153 | 156 | """Create a new history accessor. |
|
154 | 157 | |
|
155 | 158 | Parameters |
|
156 | 159 | ---------- |
|
157 | 160 | profile : str |
|
158 | 161 | The name of the profile from which to open history. |
|
159 | 162 | hist_file : str |
|
160 | 163 | Path to an SQLite history database stored by IPython. If specified, |
|
161 | 164 | hist_file overrides profile. |
|
162 | config : | |
|
165 | config : :class:`~IPython.config.loader.Config` | |
|
163 | 166 | Config object. hist_file can also be set through this. |
|
164 | 167 | """ |
|
165 | 168 | # We need a pointer back to the shell for various tasks. |
|
166 | 169 | super(HistoryAccessor, self).__init__(**traits) |
|
167 | 170 | # defer setting hist_file from kwarg until after init, |
|
168 | 171 | # otherwise the default kwarg value would clobber any value |
|
169 | 172 | # set by config |
|
170 | 173 | if hist_file: |
|
171 | 174 | self.hist_file = hist_file |
|
172 | 175 | |
|
173 | 176 | if self.hist_file == u'': |
|
174 | 177 | # No one has set the hist_file, yet. |
|
175 | 178 | self.hist_file = self._get_hist_file_name(profile) |
|
176 | 179 | |
|
177 | 180 | if sqlite3 is None and self.enabled: |
|
178 | 181 | warn("IPython History requires SQLite, your history will not be saved") |
|
179 | 182 | self.enabled = False |
|
180 | 183 | |
|
181 | 184 | self.init_db() |
|
182 | 185 | |
|
183 | 186 | def _get_hist_file_name(self, profile='default'): |
|
184 | 187 | """Find the history file for the given profile name. |
|
185 | 188 | |
|
186 | 189 | This is overridden by the HistoryManager subclass, to use the shell's |
|
187 | 190 | active profile. |
|
188 | 191 | |
|
189 | 192 | Parameters |
|
190 | 193 | ---------- |
|
191 | 194 | profile : str |
|
192 | 195 | The name of a profile which has a history file. |
|
193 | 196 | """ |
|
194 | 197 | return os.path.join(locate_profile(profile), 'history.sqlite') |
|
195 | 198 | |
|
196 | 199 | @catch_corrupt_db |
|
197 | 200 | def init_db(self): |
|
198 | 201 | """Connect to the database, and create tables if necessary.""" |
|
199 | 202 | if not self.enabled: |
|
200 | 203 | self.db = DummyDB() |
|
201 | 204 | return |
|
202 | 205 | |
|
203 | 206 | # use detect_types so that timestamps return datetime objects |
|
204 | 207 | kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) |
|
205 | 208 | kwargs.update(self.connection_options) |
|
206 | 209 | self.db = sqlite3.connect(self.hist_file, **kwargs) |
|
207 | 210 | self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer |
|
208 | 211 | primary key autoincrement, start timestamp, |
|
209 | 212 | end timestamp, num_cmds integer, remark text)""") |
|
210 | 213 | self.db.execute("""CREATE TABLE IF NOT EXISTS history |
|
211 | 214 | (session integer, line integer, source text, source_raw text, |
|
212 | 215 | PRIMARY KEY (session, line))""") |
|
213 | 216 | # Output history is optional, but ensure the table's there so it can be |
|
214 | 217 | # enabled later. |
|
215 | 218 | self.db.execute("""CREATE TABLE IF NOT EXISTS output_history |
|
216 | 219 | (session integer, line integer, output text, |
|
217 | 220 | PRIMARY KEY (session, line))""") |
|
218 | 221 | self.db.commit() |
|
219 | 222 | |
|
220 | 223 | def writeout_cache(self): |
|
221 | 224 | """Overridden by HistoryManager to dump the cache before certain |
|
222 | 225 | database lookups.""" |
|
223 | 226 | pass |
|
224 | 227 | |
|
225 | 228 | ## ------------------------------- |
|
226 | 229 | ## Methods for retrieving history: |
|
227 | 230 | ## ------------------------------- |
|
228 | 231 | def _run_sql(self, sql, params, raw=True, output=False): |
|
229 | 232 | """Prepares and runs an SQL query for the history database. |
|
230 | 233 | |
|
231 | 234 | Parameters |
|
232 | 235 | ---------- |
|
233 | 236 | sql : str |
|
234 | 237 | Any filtering expressions to go after SELECT ... FROM ... |
|
235 | 238 | params : tuple |
|
236 | 239 | Parameters passed to the SQL query (to replace "?") |
|
237 | 240 | raw, output : bool |
|
238 | 241 | See :meth:`get_range` |
|
239 | 242 | |
|
240 | 243 | Returns |
|
241 | 244 | ------- |
|
242 | 245 | Tuples as :meth:`get_range` |
|
243 | 246 | """ |
|
244 | 247 | toget = 'source_raw' if raw else 'source' |
|
245 | 248 | sqlfrom = "history" |
|
246 | 249 | if output: |
|
247 | 250 | sqlfrom = "history LEFT JOIN output_history USING (session, line)" |
|
248 | 251 | toget = "history.%s, output_history.output" % toget |
|
249 | 252 | cur = self.db.execute("SELECT session, line, %s FROM %s " %\ |
|
250 | 253 | (toget, sqlfrom) + sql, params) |
|
251 | 254 | if output: # Regroup into 3-tuples, and parse JSON |
|
252 | 255 | return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur) |
|
253 | 256 | return cur |
|
254 | 257 | |
|
255 | 258 | @needs_sqlite |
|
256 | 259 | @catch_corrupt_db |
|
257 |
def get_session_info(self, session |
|
|
258 |
""" |
|
|
260 | def get_session_info(self, session): | |
|
261 | """Get info about a session. | |
|
259 | 262 | |
|
260 | 263 | Parameters |
|
261 | 264 | ---------- |
|
262 | 265 | |
|
263 | 266 | session : int |
|
264 |
Session number to retrieve. |
|
|
265 | numbers count back from current session, so -1 is previous session. | |
|
267 | Session number to retrieve. | |
|
266 | 268 | |
|
267 | 269 | Returns |
|
268 | 270 | ------- |
|
269 | ||
|
270 | (session_id [int], start [datetime], end [datetime], num_cmds [int], | |
|
271 | remark [unicode]) | |
|
272 | ||
|
273 | Sessions that are running or did not exit cleanly will have `end=None` | |
|
274 | and `num_cmds=None`. | |
|
275 | ||
|
271 | ||
|
272 | session_id : int | |
|
273 | Session ID number | |
|
274 | start : datetime | |
|
275 | Timestamp for the start of the session. | |
|
276 | end : datetime | |
|
277 | Timestamp for the end of the session, or None if IPython crashed. | |
|
278 | num_cmds : int | |
|
279 | Number of commands run, or None if IPython crashed. | |
|
280 | remark : unicode | |
|
281 | A manually set description. | |
|
276 | 282 | """ |
|
277 | ||
|
278 | if session <= 0: | |
|
279 | session += self.session_number | |
|
280 | ||
|
281 | 283 | query = "SELECT * from sessions where session == ?" |
|
282 | 284 | return self.db.execute(query, (session,)).fetchone() |
|
283 | 285 | |
|
284 | 286 | @catch_corrupt_db |
|
287 | def get_last_session_id(self): | |
|
288 | """Get the last session ID currently in the database. | |
|
289 | ||
|
290 | Within IPython, this should be the same as the value stored in | |
|
291 | :attr:`HistoryManager.session_number`. | |
|
292 | """ | |
|
293 | for record in self.get_tail(n=1, include_latest=True): | |
|
294 | return record[0] | |
|
295 | ||
|
296 | @catch_corrupt_db | |
|
285 | 297 | def get_tail(self, n=10, raw=True, output=False, include_latest=False): |
|
286 | 298 | """Get the last n lines from the history database. |
|
287 | 299 | |
|
288 | 300 | Parameters |
|
289 | 301 | ---------- |
|
290 | 302 | n : int |
|
291 | 303 | The number of lines to get |
|
292 | 304 | raw, output : bool |
|
293 | 305 | See :meth:`get_range` |
|
294 | 306 | include_latest : bool |
|
295 | 307 | If False (default), n+1 lines are fetched, and the latest one |
|
296 | 308 | is discarded. This is intended to be used where the function |
|
297 | 309 | is called by a user command, which it should not return. |
|
298 | 310 | |
|
299 | 311 | Returns |
|
300 | 312 | ------- |
|
301 | 313 | Tuples as :meth:`get_range` |
|
302 | 314 | """ |
|
303 | 315 | self.writeout_cache() |
|
304 | 316 | if not include_latest: |
|
305 | 317 | n += 1 |
|
306 | 318 | cur = self._run_sql("ORDER BY session DESC, line DESC LIMIT ?", |
|
307 | 319 | (n,), raw=raw, output=output) |
|
308 | 320 | if not include_latest: |
|
309 | 321 | return reversed(list(cur)[1:]) |
|
310 | 322 | return reversed(list(cur)) |
|
311 | 323 | |
|
312 | 324 | @catch_corrupt_db |
|
313 | 325 | def search(self, pattern="*", raw=True, search_raw=True, |
|
314 | 326 | output=False, n=None, unique=False): |
|
315 | 327 | """Search the database using unix glob-style matching (wildcards |
|
316 | 328 | * and ?). |
|
317 | 329 | |
|
318 | 330 | Parameters |
|
319 | 331 | ---------- |
|
320 | 332 | pattern : str |
|
321 | 333 | The wildcarded pattern to match when searching |
|
322 | 334 | search_raw : bool |
|
323 | 335 | If True, search the raw input, otherwise, the parsed input |
|
324 | 336 | raw, output : bool |
|
325 | 337 | See :meth:`get_range` |
|
326 | 338 | n : None or int |
|
327 | 339 | If an integer is given, it defines the limit of |
|
328 | 340 | returned entries. |
|
329 | 341 | unique : bool |
|
330 | 342 | When it is true, return only unique entries. |
|
331 | 343 | |
|
332 | 344 | Returns |
|
333 | 345 | ------- |
|
334 | 346 | Tuples as :meth:`get_range` |
|
335 | 347 | """ |
|
336 | 348 | tosearch = "source_raw" if search_raw else "source" |
|
337 | 349 | if output: |
|
338 | 350 | tosearch = "history." + tosearch |
|
339 | 351 | self.writeout_cache() |
|
340 | 352 | sqlform = "WHERE %s GLOB ?" % tosearch |
|
341 | 353 | params = (pattern,) |
|
342 | 354 | if unique: |
|
343 | 355 | sqlform += ' GROUP BY {0}'.format(tosearch) |
|
344 | 356 | if n is not None: |
|
345 | 357 | sqlform += " ORDER BY session DESC, line DESC LIMIT ?" |
|
346 | 358 | params += (n,) |
|
347 | 359 | elif unique: |
|
348 | 360 | sqlform += " ORDER BY session, line" |
|
349 | 361 | cur = self._run_sql(sqlform, params, raw=raw, output=output) |
|
350 | 362 | if n is not None: |
|
351 | 363 | return reversed(list(cur)) |
|
352 | 364 | return cur |
|
353 | 365 | |
|
354 | 366 | @catch_corrupt_db |
|
355 | 367 | def get_range(self, session, start=1, stop=None, raw=True,output=False): |
|
356 | 368 | """Retrieve input by session. |
|
357 | 369 | |
|
358 | 370 | Parameters |
|
359 | 371 | ---------- |
|
360 | 372 | session : int |
|
361 | 373 | Session number to retrieve. |
|
362 | 374 | start : int |
|
363 | 375 | First line to retrieve. |
|
364 | 376 | stop : int |
|
365 | 377 | End of line range (excluded from output itself). If None, retrieve |
|
366 | 378 | to the end of the session. |
|
367 | 379 | raw : bool |
|
368 | 380 | If True, return untranslated input |
|
369 | 381 | output : bool |
|
370 | 382 | If True, attempt to include output. This will be 'real' Python |
|
371 | 383 | objects for the current session, or text reprs from previous |
|
372 | 384 | sessions if db_log_output was enabled at the time. Where no output |
|
373 | 385 | is found, None is used. |
|
374 | 386 | |
|
375 | 387 | Returns |
|
376 | 388 | ------- |
|
377 | An iterator over the desired lines. Each line is a 3-tuple, either | |
|
378 | (session, line, input) if output is False, or | |
|
379 |
(session, line, |
|
|
389 | entries | |
|
390 | An iterator over the desired lines. Each line is a 3-tuple, either | |
|
391 | (session, line, input) if output is False, or | |
|
392 | (session, line, (input, output)) if output is True. | |
|
380 | 393 | """ |
|
381 | 394 | if stop: |
|
382 | 395 | lineclause = "line >= ? AND line < ?" |
|
383 | 396 | params = (session, start, stop) |
|
384 | 397 | else: |
|
385 | 398 | lineclause = "line>=?" |
|
386 | 399 | params = (session, start) |
|
387 | 400 | |
|
388 | 401 | return self._run_sql("WHERE session==? AND %s" % lineclause, |
|
389 | 402 | params, raw=raw, output=output) |
|
390 | 403 | |
|
391 | 404 | def get_range_by_str(self, rangestr, raw=True, output=False): |
|
392 | 405 | """Get lines of history from a string of ranges, as used by magic |
|
393 | 406 | commands %hist, %save, %macro, etc. |
|
394 | 407 | |
|
395 | 408 | Parameters |
|
396 | 409 | ---------- |
|
397 | 410 | rangestr : str |
|
398 | 411 | A string specifying ranges, e.g. "5 ~2/1-4". See |
|
399 | 412 | :func:`magic_history` for full details. |
|
400 | 413 | raw, output : bool |
|
401 | 414 | As :meth:`get_range` |
|
402 | 415 | |
|
403 | 416 | Returns |
|
404 | 417 | ------- |
|
405 | 418 | Tuples as :meth:`get_range` |
|
406 | 419 | """ |
|
407 | 420 | for sess, s, e in extract_hist_ranges(rangestr): |
|
408 | 421 | for line in self.get_range(sess, s, e, raw=raw, output=output): |
|
409 | 422 | yield line |
|
410 | 423 | |
|
411 | 424 | |
|
412 | 425 | class HistoryManager(HistoryAccessor): |
|
413 | 426 | """A class to organize all history-related functionality in one place. |
|
414 | 427 | """ |
|
415 | 428 | # Public interface |
|
416 | 429 | |
|
417 | 430 | # An instance of the IPython shell we are attached to |
|
418 | 431 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') |
|
419 | 432 | # Lists to hold processed and raw history. These start with a blank entry |
|
420 | 433 | # so that we can index them starting from 1 |
|
421 | 434 | input_hist_parsed = List([""]) |
|
422 | 435 | input_hist_raw = List([""]) |
|
423 | 436 | # A list of directories visited during session |
|
424 | 437 | dir_hist = List() |
|
425 | 438 | def _dir_hist_default(self): |
|
426 | 439 | try: |
|
427 | 440 | return [py3compat.getcwd()] |
|
428 | 441 | except OSError: |
|
429 | 442 | return [] |
|
430 | 443 | |
|
431 | 444 | # A dict of output history, keyed with ints from the shell's |
|
432 | 445 | # execution count. |
|
433 | 446 | output_hist = Dict() |
|
434 | 447 | # The text/plain repr of outputs. |
|
435 | 448 | output_hist_reprs = Dict() |
|
436 | 449 | |
|
437 | 450 | # The number of the current session in the history database |
|
438 | 451 | session_number = Integer() |
|
439 | 452 | |
|
440 | 453 | db_log_output = Bool(False, config=True, |
|
441 | 454 | help="Should the history database include output? (default: no)" |
|
442 | 455 | ) |
|
443 | 456 | db_cache_size = Integer(0, config=True, |
|
444 | 457 | help="Write to database every x commands (higher values save disk access & power).\n" |
|
445 | 458 | "Values of 1 or less effectively disable caching." |
|
446 | 459 | ) |
|
447 | 460 | # The input and output caches |
|
448 | 461 | db_input_cache = List() |
|
449 | 462 | db_output_cache = List() |
|
450 | 463 | |
|
451 | 464 | # History saving in separate thread |
|
452 | 465 | save_thread = Instance('IPython.core.history.HistorySavingThread') |
|
453 | 466 | try: # Event is a function returning an instance of _Event... |
|
454 | 467 | save_flag = Instance(threading._Event) |
|
455 | 468 | except AttributeError: # ...until Python 3.3, when it's a class. |
|
456 | 469 | save_flag = Instance(threading.Event) |
|
457 | 470 | |
|
458 | 471 | # Private interface |
|
459 | 472 | # Variables used to store the three last inputs from the user. On each new |
|
460 | 473 | # history update, we populate the user's namespace with these, shifted as |
|
461 | 474 | # necessary. |
|
462 | 475 | _i00 = Unicode(u'') |
|
463 | 476 | _i = Unicode(u'') |
|
464 | 477 | _ii = Unicode(u'') |
|
465 | 478 | _iii = Unicode(u'') |
|
466 | 479 | |
|
467 | 480 | # A regex matching all forms of the exit command, so that we don't store |
|
468 | 481 | # them in the history (it's annoying to rewind the first entry and land on |
|
469 | 482 | # an exit call). |
|
470 | 483 | _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$") |
|
471 | 484 | |
|
472 | 485 | def __init__(self, shell=None, config=None, **traits): |
|
473 | 486 | """Create a new history manager associated with a shell instance. |
|
474 | 487 | """ |
|
475 | 488 | # We need a pointer back to the shell for various tasks. |
|
476 | 489 | super(HistoryManager, self).__init__(shell=shell, config=config, |
|
477 | 490 | **traits) |
|
478 | 491 | self.save_flag = threading.Event() |
|
479 | 492 | self.db_input_cache_lock = threading.Lock() |
|
480 | 493 | self.db_output_cache_lock = threading.Lock() |
|
481 | 494 | if self.enabled and self.hist_file != ':memory:': |
|
482 | 495 | self.save_thread = HistorySavingThread(self) |
|
483 | 496 | self.save_thread.start() |
|
484 | 497 | |
|
485 | 498 | self.new_session() |
|
486 | 499 | |
|
487 | 500 | def _get_hist_file_name(self, profile=None): |
|
488 | 501 | """Get default history file name based on the Shell's profile. |
|
489 | 502 | |
|
490 | 503 | The profile parameter is ignored, but must exist for compatibility with |
|
491 | 504 | the parent class.""" |
|
492 | 505 | profile_dir = self.shell.profile_dir.location |
|
493 | 506 | return os.path.join(profile_dir, 'history.sqlite') |
|
494 | 507 | |
|
495 | 508 | @needs_sqlite |
|
496 | 509 | def new_session(self, conn=None): |
|
497 | 510 | """Get a new session number.""" |
|
498 | 511 | if conn is None: |
|
499 | 512 | conn = self.db |
|
500 | 513 | |
|
501 | 514 | with conn: |
|
502 | 515 | cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL, |
|
503 | 516 | NULL, "") """, (datetime.datetime.now(),)) |
|
504 | 517 | self.session_number = cur.lastrowid |
|
505 | 518 | |
|
506 | 519 | def end_session(self): |
|
507 | 520 | """Close the database session, filling in the end time and line count.""" |
|
508 | 521 | self.writeout_cache() |
|
509 | 522 | with self.db: |
|
510 | 523 | self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE |
|
511 | 524 | session==?""", (datetime.datetime.now(), |
|
512 | 525 | len(self.input_hist_parsed)-1, self.session_number)) |
|
513 | 526 | self.session_number = 0 |
|
514 | 527 | |
|
515 | 528 | def name_session(self, name): |
|
516 | 529 | """Give the current session a name in the history database.""" |
|
517 | 530 | with self.db: |
|
518 | 531 | self.db.execute("UPDATE sessions SET remark=? WHERE session==?", |
|
519 | 532 | (name, self.session_number)) |
|
520 | 533 | |
|
521 | 534 | def reset(self, new_session=True): |
|
522 | 535 | """Clear the session history, releasing all object references, and |
|
523 | 536 | optionally open a new session.""" |
|
524 | 537 | self.output_hist.clear() |
|
525 | 538 | # The directory history can't be completely empty |
|
526 | 539 | self.dir_hist[:] = [py3compat.getcwd()] |
|
527 | 540 | |
|
528 | 541 | if new_session: |
|
529 | 542 | if self.session_number: |
|
530 | 543 | self.end_session() |
|
531 | 544 | self.input_hist_parsed[:] = [""] |
|
532 | 545 | self.input_hist_raw[:] = [""] |
|
533 | 546 | self.new_session() |
|
534 | 547 | |
|
535 | 548 | # ------------------------------ |
|
536 | 549 | # Methods for retrieving history |
|
537 | 550 | # ------------------------------ |
|
551 | def get_session_info(self, session=0): | |
|
552 | """Get info about a session. | |
|
553 | ||
|
554 | Parameters | |
|
555 | ---------- | |
|
556 | ||
|
557 | session : int | |
|
558 | Session number to retrieve. The current session is 0, and negative | |
|
559 | numbers count back from current session, so -1 is the previous session. | |
|
560 | ||
|
561 | Returns | |
|
562 | ------- | |
|
563 | ||
|
564 | session_id : int | |
|
565 | Session ID number | |
|
566 | start : datetime | |
|
567 | Timestamp for the start of the session. | |
|
568 | end : datetime | |
|
569 | Timestamp for the end of the session, or None if IPython crashed. | |
|
570 | num_cmds : int | |
|
571 | Number of commands run, or None if IPython crashed. | |
|
572 | remark : unicode | |
|
573 | A manually set description. | |
|
574 | """ | |
|
575 | if session <= 0: | |
|
576 | session += self.session_number | |
|
577 | ||
|
578 | return super(HistoryManager, self).get_session_info(session=session) | |
|
579 | ||
|
538 | 580 | def _get_range_session(self, start=1, stop=None, raw=True, output=False): |
|
539 | 581 | """Get input and output history from the current session. Called by |
|
540 | 582 | get_range, and takes similar parameters.""" |
|
541 | 583 | input_hist = self.input_hist_raw if raw else self.input_hist_parsed |
|
542 | 584 | |
|
543 | 585 | n = len(input_hist) |
|
544 | 586 | if start < 0: |
|
545 | 587 | start += n |
|
546 | 588 | if not stop or (stop > n): |
|
547 | 589 | stop = n |
|
548 | 590 | elif stop < 0: |
|
549 | 591 | stop += n |
|
550 | 592 | |
|
551 | 593 | for i in range(start, stop): |
|
552 | 594 | if output: |
|
553 | 595 | line = (input_hist[i], self.output_hist_reprs.get(i)) |
|
554 | 596 | else: |
|
555 | 597 | line = input_hist[i] |
|
556 | 598 | yield (0, i, line) |
|
557 | 599 | |
|
558 | 600 | def get_range(self, session=0, start=1, stop=None, raw=True,output=False): |
|
559 | 601 | """Retrieve input by session. |
|
560 | 602 | |
|
561 | 603 | Parameters |
|
562 | 604 | ---------- |
|
563 | 605 | session : int |
|
564 | 606 | Session number to retrieve. The current session is 0, and negative |
|
565 | 607 | numbers count back from current session, so -1 is previous session. |
|
566 | 608 | start : int |
|
567 | 609 | First line to retrieve. |
|
568 | 610 | stop : int |
|
569 | 611 | End of line range (excluded from output itself). If None, retrieve |
|
570 | 612 | to the end of the session. |
|
571 | 613 | raw : bool |
|
572 | 614 | If True, return untranslated input |
|
573 | 615 | output : bool |
|
574 | 616 | If True, attempt to include output. This will be 'real' Python |
|
575 | 617 | objects for the current session, or text reprs from previous |
|
576 | 618 | sessions if db_log_output was enabled at the time. Where no output |
|
577 | 619 | is found, None is used. |
|
578 | 620 | |
|
579 | 621 | Returns |
|
580 | 622 | ------- |
|
581 | An iterator over the desired lines. Each line is a 3-tuple, either | |
|
582 | (session, line, input) if output is False, or | |
|
583 |
(session, line, |
|
|
623 | entries | |
|
624 | An iterator over the desired lines. Each line is a 3-tuple, either | |
|
625 | (session, line, input) if output is False, or | |
|
626 | (session, line, (input, output)) if output is True. | |
|
584 | 627 | """ |
|
585 | 628 | if session <= 0: |
|
586 | 629 | session += self.session_number |
|
587 | 630 | if session==self.session_number: # Current session |
|
588 | 631 | return self._get_range_session(start, stop, raw, output) |
|
589 | 632 | return super(HistoryManager, self).get_range(session, start, stop, raw, |
|
590 | 633 | output) |
|
591 | 634 | |
|
592 | 635 | ## ---------------------------- |
|
593 | 636 | ## Methods for storing history: |
|
594 | 637 | ## ---------------------------- |
|
595 | 638 | def store_inputs(self, line_num, source, source_raw=None): |
|
596 | 639 | """Store source and raw input in history and create input cache |
|
597 | variables _i*. | |
|
640 | variables ``_i*``. | |
|
598 | 641 | |
|
599 | 642 | Parameters |
|
600 | 643 | ---------- |
|
601 | 644 | line_num : int |
|
602 | 645 | The prompt number of this input. |
|
603 | 646 | |
|
604 | 647 | source : str |
|
605 | 648 | Python input. |
|
606 | 649 | |
|
607 | 650 | source_raw : str, optional |
|
608 | 651 | If given, this is the raw input without any IPython transformations |
|
609 | 652 | applied to it. If not given, ``source`` is used. |
|
610 | 653 | """ |
|
611 | 654 | if source_raw is None: |
|
612 | 655 | source_raw = source |
|
613 | 656 | source = source.rstrip('\n') |
|
614 | 657 | source_raw = source_raw.rstrip('\n') |
|
615 | 658 | |
|
616 | 659 | # do not store exit/quit commands |
|
617 | 660 | if self._exit_re.match(source_raw.strip()): |
|
618 | 661 | return |
|
619 | 662 | |
|
620 | 663 | self.input_hist_parsed.append(source) |
|
621 | 664 | self.input_hist_raw.append(source_raw) |
|
622 | 665 | |
|
623 | 666 | with self.db_input_cache_lock: |
|
624 | 667 | self.db_input_cache.append((line_num, source, source_raw)) |
|
625 | 668 | # Trigger to flush cache and write to DB. |
|
626 | 669 | if len(self.db_input_cache) >= self.db_cache_size: |
|
627 | 670 | self.save_flag.set() |
|
628 | 671 | |
|
629 | 672 | # update the auto _i variables |
|
630 | 673 | self._iii = self._ii |
|
631 | 674 | self._ii = self._i |
|
632 | 675 | self._i = self._i00 |
|
633 | 676 | self._i00 = source_raw |
|
634 | 677 | |
|
635 | 678 | # hackish access to user namespace to create _i1,_i2... dynamically |
|
636 | 679 | new_i = '_i%s' % line_num |
|
637 | 680 | to_main = {'_i': self._i, |
|
638 | 681 | '_ii': self._ii, |
|
639 | 682 | '_iii': self._iii, |
|
640 | 683 | new_i : self._i00 } |
|
641 | 684 | |
|
642 | 685 | if self.shell is not None: |
|
643 | 686 | self.shell.push(to_main, interactive=False) |
|
644 | 687 | |
|
645 | 688 | def store_output(self, line_num): |
|
646 | 689 | """If database output logging is enabled, this saves all the |
|
647 | 690 | outputs from the indicated prompt number to the database. It's |
|
648 | 691 | called by run_cell after code has been executed. |
|
649 | 692 | |
|
650 | 693 | Parameters |
|
651 | 694 | ---------- |
|
652 | 695 | line_num : int |
|
653 | 696 | The line number from which to save outputs |
|
654 | 697 | """ |
|
655 | 698 | if (not self.db_log_output) or (line_num not in self.output_hist_reprs): |
|
656 | 699 | return |
|
657 | 700 | output = self.output_hist_reprs[line_num] |
|
658 | 701 | |
|
659 | 702 | with self.db_output_cache_lock: |
|
660 | 703 | self.db_output_cache.append((line_num, output)) |
|
661 | 704 | if self.db_cache_size <= 1: |
|
662 | 705 | self.save_flag.set() |
|
663 | 706 | |
|
664 | 707 | def _writeout_input_cache(self, conn): |
|
665 | 708 | with conn: |
|
666 | 709 | for line in self.db_input_cache: |
|
667 | 710 | conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)", |
|
668 | 711 | (self.session_number,)+line) |
|
669 | 712 | |
|
670 | 713 | def _writeout_output_cache(self, conn): |
|
671 | 714 | with conn: |
|
672 | 715 | for line in self.db_output_cache: |
|
673 | 716 | conn.execute("INSERT INTO output_history VALUES (?, ?, ?)", |
|
674 | 717 | (self.session_number,)+line) |
|
675 | 718 | |
|
676 | 719 | @needs_sqlite |
|
677 | 720 | def writeout_cache(self, conn=None): |
|
678 | 721 | """Write any entries in the cache to the database.""" |
|
679 | 722 | if conn is None: |
|
680 | 723 | conn = self.db |
|
681 | 724 | |
|
682 | 725 | with self.db_input_cache_lock: |
|
683 | 726 | try: |
|
684 | 727 | self._writeout_input_cache(conn) |
|
685 | 728 | except sqlite3.IntegrityError: |
|
686 | 729 | self.new_session(conn) |
|
687 | 730 | print("ERROR! Session/line number was not unique in", |
|
688 | 731 | "database. History logging moved to new session", |
|
689 | 732 | self.session_number) |
|
690 | 733 | try: |
|
691 | 734 | # Try writing to the new session. If this fails, don't |
|
692 | 735 | # recurse |
|
693 | 736 | self._writeout_input_cache(conn) |
|
694 | 737 | except sqlite3.IntegrityError: |
|
695 | 738 | pass |
|
696 | 739 | finally: |
|
697 | 740 | self.db_input_cache = [] |
|
698 | 741 | |
|
699 | 742 | with self.db_output_cache_lock: |
|
700 | 743 | try: |
|
701 | 744 | self._writeout_output_cache(conn) |
|
702 | 745 | except sqlite3.IntegrityError: |
|
703 | 746 | print("!! Session/line number for output was not unique", |
|
704 | 747 | "in database. Output will not be stored.") |
|
705 | 748 | finally: |
|
706 | 749 | self.db_output_cache = [] |
|
707 | 750 | |
|
708 | 751 | |
|
709 | 752 | class HistorySavingThread(threading.Thread): |
|
710 | 753 | """This thread takes care of writing history to the database, so that |
|
711 | 754 | the UI isn't held up while that happens. |
|
712 | 755 | |
|
713 | 756 | It waits for the HistoryManager's save_flag to be set, then writes out |
|
714 | 757 | the history cache. The main thread is responsible for setting the flag when |
|
715 | 758 | the cache size reaches a defined threshold.""" |
|
716 | 759 | daemon = True |
|
717 | 760 | stop_now = False |
|
718 | 761 | enabled = True |
|
719 | 762 | def __init__(self, history_manager): |
|
720 | 763 | super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread") |
|
721 | 764 | self.history_manager = history_manager |
|
722 | 765 | self.enabled = history_manager.enabled |
|
723 | 766 | atexit.register(self.stop) |
|
724 | 767 | |
|
725 | 768 | @needs_sqlite |
|
726 | 769 | def run(self): |
|
727 | 770 | # We need a separate db connection per thread: |
|
728 | 771 | try: |
|
729 | 772 | self.db = sqlite3.connect(self.history_manager.hist_file, |
|
730 | 773 | **self.history_manager.connection_options |
|
731 | 774 | ) |
|
732 | 775 | while True: |
|
733 | 776 | self.history_manager.save_flag.wait() |
|
734 | 777 | if self.stop_now: |
|
735 | 778 | return |
|
736 | 779 | self.history_manager.save_flag.clear() |
|
737 | 780 | self.history_manager.writeout_cache(self.db) |
|
738 | 781 | except Exception as e: |
|
739 | 782 | print(("The history saving thread hit an unexpected error (%s)." |
|
740 | 783 | "History will not be written to the database.") % repr(e)) |
|
741 | 784 | |
|
742 | 785 | def stop(self): |
|
743 | 786 | """This can be called from the main thread to safely stop this thread. |
|
744 | 787 | |
|
745 | 788 | Note that it does not attempt to write out remaining history before |
|
746 | 789 | exiting. That should be done by calling the HistoryManager's |
|
747 | 790 | end_session method.""" |
|
748 | 791 | self.stop_now = True |
|
749 | 792 | self.history_manager.save_flag.set() |
|
750 | 793 | self.join() |
|
751 | 794 | |
|
752 | 795 | |
|
753 | 796 | # To match, e.g. ~5/8-~2/3 |
|
754 | 797 | range_re = re.compile(r""" |
|
755 | 798 | ((?P<startsess>~?\d+)/)? |
|
756 | 799 | (?P<start>\d+)? |
|
757 | 800 | ((?P<sep>[\-:]) |
|
758 | 801 | ((?P<endsess>~?\d+)/)? |
|
759 | 802 | (?P<end>\d+))? |
|
760 | 803 | $""", re.VERBOSE) |
|
761 | 804 | |
|
762 | 805 | |
|
763 | 806 | def extract_hist_ranges(ranges_str): |
|
764 | 807 | """Turn a string of history ranges into 3-tuples of (session, start, stop). |
|
765 | 808 | |
|
766 | 809 | Examples |
|
767 | 810 | -------- |
|
768 |
list(extract_ |
|
|
769 |
[(-8, 5, None), (-7, 1, |
|
|
811 | >>> list(extract_hist_ranges("~8/5-~7/4 2")) | |
|
812 | [(-8, 5, None), (-7, 1, 5), (0, 2, 3)] | |
|
770 | 813 | """ |
|
771 | 814 | for range_str in ranges_str.split(): |
|
772 | 815 | rmatch = range_re.match(range_str) |
|
773 | 816 | if not rmatch: |
|
774 | 817 | continue |
|
775 | 818 | start = rmatch.group("start") |
|
776 | 819 | if start: |
|
777 | 820 | start = int(start) |
|
778 | 821 | end = rmatch.group("end") |
|
779 | 822 | # If no end specified, get (a, a + 1) |
|
780 | 823 | end = int(end) if end else start + 1 |
|
781 | 824 | else: # start not specified |
|
782 | 825 | if not rmatch.group('startsess'): # no startsess |
|
783 | 826 | continue |
|
784 | 827 | start = 1 |
|
785 | 828 | end = None # provide the entire session hist |
|
786 | 829 | |
|
787 | 830 | if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3] |
|
788 | 831 | end += 1 |
|
789 | 832 | startsess = rmatch.group("startsess") or "0" |
|
790 | 833 | endsess = rmatch.group("endsess") or startsess |
|
791 | 834 | startsess = int(startsess.replace("~","-")) |
|
792 | 835 | endsess = int(endsess.replace("~","-")) |
|
793 | 836 | assert endsess >= startsess, "start session must be earlier than end session" |
|
794 | 837 | |
|
795 | 838 | if endsess == startsess: |
|
796 | 839 | yield (startsess, start, end) |
|
797 | 840 | continue |
|
798 | 841 | # Multiple sessions in one range: |
|
799 | 842 | yield (startsess, start, None) |
|
800 | 843 | for sess in range(startsess+1, endsess): |
|
801 | 844 | yield (sess, 1, None) |
|
802 | 845 | yield (endsess, 1, end) |
|
803 | 846 | |
|
804 | 847 | |
|
805 | 848 | def _format_lineno(session, line): |
|
806 | 849 | """Helper function to format line numbers properly.""" |
|
807 | 850 | if session == 0: |
|
808 | 851 | return str(line) |
|
809 | 852 | return "%s#%s" % (session, line) |
|
810 | 853 | |
|
811 | 854 |
@@ -1,280 +1,281 b'' | |||
|
1 | 1 | """Magic functions for running cells in various scripts.""" |
|
2 | 2 | from __future__ import print_function |
|
3 | 3 | #----------------------------------------------------------------------------- |
|
4 | 4 | # Copyright (c) 2012 The IPython Development Team. |
|
5 | 5 | # |
|
6 | 6 | # Distributed under the terms of the Modified BSD License. |
|
7 | 7 | # |
|
8 | 8 | # The full license is in the file COPYING.txt, distributed with this software. |
|
9 | 9 | #----------------------------------------------------------------------------- |
|
10 | 10 | |
|
11 | 11 | #----------------------------------------------------------------------------- |
|
12 | 12 | # Imports |
|
13 | 13 | #----------------------------------------------------------------------------- |
|
14 | 14 | |
|
15 | 15 | # Stdlib |
|
16 | 16 | import errno |
|
17 | 17 | import os |
|
18 | 18 | import sys |
|
19 | 19 | import signal |
|
20 | 20 | import time |
|
21 | 21 | from subprocess import Popen, PIPE |
|
22 | 22 | import atexit |
|
23 | 23 | |
|
24 | 24 | # Our own packages |
|
25 | 25 | from IPython.config.configurable import Configurable |
|
26 | 26 | from IPython.core import magic_arguments |
|
27 | 27 | from IPython.core.magic import ( |
|
28 | 28 | Magics, magics_class, line_magic, cell_magic |
|
29 | 29 | ) |
|
30 | 30 | from IPython.lib.backgroundjobs import BackgroundJobManager |
|
31 | 31 | from IPython.utils import py3compat |
|
32 | 32 | from IPython.utils.process import arg_split |
|
33 | 33 | from IPython.utils.traitlets import List, Dict |
|
34 | 34 | |
|
35 | 35 | #----------------------------------------------------------------------------- |
|
36 | 36 | # Magic implementation classes |
|
37 | 37 | #----------------------------------------------------------------------------- |
|
38 | 38 | |
|
39 | 39 | def script_args(f): |
|
40 | 40 | """single decorator for adding script args""" |
|
41 | 41 | args = [ |
|
42 | 42 | magic_arguments.argument( |
|
43 | 43 | '--out', type=str, |
|
44 | 44 | help="""The variable in which to store stdout from the script. |
|
45 | 45 | If the script is backgrounded, this will be the stdout *pipe*, |
|
46 | 46 | instead of the stderr text itself. |
|
47 | 47 | """ |
|
48 | 48 | ), |
|
49 | 49 | magic_arguments.argument( |
|
50 | 50 | '--err', type=str, |
|
51 | 51 | help="""The variable in which to store stderr from the script. |
|
52 | 52 | If the script is backgrounded, this will be the stderr *pipe*, |
|
53 | 53 | instead of the stderr text itself. |
|
54 | 54 | """ |
|
55 | 55 | ), |
|
56 | 56 | magic_arguments.argument( |
|
57 | 57 | '--bg', action="store_true", |
|
58 | 58 | help="""Whether to run the script in the background. |
|
59 | 59 | If given, the only way to see the output of the command is |
|
60 | 60 | with --out/err. |
|
61 | 61 | """ |
|
62 | 62 | ), |
|
63 | 63 | magic_arguments.argument( |
|
64 | 64 | '--proc', type=str, |
|
65 | 65 | help="""The variable in which to store Popen instance. |
|
66 | 66 | This is used only when --bg option is given. |
|
67 | 67 | """ |
|
68 | 68 | ), |
|
69 | 69 | ] |
|
70 | 70 | for arg in args: |
|
71 | 71 | f = arg(f) |
|
72 | 72 | return f |
|
73 | 73 | |
|
74 | 74 | @magics_class |
|
75 | 75 | class ScriptMagics(Magics): |
|
76 | 76 | """Magics for talking to scripts |
|
77 | 77 | |
|
78 | 78 | This defines a base `%%script` cell magic for running a cell |
|
79 | 79 | with a program in a subprocess, and registers a few top-level |
|
80 | 80 | magics that call %%script with common interpreters. |
|
81 | 81 | """ |
|
82 | 82 | script_magics = List(config=True, |
|
83 | 83 | help="""Extra script cell magics to define |
|
84 | 84 | |
|
85 | 85 | This generates simple wrappers of `%%script foo` as `%%foo`. |
|
86 | 86 | |
|
87 | 87 | If you want to add script magics that aren't on your path, |
|
88 | 88 | specify them in script_paths |
|
89 | 89 | """, |
|
90 | 90 | ) |
|
91 | 91 | def _script_magics_default(self): |
|
92 | 92 | """default to a common list of programs""" |
|
93 | 93 | |
|
94 | 94 | defaults = [ |
|
95 | 95 | 'sh', |
|
96 | 96 | 'bash', |
|
97 | 97 | 'perl', |
|
98 | 98 | 'ruby', |
|
99 | 99 | 'python', |
|
100 | 'python2', | |
|
100 | 101 | 'python3', |
|
101 | 102 | 'pypy', |
|
102 | 103 | ] |
|
103 | 104 | if os.name == 'nt': |
|
104 | 105 | defaults.extend([ |
|
105 | 106 | 'cmd', |
|
106 | 107 | 'powershell', |
|
107 | 108 | ]) |
|
108 | 109 | |
|
109 | 110 | return defaults |
|
110 | 111 | |
|
111 | 112 | script_paths = Dict(config=True, |
|
112 | 113 | help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby' |
|
113 | 114 | |
|
114 | 115 | Only necessary for items in script_magics where the default path will not |
|
115 | 116 | find the right interpreter. |
|
116 | 117 | """ |
|
117 | 118 | ) |
|
118 | 119 | |
|
119 | 120 | def __init__(self, shell=None): |
|
120 | 121 | super(ScriptMagics, self).__init__(shell=shell) |
|
121 | 122 | self._generate_script_magics() |
|
122 | 123 | self.job_manager = BackgroundJobManager() |
|
123 | 124 | self.bg_processes = [] |
|
124 | 125 | atexit.register(self.kill_bg_processes) |
|
125 | 126 | |
|
126 | 127 | def __del__(self): |
|
127 | 128 | self.kill_bg_processes() |
|
128 | 129 | |
|
129 | 130 | def _generate_script_magics(self): |
|
130 | 131 | cell_magics = self.magics['cell'] |
|
131 | 132 | for name in self.script_magics: |
|
132 | 133 | cell_magics[name] = self._make_script_magic(name) |
|
133 | 134 | |
|
134 | 135 | def _make_script_magic(self, name): |
|
135 | 136 | """make a named magic, that calls %%script with a particular program""" |
|
136 | 137 | # expand to explicit path if necessary: |
|
137 | 138 | script = self.script_paths.get(name, name) |
|
138 | 139 | |
|
139 | 140 | @magic_arguments.magic_arguments() |
|
140 | 141 | @script_args |
|
141 | 142 | def named_script_magic(line, cell): |
|
142 | 143 | # if line, add it as cl-flags |
|
143 | 144 | if line: |
|
144 | 145 | line = "%s %s" % (script, line) |
|
145 | 146 | else: |
|
146 | 147 | line = script |
|
147 | 148 | return self.shebang(line, cell) |
|
148 | 149 | |
|
149 | 150 | # write a basic docstring: |
|
150 | 151 | named_script_magic.__doc__ = \ |
|
151 | 152 | """%%{name} script magic |
|
152 | 153 | |
|
153 | 154 | Run cells with {script} in a subprocess. |
|
154 | 155 | |
|
155 | 156 | This is a shortcut for `%%script {script}` |
|
156 | 157 | """.format(**locals()) |
|
157 | 158 | |
|
158 | 159 | return named_script_magic |
|
159 | 160 | |
|
160 | 161 | @magic_arguments.magic_arguments() |
|
161 | 162 | @script_args |
|
162 | 163 | @cell_magic("script") |
|
163 | 164 | def shebang(self, line, cell): |
|
164 | 165 | """Run a cell via a shell command |
|
165 | 166 | |
|
166 | 167 | The `%%script` line is like the #! line of script, |
|
167 | 168 | specifying a program (bash, perl, ruby, etc.) with which to run. |
|
168 | 169 | |
|
169 | 170 | The rest of the cell is run by that program. |
|
170 | 171 | |
|
171 | 172 | Examples |
|
172 | 173 | -------- |
|
173 | 174 | :: |
|
174 | 175 | |
|
175 | 176 | In [1]: %%script bash |
|
176 | 177 | ...: for i in 1 2 3; do |
|
177 | 178 | ...: echo $i |
|
178 | 179 | ...: done |
|
179 | 180 | 1 |
|
180 | 181 | 2 |
|
181 | 182 | 3 |
|
182 | 183 | """ |
|
183 | 184 | argv = arg_split(line, posix = not sys.platform.startswith('win')) |
|
184 | 185 | args, cmd = self.shebang.parser.parse_known_args(argv) |
|
185 | 186 | |
|
186 | 187 | try: |
|
187 | 188 | p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE) |
|
188 | 189 | except OSError as e: |
|
189 | 190 | if e.errno == errno.ENOENT: |
|
190 | 191 | print("Couldn't find program: %r" % cmd[0]) |
|
191 | 192 | return |
|
192 | 193 | else: |
|
193 | 194 | raise |
|
194 | 195 | |
|
195 | 196 | cell = cell.encode('utf8', 'replace') |
|
196 | 197 | if args.bg: |
|
197 | 198 | self.bg_processes.append(p) |
|
198 | 199 | self._gc_bg_processes() |
|
199 | 200 | if args.out: |
|
200 | 201 | self.shell.user_ns[args.out] = p.stdout |
|
201 | 202 | if args.err: |
|
202 | 203 | self.shell.user_ns[args.err] = p.stderr |
|
203 | 204 | self.job_manager.new(self._run_script, p, cell, daemon=True) |
|
204 | 205 | if args.proc: |
|
205 | 206 | self.shell.user_ns[args.proc] = p |
|
206 | 207 | return |
|
207 | 208 | |
|
208 | 209 | try: |
|
209 | 210 | out, err = p.communicate(cell) |
|
210 | 211 | except KeyboardInterrupt: |
|
211 | 212 | try: |
|
212 | 213 | p.send_signal(signal.SIGINT) |
|
213 | 214 | time.sleep(0.1) |
|
214 | 215 | if p.poll() is not None: |
|
215 | 216 | print("Process is interrupted.") |
|
216 | 217 | return |
|
217 | 218 | p.terminate() |
|
218 | 219 | time.sleep(0.1) |
|
219 | 220 | if p.poll() is not None: |
|
220 | 221 | print("Process is terminated.") |
|
221 | 222 | return |
|
222 | 223 | p.kill() |
|
223 | 224 | print("Process is killed.") |
|
224 | 225 | except OSError: |
|
225 | 226 | pass |
|
226 | 227 | except Exception as e: |
|
227 | 228 | print("Error while terminating subprocess (pid=%i): %s" \ |
|
228 | 229 | % (p.pid, e)) |
|
229 | 230 | return |
|
230 | 231 | out = py3compat.bytes_to_str(out) |
|
231 | 232 | err = py3compat.bytes_to_str(err) |
|
232 | 233 | if args.out: |
|
233 | 234 | self.shell.user_ns[args.out] = out |
|
234 | 235 | else: |
|
235 | 236 | sys.stdout.write(out) |
|
236 | 237 | sys.stdout.flush() |
|
237 | 238 | if args.err: |
|
238 | 239 | self.shell.user_ns[args.err] = err |
|
239 | 240 | else: |
|
240 | 241 | sys.stderr.write(err) |
|
241 | 242 | sys.stderr.flush() |
|
242 | 243 | |
|
243 | 244 | def _run_script(self, p, cell): |
|
244 | 245 | """callback for running the script in the background""" |
|
245 | 246 | p.stdin.write(cell) |
|
246 | 247 | p.stdin.close() |
|
247 | 248 | p.wait() |
|
248 | 249 | |
|
249 | 250 | @line_magic("killbgscripts") |
|
250 | 251 | def killbgscripts(self, _nouse_=''): |
|
251 | 252 | """Kill all BG processes started by %%script and its family.""" |
|
252 | 253 | self.kill_bg_processes() |
|
253 | 254 | print("All background processes were killed.") |
|
254 | 255 | |
|
255 | 256 | def kill_bg_processes(self): |
|
256 | 257 | """Kill all BG processes which are still running.""" |
|
257 | 258 | for p in self.bg_processes: |
|
258 | 259 | if p.poll() is None: |
|
259 | 260 | try: |
|
260 | 261 | p.send_signal(signal.SIGINT) |
|
261 | 262 | except: |
|
262 | 263 | pass |
|
263 | 264 | time.sleep(0.1) |
|
264 | 265 | for p in self.bg_processes: |
|
265 | 266 | if p.poll() is None: |
|
266 | 267 | try: |
|
267 | 268 | p.terminate() |
|
268 | 269 | except: |
|
269 | 270 | pass |
|
270 | 271 | time.sleep(0.1) |
|
271 | 272 | for p in self.bg_processes: |
|
272 | 273 | if p.poll() is None: |
|
273 | 274 | try: |
|
274 | 275 | p.kill() |
|
275 | 276 | except: |
|
276 | 277 | pass |
|
277 | 278 | self._gc_bg_processes() |
|
278 | 279 | |
|
279 | 280 | def _gc_bg_processes(self): |
|
280 | 281 | self.bg_processes = [p for p in self.bg_processes if p.poll() is None] |
@@ -1,376 +1,382 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | """Pylab (matplotlib) support utilities. |
|
3 | 3 | |
|
4 | 4 | Authors |
|
5 | 5 | ------- |
|
6 | 6 | |
|
7 | 7 | * Fernando Perez. |
|
8 | 8 | * Brian Granger |
|
9 | 9 | """ |
|
10 | 10 | from __future__ import print_function |
|
11 | 11 | |
|
12 | 12 | #----------------------------------------------------------------------------- |
|
13 | 13 | # Copyright (C) 2009 The IPython Development Team |
|
14 | 14 | # |
|
15 | 15 | # Distributed under the terms of the BSD License. The full license is in |
|
16 | 16 | # the file COPYING, distributed as part of this software. |
|
17 | 17 | #----------------------------------------------------------------------------- |
|
18 | 18 | |
|
19 | 19 | #----------------------------------------------------------------------------- |
|
20 | 20 | # Imports |
|
21 | 21 | #----------------------------------------------------------------------------- |
|
22 | 22 | |
|
23 | 23 | import sys |
|
24 | 24 | from io import BytesIO |
|
25 | 25 | |
|
26 | 26 | from IPython.core.display import _pngxy |
|
27 | 27 | from IPython.utils.decorators import flag_calls |
|
28 | 28 | from IPython.utils import py3compat |
|
29 | 29 | |
|
30 | 30 | # If user specifies a GUI, that dictates the backend, otherwise we read the |
|
31 | 31 | # user's mpl default from the mpl rc structure |
|
32 | 32 | backends = {'tk': 'TkAgg', |
|
33 | 33 | 'gtk': 'GTKAgg', |
|
34 | 34 | 'gtk3': 'GTK3Agg', |
|
35 | 35 | 'wx': 'WXAgg', |
|
36 | 36 | 'qt': 'Qt4Agg', # qt3 not supported |
|
37 | 37 | 'qt4': 'Qt4Agg', |
|
38 | 38 | 'osx': 'MacOSX', |
|
39 | 39 | 'inline' : 'module://IPython.kernel.zmq.pylab.backend_inline'} |
|
40 | 40 | |
|
41 | 41 | # We also need a reverse backends2guis mapping that will properly choose which |
|
42 | 42 | # GUI support to activate based on the desired matplotlib backend. For the |
|
43 | 43 | # most part it's just a reverse of the above dict, but we also need to add a |
|
44 | 44 | # few others that map to the same GUI manually: |
|
45 | 45 | backend2gui = dict(zip(backends.values(), backends.keys())) |
|
46 | 46 | # Our tests expect backend2gui to just return 'qt' |
|
47 | 47 | backend2gui['Qt4Agg'] = 'qt' |
|
48 | 48 | # In the reverse mapping, there are a few extra valid matplotlib backends that |
|
49 | 49 | # map to the same GUI support |
|
50 | 50 | backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk' |
|
51 | 51 | backend2gui['GTK3Cairo'] = 'gtk3' |
|
52 | 52 | backend2gui['WX'] = 'wx' |
|
53 | 53 | backend2gui['CocoaAgg'] = 'osx' |
|
54 | 54 | |
|
55 | 55 | #----------------------------------------------------------------------------- |
|
56 | 56 | # Matplotlib utilities |
|
57 | 57 | #----------------------------------------------------------------------------- |
|
58 | 58 | |
|
59 | 59 | |
|
60 | 60 | def getfigs(*fig_nums): |
|
61 | 61 | """Get a list of matplotlib figures by figure numbers. |
|
62 | 62 | |
|
63 | 63 | If no arguments are given, all available figures are returned. If the |
|
64 | 64 | argument list contains references to invalid figures, a warning is printed |
|
65 | 65 | but the function continues pasting further figures. |
|
66 | 66 | |
|
67 | 67 | Parameters |
|
68 | 68 | ---------- |
|
69 | 69 | figs : tuple |
|
70 | 70 | A tuple of ints giving the figure numbers of the figures to return. |
|
71 | 71 | """ |
|
72 | 72 | from matplotlib._pylab_helpers import Gcf |
|
73 | 73 | if not fig_nums: |
|
74 | 74 | fig_managers = Gcf.get_all_fig_managers() |
|
75 | 75 | return [fm.canvas.figure for fm in fig_managers] |
|
76 | 76 | else: |
|
77 | 77 | figs = [] |
|
78 | 78 | for num in fig_nums: |
|
79 | 79 | f = Gcf.figs.get(num) |
|
80 | 80 | if f is None: |
|
81 | 81 | print('Warning: figure %s not available.' % num) |
|
82 | 82 | else: |
|
83 | 83 | figs.append(f.canvas.figure) |
|
84 | 84 | return figs |
|
85 | 85 | |
|
86 | 86 | |
|
87 | 87 | def figsize(sizex, sizey): |
|
88 | 88 | """Set the default figure size to be [sizex, sizey]. |
|
89 | 89 | |
|
90 | 90 | This is just an easy to remember, convenience wrapper that sets:: |
|
91 | 91 | |
|
92 | 92 | matplotlib.rcParams['figure.figsize'] = [sizex, sizey] |
|
93 | 93 | """ |
|
94 | 94 | import matplotlib |
|
95 | 95 | matplotlib.rcParams['figure.figsize'] = [sizex, sizey] |
|
96 | 96 | |
|
97 | 97 | |
|
98 | 98 | def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs): |
|
99 |
"""Print a figure to an image, and return the resulting |
|
|
99 | """Print a figure to an image, and return the resulting file data | |
|
100 | ||
|
101 | Returned data will be bytes unless ``fmt='svg'``, | |
|
102 | in which case it will be unicode. | |
|
100 | 103 | |
|
101 | 104 | Any keyword args are passed to fig.canvas.print_figure, |
|
102 | 105 | such as ``quality`` or ``bbox_inches``. |
|
103 | 106 | """ |
|
104 | 107 | from matplotlib import rcParams |
|
105 | 108 | # When there's an empty figure, we shouldn't return anything, otherwise we |
|
106 | 109 | # get big blank areas in the qt console. |
|
107 | 110 | if not fig.axes and not fig.lines: |
|
108 | 111 | return |
|
109 | 112 | |
|
110 | 113 | dpi = rcParams['savefig.dpi'] |
|
111 | 114 | if fmt == 'retina': |
|
112 | 115 | dpi = dpi * 2 |
|
113 | 116 | fmt = 'png' |
|
114 | 117 | |
|
115 | 118 | # build keyword args |
|
116 | 119 | kw = dict( |
|
117 | 120 | format=fmt, |
|
118 | 121 | fc=fig.get_facecolor(), |
|
119 | 122 | ec=fig.get_edgecolor(), |
|
120 | 123 | dpi=dpi, |
|
121 | 124 | bbox_inches=bbox_inches, |
|
122 | 125 | ) |
|
123 | 126 | # **kwargs get higher priority |
|
124 | 127 | kw.update(kwargs) |
|
125 | 128 | |
|
126 | 129 | bytes_io = BytesIO() |
|
127 | 130 | fig.canvas.print_figure(bytes_io, **kw) |
|
128 |
|
|
|
131 | data = bytes_io.getvalue() | |
|
132 | if fmt == 'svg': | |
|
133 | data = data.decode('utf-8') | |
|
134 | return data | |
|
129 | 135 | |
|
130 | 136 | def retina_figure(fig, **kwargs): |
|
131 | 137 | """format a figure as a pixel-doubled (retina) PNG""" |
|
132 | 138 | pngdata = print_figure(fig, fmt='retina', **kwargs) |
|
133 | 139 | w, h = _pngxy(pngdata) |
|
134 | 140 | metadata = dict(width=w//2, height=h//2) |
|
135 | 141 | return pngdata, metadata |
|
136 | 142 | |
|
137 | 143 | # We need a little factory function here to create the closure where |
|
138 | 144 | # safe_execfile can live. |
|
139 | 145 | def mpl_runner(safe_execfile): |
|
140 | 146 | """Factory to return a matplotlib-enabled runner for %run. |
|
141 | 147 | |
|
142 | 148 | Parameters |
|
143 | 149 | ---------- |
|
144 | 150 | safe_execfile : function |
|
145 | 151 | This must be a function with the same interface as the |
|
146 | 152 | :meth:`safe_execfile` method of IPython. |
|
147 | 153 | |
|
148 | 154 | Returns |
|
149 | 155 | ------- |
|
150 | 156 | A function suitable for use as the ``runner`` argument of the %run magic |
|
151 | 157 | function. |
|
152 | 158 | """ |
|
153 | 159 | |
|
154 | 160 | def mpl_execfile(fname,*where,**kw): |
|
155 | 161 | """matplotlib-aware wrapper around safe_execfile. |
|
156 | 162 | |
|
157 | 163 | Its interface is identical to that of the :func:`execfile` builtin. |
|
158 | 164 | |
|
159 | 165 | This is ultimately a call to execfile(), but wrapped in safeties to |
|
160 | 166 | properly handle interactive rendering.""" |
|
161 | 167 | |
|
162 | 168 | import matplotlib |
|
163 | 169 | import matplotlib.pylab as pylab |
|
164 | 170 | |
|
165 | 171 | #print '*** Matplotlib runner ***' # dbg |
|
166 | 172 | # turn off rendering until end of script |
|
167 | 173 | is_interactive = matplotlib.rcParams['interactive'] |
|
168 | 174 | matplotlib.interactive(False) |
|
169 | 175 | safe_execfile(fname,*where,**kw) |
|
170 | 176 | matplotlib.interactive(is_interactive) |
|
171 | 177 | # make rendering call now, if the user tried to do it |
|
172 | 178 | if pylab.draw_if_interactive.called: |
|
173 | 179 | pylab.draw() |
|
174 | 180 | pylab.draw_if_interactive.called = False |
|
175 | 181 | |
|
176 | 182 | return mpl_execfile |
|
177 | 183 | |
|
178 | 184 | |
|
179 | 185 | def select_figure_formats(shell, formats, **kwargs): |
|
180 | 186 | """Select figure formats for the inline backend. |
|
181 | 187 | |
|
182 | 188 | Parameters |
|
183 | 189 | ========== |
|
184 | 190 | shell : InteractiveShell |
|
185 | 191 | The main IPython instance. |
|
186 | 192 | formats : str or set |
|
187 | 193 | One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'. |
|
188 | 194 | **kwargs : any |
|
189 | 195 | Extra keyword arguments to be passed to fig.canvas.print_figure. |
|
190 | 196 | """ |
|
191 | 197 | from matplotlib.figure import Figure |
|
192 | 198 | from IPython.kernel.zmq.pylab import backend_inline |
|
193 | 199 | |
|
194 | 200 | svg_formatter = shell.display_formatter.formatters['image/svg+xml'] |
|
195 | 201 | png_formatter = shell.display_formatter.formatters['image/png'] |
|
196 | 202 | jpg_formatter = shell.display_formatter.formatters['image/jpeg'] |
|
197 | 203 | pdf_formatter = shell.display_formatter.formatters['application/pdf'] |
|
198 | 204 | |
|
199 | 205 | if isinstance(formats, py3compat.string_types): |
|
200 | 206 | formats = {formats} |
|
201 | 207 | # cast in case of list / tuple |
|
202 | 208 | formats = set(formats) |
|
203 | 209 | |
|
204 | 210 | [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ] |
|
205 | 211 | |
|
206 | 212 | supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'} |
|
207 | 213 | bad = formats.difference(supported) |
|
208 | 214 | if bad: |
|
209 | 215 | bs = "%s" % ','.join([repr(f) for f in bad]) |
|
210 | 216 | gs = "%s" % ','.join([repr(f) for f in supported]) |
|
211 | 217 | raise ValueError("supported formats are: %s not %s" % (gs, bs)) |
|
212 | 218 | |
|
213 | 219 | if 'png' in formats: |
|
214 | 220 | png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs)) |
|
215 | 221 | if 'retina' in formats or 'png2x' in formats: |
|
216 | 222 | png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs)) |
|
217 | 223 | if 'jpg' in formats or 'jpeg' in formats: |
|
218 | 224 | jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs)) |
|
219 | 225 | if 'svg' in formats: |
|
220 | 226 | svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs)) |
|
221 | 227 | if 'pdf' in formats: |
|
222 | 228 | pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs)) |
|
223 | 229 | |
|
224 | 230 | #----------------------------------------------------------------------------- |
|
225 | 231 | # Code for initializing matplotlib and importing pylab |
|
226 | 232 | #----------------------------------------------------------------------------- |
|
227 | 233 | |
|
228 | 234 | |
|
229 | 235 | def find_gui_and_backend(gui=None, gui_select=None): |
|
230 | 236 | """Given a gui string return the gui and mpl backend. |
|
231 | 237 | |
|
232 | 238 | Parameters |
|
233 | 239 | ---------- |
|
234 | 240 | gui : str |
|
235 | 241 | Can be one of ('tk','gtk','wx','qt','qt4','inline'). |
|
236 | 242 | gui_select : str |
|
237 | 243 | Can be one of ('tk','gtk','wx','qt','qt4','inline'). |
|
238 | 244 | This is any gui already selected by the shell. |
|
239 | 245 | |
|
240 | 246 | Returns |
|
241 | 247 | ------- |
|
242 | 248 | A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg', |
|
243 | 249 | 'WXAgg','Qt4Agg','module://IPython.kernel.zmq.pylab.backend_inline'). |
|
244 | 250 | """ |
|
245 | 251 | |
|
246 | 252 | import matplotlib |
|
247 | 253 | |
|
248 | 254 | if gui and gui != 'auto': |
|
249 | 255 | # select backend based on requested gui |
|
250 | 256 | backend = backends[gui] |
|
251 | 257 | else: |
|
252 | 258 | # We need to read the backend from the original data structure, *not* |
|
253 | 259 | # from mpl.rcParams, since a prior invocation of %matplotlib may have |
|
254 | 260 | # overwritten that. |
|
255 | 261 | # WARNING: this assumes matplotlib 1.1 or newer!! |
|
256 | 262 | backend = matplotlib.rcParamsOrig['backend'] |
|
257 | 263 | # In this case, we need to find what the appropriate gui selection call |
|
258 | 264 | # should be for IPython, so we can activate inputhook accordingly |
|
259 | 265 | gui = backend2gui.get(backend, None) |
|
260 | 266 | |
|
261 | 267 | # If we have already had a gui active, we need it and inline are the |
|
262 | 268 | # ones allowed. |
|
263 | 269 | if gui_select and gui != gui_select: |
|
264 | 270 | gui = gui_select |
|
265 | 271 | backend = backends[gui] |
|
266 | 272 | |
|
267 | 273 | return gui, backend |
|
268 | 274 | |
|
269 | 275 | |
|
270 | 276 | def activate_matplotlib(backend): |
|
271 | 277 | """Activate the given backend and set interactive to True.""" |
|
272 | 278 | |
|
273 | 279 | import matplotlib |
|
274 | 280 | matplotlib.interactive(True) |
|
275 | 281 | |
|
276 | 282 | # Matplotlib had a bug where even switch_backend could not force |
|
277 | 283 | # the rcParam to update. This needs to be set *before* the module |
|
278 | 284 | # magic of switch_backend(). |
|
279 | 285 | matplotlib.rcParams['backend'] = backend |
|
280 | 286 | |
|
281 | 287 | import matplotlib.pyplot |
|
282 | 288 | matplotlib.pyplot.switch_backend(backend) |
|
283 | 289 | |
|
284 | 290 | # This must be imported last in the matplotlib series, after |
|
285 | 291 | # backend/interactivity choices have been made |
|
286 | 292 | import matplotlib.pylab as pylab |
|
287 | 293 | |
|
288 | 294 | pylab.show._needmain = False |
|
289 | 295 | # We need to detect at runtime whether show() is called by the user. |
|
290 | 296 | # For this, we wrap it into a decorator which adds a 'called' flag. |
|
291 | 297 | pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive) |
|
292 | 298 | |
|
293 | 299 | |
|
294 | 300 | def import_pylab(user_ns, import_all=True): |
|
295 | 301 | """Populate the namespace with pylab-related values. |
|
296 | 302 | |
|
297 | 303 | Imports matplotlib, pylab, numpy, and everything from pylab and numpy. |
|
298 | 304 | |
|
299 | 305 | Also imports a few names from IPython (figsize, display, getfigs) |
|
300 | 306 | |
|
301 | 307 | """ |
|
302 | 308 | |
|
303 | 309 | # Import numpy as np/pyplot as plt are conventions we're trying to |
|
304 | 310 | # somewhat standardize on. Making them available to users by default |
|
305 | 311 | # will greatly help this. |
|
306 | 312 | s = ("import numpy\n" |
|
307 | 313 | "import matplotlib\n" |
|
308 | 314 | "from matplotlib import pylab, mlab, pyplot\n" |
|
309 | 315 | "np = numpy\n" |
|
310 | 316 | "plt = pyplot\n" |
|
311 | 317 | ) |
|
312 | 318 | exec(s, user_ns) |
|
313 | 319 | |
|
314 | 320 | if import_all: |
|
315 | 321 | s = ("from matplotlib.pylab import *\n" |
|
316 | 322 | "from numpy import *\n") |
|
317 | 323 | exec(s, user_ns) |
|
318 | 324 | |
|
319 | 325 | # IPython symbols to add |
|
320 | 326 | user_ns['figsize'] = figsize |
|
321 | 327 | from IPython.core.display import display |
|
322 | 328 | # Add display and getfigs to the user's namespace |
|
323 | 329 | user_ns['display'] = display |
|
324 | 330 | user_ns['getfigs'] = getfigs |
|
325 | 331 | |
|
326 | 332 | |
|
327 | 333 | def configure_inline_support(shell, backend): |
|
328 | 334 | """Configure an IPython shell object for matplotlib use. |
|
329 | 335 | |
|
330 | 336 | Parameters |
|
331 | 337 | ---------- |
|
332 | 338 | shell : InteractiveShell instance |
|
333 | 339 | |
|
334 | 340 | backend : matplotlib backend |
|
335 | 341 | """ |
|
336 | 342 | # If using our svg payload backend, register the post-execution |
|
337 | 343 | # function that will pick up the results for display. This can only be |
|
338 | 344 | # done with access to the real shell object. |
|
339 | 345 | |
|
340 | 346 | # Note: if we can't load the inline backend, then there's no point |
|
341 | 347 | # continuing (such as in terminal-only shells in environments without |
|
342 | 348 | # zeromq available). |
|
343 | 349 | try: |
|
344 | 350 | from IPython.kernel.zmq.pylab.backend_inline import InlineBackend |
|
345 | 351 | except ImportError: |
|
346 | 352 | return |
|
347 | 353 | from matplotlib import pyplot |
|
348 | 354 | |
|
349 | 355 | cfg = InlineBackend.instance(parent=shell) |
|
350 | 356 | cfg.shell = shell |
|
351 | 357 | if cfg not in shell.configurables: |
|
352 | 358 | shell.configurables.append(cfg) |
|
353 | 359 | |
|
354 | 360 | if backend == backends['inline']: |
|
355 | 361 | from IPython.kernel.zmq.pylab.backend_inline import flush_figures |
|
356 | 362 | shell.events.register('post_execute', flush_figures) |
|
357 | 363 | |
|
358 | 364 | # Save rcParams that will be overwrittern |
|
359 | 365 | shell._saved_rcParams = dict() |
|
360 | 366 | for k in cfg.rc: |
|
361 | 367 | shell._saved_rcParams[k] = pyplot.rcParams[k] |
|
362 | 368 | # load inline_rc |
|
363 | 369 | pyplot.rcParams.update(cfg.rc) |
|
364 | 370 | else: |
|
365 | 371 | from IPython.kernel.zmq.pylab.backend_inline import flush_figures |
|
366 | 372 | try: |
|
367 | 373 | shell.events.unregister('post_execute', flush_figures) |
|
368 | 374 | except ValueError: |
|
369 | 375 | pass |
|
370 | 376 | if hasattr(shell, '_saved_rcParams'): |
|
371 | 377 | pyplot.rcParams.update(shell._saved_rcParams) |
|
372 | 378 | del shell._saved_rcParams |
|
373 | 379 | |
|
374 | 380 | # Setup the default figure format |
|
375 | 381 | select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs) |
|
376 | 382 |
@@ -1,148 +1,149 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | """Release data for the IPython project.""" |
|
3 | 3 | |
|
4 | 4 | #----------------------------------------------------------------------------- |
|
5 | 5 | # Copyright (c) 2008, IPython Development Team. |
|
6 | 6 | # Copyright (c) 2001, Fernando Perez <fernando.perez@colorado.edu> |
|
7 | 7 | # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de> |
|
8 | 8 | # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu> |
|
9 | 9 | # |
|
10 | 10 | # Distributed under the terms of the Modified BSD License. |
|
11 | 11 | # |
|
12 | 12 | # The full license is in the file COPYING.txt, distributed with this software. |
|
13 | 13 | #----------------------------------------------------------------------------- |
|
14 | 14 | |
|
15 | 15 | # Name of the package for release purposes. This is the name which labels |
|
16 | 16 | # the tarballs and RPMs made by distutils, so it's best to lowercase it. |
|
17 | 17 | name = 'ipython' |
|
18 | 18 | |
|
19 | 19 | # IPython version information. An empty _version_extra corresponds to a full |
|
20 | 20 | # release. 'dev' as a _version_extra string means this is a development |
|
21 | 21 | # version |
|
22 | 22 | _version_major = 2 |
|
23 | 23 | _version_minor = 0 |
|
24 | 24 | _version_patch = 0 |
|
25 | 25 | _version_extra = 'dev' |
|
26 | 26 | # _version_extra = 'rc1' |
|
27 | 27 | # _version_extra = '' # Uncomment this for full releases |
|
28 | 28 | |
|
29 | codename = 'Work in Progress' | |
|
29 | # release.codename is deprecated in 2.0, will be removed in 3.0 | |
|
30 | codename = '' | |
|
30 | 31 | |
|
31 | 32 | # Construct full version string from these. |
|
32 | 33 | _ver = [_version_major, _version_minor, _version_patch] |
|
33 | 34 | |
|
34 | 35 | __version__ = '.'.join(map(str, _ver)) |
|
35 | 36 | if _version_extra: |
|
36 | 37 | __version__ = __version__ + '-' + _version_extra |
|
37 | 38 | |
|
38 | 39 | version = __version__ # backwards compatibility name |
|
39 | 40 | version_info = (_version_major, _version_minor, _version_patch, _version_extra) |
|
40 | 41 | |
|
41 | 42 | # Change this when incrementing the kernel protocol version |
|
42 | 43 | kernel_protocol_version_info = (4, 1) |
|
43 | 44 | |
|
44 | 45 | description = "IPython: Productive Interactive Computing" |
|
45 | 46 | |
|
46 | 47 | long_description = \ |
|
47 | 48 | """ |
|
48 | 49 | IPython provides a rich toolkit to help you make the most out of using Python |
|
49 | 50 | interactively. Its main components are: |
|
50 | 51 | |
|
51 | 52 | * Powerful interactive Python shells (terminal- and Qt-based). |
|
52 | 53 | * A web-based interactive notebook environment with all shell features plus |
|
53 | 54 | support for embedded figures, animations and rich media. |
|
54 | 55 | * Support for interactive data visualization and use of GUI toolkits. |
|
55 | 56 | * Flexible, embeddable interpreters to load into your own projects. |
|
56 | 57 | * A high-performance library for high level and interactive parallel computing |
|
57 | 58 | that works in multicore systems, clusters, supercomputing and cloud scenarios. |
|
58 | 59 | |
|
59 | 60 | The enhanced interactive Python shells have the following main features: |
|
60 | 61 | |
|
61 | 62 | * Comprehensive object introspection. |
|
62 | 63 | |
|
63 | 64 | * Input history, persistent across sessions. |
|
64 | 65 | |
|
65 | 66 | * Caching of output results during a session with automatically generated |
|
66 | 67 | references. |
|
67 | 68 | |
|
68 | 69 | * Extensible tab completion, with support by default for completion of python |
|
69 | 70 | variables and keywords, filenames and function keywords. |
|
70 | 71 | |
|
71 | 72 | * Extensible system of 'magic' commands for controlling the environment and |
|
72 | 73 | performing many tasks related either to IPython or the operating system. |
|
73 | 74 | |
|
74 | 75 | * A rich configuration system with easy switching between different setups |
|
75 | 76 | (simpler than changing $PYTHONSTARTUP environment variables every time). |
|
76 | 77 | |
|
77 | 78 | * Session logging and reloading. |
|
78 | 79 | |
|
79 | 80 | * Extensible syntax processing for special purpose situations. |
|
80 | 81 | |
|
81 | 82 | * Access to the system shell with user-extensible alias system. |
|
82 | 83 | |
|
83 | 84 | * Easily embeddable in other Python programs and GUIs. |
|
84 | 85 | |
|
85 | 86 | * Integrated access to the pdb debugger and the Python profiler. |
|
86 | 87 | |
|
87 | 88 | The parallel computing architecture has the following main features: |
|
88 | 89 | |
|
89 | 90 | * Quickly parallelize Python code from an interactive Python/IPython session. |
|
90 | 91 | |
|
91 | 92 | * A flexible and dynamic process model that be deployed on anything from |
|
92 | 93 | multicore workstations to supercomputers. |
|
93 | 94 | |
|
94 | 95 | * An architecture that supports many different styles of parallelism, from |
|
95 | 96 | message passing to task farming. |
|
96 | 97 | |
|
97 | 98 | * Both blocking and fully asynchronous interfaces. |
|
98 | 99 | |
|
99 | 100 | * High level APIs that enable many things to be parallelized in a few lines |
|
100 | 101 | of code. |
|
101 | 102 | |
|
102 | 103 | * Share live parallel jobs with other users securely. |
|
103 | 104 | |
|
104 | 105 | * Dynamically load balanced task farming system. |
|
105 | 106 | |
|
106 | 107 | * Robust error handling in parallel code. |
|
107 | 108 | |
|
108 | 109 | The latest development version is always available from IPython's `GitHub |
|
109 | 110 | site <http://github.com/ipython>`_. |
|
110 | 111 | """ |
|
111 | 112 | |
|
112 | 113 | license = 'BSD' |
|
113 | 114 | |
|
114 | 115 | authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'), |
|
115 | 116 | 'Janko' : ('Janko Hauser','jhauser@zscout.de'), |
|
116 | 117 | 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu'), |
|
117 | 118 | 'Ville' : ('Ville Vainio','vivainio@gmail.com'), |
|
118 | 119 | 'Brian' : ('Brian E Granger', 'ellisonbg@gmail.com'), |
|
119 | 120 | 'Min' : ('Min Ragan-Kelley', 'benjaminrk@gmail.com'), |
|
120 | 121 | 'Thomas' : ('Thomas A. Kluyver', 'takowl@gmail.com'), |
|
121 | 122 | 'Jorgen' : ('Jorgen Stenarson', 'jorgen.stenarson@bostream.nu'), |
|
122 | 123 | 'Matthias' : ('Matthias Bussonnier', 'bussonniermatthias@gmail.com'), |
|
123 | 124 | } |
|
124 | 125 | |
|
125 | 126 | author = 'The IPython Development Team' |
|
126 | 127 | |
|
127 | 128 | author_email = 'ipython-dev@scipy.org' |
|
128 | 129 | |
|
129 | 130 | url = 'http://ipython.org' |
|
130 | 131 | |
|
131 | 132 | download_url = 'https://github.com/ipython/ipython/downloads' |
|
132 | 133 | |
|
133 | 134 | platforms = ['Linux','Mac OSX','Windows XP/Vista/7/8'] |
|
134 | 135 | |
|
135 | 136 | keywords = ['Interactive','Interpreter','Shell','Parallel','Distributed', |
|
136 | 137 | 'Web-based computing', 'Qt console', 'Embedding'] |
|
137 | 138 | |
|
138 | 139 | classifiers = [ |
|
139 | 140 | 'Intended Audience :: Developers', |
|
140 | 141 | 'Intended Audience :: Science/Research', |
|
141 | 142 | 'License :: OSI Approved :: BSD License', |
|
142 | 143 | 'Programming Language :: Python', |
|
143 | 144 | 'Programming Language :: Python :: 2', |
|
144 | 145 | 'Programming Language :: Python :: 2.7', |
|
145 | 146 | 'Programming Language :: Python :: 3', |
|
146 | 147 | 'Topic :: System :: Distributed Computing', |
|
147 | 148 | 'Topic :: System :: Shells' |
|
148 | 149 | ] |
@@ -1,241 +1,241 b'' | |||
|
1 | 1 | """Tests for pylab tools module. |
|
2 | 2 | """ |
|
3 | 3 | #----------------------------------------------------------------------------- |
|
4 | 4 | # Copyright (c) 2011, the IPython Development Team. |
|
5 | 5 | # |
|
6 | 6 | # Distributed under the terms of the Modified BSD License. |
|
7 | 7 | # |
|
8 | 8 | # The full license is in the file COPYING.txt, distributed with this software. |
|
9 | 9 | #----------------------------------------------------------------------------- |
|
10 | 10 | |
|
11 | 11 | #----------------------------------------------------------------------------- |
|
12 | 12 | # Imports |
|
13 | 13 | #----------------------------------------------------------------------------- |
|
14 | 14 | from __future__ import print_function |
|
15 | 15 | |
|
16 | 16 | from io import UnsupportedOperation, BytesIO |
|
17 | 17 | |
|
18 | 18 | import matplotlib |
|
19 | 19 | matplotlib.use('Agg') |
|
20 | 20 | from matplotlib.figure import Figure |
|
21 | 21 | |
|
22 | 22 | from nose import SkipTest |
|
23 | 23 | import nose.tools as nt |
|
24 | 24 | |
|
25 | 25 | from matplotlib import pyplot as plt |
|
26 | 26 | import numpy as np |
|
27 | 27 | |
|
28 | 28 | # Our own imports |
|
29 | 29 | from IPython.core.getipython import get_ipython |
|
30 | 30 | from IPython.core.interactiveshell import InteractiveShell |
|
31 | 31 | from IPython.core.display import _PNG, _JPEG |
|
32 | 32 | from .. import pylabtools as pt |
|
33 | 33 | |
|
34 | 34 | from IPython.testing import decorators as dec |
|
35 | 35 | |
|
36 | 36 | #----------------------------------------------------------------------------- |
|
37 | 37 | # Globals and constants |
|
38 | 38 | #----------------------------------------------------------------------------- |
|
39 | 39 | |
|
40 | 40 | #----------------------------------------------------------------------------- |
|
41 | 41 | # Local utilities |
|
42 | 42 | #----------------------------------------------------------------------------- |
|
43 | 43 | |
|
44 | 44 | #----------------------------------------------------------------------------- |
|
45 | 45 | # Classes and functions |
|
46 | 46 | #----------------------------------------------------------------------------- |
|
47 | 47 | |
|
48 | 48 | def test_figure_to_svg(): |
|
49 | 49 | # simple empty-figure test |
|
50 | 50 | fig = plt.figure() |
|
51 | 51 | nt.assert_equal(pt.print_figure(fig, 'svg'), None) |
|
52 | 52 | |
|
53 | 53 | plt.close('all') |
|
54 | 54 | |
|
55 | 55 | # simple check for at least svg-looking output |
|
56 | 56 | fig = plt.figure() |
|
57 | 57 | ax = fig.add_subplot(1,1,1) |
|
58 | 58 | ax.plot([1,2,3]) |
|
59 | 59 | plt.draw() |
|
60 | 60 | svg = pt.print_figure(fig, 'svg')[:100].lower() |
|
61 |
nt.assert_in( |
|
|
61 | nt.assert_in(u'doctype svg', svg) | |
|
62 | 62 | |
|
63 | 63 | def _check_pil_jpeg_bytes(): |
|
64 | 64 | """Skip if PIL can't write JPEGs to BytesIO objects""" |
|
65 | 65 | # PIL's JPEG plugin can't write to BytesIO objects |
|
66 | 66 | # Pillow fixes this |
|
67 | 67 | from PIL import Image |
|
68 | 68 | buf = BytesIO() |
|
69 | 69 | img = Image.new("RGB", (4,4)) |
|
70 | 70 | try: |
|
71 | 71 | img.save(buf, 'jpeg') |
|
72 | 72 | except Exception as e: |
|
73 | 73 | ename = e.__class__.__name__ |
|
74 | 74 | raise SkipTest("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e)) |
|
75 | 75 | |
|
76 | 76 | @dec.skip_without("PIL.Image") |
|
77 | 77 | def test_figure_to_jpeg(): |
|
78 | 78 | _check_pil_jpeg_bytes() |
|
79 | 79 | # simple check for at least jpeg-looking output |
|
80 | 80 | fig = plt.figure() |
|
81 | 81 | ax = fig.add_subplot(1,1,1) |
|
82 | 82 | ax.plot([1,2,3]) |
|
83 | 83 | plt.draw() |
|
84 | 84 | jpeg = pt.print_figure(fig, 'jpeg', quality=50)[:100].lower() |
|
85 | 85 | assert jpeg.startswith(_JPEG) |
|
86 | 86 | |
|
87 | 87 | def test_retina_figure(): |
|
88 | 88 | fig = plt.figure() |
|
89 | 89 | ax = fig.add_subplot(1,1,1) |
|
90 | 90 | ax.plot([1,2,3]) |
|
91 | 91 | plt.draw() |
|
92 | 92 | png, md = pt.retina_figure(fig) |
|
93 | 93 | assert png.startswith(_PNG) |
|
94 | 94 | nt.assert_in('width', md) |
|
95 | 95 | nt.assert_in('height', md) |
|
96 | 96 | |
|
97 | 97 | _fmt_mime_map = { |
|
98 | 98 | 'png': 'image/png', |
|
99 | 99 | 'jpeg': 'image/jpeg', |
|
100 | 100 | 'pdf': 'application/pdf', |
|
101 | 101 | 'retina': 'image/png', |
|
102 | 102 | 'svg': 'image/svg+xml', |
|
103 | 103 | } |
|
104 | 104 | |
|
105 | 105 | def test_select_figure_formats_str(): |
|
106 | 106 | ip = get_ipython() |
|
107 | 107 | for fmt, active_mime in _fmt_mime_map.items(): |
|
108 | 108 | pt.select_figure_formats(ip, fmt) |
|
109 | 109 | for mime, f in ip.display_formatter.formatters.items(): |
|
110 | 110 | if mime == active_mime: |
|
111 | 111 | nt.assert_in(Figure, f) |
|
112 | 112 | else: |
|
113 | 113 | nt.assert_not_in(Figure, f) |
|
114 | 114 | |
|
115 | 115 | def test_select_figure_formats_kwargs(): |
|
116 | 116 | ip = get_ipython() |
|
117 | 117 | kwargs = dict(quality=10, bbox_inches='tight') |
|
118 | 118 | pt.select_figure_formats(ip, 'png', **kwargs) |
|
119 | 119 | formatter = ip.display_formatter.formatters['image/png'] |
|
120 | 120 | f = formatter.lookup_by_type(Figure) |
|
121 | 121 | cell = f.__closure__[0].cell_contents |
|
122 | 122 | nt.assert_equal(cell, kwargs) |
|
123 | 123 | |
|
124 | 124 | # check that the formatter doesn't raise |
|
125 | 125 | fig = plt.figure() |
|
126 | 126 | ax = fig.add_subplot(1,1,1) |
|
127 | 127 | ax.plot([1,2,3]) |
|
128 | 128 | plt.draw() |
|
129 | 129 | formatter.enabled = True |
|
130 | 130 | png = formatter(fig) |
|
131 | 131 | assert png.startswith(_PNG) |
|
132 | 132 | |
|
133 | 133 | def test_select_figure_formats_set(): |
|
134 | 134 | ip = get_ipython() |
|
135 | 135 | for fmts in [ |
|
136 | 136 | {'png', 'svg'}, |
|
137 | 137 | ['png'], |
|
138 | 138 | ('jpeg', 'pdf', 'retina'), |
|
139 | 139 | {'svg'}, |
|
140 | 140 | ]: |
|
141 | 141 | active_mimes = {_fmt_mime_map[fmt] for fmt in fmts} |
|
142 | 142 | pt.select_figure_formats(ip, fmts) |
|
143 | 143 | for mime, f in ip.display_formatter.formatters.items(): |
|
144 | 144 | if mime in active_mimes: |
|
145 | 145 | nt.assert_in(Figure, f) |
|
146 | 146 | else: |
|
147 | 147 | nt.assert_not_in(Figure, f) |
|
148 | 148 | |
|
149 | 149 | def test_select_figure_formats_bad(): |
|
150 | 150 | ip = get_ipython() |
|
151 | 151 | with nt.assert_raises(ValueError): |
|
152 | 152 | pt.select_figure_formats(ip, 'foo') |
|
153 | 153 | with nt.assert_raises(ValueError): |
|
154 | 154 | pt.select_figure_formats(ip, {'png', 'foo'}) |
|
155 | 155 | with nt.assert_raises(ValueError): |
|
156 | 156 | pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad']) |
|
157 | 157 | |
|
158 | 158 | def test_import_pylab(): |
|
159 | 159 | ns = {} |
|
160 | 160 | pt.import_pylab(ns, import_all=False) |
|
161 | 161 | nt.assert_true('plt' in ns) |
|
162 | 162 | nt.assert_equal(ns['np'], np) |
|
163 | 163 | |
|
164 | 164 | class TestPylabSwitch(object): |
|
165 | 165 | class Shell(InteractiveShell): |
|
166 | 166 | def enable_gui(self, gui): |
|
167 | 167 | pass |
|
168 | 168 | |
|
169 | 169 | def setup(self): |
|
170 | 170 | import matplotlib |
|
171 | 171 | def act_mpl(backend): |
|
172 | 172 | matplotlib.rcParams['backend'] = backend |
|
173 | 173 | |
|
174 | 174 | # Save rcParams since they get modified |
|
175 | 175 | self._saved_rcParams = matplotlib.rcParams |
|
176 | 176 | self._saved_rcParamsOrig = matplotlib.rcParamsOrig |
|
177 | 177 | matplotlib.rcParams = dict(backend='Qt4Agg') |
|
178 | 178 | matplotlib.rcParamsOrig = dict(backend='Qt4Agg') |
|
179 | 179 | |
|
180 | 180 | # Mock out functions |
|
181 | 181 | self._save_am = pt.activate_matplotlib |
|
182 | 182 | pt.activate_matplotlib = act_mpl |
|
183 | 183 | self._save_ip = pt.import_pylab |
|
184 | 184 | pt.import_pylab = lambda *a,**kw:None |
|
185 | 185 | self._save_cis = pt.configure_inline_support |
|
186 | 186 | pt.configure_inline_support = lambda *a,**kw:None |
|
187 | 187 | |
|
188 | 188 | def teardown(self): |
|
189 | 189 | pt.activate_matplotlib = self._save_am |
|
190 | 190 | pt.import_pylab = self._save_ip |
|
191 | 191 | pt.configure_inline_support = self._save_cis |
|
192 | 192 | import matplotlib |
|
193 | 193 | matplotlib.rcParams = self._saved_rcParams |
|
194 | 194 | matplotlib.rcParamsOrig = self._saved_rcParamsOrig |
|
195 | 195 | |
|
196 | 196 | def test_qt(self): |
|
197 | 197 | s = self.Shell() |
|
198 | 198 | gui, backend = s.enable_matplotlib(None) |
|
199 | 199 | nt.assert_equal(gui, 'qt') |
|
200 | 200 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
201 | 201 | |
|
202 | 202 | gui, backend = s.enable_matplotlib('inline') |
|
203 | 203 | nt.assert_equal(gui, 'inline') |
|
204 | 204 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
205 | 205 | |
|
206 | 206 | gui, backend = s.enable_matplotlib('qt') |
|
207 | 207 | nt.assert_equal(gui, 'qt') |
|
208 | 208 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
209 | 209 | |
|
210 | 210 | gui, backend = s.enable_matplotlib('inline') |
|
211 | 211 | nt.assert_equal(gui, 'inline') |
|
212 | 212 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
213 | 213 | |
|
214 | 214 | gui, backend = s.enable_matplotlib() |
|
215 | 215 | nt.assert_equal(gui, 'qt') |
|
216 | 216 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
217 | 217 | |
|
218 | 218 | def test_inline(self): |
|
219 | 219 | s = self.Shell() |
|
220 | 220 | gui, backend = s.enable_matplotlib('inline') |
|
221 | 221 | nt.assert_equal(gui, 'inline') |
|
222 | 222 | nt.assert_equal(s.pylab_gui_select, None) |
|
223 | 223 | |
|
224 | 224 | gui, backend = s.enable_matplotlib('inline') |
|
225 | 225 | nt.assert_equal(gui, 'inline') |
|
226 | 226 | nt.assert_equal(s.pylab_gui_select, None) |
|
227 | 227 | |
|
228 | 228 | gui, backend = s.enable_matplotlib('qt') |
|
229 | 229 | nt.assert_equal(gui, 'qt') |
|
230 | 230 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
231 | 231 | |
|
232 | 232 | def test_qt_gtk(self): |
|
233 | 233 | s = self.Shell() |
|
234 | 234 | gui, backend = s.enable_matplotlib('qt') |
|
235 | 235 | nt.assert_equal(gui, 'qt') |
|
236 | 236 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
237 | 237 | |
|
238 | 238 | gui, backend = s.enable_matplotlib('gtk') |
|
239 | 239 | nt.assert_equal(gui, 'qt') |
|
240 | 240 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
241 | 241 |
@@ -1,851 +1,854 b'' | |||
|
1 | 1 | # coding: utf-8 |
|
2 | 2 | """A tornado based IPython notebook server. |
|
3 | 3 | |
|
4 | 4 | Authors: |
|
5 | 5 | |
|
6 | 6 | * Brian Granger |
|
7 | 7 | """ |
|
8 | 8 | from __future__ import print_function |
|
9 | 9 | #----------------------------------------------------------------------------- |
|
10 | 10 | # Copyright (C) 2013 The IPython Development Team |
|
11 | 11 | # |
|
12 | 12 | # Distributed under the terms of the BSD License. The full license is in |
|
13 | 13 | # the file COPYING, distributed as part of this software. |
|
14 | 14 | #----------------------------------------------------------------------------- |
|
15 | 15 | |
|
16 | 16 | #----------------------------------------------------------------------------- |
|
17 | 17 | # Imports |
|
18 | 18 | #----------------------------------------------------------------------------- |
|
19 | 19 | |
|
20 | 20 | # stdlib |
|
21 | 21 | import errno |
|
22 | 22 | import io |
|
23 | 23 | import json |
|
24 | 24 | import logging |
|
25 | 25 | import os |
|
26 | 26 | import random |
|
27 | 27 | import select |
|
28 | 28 | import signal |
|
29 | 29 | import socket |
|
30 | 30 | import sys |
|
31 | 31 | import threading |
|
32 | 32 | import time |
|
33 | 33 | import webbrowser |
|
34 | 34 | |
|
35 | 35 | |
|
36 | 36 | # Third party |
|
37 | 37 | # check for pyzmq 2.1.11 |
|
38 | 38 | from IPython.utils.zmqrelated import check_for_zmq |
|
39 | 39 | check_for_zmq('2.1.11', 'IPython.html') |
|
40 | 40 | |
|
41 | 41 | from jinja2 import Environment, FileSystemLoader |
|
42 | 42 | |
|
43 | 43 | # Install the pyzmq ioloop. This has to be done before anything else from |
|
44 | 44 | # tornado is imported. |
|
45 | 45 | from zmq.eventloop import ioloop |
|
46 | 46 | ioloop.install() |
|
47 | 47 | |
|
48 | 48 | # check for tornado 3.1.0 |
|
49 | 49 | msg = "The IPython Notebook requires tornado >= 3.1.0" |
|
50 | 50 | try: |
|
51 | 51 | import tornado |
|
52 | 52 | except ImportError: |
|
53 | 53 | raise ImportError(msg) |
|
54 | 54 | try: |
|
55 | 55 | version_info = tornado.version_info |
|
56 | 56 | except AttributeError: |
|
57 | 57 | raise ImportError(msg + ", but you have < 1.1.0") |
|
58 | 58 | if version_info < (3,1,0): |
|
59 | 59 | raise ImportError(msg + ", but you have %s" % tornado.version) |
|
60 | 60 | |
|
61 | 61 | from tornado import httpserver |
|
62 | 62 | from tornado import web |
|
63 | 63 | |
|
64 | 64 | # Our own libraries |
|
65 | 65 | from IPython.html import DEFAULT_STATIC_FILES_PATH |
|
66 | 66 | from .base.handlers import Template404 |
|
67 | 67 | from .log import log_request |
|
68 | 68 | from .services.kernels.kernelmanager import MappingKernelManager |
|
69 | 69 | from .services.notebooks.nbmanager import NotebookManager |
|
70 | 70 | from .services.notebooks.filenbmanager import FileNotebookManager |
|
71 | 71 | from .services.clusters.clustermanager import ClusterManager |
|
72 | 72 | from .services.sessions.sessionmanager import SessionManager |
|
73 | 73 | |
|
74 | 74 | from .base.handlers import AuthenticatedFileHandler, FileFindHandler |
|
75 | 75 | |
|
76 | from IPython.config import Config | |
|
76 | 77 | from IPython.config.application import catch_config_error, boolean_flag |
|
77 | 78 | from IPython.core.application import BaseIPythonApplication |
|
78 | 79 | from IPython.core.profiledir import ProfileDir |
|
79 | 80 | from IPython.consoleapp import IPythonConsoleApp |
|
80 | 81 | from IPython.kernel import swallow_argv |
|
81 | 82 | from IPython.kernel.zmq.session import default_secure |
|
82 | 83 | from IPython.kernel.zmq.kernelapp import ( |
|
83 | 84 | kernel_flags, |
|
84 | 85 | kernel_aliases, |
|
85 | 86 | ) |
|
86 | 87 | from IPython.nbformat.sign import NotebookNotary |
|
87 | 88 | from IPython.utils.importstring import import_item |
|
88 | 89 | from IPython.utils.localinterfaces import localhost |
|
89 | 90 | from IPython.utils import submodule |
|
90 | 91 | from IPython.utils.traitlets import ( |
|
91 | 92 | Dict, Unicode, Integer, List, Bool, Bytes, |
|
92 | 93 | DottedObjectName, TraitError, |
|
93 | 94 | ) |
|
94 | 95 | from IPython.utils import py3compat |
|
95 | 96 | from IPython.utils.path import filefind, get_ipython_dir |
|
96 | 97 | |
|
97 | 98 | from .utils import url_path_join |
|
98 | 99 | |
|
99 | 100 | #----------------------------------------------------------------------------- |
|
100 | 101 | # Module globals |
|
101 | 102 | #----------------------------------------------------------------------------- |
|
102 | 103 | |
|
103 | 104 | _examples = """ |
|
104 | 105 | ipython notebook # start the notebook |
|
105 | 106 | ipython notebook --profile=sympy # use the sympy profile |
|
106 | 107 | ipython notebook --certfile=mycert.pem # use SSL/TLS certificate |
|
107 | 108 | """ |
|
108 | 109 | |
|
109 | 110 | #----------------------------------------------------------------------------- |
|
110 | 111 | # Helper functions |
|
111 | 112 | #----------------------------------------------------------------------------- |
|
112 | 113 | |
|
113 | 114 | def random_ports(port, n): |
|
114 | 115 | """Generate a list of n random ports near the given port. |
|
115 | 116 | |
|
116 | 117 | The first 5 ports will be sequential, and the remaining n-5 will be |
|
117 | 118 | randomly selected in the range [port-2*n, port+2*n]. |
|
118 | 119 | """ |
|
119 | 120 | for i in range(min(5, n)): |
|
120 | 121 | yield port + i |
|
121 | 122 | for i in range(n-5): |
|
122 | 123 | yield max(1, port + random.randint(-2*n, 2*n)) |
|
123 | 124 | |
|
124 | 125 | def load_handlers(name): |
|
125 | 126 | """Load the (URL pattern, handler) tuples for each component.""" |
|
126 | 127 | name = 'IPython.html.' + name |
|
127 | 128 | mod = __import__(name, fromlist=['default_handlers']) |
|
128 | 129 | return mod.default_handlers |
|
129 | 130 | |
|
130 | 131 | #----------------------------------------------------------------------------- |
|
131 | 132 | # The Tornado web application |
|
132 | 133 | #----------------------------------------------------------------------------- |
|
133 | 134 | |
|
134 | 135 | class NotebookWebApplication(web.Application): |
|
135 | 136 | |
|
136 | 137 | def __init__(self, ipython_app, kernel_manager, notebook_manager, |
|
137 | 138 | cluster_manager, session_manager, log, base_url, |
|
138 | 139 | settings_overrides, jinja_env_options): |
|
139 | 140 | |
|
140 | 141 | settings = self.init_settings( |
|
141 | 142 | ipython_app, kernel_manager, notebook_manager, cluster_manager, |
|
142 | 143 | session_manager, log, base_url, settings_overrides, jinja_env_options) |
|
143 | 144 | handlers = self.init_handlers(settings) |
|
144 | 145 | |
|
145 | 146 | super(NotebookWebApplication, self).__init__(handlers, **settings) |
|
146 | 147 | |
|
147 | 148 | def init_settings(self, ipython_app, kernel_manager, notebook_manager, |
|
148 | 149 | cluster_manager, session_manager, log, base_url, |
|
149 | 150 | settings_overrides, jinja_env_options=None): |
|
150 | 151 | # Python < 2.6.5 doesn't accept unicode keys in f(**kwargs), and |
|
151 | 152 | # base_url will always be unicode, which will in turn |
|
152 | 153 | # make the patterns unicode, and ultimately result in unicode |
|
153 | 154 | # keys in kwargs to handler._execute(**kwargs) in tornado. |
|
154 | 155 | # This enforces that base_url be ascii in that situation. |
|
155 | 156 | # |
|
156 | 157 | # Note that the URLs these patterns check against are escaped, |
|
157 | 158 | # and thus guaranteed to be ASCII: 'héllo' is really 'h%C3%A9llo'. |
|
158 | 159 | base_url = py3compat.unicode_to_str(base_url, 'ascii') |
|
159 | 160 | template_path = settings_overrides.get("template_path", os.path.join(os.path.dirname(__file__), "templates")) |
|
160 | 161 | jenv_opt = jinja_env_options if jinja_env_options else {} |
|
161 | 162 | env = Environment(loader=FileSystemLoader(template_path),**jenv_opt ) |
|
162 | 163 | settings = dict( |
|
163 | 164 | # basics |
|
164 | 165 | log_function=log_request, |
|
165 | 166 | base_url=base_url, |
|
166 | 167 | template_path=template_path, |
|
167 | 168 | static_path=ipython_app.static_file_path, |
|
168 | 169 | static_handler_class = FileFindHandler, |
|
169 | 170 | static_url_prefix = url_path_join(base_url,'/static/'), |
|
170 | 171 | |
|
171 | 172 | # authentication |
|
172 | 173 | cookie_secret=ipython_app.cookie_secret, |
|
173 | 174 | login_url=url_path_join(base_url,'/login'), |
|
174 | 175 | password=ipython_app.password, |
|
175 | 176 | |
|
176 | 177 | # managers |
|
177 | 178 | kernel_manager=kernel_manager, |
|
178 | 179 | notebook_manager=notebook_manager, |
|
179 | 180 | cluster_manager=cluster_manager, |
|
180 | 181 | session_manager=session_manager, |
|
181 | 182 | |
|
182 | 183 | # IPython stuff |
|
183 | 184 | nbextensions_path = ipython_app.nbextensions_path, |
|
184 | 185 | mathjax_url=ipython_app.mathjax_url, |
|
185 | 186 | config=ipython_app.config, |
|
186 | 187 | jinja2_env=env, |
|
187 | 188 | ) |
|
188 | 189 | |
|
189 | 190 | # allow custom overrides for the tornado web app. |
|
190 | 191 | settings.update(settings_overrides) |
|
191 | 192 | return settings |
|
192 | 193 | |
|
193 | 194 | def init_handlers(self, settings): |
|
194 | 195 | # Load the (URL pattern, handler) tuples for each component. |
|
195 | 196 | handlers = [] |
|
196 | 197 | handlers.extend(load_handlers('base.handlers')) |
|
197 | 198 | handlers.extend(load_handlers('tree.handlers')) |
|
198 | 199 | handlers.extend(load_handlers('auth.login')) |
|
199 | 200 | handlers.extend(load_handlers('auth.logout')) |
|
200 | 201 | handlers.extend(load_handlers('notebook.handlers')) |
|
201 | 202 | handlers.extend(load_handlers('nbconvert.handlers')) |
|
202 | 203 | handlers.extend(load_handlers('services.kernels.handlers')) |
|
203 | 204 | handlers.extend(load_handlers('services.notebooks.handlers')) |
|
204 | 205 | handlers.extend(load_handlers('services.clusters.handlers')) |
|
205 | 206 | handlers.extend(load_handlers('services.sessions.handlers')) |
|
206 | 207 | handlers.extend(load_handlers('services.nbconvert.handlers')) |
|
207 | 208 | # FIXME: /files/ should be handled by the Contents service when it exists |
|
208 | 209 | nbm = settings['notebook_manager'] |
|
209 | 210 | if hasattr(nbm, 'notebook_dir'): |
|
210 | 211 | handlers.extend([ |
|
211 | 212 | (r"/files/(.*)", AuthenticatedFileHandler, {'path' : nbm.notebook_dir}), |
|
212 | 213 | (r"/nbextensions/(.*)", FileFindHandler, {'path' : settings['nbextensions_path']}), |
|
213 | 214 | ]) |
|
214 | 215 | # prepend base_url onto the patterns that we match |
|
215 | 216 | new_handlers = [] |
|
216 | 217 | for handler in handlers: |
|
217 | 218 | pattern = url_path_join(settings['base_url'], handler[0]) |
|
218 | 219 | new_handler = tuple([pattern] + list(handler[1:])) |
|
219 | 220 | new_handlers.append(new_handler) |
|
220 | 221 | # add 404 on the end, which will catch everything that falls through |
|
221 | 222 | new_handlers.append((r'(.*)', Template404)) |
|
222 | 223 | return new_handlers |
|
223 | 224 | |
|
224 | 225 | |
|
225 | 226 | class NbserverListApp(BaseIPythonApplication): |
|
226 | 227 | |
|
227 | 228 | description="List currently running notebook servers in this profile." |
|
228 | 229 | |
|
229 | 230 | flags = dict( |
|
230 | 231 | json=({'NbserverListApp': {'json': True}}, |
|
231 | 232 | "Produce machine-readable JSON output."), |
|
232 | 233 | ) |
|
233 | 234 | |
|
234 | 235 | json = Bool(False, config=True, |
|
235 | 236 | help="If True, each line of output will be a JSON object with the " |
|
236 | 237 | "details from the server info file.") |
|
237 | 238 | |
|
238 | 239 | def start(self): |
|
239 | 240 | if not self.json: |
|
240 | 241 | print("Currently running servers:") |
|
241 | 242 | for serverinfo in list_running_servers(self.profile): |
|
242 | 243 | if self.json: |
|
243 | 244 | print(json.dumps(serverinfo)) |
|
244 | 245 | else: |
|
245 | 246 | print(serverinfo['url'], "::", serverinfo['notebook_dir']) |
|
246 | 247 | |
|
247 | 248 | #----------------------------------------------------------------------------- |
|
248 | 249 | # Aliases and Flags |
|
249 | 250 | #----------------------------------------------------------------------------- |
|
250 | 251 | |
|
251 | 252 | flags = dict(kernel_flags) |
|
252 | 253 | flags['no-browser']=( |
|
253 | 254 | {'NotebookApp' : {'open_browser' : False}}, |
|
254 | 255 | "Don't open the notebook in a browser after startup." |
|
255 | 256 | ) |
|
256 | 257 | flags['no-mathjax']=( |
|
257 | 258 | {'NotebookApp' : {'enable_mathjax' : False}}, |
|
258 | 259 | """Disable MathJax |
|
259 | 260 | |
|
260 | 261 | MathJax is the javascript library IPython uses to render math/LaTeX. It is |
|
261 | 262 | very large, so you may want to disable it if you have a slow internet |
|
262 | 263 | connection, or for offline use of the notebook. |
|
263 | 264 | |
|
264 | 265 | When disabled, equations etc. will appear as their untransformed TeX source. |
|
265 | 266 | """ |
|
266 | 267 | ) |
|
267 | 268 | |
|
268 | 269 | # Add notebook manager flags |
|
269 | 270 | flags.update(boolean_flag('script', 'FileNotebookManager.save_script', |
|
270 | 271 | 'Auto-save a .py script everytime the .ipynb notebook is saved', |
|
271 | 272 | 'Do not auto-save .py scripts for every notebook')) |
|
272 | 273 | |
|
273 | 274 | # the flags that are specific to the frontend |
|
274 | 275 | # these must be scrubbed before being passed to the kernel, |
|
275 | 276 | # or it will raise an error on unrecognized flags |
|
276 | 277 | notebook_flags = ['no-browser', 'no-mathjax', 'script', 'no-script'] |
|
277 | 278 | |
|
278 | 279 | aliases = dict(kernel_aliases) |
|
279 | 280 | |
|
280 | 281 | aliases.update({ |
|
281 | 282 | 'ip': 'NotebookApp.ip', |
|
282 | 283 | 'port': 'NotebookApp.port', |
|
283 | 284 | 'port-retries': 'NotebookApp.port_retries', |
|
284 | 285 | 'transport': 'KernelManager.transport', |
|
285 | 286 | 'keyfile': 'NotebookApp.keyfile', |
|
286 | 287 | 'certfile': 'NotebookApp.certfile', |
|
287 | 288 | 'notebook-dir': 'NotebookApp.notebook_dir', |
|
288 | 289 | 'browser': 'NotebookApp.browser', |
|
289 | 290 | }) |
|
290 | 291 | |
|
291 | 292 | # remove ipkernel flags that are singletons, and don't make sense in |
|
292 | 293 | # multi-kernel evironment: |
|
293 | 294 | aliases.pop('f', None) |
|
294 | 295 | |
|
295 | 296 | notebook_aliases = [u'port', u'port-retries', u'ip', u'keyfile', u'certfile', |
|
296 | 297 | u'notebook-dir', u'profile', u'profile-dir'] |
|
297 | 298 | |
|
298 | 299 | #----------------------------------------------------------------------------- |
|
299 | 300 | # NotebookApp |
|
300 | 301 | #----------------------------------------------------------------------------- |
|
301 | 302 | |
|
302 | 303 | class NotebookApp(BaseIPythonApplication): |
|
303 | 304 | |
|
304 | 305 | name = 'ipython-notebook' |
|
305 | 306 | |
|
306 | 307 | description = """ |
|
307 | 308 | The IPython HTML Notebook. |
|
308 | 309 | |
|
309 | 310 | This launches a Tornado based HTML Notebook Server that serves up an |
|
310 | 311 | HTML5/Javascript Notebook client. |
|
311 | 312 | """ |
|
312 | 313 | examples = _examples |
|
313 | 314 | |
|
314 | 315 | classes = IPythonConsoleApp.classes + [MappingKernelManager, NotebookManager, |
|
315 | 316 | FileNotebookManager, NotebookNotary] |
|
316 | 317 | flags = Dict(flags) |
|
317 | 318 | aliases = Dict(aliases) |
|
318 | 319 | |
|
319 | 320 | subcommands = dict( |
|
320 | 321 | list=(NbserverListApp, NbserverListApp.description.splitlines()[0]), |
|
321 | 322 | ) |
|
322 | 323 | |
|
323 | 324 | kernel_argv = List(Unicode) |
|
324 | 325 | |
|
325 | 326 | def _log_level_default(self): |
|
326 | 327 | return logging.INFO |
|
327 | 328 | |
|
328 | 329 | def _log_format_default(self): |
|
329 | 330 | """override default log format to include time""" |
|
330 | 331 | return u"%(asctime)s.%(msecs).03d [%(name)s]%(highlevel)s %(message)s" |
|
331 | 332 | |
|
332 | 333 | # create requested profiles by default, if they don't exist: |
|
333 | 334 | auto_create = Bool(True) |
|
334 | 335 | |
|
335 | 336 | # file to be opened in the notebook server |
|
336 | 337 | file_to_run = Unicode('', config=True) |
|
337 | 338 | def _file_to_run_changed(self, name, old, new): |
|
338 | 339 | path, base = os.path.split(new) |
|
339 | 340 | if path: |
|
340 | 341 | self.file_to_run = base |
|
341 | 342 | self.notebook_dir = path |
|
342 | 343 | |
|
343 | 344 | # Network related information. |
|
344 | 345 | |
|
345 | 346 | ip = Unicode(config=True, |
|
346 | 347 | help="The IP address the notebook server will listen on." |
|
347 | 348 | ) |
|
348 | 349 | def _ip_default(self): |
|
349 | 350 | return localhost() |
|
350 | 351 | |
|
351 | 352 | def _ip_changed(self, name, old, new): |
|
352 | 353 | if new == u'*': self.ip = u'' |
|
353 | 354 | |
|
354 | 355 | port = Integer(8888, config=True, |
|
355 | 356 | help="The port the notebook server will listen on." |
|
356 | 357 | ) |
|
357 | 358 | port_retries = Integer(50, config=True, |
|
358 | 359 | help="The number of additional ports to try if the specified port is not available." |
|
359 | 360 | ) |
|
360 | 361 | |
|
361 | 362 | certfile = Unicode(u'', config=True, |
|
362 | 363 | help="""The full path to an SSL/TLS certificate file.""" |
|
363 | 364 | ) |
|
364 | 365 | |
|
365 | 366 | keyfile = Unicode(u'', config=True, |
|
366 | 367 | help="""The full path to a private key file for usage with SSL/TLS.""" |
|
367 | 368 | ) |
|
368 | 369 | |
|
369 | 370 | cookie_secret = Bytes(b'', config=True, |
|
370 | 371 | help="""The random bytes used to secure cookies. |
|
371 | 372 | By default this is a new random number every time you start the Notebook. |
|
372 | 373 | Set it to a value in a config file to enable logins to persist across server sessions. |
|
373 | 374 | |
|
374 | 375 | Note: Cookie secrets should be kept private, do not share config files with |
|
375 | 376 | cookie_secret stored in plaintext (you can read the value from a file). |
|
376 | 377 | """ |
|
377 | 378 | ) |
|
378 | 379 | def _cookie_secret_default(self): |
|
379 | 380 | return os.urandom(1024) |
|
380 | 381 | |
|
381 | 382 | password = Unicode(u'', config=True, |
|
382 | 383 | help="""Hashed password to use for web authentication. |
|
383 | 384 | |
|
384 | 385 | To generate, type in a python/IPython shell: |
|
385 | 386 | |
|
386 | 387 | from IPython.lib import passwd; passwd() |
|
387 | 388 | |
|
388 | 389 | The string should be of the form type:salt:hashed-password. |
|
389 | 390 | """ |
|
390 | 391 | ) |
|
391 | 392 | |
|
392 | 393 | open_browser = Bool(True, config=True, |
|
393 | 394 | help="""Whether to open in a browser after starting. |
|
394 | 395 | The specific browser used is platform dependent and |
|
395 | 396 | determined by the python standard library `webbrowser` |
|
396 | 397 | module, unless it is overridden using the --browser |
|
397 | 398 | (NotebookApp.browser) configuration option. |
|
398 | 399 | """) |
|
399 | 400 | |
|
400 | 401 | browser = Unicode(u'', config=True, |
|
401 | 402 | help="""Specify what command to use to invoke a web |
|
402 | 403 | browser when opening the notebook. If not specified, the |
|
403 | 404 | default browser will be determined by the `webbrowser` |
|
404 | 405 | standard library module, which allows setting of the |
|
405 | 406 | BROWSER environment variable to override it. |
|
406 | 407 | """) |
|
407 | 408 | |
|
408 | 409 | webapp_settings = Dict(config=True, |
|
409 | 410 | help="Supply overrides for the tornado.web.Application that the " |
|
410 | 411 | "IPython notebook uses.") |
|
411 | 412 | |
|
412 | 413 | jinja_environment_options = Dict(config=True, |
|
413 | 414 | help="Supply extra arguments that will be passed to Jinja environment.") |
|
414 | 415 | |
|
415 | 416 | |
|
416 | 417 | enable_mathjax = Bool(True, config=True, |
|
417 | 418 | help="""Whether to enable MathJax for typesetting math/TeX |
|
418 | 419 | |
|
419 | 420 | MathJax is the javascript library IPython uses to render math/LaTeX. It is |
|
420 | 421 | very large, so you may want to disable it if you have a slow internet |
|
421 | 422 | connection, or for offline use of the notebook. |
|
422 | 423 | |
|
423 | 424 | When disabled, equations etc. will appear as their untransformed TeX source. |
|
424 | 425 | """ |
|
425 | 426 | ) |
|
426 | 427 | def _enable_mathjax_changed(self, name, old, new): |
|
427 | 428 | """set mathjax url to empty if mathjax is disabled""" |
|
428 | 429 | if not new: |
|
429 | 430 | self.mathjax_url = u'' |
|
430 | 431 | |
|
431 | 432 | base_url = Unicode('/', config=True, |
|
432 | 433 | help='''The base URL for the notebook server. |
|
433 | 434 | |
|
434 | 435 | Leading and trailing slashes can be omitted, |
|
435 | 436 | and will automatically be added. |
|
436 | 437 | ''') |
|
437 | 438 | def _base_url_changed(self, name, old, new): |
|
438 | 439 | if not new.startswith('/'): |
|
439 | 440 | self.base_url = '/'+new |
|
440 | 441 | elif not new.endswith('/'): |
|
441 | 442 | self.base_url = new+'/' |
|
442 | 443 | |
|
443 | 444 | base_project_url = Unicode('/', config=True, help="""DEPRECATED use base_url""") |
|
444 | 445 | def _base_project_url_changed(self, name, old, new): |
|
445 | 446 | self.log.warn("base_project_url is deprecated, use base_url") |
|
446 | 447 | self.base_url = new |
|
447 | 448 | |
|
448 | 449 | extra_static_paths = List(Unicode, config=True, |
|
449 | 450 | help="""Extra paths to search for serving static files. |
|
450 | 451 | |
|
451 | 452 | This allows adding javascript/css to be available from the notebook server machine, |
|
452 | 453 | or overriding individual files in the IPython""" |
|
453 | 454 | ) |
|
454 | 455 | def _extra_static_paths_default(self): |
|
455 | 456 | return [os.path.join(self.profile_dir.location, 'static')] |
|
456 | 457 | |
|
457 | 458 | @property |
|
458 | 459 | def static_file_path(self): |
|
459 | 460 | """return extra paths + the default location""" |
|
460 | 461 | return self.extra_static_paths + [DEFAULT_STATIC_FILES_PATH] |
|
461 | 462 | |
|
462 | 463 | nbextensions_path = List(Unicode, config=True, |
|
463 | 464 | help="""paths for Javascript extensions. By default, this is just IPYTHONDIR/nbextensions""" |
|
464 | 465 | ) |
|
465 | 466 | def _nbextensions_path_default(self): |
|
466 | 467 | return [os.path.join(get_ipython_dir(), 'nbextensions')] |
|
467 | 468 | |
|
468 | 469 | mathjax_url = Unicode("", config=True, |
|
469 | 470 | help="""The url for MathJax.js.""" |
|
470 | 471 | ) |
|
471 | 472 | def _mathjax_url_default(self): |
|
472 | 473 | if not self.enable_mathjax: |
|
473 | 474 | return u'' |
|
474 | 475 | static_url_prefix = self.webapp_settings.get("static_url_prefix", |
|
475 | 476 | url_path_join(self.base_url, "static") |
|
476 | 477 | ) |
|
477 | 478 | |
|
478 | 479 | # try local mathjax, either in nbextensions/mathjax or static/mathjax |
|
479 | 480 | for (url_prefix, search_path) in [ |
|
480 | 481 | (url_path_join(self.base_url, "nbextensions"), self.nbextensions_path), |
|
481 | 482 | (static_url_prefix, self.static_file_path), |
|
482 | 483 | ]: |
|
483 | 484 | self.log.debug("searching for local mathjax in %s", search_path) |
|
484 | 485 | try: |
|
485 | 486 | mathjax = filefind(os.path.join('mathjax', 'MathJax.js'), search_path) |
|
486 | 487 | except IOError: |
|
487 | 488 | continue |
|
488 | 489 | else: |
|
489 | 490 | url = url_path_join(url_prefix, u"mathjax/MathJax.js") |
|
490 | 491 | self.log.info("Serving local MathJax from %s at %s", mathjax, url) |
|
491 | 492 | return url |
|
492 | 493 | |
|
493 | 494 | # no local mathjax, serve from CDN |
|
494 | 495 | if self.certfile: |
|
495 | 496 | # HTTPS: load from Rackspace CDN, because SSL certificate requires it |
|
496 | 497 | host = u"https://c328740.ssl.cf1.rackcdn.com" |
|
497 | 498 | else: |
|
498 | 499 | host = u"http://cdn.mathjax.org" |
|
499 | 500 | |
|
500 | 501 | url = host + u"/mathjax/latest/MathJax.js" |
|
501 | 502 | self.log.info("Using MathJax from CDN: %s", url) |
|
502 | 503 | return url |
|
503 | 504 | |
|
504 | 505 | def _mathjax_url_changed(self, name, old, new): |
|
505 | 506 | if new and not self.enable_mathjax: |
|
506 | 507 | # enable_mathjax=False overrides mathjax_url |
|
507 | 508 | self.mathjax_url = u'' |
|
508 | 509 | else: |
|
509 | 510 | self.log.info("Using MathJax: %s", new) |
|
510 | 511 | |
|
511 | 512 | notebook_manager_class = DottedObjectName('IPython.html.services.notebooks.filenbmanager.FileNotebookManager', |
|
512 | 513 | config=True, |
|
513 | 514 | help='The notebook manager class to use.') |
|
514 | 515 | |
|
515 | 516 | trust_xheaders = Bool(False, config=True, |
|
516 | 517 | help=("Whether to trust or not X-Scheme/X-Forwarded-Proto and X-Real-Ip/X-Forwarded-For headers" |
|
517 | 518 | "sent by the upstream reverse proxy. Necessary if the proxy handles SSL") |
|
518 | 519 | ) |
|
519 | 520 | |
|
520 | 521 | info_file = Unicode() |
|
521 | 522 | |
|
522 | 523 | def _info_file_default(self): |
|
523 | 524 | info_file = "nbserver-%s.json"%os.getpid() |
|
524 | 525 | return os.path.join(self.profile_dir.security_dir, info_file) |
|
525 | 526 | |
|
526 | 527 | notebook_dir = Unicode(py3compat.getcwd(), config=True, |
|
527 | 528 | help="The directory to use for notebooks and kernels." |
|
528 | 529 | ) |
|
529 | 530 | |
|
530 | 531 | def _notebook_dir_changed(self, name, old, new): |
|
531 | 532 | """Do a bit of validation of the notebook dir.""" |
|
532 | 533 | if not os.path.isabs(new): |
|
533 | 534 | # If we receive a non-absolute path, make it absolute. |
|
534 | 535 | self.notebook_dir = os.path.abspath(new) |
|
535 | 536 | return |
|
536 | 537 | if not os.path.isdir(new): |
|
537 | 538 | raise TraitError("No such notebook dir: %r" % new) |
|
538 | 539 | |
|
539 | 540 | # setting App.notebook_dir implies setting notebook and kernel dirs as well |
|
540 | 541 | self.config.FileNotebookManager.notebook_dir = new |
|
541 | 542 | self.config.MappingKernelManager.root_dir = new |
|
542 | 543 | |
|
543 | 544 | |
|
544 | 545 | def parse_command_line(self, argv=None): |
|
545 | 546 | super(NotebookApp, self).parse_command_line(argv) |
|
546 | 547 | |
|
547 | 548 | if self.extra_args: |
|
548 | 549 | arg0 = self.extra_args[0] |
|
549 | 550 | f = os.path.abspath(arg0) |
|
550 | 551 | self.argv.remove(arg0) |
|
551 | 552 | if not os.path.exists(f): |
|
552 | 553 | self.log.critical("No such file or directory: %s", f) |
|
553 | 554 | self.exit(1) |
|
554 | 555 | |
|
555 | 556 | # Use config here, to ensure that it takes higher priority than |
|
556 | 557 | # anything that comes from the profile. |
|
558 | c = Config() | |
|
557 | 559 | if os.path.isdir(f): |
|
558 |
|
|
|
560 | c.NotebookApp.notebook_dir = f | |
|
559 | 561 | elif os.path.isfile(f): |
|
560 |
|
|
|
562 | c.NotebookApp.file_to_run = f | |
|
563 | self.update_config(c) | |
|
561 | 564 | |
|
562 | 565 | def init_kernel_argv(self): |
|
563 | 566 | """construct the kernel arguments""" |
|
564 | 567 | # Scrub frontend-specific flags |
|
565 | 568 | self.kernel_argv = swallow_argv(self.argv, notebook_aliases, notebook_flags) |
|
566 | 569 | if any(arg.startswith(u'--pylab') for arg in self.kernel_argv): |
|
567 | 570 | self.log.warn('\n '.join([ |
|
568 | 571 | "Starting all kernels in pylab mode is not recommended,", |
|
569 | 572 | "and will be disabled in a future release.", |
|
570 | 573 | "Please use the %matplotlib magic to enable matplotlib instead.", |
|
571 | 574 | "pylab implies many imports, which can have confusing side effects", |
|
572 | 575 | "and harm the reproducibility of your notebooks.", |
|
573 | 576 | ])) |
|
574 | 577 | # Kernel should inherit default config file from frontend |
|
575 | 578 | self.kernel_argv.append("--IPKernelApp.parent_appname='%s'" % self.name) |
|
576 | 579 | # Kernel should get *absolute* path to profile directory |
|
577 | 580 | self.kernel_argv.extend(["--profile-dir", self.profile_dir.location]) |
|
578 | 581 | |
|
579 | 582 | def init_configurables(self): |
|
580 | 583 | # force Session default to be secure |
|
581 | 584 | default_secure(self.config) |
|
582 | 585 | self.kernel_manager = MappingKernelManager( |
|
583 | 586 | parent=self, log=self.log, kernel_argv=self.kernel_argv, |
|
584 | 587 | connection_dir = self.profile_dir.security_dir, |
|
585 | 588 | ) |
|
586 | 589 | kls = import_item(self.notebook_manager_class) |
|
587 | 590 | self.notebook_manager = kls(parent=self, log=self.log) |
|
588 | 591 | self.session_manager = SessionManager(parent=self, log=self.log) |
|
589 | 592 | self.cluster_manager = ClusterManager(parent=self, log=self.log) |
|
590 | 593 | self.cluster_manager.update_profiles() |
|
591 | 594 | |
|
592 | 595 | def init_logging(self): |
|
593 | 596 | # This prevents double log messages because tornado use a root logger that |
|
594 | 597 | # self.log is a child of. The logging module dipatches log messages to a log |
|
595 | 598 | # and all of its ancenstors until propagate is set to False. |
|
596 | 599 | self.log.propagate = False |
|
597 | 600 | |
|
598 | 601 | # hook up tornado 3's loggers to our app handlers |
|
599 | 602 | for name in ('access', 'application', 'general'): |
|
600 | 603 | logger = logging.getLogger('tornado.%s' % name) |
|
601 | 604 | logger.parent = self.log |
|
602 | 605 | logger.setLevel(self.log.level) |
|
603 | 606 | |
|
604 | 607 | def init_webapp(self): |
|
605 | 608 | """initialize tornado webapp and httpserver""" |
|
606 | 609 | self.web_app = NotebookWebApplication( |
|
607 | 610 | self, self.kernel_manager, self.notebook_manager, |
|
608 | 611 | self.cluster_manager, self.session_manager, |
|
609 | 612 | self.log, self.base_url, self.webapp_settings, |
|
610 | 613 | self.jinja_environment_options |
|
611 | 614 | ) |
|
612 | 615 | if self.certfile: |
|
613 | 616 | ssl_options = dict(certfile=self.certfile) |
|
614 | 617 | if self.keyfile: |
|
615 | 618 | ssl_options['keyfile'] = self.keyfile |
|
616 | 619 | else: |
|
617 | 620 | ssl_options = None |
|
618 | 621 | self.web_app.password = self.password |
|
619 | 622 | self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options, |
|
620 | 623 | xheaders=self.trust_xheaders) |
|
621 | 624 | if not self.ip: |
|
622 | 625 | warning = "WARNING: The notebook server is listening on all IP addresses" |
|
623 | 626 | if ssl_options is None: |
|
624 | 627 | self.log.critical(warning + " and not using encryption. This " |
|
625 | 628 | "is not recommended.") |
|
626 | 629 | if not self.password: |
|
627 | 630 | self.log.critical(warning + " and not using authentication. " |
|
628 | 631 | "This is highly insecure and not recommended.") |
|
629 | 632 | success = None |
|
630 | 633 | for port in random_ports(self.port, self.port_retries+1): |
|
631 | 634 | try: |
|
632 | 635 | self.http_server.listen(port, self.ip) |
|
633 | 636 | except socket.error as e: |
|
634 | 637 | if e.errno == errno.EADDRINUSE: |
|
635 | 638 | self.log.info('The port %i is already in use, trying another random port.' % port) |
|
636 | 639 | continue |
|
637 | 640 | elif e.errno in (errno.EACCES, getattr(errno, 'WSAEACCES', errno.EACCES)): |
|
638 | 641 | self.log.warn("Permission to listen on port %i denied" % port) |
|
639 | 642 | continue |
|
640 | 643 | else: |
|
641 | 644 | raise |
|
642 | 645 | else: |
|
643 | 646 | self.port = port |
|
644 | 647 | success = True |
|
645 | 648 | break |
|
646 | 649 | if not success: |
|
647 | 650 | self.log.critical('ERROR: the notebook server could not be started because ' |
|
648 | 651 | 'no available port could be found.') |
|
649 | 652 | self.exit(1) |
|
650 | 653 | |
|
651 | 654 | @property |
|
652 | 655 | def display_url(self): |
|
653 | 656 | ip = self.ip if self.ip else '[all ip addresses on your system]' |
|
654 | 657 | return self._url(ip) |
|
655 | 658 | |
|
656 | 659 | @property |
|
657 | 660 | def connection_url(self): |
|
658 | 661 | ip = self.ip if self.ip else localhost() |
|
659 | 662 | return self._url(ip) |
|
660 | 663 | |
|
661 | 664 | def _url(self, ip): |
|
662 | 665 | proto = 'https' if self.certfile else 'http' |
|
663 | 666 | return "%s://%s:%i%s" % (proto, ip, self.port, self.base_url) |
|
664 | 667 | |
|
665 | 668 | def init_signal(self): |
|
666 | 669 | if not sys.platform.startswith('win'): |
|
667 | 670 | signal.signal(signal.SIGINT, self._handle_sigint) |
|
668 | 671 | signal.signal(signal.SIGTERM, self._signal_stop) |
|
669 | 672 | if hasattr(signal, 'SIGUSR1'): |
|
670 | 673 | # Windows doesn't support SIGUSR1 |
|
671 | 674 | signal.signal(signal.SIGUSR1, self._signal_info) |
|
672 | 675 | if hasattr(signal, 'SIGINFO'): |
|
673 | 676 | # only on BSD-based systems |
|
674 | 677 | signal.signal(signal.SIGINFO, self._signal_info) |
|
675 | 678 | |
|
676 | 679 | def _handle_sigint(self, sig, frame): |
|
677 | 680 | """SIGINT handler spawns confirmation dialog""" |
|
678 | 681 | # register more forceful signal handler for ^C^C case |
|
679 | 682 | signal.signal(signal.SIGINT, self._signal_stop) |
|
680 | 683 | # request confirmation dialog in bg thread, to avoid |
|
681 | 684 | # blocking the App |
|
682 | 685 | thread = threading.Thread(target=self._confirm_exit) |
|
683 | 686 | thread.daemon = True |
|
684 | 687 | thread.start() |
|
685 | 688 | |
|
686 | 689 | def _restore_sigint_handler(self): |
|
687 | 690 | """callback for restoring original SIGINT handler""" |
|
688 | 691 | signal.signal(signal.SIGINT, self._handle_sigint) |
|
689 | 692 | |
|
690 | 693 | def _confirm_exit(self): |
|
691 | 694 | """confirm shutdown on ^C |
|
692 | 695 | |
|
693 | 696 | A second ^C, or answering 'y' within 5s will cause shutdown, |
|
694 | 697 | otherwise original SIGINT handler will be restored. |
|
695 | 698 | |
|
696 | 699 | This doesn't work on Windows. |
|
697 | 700 | """ |
|
698 | 701 | # FIXME: remove this delay when pyzmq dependency is >= 2.1.11 |
|
699 | 702 | time.sleep(0.1) |
|
700 | 703 | info = self.log.info |
|
701 | 704 | info('interrupted') |
|
702 | 705 | print(self.notebook_info()) |
|
703 | 706 | sys.stdout.write("Shutdown this notebook server (y/[n])? ") |
|
704 | 707 | sys.stdout.flush() |
|
705 | 708 | r,w,x = select.select([sys.stdin], [], [], 5) |
|
706 | 709 | if r: |
|
707 | 710 | line = sys.stdin.readline() |
|
708 | 711 | if line.lower().startswith('y'): |
|
709 | 712 | self.log.critical("Shutdown confirmed") |
|
710 | 713 | ioloop.IOLoop.instance().stop() |
|
711 | 714 | return |
|
712 | 715 | else: |
|
713 | 716 | print("No answer for 5s:", end=' ') |
|
714 | 717 | print("resuming operation...") |
|
715 | 718 | # no answer, or answer is no: |
|
716 | 719 | # set it back to original SIGINT handler |
|
717 | 720 | # use IOLoop.add_callback because signal.signal must be called |
|
718 | 721 | # from main thread |
|
719 | 722 | ioloop.IOLoop.instance().add_callback(self._restore_sigint_handler) |
|
720 | 723 | |
|
721 | 724 | def _signal_stop(self, sig, frame): |
|
722 | 725 | self.log.critical("received signal %s, stopping", sig) |
|
723 | 726 | ioloop.IOLoop.instance().stop() |
|
724 | 727 | |
|
725 | 728 | def _signal_info(self, sig, frame): |
|
726 | 729 | print(self.notebook_info()) |
|
727 | 730 | |
|
728 | 731 | def init_components(self): |
|
729 | 732 | """Check the components submodule, and warn if it's unclean""" |
|
730 | 733 | status = submodule.check_submodule_status() |
|
731 | 734 | if status == 'missing': |
|
732 | 735 | self.log.warn("components submodule missing, running `git submodule update`") |
|
733 | 736 | submodule.update_submodules(submodule.ipython_parent()) |
|
734 | 737 | elif status == 'unclean': |
|
735 | 738 | self.log.warn("components submodule unclean, you may see 404s on static/components") |
|
736 | 739 | self.log.warn("run `setup.py submodule` or `git submodule update` to update") |
|
737 | 740 | |
|
738 | 741 | @catch_config_error |
|
739 | 742 | def initialize(self, argv=None): |
|
740 | 743 | super(NotebookApp, self).initialize(argv) |
|
741 | 744 | self.init_logging() |
|
742 | 745 | self.init_kernel_argv() |
|
743 | 746 | self.init_configurables() |
|
744 | 747 | self.init_components() |
|
745 | 748 | self.init_webapp() |
|
746 | 749 | self.init_signal() |
|
747 | 750 | |
|
748 | 751 | def cleanup_kernels(self): |
|
749 | 752 | """Shutdown all kernels. |
|
750 | 753 | |
|
751 | 754 | The kernels will shutdown themselves when this process no longer exists, |
|
752 | 755 | but explicit shutdown allows the KernelManagers to cleanup the connection files. |
|
753 | 756 | """ |
|
754 | 757 | self.log.info('Shutting down kernels') |
|
755 | 758 | self.kernel_manager.shutdown_all() |
|
756 | 759 | |
|
757 | 760 | def notebook_info(self): |
|
758 | 761 | "Return the current working directory and the server url information" |
|
759 | 762 | info = self.notebook_manager.info_string() + "\n" |
|
760 | 763 | info += "%d active kernels \n" % len(self.kernel_manager._kernels) |
|
761 | 764 | return info + "The IPython Notebook is running at: %s" % self.display_url |
|
762 | 765 | |
|
763 | 766 | def server_info(self): |
|
764 | 767 | """Return a JSONable dict of information about this server.""" |
|
765 | 768 | return {'url': self.connection_url, |
|
766 | 769 | 'hostname': self.ip if self.ip else 'localhost', |
|
767 | 770 | 'port': self.port, |
|
768 | 771 | 'secure': bool(self.certfile), |
|
769 | 772 | 'base_url': self.base_url, |
|
770 | 773 | 'notebook_dir': os.path.abspath(self.notebook_dir), |
|
771 | 774 | } |
|
772 | 775 | |
|
773 | 776 | def write_server_info_file(self): |
|
774 | 777 | """Write the result of server_info() to the JSON file info_file.""" |
|
775 | 778 | with open(self.info_file, 'w') as f: |
|
776 | 779 | json.dump(self.server_info(), f, indent=2) |
|
777 | 780 | |
|
778 | 781 | def remove_server_info_file(self): |
|
779 | 782 | """Remove the nbserver-<pid>.json file created for this server. |
|
780 | 783 | |
|
781 | 784 | Ignores the error raised when the file has already been removed. |
|
782 | 785 | """ |
|
783 | 786 | try: |
|
784 | 787 | os.unlink(self.info_file) |
|
785 | 788 | except OSError as e: |
|
786 | 789 | if e.errno != errno.ENOENT: |
|
787 | 790 | raise |
|
788 | 791 | |
|
789 | 792 | def start(self): |
|
790 | 793 | """ Start the IPython Notebook server app, after initialization |
|
791 | 794 | |
|
792 | 795 | This method takes no arguments so all configuration and initialization |
|
793 | 796 | must be done prior to calling this method.""" |
|
794 | 797 | if self.subapp is not None: |
|
795 | 798 | return self.subapp.start() |
|
796 | 799 | |
|
797 | 800 | info = self.log.info |
|
798 | 801 | for line in self.notebook_info().split("\n"): |
|
799 | 802 | info(line) |
|
800 | 803 | info("Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).") |
|
801 | 804 | |
|
802 | 805 | self.write_server_info_file() |
|
803 | 806 | |
|
804 | 807 | if self.open_browser or self.file_to_run: |
|
805 | 808 | try: |
|
806 | 809 | browser = webbrowser.get(self.browser or None) |
|
807 | 810 | except webbrowser.Error as e: |
|
808 | 811 | self.log.warn('No web browser found: %s.' % e) |
|
809 | 812 | browser = None |
|
810 | 813 | |
|
811 | 814 | if self.file_to_run: |
|
812 | 815 | fullpath = os.path.join(self.notebook_dir, self.file_to_run) |
|
813 | 816 | if not os.path.exists(fullpath): |
|
814 | 817 | self.log.critical("%s does not exist" % fullpath) |
|
815 | 818 | self.exit(1) |
|
816 | 819 | |
|
817 | 820 | uri = url_path_join('notebooks', self.file_to_run) |
|
818 | 821 | else: |
|
819 | 822 | uri = 'tree' |
|
820 | 823 | if browser: |
|
821 | 824 | b = lambda : browser.open(url_path_join(self.connection_url, uri), |
|
822 | 825 | new=2) |
|
823 | 826 | threading.Thread(target=b).start() |
|
824 | 827 | try: |
|
825 | 828 | ioloop.IOLoop.instance().start() |
|
826 | 829 | except KeyboardInterrupt: |
|
827 | 830 | info("Interrupted...") |
|
828 | 831 | finally: |
|
829 | 832 | self.cleanup_kernels() |
|
830 | 833 | self.remove_server_info_file() |
|
831 | 834 | |
|
832 | 835 | |
|
833 | 836 | def list_running_servers(profile='default'): |
|
834 | 837 | """Iterate over the server info files of running notebook servers. |
|
835 | 838 | |
|
836 | 839 | Given a profile name, find nbserver-* files in the security directory of |
|
837 | 840 | that profile, and yield dicts of their information, each one pertaining to |
|
838 | 841 | a currently running notebook server instance. |
|
839 | 842 | """ |
|
840 | 843 | pd = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), name=profile) |
|
841 | 844 | for file in os.listdir(pd.security_dir): |
|
842 | 845 | if file.startswith('nbserver-'): |
|
843 | 846 | with io.open(os.path.join(pd.security_dir, file), encoding='utf-8') as f: |
|
844 | 847 | yield json.load(f) |
|
845 | 848 | |
|
846 | 849 | #----------------------------------------------------------------------------- |
|
847 | 850 | # Main entry point |
|
848 | 851 | #----------------------------------------------------------------------------- |
|
849 | 852 | |
|
850 | 853 | launch_new_instance = NotebookApp.launch_instance |
|
851 | 854 |
@@ -1,269 +1,259 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 | // Keyboard management |
|
10 | 10 | //============================================================================ |
|
11 | 11 | |
|
12 | 12 | IPython.namespace('IPython.keyboard'); |
|
13 | 13 | |
|
14 | 14 | IPython.keyboard = (function (IPython) { |
|
15 | 15 | "use strict"; |
|
16 | 16 | |
|
17 | 17 | // Setup global keycodes and inverse keycodes. |
|
18 | 18 | |
|
19 | 19 | // See http://unixpapa.com/js/key.html for a complete description. The short of |
|
20 | 20 | // it is that there are different keycode sets. Firefox uses the "Mozilla keycodes" |
|
21 | 21 | // and Webkit/IE use the "IE keycodes". These keycode sets are mostly the same |
|
22 | 22 | // but have minor differences. |
|
23 | 23 | |
|
24 | 24 | // These apply to Firefox, (Webkit and IE) |
|
25 | 25 | var _keycodes = { |
|
26 | 26 | 'a': 65, 'b': 66, 'c': 67, 'd': 68, 'e': 69, 'f': 70, 'g': 71, 'h': 72, 'i': 73, |
|
27 | 27 | 'j': 74, 'k': 75, 'l': 76, 'm': 77, 'n': 78, 'o': 79, 'p': 80, 'q': 81, 'r': 82, |
|
28 | 28 | 's': 83, 't': 84, 'u': 85, 'v': 86, 'w': 87, 'x': 88, 'y': 89, 'z': 90, |
|
29 | 29 | '1 !': 49, '2 @': 50, '3 #': 51, '4 $': 52, '5 %': 53, '6 ^': 54, |
|
30 | 30 | '7 &': 55, '8 *': 56, '9 (': 57, '0 )': 48, |
|
31 | 31 | '[ {': 219, '] }': 221, '` ~': 192, ', <': 188, '. >': 190, '/ ?': 191, |
|
32 | 32 | '\\ |': 220, '\' "': 222, |
|
33 | 33 | 'numpad0': 96, 'numpad1': 97, 'numpad2': 98, 'numpad3': 99, 'numpad4': 100, |
|
34 | 34 | 'numpad5': 101, 'numpad6': 102, 'numpad7': 103, 'numpad8': 104, 'numpad9': 105, |
|
35 | 35 | 'multiply': 106, 'add': 107, 'subtract': 109, 'decimal': 110, 'divide': 111, |
|
36 | 36 | 'f1': 112, 'f2': 113, 'f3': 114, 'f4': 115, 'f5': 116, 'f6': 117, 'f7': 118, |
|
37 | 37 | 'f8': 119, 'f9': 120, 'f11': 122, 'f12': 123, 'f13': 124, 'f14': 125, 'f15': 126, |
|
38 | 38 | 'backspace': 8, 'tab': 9, 'enter': 13, 'shift': 16, 'ctrl': 17, 'alt': 18, |
|
39 | 39 | 'meta': 91, 'capslock': 20, 'esc': 27, 'space': 32, 'pageup': 33, 'pagedown': 34, |
|
40 | 40 | 'end': 35, 'home': 36, 'left': 37, 'up': 38, 'right': 39, 'down': 40, |
|
41 | 41 | 'insert': 45, 'delete': 46, 'numlock': 144, |
|
42 | 42 | }; |
|
43 | 43 | |
|
44 | 44 | // These apply to Firefox and Opera |
|
45 | 45 | var _mozilla_keycodes = { |
|
46 | 46 | '; :': 59, '= +': 61, '- _': 173, 'meta': 224 |
|
47 | 47 | }; |
|
48 | 48 | |
|
49 | 49 | // This apply to Webkit and IE |
|
50 | 50 | var _ie_keycodes = { |
|
51 | 51 | '; :': 186, '= +': 187, '- _': 189 |
|
52 | 52 | }; |
|
53 | 53 | |
|
54 | 54 | var browser = IPython.utils.browser[0]; |
|
55 | 55 | var platform = IPython.utils.platform; |
|
56 | 56 | |
|
57 | 57 | if (browser === 'Firefox' || browser === 'Opera' || browser === 'Netscape') { |
|
58 | 58 | $.extend(_keycodes, _mozilla_keycodes); |
|
59 | 59 | } else if (browser === 'Safari' || browser === 'Chrome' || browser === 'MSIE') { |
|
60 | 60 | $.extend(_keycodes, _ie_keycodes); |
|
61 | 61 | } |
|
62 | 62 | |
|
63 | 63 | var keycodes = {}; |
|
64 | 64 | var inv_keycodes = {}; |
|
65 | 65 | for (var name in _keycodes) { |
|
66 | 66 | var names = name.split(' '); |
|
67 | 67 | if (names.length === 1) { |
|
68 | 68 | var n = names[0]; |
|
69 | 69 | keycodes[n] = _keycodes[n]; |
|
70 | 70 | inv_keycodes[_keycodes[n]] = n; |
|
71 | 71 | } else { |
|
72 | 72 | var primary = names[0]; |
|
73 | 73 | var secondary = names[1]; |
|
74 | 74 | keycodes[primary] = _keycodes[name]; |
|
75 | 75 | keycodes[secondary] = _keycodes[name]; |
|
76 | 76 | inv_keycodes[_keycodes[name]] = primary; |
|
77 | 77 | } |
|
78 | 78 | } |
|
79 | 79 | |
|
80 | 80 | var normalize_key = function (key) { |
|
81 | 81 | return inv_keycodes[keycodes[key]]; |
|
82 | 82 | }; |
|
83 | 83 | |
|
84 | 84 | var normalize_shortcut = function (shortcut) { |
|
85 | 85 | // Put a shortcut into normalized form: |
|
86 | 86 | // 1. Make lowercase |
|
87 | 87 | // 2. Replace cmd by meta |
|
88 | 88 | // 3. Sort '-' separated modifiers into the order alt-ctrl-meta-shift |
|
89 | 89 | // 4. Normalize keys |
|
90 | 90 | shortcut = shortcut.toLowerCase().replace('cmd', 'meta'); |
|
91 | 91 | shortcut = shortcut.replace(/-$/, '_'); // catch shortcuts using '-' key |
|
92 | 92 | var values = shortcut.split("-"); |
|
93 | 93 | if (values.length === 1) { |
|
94 | 94 | return normalize_key(values[0]); |
|
95 | 95 | } else { |
|
96 | 96 | var modifiers = values.slice(0,-1); |
|
97 | 97 | var key = normalize_key(values[values.length-1]); |
|
98 | 98 | modifiers.sort(); |
|
99 | 99 | return modifiers.join('-') + '-' + key; |
|
100 | 100 | } |
|
101 | 101 | }; |
|
102 | 102 | |
|
103 | 103 | var shortcut_to_event = function (shortcut, type) { |
|
104 | 104 | // Convert a shortcut (shift-r) to a jQuery Event object |
|
105 | 105 | type = type || 'keydown'; |
|
106 | 106 | shortcut = normalize_shortcut(shortcut); |
|
107 | 107 | shortcut = shortcut.replace(/-$/, '_'); // catch shortcuts using '-' key |
|
108 | 108 | var values = shortcut.split("-"); |
|
109 | 109 | var modifiers = values.slice(0,-1); |
|
110 | 110 | var key = values[values.length-1]; |
|
111 | 111 | var opts = {which: keycodes[key]}; |
|
112 | 112 | if (modifiers.indexOf('alt') !== -1) {opts.altKey = true;} |
|
113 | 113 | if (modifiers.indexOf('ctrl') !== -1) {opts.ctrlKey = true;} |
|
114 | 114 | if (modifiers.indexOf('meta') !== -1) {opts.metaKey = true;} |
|
115 | 115 | if (modifiers.indexOf('shift') !== -1) {opts.shiftKey = true;} |
|
116 | 116 | return $.Event(type, opts); |
|
117 | 117 | }; |
|
118 | 118 | |
|
119 | 119 | var event_to_shortcut = function (event) { |
|
120 | 120 | // Convert a jQuery Event object to a shortcut (shift-r) |
|
121 | 121 | var shortcut = ''; |
|
122 | 122 | var key = inv_keycodes[event.which]; |
|
123 | 123 | if (event.altKey && key !== 'alt') {shortcut += 'alt-';} |
|
124 | 124 | if (event.ctrlKey && key !== 'ctrl') {shortcut += 'ctrl-';} |
|
125 | 125 | if (event.metaKey && key !== 'meta') {shortcut += 'meta-';} |
|
126 | 126 | if (event.shiftKey && key !== 'shift') {shortcut += 'shift-';} |
|
127 | 127 | shortcut += key; |
|
128 | 128 | return shortcut; |
|
129 | 129 | }; |
|
130 | 130 | |
|
131 | var trigger_keydown = function (shortcut, element) { | |
|
132 | // Trigger shortcut keydown on an element | |
|
133 | element = element || document; | |
|
134 | element = $(element); | |
|
135 | var event = shortcut_to_event(shortcut, 'keydown'); | |
|
136 | element.trigger(event); | |
|
137 | }; | |
|
138 | ||
|
139 | ||
|
140 | 131 | // Shortcut manager class |
|
141 | 132 | |
|
142 | 133 | var ShortcutManager = function (delay) { |
|
143 | 134 | this._shortcuts = {}; |
|
144 | 135 | this._counts = {}; |
|
145 | 136 | this._timers = {}; |
|
146 | 137 | this.delay = delay || 800; // delay in milliseconds |
|
147 | 138 | }; |
|
148 | 139 | |
|
149 | 140 | ShortcutManager.prototype.help = function () { |
|
150 | 141 | var help = []; |
|
151 | 142 | for (var shortcut in this._shortcuts) { |
|
152 | 143 | var help_string = this._shortcuts[shortcut]['help']; |
|
153 | 144 | var help_index = this._shortcuts[shortcut]['help_index']; |
|
154 | 145 | if (help_string) { |
|
155 | 146 | if (platform === 'MacOS') { |
|
156 | 147 | shortcut = shortcut.replace('meta', 'cmd'); |
|
157 | 148 | } |
|
158 | 149 | help.push({ |
|
159 | 150 | shortcut: shortcut, |
|
160 | 151 | help: help_string, |
|
161 | 152 | help_index: help_index} |
|
162 | 153 | ); |
|
163 | 154 | } |
|
164 | 155 | } |
|
165 | 156 | help.sort(function (a, b) { |
|
166 | 157 | if (a.help_index > b.help_index) |
|
167 | 158 | return 1; |
|
168 | 159 | if (a.help_index < b.help_index) |
|
169 | 160 | return -1; |
|
170 | 161 | return 0; |
|
171 | 162 | }); |
|
172 | 163 | return help; |
|
173 | 164 | }; |
|
174 | 165 | |
|
175 | 166 | ShortcutManager.prototype.clear_shortcuts = function () { |
|
176 | 167 | this._shortcuts = {}; |
|
177 | 168 | }; |
|
178 | 169 | |
|
179 | 170 | ShortcutManager.prototype.add_shortcut = function (shortcut, data, suppress_help_update) { |
|
180 | 171 | if (typeof(data) === 'function') { |
|
181 | 172 | data = {help: '', help_index: '', handler: data}; |
|
182 | 173 | } |
|
183 | 174 | data.help_index = data.help_index || ''; |
|
184 | 175 | data.help = data.help || ''; |
|
185 | 176 | data.count = data.count || 1; |
|
186 | 177 | if (data.help_index === '') { |
|
187 | 178 | data.help_index = 'zz'; |
|
188 | 179 | } |
|
189 | 180 | shortcut = normalize_shortcut(shortcut); |
|
190 | 181 | this._counts[shortcut] = 0; |
|
191 | 182 | this._shortcuts[shortcut] = data; |
|
192 | 183 | if (!suppress_help_update) { |
|
193 | 184 | // update the keyboard shortcuts notebook help |
|
194 | 185 | $([IPython.events]).trigger('rebuild.QuickHelp'); |
|
195 | 186 | } |
|
196 | 187 | }; |
|
197 | 188 | |
|
198 | 189 | ShortcutManager.prototype.add_shortcuts = function (data) { |
|
199 | 190 | for (var shortcut in data) { |
|
200 | 191 | this.add_shortcut(shortcut, data[shortcut], true); |
|
201 | 192 | } |
|
202 | 193 | // update the keyboard shortcuts notebook help |
|
203 | 194 | $([IPython.events]).trigger('rebuild.QuickHelp'); |
|
204 | 195 | }; |
|
205 | 196 | |
|
206 | 197 | ShortcutManager.prototype.remove_shortcut = function (shortcut, suppress_help_update) { |
|
207 | 198 | shortcut = normalize_shortcut(shortcut); |
|
208 | 199 | delete this._counts[shortcut]; |
|
209 | 200 | delete this._shortcuts[shortcut]; |
|
210 | 201 | if (!suppress_help_update) { |
|
211 | 202 | // update the keyboard shortcuts notebook help |
|
212 | 203 | $([IPython.events]).trigger('rebuild.QuickHelp'); |
|
213 | 204 | } |
|
214 | 205 | }; |
|
215 | 206 | |
|
216 | 207 | ShortcutManager.prototype.count_handler = function (shortcut, event, data) { |
|
217 | 208 | var that = this; |
|
218 | 209 | var c = this._counts; |
|
219 | 210 | var t = this._timers; |
|
220 | 211 | var timer = null; |
|
221 | 212 | if (c[shortcut] === data.count-1) { |
|
222 | 213 | c[shortcut] = 0; |
|
223 | 214 | var timer = t[shortcut]; |
|
224 | 215 | if (timer) {clearTimeout(timer); delete t[shortcut];} |
|
225 | 216 | return data.handler(event); |
|
226 | 217 | } else { |
|
227 | 218 | c[shortcut] = c[shortcut] + 1; |
|
228 | 219 | timer = setTimeout(function () { |
|
229 | 220 | c[shortcut] = 0; |
|
230 | 221 | }, that.delay); |
|
231 | 222 | t[shortcut] = timer; |
|
232 | 223 | } |
|
233 | 224 | return false; |
|
234 | 225 | }; |
|
235 | 226 | |
|
236 | 227 | ShortcutManager.prototype.call_handler = function (event) { |
|
237 | 228 | var shortcut = event_to_shortcut(event); |
|
238 | 229 | var data = this._shortcuts[shortcut]; |
|
239 | 230 | if (data) { |
|
240 | 231 | var handler = data['handler']; |
|
241 | 232 | if (handler) { |
|
242 | 233 | if (data.count === 1) { |
|
243 | 234 | return handler(event); |
|
244 | 235 | } else if (data.count > 1) { |
|
245 | 236 | return this.count_handler(shortcut, event, data); |
|
246 | 237 | } |
|
247 | 238 | } |
|
248 | 239 | } |
|
249 | 240 | return true; |
|
250 | 241 | }; |
|
251 | 242 | |
|
252 | 243 | ShortcutManager.prototype.handles = function (event) { |
|
253 | 244 | var shortcut = event_to_shortcut(event); |
|
254 | 245 | var data = this._shortcuts[shortcut]; |
|
255 | return !( data === undefined ) | |
|
246 | return !( data === undefined || data.handler === undefined ) | |
|
256 | 247 | } |
|
257 | 248 | |
|
258 | 249 | return { |
|
259 | 250 | keycodes : keycodes, |
|
260 | 251 | inv_keycodes : inv_keycodes, |
|
261 | 252 | ShortcutManager : ShortcutManager, |
|
262 | 253 | normalize_key : normalize_key, |
|
263 | 254 | normalize_shortcut : normalize_shortcut, |
|
264 | 255 | shortcut_to_event : shortcut_to_event, |
|
265 |
event_to_shortcut : event_to_shortcut |
|
|
266 | trigger_keydown : trigger_keydown | |
|
256 | event_to_shortcut : event_to_shortcut | |
|
267 | 257 | }; |
|
268 | 258 | |
|
269 | 259 | }(IPython)); |
@@ -1,2407 +1,2413 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 | 16 | |
|
17 | 17 | /** |
|
18 | 18 | * A notebook contains and manages cells. |
|
19 | 19 | * |
|
20 | 20 | * @class Notebook |
|
21 | 21 | * @constructor |
|
22 | 22 | * @param {String} selector A jQuery selector for the notebook's DOM element |
|
23 | 23 | * @param {Object} [options] A config object |
|
24 | 24 | */ |
|
25 | 25 | var Notebook = function (selector, options) { |
|
26 | 26 | this.options = options = options || {}; |
|
27 | 27 | this.base_url = options.base_url; |
|
28 | 28 | this.notebook_path = options.notebook_path; |
|
29 | 29 | this.notebook_name = options.notebook_name; |
|
30 | 30 | this.element = $(selector); |
|
31 | 31 | this.element.scroll(); |
|
32 | 32 | this.element.data("notebook", this); |
|
33 | 33 | this.next_prompt_number = 1; |
|
34 | 34 | this.session = null; |
|
35 | 35 | this.kernel = null; |
|
36 | 36 | this.clipboard = null; |
|
37 | 37 | this.undelete_backup = null; |
|
38 | 38 | this.undelete_index = null; |
|
39 | 39 | this.undelete_below = false; |
|
40 | 40 | this.paste_enabled = false; |
|
41 | 41 | // It is important to start out in command mode to match the intial mode |
|
42 | 42 | // of the KeyboardManager. |
|
43 | 43 | this.mode = 'command'; |
|
44 | 44 | this.set_dirty(false); |
|
45 | 45 | this.metadata = {}; |
|
46 | 46 | this._checkpoint_after_save = false; |
|
47 | 47 | this.last_checkpoint = null; |
|
48 | 48 | this.checkpoints = []; |
|
49 | 49 | this.autosave_interval = 0; |
|
50 | 50 | this.autosave_timer = null; |
|
51 | 51 | // autosave *at most* every two minutes |
|
52 | 52 | this.minimum_autosave_interval = 120000; |
|
53 | 53 | // single worksheet for now |
|
54 | 54 | this.worksheet_metadata = {}; |
|
55 | 55 | this.notebook_name_blacklist_re = /[\/\\:]/; |
|
56 | 56 | this.nbformat = 3; // Increment this when changing the nbformat |
|
57 | 57 | this.nbformat_minor = 0; // Increment this when changing the nbformat |
|
58 | 58 | this.style(); |
|
59 | 59 | this.create_elements(); |
|
60 | 60 | this.bind_events(); |
|
61 | this.save_notebook = function() { // don't allow save until notebook_loaded | |
|
62 | this.save_notebook_error(null, null, "Load failed, save is disabled"); | |
|
63 | }; | |
|
61 | 64 | }; |
|
62 | 65 | |
|
63 | 66 | /** |
|
64 | 67 | * Tweak the notebook's CSS style. |
|
65 | 68 | * |
|
66 | 69 | * @method style |
|
67 | 70 | */ |
|
68 | 71 | Notebook.prototype.style = function () { |
|
69 | 72 | $('div#notebook').addClass('border-box-sizing'); |
|
70 | 73 | }; |
|
71 | 74 | |
|
72 | 75 | /** |
|
73 | 76 | * Create an HTML and CSS representation of the notebook. |
|
74 | 77 | * |
|
75 | 78 | * @method create_elements |
|
76 | 79 | */ |
|
77 | 80 | Notebook.prototype.create_elements = function () { |
|
78 | 81 | var that = this; |
|
79 | 82 | this.element.attr('tabindex','-1'); |
|
80 | 83 | this.container = $("<div/>").addClass("container").attr("id", "notebook-container"); |
|
81 | 84 | // We add this end_space div to the end of the notebook div to: |
|
82 | 85 | // i) provide a margin between the last cell and the end of the notebook |
|
83 | 86 | // ii) to prevent the div from scrolling up when the last cell is being |
|
84 | 87 | // edited, but is too low on the page, which browsers will do automatically. |
|
85 | 88 | var end_space = $('<div/>').addClass('end_space'); |
|
86 | 89 | end_space.dblclick(function (e) { |
|
87 | 90 | var ncells = that.ncells(); |
|
88 | 91 | that.insert_cell_below('code',ncells-1); |
|
89 | 92 | }); |
|
90 | 93 | this.element.append(this.container); |
|
91 | 94 | this.container.append(end_space); |
|
92 | 95 | }; |
|
93 | 96 | |
|
94 | 97 | /** |
|
95 | 98 | * Bind JavaScript events: key presses and custom IPython events. |
|
96 | 99 | * |
|
97 | 100 | * @method bind_events |
|
98 | 101 | */ |
|
99 | 102 | Notebook.prototype.bind_events = function () { |
|
100 | 103 | var that = this; |
|
101 | 104 | |
|
102 | 105 | $([IPython.events]).on('set_next_input.Notebook', function (event, data) { |
|
103 | 106 | var index = that.find_cell_index(data.cell); |
|
104 | 107 | var new_cell = that.insert_cell_below('code',index); |
|
105 | 108 | new_cell.set_text(data.text); |
|
106 | 109 | that.dirty = true; |
|
107 | 110 | }); |
|
108 | 111 | |
|
109 | 112 | $([IPython.events]).on('set_dirty.Notebook', function (event, data) { |
|
110 | 113 | that.dirty = data.value; |
|
111 | 114 | }); |
|
112 | 115 | |
|
113 | 116 | $([IPython.events]).on('trust_changed.Notebook', function (event, data) { |
|
114 | 117 | that.trusted = data.value; |
|
115 | 118 | }); |
|
116 | 119 | |
|
117 | 120 | $([IPython.events]).on('select.Cell', function (event, data) { |
|
118 | 121 | var index = that.find_cell_index(data.cell); |
|
119 | 122 | that.select(index); |
|
120 | 123 | }); |
|
121 | 124 | |
|
122 | 125 | $([IPython.events]).on('edit_mode.Cell', function (event, data) { |
|
123 | 126 | that.handle_edit_mode(data.cell); |
|
124 | 127 | }); |
|
125 | 128 | |
|
126 | 129 | $([IPython.events]).on('command_mode.Cell', function (event, data) { |
|
127 | 130 | that.handle_command_mode(data.cell); |
|
128 | 131 | }); |
|
129 | 132 | |
|
130 | 133 | $([IPython.events]).on('status_autorestarting.Kernel', function () { |
|
131 | 134 | IPython.dialog.modal({ |
|
132 | 135 | title: "Kernel Restarting", |
|
133 | 136 | body: "The kernel appears to have died. It will restart automatically.", |
|
134 | 137 | buttons: { |
|
135 | 138 | OK : { |
|
136 | 139 | class : "btn-primary" |
|
137 | 140 | } |
|
138 | 141 | } |
|
139 | 142 | }); |
|
140 | 143 | }); |
|
141 | 144 | |
|
142 | 145 | var collapse_time = function (time) { |
|
143 | 146 | var app_height = $('#ipython-main-app').height(); // content height |
|
144 | 147 | var splitter_height = $('div#pager_splitter').outerHeight(true); |
|
145 | 148 | var new_height = app_height - splitter_height; |
|
146 | 149 | that.element.animate({height : new_height + 'px'}, time); |
|
147 | 150 | }; |
|
148 | 151 | |
|
149 | 152 | this.element.bind('collapse_pager', function (event, extrap) { |
|
150 | 153 | var time = (extrap !== undefined) ? ((extrap.duration !== undefined ) ? extrap.duration : 'fast') : 'fast'; |
|
151 | 154 | collapse_time(time); |
|
152 | 155 | }); |
|
153 | 156 | |
|
154 | 157 | var expand_time = function (time) { |
|
155 | 158 | var app_height = $('#ipython-main-app').height(); // content height |
|
156 | 159 | var splitter_height = $('div#pager_splitter').outerHeight(true); |
|
157 | 160 | var pager_height = $('div#pager').outerHeight(true); |
|
158 | 161 | var new_height = app_height - pager_height - splitter_height; |
|
159 | 162 | that.element.animate({height : new_height + 'px'}, time); |
|
160 | 163 | }; |
|
161 | 164 | |
|
162 | 165 | this.element.bind('expand_pager', function (event, extrap) { |
|
163 | 166 | var time = (extrap !== undefined) ? ((extrap.duration !== undefined ) ? extrap.duration : 'fast') : 'fast'; |
|
164 | 167 | expand_time(time); |
|
165 | 168 | }); |
|
166 | 169 | |
|
167 | 170 | // Firefox 22 broke $(window).on("beforeunload") |
|
168 | 171 | // I'm not sure why or how. |
|
169 | 172 | window.onbeforeunload = function (e) { |
|
170 | 173 | // TODO: Make killing the kernel configurable. |
|
171 | 174 | var kill_kernel = false; |
|
172 | 175 | if (kill_kernel) { |
|
173 | 176 | that.session.kill_kernel(); |
|
174 | 177 | } |
|
175 | 178 | // if we are autosaving, trigger an autosave on nav-away. |
|
176 | 179 | // still warn, because if we don't the autosave may fail. |
|
177 | 180 | if (that.dirty) { |
|
178 | 181 | if ( that.autosave_interval ) { |
|
179 | 182 | // schedule autosave in a timeout |
|
180 | 183 | // this gives you a chance to forcefully discard changes |
|
181 | 184 | // by reloading the page if you *really* want to. |
|
182 | 185 | // the timer doesn't start until you *dismiss* the dialog. |
|
183 | 186 | setTimeout(function () { |
|
184 | 187 | if (that.dirty) { |
|
185 | 188 | that.save_notebook(); |
|
186 | 189 | } |
|
187 | 190 | }, 1000); |
|
188 | 191 | return "Autosave in progress, latest changes may be lost."; |
|
189 | 192 | } else { |
|
190 | 193 | return "Unsaved changes will be lost."; |
|
191 | 194 | } |
|
192 | 195 | } |
|
193 | 196 | // Null is the *only* return value that will make the browser not |
|
194 | 197 | // pop up the "don't leave" dialog. |
|
195 | 198 | return null; |
|
196 | 199 | }; |
|
197 | 200 | }; |
|
198 | 201 | |
|
199 | 202 | /** |
|
200 | 203 | * Set the dirty flag, and trigger the set_dirty.Notebook event |
|
201 | 204 | * |
|
202 | 205 | * @method set_dirty |
|
203 | 206 | */ |
|
204 | 207 | Notebook.prototype.set_dirty = function (value) { |
|
205 | 208 | if (value === undefined) { |
|
206 | 209 | value = true; |
|
207 | 210 | } |
|
208 | 211 | if (this.dirty == value) { |
|
209 | 212 | return; |
|
210 | 213 | } |
|
211 | 214 | $([IPython.events]).trigger('set_dirty.Notebook', {value: value}); |
|
212 | 215 | }; |
|
213 | 216 | |
|
214 | 217 | /** |
|
215 | 218 | * Scroll the top of the page to a given cell. |
|
216 | 219 | * |
|
217 | 220 | * @method scroll_to_cell |
|
218 | 221 | * @param {Number} cell_number An index of the cell to view |
|
219 | 222 | * @param {Number} time Animation time in milliseconds |
|
220 | 223 | * @return {Number} Pixel offset from the top of the container |
|
221 | 224 | */ |
|
222 | 225 | Notebook.prototype.scroll_to_cell = function (cell_number, time) { |
|
223 | 226 | var cells = this.get_cells(); |
|
224 | 227 | time = time || 0; |
|
225 | 228 | cell_number = Math.min(cells.length-1,cell_number); |
|
226 | 229 | cell_number = Math.max(0 ,cell_number); |
|
227 | 230 | var scroll_value = cells[cell_number].element.position().top-cells[0].element.position().top ; |
|
228 | 231 | this.element.animate({scrollTop:scroll_value}, time); |
|
229 | 232 | return scroll_value; |
|
230 | 233 | }; |
|
231 | 234 | |
|
232 | 235 | /** |
|
233 | 236 | * Scroll to the bottom of the page. |
|
234 | 237 | * |
|
235 | 238 | * @method scroll_to_bottom |
|
236 | 239 | */ |
|
237 | 240 | Notebook.prototype.scroll_to_bottom = function () { |
|
238 | 241 | this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0); |
|
239 | 242 | }; |
|
240 | 243 | |
|
241 | 244 | /** |
|
242 | 245 | * Scroll to the top of the page. |
|
243 | 246 | * |
|
244 | 247 | * @method scroll_to_top |
|
245 | 248 | */ |
|
246 | 249 | Notebook.prototype.scroll_to_top = function () { |
|
247 | 250 | this.element.animate({scrollTop:0}, 0); |
|
248 | 251 | }; |
|
249 | 252 | |
|
250 | 253 | // Edit Notebook metadata |
|
251 | 254 | |
|
252 | 255 | Notebook.prototype.edit_metadata = function () { |
|
253 | 256 | var that = this; |
|
254 | 257 | IPython.dialog.edit_metadata(this.metadata, function (md) { |
|
255 | 258 | that.metadata = md; |
|
256 | 259 | }, 'Notebook'); |
|
257 | 260 | }; |
|
258 | 261 | |
|
259 | 262 | // Cell indexing, retrieval, etc. |
|
260 | 263 | |
|
261 | 264 | /** |
|
262 | 265 | * Get all cell elements in the notebook. |
|
263 | 266 | * |
|
264 | 267 | * @method get_cell_elements |
|
265 | 268 | * @return {jQuery} A selector of all cell elements |
|
266 | 269 | */ |
|
267 | 270 | Notebook.prototype.get_cell_elements = function () { |
|
268 | 271 | return this.container.children("div.cell"); |
|
269 | 272 | }; |
|
270 | 273 | |
|
271 | 274 | /** |
|
272 | 275 | * Get a particular cell element. |
|
273 | 276 | * |
|
274 | 277 | * @method get_cell_element |
|
275 | 278 | * @param {Number} index An index of a cell to select |
|
276 | 279 | * @return {jQuery} A selector of the given cell. |
|
277 | 280 | */ |
|
278 | 281 | Notebook.prototype.get_cell_element = function (index) { |
|
279 | 282 | var result = null; |
|
280 | 283 | var e = this.get_cell_elements().eq(index); |
|
281 | 284 | if (e.length !== 0) { |
|
282 | 285 | result = e; |
|
283 | 286 | } |
|
284 | 287 | return result; |
|
285 | 288 | }; |
|
286 | 289 | |
|
287 | 290 | /** |
|
288 | 291 | * Try to get a particular cell by msg_id. |
|
289 | 292 | * |
|
290 | 293 | * @method get_msg_cell |
|
291 | 294 | * @param {String} msg_id A message UUID |
|
292 | 295 | * @return {Cell} Cell or null if no cell was found. |
|
293 | 296 | */ |
|
294 | 297 | Notebook.prototype.get_msg_cell = function (msg_id) { |
|
295 | 298 | return IPython.CodeCell.msg_cells[msg_id] || null; |
|
296 | 299 | }; |
|
297 | 300 | |
|
298 | 301 | /** |
|
299 | 302 | * Count the cells in this notebook. |
|
300 | 303 | * |
|
301 | 304 | * @method ncells |
|
302 | 305 | * @return {Number} The number of cells in this notebook |
|
303 | 306 | */ |
|
304 | 307 | Notebook.prototype.ncells = function () { |
|
305 | 308 | return this.get_cell_elements().length; |
|
306 | 309 | }; |
|
307 | 310 | |
|
308 | 311 | /** |
|
309 | 312 | * Get all Cell objects in this notebook. |
|
310 | 313 | * |
|
311 | 314 | * @method get_cells |
|
312 | 315 | * @return {Array} This notebook's Cell objects |
|
313 | 316 | */ |
|
314 | 317 | // TODO: we are often calling cells as cells()[i], which we should optimize |
|
315 | 318 | // to cells(i) or a new method. |
|
316 | 319 | Notebook.prototype.get_cells = function () { |
|
317 | 320 | return this.get_cell_elements().toArray().map(function (e) { |
|
318 | 321 | return $(e).data("cell"); |
|
319 | 322 | }); |
|
320 | 323 | }; |
|
321 | 324 | |
|
322 | 325 | /** |
|
323 | 326 | * Get a Cell object from this notebook. |
|
324 | 327 | * |
|
325 | 328 | * @method get_cell |
|
326 | 329 | * @param {Number} index An index of a cell to retrieve |
|
327 | 330 | * @return {Cell} A particular cell |
|
328 | 331 | */ |
|
329 | 332 | Notebook.prototype.get_cell = function (index) { |
|
330 | 333 | var result = null; |
|
331 | 334 | var ce = this.get_cell_element(index); |
|
332 | 335 | if (ce !== null) { |
|
333 | 336 | result = ce.data('cell'); |
|
334 | 337 | } |
|
335 | 338 | return result; |
|
336 | 339 | }; |
|
337 | 340 | |
|
338 | 341 | /** |
|
339 | 342 | * Get the cell below a given cell. |
|
340 | 343 | * |
|
341 | 344 | * @method get_next_cell |
|
342 | 345 | * @param {Cell} cell The provided cell |
|
343 | 346 | * @return {Cell} The next cell |
|
344 | 347 | */ |
|
345 | 348 | Notebook.prototype.get_next_cell = function (cell) { |
|
346 | 349 | var result = null; |
|
347 | 350 | var index = this.find_cell_index(cell); |
|
348 | 351 | if (this.is_valid_cell_index(index+1)) { |
|
349 | 352 | result = this.get_cell(index+1); |
|
350 | 353 | } |
|
351 | 354 | return result; |
|
352 | 355 | }; |
|
353 | 356 | |
|
354 | 357 | /** |
|
355 | 358 | * Get the cell above a given cell. |
|
356 | 359 | * |
|
357 | 360 | * @method get_prev_cell |
|
358 | 361 | * @param {Cell} cell The provided cell |
|
359 | 362 | * @return {Cell} The previous cell |
|
360 | 363 | */ |
|
361 | 364 | Notebook.prototype.get_prev_cell = function (cell) { |
|
362 | 365 | // TODO: off-by-one |
|
363 | 366 | // nb.get_prev_cell(nb.get_cell(1)) is null |
|
364 | 367 | var result = null; |
|
365 | 368 | var index = this.find_cell_index(cell); |
|
366 | 369 | if (index !== null && index > 1) { |
|
367 | 370 | result = this.get_cell(index-1); |
|
368 | 371 | } |
|
369 | 372 | return result; |
|
370 | 373 | }; |
|
371 | 374 | |
|
372 | 375 | /** |
|
373 | 376 | * Get the numeric index of a given cell. |
|
374 | 377 | * |
|
375 | 378 | * @method find_cell_index |
|
376 | 379 | * @param {Cell} cell The provided cell |
|
377 | 380 | * @return {Number} The cell's numeric index |
|
378 | 381 | */ |
|
379 | 382 | Notebook.prototype.find_cell_index = function (cell) { |
|
380 | 383 | var result = null; |
|
381 | 384 | this.get_cell_elements().filter(function (index) { |
|
382 | 385 | if ($(this).data("cell") === cell) { |
|
383 | 386 | result = index; |
|
384 | 387 | } |
|
385 | 388 | }); |
|
386 | 389 | return result; |
|
387 | 390 | }; |
|
388 | 391 | |
|
389 | 392 | /** |
|
390 | 393 | * Get a given index , or the selected index if none is provided. |
|
391 | 394 | * |
|
392 | 395 | * @method index_or_selected |
|
393 | 396 | * @param {Number} index A cell's index |
|
394 | 397 | * @return {Number} The given index, or selected index if none is provided. |
|
395 | 398 | */ |
|
396 | 399 | Notebook.prototype.index_or_selected = function (index) { |
|
397 | 400 | var i; |
|
398 | 401 | if (index === undefined || index === null) { |
|
399 | 402 | i = this.get_selected_index(); |
|
400 | 403 | if (i === null) { |
|
401 | 404 | i = 0; |
|
402 | 405 | } |
|
403 | 406 | } else { |
|
404 | 407 | i = index; |
|
405 | 408 | } |
|
406 | 409 | return i; |
|
407 | 410 | }; |
|
408 | 411 | |
|
409 | 412 | /** |
|
410 | 413 | * Get the currently selected cell. |
|
411 | 414 | * @method get_selected_cell |
|
412 | 415 | * @return {Cell} The selected cell |
|
413 | 416 | */ |
|
414 | 417 | Notebook.prototype.get_selected_cell = function () { |
|
415 | 418 | var index = this.get_selected_index(); |
|
416 | 419 | return this.get_cell(index); |
|
417 | 420 | }; |
|
418 | 421 | |
|
419 | 422 | /** |
|
420 | 423 | * Check whether a cell index is valid. |
|
421 | 424 | * |
|
422 | 425 | * @method is_valid_cell_index |
|
423 | 426 | * @param {Number} index A cell index |
|
424 | 427 | * @return True if the index is valid, false otherwise |
|
425 | 428 | */ |
|
426 | 429 | Notebook.prototype.is_valid_cell_index = function (index) { |
|
427 | 430 | if (index !== null && index >= 0 && index < this.ncells()) { |
|
428 | 431 | return true; |
|
429 | 432 | } else { |
|
430 | 433 | return false; |
|
431 | 434 | } |
|
432 | 435 | }; |
|
433 | 436 | |
|
434 | 437 | /** |
|
435 | 438 | * Get the index of the currently selected cell. |
|
436 | 439 | |
|
437 | 440 | * @method get_selected_index |
|
438 | 441 | * @return {Number} The selected cell's numeric index |
|
439 | 442 | */ |
|
440 | 443 | Notebook.prototype.get_selected_index = function () { |
|
441 | 444 | var result = null; |
|
442 | 445 | this.get_cell_elements().filter(function (index) { |
|
443 | 446 | if ($(this).data("cell").selected === true) { |
|
444 | 447 | result = index; |
|
445 | 448 | } |
|
446 | 449 | }); |
|
447 | 450 | return result; |
|
448 | 451 | }; |
|
449 | 452 | |
|
450 | 453 | |
|
451 | 454 | // Cell selection. |
|
452 | 455 | |
|
453 | 456 | /** |
|
454 | 457 | * Programmatically select a cell. |
|
455 | 458 | * |
|
456 | 459 | * @method select |
|
457 | 460 | * @param {Number} index A cell's index |
|
458 | 461 | * @return {Notebook} This notebook |
|
459 | 462 | */ |
|
460 | 463 | Notebook.prototype.select = function (index) { |
|
461 | 464 | if (this.is_valid_cell_index(index)) { |
|
462 | 465 | var sindex = this.get_selected_index(); |
|
463 | 466 | if (sindex !== null && index !== sindex) { |
|
464 | 467 | // If we are about to select a different cell, make sure we are |
|
465 | 468 | // first in command mode. |
|
466 | 469 | if (this.mode !== 'command') { |
|
467 | 470 | this.command_mode(); |
|
468 | 471 | } |
|
469 | 472 | this.get_cell(sindex).unselect(); |
|
470 | 473 | } |
|
471 | 474 | var cell = this.get_cell(index); |
|
472 | 475 | cell.select(); |
|
473 | 476 | if (cell.cell_type === 'heading') { |
|
474 | 477 | $([IPython.events]).trigger('selected_cell_type_changed.Notebook', |
|
475 | 478 | {'cell_type':cell.cell_type,level:cell.level} |
|
476 | 479 | ); |
|
477 | 480 | } else { |
|
478 | 481 | $([IPython.events]).trigger('selected_cell_type_changed.Notebook', |
|
479 | 482 | {'cell_type':cell.cell_type} |
|
480 | 483 | ); |
|
481 | 484 | } |
|
482 | 485 | } |
|
483 | 486 | return this; |
|
484 | 487 | }; |
|
485 | 488 | |
|
486 | 489 | /** |
|
487 | 490 | * Programmatically select the next cell. |
|
488 | 491 | * |
|
489 | 492 | * @method select_next |
|
490 | 493 | * @return {Notebook} This notebook |
|
491 | 494 | */ |
|
492 | 495 | Notebook.prototype.select_next = function () { |
|
493 | 496 | var index = this.get_selected_index(); |
|
494 | 497 | this.select(index+1); |
|
495 | 498 | return this; |
|
496 | 499 | }; |
|
497 | 500 | |
|
498 | 501 | /** |
|
499 | 502 | * Programmatically select the previous cell. |
|
500 | 503 | * |
|
501 | 504 | * @method select_prev |
|
502 | 505 | * @return {Notebook} This notebook |
|
503 | 506 | */ |
|
504 | 507 | Notebook.prototype.select_prev = function () { |
|
505 | 508 | var index = this.get_selected_index(); |
|
506 | 509 | this.select(index-1); |
|
507 | 510 | return this; |
|
508 | 511 | }; |
|
509 | 512 | |
|
510 | 513 | |
|
511 | 514 | // Edit/Command mode |
|
512 | 515 | |
|
513 | 516 | /** |
|
514 | 517 | * Gets the index of the cell that is in edit mode. |
|
515 | 518 | * |
|
516 | 519 | * @method get_edit_index |
|
517 | 520 | * |
|
518 | 521 | * @return index {int} |
|
519 | 522 | **/ |
|
520 | 523 | Notebook.prototype.get_edit_index = function () { |
|
521 | 524 | var result = null; |
|
522 | 525 | this.get_cell_elements().filter(function (index) { |
|
523 | 526 | if ($(this).data("cell").mode === 'edit') { |
|
524 | 527 | result = index; |
|
525 | 528 | } |
|
526 | 529 | }); |
|
527 | 530 | return result; |
|
528 | 531 | }; |
|
529 | 532 | |
|
530 | 533 | /** |
|
531 | 534 | * Handle when a a cell blurs and the notebook should enter command mode. |
|
532 | 535 | * |
|
533 | 536 | * @method handle_command_mode |
|
534 | 537 | * @param [cell] {Cell} Cell to enter command mode on. |
|
535 | 538 | **/ |
|
536 | 539 | Notebook.prototype.handle_command_mode = function (cell) { |
|
537 | 540 | if (this.mode !== 'command') { |
|
538 | 541 | cell.command_mode(); |
|
539 | 542 | this.mode = 'command'; |
|
540 | 543 | $([IPython.events]).trigger('command_mode.Notebook'); |
|
541 | 544 | IPython.keyboard_manager.command_mode(); |
|
542 | 545 | } |
|
543 | 546 | }; |
|
544 | 547 | |
|
545 | 548 | /** |
|
546 | 549 | * Make the notebook enter command mode. |
|
547 | 550 | * |
|
548 | 551 | * @method command_mode |
|
549 | 552 | **/ |
|
550 | 553 | Notebook.prototype.command_mode = function () { |
|
551 | 554 | var cell = this.get_cell(this.get_edit_index()); |
|
552 | 555 | if (cell && this.mode !== 'command') { |
|
553 | 556 | // We don't call cell.command_mode, but rather call cell.focus_cell() |
|
554 | 557 | // which will blur and CM editor and trigger the call to |
|
555 | 558 | // handle_command_mode. |
|
556 | 559 | cell.focus_cell(); |
|
557 | 560 | } |
|
558 | 561 | }; |
|
559 | 562 | |
|
560 | 563 | /** |
|
561 | 564 | * Handle when a cell fires it's edit_mode event. |
|
562 | 565 | * |
|
563 | 566 | * @method handle_edit_mode |
|
564 | 567 | * @param [cell] {Cell} Cell to enter edit mode on. |
|
565 | 568 | **/ |
|
566 | 569 | Notebook.prototype.handle_edit_mode = function (cell) { |
|
567 | 570 | if (cell && this.mode !== 'edit') { |
|
568 | 571 | cell.edit_mode(); |
|
569 | 572 | this.mode = 'edit'; |
|
570 | 573 | $([IPython.events]).trigger('edit_mode.Notebook'); |
|
571 | 574 | IPython.keyboard_manager.edit_mode(); |
|
572 | 575 | } |
|
573 | 576 | }; |
|
574 | 577 | |
|
575 | 578 | /** |
|
576 | 579 | * Make a cell enter edit mode. |
|
577 | 580 | * |
|
578 | 581 | * @method edit_mode |
|
579 | 582 | **/ |
|
580 | 583 | Notebook.prototype.edit_mode = function () { |
|
581 | 584 | var cell = this.get_selected_cell(); |
|
582 | 585 | if (cell && this.mode !== 'edit') { |
|
583 | 586 | cell.unrender(); |
|
584 | 587 | cell.focus_editor(); |
|
585 | 588 | } |
|
586 | 589 | }; |
|
587 | 590 | |
|
588 | 591 | /** |
|
589 | 592 | * Focus the currently selected cell. |
|
590 | 593 | * |
|
591 | 594 | * @method focus_cell |
|
592 | 595 | **/ |
|
593 | 596 | Notebook.prototype.focus_cell = function () { |
|
594 | 597 | var cell = this.get_selected_cell(); |
|
595 | 598 | if (cell === null) {return;} // No cell is selected |
|
596 | 599 | cell.focus_cell(); |
|
597 | 600 | }; |
|
598 | 601 | |
|
599 | 602 | // Cell movement |
|
600 | 603 | |
|
601 | 604 | /** |
|
602 | 605 | * Move given (or selected) cell up and select it. |
|
603 | 606 | * |
|
604 | 607 | * @method move_cell_up |
|
605 | 608 | * @param [index] {integer} cell index |
|
606 | 609 | * @return {Notebook} This notebook |
|
607 | 610 | **/ |
|
608 | 611 | Notebook.prototype.move_cell_up = function (index) { |
|
609 | 612 | var i = this.index_or_selected(index); |
|
610 | 613 | if (this.is_valid_cell_index(i) && i > 0) { |
|
611 | 614 | var pivot = this.get_cell_element(i-1); |
|
612 | 615 | var tomove = this.get_cell_element(i); |
|
613 | 616 | if (pivot !== null && tomove !== null) { |
|
614 | 617 | tomove.detach(); |
|
615 | 618 | pivot.before(tomove); |
|
616 | 619 | this.select(i-1); |
|
617 | 620 | var cell = this.get_selected_cell(); |
|
618 | 621 | cell.focus_cell(); |
|
619 | 622 | } |
|
620 | 623 | this.set_dirty(true); |
|
621 | 624 | } |
|
622 | 625 | return this; |
|
623 | 626 | }; |
|
624 | 627 | |
|
625 | 628 | |
|
626 | 629 | /** |
|
627 | 630 | * Move given (or selected) cell down and select it |
|
628 | 631 | * |
|
629 | 632 | * @method move_cell_down |
|
630 | 633 | * @param [index] {integer} cell index |
|
631 | 634 | * @return {Notebook} This notebook |
|
632 | 635 | **/ |
|
633 | 636 | Notebook.prototype.move_cell_down = function (index) { |
|
634 | 637 | var i = this.index_or_selected(index); |
|
635 | 638 | if (this.is_valid_cell_index(i) && this.is_valid_cell_index(i+1)) { |
|
636 | 639 | var pivot = this.get_cell_element(i+1); |
|
637 | 640 | var tomove = this.get_cell_element(i); |
|
638 | 641 | if (pivot !== null && tomove !== null) { |
|
639 | 642 | tomove.detach(); |
|
640 | 643 | pivot.after(tomove); |
|
641 | 644 | this.select(i+1); |
|
642 | 645 | var cell = this.get_selected_cell(); |
|
643 | 646 | cell.focus_cell(); |
|
644 | 647 | } |
|
645 | 648 | } |
|
646 | 649 | this.set_dirty(); |
|
647 | 650 | return this; |
|
648 | 651 | }; |
|
649 | 652 | |
|
650 | 653 | |
|
651 | 654 | // Insertion, deletion. |
|
652 | 655 | |
|
653 | 656 | /** |
|
654 | 657 | * Delete a cell from the notebook. |
|
655 | 658 | * |
|
656 | 659 | * @method delete_cell |
|
657 | 660 | * @param [index] A cell's numeric index |
|
658 | 661 | * @return {Notebook} This notebook |
|
659 | 662 | */ |
|
660 | 663 | Notebook.prototype.delete_cell = function (index) { |
|
661 | 664 | var i = this.index_or_selected(index); |
|
662 | 665 | var cell = this.get_selected_cell(); |
|
663 | 666 | this.undelete_backup = cell.toJSON(); |
|
664 | 667 | $('#undelete_cell').removeClass('disabled'); |
|
665 | 668 | if (this.is_valid_cell_index(i)) { |
|
666 | 669 | var old_ncells = this.ncells(); |
|
667 | 670 | var ce = this.get_cell_element(i); |
|
668 | 671 | ce.remove(); |
|
669 | 672 | if (i === 0) { |
|
670 | 673 | // Always make sure we have at least one cell. |
|
671 | 674 | if (old_ncells === 1) { |
|
672 | 675 | this.insert_cell_below('code'); |
|
673 | 676 | } |
|
674 | 677 | this.select(0); |
|
675 | 678 | this.undelete_index = 0; |
|
676 | 679 | this.undelete_below = false; |
|
677 | 680 | } else if (i === old_ncells-1 && i !== 0) { |
|
678 | 681 | this.select(i-1); |
|
679 | 682 | this.undelete_index = i - 1; |
|
680 | 683 | this.undelete_below = true; |
|
681 | 684 | } else { |
|
682 | 685 | this.select(i); |
|
683 | 686 | this.undelete_index = i; |
|
684 | 687 | this.undelete_below = false; |
|
685 | 688 | } |
|
686 | 689 | $([IPython.events]).trigger('delete.Cell', {'cell': cell, 'index': i}); |
|
687 | 690 | this.set_dirty(true); |
|
688 | 691 | } |
|
689 | 692 | return this; |
|
690 | 693 | }; |
|
691 | 694 | |
|
692 | 695 | /** |
|
693 | 696 | * Restore the most recently deleted cell. |
|
694 | 697 | * |
|
695 | 698 | * @method undelete |
|
696 | 699 | */ |
|
697 | 700 | Notebook.prototype.undelete_cell = function() { |
|
698 | 701 | if (this.undelete_backup !== null && this.undelete_index !== null) { |
|
699 | 702 | var current_index = this.get_selected_index(); |
|
700 | 703 | if (this.undelete_index < current_index) { |
|
701 | 704 | current_index = current_index + 1; |
|
702 | 705 | } |
|
703 | 706 | if (this.undelete_index >= this.ncells()) { |
|
704 | 707 | this.select(this.ncells() - 1); |
|
705 | 708 | } |
|
706 | 709 | else { |
|
707 | 710 | this.select(this.undelete_index); |
|
708 | 711 | } |
|
709 | 712 | var cell_data = this.undelete_backup; |
|
710 | 713 | var new_cell = null; |
|
711 | 714 | if (this.undelete_below) { |
|
712 | 715 | new_cell = this.insert_cell_below(cell_data.cell_type); |
|
713 | 716 | } else { |
|
714 | 717 | new_cell = this.insert_cell_above(cell_data.cell_type); |
|
715 | 718 | } |
|
716 | 719 | new_cell.fromJSON(cell_data); |
|
717 | 720 | if (this.undelete_below) { |
|
718 | 721 | this.select(current_index+1); |
|
719 | 722 | } else { |
|
720 | 723 | this.select(current_index); |
|
721 | 724 | } |
|
722 | 725 | this.undelete_backup = null; |
|
723 | 726 | this.undelete_index = null; |
|
724 | 727 | } |
|
725 | 728 | $('#undelete_cell').addClass('disabled'); |
|
726 | 729 | }; |
|
727 | 730 | |
|
728 | 731 | /** |
|
729 | 732 | * Insert a cell so that after insertion the cell is at given index. |
|
730 | 733 | * |
|
731 | 734 | * Similar to insert_above, but index parameter is mandatory |
|
732 | 735 | * |
|
733 | 736 | * Index will be brought back into the accissible range [0,n] |
|
734 | 737 | * |
|
735 | 738 | * @method insert_cell_at_index |
|
736 | 739 | * @param type {string} in ['code','markdown','heading'] |
|
737 | 740 | * @param [index] {int} a valid index where to inser cell |
|
738 | 741 | * |
|
739 | 742 | * @return cell {cell|null} created cell or null |
|
740 | 743 | **/ |
|
741 | 744 | Notebook.prototype.insert_cell_at_index = function(type, index){ |
|
742 | 745 | |
|
743 | 746 | var ncells = this.ncells(); |
|
744 | 747 | index = Math.min(index,ncells); |
|
745 | 748 | index = Math.max(index,0); |
|
746 | 749 | var cell = null; |
|
747 | 750 | |
|
748 | 751 | if (ncells === 0 || this.is_valid_cell_index(index) || index === ncells) { |
|
749 | 752 | if (type === 'code') { |
|
750 | 753 | cell = new IPython.CodeCell(this.kernel); |
|
751 | 754 | cell.set_input_prompt(); |
|
752 | 755 | } else if (type === 'markdown') { |
|
753 | 756 | cell = new IPython.MarkdownCell(); |
|
754 | 757 | } else if (type === 'raw') { |
|
755 | 758 | cell = new IPython.RawCell(); |
|
756 | 759 | } else if (type === 'heading') { |
|
757 | 760 | cell = new IPython.HeadingCell(); |
|
758 | 761 | } |
|
759 | 762 | |
|
760 | 763 | if(this._insert_element_at_index(cell.element,index)) { |
|
761 | 764 | cell.render(); |
|
762 | 765 | $([IPython.events]).trigger('create.Cell', {'cell': cell, 'index': index}); |
|
763 | 766 | cell.refresh(); |
|
764 | 767 | // We used to select the cell after we refresh it, but there |
|
765 | 768 | // are now cases were this method is called where select is |
|
766 | 769 | // not appropriate. The selection logic should be handled by the |
|
767 | 770 | // caller of the the top level insert_cell methods. |
|
768 | 771 | this.set_dirty(true); |
|
769 | 772 | } |
|
770 | 773 | } |
|
771 | 774 | return cell; |
|
772 | 775 | |
|
773 | 776 | }; |
|
774 | 777 | |
|
775 | 778 | /** |
|
776 | 779 | * Insert an element at given cell index. |
|
777 | 780 | * |
|
778 | 781 | * @method _insert_element_at_index |
|
779 | 782 | * @param element {dom element} a cell element |
|
780 | 783 | * @param [index] {int} a valid index where to inser cell |
|
781 | 784 | * @private |
|
782 | 785 | * |
|
783 | 786 | * return true if everything whent fine. |
|
784 | 787 | **/ |
|
785 | 788 | Notebook.prototype._insert_element_at_index = function(element, index){ |
|
786 | 789 | if (element === undefined){ |
|
787 | 790 | return false; |
|
788 | 791 | } |
|
789 | 792 | |
|
790 | 793 | var ncells = this.ncells(); |
|
791 | 794 | |
|
792 | 795 | if (ncells === 0) { |
|
793 | 796 | // special case append if empty |
|
794 | 797 | this.element.find('div.end_space').before(element); |
|
795 | 798 | } else if ( ncells === index ) { |
|
796 | 799 | // special case append it the end, but not empty |
|
797 | 800 | this.get_cell_element(index-1).after(element); |
|
798 | 801 | } else if (this.is_valid_cell_index(index)) { |
|
799 | 802 | // otherwise always somewhere to append to |
|
800 | 803 | this.get_cell_element(index).before(element); |
|
801 | 804 | } else { |
|
802 | 805 | return false; |
|
803 | 806 | } |
|
804 | 807 | |
|
805 | 808 | if (this.undelete_index !== null && index <= this.undelete_index) { |
|
806 | 809 | this.undelete_index = this.undelete_index + 1; |
|
807 | 810 | this.set_dirty(true); |
|
808 | 811 | } |
|
809 | 812 | return true; |
|
810 | 813 | }; |
|
811 | 814 | |
|
812 | 815 | /** |
|
813 | 816 | * Insert a cell of given type above given index, or at top |
|
814 | 817 | * of notebook if index smaller than 0. |
|
815 | 818 | * |
|
816 | 819 | * default index value is the one of currently selected cell |
|
817 | 820 | * |
|
818 | 821 | * @method insert_cell_above |
|
819 | 822 | * @param type {string} cell type |
|
820 | 823 | * @param [index] {integer} |
|
821 | 824 | * |
|
822 | 825 | * @return handle to created cell or null |
|
823 | 826 | **/ |
|
824 | 827 | Notebook.prototype.insert_cell_above = function (type, index) { |
|
825 | 828 | index = this.index_or_selected(index); |
|
826 | 829 | return this.insert_cell_at_index(type, index); |
|
827 | 830 | }; |
|
828 | 831 | |
|
829 | 832 | /** |
|
830 | 833 | * Insert a cell of given type below given index, or at bottom |
|
831 | 834 | * of notebook if index greater thatn number of cell |
|
832 | 835 | * |
|
833 | 836 | * default index value is the one of currently selected cell |
|
834 | 837 | * |
|
835 | 838 | * @method insert_cell_below |
|
836 | 839 | * @param type {string} cell type |
|
837 | 840 | * @param [index] {integer} |
|
838 | 841 | * |
|
839 | 842 | * @return handle to created cell or null |
|
840 | 843 | * |
|
841 | 844 | **/ |
|
842 | 845 | Notebook.prototype.insert_cell_below = function (type, index) { |
|
843 | 846 | index = this.index_or_selected(index); |
|
844 | 847 | return this.insert_cell_at_index(type, index+1); |
|
845 | 848 | }; |
|
846 | 849 | |
|
847 | 850 | |
|
848 | 851 | /** |
|
849 | 852 | * Insert cell at end of notebook |
|
850 | 853 | * |
|
851 | 854 | * @method insert_cell_at_bottom |
|
852 | 855 | * @param {String} type cell type |
|
853 | 856 | * |
|
854 | 857 | * @return the added cell; or null |
|
855 | 858 | **/ |
|
856 | 859 | Notebook.prototype.insert_cell_at_bottom = function (type){ |
|
857 | 860 | var len = this.ncells(); |
|
858 | 861 | return this.insert_cell_below(type,len-1); |
|
859 | 862 | }; |
|
860 | 863 | |
|
861 | 864 | /** |
|
862 | 865 | * Turn a cell into a code cell. |
|
863 | 866 | * |
|
864 | 867 | * @method to_code |
|
865 | 868 | * @param {Number} [index] A cell's index |
|
866 | 869 | */ |
|
867 | 870 | Notebook.prototype.to_code = function (index) { |
|
868 | 871 | var i = this.index_or_selected(index); |
|
869 | 872 | if (this.is_valid_cell_index(i)) { |
|
870 | 873 | var source_element = this.get_cell_element(i); |
|
871 | 874 | var source_cell = source_element.data("cell"); |
|
872 | 875 | if (!(source_cell instanceof IPython.CodeCell)) { |
|
873 | 876 | var target_cell = this.insert_cell_below('code',i); |
|
874 | 877 | var text = source_cell.get_text(); |
|
875 | 878 | if (text === source_cell.placeholder) { |
|
876 | 879 | text = ''; |
|
877 | 880 | } |
|
878 | 881 | target_cell.set_text(text); |
|
879 | 882 | // make this value the starting point, so that we can only undo |
|
880 | 883 | // to this state, instead of a blank cell |
|
881 | 884 | target_cell.code_mirror.clearHistory(); |
|
882 | 885 | source_element.remove(); |
|
883 | 886 | this.select(i); |
|
884 | 887 | this.set_dirty(true); |
|
885 | 888 | } |
|
886 | 889 | } |
|
887 | 890 | }; |
|
888 | 891 | |
|
889 | 892 | /** |
|
890 | 893 | * Turn a cell into a Markdown cell. |
|
891 | 894 | * |
|
892 | 895 | * @method to_markdown |
|
893 | 896 | * @param {Number} [index] A cell's index |
|
894 | 897 | */ |
|
895 | 898 | Notebook.prototype.to_markdown = function (index) { |
|
896 | 899 | var i = this.index_or_selected(index); |
|
897 | 900 | if (this.is_valid_cell_index(i)) { |
|
898 | 901 | var source_element = this.get_cell_element(i); |
|
899 | 902 | var source_cell = source_element.data("cell"); |
|
900 | 903 | if (!(source_cell instanceof IPython.MarkdownCell)) { |
|
901 | 904 | var target_cell = this.insert_cell_below('markdown',i); |
|
902 | 905 | var text = source_cell.get_text(); |
|
903 | 906 | if (text === source_cell.placeholder) { |
|
904 | 907 | text = ''; |
|
905 | 908 | } |
|
906 | 909 | // We must show the editor before setting its contents |
|
907 | 910 | target_cell.unrender(); |
|
908 | 911 | target_cell.set_text(text); |
|
909 | 912 | // make this value the starting point, so that we can only undo |
|
910 | 913 | // to this state, instead of a blank cell |
|
911 | 914 | target_cell.code_mirror.clearHistory(); |
|
912 | 915 | source_element.remove(); |
|
913 | 916 | this.select(i); |
|
914 | 917 | if ((source_cell instanceof IPython.TextCell) && source_cell.rendered) { |
|
915 | 918 | target_cell.render(); |
|
916 | 919 | } |
|
917 | 920 | this.set_dirty(true); |
|
918 | 921 | } |
|
919 | 922 | } |
|
920 | 923 | }; |
|
921 | 924 | |
|
922 | 925 | /** |
|
923 | 926 | * Turn a cell into a raw text cell. |
|
924 | 927 | * |
|
925 | 928 | * @method to_raw |
|
926 | 929 | * @param {Number} [index] A cell's index |
|
927 | 930 | */ |
|
928 | 931 | Notebook.prototype.to_raw = function (index) { |
|
929 | 932 | var i = this.index_or_selected(index); |
|
930 | 933 | if (this.is_valid_cell_index(i)) { |
|
931 | 934 | var source_element = this.get_cell_element(i); |
|
932 | 935 | var source_cell = source_element.data("cell"); |
|
933 | 936 | var target_cell = null; |
|
934 | 937 | if (!(source_cell instanceof IPython.RawCell)) { |
|
935 | 938 | target_cell = this.insert_cell_below('raw',i); |
|
936 | 939 | var text = source_cell.get_text(); |
|
937 | 940 | if (text === source_cell.placeholder) { |
|
938 | 941 | text = ''; |
|
939 | 942 | } |
|
940 | 943 | // We must show the editor before setting its contents |
|
941 | 944 | target_cell.unrender(); |
|
942 | 945 | target_cell.set_text(text); |
|
943 | 946 | // make this value the starting point, so that we can only undo |
|
944 | 947 | // to this state, instead of a blank cell |
|
945 | 948 | target_cell.code_mirror.clearHistory(); |
|
946 | 949 | source_element.remove(); |
|
947 | 950 | this.select(i); |
|
948 | 951 | this.set_dirty(true); |
|
949 | 952 | } |
|
950 | 953 | } |
|
951 | 954 | }; |
|
952 | 955 | |
|
953 | 956 | /** |
|
954 | 957 | * Turn a cell into a heading cell. |
|
955 | 958 | * |
|
956 | 959 | * @method to_heading |
|
957 | 960 | * @param {Number} [index] A cell's index |
|
958 | 961 | * @param {Number} [level] A heading level (e.g., 1 becomes <h1>) |
|
959 | 962 | */ |
|
960 | 963 | Notebook.prototype.to_heading = function (index, level) { |
|
961 | 964 | level = level || 1; |
|
962 | 965 | var i = this.index_or_selected(index); |
|
963 | 966 | if (this.is_valid_cell_index(i)) { |
|
964 | 967 | var source_element = this.get_cell_element(i); |
|
965 | 968 | var source_cell = source_element.data("cell"); |
|
966 | 969 | var target_cell = null; |
|
967 | 970 | if (source_cell instanceof IPython.HeadingCell) { |
|
968 | 971 | source_cell.set_level(level); |
|
969 | 972 | } else { |
|
970 | 973 | target_cell = this.insert_cell_below('heading',i); |
|
971 | 974 | var text = source_cell.get_text(); |
|
972 | 975 | if (text === source_cell.placeholder) { |
|
973 | 976 | text = ''; |
|
974 | 977 | } |
|
975 | 978 | // We must show the editor before setting its contents |
|
976 | 979 | target_cell.set_level(level); |
|
977 | 980 | target_cell.unrender(); |
|
978 | 981 | target_cell.set_text(text); |
|
979 | 982 | // make this value the starting point, so that we can only undo |
|
980 | 983 | // to this state, instead of a blank cell |
|
981 | 984 | target_cell.code_mirror.clearHistory(); |
|
982 | 985 | source_element.remove(); |
|
983 | 986 | this.select(i); |
|
984 | 987 | if ((source_cell instanceof IPython.TextCell) && source_cell.rendered) { |
|
985 | 988 | target_cell.render(); |
|
986 | 989 | } |
|
987 | 990 | } |
|
988 | 991 | this.set_dirty(true); |
|
989 | 992 | $([IPython.events]).trigger('selected_cell_type_changed.Notebook', |
|
990 | 993 | {'cell_type':'heading',level:level} |
|
991 | 994 | ); |
|
992 | 995 | } |
|
993 | 996 | }; |
|
994 | 997 | |
|
995 | 998 | |
|
996 | 999 | // Cut/Copy/Paste |
|
997 | 1000 | |
|
998 | 1001 | /** |
|
999 | 1002 | * Enable UI elements for pasting cells. |
|
1000 | 1003 | * |
|
1001 | 1004 | * @method enable_paste |
|
1002 | 1005 | */ |
|
1003 | 1006 | Notebook.prototype.enable_paste = function () { |
|
1004 | 1007 | var that = this; |
|
1005 | 1008 | if (!this.paste_enabled) { |
|
1006 | 1009 | $('#paste_cell_replace').removeClass('disabled') |
|
1007 | 1010 | .on('click', function () {that.paste_cell_replace();}); |
|
1008 | 1011 | $('#paste_cell_above').removeClass('disabled') |
|
1009 | 1012 | .on('click', function () {that.paste_cell_above();}); |
|
1010 | 1013 | $('#paste_cell_below').removeClass('disabled') |
|
1011 | 1014 | .on('click', function () {that.paste_cell_below();}); |
|
1012 | 1015 | this.paste_enabled = true; |
|
1013 | 1016 | } |
|
1014 | 1017 | }; |
|
1015 | 1018 | |
|
1016 | 1019 | /** |
|
1017 | 1020 | * Disable UI elements for pasting cells. |
|
1018 | 1021 | * |
|
1019 | 1022 | * @method disable_paste |
|
1020 | 1023 | */ |
|
1021 | 1024 | Notebook.prototype.disable_paste = function () { |
|
1022 | 1025 | if (this.paste_enabled) { |
|
1023 | 1026 | $('#paste_cell_replace').addClass('disabled').off('click'); |
|
1024 | 1027 | $('#paste_cell_above').addClass('disabled').off('click'); |
|
1025 | 1028 | $('#paste_cell_below').addClass('disabled').off('click'); |
|
1026 | 1029 | this.paste_enabled = false; |
|
1027 | 1030 | } |
|
1028 | 1031 | }; |
|
1029 | 1032 | |
|
1030 | 1033 | /** |
|
1031 | 1034 | * Cut a cell. |
|
1032 | 1035 | * |
|
1033 | 1036 | * @method cut_cell |
|
1034 | 1037 | */ |
|
1035 | 1038 | Notebook.prototype.cut_cell = function () { |
|
1036 | 1039 | this.copy_cell(); |
|
1037 | 1040 | this.delete_cell(); |
|
1038 | 1041 | }; |
|
1039 | 1042 | |
|
1040 | 1043 | /** |
|
1041 | 1044 | * Copy a cell. |
|
1042 | 1045 | * |
|
1043 | 1046 | * @method copy_cell |
|
1044 | 1047 | */ |
|
1045 | 1048 | Notebook.prototype.copy_cell = function () { |
|
1046 | 1049 | var cell = this.get_selected_cell(); |
|
1047 | 1050 | this.clipboard = cell.toJSON(); |
|
1048 | 1051 | this.enable_paste(); |
|
1049 | 1052 | }; |
|
1050 | 1053 | |
|
1051 | 1054 | /** |
|
1052 | 1055 | * Replace the selected cell with a cell in the clipboard. |
|
1053 | 1056 | * |
|
1054 | 1057 | * @method paste_cell_replace |
|
1055 | 1058 | */ |
|
1056 | 1059 | Notebook.prototype.paste_cell_replace = function () { |
|
1057 | 1060 | if (this.clipboard !== null && this.paste_enabled) { |
|
1058 | 1061 | var cell_data = this.clipboard; |
|
1059 | 1062 | var new_cell = this.insert_cell_above(cell_data.cell_type); |
|
1060 | 1063 | new_cell.fromJSON(cell_data); |
|
1061 | 1064 | var old_cell = this.get_next_cell(new_cell); |
|
1062 | 1065 | this.delete_cell(this.find_cell_index(old_cell)); |
|
1063 | 1066 | this.select(this.find_cell_index(new_cell)); |
|
1064 | 1067 | } |
|
1065 | 1068 | }; |
|
1066 | 1069 | |
|
1067 | 1070 | /** |
|
1068 | 1071 | * Paste a cell from the clipboard above the selected cell. |
|
1069 | 1072 | * |
|
1070 | 1073 | * @method paste_cell_above |
|
1071 | 1074 | */ |
|
1072 | 1075 | Notebook.prototype.paste_cell_above = function () { |
|
1073 | 1076 | if (this.clipboard !== null && this.paste_enabled) { |
|
1074 | 1077 | var cell_data = this.clipboard; |
|
1075 | 1078 | var new_cell = this.insert_cell_above(cell_data.cell_type); |
|
1076 | 1079 | new_cell.fromJSON(cell_data); |
|
1077 | 1080 | new_cell.focus_cell(); |
|
1078 | 1081 | } |
|
1079 | 1082 | }; |
|
1080 | 1083 | |
|
1081 | 1084 | /** |
|
1082 | 1085 | * Paste a cell from the clipboard below the selected cell. |
|
1083 | 1086 | * |
|
1084 | 1087 | * @method paste_cell_below |
|
1085 | 1088 | */ |
|
1086 | 1089 | Notebook.prototype.paste_cell_below = function () { |
|
1087 | 1090 | if (this.clipboard !== null && this.paste_enabled) { |
|
1088 | 1091 | var cell_data = this.clipboard; |
|
1089 | 1092 | var new_cell = this.insert_cell_below(cell_data.cell_type); |
|
1090 | 1093 | new_cell.fromJSON(cell_data); |
|
1091 | 1094 | new_cell.focus_cell(); |
|
1092 | 1095 | } |
|
1093 | 1096 | }; |
|
1094 | 1097 | |
|
1095 | 1098 | // Split/merge |
|
1096 | 1099 | |
|
1097 | 1100 | /** |
|
1098 | 1101 | * Split the selected cell into two, at the cursor. |
|
1099 | 1102 | * |
|
1100 | 1103 | * @method split_cell |
|
1101 | 1104 | */ |
|
1102 | 1105 | Notebook.prototype.split_cell = function () { |
|
1103 | 1106 | var mdc = IPython.MarkdownCell; |
|
1104 | 1107 | var rc = IPython.RawCell; |
|
1105 | 1108 | var cell = this.get_selected_cell(); |
|
1106 | 1109 | if (cell.is_splittable()) { |
|
1107 | 1110 | var texta = cell.get_pre_cursor(); |
|
1108 | 1111 | var textb = cell.get_post_cursor(); |
|
1109 | 1112 | if (cell instanceof IPython.CodeCell) { |
|
1110 | 1113 | // In this case the operations keep the notebook in its existing mode |
|
1111 | 1114 | // so we don't need to do any post-op mode changes. |
|
1112 | 1115 | cell.set_text(textb); |
|
1113 | 1116 | var new_cell = this.insert_cell_above('code'); |
|
1114 | 1117 | new_cell.set_text(texta); |
|
1115 | 1118 | } else if ((cell instanceof mdc && !cell.rendered) || (cell instanceof rc)) { |
|
1116 | 1119 | // We know cell is !rendered so we can use set_text. |
|
1117 | 1120 | cell.set_text(textb); |
|
1118 | 1121 | var new_cell = this.insert_cell_above(cell.cell_type); |
|
1119 | 1122 | // Unrender the new cell so we can call set_text. |
|
1120 | 1123 | new_cell.unrender(); |
|
1121 | 1124 | new_cell.set_text(texta); |
|
1122 | 1125 | } |
|
1123 | 1126 | } |
|
1124 | 1127 | }; |
|
1125 | 1128 | |
|
1126 | 1129 | /** |
|
1127 | 1130 | * Combine the selected cell into the cell above it. |
|
1128 | 1131 | * |
|
1129 | 1132 | * @method merge_cell_above |
|
1130 | 1133 | */ |
|
1131 | 1134 | Notebook.prototype.merge_cell_above = function () { |
|
1132 | 1135 | var mdc = IPython.MarkdownCell; |
|
1133 | 1136 | var rc = IPython.RawCell; |
|
1134 | 1137 | var index = this.get_selected_index(); |
|
1135 | 1138 | var cell = this.get_cell(index); |
|
1136 | 1139 | var render = cell.rendered; |
|
1137 | 1140 | if (!cell.is_mergeable()) { |
|
1138 | 1141 | return; |
|
1139 | 1142 | } |
|
1140 | 1143 | if (index > 0) { |
|
1141 | 1144 | var upper_cell = this.get_cell(index-1); |
|
1142 | 1145 | if (!upper_cell.is_mergeable()) { |
|
1143 | 1146 | return; |
|
1144 | 1147 | } |
|
1145 | 1148 | var upper_text = upper_cell.get_text(); |
|
1146 | 1149 | var text = cell.get_text(); |
|
1147 | 1150 | if (cell instanceof IPython.CodeCell) { |
|
1148 | 1151 | cell.set_text(upper_text+'\n'+text); |
|
1149 | 1152 | } else if ((cell instanceof mdc) || (cell instanceof rc)) { |
|
1150 | 1153 | cell.unrender(); // Must unrender before we set_text. |
|
1151 | 1154 | cell.set_text(upper_text+'\n\n'+text); |
|
1152 | 1155 | if (render) { |
|
1153 | 1156 | // The rendered state of the final cell should match |
|
1154 | 1157 | // that of the original selected cell; |
|
1155 | 1158 | cell.render(); |
|
1156 | 1159 | } |
|
1157 | 1160 | } |
|
1158 | 1161 | this.delete_cell(index-1); |
|
1159 | 1162 | this.select(this.find_cell_index(cell)); |
|
1160 | 1163 | } |
|
1161 | 1164 | }; |
|
1162 | 1165 | |
|
1163 | 1166 | /** |
|
1164 | 1167 | * Combine the selected cell into the cell below it. |
|
1165 | 1168 | * |
|
1166 | 1169 | * @method merge_cell_below |
|
1167 | 1170 | */ |
|
1168 | 1171 | Notebook.prototype.merge_cell_below = function () { |
|
1169 | 1172 | var mdc = IPython.MarkdownCell; |
|
1170 | 1173 | var rc = IPython.RawCell; |
|
1171 | 1174 | var index = this.get_selected_index(); |
|
1172 | 1175 | var cell = this.get_cell(index); |
|
1173 | 1176 | var render = cell.rendered; |
|
1174 | 1177 | if (!cell.is_mergeable()) { |
|
1175 | 1178 | return; |
|
1176 | 1179 | } |
|
1177 | 1180 | if (index < this.ncells()-1) { |
|
1178 | 1181 | var lower_cell = this.get_cell(index+1); |
|
1179 | 1182 | if (!lower_cell.is_mergeable()) { |
|
1180 | 1183 | return; |
|
1181 | 1184 | } |
|
1182 | 1185 | var lower_text = lower_cell.get_text(); |
|
1183 | 1186 | var text = cell.get_text(); |
|
1184 | 1187 | if (cell instanceof IPython.CodeCell) { |
|
1185 | 1188 | cell.set_text(text+'\n'+lower_text); |
|
1186 | 1189 | } else if ((cell instanceof mdc) || (cell instanceof rc)) { |
|
1187 | 1190 | cell.unrender(); // Must unrender before we set_text. |
|
1188 | 1191 | cell.set_text(text+'\n\n'+lower_text); |
|
1189 | 1192 | if (render) { |
|
1190 | 1193 | // The rendered state of the final cell should match |
|
1191 | 1194 | // that of the original selected cell; |
|
1192 | 1195 | cell.render(); |
|
1193 | 1196 | } |
|
1194 | 1197 | } |
|
1195 | 1198 | this.delete_cell(index+1); |
|
1196 | 1199 | this.select(this.find_cell_index(cell)); |
|
1197 | 1200 | } |
|
1198 | 1201 | }; |
|
1199 | 1202 | |
|
1200 | 1203 | |
|
1201 | 1204 | // Cell collapsing and output clearing |
|
1202 | 1205 | |
|
1203 | 1206 | /** |
|
1204 | 1207 | * Hide a cell's output. |
|
1205 | 1208 | * |
|
1206 | 1209 | * @method collapse_output |
|
1207 | 1210 | * @param {Number} index A cell's numeric index |
|
1208 | 1211 | */ |
|
1209 | 1212 | Notebook.prototype.collapse_output = function (index) { |
|
1210 | 1213 | var i = this.index_or_selected(index); |
|
1211 | 1214 | var cell = this.get_cell(i); |
|
1212 | 1215 | if (cell !== null && (cell instanceof IPython.CodeCell)) { |
|
1213 | 1216 | cell.collapse_output(); |
|
1214 | 1217 | this.set_dirty(true); |
|
1215 | 1218 | } |
|
1216 | 1219 | }; |
|
1217 | 1220 | |
|
1218 | 1221 | /** |
|
1219 | 1222 | * Hide each code cell's output area. |
|
1220 | 1223 | * |
|
1221 | 1224 | * @method collapse_all_output |
|
1222 | 1225 | */ |
|
1223 | 1226 | Notebook.prototype.collapse_all_output = function () { |
|
1224 | 1227 | $.map(this.get_cells(), function (cell, i) { |
|
1225 | 1228 | if (cell instanceof IPython.CodeCell) { |
|
1226 | 1229 | cell.collapse_output(); |
|
1227 | 1230 | } |
|
1228 | 1231 | }); |
|
1229 | 1232 | // this should not be set if the `collapse` key is removed from nbformat |
|
1230 | 1233 | this.set_dirty(true); |
|
1231 | 1234 | }; |
|
1232 | 1235 | |
|
1233 | 1236 | /** |
|
1234 | 1237 | * Show a cell's output. |
|
1235 | 1238 | * |
|
1236 | 1239 | * @method expand_output |
|
1237 | 1240 | * @param {Number} index A cell's numeric index |
|
1238 | 1241 | */ |
|
1239 | 1242 | Notebook.prototype.expand_output = function (index) { |
|
1240 | 1243 | var i = this.index_or_selected(index); |
|
1241 | 1244 | var cell = this.get_cell(i); |
|
1242 | 1245 | if (cell !== null && (cell instanceof IPython.CodeCell)) { |
|
1243 | 1246 | cell.expand_output(); |
|
1244 | 1247 | this.set_dirty(true); |
|
1245 | 1248 | } |
|
1246 | 1249 | }; |
|
1247 | 1250 | |
|
1248 | 1251 | /** |
|
1249 | 1252 | * Expand each code cell's output area, and remove scrollbars. |
|
1250 | 1253 | * |
|
1251 | 1254 | * @method expand_all_output |
|
1252 | 1255 | */ |
|
1253 | 1256 | Notebook.prototype.expand_all_output = function () { |
|
1254 | 1257 | $.map(this.get_cells(), function (cell, i) { |
|
1255 | 1258 | if (cell instanceof IPython.CodeCell) { |
|
1256 | 1259 | cell.expand_output(); |
|
1257 | 1260 | } |
|
1258 | 1261 | }); |
|
1259 | 1262 | // this should not be set if the `collapse` key is removed from nbformat |
|
1260 | 1263 | this.set_dirty(true); |
|
1261 | 1264 | }; |
|
1262 | 1265 | |
|
1263 | 1266 | /** |
|
1264 | 1267 | * Clear the selected CodeCell's output area. |
|
1265 | 1268 | * |
|
1266 | 1269 | * @method clear_output |
|
1267 | 1270 | * @param {Number} index A cell's numeric index |
|
1268 | 1271 | */ |
|
1269 | 1272 | Notebook.prototype.clear_output = function (index) { |
|
1270 | 1273 | var i = this.index_or_selected(index); |
|
1271 | 1274 | var cell = this.get_cell(i); |
|
1272 | 1275 | if (cell !== null && (cell instanceof IPython.CodeCell)) { |
|
1273 | 1276 | cell.clear_output(); |
|
1274 | 1277 | this.set_dirty(true); |
|
1275 | 1278 | } |
|
1276 | 1279 | }; |
|
1277 | 1280 | |
|
1278 | 1281 | /** |
|
1279 | 1282 | * Clear each code cell's output area. |
|
1280 | 1283 | * |
|
1281 | 1284 | * @method clear_all_output |
|
1282 | 1285 | */ |
|
1283 | 1286 | Notebook.prototype.clear_all_output = function () { |
|
1284 | 1287 | $.map(this.get_cells(), function (cell, i) { |
|
1285 | 1288 | if (cell instanceof IPython.CodeCell) { |
|
1286 | 1289 | cell.clear_output(); |
|
1287 | 1290 | } |
|
1288 | 1291 | }); |
|
1289 | 1292 | this.set_dirty(true); |
|
1290 | 1293 | }; |
|
1291 | 1294 | |
|
1292 | 1295 | /** |
|
1293 | 1296 | * Scroll the selected CodeCell's output area. |
|
1294 | 1297 | * |
|
1295 | 1298 | * @method scroll_output |
|
1296 | 1299 | * @param {Number} index A cell's numeric index |
|
1297 | 1300 | */ |
|
1298 | 1301 | Notebook.prototype.scroll_output = function (index) { |
|
1299 | 1302 | var i = this.index_or_selected(index); |
|
1300 | 1303 | var cell = this.get_cell(i); |
|
1301 | 1304 | if (cell !== null && (cell instanceof IPython.CodeCell)) { |
|
1302 | 1305 | cell.scroll_output(); |
|
1303 | 1306 | this.set_dirty(true); |
|
1304 | 1307 | } |
|
1305 | 1308 | }; |
|
1306 | 1309 | |
|
1307 | 1310 | /** |
|
1308 | 1311 | * Expand each code cell's output area, and add a scrollbar for long output. |
|
1309 | 1312 | * |
|
1310 | 1313 | * @method scroll_all_output |
|
1311 | 1314 | */ |
|
1312 | 1315 | Notebook.prototype.scroll_all_output = function () { |
|
1313 | 1316 | $.map(this.get_cells(), function (cell, i) { |
|
1314 | 1317 | if (cell instanceof IPython.CodeCell) { |
|
1315 | 1318 | cell.scroll_output(); |
|
1316 | 1319 | } |
|
1317 | 1320 | }); |
|
1318 | 1321 | // this should not be set if the `collapse` key is removed from nbformat |
|
1319 | 1322 | this.set_dirty(true); |
|
1320 | 1323 | }; |
|
1321 | 1324 | |
|
1322 | 1325 | /** Toggle whether a cell's output is collapsed or expanded. |
|
1323 | 1326 | * |
|
1324 | 1327 | * @method toggle_output |
|
1325 | 1328 | * @param {Number} index A cell's numeric index |
|
1326 | 1329 | */ |
|
1327 | 1330 | Notebook.prototype.toggle_output = function (index) { |
|
1328 | 1331 | var i = this.index_or_selected(index); |
|
1329 | 1332 | var cell = this.get_cell(i); |
|
1330 | 1333 | if (cell !== null && (cell instanceof IPython.CodeCell)) { |
|
1331 | 1334 | cell.toggle_output(); |
|
1332 | 1335 | this.set_dirty(true); |
|
1333 | 1336 | } |
|
1334 | 1337 | }; |
|
1335 | 1338 | |
|
1336 | 1339 | /** |
|
1337 | 1340 | * Hide/show the output of all cells. |
|
1338 | 1341 | * |
|
1339 | 1342 | * @method toggle_all_output |
|
1340 | 1343 | */ |
|
1341 | 1344 | Notebook.prototype.toggle_all_output = function () { |
|
1342 | 1345 | $.map(this.get_cells(), function (cell, i) { |
|
1343 | 1346 | if (cell instanceof IPython.CodeCell) { |
|
1344 | 1347 | cell.toggle_output(); |
|
1345 | 1348 | } |
|
1346 | 1349 | }); |
|
1347 | 1350 | // this should not be set if the `collapse` key is removed from nbformat |
|
1348 | 1351 | this.set_dirty(true); |
|
1349 | 1352 | }; |
|
1350 | 1353 | |
|
1351 | 1354 | /** |
|
1352 | 1355 | * Toggle a scrollbar for long cell outputs. |
|
1353 | 1356 | * |
|
1354 | 1357 | * @method toggle_output_scroll |
|
1355 | 1358 | * @param {Number} index A cell's numeric index |
|
1356 | 1359 | */ |
|
1357 | 1360 | Notebook.prototype.toggle_output_scroll = function (index) { |
|
1358 | 1361 | var i = this.index_or_selected(index); |
|
1359 | 1362 | var cell = this.get_cell(i); |
|
1360 | 1363 | if (cell !== null && (cell instanceof IPython.CodeCell)) { |
|
1361 | 1364 | cell.toggle_output_scroll(); |
|
1362 | 1365 | this.set_dirty(true); |
|
1363 | 1366 | } |
|
1364 | 1367 | }; |
|
1365 | 1368 | |
|
1366 | 1369 | /** |
|
1367 | 1370 | * Toggle the scrolling of long output on all cells. |
|
1368 | 1371 | * |
|
1369 | 1372 | * @method toggle_all_output_scrolling |
|
1370 | 1373 | */ |
|
1371 | 1374 | Notebook.prototype.toggle_all_output_scroll = function () { |
|
1372 | 1375 | $.map(this.get_cells(), function (cell, i) { |
|
1373 | 1376 | if (cell instanceof IPython.CodeCell) { |
|
1374 | 1377 | cell.toggle_output_scroll(); |
|
1375 | 1378 | } |
|
1376 | 1379 | }); |
|
1377 | 1380 | // this should not be set if the `collapse` key is removed from nbformat |
|
1378 | 1381 | this.set_dirty(true); |
|
1379 | 1382 | }; |
|
1380 | 1383 | |
|
1381 | 1384 | // Other cell functions: line numbers, ... |
|
1382 | 1385 | |
|
1383 | 1386 | /** |
|
1384 | 1387 | * Toggle line numbers in the selected cell's input area. |
|
1385 | 1388 | * |
|
1386 | 1389 | * @method cell_toggle_line_numbers |
|
1387 | 1390 | */ |
|
1388 | 1391 | Notebook.prototype.cell_toggle_line_numbers = function() { |
|
1389 | 1392 | this.get_selected_cell().toggle_line_numbers(); |
|
1390 | 1393 | }; |
|
1391 | 1394 | |
|
1392 | 1395 | // Session related things |
|
1393 | 1396 | |
|
1394 | 1397 | /** |
|
1395 | 1398 | * Start a new session and set it on each code cell. |
|
1396 | 1399 | * |
|
1397 | 1400 | * @method start_session |
|
1398 | 1401 | */ |
|
1399 | 1402 | Notebook.prototype.start_session = function () { |
|
1400 | 1403 | this.session = new IPython.Session(this, this.options); |
|
1401 | 1404 | this.session.start($.proxy(this._session_started, this)); |
|
1402 | 1405 | }; |
|
1403 | 1406 | |
|
1404 | 1407 | |
|
1405 | 1408 | /** |
|
1406 | 1409 | * Once a session is started, link the code cells to the kernel and pass the |
|
1407 | 1410 | * comm manager to the widget manager |
|
1408 | 1411 | * |
|
1409 | 1412 | */ |
|
1410 | 1413 | Notebook.prototype._session_started = function(){ |
|
1411 | 1414 | this.kernel = this.session.kernel; |
|
1412 | 1415 | var ncells = this.ncells(); |
|
1413 | 1416 | for (var i=0; i<ncells; i++) { |
|
1414 | 1417 | var cell = this.get_cell(i); |
|
1415 | 1418 | if (cell instanceof IPython.CodeCell) { |
|
1416 | 1419 | cell.set_kernel(this.session.kernel); |
|
1417 | 1420 | } |
|
1418 | 1421 | } |
|
1419 | 1422 | }; |
|
1420 | 1423 | |
|
1421 | 1424 | /** |
|
1422 | 1425 | * Prompt the user to restart the IPython kernel. |
|
1423 | 1426 | * |
|
1424 | 1427 | * @method restart_kernel |
|
1425 | 1428 | */ |
|
1426 | 1429 | Notebook.prototype.restart_kernel = function () { |
|
1427 | 1430 | var that = this; |
|
1428 | 1431 | IPython.dialog.modal({ |
|
1429 | 1432 | title : "Restart kernel or continue running?", |
|
1430 | 1433 | body : $("<p/>").text( |
|
1431 | 1434 | 'Do you want to restart the current kernel? You will lose all variables defined in it.' |
|
1432 | 1435 | ), |
|
1433 | 1436 | buttons : { |
|
1434 | 1437 | "Continue running" : {}, |
|
1435 | 1438 | "Restart" : { |
|
1436 | 1439 | "class" : "btn-danger", |
|
1437 | 1440 | "click" : function() { |
|
1438 | 1441 | that.session.restart_kernel(); |
|
1439 | 1442 | } |
|
1440 | 1443 | } |
|
1441 | 1444 | } |
|
1442 | 1445 | }); |
|
1443 | 1446 | }; |
|
1444 | 1447 | |
|
1445 | 1448 | /** |
|
1446 | 1449 | * Execute or render cell outputs and go into command mode. |
|
1447 | 1450 | * |
|
1448 | 1451 | * @method execute_cell |
|
1449 | 1452 | */ |
|
1450 | 1453 | Notebook.prototype.execute_cell = function () { |
|
1451 | 1454 | // mode = shift, ctrl, alt |
|
1452 | 1455 | var cell = this.get_selected_cell(); |
|
1453 | 1456 | var cell_index = this.find_cell_index(cell); |
|
1454 | 1457 | |
|
1455 | 1458 | cell.execute(); |
|
1456 | 1459 | this.command_mode(); |
|
1457 | 1460 | this.set_dirty(true); |
|
1458 | 1461 | }; |
|
1459 | 1462 | |
|
1460 | 1463 | /** |
|
1461 | 1464 | * Execute or render cell outputs and insert a new cell below. |
|
1462 | 1465 | * |
|
1463 | 1466 | * @method execute_cell_and_insert_below |
|
1464 | 1467 | */ |
|
1465 | 1468 | Notebook.prototype.execute_cell_and_insert_below = function () { |
|
1466 | 1469 | var cell = this.get_selected_cell(); |
|
1467 | 1470 | var cell_index = this.find_cell_index(cell); |
|
1468 | 1471 | |
|
1469 | 1472 | cell.execute(); |
|
1470 | 1473 | |
|
1471 | 1474 | // If we are at the end always insert a new cell and return |
|
1472 | 1475 | if (cell_index === (this.ncells()-1)) { |
|
1473 | 1476 | this.command_mode(); |
|
1474 | 1477 | this.insert_cell_below('code'); |
|
1475 | 1478 | this.select(cell_index+1); |
|
1476 | 1479 | this.edit_mode(); |
|
1477 | 1480 | this.scroll_to_bottom(); |
|
1478 | 1481 | this.set_dirty(true); |
|
1479 | 1482 | return; |
|
1480 | 1483 | } |
|
1481 | 1484 | |
|
1482 | 1485 | this.command_mode(); |
|
1483 | 1486 | this.insert_cell_below('code'); |
|
1484 | 1487 | this.select(cell_index+1); |
|
1485 | 1488 | this.edit_mode(); |
|
1486 | 1489 | this.set_dirty(true); |
|
1487 | 1490 | }; |
|
1488 | 1491 | |
|
1489 | 1492 | /** |
|
1490 | 1493 | * Execute or render cell outputs and select the next cell. |
|
1491 | 1494 | * |
|
1492 | 1495 | * @method execute_cell_and_select_below |
|
1493 | 1496 | */ |
|
1494 | 1497 | Notebook.prototype.execute_cell_and_select_below = function () { |
|
1495 | 1498 | |
|
1496 | 1499 | var cell = this.get_selected_cell(); |
|
1497 | 1500 | var cell_index = this.find_cell_index(cell); |
|
1498 | 1501 | |
|
1499 | 1502 | cell.execute(); |
|
1500 | 1503 | |
|
1501 | 1504 | // If we are at the end always insert a new cell and return |
|
1502 | 1505 | if (cell_index === (this.ncells()-1)) { |
|
1503 | 1506 | this.command_mode(); |
|
1504 | 1507 | this.insert_cell_below('code'); |
|
1505 | 1508 | this.select(cell_index+1); |
|
1506 | 1509 | this.edit_mode(); |
|
1507 | 1510 | this.scroll_to_bottom(); |
|
1508 | 1511 | this.set_dirty(true); |
|
1509 | 1512 | return; |
|
1510 | 1513 | } |
|
1511 | 1514 | |
|
1512 | 1515 | this.command_mode(); |
|
1513 | 1516 | this.select(cell_index+1); |
|
1514 | 1517 | this.focus_cell(); |
|
1515 | 1518 | this.set_dirty(true); |
|
1516 | 1519 | }; |
|
1517 | 1520 | |
|
1518 | 1521 | /** |
|
1519 | 1522 | * Execute all cells below the selected cell. |
|
1520 | 1523 | * |
|
1521 | 1524 | * @method execute_cells_below |
|
1522 | 1525 | */ |
|
1523 | 1526 | Notebook.prototype.execute_cells_below = function () { |
|
1524 | 1527 | this.execute_cell_range(this.get_selected_index(), this.ncells()); |
|
1525 | 1528 | this.scroll_to_bottom(); |
|
1526 | 1529 | }; |
|
1527 | 1530 | |
|
1528 | 1531 | /** |
|
1529 | 1532 | * Execute all cells above the selected cell. |
|
1530 | 1533 | * |
|
1531 | 1534 | * @method execute_cells_above |
|
1532 | 1535 | */ |
|
1533 | 1536 | Notebook.prototype.execute_cells_above = function () { |
|
1534 | 1537 | this.execute_cell_range(0, this.get_selected_index()); |
|
1535 | 1538 | }; |
|
1536 | 1539 | |
|
1537 | 1540 | /** |
|
1538 | 1541 | * Execute all cells. |
|
1539 | 1542 | * |
|
1540 | 1543 | * @method execute_all_cells |
|
1541 | 1544 | */ |
|
1542 | 1545 | Notebook.prototype.execute_all_cells = function () { |
|
1543 | 1546 | this.execute_cell_range(0, this.ncells()); |
|
1544 | 1547 | this.scroll_to_bottom(); |
|
1545 | 1548 | }; |
|
1546 | 1549 | |
|
1547 | 1550 | /** |
|
1548 | 1551 | * Execute a contiguous range of cells. |
|
1549 | 1552 | * |
|
1550 | 1553 | * @method execute_cell_range |
|
1551 | 1554 | * @param {Number} start Index of the first cell to execute (inclusive) |
|
1552 | 1555 | * @param {Number} end Index of the last cell to execute (exclusive) |
|
1553 | 1556 | */ |
|
1554 | 1557 | Notebook.prototype.execute_cell_range = function (start, end) { |
|
1555 | 1558 | this.command_mode(); |
|
1556 | 1559 | for (var i=start; i<end; i++) { |
|
1557 | 1560 | this.select(i); |
|
1558 | 1561 | this.execute_cell(); |
|
1559 | 1562 | } |
|
1560 | 1563 | }; |
|
1561 | 1564 | |
|
1562 | 1565 | // Persistance and loading |
|
1563 | 1566 | |
|
1564 | 1567 | /** |
|
1565 | 1568 | * Getter method for this notebook's name. |
|
1566 | 1569 | * |
|
1567 | 1570 | * @method get_notebook_name |
|
1568 | 1571 | * @return {String} This notebook's name (excluding file extension) |
|
1569 | 1572 | */ |
|
1570 | 1573 | Notebook.prototype.get_notebook_name = function () { |
|
1571 | 1574 | var nbname = this.notebook_name.substring(0,this.notebook_name.length-6); |
|
1572 | 1575 | return nbname; |
|
1573 | 1576 | }; |
|
1574 | 1577 | |
|
1575 | 1578 | /** |
|
1576 | 1579 | * Setter method for this notebook's name. |
|
1577 | 1580 | * |
|
1578 | 1581 | * @method set_notebook_name |
|
1579 | 1582 | * @param {String} name A new name for this notebook |
|
1580 | 1583 | */ |
|
1581 | 1584 | Notebook.prototype.set_notebook_name = function (name) { |
|
1582 | 1585 | this.notebook_name = name; |
|
1583 | 1586 | }; |
|
1584 | 1587 | |
|
1585 | 1588 | /** |
|
1586 | 1589 | * Check that a notebook's name is valid. |
|
1587 | 1590 | * |
|
1588 | 1591 | * @method test_notebook_name |
|
1589 | 1592 | * @param {String} nbname A name for this notebook |
|
1590 | 1593 | * @return {Boolean} True if the name is valid, false if invalid |
|
1591 | 1594 | */ |
|
1592 | 1595 | Notebook.prototype.test_notebook_name = function (nbname) { |
|
1593 | 1596 | nbname = nbname || ''; |
|
1594 | 1597 | if (nbname.length>0 && !this.notebook_name_blacklist_re.test(nbname)) { |
|
1595 | 1598 | return true; |
|
1596 | 1599 | } else { |
|
1597 | 1600 | return false; |
|
1598 | 1601 | } |
|
1599 | 1602 | }; |
|
1600 | 1603 | |
|
1601 | 1604 | /** |
|
1602 | 1605 | * Load a notebook from JSON (.ipynb). |
|
1603 | 1606 | * |
|
1604 | 1607 | * This currently handles one worksheet: others are deleted. |
|
1605 | 1608 | * |
|
1606 | 1609 | * @method fromJSON |
|
1607 | 1610 | * @param {Object} data JSON representation of a notebook |
|
1608 | 1611 | */ |
|
1609 | 1612 | Notebook.prototype.fromJSON = function (data) { |
|
1610 | 1613 | var content = data.content; |
|
1611 | 1614 | var ncells = this.ncells(); |
|
1612 | 1615 | var i; |
|
1613 | 1616 | for (i=0; i<ncells; i++) { |
|
1614 | 1617 | // Always delete cell 0 as they get renumbered as they are deleted. |
|
1615 | 1618 | this.delete_cell(0); |
|
1616 | 1619 | } |
|
1617 | 1620 | // Save the metadata and name. |
|
1618 | 1621 | this.metadata = content.metadata; |
|
1619 | 1622 | this.notebook_name = data.name; |
|
1620 | 1623 | var trusted = true; |
|
1621 | 1624 | // Only handle 1 worksheet for now. |
|
1622 | 1625 | var worksheet = content.worksheets[0]; |
|
1623 | 1626 | if (worksheet !== undefined) { |
|
1624 | 1627 | if (worksheet.metadata) { |
|
1625 | 1628 | this.worksheet_metadata = worksheet.metadata; |
|
1626 | 1629 | } |
|
1627 | 1630 | var new_cells = worksheet.cells; |
|
1628 | 1631 | ncells = new_cells.length; |
|
1629 | 1632 | var cell_data = null; |
|
1630 | 1633 | var new_cell = null; |
|
1631 | 1634 | for (i=0; i<ncells; i++) { |
|
1632 | 1635 | cell_data = new_cells[i]; |
|
1633 | 1636 | // VERSIONHACK: plaintext -> raw |
|
1634 | 1637 | // handle never-released plaintext name for raw cells |
|
1635 | 1638 | if (cell_data.cell_type === 'plaintext'){ |
|
1636 | 1639 | cell_data.cell_type = 'raw'; |
|
1637 | 1640 | } |
|
1638 | 1641 | |
|
1639 | 1642 | new_cell = this.insert_cell_at_index(cell_data.cell_type, i); |
|
1640 | 1643 | new_cell.fromJSON(cell_data); |
|
1641 | 1644 | if (new_cell.cell_type == 'code' && !new_cell.output_area.trusted) { |
|
1642 | 1645 | trusted = false; |
|
1643 | 1646 | } |
|
1644 | 1647 | } |
|
1645 | 1648 | } |
|
1646 | 1649 | if (trusted != this.trusted) { |
|
1647 | 1650 | this.trusted = trusted; |
|
1648 | 1651 | $([IPython.events]).trigger("trust_changed.Notebook", trusted); |
|
1649 | 1652 | } |
|
1650 | 1653 | if (content.worksheets.length > 1) { |
|
1651 | 1654 | IPython.dialog.modal({ |
|
1652 | 1655 | title : "Multiple worksheets", |
|
1653 | 1656 | body : "This notebook has " + data.worksheets.length + " worksheets, " + |
|
1654 | 1657 | "but this version of IPython can only handle the first. " + |
|
1655 | 1658 | "If you save this notebook, worksheets after the first will be lost.", |
|
1656 | 1659 | buttons : { |
|
1657 | 1660 | OK : { |
|
1658 | 1661 | class : "btn-danger" |
|
1659 | 1662 | } |
|
1660 | 1663 | } |
|
1661 | 1664 | }); |
|
1662 | 1665 | } |
|
1663 | 1666 | }; |
|
1664 | 1667 | |
|
1665 | 1668 | /** |
|
1666 | 1669 | * Dump this notebook into a JSON-friendly object. |
|
1667 | 1670 | * |
|
1668 | 1671 | * @method toJSON |
|
1669 | 1672 | * @return {Object} A JSON-friendly representation of this notebook. |
|
1670 | 1673 | */ |
|
1671 | 1674 | Notebook.prototype.toJSON = function () { |
|
1672 | 1675 | var cells = this.get_cells(); |
|
1673 | 1676 | var ncells = cells.length; |
|
1674 | 1677 | var cell_array = new Array(ncells); |
|
1675 | 1678 | var trusted = true; |
|
1676 | 1679 | for (var i=0; i<ncells; i++) { |
|
1677 | 1680 | var cell = cells[i]; |
|
1678 | 1681 | if (cell.cell_type == 'code' && !cell.output_area.trusted) { |
|
1679 | 1682 | trusted = false; |
|
1680 | 1683 | } |
|
1681 | 1684 | cell_array[i] = cell.toJSON(); |
|
1682 | 1685 | } |
|
1683 | 1686 | var data = { |
|
1684 | 1687 | // Only handle 1 worksheet for now. |
|
1685 | 1688 | worksheets : [{ |
|
1686 | 1689 | cells: cell_array, |
|
1687 | 1690 | metadata: this.worksheet_metadata |
|
1688 | 1691 | }], |
|
1689 | 1692 | metadata : this.metadata |
|
1690 | 1693 | }; |
|
1691 | 1694 | if (trusted != this.trusted) { |
|
1692 | 1695 | this.trusted = trusted; |
|
1693 | 1696 | $([IPython.events]).trigger("trust_changed.Notebook", trusted); |
|
1694 | 1697 | } |
|
1695 | 1698 | return data; |
|
1696 | 1699 | }; |
|
1697 | 1700 | |
|
1698 | 1701 | /** |
|
1699 | 1702 | * Start an autosave timer, for periodically saving the notebook. |
|
1700 | 1703 | * |
|
1701 | 1704 | * @method set_autosave_interval |
|
1702 | 1705 | * @param {Integer} interval the autosave interval in milliseconds |
|
1703 | 1706 | */ |
|
1704 | 1707 | Notebook.prototype.set_autosave_interval = function (interval) { |
|
1705 | 1708 | var that = this; |
|
1706 | 1709 | // clear previous interval, so we don't get simultaneous timers |
|
1707 | 1710 | if (this.autosave_timer) { |
|
1708 | 1711 | clearInterval(this.autosave_timer); |
|
1709 | 1712 | } |
|
1710 | 1713 | |
|
1711 | 1714 | this.autosave_interval = this.minimum_autosave_interval = interval; |
|
1712 | 1715 | if (interval) { |
|
1713 | 1716 | this.autosave_timer = setInterval(function() { |
|
1714 | 1717 | if (that.dirty) { |
|
1715 | 1718 | that.save_notebook(); |
|
1716 | 1719 | } |
|
1717 | 1720 | }, interval); |
|
1718 | 1721 | $([IPython.events]).trigger("autosave_enabled.Notebook", interval); |
|
1719 | 1722 | } else { |
|
1720 | 1723 | this.autosave_timer = null; |
|
1721 | 1724 | $([IPython.events]).trigger("autosave_disabled.Notebook"); |
|
1722 | 1725 | } |
|
1723 | 1726 | }; |
|
1724 | 1727 | |
|
1725 | 1728 | /** |
|
1726 | * Save this notebook on the server. | |
|
1729 | * Save this notebook on the server. This becomes a notebook instance's | |
|
1730 | * .save_notebook method *after* the entire notebook has been loaded. | |
|
1727 | 1731 | * |
|
1728 | 1732 | * @method save_notebook |
|
1729 | 1733 | */ |
|
1730 | 1734 | Notebook.prototype.save_notebook = function (extra_settings) { |
|
1731 | 1735 | // Create a JSON model to be sent to the server. |
|
1732 | 1736 | var model = {}; |
|
1733 | 1737 | model.name = this.notebook_name; |
|
1734 | 1738 | model.path = this.notebook_path; |
|
1735 | 1739 | model.content = this.toJSON(); |
|
1736 | 1740 | model.content.nbformat = this.nbformat; |
|
1737 | 1741 | model.content.nbformat_minor = this.nbformat_minor; |
|
1738 | 1742 | // time the ajax call for autosave tuning purposes. |
|
1739 | 1743 | var start = new Date().getTime(); |
|
1740 | 1744 | // We do the call with settings so we can set cache to false. |
|
1741 | 1745 | var settings = { |
|
1742 | 1746 | processData : false, |
|
1743 | 1747 | cache : false, |
|
1744 | 1748 | type : "PUT", |
|
1745 | 1749 | data : JSON.stringify(model), |
|
1746 | 1750 | headers : {'Content-Type': 'application/json'}, |
|
1747 | 1751 | success : $.proxy(this.save_notebook_success, this, start), |
|
1748 | 1752 | error : $.proxy(this.save_notebook_error, this) |
|
1749 | 1753 | }; |
|
1750 | 1754 | if (extra_settings) { |
|
1751 | 1755 | for (var key in extra_settings) { |
|
1752 | 1756 | settings[key] = extra_settings[key]; |
|
1753 | 1757 | } |
|
1754 | 1758 | } |
|
1755 | 1759 | $([IPython.events]).trigger('notebook_saving.Notebook'); |
|
1756 | 1760 | var url = utils.url_join_encode( |
|
1757 | 1761 | this.base_url, |
|
1758 | 1762 | 'api/notebooks', |
|
1759 | 1763 | this.notebook_path, |
|
1760 | 1764 | this.notebook_name |
|
1761 | 1765 | ); |
|
1762 | 1766 | $.ajax(url, settings); |
|
1763 | 1767 | }; |
|
1764 | 1768 | |
|
1765 | 1769 | /** |
|
1766 | 1770 | * Success callback for saving a notebook. |
|
1767 | 1771 | * |
|
1768 | 1772 | * @method save_notebook_success |
|
1769 | 1773 | * @param {Integer} start the time when the save request started |
|
1770 | 1774 | * @param {Object} data JSON representation of a notebook |
|
1771 | 1775 | * @param {String} status Description of response status |
|
1772 | 1776 | * @param {jqXHR} xhr jQuery Ajax object |
|
1773 | 1777 | */ |
|
1774 | 1778 | Notebook.prototype.save_notebook_success = function (start, data, status, xhr) { |
|
1775 | 1779 | this.set_dirty(false); |
|
1776 | 1780 | $([IPython.events]).trigger('notebook_saved.Notebook'); |
|
1777 | 1781 | this._update_autosave_interval(start); |
|
1778 | 1782 | if (this._checkpoint_after_save) { |
|
1779 | 1783 | this.create_checkpoint(); |
|
1780 | 1784 | this._checkpoint_after_save = false; |
|
1781 | 1785 | } |
|
1782 | 1786 | }; |
|
1783 | 1787 | |
|
1784 | 1788 | /** |
|
1785 | 1789 | * update the autosave interval based on how long the last save took |
|
1786 | 1790 | * |
|
1787 | 1791 | * @method _update_autosave_interval |
|
1788 | 1792 | * @param {Integer} timestamp when the save request started |
|
1789 | 1793 | */ |
|
1790 | 1794 | Notebook.prototype._update_autosave_interval = function (start) { |
|
1791 | 1795 | var duration = (new Date().getTime() - start); |
|
1792 | 1796 | if (this.autosave_interval) { |
|
1793 | 1797 | // new save interval: higher of 10x save duration or parameter (default 30 seconds) |
|
1794 | 1798 | var interval = Math.max(10 * duration, this.minimum_autosave_interval); |
|
1795 | 1799 | // round to 10 seconds, otherwise we will be setting a new interval too often |
|
1796 | 1800 | interval = 10000 * Math.round(interval / 10000); |
|
1797 | 1801 | // set new interval, if it's changed |
|
1798 | 1802 | if (interval != this.autosave_interval) { |
|
1799 | 1803 | this.set_autosave_interval(interval); |
|
1800 | 1804 | } |
|
1801 | 1805 | } |
|
1802 | 1806 | }; |
|
1803 | 1807 | |
|
1804 | 1808 | /** |
|
1805 | 1809 | * Failure callback for saving a notebook. |
|
1806 | 1810 | * |
|
1807 | 1811 | * @method save_notebook_error |
|
1808 | 1812 | * @param {jqXHR} xhr jQuery Ajax object |
|
1809 | 1813 | * @param {String} status Description of response status |
|
1810 | 1814 | * @param {String} error HTTP error message |
|
1811 | 1815 | */ |
|
1812 | 1816 | Notebook.prototype.save_notebook_error = function (xhr, status, error) { |
|
1813 | 1817 | $([IPython.events]).trigger('notebook_save_failed.Notebook', [xhr, status, error]); |
|
1814 | 1818 | }; |
|
1815 | 1819 | |
|
1816 | 1820 | /** |
|
1817 | 1821 | * Explicitly trust the output of this notebook. |
|
1818 | 1822 | * |
|
1819 | 1823 | * @method trust_notebook |
|
1820 | 1824 | */ |
|
1821 | 1825 | Notebook.prototype.trust_notebook = function (extra_settings) { |
|
1822 | 1826 | var body = $("<div>").append($("<p>") |
|
1823 | 1827 | .text("A trusted IPython notebook may execute hidden malicious code ") |
|
1824 | 1828 | .append($("<strong>") |
|
1825 | 1829 | .append( |
|
1826 | 1830 | $("<em>").text("when you open it") |
|
1827 | 1831 | ) |
|
1828 | 1832 | ).append(".").append( |
|
1829 | 1833 | " Selecting trust will immediately reload this notebook in a trusted state." |
|
1830 | 1834 | ).append( |
|
1831 | 1835 | " For more information, see the " |
|
1832 | ).append($("<a>").attr("href", "http://ipython.org/security.html") | |
|
1836 | ).append($("<a>").attr("href", "http://ipython.org/ipython-doc/2/notebook/security.html") | |
|
1833 | 1837 | .text("IPython security documentation") |
|
1834 | 1838 | ).append(".") |
|
1835 | 1839 | ); |
|
1836 | 1840 | |
|
1837 | 1841 | var nb = this; |
|
1838 | 1842 | IPython.dialog.modal({ |
|
1839 | 1843 | title: "Trust this notebook?", |
|
1840 | 1844 | body: body, |
|
1841 | 1845 | |
|
1842 | 1846 | buttons: { |
|
1843 | 1847 | Cancel : {}, |
|
1844 | 1848 | Trust : { |
|
1845 | 1849 | class : "btn-danger", |
|
1846 | 1850 | click : function () { |
|
1847 | 1851 | var cells = nb.get_cells(); |
|
1848 | 1852 | for (var i = 0; i < cells.length; i++) { |
|
1849 | 1853 | var cell = cells[i]; |
|
1850 | 1854 | if (cell.cell_type == 'code') { |
|
1851 | 1855 | cell.output_area.trusted = true; |
|
1852 | 1856 | } |
|
1853 | 1857 | } |
|
1854 | 1858 | $([IPython.events]).on('notebook_saved.Notebook', function () { |
|
1855 | 1859 | window.location.reload(); |
|
1856 | 1860 | }); |
|
1857 | 1861 | nb.save_notebook(); |
|
1858 | 1862 | } |
|
1859 | 1863 | } |
|
1860 | 1864 | } |
|
1861 | 1865 | }); |
|
1862 | 1866 | }; |
|
1863 | 1867 | |
|
1864 | 1868 | Notebook.prototype.new_notebook = function(){ |
|
1865 | 1869 | var path = this.notebook_path; |
|
1866 | 1870 | var base_url = this.base_url; |
|
1867 | 1871 | var settings = { |
|
1868 | 1872 | processData : false, |
|
1869 | 1873 | cache : false, |
|
1870 | 1874 | type : "POST", |
|
1871 | 1875 | dataType : "json", |
|
1872 | 1876 | async : false, |
|
1873 | 1877 | success : function (data, status, xhr){ |
|
1874 | 1878 | var notebook_name = data.name; |
|
1875 | 1879 | window.open( |
|
1876 | 1880 | utils.url_join_encode( |
|
1877 | 1881 | base_url, |
|
1878 | 1882 | 'notebooks', |
|
1879 | 1883 | path, |
|
1880 | 1884 | notebook_name |
|
1881 | 1885 | ), |
|
1882 | 1886 | '_blank' |
|
1883 | 1887 | ); |
|
1884 | 1888 | } |
|
1885 | 1889 | }; |
|
1886 | 1890 | var url = utils.url_join_encode( |
|
1887 | 1891 | base_url, |
|
1888 | 1892 | 'api/notebooks', |
|
1889 | 1893 | path |
|
1890 | 1894 | ); |
|
1891 | 1895 | $.ajax(url,settings); |
|
1892 | 1896 | }; |
|
1893 | 1897 | |
|
1894 | 1898 | |
|
1895 | 1899 | Notebook.prototype.copy_notebook = function(){ |
|
1896 | 1900 | var path = this.notebook_path; |
|
1897 | 1901 | var base_url = this.base_url; |
|
1898 | 1902 | var settings = { |
|
1899 | 1903 | processData : false, |
|
1900 | 1904 | cache : false, |
|
1901 | 1905 | type : "POST", |
|
1902 | 1906 | dataType : "json", |
|
1903 | 1907 | data : JSON.stringify({copy_from : this.notebook_name}), |
|
1904 | 1908 | async : false, |
|
1905 | 1909 | success : function (data, status, xhr) { |
|
1906 | 1910 | window.open(utils.url_join_encode( |
|
1907 | 1911 | base_url, |
|
1908 | 1912 | 'notebooks', |
|
1909 | 1913 | data.path, |
|
1910 | 1914 | data.name |
|
1911 | 1915 | ), '_blank'); |
|
1912 | 1916 | } |
|
1913 | 1917 | }; |
|
1914 | 1918 | var url = utils.url_join_encode( |
|
1915 | 1919 | base_url, |
|
1916 | 1920 | 'api/notebooks', |
|
1917 | 1921 | path |
|
1918 | 1922 | ); |
|
1919 | 1923 | $.ajax(url,settings); |
|
1920 | 1924 | }; |
|
1921 | 1925 | |
|
1922 | 1926 | Notebook.prototype.rename = function (nbname) { |
|
1923 | 1927 | var that = this; |
|
1924 | 1928 | if (!nbname.match(/\.ipynb$/)) { |
|
1925 | 1929 | nbname = nbname + ".ipynb"; |
|
1926 | 1930 | } |
|
1927 | 1931 | var data = {name: nbname}; |
|
1928 | 1932 | var settings = { |
|
1929 | 1933 | processData : false, |
|
1930 | 1934 | cache : false, |
|
1931 | 1935 | type : "PATCH", |
|
1932 | 1936 | data : JSON.stringify(data), |
|
1933 | 1937 | dataType: "json", |
|
1934 | 1938 | headers : {'Content-Type': 'application/json'}, |
|
1935 | 1939 | success : $.proxy(that.rename_success, this), |
|
1936 | 1940 | error : $.proxy(that.rename_error, this) |
|
1937 | 1941 | }; |
|
1938 | 1942 | $([IPython.events]).trigger('rename_notebook.Notebook', data); |
|
1939 | 1943 | var url = utils.url_join_encode( |
|
1940 | 1944 | this.base_url, |
|
1941 | 1945 | 'api/notebooks', |
|
1942 | 1946 | this.notebook_path, |
|
1943 | 1947 | this.notebook_name |
|
1944 | 1948 | ); |
|
1945 | 1949 | $.ajax(url, settings); |
|
1946 | 1950 | }; |
|
1947 | 1951 | |
|
1948 | 1952 | Notebook.prototype.delete = function () { |
|
1949 | 1953 | var that = this; |
|
1950 | 1954 | var settings = { |
|
1951 | 1955 | processData : false, |
|
1952 | 1956 | cache : false, |
|
1953 | 1957 | type : "DELETE", |
|
1954 | 1958 | dataType: "json", |
|
1955 | 1959 | }; |
|
1956 | 1960 | var url = utils.url_join_encode( |
|
1957 | 1961 | this.base_url, |
|
1958 | 1962 | 'api/notebooks', |
|
1959 | 1963 | this.notebook_path, |
|
1960 | 1964 | this.notebook_name |
|
1961 | 1965 | ); |
|
1962 | 1966 | $.ajax(url, settings); |
|
1963 | 1967 | }; |
|
1964 | 1968 | |
|
1965 | 1969 | |
|
1966 | 1970 | Notebook.prototype.rename_success = function (json, status, xhr) { |
|
1967 | 1971 | var name = this.notebook_name = json.name; |
|
1968 | 1972 | var path = json.path; |
|
1969 | 1973 | this.session.rename_notebook(name, path); |
|
1970 | 1974 | $([IPython.events]).trigger('notebook_renamed.Notebook', json); |
|
1971 | 1975 | }; |
|
1972 | 1976 | |
|
1973 | 1977 | Notebook.prototype.rename_error = function (xhr, status, error) { |
|
1974 | 1978 | var that = this; |
|
1975 | 1979 | var dialog = $('<div/>').append( |
|
1976 | 1980 | $("<p/>").addClass("rename-message") |
|
1977 | 1981 | .text('This notebook name already exists.') |
|
1978 | 1982 | ); |
|
1979 | 1983 | $([IPython.events]).trigger('notebook_rename_failed.Notebook', [xhr, status, error]); |
|
1980 | 1984 | IPython.dialog.modal({ |
|
1981 | 1985 | title: "Notebook Rename Error!", |
|
1982 | 1986 | body: dialog, |
|
1983 | 1987 | buttons : { |
|
1984 | 1988 | "Cancel": {}, |
|
1985 | 1989 | "OK": { |
|
1986 | 1990 | class: "btn-primary", |
|
1987 | 1991 | click: function () { |
|
1988 | 1992 | IPython.save_widget.rename_notebook(); |
|
1989 | 1993 | }} |
|
1990 | 1994 | }, |
|
1991 | 1995 | open : function (event, ui) { |
|
1992 | 1996 | var that = $(this); |
|
1993 | 1997 | // Upon ENTER, click the OK button. |
|
1994 | 1998 | that.find('input[type="text"]').keydown(function (event, ui) { |
|
1995 | 1999 | if (event.which === IPython.keyboard.keycodes.enter) { |
|
1996 | 2000 | that.find('.btn-primary').first().click(); |
|
1997 | 2001 | } |
|
1998 | 2002 | }); |
|
1999 | 2003 | that.find('input[type="text"]').focus(); |
|
2000 | 2004 | } |
|
2001 | 2005 | }); |
|
2002 | 2006 | }; |
|
2003 | 2007 | |
|
2004 | 2008 | /** |
|
2005 | 2009 | * Request a notebook's data from the server. |
|
2006 | 2010 | * |
|
2007 | 2011 | * @method load_notebook |
|
2008 | 2012 | * @param {String} notebook_name and path A notebook to load |
|
2009 | 2013 | */ |
|
2010 | 2014 | Notebook.prototype.load_notebook = function (notebook_name, notebook_path) { |
|
2011 | 2015 | var that = this; |
|
2012 | 2016 | this.notebook_name = notebook_name; |
|
2013 | 2017 | this.notebook_path = notebook_path; |
|
2014 | 2018 | // We do the call with settings so we can set cache to false. |
|
2015 | 2019 | var settings = { |
|
2016 | 2020 | processData : false, |
|
2017 | 2021 | cache : false, |
|
2018 | 2022 | type : "GET", |
|
2019 | 2023 | dataType : "json", |
|
2020 | 2024 | success : $.proxy(this.load_notebook_success,this), |
|
2021 | 2025 | error : $.proxy(this.load_notebook_error,this), |
|
2022 | 2026 | }; |
|
2023 | 2027 | $([IPython.events]).trigger('notebook_loading.Notebook'); |
|
2024 | 2028 | var url = utils.url_join_encode( |
|
2025 | 2029 | this.base_url, |
|
2026 | 2030 | 'api/notebooks', |
|
2027 | 2031 | this.notebook_path, |
|
2028 | 2032 | this.notebook_name |
|
2029 | 2033 | ); |
|
2030 | 2034 | $.ajax(url, settings); |
|
2031 | 2035 | }; |
|
2032 | 2036 | |
|
2033 | 2037 | /** |
|
2034 | 2038 | * Success callback for loading a notebook from the server. |
|
2035 | 2039 | * |
|
2036 | 2040 | * Load notebook data from the JSON response. |
|
2037 | 2041 | * |
|
2038 | 2042 | * @method load_notebook_success |
|
2039 | 2043 | * @param {Object} data JSON representation of a notebook |
|
2040 | 2044 | * @param {String} status Description of response status |
|
2041 | 2045 | * @param {jqXHR} xhr jQuery Ajax object |
|
2042 | 2046 | */ |
|
2043 | 2047 | Notebook.prototype.load_notebook_success = function (data, status, xhr) { |
|
2044 | 2048 | this.fromJSON(data); |
|
2045 | 2049 | if (this.ncells() === 0) { |
|
2046 | 2050 | this.insert_cell_below('code'); |
|
2047 | 2051 | this.edit_mode(0); |
|
2048 | 2052 | } else { |
|
2049 | 2053 | this.select(0); |
|
2050 | 2054 | this.handle_command_mode(this.get_cell(0)); |
|
2051 | 2055 | } |
|
2052 | 2056 | this.set_dirty(false); |
|
2053 | 2057 | this.scroll_to_top(); |
|
2054 | 2058 | if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) { |
|
2055 | 2059 | var msg = "This notebook has been converted from an older " + |
|
2056 | 2060 | "notebook format (v"+data.orig_nbformat+") to the current notebook " + |
|
2057 | 2061 | "format (v"+data.nbformat+"). The next time you save this notebook, the " + |
|
2058 | 2062 | "newer notebook format will be used and older versions of IPython " + |
|
2059 | 2063 | "may not be able to read it. To keep the older version, close the " + |
|
2060 | 2064 | "notebook without saving it."; |
|
2061 | 2065 | IPython.dialog.modal({ |
|
2062 | 2066 | title : "Notebook converted", |
|
2063 | 2067 | body : msg, |
|
2064 | 2068 | buttons : { |
|
2065 | 2069 | OK : { |
|
2066 | 2070 | class : "btn-primary" |
|
2067 | 2071 | } |
|
2068 | 2072 | } |
|
2069 | 2073 | }); |
|
2070 | 2074 | } else if (data.orig_nbformat_minor !== undefined && data.nbformat_minor !== data.orig_nbformat_minor) { |
|
2071 | 2075 | var that = this; |
|
2072 | 2076 | var orig_vs = 'v' + data.nbformat + '.' + data.orig_nbformat_minor; |
|
2073 | 2077 | var this_vs = 'v' + data.nbformat + '.' + this.nbformat_minor; |
|
2074 | 2078 | var msg = "This notebook is version " + orig_vs + ", but we only fully support up to " + |
|
2075 | 2079 | this_vs + ". You can still work with this notebook, but some features " + |
|
2076 | 2080 | "introduced in later notebook versions may not be available."; |
|
2077 | 2081 | |
|
2078 | 2082 | IPython.dialog.modal({ |
|
2079 | 2083 | title : "Newer Notebook", |
|
2080 | 2084 | body : msg, |
|
2081 | 2085 | buttons : { |
|
2082 | 2086 | OK : { |
|
2083 | 2087 | class : "btn-danger" |
|
2084 | 2088 | } |
|
2085 | 2089 | } |
|
2086 | 2090 | }); |
|
2087 | 2091 | |
|
2088 | 2092 | } |
|
2089 | 2093 | |
|
2090 | 2094 | // Create the session after the notebook is completely loaded to prevent |
|
2091 | 2095 | // code execution upon loading, which is a security risk. |
|
2092 | 2096 | if (this.session === null) { |
|
2093 | 2097 | this.start_session(); |
|
2094 | 2098 | } |
|
2095 | 2099 | // load our checkpoint list |
|
2096 | 2100 | this.list_checkpoints(); |
|
2097 | 2101 | |
|
2098 | 2102 | // load toolbar state |
|
2099 | 2103 | if (this.metadata.celltoolbar) { |
|
2100 | 2104 | IPython.CellToolbar.global_show(); |
|
2101 | 2105 | IPython.CellToolbar.activate_preset(this.metadata.celltoolbar); |
|
2102 | 2106 | } |
|
2103 | ||
|
2107 | ||
|
2108 | // now that we're fully loaded, it is safe to restore save functionality | |
|
2109 | delete(this.save_notebook); | |
|
2104 | 2110 | $([IPython.events]).trigger('notebook_loaded.Notebook'); |
|
2105 | 2111 | }; |
|
2106 | 2112 | |
|
2107 | 2113 | /** |
|
2108 | 2114 | * Failure callback for loading a notebook from the server. |
|
2109 | 2115 | * |
|
2110 | 2116 | * @method load_notebook_error |
|
2111 | 2117 | * @param {jqXHR} xhr jQuery Ajax object |
|
2112 | 2118 | * @param {String} status Description of response status |
|
2113 | 2119 | * @param {String} error HTTP error message |
|
2114 | 2120 | */ |
|
2115 | 2121 | Notebook.prototype.load_notebook_error = function (xhr, status, error) { |
|
2116 | 2122 | $([IPython.events]).trigger('notebook_load_failed.Notebook', [xhr, status, error]); |
|
2117 | 2123 | var msg; |
|
2118 | 2124 | if (xhr.status === 400) { |
|
2119 | 2125 | msg = error; |
|
2120 | 2126 | } else if (xhr.status === 500) { |
|
2121 | 2127 | msg = "An unknown error occurred while loading this notebook. " + |
|
2122 | 2128 | "This version can load notebook formats " + |
|
2123 | 2129 | "v" + this.nbformat + " or earlier."; |
|
2124 | 2130 | } |
|
2125 | 2131 | IPython.dialog.modal({ |
|
2126 | 2132 | title: "Error loading notebook", |
|
2127 | 2133 | body : msg, |
|
2128 | 2134 | buttons : { |
|
2129 | 2135 | "OK": {} |
|
2130 | 2136 | } |
|
2131 | 2137 | }); |
|
2132 | 2138 | }; |
|
2133 | 2139 | |
|
2134 | 2140 | /********************* checkpoint-related *********************/ |
|
2135 | 2141 | |
|
2136 | 2142 | /** |
|
2137 | 2143 | * Save the notebook then immediately create a checkpoint. |
|
2138 | 2144 | * |
|
2139 | 2145 | * @method save_checkpoint |
|
2140 | 2146 | */ |
|
2141 | 2147 | Notebook.prototype.save_checkpoint = function () { |
|
2142 | 2148 | this._checkpoint_after_save = true; |
|
2143 | 2149 | this.save_notebook(); |
|
2144 | 2150 | }; |
|
2145 | 2151 | |
|
2146 | 2152 | /** |
|
2147 | 2153 | * Add a checkpoint for this notebook. |
|
2148 | 2154 | * for use as a callback from checkpoint creation. |
|
2149 | 2155 | * |
|
2150 | 2156 | * @method add_checkpoint |
|
2151 | 2157 | */ |
|
2152 | 2158 | Notebook.prototype.add_checkpoint = function (checkpoint) { |
|
2153 | 2159 | var found = false; |
|
2154 | 2160 | for (var i = 0; i < this.checkpoints.length; i++) { |
|
2155 | 2161 | var existing = this.checkpoints[i]; |
|
2156 | 2162 | if (existing.id == checkpoint.id) { |
|
2157 | 2163 | found = true; |
|
2158 | 2164 | this.checkpoints[i] = checkpoint; |
|
2159 | 2165 | break; |
|
2160 | 2166 | } |
|
2161 | 2167 | } |
|
2162 | 2168 | if (!found) { |
|
2163 | 2169 | this.checkpoints.push(checkpoint); |
|
2164 | 2170 | } |
|
2165 | 2171 | this.last_checkpoint = this.checkpoints[this.checkpoints.length - 1]; |
|
2166 | 2172 | }; |
|
2167 | 2173 | |
|
2168 | 2174 | /** |
|
2169 | 2175 | * List checkpoints for this notebook. |
|
2170 | 2176 | * |
|
2171 | 2177 | * @method list_checkpoints |
|
2172 | 2178 | */ |
|
2173 | 2179 | Notebook.prototype.list_checkpoints = function () { |
|
2174 | 2180 | var url = utils.url_join_encode( |
|
2175 | 2181 | this.base_url, |
|
2176 | 2182 | 'api/notebooks', |
|
2177 | 2183 | this.notebook_path, |
|
2178 | 2184 | this.notebook_name, |
|
2179 | 2185 | 'checkpoints' |
|
2180 | 2186 | ); |
|
2181 | 2187 | $.get(url).done( |
|
2182 | 2188 | $.proxy(this.list_checkpoints_success, this) |
|
2183 | 2189 | ).fail( |
|
2184 | 2190 | $.proxy(this.list_checkpoints_error, this) |
|
2185 | 2191 | ); |
|
2186 | 2192 | }; |
|
2187 | 2193 | |
|
2188 | 2194 | /** |
|
2189 | 2195 | * Success callback for listing checkpoints. |
|
2190 | 2196 | * |
|
2191 | 2197 | * @method list_checkpoint_success |
|
2192 | 2198 | * @param {Object} data JSON representation of a checkpoint |
|
2193 | 2199 | * @param {String} status Description of response status |
|
2194 | 2200 | * @param {jqXHR} xhr jQuery Ajax object |
|
2195 | 2201 | */ |
|
2196 | 2202 | Notebook.prototype.list_checkpoints_success = function (data, status, xhr) { |
|
2197 | 2203 | data = $.parseJSON(data); |
|
2198 | 2204 | this.checkpoints = data; |
|
2199 | 2205 | if (data.length) { |
|
2200 | 2206 | this.last_checkpoint = data[data.length - 1]; |
|
2201 | 2207 | } else { |
|
2202 | 2208 | this.last_checkpoint = null; |
|
2203 | 2209 | } |
|
2204 | 2210 | $([IPython.events]).trigger('checkpoints_listed.Notebook', [data]); |
|
2205 | 2211 | }; |
|
2206 | 2212 | |
|
2207 | 2213 | /** |
|
2208 | 2214 | * Failure callback for listing a checkpoint. |
|
2209 | 2215 | * |
|
2210 | 2216 | * @method list_checkpoint_error |
|
2211 | 2217 | * @param {jqXHR} xhr jQuery Ajax object |
|
2212 | 2218 | * @param {String} status Description of response status |
|
2213 | 2219 | * @param {String} error_msg HTTP error message |
|
2214 | 2220 | */ |
|
2215 | 2221 | Notebook.prototype.list_checkpoints_error = function (xhr, status, error_msg) { |
|
2216 | 2222 | $([IPython.events]).trigger('list_checkpoints_failed.Notebook'); |
|
2217 | 2223 | }; |
|
2218 | 2224 | |
|
2219 | 2225 | /** |
|
2220 | 2226 | * Create a checkpoint of this notebook on the server from the most recent save. |
|
2221 | 2227 | * |
|
2222 | 2228 | * @method create_checkpoint |
|
2223 | 2229 | */ |
|
2224 | 2230 | Notebook.prototype.create_checkpoint = function () { |
|
2225 | 2231 | var url = utils.url_join_encode( |
|
2226 | 2232 | this.base_url, |
|
2227 | 2233 | 'api/notebooks', |
|
2228 | 2234 | this.notebook_path, |
|
2229 | 2235 | this.notebook_name, |
|
2230 | 2236 | 'checkpoints' |
|
2231 | 2237 | ); |
|
2232 | 2238 | $.post(url).done( |
|
2233 | 2239 | $.proxy(this.create_checkpoint_success, this) |
|
2234 | 2240 | ).fail( |
|
2235 | 2241 | $.proxy(this.create_checkpoint_error, this) |
|
2236 | 2242 | ); |
|
2237 | 2243 | }; |
|
2238 | 2244 | |
|
2239 | 2245 | /** |
|
2240 | 2246 | * Success callback for creating a checkpoint. |
|
2241 | 2247 | * |
|
2242 | 2248 | * @method create_checkpoint_success |
|
2243 | 2249 | * @param {Object} data JSON representation of a checkpoint |
|
2244 | 2250 | * @param {String} status Description of response status |
|
2245 | 2251 | * @param {jqXHR} xhr jQuery Ajax object |
|
2246 | 2252 | */ |
|
2247 | 2253 | Notebook.prototype.create_checkpoint_success = function (data, status, xhr) { |
|
2248 | 2254 | data = $.parseJSON(data); |
|
2249 | 2255 | this.add_checkpoint(data); |
|
2250 | 2256 | $([IPython.events]).trigger('checkpoint_created.Notebook', data); |
|
2251 | 2257 | }; |
|
2252 | 2258 | |
|
2253 | 2259 | /** |
|
2254 | 2260 | * Failure callback for creating a checkpoint. |
|
2255 | 2261 | * |
|
2256 | 2262 | * @method create_checkpoint_error |
|
2257 | 2263 | * @param {jqXHR} xhr jQuery Ajax object |
|
2258 | 2264 | * @param {String} status Description of response status |
|
2259 | 2265 | * @param {String} error_msg HTTP error message |
|
2260 | 2266 | */ |
|
2261 | 2267 | Notebook.prototype.create_checkpoint_error = function (xhr, status, error_msg) { |
|
2262 | 2268 | $([IPython.events]).trigger('checkpoint_failed.Notebook'); |
|
2263 | 2269 | }; |
|
2264 | 2270 | |
|
2265 | 2271 | Notebook.prototype.restore_checkpoint_dialog = function (checkpoint) { |
|
2266 | 2272 | var that = this; |
|
2267 | 2273 | checkpoint = checkpoint || this.last_checkpoint; |
|
2268 | 2274 | if ( ! checkpoint ) { |
|
2269 | 2275 | console.log("restore dialog, but no checkpoint to restore to!"); |
|
2270 | 2276 | return; |
|
2271 | 2277 | } |
|
2272 | 2278 | var body = $('<div/>').append( |
|
2273 | 2279 | $('<p/>').addClass("p-space").text( |
|
2274 | 2280 | "Are you sure you want to revert the notebook to " + |
|
2275 | 2281 | "the latest checkpoint?" |
|
2276 | 2282 | ).append( |
|
2277 | 2283 | $("<strong/>").text( |
|
2278 | 2284 | " This cannot be undone." |
|
2279 | 2285 | ) |
|
2280 | 2286 | ) |
|
2281 | 2287 | ).append( |
|
2282 | 2288 | $('<p/>').addClass("p-space").text("The checkpoint was last updated at:") |
|
2283 | 2289 | ).append( |
|
2284 | 2290 | $('<p/>').addClass("p-space").text( |
|
2285 | 2291 | Date(checkpoint.last_modified) |
|
2286 | 2292 | ).css("text-align", "center") |
|
2287 | 2293 | ); |
|
2288 | 2294 | |
|
2289 | 2295 | IPython.dialog.modal({ |
|
2290 | 2296 | title : "Revert notebook to checkpoint", |
|
2291 | 2297 | body : body, |
|
2292 | 2298 | buttons : { |
|
2293 | 2299 | Revert : { |
|
2294 | 2300 | class : "btn-danger", |
|
2295 | 2301 | click : function () { |
|
2296 | 2302 | that.restore_checkpoint(checkpoint.id); |
|
2297 | 2303 | } |
|
2298 | 2304 | }, |
|
2299 | 2305 | Cancel : {} |
|
2300 | 2306 | } |
|
2301 | 2307 | }); |
|
2302 | 2308 | }; |
|
2303 | 2309 | |
|
2304 | 2310 | /** |
|
2305 | 2311 | * Restore the notebook to a checkpoint state. |
|
2306 | 2312 | * |
|
2307 | 2313 | * @method restore_checkpoint |
|
2308 | 2314 | * @param {String} checkpoint ID |
|
2309 | 2315 | */ |
|
2310 | 2316 | Notebook.prototype.restore_checkpoint = function (checkpoint) { |
|
2311 | 2317 | $([IPython.events]).trigger('notebook_restoring.Notebook', checkpoint); |
|
2312 | 2318 | var url = utils.url_join_encode( |
|
2313 | 2319 | this.base_url, |
|
2314 | 2320 | 'api/notebooks', |
|
2315 | 2321 | this.notebook_path, |
|
2316 | 2322 | this.notebook_name, |
|
2317 | 2323 | 'checkpoints', |
|
2318 | 2324 | checkpoint |
|
2319 | 2325 | ); |
|
2320 | 2326 | $.post(url).done( |
|
2321 | 2327 | $.proxy(this.restore_checkpoint_success, this) |
|
2322 | 2328 | ).fail( |
|
2323 | 2329 | $.proxy(this.restore_checkpoint_error, this) |
|
2324 | 2330 | ); |
|
2325 | 2331 | }; |
|
2326 | 2332 | |
|
2327 | 2333 | /** |
|
2328 | 2334 | * Success callback for restoring a notebook to a checkpoint. |
|
2329 | 2335 | * |
|
2330 | 2336 | * @method restore_checkpoint_success |
|
2331 | 2337 | * @param {Object} data (ignored, should be empty) |
|
2332 | 2338 | * @param {String} status Description of response status |
|
2333 | 2339 | * @param {jqXHR} xhr jQuery Ajax object |
|
2334 | 2340 | */ |
|
2335 | 2341 | Notebook.prototype.restore_checkpoint_success = function (data, status, xhr) { |
|
2336 | 2342 | $([IPython.events]).trigger('checkpoint_restored.Notebook'); |
|
2337 | 2343 | this.load_notebook(this.notebook_name, this.notebook_path); |
|
2338 | 2344 | }; |
|
2339 | 2345 | |
|
2340 | 2346 | /** |
|
2341 | 2347 | * Failure callback for restoring a notebook to a checkpoint. |
|
2342 | 2348 | * |
|
2343 | 2349 | * @method restore_checkpoint_error |
|
2344 | 2350 | * @param {jqXHR} xhr jQuery Ajax object |
|
2345 | 2351 | * @param {String} status Description of response status |
|
2346 | 2352 | * @param {String} error_msg HTTP error message |
|
2347 | 2353 | */ |
|
2348 | 2354 | Notebook.prototype.restore_checkpoint_error = function (xhr, status, error_msg) { |
|
2349 | 2355 | $([IPython.events]).trigger('checkpoint_restore_failed.Notebook'); |
|
2350 | 2356 | }; |
|
2351 | 2357 | |
|
2352 | 2358 | /** |
|
2353 | 2359 | * Delete a notebook checkpoint. |
|
2354 | 2360 | * |
|
2355 | 2361 | * @method delete_checkpoint |
|
2356 | 2362 | * @param {String} checkpoint ID |
|
2357 | 2363 | */ |
|
2358 | 2364 | Notebook.prototype.delete_checkpoint = function (checkpoint) { |
|
2359 | 2365 | $([IPython.events]).trigger('notebook_restoring.Notebook', checkpoint); |
|
2360 | 2366 | var url = utils.url_join_encode( |
|
2361 | 2367 | this.base_url, |
|
2362 | 2368 | 'api/notebooks', |
|
2363 | 2369 | this.notebook_path, |
|
2364 | 2370 | this.notebook_name, |
|
2365 | 2371 | 'checkpoints', |
|
2366 | 2372 | checkpoint |
|
2367 | 2373 | ); |
|
2368 | 2374 | $.ajax(url, { |
|
2369 | 2375 | type: 'DELETE', |
|
2370 | 2376 | success: $.proxy(this.delete_checkpoint_success, this), |
|
2371 | 2377 | error: $.proxy(this.delete_notebook_error,this) |
|
2372 | 2378 | }); |
|
2373 | 2379 | }; |
|
2374 | 2380 | |
|
2375 | 2381 | /** |
|
2376 | 2382 | * Success callback for deleting a notebook checkpoint |
|
2377 | 2383 | * |
|
2378 | 2384 | * @method delete_checkpoint_success |
|
2379 | 2385 | * @param {Object} data (ignored, should be empty) |
|
2380 | 2386 | * @param {String} status Description of response status |
|
2381 | 2387 | * @param {jqXHR} xhr jQuery Ajax object |
|
2382 | 2388 | */ |
|
2383 | 2389 | Notebook.prototype.delete_checkpoint_success = function (data, status, xhr) { |
|
2384 | 2390 | $([IPython.events]).trigger('checkpoint_deleted.Notebook', data); |
|
2385 | 2391 | this.load_notebook(this.notebook_name, this.notebook_path); |
|
2386 | 2392 | }; |
|
2387 | 2393 | |
|
2388 | 2394 | /** |
|
2389 | 2395 | * Failure callback for deleting a notebook checkpoint. |
|
2390 | 2396 | * |
|
2391 | 2397 | * @method delete_checkpoint_error |
|
2392 | 2398 | * @param {jqXHR} xhr jQuery Ajax object |
|
2393 | 2399 | * @param {String} status Description of response status |
|
2394 | 2400 | * @param {String} error_msg HTTP error message |
|
2395 | 2401 | */ |
|
2396 | 2402 | Notebook.prototype.delete_checkpoint_error = function (xhr, status, error_msg) { |
|
2397 | 2403 | $([IPython.events]).trigger('checkpoint_delete_failed.Notebook'); |
|
2398 | 2404 | }; |
|
2399 | 2405 | |
|
2400 | 2406 | |
|
2401 | 2407 | IPython.Notebook = Notebook; |
|
2402 | 2408 | |
|
2403 | 2409 | |
|
2404 | 2410 | return IPython; |
|
2405 | 2411 | |
|
2406 | 2412 | }(IPython)); |
|
2407 | 2413 |
@@ -1,235 +1,235 b'' | |||
|
1 | 1 | //---------------------------------------------------------------------------- |
|
2 | 2 | // Copyright (C) 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 | // Notification widget |
|
10 | 10 | //============================================================================ |
|
11 | 11 | |
|
12 | 12 | var IPython = (function (IPython) { |
|
13 | 13 | "use strict"; |
|
14 | 14 | var utils = IPython.utils; |
|
15 | 15 | |
|
16 | 16 | |
|
17 | 17 | var NotificationArea = function (selector) { |
|
18 | 18 | this.selector = selector; |
|
19 | 19 | if (this.selector !== undefined) { |
|
20 | 20 | this.element = $(selector); |
|
21 | 21 | } |
|
22 | 22 | this.widget_dict = {}; |
|
23 | 23 | }; |
|
24 | 24 | |
|
25 | 25 | NotificationArea.prototype.temp_message = function (msg, timeout, css_class) { |
|
26 | 26 | var uuid = utils.uuid(); |
|
27 | 27 | if( css_class == 'danger') {css_class = 'ui-state-error';} |
|
28 | 28 | if( css_class == 'warning') {css_class = 'ui-state-highlight';} |
|
29 | 29 | var tdiv = $('<div>') |
|
30 | 30 | .attr('id',uuid) |
|
31 | 31 | .addClass('notification_widget ui-widget ui-widget-content ui-corner-all') |
|
32 | 32 | .addClass('border-box-sizing') |
|
33 | 33 | .addClass(css_class) |
|
34 | 34 | .hide() |
|
35 | 35 | .text(msg); |
|
36 | 36 | |
|
37 | 37 | $(this.selector).append(tdiv); |
|
38 | 38 | var tmout = Math.max(1500,(timeout||1500)); |
|
39 | 39 | tdiv.fadeIn(100); |
|
40 | 40 | |
|
41 | 41 | setTimeout(function () { |
|
42 | 42 | tdiv.fadeOut(100, function () {tdiv.remove();}); |
|
43 | 43 | }, tmout); |
|
44 | 44 | }; |
|
45 | 45 | |
|
46 | 46 | NotificationArea.prototype.widget = function(name) { |
|
47 | 47 | if(this.widget_dict[name] === undefined) { |
|
48 | 48 | return this.new_notification_widget(name); |
|
49 | 49 | } |
|
50 | 50 | return this.get_widget(name); |
|
51 | 51 | }; |
|
52 | 52 | |
|
53 | 53 | NotificationArea.prototype.get_widget = function(name) { |
|
54 | 54 | if(this.widget_dict[name] === undefined) { |
|
55 | 55 | throw('no widgets with this name'); |
|
56 | 56 | } |
|
57 | 57 | return this.widget_dict[name]; |
|
58 | 58 | }; |
|
59 | 59 | |
|
60 | 60 | NotificationArea.prototype.new_notification_widget = function(name) { |
|
61 | 61 | if(this.widget_dict[name] !== undefined) { |
|
62 | 62 | throw('widget with that name already exists ! '); |
|
63 | 63 | } |
|
64 | 64 | var div = $('<div/>').attr('id','notification_'+name); |
|
65 | 65 | $(this.selector).append(div); |
|
66 | 66 | this.widget_dict[name] = new IPython.NotificationWidget('#notification_'+name); |
|
67 | 67 | return this.widget_dict[name]; |
|
68 | 68 | }; |
|
69 | 69 | |
|
70 | 70 | NotificationArea.prototype.init_notification_widgets = function() { |
|
71 | 71 | var knw = this.new_notification_widget('kernel'); |
|
72 | 72 | var $kernel_ind_icon = $("#kernel_indicator_icon"); |
|
73 | 73 | var $modal_ind_icon = $("#modal_indicator_icon"); |
|
74 | 74 | |
|
75 | 75 | // Command/Edit mode |
|
76 | 76 | $([IPython.events]).on('edit_mode.Notebook',function () { |
|
77 | 77 | IPython.save_widget.update_document_title(); |
|
78 | 78 | $modal_ind_icon.attr('class','edit_mode_icon').attr('title','Edit Mode'); |
|
79 | 79 | }); |
|
80 | 80 | |
|
81 | 81 | $([IPython.events]).on('command_mode.Notebook',function () { |
|
82 | 82 | IPython.save_widget.update_document_title(); |
|
83 | 83 | $modal_ind_icon.attr('class','command_mode_icon').attr('title','Command Mode'); |
|
84 | 84 | }); |
|
85 | 85 | |
|
86 | 86 | // Implicitly start off in Command mode, switching to Edit mode will trigger event |
|
87 | 87 | $modal_ind_icon.attr('class','command-mode_icon').attr('title','Command Mode'); |
|
88 | 88 | |
|
89 | 89 | // Kernel events |
|
90 | 90 | $([IPython.events]).on('status_idle.Kernel',function () { |
|
91 | 91 | IPython.save_widget.update_document_title(); |
|
92 | 92 | $kernel_ind_icon.attr('class','kernel_idle_icon').attr('title','Kernel Idle'); |
|
93 | 93 | }); |
|
94 | 94 | |
|
95 | 95 | $([IPython.events]).on('status_busy.Kernel',function () { |
|
96 | 96 | window.document.title='(Busy) '+window.document.title; |
|
97 | 97 | $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy'); |
|
98 | 98 | }); |
|
99 | 99 | |
|
100 | 100 | $([IPython.events]).on('status_restarting.Kernel',function () { |
|
101 | 101 | IPython.save_widget.update_document_title(); |
|
102 | 102 | knw.set_message("Restarting kernel", 2000); |
|
103 | 103 | }); |
|
104 | 104 | |
|
105 | 105 | $([IPython.events]).on('status_interrupting.Kernel',function () { |
|
106 | 106 | knw.set_message("Interrupting kernel", 2000); |
|
107 | 107 | }); |
|
108 | 108 | |
|
109 | 109 | // Start the kernel indicator in the busy state, and send a kernel_info request. |
|
110 | 110 | // When the kernel_info reply arrives, the kernel is idle. |
|
111 | 111 | $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy'); |
|
112 | 112 | |
|
113 | 113 | $([IPython.events]).on('status_started.Kernel', function (evt, data) { |
|
114 | 114 | data.kernel.kernel_info(function () { |
|
115 | 115 | $([IPython.events]).trigger('status_idle.Kernel'); |
|
116 | 116 | }); |
|
117 | 117 | }); |
|
118 | 118 | |
|
119 | 119 | $([IPython.events]).on('status_dead.Kernel',function () { |
|
120 | 120 | var msg = 'The kernel has died, and the automatic restart has failed.' + |
|
121 | 121 | ' It is possible the kernel cannot be restarted.' + |
|
122 | 122 | ' If you are not able to restart the kernel, you will still be able to save' + |
|
123 | 123 | ' the notebook, but running code will no longer work until the notebook' + |
|
124 | 124 | ' is reopened.'; |
|
125 | 125 | |
|
126 | 126 | IPython.dialog.modal({ |
|
127 | 127 | title: "Dead kernel", |
|
128 | 128 | body : msg, |
|
129 | 129 | buttons : { |
|
130 | 130 | "Manual Restart": { |
|
131 | 131 | class: "btn-danger", |
|
132 | 132 | click: function () { |
|
133 | 133 | $([IPython.events]).trigger('status_restarting.Kernel'); |
|
134 | 134 | IPython.notebook.start_kernel(); |
|
135 | 135 | } |
|
136 | 136 | }, |
|
137 | 137 | "Don't restart": {} |
|
138 | 138 | } |
|
139 | 139 | }); |
|
140 | 140 | }); |
|
141 | 141 | |
|
142 | 142 | $([IPython.events]).on('websocket_closed.Kernel', function (event, data) { |
|
143 | 143 | var kernel = data.kernel; |
|
144 | 144 | var ws_url = data.ws_url; |
|
145 | 145 | var early = data.early; |
|
146 | 146 | var msg; |
|
147 | 147 | if (!early) { |
|
148 | 148 | knw.set_message('Reconnecting WebSockets', 1000); |
|
149 | 149 | setTimeout(function () { |
|
150 | 150 | kernel.start_channels(); |
|
151 | 151 | }, 5000); |
|
152 | 152 | return; |
|
153 | 153 | } |
|
154 | 154 | console.log('WebSocket connection failed: ', ws_url); |
|
155 | 155 | msg = "A WebSocket connection could not be established." + |
|
156 | 156 | " You will NOT be able to run code. Check your" + |
|
157 | 157 | " network connection or notebook server configuration."; |
|
158 | 158 | IPython.dialog.modal({ |
|
159 | 159 | title: "WebSocket connection failed", |
|
160 | 160 | body: msg, |
|
161 | 161 | buttons : { |
|
162 | 162 | "OK": {}, |
|
163 | 163 | "Reconnect": { |
|
164 | 164 | click: function () { |
|
165 | 165 | knw.set_message('Reconnecting WebSockets', 1000); |
|
166 | 166 | setTimeout(function () { |
|
167 | 167 | kernel.start_channels(); |
|
168 | 168 | }, 5000); |
|
169 | 169 | } |
|
170 | 170 | } |
|
171 | 171 | } |
|
172 | 172 | }); |
|
173 | 173 | }); |
|
174 | 174 | |
|
175 | 175 | |
|
176 | 176 | var nnw = this.new_notification_widget('notebook'); |
|
177 | 177 | |
|
178 | 178 | // Notebook events |
|
179 | 179 | $([IPython.events]).on('notebook_loading.Notebook', function () { |
|
180 | 180 | nnw.set_message("Loading notebook",500); |
|
181 | 181 | }); |
|
182 | 182 | $([IPython.events]).on('notebook_loaded.Notebook', function () { |
|
183 | 183 | nnw.set_message("Notebook loaded",500); |
|
184 | 184 | }); |
|
185 | 185 | $([IPython.events]).on('notebook_saving.Notebook', function () { |
|
186 | 186 | nnw.set_message("Saving notebook",500); |
|
187 | 187 | }); |
|
188 | 188 | $([IPython.events]).on('notebook_saved.Notebook', function () { |
|
189 | 189 | nnw.set_message("Notebook saved",2000); |
|
190 | 190 | }); |
|
191 | $([IPython.events]).on('notebook_save_failed.Notebook', function () { | |
|
192 | nnw.set_message("Notebook save failed"); | |
|
191 | $([IPython.events]).on('notebook_save_failed.Notebook', function (evt, xhr, status, data) { | |
|
192 | nnw.set_message(data || "Notebook save failed"); | |
|
193 | 193 | }); |
|
194 | 194 | |
|
195 | 195 | // Checkpoint events |
|
196 | 196 | $([IPython.events]).on('checkpoint_created.Notebook', function (evt, data) { |
|
197 | 197 | var msg = "Checkpoint created"; |
|
198 | 198 | if (data.last_modified) { |
|
199 | 199 | var d = new Date(data.last_modified); |
|
200 | 200 | msg = msg + ": " + d.format("HH:MM:ss"); |
|
201 | 201 | } |
|
202 | 202 | nnw.set_message(msg, 2000); |
|
203 | 203 | }); |
|
204 | 204 | $([IPython.events]).on('checkpoint_failed.Notebook', function () { |
|
205 | 205 | nnw.set_message("Checkpoint failed"); |
|
206 | 206 | }); |
|
207 | 207 | $([IPython.events]).on('checkpoint_deleted.Notebook', function () { |
|
208 | 208 | nnw.set_message("Checkpoint deleted", 500); |
|
209 | 209 | }); |
|
210 | 210 | $([IPython.events]).on('checkpoint_delete_failed.Notebook', function () { |
|
211 | 211 | nnw.set_message("Checkpoint delete failed"); |
|
212 | 212 | }); |
|
213 | 213 | $([IPython.events]).on('checkpoint_restoring.Notebook', function () { |
|
214 | 214 | nnw.set_message("Restoring to checkpoint...", 500); |
|
215 | 215 | }); |
|
216 | 216 | $([IPython.events]).on('checkpoint_restore_failed.Notebook', function () { |
|
217 | 217 | nnw.set_message("Checkpoint restore failed"); |
|
218 | 218 | }); |
|
219 | 219 | |
|
220 | 220 | // Autosave events |
|
221 | 221 | $([IPython.events]).on('autosave_disabled.Notebook', function () { |
|
222 | 222 | nnw.set_message("Autosave disabled", 2000); |
|
223 | 223 | }); |
|
224 | 224 | $([IPython.events]).on('autosave_enabled.Notebook', function (evt, interval) { |
|
225 | 225 | nnw.set_message("Saving every " + interval / 1000 + "s", 1000); |
|
226 | 226 | }); |
|
227 | 227 | |
|
228 | 228 | }; |
|
229 | 229 | |
|
230 | 230 | IPython.NotificationArea = NotificationArea; |
|
231 | 231 | |
|
232 | 232 | return IPython; |
|
233 | 233 | |
|
234 | 234 | }(IPython)); |
|
235 | 235 |
@@ -1,874 +1,878 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.trusted = true; |
|
35 | 35 | this.clear_queued = null; |
|
36 | 36 | if (prompt_area === undefined) { |
|
37 | 37 | this.prompt_area = true; |
|
38 | 38 | } else { |
|
39 | 39 | this.prompt_area = prompt_area; |
|
40 | 40 | } |
|
41 | 41 | this.create_elements(); |
|
42 | 42 | this.style(); |
|
43 | 43 | this.bind_events(); |
|
44 | 44 | }; |
|
45 | 45 | |
|
46 | 46 | |
|
47 | 47 | /** |
|
48 | 48 | * Class prototypes |
|
49 | 49 | **/ |
|
50 | 50 | |
|
51 | 51 | OutputArea.prototype.create_elements = function () { |
|
52 | 52 | this.element = $("<div/>"); |
|
53 | 53 | this.collapse_button = $("<div/>"); |
|
54 | 54 | this.prompt_overlay = $("<div/>"); |
|
55 | 55 | this.wrapper.append(this.prompt_overlay); |
|
56 | 56 | this.wrapper.append(this.element); |
|
57 | 57 | this.wrapper.append(this.collapse_button); |
|
58 | 58 | }; |
|
59 | 59 | |
|
60 | 60 | |
|
61 | 61 | OutputArea.prototype.style = function () { |
|
62 | 62 | this.collapse_button.hide(); |
|
63 | 63 | this.prompt_overlay.hide(); |
|
64 | 64 | |
|
65 | 65 | this.wrapper.addClass('output_wrapper'); |
|
66 | 66 | this.element.addClass('output'); |
|
67 | 67 | |
|
68 | 68 | this.collapse_button.addClass("btn output_collapsed"); |
|
69 | 69 | this.collapse_button.attr('title', 'click to expand output'); |
|
70 | 70 | this.collapse_button.text('. . .'); |
|
71 | 71 | |
|
72 | 72 | this.prompt_overlay.addClass('out_prompt_overlay prompt'); |
|
73 | 73 | this.prompt_overlay.attr('title', 'click to expand output; double click to hide output'); |
|
74 | 74 | |
|
75 | 75 | this.collapse(); |
|
76 | 76 | }; |
|
77 | 77 | |
|
78 | 78 | /** |
|
79 | 79 | * Should the OutputArea scroll? |
|
80 | 80 | * Returns whether the height (in lines) exceeds a threshold. |
|
81 | 81 | * |
|
82 | 82 | * @private |
|
83 | 83 | * @method _should_scroll |
|
84 | 84 | * @param [lines=100]{Integer} |
|
85 | 85 | * @return {Bool} |
|
86 | 86 | * |
|
87 | 87 | */ |
|
88 | 88 | OutputArea.prototype._should_scroll = function (lines) { |
|
89 | 89 | if (lines <=0 ){ return } |
|
90 | 90 | if (!lines) { |
|
91 | 91 | lines = 100; |
|
92 | 92 | } |
|
93 | 93 | // line-height from http://stackoverflow.com/questions/1185151 |
|
94 | 94 | var fontSize = this.element.css('font-size'); |
|
95 | 95 | var lineHeight = Math.floor(parseInt(fontSize.replace('px','')) * 1.5); |
|
96 | 96 | |
|
97 | 97 | return (this.element.height() > lines * lineHeight); |
|
98 | 98 | }; |
|
99 | 99 | |
|
100 | 100 | |
|
101 | 101 | OutputArea.prototype.bind_events = function () { |
|
102 | 102 | var that = this; |
|
103 | 103 | this.prompt_overlay.dblclick(function () { that.toggle_output(); }); |
|
104 | 104 | this.prompt_overlay.click(function () { that.toggle_scroll(); }); |
|
105 | 105 | |
|
106 | 106 | this.element.resize(function () { |
|
107 | 107 | // FIXME: Firefox on Linux misbehaves, so automatic scrolling is disabled |
|
108 | 108 | if ( IPython.utils.browser[0] === "Firefox" ) { |
|
109 | 109 | return; |
|
110 | 110 | } |
|
111 | 111 | // maybe scroll output, |
|
112 | 112 | // if it's grown large enough and hasn't already been scrolled. |
|
113 | 113 | if ( !that.scrolled && that._should_scroll(OutputArea.auto_scroll_threshold)) { |
|
114 | 114 | that.scroll_area(); |
|
115 | 115 | } |
|
116 | 116 | }); |
|
117 | 117 | this.collapse_button.click(function () { |
|
118 | 118 | that.expand(); |
|
119 | 119 | }); |
|
120 | 120 | }; |
|
121 | 121 | |
|
122 | 122 | |
|
123 | 123 | OutputArea.prototype.collapse = function () { |
|
124 | 124 | if (!this.collapsed) { |
|
125 | 125 | this.element.hide(); |
|
126 | 126 | this.prompt_overlay.hide(); |
|
127 | 127 | if (this.element.html()){ |
|
128 | 128 | this.collapse_button.show(); |
|
129 | 129 | } |
|
130 | 130 | this.collapsed = true; |
|
131 | 131 | } |
|
132 | 132 | }; |
|
133 | 133 | |
|
134 | 134 | |
|
135 | 135 | OutputArea.prototype.expand = function () { |
|
136 | 136 | if (this.collapsed) { |
|
137 | 137 | this.collapse_button.hide(); |
|
138 | 138 | this.element.show(); |
|
139 | 139 | this.prompt_overlay.show(); |
|
140 | 140 | this.collapsed = false; |
|
141 | 141 | } |
|
142 | 142 | }; |
|
143 | 143 | |
|
144 | 144 | |
|
145 | 145 | OutputArea.prototype.toggle_output = function () { |
|
146 | 146 | if (this.collapsed) { |
|
147 | 147 | this.expand(); |
|
148 | 148 | } else { |
|
149 | 149 | this.collapse(); |
|
150 | 150 | } |
|
151 | 151 | }; |
|
152 | 152 | |
|
153 | 153 | |
|
154 | 154 | OutputArea.prototype.scroll_area = function () { |
|
155 | 155 | this.element.addClass('output_scroll'); |
|
156 | 156 | this.prompt_overlay.attr('title', 'click to unscroll output; double click to hide'); |
|
157 | 157 | this.scrolled = true; |
|
158 | 158 | }; |
|
159 | 159 | |
|
160 | 160 | |
|
161 | 161 | OutputArea.prototype.unscroll_area = function () { |
|
162 | 162 | this.element.removeClass('output_scroll'); |
|
163 | 163 | this.prompt_overlay.attr('title', 'click to scroll output; double click to hide'); |
|
164 | 164 | this.scrolled = false; |
|
165 | 165 | }; |
|
166 | 166 | |
|
167 | 167 | /** |
|
168 | 168 | * |
|
169 | 169 | * Scroll OutputArea if height supperior than a threshold (in lines). |
|
170 | 170 | * |
|
171 | 171 | * Threshold is a maximum number of lines. If unspecified, defaults to |
|
172 | 172 | * OutputArea.minimum_scroll_threshold. |
|
173 | 173 | * |
|
174 | 174 | * Negative threshold will prevent the OutputArea from ever scrolling. |
|
175 | 175 | * |
|
176 | 176 | * @method scroll_if_long |
|
177 | 177 | * |
|
178 | 178 | * @param [lines=20]{Number} Default to 20 if not set, |
|
179 | 179 | * behavior undefined for value of `0`. |
|
180 | 180 | * |
|
181 | 181 | **/ |
|
182 | 182 | OutputArea.prototype.scroll_if_long = function (lines) { |
|
183 | 183 | var n = lines | OutputArea.minimum_scroll_threshold; |
|
184 | 184 | if(n <= 0){ |
|
185 | 185 | return |
|
186 | 186 | } |
|
187 | 187 | |
|
188 | 188 | if (this._should_scroll(n)) { |
|
189 | 189 | // only allow scrolling long-enough output |
|
190 | 190 | this.scroll_area(); |
|
191 | 191 | } |
|
192 | 192 | }; |
|
193 | 193 | |
|
194 | 194 | |
|
195 | 195 | OutputArea.prototype.toggle_scroll = function () { |
|
196 | 196 | if (this.scrolled) { |
|
197 | 197 | this.unscroll_area(); |
|
198 | 198 | } else { |
|
199 | 199 | // only allow scrolling long-enough output |
|
200 | 200 | this.scroll_if_long(); |
|
201 | 201 | } |
|
202 | 202 | }; |
|
203 | 203 | |
|
204 | 204 | |
|
205 | 205 | // typeset with MathJax if MathJax is available |
|
206 | 206 | OutputArea.prototype.typeset = function () { |
|
207 | 207 | if (window.MathJax){ |
|
208 | 208 | MathJax.Hub.Queue(["Typeset",MathJax.Hub]); |
|
209 | 209 | } |
|
210 | 210 | }; |
|
211 | 211 | |
|
212 | 212 | |
|
213 | 213 | OutputArea.prototype.handle_output = function (msg) { |
|
214 | 214 | var json = {}; |
|
215 | 215 | var msg_type = json.output_type = msg.header.msg_type; |
|
216 | 216 | var content = msg.content; |
|
217 | 217 | if (msg_type === "stream") { |
|
218 | 218 | json.text = content.data; |
|
219 | 219 | json.stream = content.name; |
|
220 | 220 | } else if (msg_type === "display_data") { |
|
221 | 221 | json = content.data; |
|
222 | 222 | json.output_type = msg_type; |
|
223 | 223 | json.metadata = content.metadata; |
|
224 | 224 | } else if (msg_type === "pyout") { |
|
225 | 225 | json = content.data; |
|
226 | 226 | json.output_type = msg_type; |
|
227 | 227 | json.metadata = content.metadata; |
|
228 | 228 | json.prompt_number = content.execution_count; |
|
229 | 229 | } else if (msg_type === "pyerr") { |
|
230 | 230 | json.ename = content.ename; |
|
231 | 231 | json.evalue = content.evalue; |
|
232 | 232 | json.traceback = content.traceback; |
|
233 | 233 | } |
|
234 | 234 | this.append_output(json); |
|
235 | 235 | }; |
|
236 | 236 | |
|
237 | 237 | |
|
238 | 238 | OutputArea.prototype.rename_keys = function (data, key_map) { |
|
239 | 239 | var remapped = {}; |
|
240 | 240 | for (var key in data) { |
|
241 | 241 | var new_key = key_map[key] || key; |
|
242 | 242 | remapped[new_key] = data[key]; |
|
243 | 243 | } |
|
244 | 244 | return remapped; |
|
245 | 245 | }; |
|
246 | 246 | |
|
247 | 247 | |
|
248 | 248 | OutputArea.output_types = [ |
|
249 | 249 | 'application/javascript', |
|
250 | 250 | 'text/html', |
|
251 | 251 | 'text/latex', |
|
252 | 252 | 'image/svg+xml', |
|
253 | 253 | 'image/png', |
|
254 | 254 | 'image/jpeg', |
|
255 | 255 | 'application/pdf', |
|
256 | 256 | 'text/plain' |
|
257 | 257 | ]; |
|
258 | 258 | |
|
259 | 259 | OutputArea.prototype.validate_output = function (json) { |
|
260 | 260 | // scrub invalid outputs |
|
261 | 261 | // TODO: right now everything is a string, but JSON really shouldn't be. |
|
262 | 262 | // nbformat 4 will fix that. |
|
263 | 263 | $.map(OutputArea.output_types, function(key){ |
|
264 | 264 | if (json[key] !== undefined && typeof json[key] !== 'string') { |
|
265 | 265 | console.log("Invalid type for " + key, json[key]); |
|
266 | 266 | delete json[key]; |
|
267 | 267 | } |
|
268 | 268 | }); |
|
269 | 269 | return json; |
|
270 | 270 | }; |
|
271 | 271 | |
|
272 | 272 | OutputArea.prototype.append_output = function (json) { |
|
273 | 273 | this.expand(); |
|
274 | 274 | // Clear the output if clear is queued. |
|
275 | 275 | var needs_height_reset = false; |
|
276 | 276 | if (this.clear_queued) { |
|
277 | 277 | this.clear_output(false); |
|
278 | 278 | needs_height_reset = true; |
|
279 | 279 | } |
|
280 | 280 | |
|
281 | 281 | // validate output data types |
|
282 | 282 | json = this.validate_output(json); |
|
283 | 283 | |
|
284 | 284 | if (json.output_type === 'pyout') { |
|
285 | 285 | this.append_pyout(json); |
|
286 | 286 | } else if (json.output_type === 'pyerr') { |
|
287 | 287 | this.append_pyerr(json); |
|
288 | 288 | } else if (json.output_type === 'display_data') { |
|
289 | 289 | this.append_display_data(json); |
|
290 | 290 | } else if (json.output_type === 'stream') { |
|
291 | 291 | this.append_stream(json); |
|
292 | 292 | } |
|
293 | 293 | |
|
294 | 294 | this.outputs.push(json); |
|
295 | 295 | |
|
296 | 296 | // Only reset the height to automatic if the height is currently |
|
297 | 297 | // fixed (done by wait=True flag on clear_output). |
|
298 | 298 | if (needs_height_reset) { |
|
299 | 299 | this.element.height(''); |
|
300 | 300 | } |
|
301 | 301 | |
|
302 | 302 | var that = this; |
|
303 | 303 | setTimeout(function(){that.element.trigger('resize');}, 100); |
|
304 | 304 | }; |
|
305 | 305 | |
|
306 | 306 | |
|
307 | 307 | OutputArea.prototype.create_output_area = function () { |
|
308 | 308 | var oa = $("<div/>").addClass("output_area"); |
|
309 | 309 | if (this.prompt_area) { |
|
310 | 310 | oa.append($('<div/>').addClass('prompt')); |
|
311 | 311 | } |
|
312 | 312 | return oa; |
|
313 | 313 | }; |
|
314 | 314 | |
|
315 | 315 | |
|
316 | 316 | function _get_metadata_key(metadata, key, mime) { |
|
317 | 317 | var mime_md = metadata[mime]; |
|
318 | 318 | // mime-specific higher priority |
|
319 | 319 | if (mime_md && mime_md[key] !== undefined) { |
|
320 | 320 | return mime_md[key]; |
|
321 | 321 | } |
|
322 | 322 | // fallback on global |
|
323 | 323 | return metadata[key]; |
|
324 | 324 | } |
|
325 | 325 | |
|
326 | 326 | OutputArea.prototype.create_output_subarea = function(md, classes, mime) { |
|
327 | 327 | var subarea = $('<div/>').addClass('output_subarea').addClass(classes); |
|
328 | 328 | if (_get_metadata_key(md, 'isolated', mime)) { |
|
329 | 329 | // Create an iframe to isolate the subarea from the rest of the |
|
330 | 330 | // document |
|
331 | 331 | var iframe = $('<iframe/>').addClass('box-flex1'); |
|
332 | 332 | iframe.css({'height':1, 'width':'100%', 'display':'block'}); |
|
333 | 333 | iframe.attr('frameborder', 0); |
|
334 | 334 | iframe.attr('scrolling', 'auto'); |
|
335 | 335 | |
|
336 | 336 | // Once the iframe is loaded, the subarea is dynamically inserted |
|
337 | 337 | iframe.on('load', function() { |
|
338 | 338 | // Workaround needed by Firefox, to properly render svg inside |
|
339 | 339 | // iframes, see http://stackoverflow.com/questions/10177190/ |
|
340 | 340 | // svg-dynamically-added-to-iframe-does-not-render-correctly |
|
341 | 341 | this.contentDocument.open(); |
|
342 | 342 | |
|
343 | 343 | // Insert the subarea into the iframe |
|
344 | 344 | // We must directly write the html. When using Jquery's append |
|
345 | 345 | // method, javascript is evaluated in the parent document and |
|
346 | 346 | // not in the iframe document. At this point, subarea doesn't |
|
347 | 347 | // contain any user content. |
|
348 | 348 | this.contentDocument.write(subarea.html()); |
|
349 | 349 | |
|
350 | 350 | this.contentDocument.close(); |
|
351 | 351 | |
|
352 | 352 | var body = this.contentDocument.body; |
|
353 | 353 | // Adjust the iframe height automatically |
|
354 | 354 | iframe.height(body.scrollHeight + 'px'); |
|
355 | 355 | }); |
|
356 | 356 | |
|
357 | 357 | // Elements should be appended to the inner subarea and not to the |
|
358 | 358 | // iframe |
|
359 | 359 | iframe.append = function(that) { |
|
360 | 360 | subarea.append(that); |
|
361 | 361 | }; |
|
362 | 362 | |
|
363 | 363 | return iframe; |
|
364 | 364 | } else { |
|
365 | 365 | return subarea; |
|
366 | 366 | } |
|
367 | 367 | } |
|
368 | 368 | |
|
369 | 369 | |
|
370 | 370 | OutputArea.prototype._append_javascript_error = function (err, element) { |
|
371 | 371 | // display a message when a javascript error occurs in display output |
|
372 | 372 | var msg = "Javascript error adding output!" |
|
373 | 373 | if ( element === undefined ) return; |
|
374 | 374 | element |
|
375 | 375 | .append($('<div/>').text(msg).addClass('js-error')) |
|
376 | 376 | .append($('<div/>').text(err.toString()).addClass('js-error')) |
|
377 | 377 | .append($('<div/>').text('See your browser Javascript console for more details.').addClass('js-error')); |
|
378 | 378 | }; |
|
379 | 379 | |
|
380 | 380 | OutputArea.prototype._safe_append = function (toinsert) { |
|
381 | 381 | // safely append an item to the document |
|
382 | 382 | // this is an object created by user code, |
|
383 | 383 | // and may have errors, which should not be raised |
|
384 | 384 | // under any circumstances. |
|
385 | 385 | try { |
|
386 | 386 | this.element.append(toinsert); |
|
387 | 387 | } catch(err) { |
|
388 | 388 | console.log(err); |
|
389 | 389 | // Create an actual output_area and output_subarea, which creates |
|
390 | 390 | // the prompt area and the proper indentation. |
|
391 | 391 | var toinsert = this.create_output_area(); |
|
392 | 392 | var subarea = $('<div/>').addClass('output_subarea'); |
|
393 | 393 | toinsert.append(subarea); |
|
394 | 394 | this._append_javascript_error(err, subarea); |
|
395 | 395 | this.element.append(toinsert); |
|
396 | 396 | } |
|
397 | 397 | }; |
|
398 | 398 | |
|
399 | 399 | |
|
400 | 400 | OutputArea.prototype.append_pyout = function (json) { |
|
401 | 401 | var n = json.prompt_number || ' '; |
|
402 | 402 | var toinsert = this.create_output_area(); |
|
403 | 403 | if (this.prompt_area) { |
|
404 | 404 | toinsert.find('div.prompt').addClass('output_prompt').text('Out[' + n + ']:'); |
|
405 | 405 | } |
|
406 | 406 | var inserted = this.append_mime_type(json, toinsert); |
|
407 | 407 | if (inserted) { |
|
408 | 408 | inserted.addClass('output_pyout'); |
|
409 | 409 | } |
|
410 | 410 | this._safe_append(toinsert); |
|
411 | 411 | // If we just output latex, typeset it. |
|
412 | 412 | if ((json['text/latex'] !== undefined) || (json['text/html'] !== undefined)) { |
|
413 | 413 | this.typeset(); |
|
414 | 414 | } |
|
415 | 415 | }; |
|
416 | 416 | |
|
417 | 417 | |
|
418 | 418 | OutputArea.prototype.append_pyerr = function (json) { |
|
419 | 419 | var tb = json.traceback; |
|
420 | 420 | if (tb !== undefined && tb.length > 0) { |
|
421 | 421 | var s = ''; |
|
422 | 422 | var len = tb.length; |
|
423 | 423 | for (var i=0; i<len; i++) { |
|
424 | 424 | s = s + tb[i] + '\n'; |
|
425 | 425 | } |
|
426 | 426 | s = s + '\n'; |
|
427 | 427 | var toinsert = this.create_output_area(); |
|
428 | 428 | var append_text = OutputArea.append_map['text/plain']; |
|
429 | 429 | if (append_text) { |
|
430 | 430 | append_text.apply(this, [s, {}, toinsert]).addClass('output_pyerr'); |
|
431 | 431 | } |
|
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 | // The only user content injected with this HTML call is |
|
456 | 456 | // escaped by the fixConsole() method. |
|
457 | 457 | pre.html(html); |
|
458 | 458 | return; |
|
459 | 459 | } |
|
460 | 460 | } |
|
461 | 461 | |
|
462 | 462 | if (!text.replace("\r", "")) { |
|
463 | 463 | // text is nothing (empty string, \r, etc.) |
|
464 | 464 | // so don't append any elements, which might add undesirable space |
|
465 | 465 | return; |
|
466 | 466 | } |
|
467 | 467 | |
|
468 | 468 | // If we got here, attach a new div |
|
469 | 469 | var toinsert = this.create_output_area(); |
|
470 | 470 | var append_text = OutputArea.append_map['text/plain']; |
|
471 | 471 | if (append_text) { |
|
472 | 472 | append_text.apply(this, [text, {}, toinsert]).addClass("output_stream " + subclass); |
|
473 | 473 | } |
|
474 | 474 | this._safe_append(toinsert); |
|
475 | 475 | }; |
|
476 | 476 | |
|
477 | 477 | |
|
478 | 478 | OutputArea.prototype.append_display_data = function (json) { |
|
479 | 479 | var toinsert = this.create_output_area(); |
|
480 | 480 | if (this.append_mime_type(json, toinsert)) { |
|
481 | 481 | this._safe_append(toinsert); |
|
482 | 482 | // If we just output latex, typeset it. |
|
483 | 483 | if ((json['text/latex'] !== undefined) || (json['text/html'] !== undefined)) { |
|
484 | 484 | this.typeset(); |
|
485 | 485 | } |
|
486 | 486 | } |
|
487 | 487 | }; |
|
488 | 488 | |
|
489 | 489 | |
|
490 | 490 | OutputArea.safe_outputs = { |
|
491 | 491 | 'text/plain' : true, |
|
492 | 492 | 'text/latex' : true, |
|
493 | 493 | 'image/png' : true, |
|
494 | 494 | 'image/jpeg' : true |
|
495 | 495 | }; |
|
496 | 496 | |
|
497 | 497 | OutputArea.prototype.append_mime_type = function (json, element) { |
|
498 | 498 | for (var type_i in OutputArea.display_order) { |
|
499 | 499 | var type = OutputArea.display_order[type_i]; |
|
500 | 500 | var append = OutputArea.append_map[type]; |
|
501 | 501 | if ((json[type] !== undefined) && append) { |
|
502 | 502 | var value = json[type]; |
|
503 | 503 | if (!this.trusted && !OutputArea.safe_outputs[type]) { |
|
504 | 504 | // not trusted, sanitize HTML |
|
505 | 505 | if (type==='text/html' || type==='text/svg') { |
|
506 | 506 | value = IPython.security.sanitize_html(value); |
|
507 | 507 | } else { |
|
508 | 508 | // don't display if we don't know how to sanitize it |
|
509 | 509 | console.log("Ignoring untrusted " + type + " output."); |
|
510 | 510 | continue; |
|
511 | 511 | } |
|
512 | 512 | } |
|
513 | 513 | var md = json.metadata || {}; |
|
514 | 514 | var toinsert = append.apply(this, [value, md, element]); |
|
515 | 515 | $([IPython.events]).trigger('output_appended.OutputArea', [type, value, md, toinsert]); |
|
516 | 516 | return toinsert; |
|
517 | 517 | } |
|
518 | 518 | } |
|
519 | 519 | return null; |
|
520 | 520 | }; |
|
521 | 521 | |
|
522 | 522 | |
|
523 | 523 | var append_html = function (html, md, element) { |
|
524 | 524 | var type = 'text/html'; |
|
525 | 525 | var toinsert = this.create_output_subarea(md, "output_html rendered_html", type); |
|
526 | 526 | IPython.keyboard_manager.register_events(toinsert); |
|
527 | 527 | toinsert.append(html); |
|
528 | 528 | element.append(toinsert); |
|
529 | 529 | return toinsert; |
|
530 | 530 | }; |
|
531 | 531 | |
|
532 | 532 | |
|
533 | 533 | var append_javascript = function (js, md, element) { |
|
534 | 534 | // We just eval the JS code, element appears in the local scope. |
|
535 | 535 | var type = 'application/javascript'; |
|
536 | 536 | var toinsert = this.create_output_subarea(md, "output_javascript", type); |
|
537 | 537 | IPython.keyboard_manager.register_events(toinsert); |
|
538 | 538 | element.append(toinsert); |
|
539 | 539 | // FIXME TODO : remove `container element for 3.0` |
|
540 | 540 | //backward compat, js should be eval'ed in a context where `container` is defined. |
|
541 | 541 | var container = element; |
|
542 | 542 | container.show = function(){console.log('Warning "container.show()" is deprecated.')}; |
|
543 | 543 | // end backward compat |
|
544 | ||
|
545 | // Fix for ipython/issues/5293, make sure `element` is the area which | |
|
546 | // output can be inserted into at the time of JS execution. | |
|
547 | element = toinsert; | |
|
544 | 548 | try { |
|
545 | 549 | eval(js); |
|
546 | 550 | } catch(err) { |
|
547 | 551 | console.log(err); |
|
548 | 552 | this._append_javascript_error(err, toinsert); |
|
549 | 553 | } |
|
550 | 554 | return toinsert; |
|
551 | 555 | }; |
|
552 | 556 | |
|
553 | 557 | |
|
554 | 558 | var append_text = function (data, md, element) { |
|
555 | 559 | var type = 'text/plain'; |
|
556 | 560 | var toinsert = this.create_output_subarea(md, "output_text", type); |
|
557 | 561 | // escape ANSI & HTML specials in plaintext: |
|
558 | 562 | data = utils.fixConsole(data); |
|
559 | 563 | data = utils.fixCarriageReturn(data); |
|
560 | 564 | data = utils.autoLinkUrls(data); |
|
561 | 565 | // The only user content injected with this HTML call is |
|
562 | 566 | // escaped by the fixConsole() method. |
|
563 | 567 | toinsert.append($("<pre/>").html(data)); |
|
564 | 568 | element.append(toinsert); |
|
565 | 569 | return toinsert; |
|
566 | 570 | }; |
|
567 | 571 | |
|
568 | 572 | |
|
569 | 573 | var append_svg = function (svg, md, element) { |
|
570 | 574 | var type = 'image/svg+xml'; |
|
571 | 575 | var toinsert = this.create_output_subarea(md, "output_svg", type); |
|
572 | 576 | toinsert.append(svg); |
|
573 | 577 | element.append(toinsert); |
|
574 | 578 | return toinsert; |
|
575 | 579 | }; |
|
576 | 580 | |
|
577 | 581 | |
|
578 | 582 | OutputArea.prototype._dblclick_to_reset_size = function (img) { |
|
579 | 583 | // wrap image after it's loaded on the page, |
|
580 | 584 | // otherwise the measured initial size will be incorrect |
|
581 | 585 | img.on("load", function (){ |
|
582 | 586 | var h0 = img.height(); |
|
583 | 587 | var w0 = img.width(); |
|
584 | 588 | if (!(h0 && w0)) { |
|
585 | 589 | // zero size, don't make it resizable |
|
586 | 590 | return; |
|
587 | 591 | } |
|
588 | 592 | img.resizable({ |
|
589 | 593 | aspectRatio: true, |
|
590 | 594 | autoHide: true |
|
591 | 595 | }); |
|
592 | 596 | img.dblclick(function () { |
|
593 | 597 | // resize wrapper & image together for some reason: |
|
594 | 598 | img.parent().height(h0); |
|
595 | 599 | img.height(h0); |
|
596 | 600 | img.parent().width(w0); |
|
597 | 601 | img.width(w0); |
|
598 | 602 | }); |
|
599 | 603 | }); |
|
600 | 604 | }; |
|
601 | 605 | |
|
602 | 606 | var set_width_height = function (img, md, mime) { |
|
603 | 607 | // set width and height of an img element from metadata |
|
604 | 608 | var height = _get_metadata_key(md, 'height', mime); |
|
605 | 609 | if (height !== undefined) img.attr('height', height); |
|
606 | 610 | var width = _get_metadata_key(md, 'width', mime); |
|
607 | 611 | if (width !== undefined) img.attr('width', width); |
|
608 | 612 | }; |
|
609 | 613 | |
|
610 | 614 | var append_png = function (png, md, element) { |
|
611 | 615 | var type = 'image/png'; |
|
612 | 616 | var toinsert = this.create_output_subarea(md, "output_png", type); |
|
613 | 617 | var img = $("<img/>").attr('src','data:image/png;base64,'+png); |
|
614 | 618 | set_width_height(img, md, 'image/png'); |
|
615 | 619 | this._dblclick_to_reset_size(img); |
|
616 | 620 | toinsert.append(img); |
|
617 | 621 | element.append(toinsert); |
|
618 | 622 | return toinsert; |
|
619 | 623 | }; |
|
620 | 624 | |
|
621 | 625 | |
|
622 | 626 | var append_jpeg = function (jpeg, md, element) { |
|
623 | 627 | var type = 'image/jpeg'; |
|
624 | 628 | var toinsert = this.create_output_subarea(md, "output_jpeg", type); |
|
625 | 629 | var img = $("<img/>").attr('src','data:image/jpeg;base64,'+jpeg); |
|
626 | 630 | set_width_height(img, md, 'image/jpeg'); |
|
627 | 631 | this._dblclick_to_reset_size(img); |
|
628 | 632 | toinsert.append(img); |
|
629 | 633 | element.append(toinsert); |
|
630 | 634 | return toinsert; |
|
631 | 635 | }; |
|
632 | 636 | |
|
633 | 637 | |
|
634 | 638 | var append_pdf = function (pdf, md, element) { |
|
635 | 639 | var type = 'application/pdf'; |
|
636 | 640 | var toinsert = this.create_output_subarea(md, "output_pdf", type); |
|
637 | 641 | var a = $('<a/>').attr('href', 'data:application/pdf;base64,'+pdf); |
|
638 | 642 | a.attr('target', '_blank'); |
|
639 | 643 | a.text('View PDF') |
|
640 | 644 | toinsert.append(a); |
|
641 | 645 | element.append(toinsert); |
|
642 | 646 | return toinsert; |
|
643 | 647 | } |
|
644 | 648 | |
|
645 | 649 | var append_latex = function (latex, md, element) { |
|
646 | 650 | // This method cannot do the typesetting because the latex first has to |
|
647 | 651 | // be on the page. |
|
648 | 652 | var type = 'text/latex'; |
|
649 | 653 | var toinsert = this.create_output_subarea(md, "output_latex", type); |
|
650 | 654 | toinsert.append(latex); |
|
651 | 655 | element.append(toinsert); |
|
652 | 656 | return toinsert; |
|
653 | 657 | }; |
|
654 | 658 | |
|
655 | 659 | |
|
656 | 660 | OutputArea.prototype.append_raw_input = function (msg) { |
|
657 | 661 | var that = this; |
|
658 | 662 | this.expand(); |
|
659 | 663 | var content = msg.content; |
|
660 | 664 | var area = this.create_output_area(); |
|
661 | 665 | |
|
662 | 666 | // disable any other raw_inputs, if they are left around |
|
663 | 667 | $("div.output_subarea.raw_input_container").remove(); |
|
664 | 668 | |
|
665 | 669 | area.append( |
|
666 | 670 | $("<div/>") |
|
667 | 671 | .addClass("box-flex1 output_subarea raw_input_container") |
|
668 | 672 | .append( |
|
669 | 673 | $("<span/>") |
|
670 | 674 | .addClass("raw_input_prompt") |
|
671 | 675 | .text(content.prompt) |
|
672 | 676 | ) |
|
673 | 677 | .append( |
|
674 | 678 | $("<input/>") |
|
675 | 679 | .addClass("raw_input") |
|
676 | 680 | .attr('type', 'text') |
|
677 | 681 | .attr("size", 47) |
|
678 | 682 | .keydown(function (event, ui) { |
|
679 | 683 | // make sure we submit on enter, |
|
680 | 684 | // and don't re-execute the *cell* on shift-enter |
|
681 | 685 | if (event.which === IPython.keyboard.keycodes.enter) { |
|
682 | 686 | that._submit_raw_input(); |
|
683 | 687 | return false; |
|
684 | 688 | } |
|
685 | 689 | }) |
|
686 | 690 | ) |
|
687 | 691 | ); |
|
688 | 692 | |
|
689 | 693 | this.element.append(area); |
|
690 | 694 | var raw_input = area.find('input.raw_input'); |
|
691 | 695 | // Register events that enable/disable the keyboard manager while raw |
|
692 | 696 | // input is focused. |
|
693 | 697 | IPython.keyboard_manager.register_events(raw_input); |
|
694 | 698 | // Note, the following line used to read raw_input.focus().focus(). |
|
695 | 699 | // This seemed to be needed otherwise only the cell would be focused. |
|
696 | 700 | // But with the modal UI, this seems to work fine with one call to focus(). |
|
697 | 701 | raw_input.focus(); |
|
698 | 702 | } |
|
699 | 703 | |
|
700 | 704 | OutputArea.prototype._submit_raw_input = function (evt) { |
|
701 | 705 | var container = this.element.find("div.raw_input_container"); |
|
702 | 706 | var theprompt = container.find("span.raw_input_prompt"); |
|
703 | 707 | var theinput = container.find("input.raw_input"); |
|
704 | 708 | var value = theinput.val(); |
|
705 | 709 | var content = { |
|
706 | 710 | output_type : 'stream', |
|
707 | 711 | name : 'stdout', |
|
708 | 712 | text : theprompt.text() + value + '\n' |
|
709 | 713 | } |
|
710 | 714 | // remove form container |
|
711 | 715 | container.parent().remove(); |
|
712 | 716 | // replace with plaintext version in stdout |
|
713 | 717 | this.append_output(content, false); |
|
714 | 718 | $([IPython.events]).trigger('send_input_reply.Kernel', value); |
|
715 | 719 | } |
|
716 | 720 | |
|
717 | 721 | |
|
718 | 722 | OutputArea.prototype.handle_clear_output = function (msg) { |
|
719 | 723 | // msg spec v4 had stdout, stderr, display keys |
|
720 | 724 | // v4.1 replaced these with just wait |
|
721 | 725 | // The default behavior is the same (stdout=stderr=display=True, wait=False), |
|
722 | 726 | // so v4 messages will still be properly handled, |
|
723 | 727 | // except for the rarely used clearing less than all output. |
|
724 | 728 | this.clear_output(msg.content.wait || false); |
|
725 | 729 | }; |
|
726 | 730 | |
|
727 | 731 | |
|
728 | 732 | OutputArea.prototype.clear_output = function(wait) { |
|
729 | 733 | if (wait) { |
|
730 | 734 | |
|
731 | 735 | // If a clear is queued, clear before adding another to the queue. |
|
732 | 736 | if (this.clear_queued) { |
|
733 | 737 | this.clear_output(false); |
|
734 | 738 | }; |
|
735 | 739 | |
|
736 | 740 | this.clear_queued = true; |
|
737 | 741 | } else { |
|
738 | 742 | |
|
739 | 743 | // Fix the output div's height if the clear_output is waiting for |
|
740 | 744 | // new output (it is being used in an animation). |
|
741 | 745 | if (this.clear_queued) { |
|
742 | 746 | var height = this.element.height(); |
|
743 | 747 | this.element.height(height); |
|
744 | 748 | this.clear_queued = false; |
|
745 | 749 | } |
|
746 | 750 | |
|
747 | 751 | // clear all, no need for logic |
|
748 | 752 | this.element.html(""); |
|
749 | 753 | this.outputs = []; |
|
750 | 754 | this.trusted = true; |
|
751 | 755 | this.unscroll_area(); |
|
752 | 756 | return; |
|
753 | 757 | }; |
|
754 | 758 | }; |
|
755 | 759 | |
|
756 | 760 | |
|
757 | 761 | // JSON serialization |
|
758 | 762 | |
|
759 | 763 | OutputArea.prototype.fromJSON = function (outputs) { |
|
760 | 764 | var len = outputs.length; |
|
761 | 765 | var data; |
|
762 | 766 | |
|
763 | 767 | for (var i=0; i<len; i++) { |
|
764 | 768 | data = outputs[i]; |
|
765 | 769 | var msg_type = data.output_type; |
|
766 | 770 | if (msg_type === "display_data" || msg_type === "pyout") { |
|
767 | 771 | // convert short keys to mime keys |
|
768 | 772 | // TODO: remove mapping of short keys when we update to nbformat 4 |
|
769 | 773 | data = this.rename_keys(data, OutputArea.mime_map_r); |
|
770 | 774 | data.metadata = this.rename_keys(data.metadata, OutputArea.mime_map_r); |
|
771 | 775 | } |
|
772 | 776 | |
|
773 | 777 | this.append_output(data); |
|
774 | 778 | } |
|
775 | 779 | }; |
|
776 | 780 | |
|
777 | 781 | |
|
778 | 782 | OutputArea.prototype.toJSON = function () { |
|
779 | 783 | var outputs = []; |
|
780 | 784 | var len = this.outputs.length; |
|
781 | 785 | var data; |
|
782 | 786 | for (var i=0; i<len; i++) { |
|
783 | 787 | data = this.outputs[i]; |
|
784 | 788 | var msg_type = data.output_type; |
|
785 | 789 | if (msg_type === "display_data" || msg_type === "pyout") { |
|
786 | 790 | // convert mime keys to short keys |
|
787 | 791 | data = this.rename_keys(data, OutputArea.mime_map); |
|
788 | 792 | data.metadata = this.rename_keys(data.metadata, OutputArea.mime_map); |
|
789 | 793 | } |
|
790 | 794 | outputs[i] = data; |
|
791 | 795 | } |
|
792 | 796 | return outputs; |
|
793 | 797 | }; |
|
794 | 798 | |
|
795 | 799 | /** |
|
796 | 800 | * Class properties |
|
797 | 801 | **/ |
|
798 | 802 | |
|
799 | 803 | /** |
|
800 | 804 | * Threshold to trigger autoscroll when the OutputArea is resized, |
|
801 | 805 | * typically when new outputs are added. |
|
802 | 806 | * |
|
803 | 807 | * Behavior is undefined if autoscroll is lower than minimum_scroll_threshold, |
|
804 | 808 | * unless it is < 0, in which case autoscroll will never be triggered |
|
805 | 809 | * |
|
806 | 810 | * @property auto_scroll_threshold |
|
807 | 811 | * @type Number |
|
808 | 812 | * @default 100 |
|
809 | 813 | * |
|
810 | 814 | **/ |
|
811 | 815 | OutputArea.auto_scroll_threshold = 100; |
|
812 | 816 | |
|
813 | 817 | /** |
|
814 | 818 | * Lower limit (in lines) for OutputArea to be made scrollable. OutputAreas |
|
815 | 819 | * shorter than this are never scrolled. |
|
816 | 820 | * |
|
817 | 821 | * @property minimum_scroll_threshold |
|
818 | 822 | * @type Number |
|
819 | 823 | * @default 20 |
|
820 | 824 | * |
|
821 | 825 | **/ |
|
822 | 826 | OutputArea.minimum_scroll_threshold = 20; |
|
823 | 827 | |
|
824 | 828 | |
|
825 | 829 | |
|
826 | 830 | OutputArea.mime_map = { |
|
827 | 831 | "text/plain" : "text", |
|
828 | 832 | "text/html" : "html", |
|
829 | 833 | "image/svg+xml" : "svg", |
|
830 | 834 | "image/png" : "png", |
|
831 | 835 | "image/jpeg" : "jpeg", |
|
832 | 836 | "text/latex" : "latex", |
|
833 | 837 | "application/json" : "json", |
|
834 | 838 | "application/javascript" : "javascript", |
|
835 | 839 | }; |
|
836 | 840 | |
|
837 | 841 | OutputArea.mime_map_r = { |
|
838 | 842 | "text" : "text/plain", |
|
839 | 843 | "html" : "text/html", |
|
840 | 844 | "svg" : "image/svg+xml", |
|
841 | 845 | "png" : "image/png", |
|
842 | 846 | "jpeg" : "image/jpeg", |
|
843 | 847 | "latex" : "text/latex", |
|
844 | 848 | "json" : "application/json", |
|
845 | 849 | "javascript" : "application/javascript", |
|
846 | 850 | }; |
|
847 | 851 | |
|
848 | 852 | OutputArea.display_order = [ |
|
849 | 853 | 'application/javascript', |
|
850 | 854 | 'text/html', |
|
851 | 855 | 'text/latex', |
|
852 | 856 | 'image/svg+xml', |
|
853 | 857 | 'image/png', |
|
854 | 858 | 'image/jpeg', |
|
855 | 859 | 'application/pdf', |
|
856 | 860 | 'text/plain' |
|
857 | 861 | ]; |
|
858 | 862 | |
|
859 | 863 | OutputArea.append_map = { |
|
860 | 864 | "text/plain" : append_text, |
|
861 | 865 | "text/html" : append_html, |
|
862 | 866 | "image/svg+xml" : append_svg, |
|
863 | 867 | "image/png" : append_png, |
|
864 | 868 | "image/jpeg" : append_jpeg, |
|
865 | 869 | "text/latex" : append_latex, |
|
866 | 870 | "application/javascript" : append_javascript, |
|
867 | 871 | "application/pdf" : append_pdf |
|
868 | 872 | }; |
|
869 | 873 | |
|
870 | 874 | IPython.OutputArea = OutputArea; |
|
871 | 875 | |
|
872 | 876 | return IPython; |
|
873 | 877 | |
|
874 | 878 | }(IPython)); |
@@ -1,391 +1,387 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 | // Tooltip |
|
9 | 9 | //============================================================================ |
|
10 | 10 | // |
|
11 | 11 | // you can set the autocall time by setting `IPython.tooltip.time_before_tooltip` in ms |
|
12 | 12 | // |
|
13 | 13 | // you can configure the differents action of pressing tab several times in a row by |
|
14 | 14 | // setting/appending different fonction in the array |
|
15 | 15 | // IPython.tooltip.tabs_functions |
|
16 | 16 | // |
|
17 | 17 | // eg : |
|
18 | 18 | // IPython.tooltip.tabs_functions[4] = function (){console.log('this is the action of the 4th tab pressing')} |
|
19 | 19 | // |
|
20 | 20 | var IPython = (function (IPython) { |
|
21 | 21 | "use strict"; |
|
22 | 22 | |
|
23 | 23 | var utils = IPython.utils; |
|
24 | 24 | |
|
25 | 25 | // tooltip constructor |
|
26 | 26 | var Tooltip = function () { |
|
27 | 27 | var that = this; |
|
28 | 28 | this.time_before_tooltip = 1200; |
|
29 | 29 | |
|
30 | 30 | // handle to html |
|
31 | 31 | this.tooltip = $('#tooltip'); |
|
32 | 32 | this._hidden = true; |
|
33 | 33 | |
|
34 | 34 | // variable for consecutive call |
|
35 | 35 | this._old_cell = null; |
|
36 | 36 | this._old_request = null; |
|
37 | 37 | this._consecutive_counter = 0; |
|
38 | 38 | |
|
39 | 39 | // 'sticky ?' |
|
40 | 40 | this._sticky = false; |
|
41 | 41 | |
|
42 | 42 | // display tooltip if the docstring is empty? |
|
43 | 43 | this._hide_if_no_docstring = false; |
|
44 | 44 | |
|
45 | 45 | // contain the button in the upper right corner |
|
46 | 46 | this.buttons = $('<div/>').addClass('tooltipbuttons'); |
|
47 | 47 | |
|
48 | 48 | // will contain the docstring |
|
49 | 49 | this.text = $('<div/>').addClass('tooltiptext').addClass('smalltooltip'); |
|
50 | 50 | |
|
51 | 51 | // build the buttons menu on the upper right |
|
52 | 52 | // expand the tooltip to see more |
|
53 | 53 | var expandlink = $('<a/>').attr('href', "#").addClass("ui-corner-all") //rounded corner |
|
54 | 54 | .attr('role', "button").attr('id', 'expanbutton').attr('title', 'Grow the tooltip vertically (press tab 2 times)').click(function () { |
|
55 | 55 | that.expand(); |
|
56 | 56 | }).append( |
|
57 | 57 | $('<span/>').text('Expand').addClass('ui-icon').addClass('ui-icon-plus')); |
|
58 | 58 | |
|
59 | 59 | // open in pager |
|
60 | 60 | var morelink = $('<a/>').attr('href', "#").attr('role', "button").addClass('ui-button').attr('title', 'show the current docstring in pager (press tab 4 times)'); |
|
61 | 61 | var morespan = $('<span/>').text('Open in Pager').addClass('ui-icon').addClass('ui-icon-arrowstop-l-n'); |
|
62 | 62 | morelink.append(morespan); |
|
63 | 63 | morelink.click(function () { |
|
64 | 64 | that.showInPager(that._old_cell); |
|
65 | 65 | }); |
|
66 | 66 | |
|
67 | 67 | // close the tooltip |
|
68 | 68 | var closelink = $('<a/>').attr('href', "#").attr('role', "button").addClass('ui-button'); |
|
69 | 69 | var closespan = $('<span/>').text('Close').addClass('ui-icon').addClass('ui-icon-close'); |
|
70 | 70 | closelink.append(closespan); |
|
71 | 71 | closelink.click(function () { |
|
72 | 72 | that.remove_and_cancel_tooltip(true); |
|
73 | 73 | }); |
|
74 | 74 | |
|
75 | 75 | this._clocklink = $('<a/>').attr('href', "#"); |
|
76 | 76 | this._clocklink.attr('role', "button"); |
|
77 | 77 | this._clocklink.addClass('ui-button'); |
|
78 | 78 | this._clocklink.attr('title', 'Tootip is not dismissed while typing for 10 seconds'); |
|
79 | 79 | var clockspan = $('<span/>').text('Close'); |
|
80 | 80 | clockspan.addClass('ui-icon'); |
|
81 | 81 | clockspan.addClass('ui-icon-clock'); |
|
82 | 82 | this._clocklink.append(clockspan); |
|
83 | 83 | this._clocklink.click(function () { |
|
84 | 84 | that.cancel_stick(); |
|
85 | 85 | }); |
|
86 | 86 | |
|
87 | 87 | |
|
88 | 88 | |
|
89 | 89 | |
|
90 | 90 | //construct the tooltip |
|
91 | 91 | // add in the reverse order you want them to appear |
|
92 | 92 | this.buttons.append(closelink); |
|
93 | 93 | this.buttons.append(expandlink); |
|
94 | 94 | this.buttons.append(morelink); |
|
95 | 95 | this.buttons.append(this._clocklink); |
|
96 | 96 | this._clocklink.hide(); |
|
97 | 97 | |
|
98 | 98 | |
|
99 | 99 | // we need a phony element to make the small arrow |
|
100 | 100 | // of the tooltip in css |
|
101 | 101 | // we will move the arrow later |
|
102 | 102 | this.arrow = $('<div/>').addClass('pretooltiparrow'); |
|
103 | 103 | this.tooltip.append(this.buttons); |
|
104 | 104 | this.tooltip.append(this.arrow); |
|
105 | 105 | this.tooltip.append(this.text); |
|
106 | 106 | |
|
107 | 107 | // function that will be called if you press tab 1, 2, 3... times in a row |
|
108 | 108 | this.tabs_functions = [function (cell, text) { |
|
109 | 109 | that._request_tooltip(cell, text); |
|
110 | 110 | }, function () { |
|
111 | 111 | that.expand(); |
|
112 | 112 | }, function () { |
|
113 | 113 | that.stick(); |
|
114 | 114 | }, function (cell) { |
|
115 | 115 | that.cancel_stick(); |
|
116 | 116 | that.showInPager(cell); |
|
117 | 117 | }]; |
|
118 | 118 | // call after all the tabs function above have bee call to clean their effects |
|
119 | 119 | // if necessary |
|
120 | 120 | this.reset_tabs_function = function (cell, text) { |
|
121 | 121 | this._old_cell = (cell) ? cell : null; |
|
122 | 122 | this._old_request = (text) ? text : null; |
|
123 | 123 | this._consecutive_counter = 0; |
|
124 | 124 | }; |
|
125 | 125 | }; |
|
126 | 126 | |
|
127 | 127 | Tooltip.prototype.is_visible = function () { |
|
128 | 128 | return !this._hidden; |
|
129 | 129 | }; |
|
130 | 130 | |
|
131 | 131 | Tooltip.prototype.showInPager = function (cell) { |
|
132 | 132 | // reexecute last call in pager by appending ? to show back in pager |
|
133 | 133 | var that = this; |
|
134 | var empty = function () {}; | |
|
135 | cell.kernel.execute( | |
|
136 | that.name + '?', { | |
|
137 | 'execute_reply': empty, | |
|
138 | 'output': empty, | |
|
139 | 'clear_output': empty, | |
|
140 | 'cell': cell | |
|
141 | }, { | |
|
142 | 'silent': false, | |
|
143 | 'store_history': true | |
|
144 | }); | |
|
134 | var callbacks = {'shell' : { | |
|
135 | 'payload' : { | |
|
136 | 'page' : $.proxy(cell._open_with_pager, cell) | |
|
137 | } | |
|
138 | } | |
|
139 | }; | |
|
140 | cell.kernel.execute(that.name + '?', callbacks, {'silent': false, 'store_history': true}); | |
|
145 | 141 | this.remove_and_cancel_tooltip(); |
|
146 | 142 | }; |
|
147 | 143 | |
|
148 | 144 | // grow the tooltip verticaly |
|
149 | 145 | Tooltip.prototype.expand = function () { |
|
150 | 146 | this.text.removeClass('smalltooltip'); |
|
151 | 147 | this.text.addClass('bigtooltip'); |
|
152 | 148 | $('#expanbutton').hide('slow'); |
|
153 | 149 | }; |
|
154 | 150 | |
|
155 | 151 | // deal with all the logic of hiding the tooltip |
|
156 | 152 | // and reset it's status |
|
157 | 153 | Tooltip.prototype._hide = function () { |
|
158 | 154 | this._hidden = true; |
|
159 | 155 | this.tooltip.fadeOut('fast'); |
|
160 | 156 | $('#expanbutton').show('slow'); |
|
161 | 157 | this.text.removeClass('bigtooltip'); |
|
162 | 158 | this.text.addClass('smalltooltip'); |
|
163 | 159 | // keep scroll top to be sure to always see the first line |
|
164 | 160 | this.text.scrollTop(0); |
|
165 | 161 | this.code_mirror = null; |
|
166 | 162 | }; |
|
167 | 163 | |
|
168 | 164 | // return true on successfully removing a visible tooltip; otherwise return |
|
169 | 165 | // false. |
|
170 | 166 | Tooltip.prototype.remove_and_cancel_tooltip = function (force) { |
|
171 | 167 | // note that we don't handle closing directly inside the calltip |
|
172 | 168 | // as in the completer, because it is not focusable, so won't |
|
173 | 169 | // get the event. |
|
174 | 170 | this.cancel_pending(); |
|
175 | 171 | if (!this._hidden) { |
|
176 | 172 | if (force || !this._sticky) { |
|
177 | 173 | this.cancel_stick(); |
|
178 | 174 | this._hide(); |
|
179 | 175 | } |
|
180 | 176 | this.reset_tabs_function(); |
|
181 | 177 | return true; |
|
182 | 178 | } else { |
|
183 | 179 | return false; |
|
184 | 180 | } |
|
185 | 181 | }; |
|
186 | 182 | |
|
187 | 183 | // cancel autocall done after '(' for example. |
|
188 | 184 | Tooltip.prototype.cancel_pending = function () { |
|
189 | 185 | if (this._tooltip_timeout !== null) { |
|
190 | 186 | clearTimeout(this._tooltip_timeout); |
|
191 | 187 | this._tooltip_timeout = null; |
|
192 | 188 | } |
|
193 | 189 | }; |
|
194 | 190 | |
|
195 | 191 | // will trigger tooltip after timeout |
|
196 | 192 | Tooltip.prototype.pending = function (cell, hide_if_no_docstring) { |
|
197 | 193 | var that = this; |
|
198 | 194 | this._tooltip_timeout = setTimeout(function () { |
|
199 | 195 | that.request(cell, hide_if_no_docstring); |
|
200 | 196 | }, that.time_before_tooltip); |
|
201 | 197 | }; |
|
202 | 198 | |
|
203 | 199 | // easy access for julia monkey patching. |
|
204 | 200 | Tooltip.last_token_re = /[a-z_][0-9a-z._]*$/gi; |
|
205 | 201 | |
|
206 | 202 | Tooltip.prototype.extract_oir_token = function(line){ |
|
207 | 203 | // use internally just to make the request to the kernel |
|
208 | 204 | // Feel free to shorten this logic if you are better |
|
209 | 205 | // than me in regEx |
|
210 | 206 | // basicaly you shoul be able to get xxx.xxx.xxx from |
|
211 | 207 | // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2, |
|
212 | 208 | // remove everything between matchin bracket (need to iterate) |
|
213 | 209 | var matchBracket = /\([^\(\)]+\)/g; |
|
214 | 210 | var endBracket = /\([^\(]*$/g; |
|
215 | 211 | var oldline = line; |
|
216 | 212 | |
|
217 | 213 | line = line.replace(matchBracket, ""); |
|
218 | 214 | while (oldline != line) { |
|
219 | 215 | oldline = line; |
|
220 | 216 | line = line.replace(matchBracket, ""); |
|
221 | 217 | } |
|
222 | 218 | // remove everything after last open bracket |
|
223 | 219 | line = line.replace(endBracket, ""); |
|
224 | 220 | // reset the regex object |
|
225 | 221 | Tooltip.last_token_re.lastIndex = 0; |
|
226 | 222 | return Tooltip.last_token_re.exec(line); |
|
227 | 223 | }; |
|
228 | 224 | |
|
229 | 225 | Tooltip.prototype._request_tooltip = function (cell, line) { |
|
230 | 226 | var callbacks = $.proxy(this._show, this); |
|
231 | 227 | var oir_token = this.extract_oir_token(line); |
|
232 | 228 | var msg_id = cell.kernel.object_info(oir_token, callbacks); |
|
233 | 229 | }; |
|
234 | 230 | |
|
235 | 231 | // make an imediate completion request |
|
236 | 232 | Tooltip.prototype.request = function (cell, hide_if_no_docstring) { |
|
237 | 233 | // request(codecell) |
|
238 | 234 | // Deal with extracting the text from the cell and counting |
|
239 | 235 | // call in a row |
|
240 | 236 | this.cancel_pending(); |
|
241 | 237 | var editor = cell.code_mirror; |
|
242 | 238 | var cursor = editor.getCursor(); |
|
243 | 239 | var text = editor.getRange({ |
|
244 | 240 | line: cursor.line, |
|
245 | 241 | ch: 0 |
|
246 | 242 | }, cursor).trim(); |
|
247 | 243 | |
|
248 | 244 | this._hide_if_no_docstring = hide_if_no_docstring; |
|
249 | 245 | |
|
250 | 246 | if(editor.somethingSelected()){ |
|
251 | 247 | text = editor.getSelection(); |
|
252 | 248 | } |
|
253 | 249 | |
|
254 | 250 | // need a permanent handel to code_mirror for future auto recall |
|
255 | 251 | this.code_mirror = editor; |
|
256 | 252 | |
|
257 | 253 | // now we treat the different number of keypress |
|
258 | 254 | // first if same cell, same text, increment counter by 1 |
|
259 | 255 | if (this._old_cell == cell && this._old_request == text && this._hidden === false) { |
|
260 | 256 | this._consecutive_counter++; |
|
261 | 257 | } else { |
|
262 | 258 | // else reset |
|
263 | 259 | this.cancel_stick(); |
|
264 | 260 | this.reset_tabs_function (cell, text); |
|
265 | 261 | } |
|
266 | 262 | |
|
267 | 263 | // don't do anything if line beggin with '(' or is empty |
|
268 | 264 | if (text === "" || text === "(") { |
|
269 | 265 | return; |
|
270 | 266 | } |
|
271 | 267 | |
|
272 | 268 | this.tabs_functions[this._consecutive_counter](cell, text); |
|
273 | 269 | |
|
274 | 270 | // then if we are at the end of list function, reset |
|
275 | 271 | if (this._consecutive_counter == this.tabs_functions.length) { |
|
276 | 272 | this.reset_tabs_function (cell, text); |
|
277 | 273 | } |
|
278 | 274 | |
|
279 | 275 | return; |
|
280 | 276 | }; |
|
281 | 277 | |
|
282 | 278 | // cancel the option of having the tooltip to stick |
|
283 | 279 | Tooltip.prototype.cancel_stick = function () { |
|
284 | 280 | clearTimeout(this._stick_timeout); |
|
285 | 281 | this._stick_timeout = null; |
|
286 | 282 | this._clocklink.hide('slow'); |
|
287 | 283 | this._sticky = false; |
|
288 | 284 | }; |
|
289 | 285 | |
|
290 | 286 | // put the tooltip in a sicky state for 10 seconds |
|
291 | 287 | // it won't be removed by remove_and_cancell() unless you called with |
|
292 | 288 | // the first parameter set to true. |
|
293 | 289 | // remove_and_cancell_tooltip(true) |
|
294 | 290 | Tooltip.prototype.stick = function (time) { |
|
295 | 291 | time = (time !== undefined) ? time : 10; |
|
296 | 292 | var that = this; |
|
297 | 293 | this._sticky = true; |
|
298 | 294 | this._clocklink.show('slow'); |
|
299 | 295 | this._stick_timeout = setTimeout(function () { |
|
300 | 296 | that._sticky = false; |
|
301 | 297 | that._clocklink.hide('slow'); |
|
302 | 298 | }, time * 1000); |
|
303 | 299 | }; |
|
304 | 300 | |
|
305 | 301 | // should be called with the kernel reply to actually show the tooltip |
|
306 | 302 | Tooltip.prototype._show = function (reply) { |
|
307 | 303 | // move the bubble if it is not hidden |
|
308 | 304 | // otherwise fade it |
|
309 | 305 | var content = reply.content; |
|
310 | 306 | if (!content.found) { |
|
311 | 307 | // object not found, nothing to show |
|
312 | 308 | return; |
|
313 | 309 | } |
|
314 | 310 | this.name = content.name; |
|
315 | 311 | |
|
316 | 312 | // do some math to have the tooltip arrow on more or less on left or right |
|
317 | 313 | // width of the editor |
|
318 | 314 | var w = $(this.code_mirror.getScrollerElement()).width(); |
|
319 | 315 | // ofset of the editor |
|
320 | 316 | var o = $(this.code_mirror.getScrollerElement()).offset(); |
|
321 | 317 | |
|
322 | 318 | // whatever anchor/head order but arrow at mid x selection |
|
323 | 319 | var anchor = this.code_mirror.cursorCoords(false); |
|
324 | 320 | var head = this.code_mirror.cursorCoords(true); |
|
325 | 321 | var xinit = (head.left+anchor.left)/2; |
|
326 | 322 | var xinter = o.left + (xinit - o.left) / w * (w - 450); |
|
327 | 323 | var posarrowleft = xinit - xinter; |
|
328 | 324 | |
|
329 | 325 | if (this._hidden === false) { |
|
330 | 326 | this.tooltip.animate({ |
|
331 | 327 | 'left': xinter - 30 + 'px', |
|
332 | 328 | 'top': (head.bottom + 10) + 'px' |
|
333 | 329 | }); |
|
334 | 330 | } else { |
|
335 | 331 | this.tooltip.css({ |
|
336 | 332 | 'left': xinter - 30 + 'px' |
|
337 | 333 | }); |
|
338 | 334 | this.tooltip.css({ |
|
339 | 335 | 'top': (head.bottom + 10) + 'px' |
|
340 | 336 | }); |
|
341 | 337 | } |
|
342 | 338 | this.arrow.animate({ |
|
343 | 339 | 'left': posarrowleft + 'px' |
|
344 | 340 | }); |
|
345 | 341 | |
|
346 | 342 | // build docstring |
|
347 | 343 | var defstring = content.call_def; |
|
348 | 344 | if (!defstring) { |
|
349 | 345 | defstring = content.init_definition; |
|
350 | 346 | } |
|
351 | 347 | if (!defstring) { |
|
352 | 348 | defstring = content.definition; |
|
353 | 349 | } |
|
354 | 350 | |
|
355 | 351 | var docstring = content.call_docstring; |
|
356 | 352 | if (!docstring) { |
|
357 | 353 | docstring = content.init_docstring; |
|
358 | 354 | } |
|
359 | 355 | if (!docstring) { |
|
360 | 356 | docstring = content.docstring; |
|
361 | 357 | } |
|
362 | 358 | |
|
363 | 359 | if (!docstring) { |
|
364 | 360 | // For reals this time, no docstring |
|
365 | 361 | if (this._hide_if_no_docstring) { |
|
366 | 362 | return; |
|
367 | 363 | } else { |
|
368 | 364 | docstring = "<empty docstring>"; |
|
369 | 365 | } |
|
370 | 366 | } |
|
371 | 367 | |
|
372 | 368 | this._hidden = false; |
|
373 | 369 | this.tooltip.fadeIn('fast'); |
|
374 | 370 | this.text.children().remove(); |
|
375 | 371 | |
|
376 | 372 | // Any HTML within the docstring is escaped by the fixConsole() method. |
|
377 | 373 | var pre = $('<pre/>').html(utils.fixConsole(docstring)); |
|
378 | 374 | if (defstring) { |
|
379 | 375 | var defstring_html = $('<pre/>').html(utils.fixConsole(defstring)); |
|
380 | 376 | this.text.append(defstring_html); |
|
381 | 377 | } |
|
382 | 378 | this.text.append(pre); |
|
383 | 379 | // keep scroll top to be sure to always see the first line |
|
384 | 380 | this.text.scrollTop(0); |
|
385 | 381 | }; |
|
386 | 382 | |
|
387 | 383 | IPython.Tooltip = Tooltip; |
|
388 | 384 | |
|
389 | 385 | return IPython; |
|
390 | 386 | |
|
391 | 387 | }(IPython)); |
@@ -1,54 +1,62 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 | 9 | |
|
10 | 10 | &.edit_mode { |
|
11 | 11 | .corner-all; |
|
12 | 12 | border : thin green solid; |
|
13 | 13 | } |
|
14 | 14 | } |
|
15 | 15 | |
|
16 | 16 | div.cell { |
|
17 | 17 | width: 100%; |
|
18 | 18 | padding: 5px 5px 5px 0px; |
|
19 | 19 | /* This acts as a spacer between cells, that is outside the border */ |
|
20 | 20 | margin: 0px; |
|
21 | 21 | outline: none; |
|
22 | 22 | } |
|
23 | 23 | |
|
24 | 24 | div.prompt { |
|
25 | 25 | /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */ |
|
26 | 26 | min-width: 11ex; |
|
27 | 27 | /* This padding is tuned to match the padding on the CodeMirror editor. */ |
|
28 | 28 | padding: @code_padding; |
|
29 | 29 | margin: 0px; |
|
30 | 30 | font-family: @monoFontFamily; |
|
31 | 31 | text-align: right; |
|
32 | 32 | /* This has to match that of the the CodeMirror class line-height below */ |
|
33 | 33 | line-height: @code_line_height; |
|
34 | 34 | } |
|
35 | 35 | |
|
36 | @media (max-width: 480px) { | |
|
37 | // prompts are in the main column on small screens, | |
|
38 | // so text should be left-aligned | |
|
39 | div.prompt { | |
|
40 | text-align: left; | |
|
41 | } | |
|
42 | } | |
|
43 | ||
|
36 | 44 | div.inner_cell { |
|
37 | 45 | .vbox(); |
|
38 | 46 | .box-flex1(); |
|
39 | 47 | } |
|
40 | 48 | |
|
41 | 49 | /* input_area and input_prompt must match in top border and margin for alignment */ |
|
42 | 50 | div.input_area { |
|
43 | 51 | border: 1px solid @light_border_color; |
|
44 | 52 | .corner-all; |
|
45 | 53 | background: @cell_background; |
|
46 | 54 | } |
|
47 | 55 | |
|
48 | 56 | /* This is needed so that empty prompt areas can collapse to zero height when there |
|
49 | 57 | is no content in the output_subarea and the prompt. The main purpose of this is |
|
50 | 58 | to make sure that empty JavaScript output_subareas have no height. */ |
|
51 | 59 | div.prompt:empty { |
|
52 | 60 | padding-top: 0; |
|
53 | 61 | padding-bottom: 0; |
|
54 | 62 | } |
@@ -1,40 +1,46 b'' | |||
|
1 | 1 | div.code_cell { |
|
2 | 2 | } |
|
3 | 3 | |
|
4 | 4 | /* any special styling for code cells that are currently running goes here */ |
|
5 | 5 | div.code_cell.running { |
|
6 | 6 | } |
|
7 | 7 | |
|
8 | 8 | div.input { |
|
9 | 9 | page-break-inside: avoid; |
|
10 | 10 | .hbox(); |
|
11 | 11 | } |
|
12 | 12 | |
|
13 | @media (max-width: 480px) { | |
|
14 | // move prompts above code on small screens | |
|
15 | div.input { | |
|
16 | .vbox(); | |
|
17 | } | |
|
18 | } | |
|
19 | ||
|
13 | 20 | /* input_area and input_prompt must match in top border and margin for alignment */ |
|
14 | 21 | div.input_prompt { |
|
15 | 22 | color: navy; |
|
16 | 23 | border-top: 1px solid transparent; |
|
17 | 24 | } |
|
18 | 25 | |
|
19 | ||
|
20 | 26 | // The styles related to div.highlight are for nbconvert HTML output only. This works |
|
21 | 27 | // because the .highlight div isn't present in the live notebook. We could put this into |
|
22 | 28 | // nbconvert, but it easily falls out of sync, can't use our less variables and doesn't |
|
23 | 29 | // help the basic template when paired with our CSS. |
|
24 | 30 | |
|
25 | 31 | div.input_area > div.highlight { |
|
26 | 32 | margin: @code_padding; |
|
27 | 33 | border: none; |
|
28 | 34 | padding: 0px; |
|
29 | 35 | background-color: transparent; |
|
30 | 36 | } |
|
31 | 37 | |
|
32 | 38 | div.input_area > div.highlight > pre { |
|
33 | 39 | margin: 0px; |
|
34 | 40 | border: 0px; |
|
35 | 41 | padding: 0px; |
|
36 | 42 | background-color: transparent; |
|
37 | 43 | font-size: @notebook_font_size; |
|
38 | 44 | line-height: @code_line_height; |
|
39 | 45 | } |
|
40 | 46 |
@@ -1,69 +1,77 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 | @media (max-width: 767px) { | |
|
11 | // remove bootstrap-responsive's body padding on small screens | |
|
12 | body.notebook_app { | |
|
13 | padding-left: 0px; | |
|
14 | padding-right: 0px; | |
|
15 | } | |
|
16 | } | |
|
17 | ||
|
10 | 18 | span#notebook_name { |
|
11 | 19 | height: 1em; |
|
12 | 20 | line-height: 1em; |
|
13 | 21 | padding: 3px; |
|
14 | 22 | border: none; |
|
15 | 23 | font-size: 146.5%; |
|
16 | 24 | } |
|
17 | 25 | |
|
18 | 26 | div#notebook_panel { |
|
19 | 27 | margin: 0px 0px 0px 0px; |
|
20 | 28 | padding: 0px; |
|
21 | 29 | .box-shadow(0 -1px 10px rgba(0,0,0,.1)); |
|
22 | 30 | } |
|
23 | 31 | div#notebook { |
|
24 | 32 | font-size: @notebook_font_size; |
|
25 | 33 | line-height: @notebook_line_height; |
|
26 | 34 | overflow-y: scroll; |
|
27 | 35 | overflow-x: auto; |
|
28 | 36 | width: 100%; |
|
29 | 37 | /* This spaces the cell away from the edge of the notebook area */ |
|
30 | 38 | padding: 1em 0 1em 0; |
|
31 | 39 | margin: 0px; |
|
32 | 40 | border-top: 1px solid @border_color; |
|
33 | 41 | outline: none; |
|
34 | 42 | .border-box-sizing(); |
|
35 | 43 | } |
|
36 | 44 | |
|
37 | 45 | div.ui-widget-content { |
|
38 | 46 | border: 1px solid @border_color; |
|
39 | 47 | outline: none; |
|
40 | 48 | } |
|
41 | 49 | |
|
42 | 50 | pre.dialog { |
|
43 | 51 | background-color: @cell_background; |
|
44 | 52 | border: 1px solid #ddd; |
|
45 | 53 | .corner-all; |
|
46 | 54 | padding: 0.4em; |
|
47 | 55 | padding-left: 2em; |
|
48 | 56 | } |
|
49 | 57 | |
|
50 | 58 | p.dialog { |
|
51 | 59 | padding : 0.2em; |
|
52 | 60 | } |
|
53 | 61 | |
|
54 | 62 | /* Word-wrap output correctly. This is the CSS3 spelling, though Firefox seems |
|
55 | 63 | to not honor it correctly. Webkit browsers (Chrome, rekonq, Safari) do. |
|
56 | 64 | */ |
|
57 | 65 | pre, code, kbd, samp { white-space: pre-wrap; } |
|
58 | 66 | |
|
59 | 67 | #fonttest { |
|
60 | 68 | font-family: @monoFontFamily; |
|
61 | 69 | } |
|
62 | 70 | |
|
63 | 71 | p { |
|
64 | 72 | margin-bottom:0; |
|
65 | 73 | } |
|
66 | 74 | |
|
67 | 75 | .end_space { |
|
68 | 76 | height: 200px; |
|
69 | 77 | } |
@@ -1,169 +1,176 b'' | |||
|
1 | 1 | div.output_wrapper { |
|
2 | 2 | /* this position must be relative to enable descendents to be absolute within it */ |
|
3 | 3 | position: relative; |
|
4 | 4 | .vbox() |
|
5 | 5 | } |
|
6 | 6 | |
|
7 | 7 | /* class for the output area when it should be height-limited */ |
|
8 | 8 | div.output_scroll { |
|
9 | 9 | /* ideally, this would be max-height, but FF barfs all over that */ |
|
10 | 10 | height: 24em; |
|
11 | 11 | /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */ |
|
12 | 12 | width: 100%; |
|
13 | 13 | |
|
14 | 14 | overflow: auto; |
|
15 | 15 | .corner-all; |
|
16 | 16 | .box-shadow(inset 0 2px 8px rgba(0, 0, 0, .8)); |
|
17 | 17 | display: block; |
|
18 | 18 | } |
|
19 | 19 | |
|
20 | 20 | /* output div while it is collapsed */ |
|
21 | 21 | div.output_collapsed { |
|
22 | 22 | margin: 0px; |
|
23 | 23 | padding: 0px; |
|
24 | 24 | .vbox(); |
|
25 | 25 | } |
|
26 | 26 | |
|
27 | 27 | div.out_prompt_overlay { |
|
28 | 28 | height: 100%; |
|
29 | 29 | padding: 0px @code_padding; |
|
30 | 30 | position: absolute; |
|
31 | 31 | .corner-all; |
|
32 | 32 | } |
|
33 | 33 | |
|
34 | 34 | div.out_prompt_overlay:hover { |
|
35 | 35 | /* use inner shadow to get border that is computed the same on WebKit/FF */ |
|
36 | 36 | .box-shadow(inset 0 0 1px #000); |
|
37 | 37 | background: rgba(240, 240, 240, 0.5); |
|
38 | 38 | } |
|
39 | 39 | |
|
40 | 40 | div.output_prompt { |
|
41 | 41 | color: darkred; |
|
42 | 42 | } |
|
43 | 43 | |
|
44 | 44 | /* This class is the outer container of all output sections. */ |
|
45 | 45 | div.output_area { |
|
46 | 46 | padding: 0px; |
|
47 | 47 | page-break-inside: avoid; |
|
48 | 48 | .hbox(); |
|
49 | 49 | |
|
50 | 50 | .MathJax_Display { |
|
51 | 51 | // Inside a CodeCell, elements are left justified |
|
52 | 52 | text-align: left !important; |
|
53 | 53 | } |
|
54 | 54 | |
|
55 | 55 | .rendered_html { |
|
56 | 56 | // Inside a CodeCell, elements are left justified |
|
57 | 57 | table { |
|
58 | 58 | margin-left: 0; |
|
59 | 59 | margin-right: 0; |
|
60 | 60 | } |
|
61 | 61 | |
|
62 | 62 | img { |
|
63 | 63 | margin-left: 0; |
|
64 | 64 | margin-right: 0; |
|
65 | 65 | } |
|
66 | 66 | } |
|
67 | 67 | } |
|
68 | 68 | |
|
69 | 69 | /* This is needed to protect the pre formating from global settings such |
|
70 | 70 | as that of bootstrap */ |
|
71 | 71 | .output { |
|
72 | 72 | .vbox(); |
|
73 | 73 | } |
|
74 | 74 | |
|
75 | @media (max-width: 480px) { | |
|
76 | // move prompts above output on small screens | |
|
77 | div.output_area { | |
|
78 | .vbox(); | |
|
79 | } | |
|
80 | } | |
|
81 | ||
|
75 | 82 | div.output_area pre { |
|
76 | 83 | margin: 0; |
|
77 | 84 | padding: 0; |
|
78 | 85 | border: 0; |
|
79 | 86 | font-size: 100%; |
|
80 | 87 | vertical-align: baseline; |
|
81 | 88 | color: black; |
|
82 | 89 | background-color: transparent; |
|
83 | 90 | .border-radius(0); |
|
84 | 91 | line-height: inherit; |
|
85 | 92 | } |
|
86 | 93 | |
|
87 | 94 | /* This class is for the output subarea inside the output_area and after |
|
88 | 95 | the prompt div. */ |
|
89 | 96 | div.output_subarea { |
|
90 | 97 | padding: @code_padding @code_padding 0.0em @code_padding; |
|
91 | 98 | .box-flex1(); |
|
92 | 99 | } |
|
93 | 100 | |
|
94 | 101 | /* The rest of the output_* classes are for special styling of the different |
|
95 | 102 | output types */ |
|
96 | 103 | |
|
97 | 104 | /* all text output has this class: */ |
|
98 | 105 | div.output_text { |
|
99 | 106 | text-align: left; |
|
100 | 107 | color: @textColor; |
|
101 | 108 | /* This has to match that of the the CodeMirror class line-height below */ |
|
102 | 109 | line-height: @code_line_height; |
|
103 | 110 | } |
|
104 | 111 | |
|
105 | 112 | /* stdout/stderr are 'text' as well as 'stream', but pyout/pyerr are *not* streams */ |
|
106 | 113 | div.output_stream { |
|
107 | 114 | } |
|
108 | 115 | |
|
109 | 116 | div.output_stdout { |
|
110 | 117 | } |
|
111 | 118 | |
|
112 | 119 | div.output_stderr { |
|
113 | 120 | background: #fdd; /* very light red background for stderr */ |
|
114 | 121 | } |
|
115 | 122 | |
|
116 | 123 | div.output_latex { |
|
117 | 124 | text-align: left; |
|
118 | 125 | } |
|
119 | 126 | |
|
120 | 127 | div.output_html { |
|
121 | 128 | } |
|
122 | 129 | |
|
123 | 130 | div.output_png { |
|
124 | 131 | } |
|
125 | 132 | |
|
126 | 133 | div.output_jpeg { |
|
127 | 134 | } |
|
128 | 135 | |
|
129 | 136 | /* Empty output_javascript divs should have no height */ |
|
130 | 137 | div.output_javascript:empty { |
|
131 | 138 | padding: 0; |
|
132 | 139 | } |
|
133 | 140 | |
|
134 | 141 | .js-error { |
|
135 | 142 | color: darkred; |
|
136 | 143 | } |
|
137 | 144 | |
|
138 | 145 | /* raw_input styles */ |
|
139 | 146 | |
|
140 | 147 | div.raw_input_container { |
|
141 | 148 | font-family: @monoFontFamily; |
|
142 | 149 | // for some reason, em padding doesn't compute the same for raw_input |
|
143 | 150 | // that is not the first input, but px does |
|
144 | 151 | padding-top: 5px; |
|
145 | 152 | } |
|
146 | 153 | |
|
147 | 154 | span.raw_input_prompt { |
|
148 | 155 | /* nothing needed here */ |
|
149 | 156 | } |
|
150 | 157 | |
|
151 | 158 | input.raw_input { |
|
152 | 159 | font-family: inherit; |
|
153 | 160 | font-size: inherit; |
|
154 | 161 | color: inherit; |
|
155 | 162 | width: auto; |
|
156 | 163 | /* make sure input baseline aligns with prompt */ |
|
157 | 164 | vertical-align: baseline; |
|
158 | 165 | /* padding + margin = 0.5em between prompt and cursor */ |
|
159 | 166 | padding: 0em 0.25em; |
|
160 | 167 | margin: 0em 0.25em; |
|
161 | 168 | } |
|
162 | 169 | |
|
163 | 170 | input.raw_input:focus { |
|
164 | 171 | box-shadow: none; |
|
165 | 172 | } |
|
166 | 173 | |
|
167 | 174 | p.p-space { |
|
168 | 175 | margin-bottom: 10px; |
|
169 | 176 | } |
@@ -1,30 +1,36 b'' | |||
|
1 | 1 | div.text_cell { |
|
2 | 2 | padding: 5px 5px 5px 0px; |
|
3 | 3 | .hbox(); |
|
4 | 4 | } |
|
5 | @media (max-width: 480px) { | |
|
6 | // remove prompt indentation on small screens | |
|
7 | div.text_cell > div.prompt { | |
|
8 | display: none; | |
|
9 | } | |
|
10 | } | |
|
5 | 11 | |
|
6 | 12 | div.text_cell_render { |
|
7 | 13 | /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/ |
|
8 | 14 | outline: none; |
|
9 | 15 | resize: none; |
|
10 | 16 | width: inherit; |
|
11 | 17 | border-style: none; |
|
12 | 18 | padding: 0.5em 0.5em 0.5em @code_padding; |
|
13 | 19 | color: @textColor; |
|
14 | 20 | } |
|
15 | 21 | |
|
16 | 22 | a.anchor-link:link { |
|
17 | 23 | text-decoration: none; |
|
18 | 24 | padding: 0px 20px; |
|
19 | 25 | visibility: hidden; |
|
20 | 26 | } |
|
21 | 27 | |
|
22 | 28 | h1,h2,h3,h4,h5,h6 { |
|
23 | 29 | &:hover .anchor-link { |
|
24 | 30 | visibility: visible; |
|
25 | 31 | } |
|
26 | 32 | } |
|
27 | 33 | |
|
28 | 34 | div.cell.text_cell.rendered { |
|
29 | 35 | padding: 0px; |
|
30 | 36 | } |
@@ -1,199 +1,199 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 | code{color:#000} |
|
6 | 6 | .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} |
|
7 | 7 | .corner-all{border-radius:4px} |
|
8 | 8 | .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;display:flex;flex-direction:row;align-items:stretch} |
|
9 | 9 | .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none} |
|
10 | 10 | .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%;display:flex;flex-direction:column;align-items:stretch} |
|
11 | 11 | .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none} |
|
12 | 12 | .hbox.reverse,.vbox.reverse,.reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:row-reverse} |
|
13 | 13 | .hbox.box-flex0,.vbox.box-flex0,.box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none;width:auto} |
|
14 | 14 | .hbox.box-flex1,.vbox.box-flex1,.box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} |
|
15 | 15 | .hbox.box-flex,.vbox.box-flex,.box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} |
|
16 | 16 | .hbox.box-flex2,.vbox.box-flex2,.box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2} |
|
17 | 17 | .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1} |
|
18 | 18 | .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2} |
|
19 | 19 | .hbox.start,.vbox.start,.start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start} |
|
20 | 20 | .hbox.end,.vbox.end,.end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end} |
|
21 | 21 | .hbox.center,.vbox.center,.center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center} |
|
22 | 22 | .hbox.align-start,.vbox.align-start,.align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start} |
|
23 | 23 | .hbox.align-end,.vbox.align-end,.align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-items:flex-end} |
|
24 | 24 | .hbox.align-center,.vbox.align-center,.align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-items:center} |
|
25 | 25 | div.error{margin:2em;text-align:center} |
|
26 | 26 | div.error>h1{font-size:500%;line-height:normal} |
|
27 | 27 | div.error>p{font-size:200%;line-height:normal} |
|
28 | 28 | div.traceback-wrapper{text-align:left;max-width:800px;margin:auto} |
|
29 | 29 | .center-nav{display:inline-block;margin-bottom:-4px} |
|
30 | 30 | .alternate_upload{background-color:none;display:inline} |
|
31 | 31 | .alternate_upload.form{padding:0;margin:0} |
|
32 | 32 | .alternate_upload input.fileinput{background-color:#f00;position:relative;opacity:0;z-index:2;width:295px;margin-left:163px;cursor:pointer;height:26px} |
|
33 | 33 | ul#tabs{margin-bottom:4px} |
|
34 | 34 | ul#tabs a{padding-top:4px;padding-bottom:4px} |
|
35 | 35 | ul.breadcrumb a:focus,ul.breadcrumb a:hover{text-decoration:none} |
|
36 | 36 | ul.breadcrumb i.icon-home{font-size:16px;margin-right:4px} |
|
37 | 37 | ul.breadcrumb span{color:#5e5e5e} |
|
38 | 38 | .list_toolbar{padding:4px 0 4px 0} |
|
39 | 39 | .list_toolbar [class*="span"]{min-height:26px} |
|
40 | 40 | .list_header{font-weight:bold} |
|
41 | 41 | .list_container{margin-top:4px;margin-bottom:20px;border:1px solid #ababab;border-radius:4px} |
|
42 | 42 | .list_container>div{border-bottom:1px solid #ababab}.list_container>div:hover .list-item{background-color:#f00} |
|
43 | 43 | .list_container>div:last-child{border:none} |
|
44 | 44 | .list_item:hover .list_item{background-color:#ddd} |
|
45 | 45 | .list_item a{text-decoration:none} |
|
46 | 46 | .list_header>div,.list_item>div{padding-top:4px;padding-bottom:4px;padding-left:7px;padding-right:7px;height:22px;line-height:22px} |
|
47 | 47 | .item_name{line-height:22px;height:26px} |
|
48 | 48 | .item_icon{font-size:14px;color:#5e5e5e;margin-right:7px} |
|
49 | 49 | .item_buttons{line-height:1em} |
|
50 | 50 | .toolbar_info{height:26px;line-height:26px} |
|
51 | 51 | input.nbname_input,input.engine_num_input{padding-top:3px;padding-bottom:3px;height:14px;line-height:14px;margin:0} |
|
52 | 52 | input.engine_num_input{width:60px} |
|
53 | 53 | .highlight_text{color:#00f} |
|
54 | 54 | #project_name>.breadcrumb{padding:0;margin-bottom:0;background-color:transparent;font-weight:bold} |
|
55 | 55 | .ansibold{font-weight:bold} |
|
56 | 56 | .ansiblack{color:#000} |
|
57 | 57 | .ansired{color:#8b0000} |
|
58 | 58 | .ansigreen{color:#006400} |
|
59 | 59 | .ansiyellow{color:#a52a2a} |
|
60 | 60 | .ansiblue{color:#00008b} |
|
61 | 61 | .ansipurple{color:#9400d3} |
|
62 | 62 | .ansicyan{color:#4682b4} |
|
63 | 63 | .ansigray{color:#808080} |
|
64 | 64 | .ansibgblack{background-color:#000} |
|
65 | 65 | .ansibgred{background-color:#f00} |
|
66 | 66 | .ansibggreen{background-color:#008000} |
|
67 | 67 | .ansibgyellow{background-color:#ff0} |
|
68 | 68 | .ansibgblue{background-color:#00f} |
|
69 | 69 | .ansibgpurple{background-color:#f0f} |
|
70 | 70 | .ansibgcyan{background-color:#0ff} |
|
71 | 71 | .ansibggray{background-color:#808080} |
|
72 | 72 | 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%;display:flex;flex-direction:column;align-items:stretch}div.cell.selected{border-radius:4px;border:thin #ababab solid} |
|
73 | 73 | div.cell.edit_mode{border-radius:4px;border:thin #008000 solid} |
|
74 | 74 | div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none} |
|
75 | 75 | div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.21429em} |
|
76 | 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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
76 | @media (max-width:480px){div.prompt{text-align:left}}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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
77 | 77 | div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7} |
|
78 | 78 | div.prompt:empty{padding-top:0;padding-bottom:0} |
|
79 | 79 | 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;display:flex;flex-direction:row;align-items:stretch} |
|
80 | div.input_prompt{color:#000080;border-top:1px solid transparent} | |
|
80 | @media (max-width:480px){div.input{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%;display:flex;flex-direction:column;align-items:stretch}}div.input_prompt{color:#000080;border-top:1px solid transparent} | |
|
81 | 81 | div.input_area>div.highlight{margin:.4em;border:none;padding:0;background-color:transparent} |
|
82 | 82 | div.input_area>div.highlight>pre{margin:0;border:0;padding:0;background-color:transparent;font-size:14px;line-height:1.21429em} |
|
83 | 83 | .CodeMirror{line-height:1.21429em;height:auto;background:none;} |
|
84 | 84 | .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto} |
|
85 | 85 | @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em} |
|
86 | 86 | .CodeMirror-linenumber{padding:0 8px 0 4px} |
|
87 | 87 | .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px} |
|
88 | 88 | .CodeMirror pre{padding:0;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
89 | 89 | pre code{display:block;padding:.5em} |
|
90 | 90 | .highlight-base,pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure .built_in,pre .nginx .title{color:#000} |
|
91 | 91 | .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} |
|
92 | 92 | .highlight-comment,pre .comment,pre .annotation,pre .template_comment,pre .diff .header,pre .chunk,pre .markdown .blockquote{color:#408080;font-style:italic} |
|
93 | 93 | .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} |
|
94 | 94 | 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:#88f} |
|
95 | 95 | .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} |
|
96 | 96 | .highlight-builtin,pre .built_in{color:#008000} |
|
97 | 97 | pre .markdown .emphasis{font-style:italic} |
|
98 | 98 | pre .nginx .built_in{font-weight:normal} |
|
99 | 99 | pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .javascript,pre .xml .vbscript,pre .xml .css,pre .xml .cdata{opacity:.5} |
|
100 | 100 | .cm-s-ipython span.cm-variable{color:#000} |
|
101 | 101 | .cm-s-ipython span.cm-keyword{color:#008000;font-weight:bold} |
|
102 | 102 | .cm-s-ipython span.cm-number{color:#080} |
|
103 | 103 | .cm-s-ipython span.cm-comment{color:#408080;font-style:italic} |
|
104 | 104 | .cm-s-ipython span.cm-string{color:#ba2121} |
|
105 | 105 | .cm-s-ipython span.cm-builtin{color:#008000} |
|
106 | 106 | .cm-s-ipython span.cm-error{color:#f00} |
|
107 | 107 | .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold} |
|
108 | 108 | .cm-s-ipython span.cm-meta{color:#a2f} |
|
109 | 109 | .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat} |
|
110 | 110 | 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%;display:flex;flex-direction:column;align-items:stretch} |
|
111 | 111 | 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);display:block} |
|
112 | 112 | div.output_collapsed{margin:0;padding:0;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%;display:flex;flex-direction:column;align-items:stretch} |
|
113 | 113 | div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px} |
|
114 | 114 | div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000;-moz-box-shadow:inset 0 0 1px #000;box-shadow:inset 0 0 1px #000;background:rgba(240,240,240,0.5)} |
|
115 | 115 | div.output_prompt{color:#8b0000} |
|
116 | 116 | div.output_area{padding:0;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;display:flex;flex-direction:row;align-items:stretch}div.output_area .MathJax_Display{text-align:left !important} |
|
117 | 117 | div.output_area .rendered_html table{margin-left:0;margin-right:0} |
|
118 | 118 | div.output_area .rendered_html img{margin-left:0;margin-right:0} |
|
119 | 119 | .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%;display:flex;flex-direction:column;align-items:stretch} |
|
120 | div.output_area pre{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:#000;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit} | |
|
120 | @media (max-width:480px){div.output_area{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%;display:flex;flex-direction:column;align-items:stretch}}div.output_area pre{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:#000;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit} | |
|
121 | 121 | div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} |
|
122 | 122 | div.output_text{text-align:left;color:#000;line-height:1.21429em} |
|
123 | 123 | div.output_stderr{background:#fdd;} |
|
124 | 124 | div.output_latex{text-align:left} |
|
125 | 125 | div.output_javascript:empty{padding:0} |
|
126 | 126 | .js-error{color:#8b0000} |
|
127 | 127 | div.raw_input_container{font-family:monospace;padding-top:5px} |
|
128 | 128 | span.raw_input_prompt{} |
|
129 | 129 | input.raw_input{font-family:inherit;font-size:inherit;color:inherit;width:auto;vertical-align:baseline;padding:0 .25em;margin:0 .25em} |
|
130 | 130 | input.raw_input:focus{box-shadow:none} |
|
131 | 131 | p.p-space{margin-bottom:10px} |
|
132 | 132 | .rendered_html{color:#000;}.rendered_html em{font-style:italic} |
|
133 | 133 | .rendered_html strong{font-weight:bold} |
|
134 | 134 | .rendered_html u{text-decoration:underline} |
|
135 | 135 | .rendered_html :link{text-decoration:underline} |
|
136 | 136 | .rendered_html :visited{text-decoration:underline} |
|
137 | 137 | .rendered_html h1{font-size:185.7%;margin:1.08em 0 0 0;font-weight:bold;line-height:1} |
|
138 | 138 | .rendered_html h2{font-size:157.1%;margin:1.27em 0 0 0;font-weight:bold;line-height:1} |
|
139 | 139 | .rendered_html h3{font-size:128.6%;margin:1.55em 0 0 0;font-weight:bold;line-height:1} |
|
140 | 140 | .rendered_html h4{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1} |
|
141 | 141 | .rendered_html h5{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1;font-style:italic} |
|
142 | 142 | .rendered_html h6{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1;font-style:italic} |
|
143 | 143 | .rendered_html h1:first-child{margin-top:.538em} |
|
144 | 144 | .rendered_html h2:first-child{margin-top:.636em} |
|
145 | 145 | .rendered_html h3:first-child{margin-top:.777em} |
|
146 | 146 | .rendered_html h4:first-child{margin-top:1em} |
|
147 | 147 | .rendered_html h5:first-child{margin-top:1em} |
|
148 | 148 | .rendered_html h6:first-child{margin-top:1em} |
|
149 | 149 | .rendered_html ul{list-style:disc;margin:0 2em} |
|
150 | 150 | .rendered_html ul ul{list-style:square;margin:0 2em} |
|
151 | 151 | .rendered_html ul ul ul{list-style:circle;margin:0 2em} |
|
152 | 152 | .rendered_html ol{list-style:decimal;margin:0 2em} |
|
153 | 153 | .rendered_html ol ol{list-style:upper-alpha;margin:0 2em} |
|
154 | 154 | .rendered_html ol ol ol{list-style:lower-alpha;margin:0 2em} |
|
155 | 155 | .rendered_html ol ol ol ol{list-style:lower-roman;margin:0 2em} |
|
156 | 156 | .rendered_html ol ol ol ol ol{list-style:decimal;margin:0 2em} |
|
157 | 157 | .rendered_html *+ul{margin-top:1em} |
|
158 | 158 | .rendered_html *+ol{margin-top:1em} |
|
159 | 159 | .rendered_html hr{color:#000;background-color:#000} |
|
160 | 160 | .rendered_html pre{margin:1em 2em} |
|
161 | 161 | .rendered_html pre,.rendered_html code{border:0;background-color:#fff;color:#000;font-size:100%;padding:0} |
|
162 | 162 | .rendered_html blockquote{margin:1em 2em} |
|
163 | 163 | .rendered_html table{margin-left:auto;margin-right:auto;border:1px solid #000;border-collapse:collapse} |
|
164 | 164 | .rendered_html tr,.rendered_html th,.rendered_html td{border:1px solid #000;border-collapse:collapse;margin:1em 2em} |
|
165 | 165 | .rendered_html td,.rendered_html th{text-align:left;vertical-align:middle;padding:4px} |
|
166 | 166 | .rendered_html th{font-weight:bold} |
|
167 | 167 | .rendered_html *+table{margin-top:1em} |
|
168 | 168 | .rendered_html p{text-align:justify} |
|
169 | 169 | .rendered_html *+p{margin-top:1em} |
|
170 | 170 | .rendered_html img{display:block;margin-left:auto;margin-right:auto} |
|
171 | 171 | .rendered_html *+img{margin-top:1em} |
|
172 | 172 | div.text_cell{padding:5px 5px 5px 0;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;display:flex;flex-direction:row;align-items:stretch} |
|
173 | div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000} | |
|
173 | @media (max-width:480px){div.text_cell>div.prompt{display:none}}div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000} | |
|
174 | 174 | a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden} |
|
175 | 175 | 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} |
|
176 | 176 | div.cell.text_cell.rendered{padding:0} |
|
177 | 177 | .widget-area{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;display:flex;flex-direction:row;align-items:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start} |
|
178 | 178 | .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top} |
|
179 | 179 | .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom} |
|
180 | 180 | .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top} |
|
181 | 181 | .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top} |
|
182 | 182 | .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;} |
|
183 | 183 | .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;margin-bottom:10px;border:1px solid #ccc;background:#fff;border-radius:4px;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;display:flex;flex-direction:row;align-items:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;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;display:flex;flex-direction:row;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important} |
|
184 | 184 | .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;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%;display:flex;flex-direction:column;align-items:stretch}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px} |
|
185 | 185 | .widget-text{width:350px;margin:0 !important} |
|
186 | 186 | .widget-listbox{width:364px;margin-bottom:0} |
|
187 | 187 | .widget-numeric-text{width:150px;margin:0 !important} |
|
188 | 188 | .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none} |
|
189 | 189 | .widget-combo-btn{min-width:138px;} |
|
190 | 190 | .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start} |
|
191 | 191 | .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start;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;display:flex;flex-direction:row;align-items:stretch} |
|
192 | 192 | .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start;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;display:flex;flex-direction:row;align-items:stretch;height:30px} |
|
193 | 193 | .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start;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%;display:flex;flex-direction:column;align-items:stretch} |
|
194 | 194 | .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start;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%;display:flex;flex-direction:column;align-items:stretch;width:30px} |
|
195 | 195 | .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important} |
|
196 | 196 | .widget-modal-body{max-height:none !important} |
|
197 | 197 | .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start} |
|
198 | 198 | .widget-radio-box{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%;display:flex;flex-direction:column;align-items:stretch;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding-top:4px} |
|
199 | 199 | .docked-widget-modal{overflow:hidden;position:relative !important;top:0 !important;left:0 !important;margin-left:0 !important} |
@@ -1,1536 +1,1536 b'' | |||
|
1 | 1 | article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block} |
|
2 | 2 | audio,canvas,video{display:inline-block;*display:inline;*zoom:1} |
|
3 | 3 | audio:not([controls]){display:none} |
|
4 | 4 | html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%} |
|
5 | 5 | a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} |
|
6 | 6 | a:hover,a:active{outline:0} |
|
7 | 7 | sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline} |
|
8 | 8 | sup{top:-0.5em} |
|
9 | 9 | sub{bottom:-0.25em} |
|
10 | 10 | img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic} |
|
11 | 11 | #map_canvas img,.google-maps img{max-width:none} |
|
12 | 12 | button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle} |
|
13 | 13 | button,input{*overflow:visible;line-height:normal} |
|
14 | 14 | button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0} |
|
15 | 15 | button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} |
|
16 | 16 | label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer} |
|
17 | 17 | input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield} |
|
18 | 18 | input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none} |
|
19 | 19 | textarea{overflow:auto;vertical-align:top} |
|
20 | 20 | @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:.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:#000;background-color:#fff} |
|
21 | 21 | a{color:#08c;text-decoration:none} |
|
22 | 22 | a:hover,a:focus{color:#005580;text-decoration:underline} |
|
23 | 23 | .img-rounded{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} |
|
24 | 24 | .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)} |
|
25 | 25 | .img-circle{border-radius:500px;-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px} |
|
26 | 26 | .row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0} |
|
27 | 27 | .row:after{clear:both} |
|
28 | 28 | [class*="span"]{float:left;min-height:1px;margin-left:20px} |
|
29 | 29 | .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px} |
|
30 | 30 | .span12{width:940px} |
|
31 | 31 | .span11{width:860px} |
|
32 | 32 | .span10{width:780px} |
|
33 | 33 | .span9{width:700px} |
|
34 | 34 | .span8{width:620px} |
|
35 | 35 | .span7{width:540px} |
|
36 | 36 | .span6{width:460px} |
|
37 | 37 | .span5{width:380px} |
|
38 | 38 | .span4{width:300px} |
|
39 | 39 | .span3{width:220px} |
|
40 | 40 | .span2{width:140px} |
|
41 | 41 | .span1{width:60px} |
|
42 | 42 | .offset12{margin-left:980px} |
|
43 | 43 | .offset11{margin-left:900px} |
|
44 | 44 | .offset10{margin-left:820px} |
|
45 | 45 | .offset9{margin-left:740px} |
|
46 | 46 | .offset8{margin-left:660px} |
|
47 | 47 | .offset7{margin-left:580px} |
|
48 | 48 | .offset6{margin-left:500px} |
|
49 | 49 | .offset5{margin-left:420px} |
|
50 | 50 | .offset4{margin-left:340px} |
|
51 | 51 | .offset3{margin-left:260px} |
|
52 | 52 | .offset2{margin-left:180px} |
|
53 | 53 | .offset1{margin-left:100px} |
|
54 | 54 | .row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0} |
|
55 | 55 | .row-fluid:after{clear:both} |
|
56 | 56 | .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%} |
|
57 | 57 | .row-fluid [class*="span"]:first-child{margin-left:0} |
|
58 | 58 | .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%} |
|
59 | 59 | .row-fluid .span12{width:100%;*width:99.94680851063829%} |
|
60 | 60 | .row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%} |
|
61 | 61 | .row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%} |
|
62 | 62 | .row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%} |
|
63 | 63 | .row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%} |
|
64 | 64 | .row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%} |
|
65 | 65 | .row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%} |
|
66 | 66 | .row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%} |
|
67 | 67 | .row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%} |
|
68 | 68 | .row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%} |
|
69 | 69 | .row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%} |
|
70 | 70 | .row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%} |
|
71 | 71 | .row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%} |
|
72 | 72 | .row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%} |
|
73 | 73 | .row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%} |
|
74 | 74 | .row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%} |
|
75 | 75 | .row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%} |
|
76 | 76 | .row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%} |
|
77 | 77 | .row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%} |
|
78 | 78 | .row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%} |
|
79 | 79 | .row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%} |
|
80 | 80 | .row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%} |
|
81 | 81 | .row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%} |
|
82 | 82 | .row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%} |
|
83 | 83 | .row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%} |
|
84 | 84 | .row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%} |
|
85 | 85 | .row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%} |
|
86 | 86 | .row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%} |
|
87 | 87 | .row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%} |
|
88 | 88 | .row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%} |
|
89 | 89 | .row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%} |
|
90 | 90 | .row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%} |
|
91 | 91 | .row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%} |
|
92 | 92 | .row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%} |
|
93 | 93 | .row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%} |
|
94 | 94 | .row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%} |
|
95 | 95 | [class*="span"].hide,.row-fluid [class*="span"].hide{display:none} |
|
96 | 96 | [class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right} |
|
97 | 97 | .container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;content:"";line-height:0} |
|
98 | 98 | .container:after{clear:both} |
|
99 | 99 | .container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0} |
|
100 | 100 | .container-fluid:after{clear:both} |
|
101 | 101 | p{margin:0 0 10px} |
|
102 | 102 | .lead{margin-bottom:20px;font-size:19.5px;font-weight:200;line-height:30px} |
|
103 | 103 | small{font-size:85%} |
|
104 | 104 | strong{font-weight:bold} |
|
105 | 105 | em{font-style:italic} |
|
106 | 106 | cite{font-style:normal} |
|
107 | 107 | .muted{color:#999} |
|
108 | 108 | a.muted:hover,a.muted:focus{color:#808080} |
|
109 | 109 | .text-warning{color:#c09853} |
|
110 | 110 | a.text-warning:hover,a.text-warning:focus{color:#a47e3c} |
|
111 | 111 | .text-error{color:#b94a48} |
|
112 | 112 | a.text-error:hover,a.text-error:focus{color:#953b39} |
|
113 | 113 | .text-info{color:#3a87ad} |
|
114 | 114 | a.text-info:hover,a.text-info:focus{color:#2d6987} |
|
115 | 115 | .text-success{color:#468847} |
|
116 | 116 | a.text-success:hover,a.text-success:focus{color:#356635} |
|
117 | 117 | .text-left{text-align:left} |
|
118 | 118 | .text-right{text-align:right} |
|
119 | 119 | .text-center{text-align:center} |
|
120 | 120 | 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:#999} |
|
121 | 121 | h1,h2,h3{line-height:40px} |
|
122 | 122 | h1{font-size:35.75px} |
|
123 | 123 | h2{font-size:29.25px} |
|
124 | 124 | h3{font-size:22.75px} |
|
125 | 125 | h4{font-size:16.25px} |
|
126 | 126 | h5{font-size:13px} |
|
127 | 127 | h6{font-size:11.049999999999999px} |
|
128 | 128 | h1 small{font-size:22.75px} |
|
129 | 129 | h2 small{font-size:16.25px} |
|
130 | 130 | h3 small{font-size:13px} |
|
131 | 131 | h4 small{font-size:13px} |
|
132 | 132 | .page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee} |
|
133 | 133 | ul,ol{padding:0;margin:0 0 10px 25px} |
|
134 | 134 | ul ul,ul ol,ol ol,ol ul{margin-bottom:0} |
|
135 | 135 | li{line-height:20px} |
|
136 | 136 | ul.unstyled,ol.unstyled{margin-left:0;list-style:none} |
|
137 | 137 | 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} |
|
138 | 138 | dl{margin-bottom:20px} |
|
139 | 139 | dt,dd{line-height:20px} |
|
140 | 140 | dt{font-weight:bold} |
|
141 | 141 | dd{margin-left:10px} |
|
142 | 142 | .dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0} |
|
143 | 143 | .dl-horizontal:after{clear:both} |
|
144 | 144 | .dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} |
|
145 | 145 | .dl-horizontal dd{margin-left:180px} |
|
146 | 146 | hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff} |
|
147 | 147 | abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999} |
|
148 | 148 | abbr.initialism{font-size:90%;text-transform:uppercase} |
|
149 | 149 | blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16.25px;font-weight:300;line-height:1.25} |
|
150 | 150 | blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'} |
|
151 | 151 | blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right} |
|
152 | 152 | blockquote.pull-right small:before{content:''} |
|
153 | 153 | blockquote.pull-right small:after{content:'\00A0 \2014'} |
|
154 | 154 | q:before,q:after,blockquote:before,blockquote:after{content:""} |
|
155 | 155 | address{display:block;margin-bottom:20px;font-style:normal;line-height:20px} |
|
156 | 156 | code,pre{padding:0 3px 2px;font-family:monospace;font-size:11px;color:#333;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} |
|
157 | 157 | code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;white-space:nowrap} |
|
158 | 158 | 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);border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px} |
|
159 | 159 | pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0} |
|
160 | 160 | .pre-scrollable{max-height:340px;overflow-y:scroll} |
|
161 | 161 | form{margin:0 0 20px} |
|
162 | 162 | fieldset{padding:0;margin:0;border:0} |
|
163 | 163 | legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:19.5px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999} |
|
164 | 164 | label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:20px} |
|
165 | 165 | input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif} |
|
166 | 166 | label{display:block;margin-bottom:5px} |
|
167 | 167 | 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:#555;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;vertical-align:middle} |
|
168 | 168 | input,textarea,.uneditable-input{width:206px} |
|
169 | 169 | textarea{height:auto} |
|
170 | 170 | 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:#fff;border:1px solid #ccc;-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)} |
|
171 | 171 | input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal} |
|
172 | 172 | input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto} |
|
173 | 173 | select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px} |
|
174 | 174 | select{width:220px;border:1px solid #ccc;background-color:#fff} |
|
175 | 175 | select[multiple],select[size]{height:auto} |
|
176 | 176 | 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} |
|
177 | 177 | .uneditable-input,.uneditable-textarea{color:#999;background-color:#fcfcfc;border-color:#ccc;-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} |
|
178 | 178 | .uneditable-input{overflow:hidden;white-space:nowrap} |
|
179 | 179 | .uneditable-textarea{width:auto;height:auto} |
|
180 | 180 | input:-moz-placeholder,textarea:-moz-placeholder{color:#999} |
|
181 | 181 | input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999} |
|
182 | 182 | input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999} |
|
183 | 183 | .radio,.checkbox{min-height:20px;padding-left:20px} |
|
184 | 184 | .radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px} |
|
185 | 185 | .controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px} |
|
186 | 186 | .radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle} |
|
187 | 187 | .radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px} |
|
188 | 188 | .input-mini{width:60px} |
|
189 | 189 | .input-small{width:90px} |
|
190 | 190 | .input-medium{width:150px} |
|
191 | 191 | .input-large{width:210px} |
|
192 | 192 | .input-xlarge{width:270px} |
|
193 | 193 | .input-xxlarge{width:530px} |
|
194 | 194 | 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} |
|
195 | 195 | .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} |
|
196 | 196 | input,textarea,.uneditable-input{margin-left:0} |
|
197 | 197 | .controls-row [class*="span"]+[class*="span"]{margin-left:20px} |
|
198 | 198 | input.span12,textarea.span12,.uneditable-input.span12{width:926px} |
|
199 | 199 | input.span11,textarea.span11,.uneditable-input.span11{width:846px} |
|
200 | 200 | input.span10,textarea.span10,.uneditable-input.span10{width:766px} |
|
201 | 201 | input.span9,textarea.span9,.uneditable-input.span9{width:686px} |
|
202 | 202 | input.span8,textarea.span8,.uneditable-input.span8{width:606px} |
|
203 | 203 | input.span7,textarea.span7,.uneditable-input.span7{width:526px} |
|
204 | 204 | input.span6,textarea.span6,.uneditable-input.span6{width:446px} |
|
205 | 205 | input.span5,textarea.span5,.uneditable-input.span5{width:366px} |
|
206 | 206 | input.span4,textarea.span4,.uneditable-input.span4{width:286px} |
|
207 | 207 | input.span3,textarea.span3,.uneditable-input.span3{width:206px} |
|
208 | 208 | input.span2,textarea.span2,.uneditable-input.span2{width:126px} |
|
209 | 209 | input.span1,textarea.span1,.uneditable-input.span1{width:46px} |
|
210 | 210 | .controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0} |
|
211 | 211 | .controls-row:after{clear:both} |
|
212 | 212 | .controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left} |
|
213 | 213 | .controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px} |
|
214 | 214 | input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee} |
|
215 | 215 | input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent} |
|
216 | 216 | .control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853} |
|
217 | 217 | .control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853} |
|
218 | 218 | .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} |
|
219 | 219 | .control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853} |
|
220 | 220 | .control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48} |
|
221 | 221 | .control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48} |
|
222 | 222 | .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} |
|
223 | 223 | .control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48} |
|
224 | 224 | .control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847} |
|
225 | 225 | .control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847} |
|
226 | 226 | .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} |
|
227 | 227 | .control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847} |
|
228 | 228 | .control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad} |
|
229 | 229 | .control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad} |
|
230 | 230 | .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} |
|
231 | 231 | .control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad} |
|
232 | 232 | 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} |
|
233 | 233 | .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} |
|
234 | 234 | .form-actions:after{clear:both} |
|
235 | 235 | .help-block,.help-inline{color:#262626} |
|
236 | 236 | .help-block{display:block;margin-bottom:10px} |
|
237 | 237 | .help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px} |
|
238 | 238 | .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} |
|
239 | 239 | .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;border-radius:0 4px 4px 0;-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} |
|
240 | 240 | .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 #fff;background-color:#eee;border:1px solid #ccc} |
|
241 | 241 | .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;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
242 | 242 | .input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546} |
|
243 | 243 | .input-prepend .add-on,.input-prepend .btn{margin-right:-1px} |
|
244 | 244 | .input-prepend .add-on:first-child,.input-prepend .btn:first-child{border-radius:4px 0 0 4px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px} |
|
245 | 245 | .input-append input,.input-append select,.input-append .uneditable-input{border-radius:4px 0 0 4px;-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{border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0} |
|
246 | 246 | .input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px} |
|
247 | 247 | .input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0} |
|
248 | 248 | .input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{border-radius:0;-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{border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0} |
|
249 | 249 | .input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;border-radius:4px 0 0 4px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px} |
|
250 | 250 | .input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0} |
|
251 | 251 | .input-prepend.input-append .btn-group:first-child{margin-left:0} |
|
252 | 252 | input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px} |
|
253 | 253 | .form-search .input-append .search-query,.form-search .input-prepend .search-query{border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
254 | 254 | .form-search .input-append .search-query{border-radius:14px 0 0 14px;-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px} |
|
255 | 255 | .form-search .input-append .btn{border-radius:0 14px 14px 0;-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0} |
|
256 | 256 | .form-search .input-prepend .search-query{border-radius:0 14px 14px 0;-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0} |
|
257 | 257 | .form-search .input-prepend .btn{border-radius:14px 0 0 14px;-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px} |
|
258 | 258 | .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} |
|
259 | 259 | .form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none} |
|
260 | 260 | .form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block} |
|
261 | 261 | .form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0} |
|
262 | 262 | .form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle} |
|
263 | 263 | .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} |
|
264 | 264 | .control-group{margin-bottom:10px} |
|
265 | 265 | legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate} |
|
266 | 266 | .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} |
|
267 | 267 | .form-horizontal .control-group:after{clear:both} |
|
268 | 268 | .form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right} |
|
269 | 269 | .form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px} |
|
270 | 270 | .form-horizontal .help-block{margin-bottom:0} |
|
271 | 271 | .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} |
|
272 | 272 | .form-horizontal .form-actions{padding-left:180px} |
|
273 | 273 | table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0} |
|
274 | 274 | .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 #ddd} |
|
275 | 275 | .table th{font-weight:bold} |
|
276 | 276 | .table thead th{vertical-align:bottom} |
|
277 | 277 | .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} |
|
278 | 278 | .table tbody+tbody{border-top:2px solid #ddd} |
|
279 | 279 | .table .table{background-color:#fff} |
|
280 | 280 | .table-condensed th,.table-condensed td{padding:4px 5px} |
|
281 | 281 | .table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd} |
|
282 | 282 | .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} |
|
283 | 283 | .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} |
|
284 | 284 | .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} |
|
285 | 285 | .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} |
|
286 | 286 | .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} |
|
287 | 287 | .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} |
|
288 | 288 | .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} |
|
289 | 289 | .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} |
|
290 | 290 | .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} |
|
291 | 291 | .table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9} |
|
292 | 292 | .table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5} |
|
293 | 293 | 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} |
|
294 | 294 | .table td.span1,.table th.span1{float:none;width:44px;margin-left:0} |
|
295 | 295 | .table td.span2,.table th.span2{float:none;width:124px;margin-left:0} |
|
296 | 296 | .table td.span3,.table th.span3{float:none;width:204px;margin-left:0} |
|
297 | 297 | .table td.span4,.table th.span4{float:none;width:284px;margin-left:0} |
|
298 | 298 | .table td.span5,.table th.span5{float:none;width:364px;margin-left:0} |
|
299 | 299 | .table td.span6,.table th.span6{float:none;width:444px;margin-left:0} |
|
300 | 300 | .table td.span7,.table th.span7{float:none;width:524px;margin-left:0} |
|
301 | 301 | .table td.span8,.table th.span8{float:none;width:604px;margin-left:0} |
|
302 | 302 | .table td.span9,.table th.span9{float:none;width:684px;margin-left:0} |
|
303 | 303 | .table td.span10,.table th.span10{float:none;width:764px;margin-left:0} |
|
304 | 304 | .table td.span11,.table th.span11{float:none;width:844px;margin-left:0} |
|
305 | 305 | .table td.span12,.table th.span12{float:none;width:924px;margin-left:0} |
|
306 | 306 | .table tbody tr.success>td{background-color:#dff0d8} |
|
307 | 307 | .table tbody tr.error>td{background-color:#f2dede} |
|
308 | 308 | .table tbody tr.warning>td{background-color:#fcf8e3} |
|
309 | 309 | .table tbody tr.info>td{background-color:#d9edf7} |
|
310 | 310 | .table-hover tbody tr.success:hover>td{background-color:#d0e9c6} |
|
311 | 311 | .table-hover tbody tr.error:hover>td{background-color:#ebcccc} |
|
312 | 312 | .table-hover tbody tr.warning:hover>td{background-color:#faf2cc} |
|
313 | 313 | .table-hover tbody tr.info:hover>td{background-color:#c4e3f3} |
|
314 | 314 | [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} |
|
315 | 315 | .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")} |
|
316 | 316 | .icon-glass{background-position:0 0} |
|
317 | 317 | .icon-music{background-position:-24px 0} |
|
318 | 318 | .icon-search{background-position:-48px 0} |
|
319 | 319 | .icon-envelope{background-position:-72px 0} |
|
320 | 320 | .icon-heart{background-position:-96px 0} |
|
321 | 321 | .icon-star{background-position:-120px 0} |
|
322 | 322 | .icon-star-empty{background-position:-144px 0} |
|
323 | 323 | .icon-user{background-position:-168px 0} |
|
324 | 324 | .icon-film{background-position:-192px 0} |
|
325 | 325 | .icon-th-large{background-position:-216px 0} |
|
326 | 326 | .icon-th{background-position:-240px 0} |
|
327 | 327 | .icon-th-list{background-position:-264px 0} |
|
328 | 328 | .icon-ok{background-position:-288px 0} |
|
329 | 329 | .icon-remove{background-position:-312px 0} |
|
330 | 330 | .icon-zoom-in{background-position:-336px 0} |
|
331 | 331 | .icon-zoom-out{background-position:-360px 0} |
|
332 | 332 | .icon-off{background-position:-384px 0} |
|
333 | 333 | .icon-signal{background-position:-408px 0} |
|
334 | 334 | .icon-cog{background-position:-432px 0} |
|
335 | 335 | .icon-trash{background-position:-456px 0} |
|
336 | 336 | .icon-home{background-position:0 -24px} |
|
337 | 337 | .icon-file{background-position:-24px -24px} |
|
338 | 338 | .icon-time{background-position:-48px -24px} |
|
339 | 339 | .icon-road{background-position:-72px -24px} |
|
340 | 340 | .icon-download-alt{background-position:-96px -24px} |
|
341 | 341 | .icon-download{background-position:-120px -24px} |
|
342 | 342 | .icon-upload{background-position:-144px -24px} |
|
343 | 343 | .icon-inbox{background-position:-168px -24px} |
|
344 | 344 | .icon-play-circle{background-position:-192px -24px} |
|
345 | 345 | .icon-repeat{background-position:-216px -24px} |
|
346 | 346 | .icon-refresh{background-position:-240px -24px} |
|
347 | 347 | .icon-list-alt{background-position:-264px -24px} |
|
348 | 348 | .icon-lock{background-position:-287px -24px} |
|
349 | 349 | .icon-flag{background-position:-312px -24px} |
|
350 | 350 | .icon-headphones{background-position:-336px -24px} |
|
351 | 351 | .icon-volume-off{background-position:-360px -24px} |
|
352 | 352 | .icon-volume-down{background-position:-384px -24px} |
|
353 | 353 | .icon-volume-up{background-position:-408px -24px} |
|
354 | 354 | .icon-qrcode{background-position:-432px -24px} |
|
355 | 355 | .icon-barcode{background-position:-456px -24px} |
|
356 | 356 | .icon-tag{background-position:0 -48px} |
|
357 | 357 | .icon-tags{background-position:-25px -48px} |
|
358 | 358 | .icon-book{background-position:-48px -48px} |
|
359 | 359 | .icon-bookmark{background-position:-72px -48px} |
|
360 | 360 | .icon-print{background-position:-96px -48px} |
|
361 | 361 | .icon-camera{background-position:-120px -48px} |
|
362 | 362 | .icon-font{background-position:-144px -48px} |
|
363 | 363 | .icon-bold{background-position:-167px -48px} |
|
364 | 364 | .icon-italic{background-position:-192px -48px} |
|
365 | 365 | .icon-text-height{background-position:-216px -48px} |
|
366 | 366 | .icon-text-width{background-position:-240px -48px} |
|
367 | 367 | .icon-align-left{background-position:-264px -48px} |
|
368 | 368 | .icon-align-center{background-position:-288px -48px} |
|
369 | 369 | .icon-align-right{background-position:-312px -48px} |
|
370 | 370 | .icon-align-justify{background-position:-336px -48px} |
|
371 | 371 | .icon-list{background-position:-360px -48px} |
|
372 | 372 | .icon-indent-left{background-position:-384px -48px} |
|
373 | 373 | .icon-indent-right{background-position:-408px -48px} |
|
374 | 374 | .icon-facetime-video{background-position:-432px -48px} |
|
375 | 375 | .icon-picture{background-position:-456px -48px} |
|
376 | 376 | .icon-pencil{background-position:0 -72px} |
|
377 | 377 | .icon-map-marker{background-position:-24px -72px} |
|
378 | 378 | .icon-adjust{background-position:-48px -72px} |
|
379 | 379 | .icon-tint{background-position:-72px -72px} |
|
380 | 380 | .icon-edit{background-position:-96px -72px} |
|
381 | 381 | .icon-share{background-position:-120px -72px} |
|
382 | 382 | .icon-check{background-position:-144px -72px} |
|
383 | 383 | .icon-move{background-position:-168px -72px} |
|
384 | 384 | .icon-step-backward{background-position:-192px -72px} |
|
385 | 385 | .icon-fast-backward{background-position:-216px -72px} |
|
386 | 386 | .icon-backward{background-position:-240px -72px} |
|
387 | 387 | .icon-play{background-position:-264px -72px} |
|
388 | 388 | .icon-pause{background-position:-288px -72px} |
|
389 | 389 | .icon-stop{background-position:-312px -72px} |
|
390 | 390 | .icon-forward{background-position:-336px -72px} |
|
391 | 391 | .icon-fast-forward{background-position:-360px -72px} |
|
392 | 392 | .icon-step-forward{background-position:-384px -72px} |
|
393 | 393 | .icon-eject{background-position:-408px -72px} |
|
394 | 394 | .icon-chevron-left{background-position:-432px -72px} |
|
395 | 395 | .icon-chevron-right{background-position:-456px -72px} |
|
396 | 396 | .icon-plus-sign{background-position:0 -96px} |
|
397 | 397 | .icon-minus-sign{background-position:-24px -96px} |
|
398 | 398 | .icon-remove-sign{background-position:-48px -96px} |
|
399 | 399 | .icon-ok-sign{background-position:-72px -96px} |
|
400 | 400 | .icon-question-sign{background-position:-96px -96px} |
|
401 | 401 | .icon-info-sign{background-position:-120px -96px} |
|
402 | 402 | .icon-screenshot{background-position:-144px -96px} |
|
403 | 403 | .icon-remove-circle{background-position:-168px -96px} |
|
404 | 404 | .icon-ok-circle{background-position:-192px -96px} |
|
405 | 405 | .icon-ban-circle{background-position:-216px -96px} |
|
406 | 406 | .icon-arrow-left{background-position:-240px -96px} |
|
407 | 407 | .icon-arrow-right{background-position:-264px -96px} |
|
408 | 408 | .icon-arrow-up{background-position:-289px -96px} |
|
409 | 409 | .icon-arrow-down{background-position:-312px -96px} |
|
410 | 410 | .icon-share-alt{background-position:-336px -96px} |
|
411 | 411 | .icon-resize-full{background-position:-360px -96px} |
|
412 | 412 | .icon-resize-small{background-position:-384px -96px} |
|
413 | 413 | .icon-plus{background-position:-408px -96px} |
|
414 | 414 | .icon-minus{background-position:-433px -96px} |
|
415 | 415 | .icon-asterisk{background-position:-456px -96px} |
|
416 | 416 | .icon-exclamation-sign{background-position:0 -120px} |
|
417 | 417 | .icon-gift{background-position:-24px -120px} |
|
418 | 418 | .icon-leaf{background-position:-48px -120px} |
|
419 | 419 | .icon-fire{background-position:-72px -120px} |
|
420 | 420 | .icon-eye-open{background-position:-96px -120px} |
|
421 | 421 | .icon-eye-close{background-position:-120px -120px} |
|
422 | 422 | .icon-warning-sign{background-position:-144px -120px} |
|
423 | 423 | .icon-plane{background-position:-168px -120px} |
|
424 | 424 | .icon-calendar{background-position:-192px -120px} |
|
425 | 425 | .icon-random{background-position:-216px -120px;width:16px} |
|
426 | 426 | .icon-comment{background-position:-240px -120px} |
|
427 | 427 | .icon-magnet{background-position:-264px -120px} |
|
428 | 428 | .icon-chevron-up{background-position:-288px -120px} |
|
429 | 429 | .icon-chevron-down{background-position:-313px -119px} |
|
430 | 430 | .icon-retweet{background-position:-336px -120px} |
|
431 | 431 | .icon-shopping-cart{background-position:-360px -120px} |
|
432 | 432 | .icon-folder-close{background-position:-384px -120px;width:16px} |
|
433 | 433 | .icon-folder-open{background-position:-408px -120px;width:16px} |
|
434 | 434 | .icon-resize-vertical{background-position:-432px -119px} |
|
435 | 435 | .icon-resize-horizontal{background-position:-456px -118px} |
|
436 | 436 | .icon-hdd{background-position:0 -144px} |
|
437 | 437 | .icon-bullhorn{background-position:-24px -144px} |
|
438 | 438 | .icon-bell{background-position:-48px -144px} |
|
439 | 439 | .icon-certificate{background-position:-72px -144px} |
|
440 | 440 | .icon-thumbs-up{background-position:-96px -144px} |
|
441 | 441 | .icon-thumbs-down{background-position:-120px -144px} |
|
442 | 442 | .icon-hand-right{background-position:-144px -144px} |
|
443 | 443 | .icon-hand-left{background-position:-168px -144px} |
|
444 | 444 | .icon-hand-up{background-position:-192px -144px} |
|
445 | 445 | .icon-hand-down{background-position:-216px -144px} |
|
446 | 446 | .icon-circle-arrow-right{background-position:-240px -144px} |
|
447 | 447 | .icon-circle-arrow-left{background-position:-264px -144px} |
|
448 | 448 | .icon-circle-arrow-up{background-position:-288px -144px} |
|
449 | 449 | .icon-circle-arrow-down{background-position:-312px -144px} |
|
450 | 450 | .icon-globe{background-position:-336px -144px} |
|
451 | 451 | .icon-wrench{background-position:-360px -144px} |
|
452 | 452 | .icon-tasks{background-position:-384px -144px} |
|
453 | 453 | .icon-filter{background-position:-408px -144px} |
|
454 | 454 | .icon-briefcase{background-position:-432px -144px} |
|
455 | 455 | .icon-fullscreen{background-position:-456px -144px} |
|
456 | 456 | .dropup,.dropdown{position:relative} |
|
457 | 457 | .dropdown-toggle{*margin-bottom:-3px} |
|
458 | 458 | .dropdown-toggle:active,.open .dropdown-toggle{outline:0} |
|
459 | 459 | .caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""} |
|
460 | 460 | .dropdown .caret{margin-top:8px;margin-left:2px} |
|
461 | 461 | .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:#fff;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} |
|
462 | 462 | .dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff} |
|
463 | 463 | .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap} |
|
464 | 464 | .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0)} |
|
465 | 465 | .dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0)} |
|
466 | 466 | .dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999} |
|
467 | 467 | .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} |
|
468 | 468 | .open{*z-index:1000}.open>.dropdown-menu{display:block} |
|
469 | 469 | .dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990} |
|
470 | 470 | .pull-right>.dropdown-menu{right:0;left:auto} |
|
471 | 471 | .dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""} |
|
472 | 472 | .dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px} |
|
473 | 473 | .dropdown-submenu{position:relative} |
|
474 | 474 | .dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;border-radius:0 6px 6px 6px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px} |
|
475 | 475 | .dropdown-submenu:hover>.dropdown-menu{display:block} |
|
476 | 476 | .dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;border-radius:5px 5px 5px 0;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0} |
|
477 | 477 | .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:#ccc;margin-top:5px;margin-right:-10px} |
|
478 | 478 | .dropdown-submenu:hover>a:after{border-left-color:#fff} |
|
479 | 479 | .dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;border-radius:6px 0 6px 6px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px} |
|
480 | 480 | .dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px} |
|
481 | 481 | .typeahead{z-index:1051;margin-top:2px;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} |
|
482 | 482 | .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)} |
|
483 | 483 | .well-large{padding:24px;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} |
|
484 | 484 | .well-small{padding:9px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} |
|
485 | 485 | .fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1} |
|
486 | 486 | .collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto} |
|
487 | 487 | .close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)} |
|
488 | 488 | button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none} |
|
489 | 489 | .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:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #fff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #fff, #e6e6e6);background-image:-o-linear-gradient(top, #fff, #e6e6e6);background-image:linear-gradient(to bottom, #fff, #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 #ccc;*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:#333;background-color:#e6e6e6;*background-color:#d9d9d9} |
|
490 | 490 | .btn:active,.btn.active{background-color:#ccc \9} |
|
491 | 491 | .btn:first-child{*margin-left:0} |
|
492 | 492 | .btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear} |
|
493 | 493 | .btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} |
|
494 | 494 | .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)} |
|
495 | 495 | .btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none} |
|
496 | 496 | .btn-large{padding:11px 19px;font-size:16.25px;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} |
|
497 | 497 | .btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px} |
|
498 | 498 | .btn-small{padding:2px 10px;font-size:11.049999999999999px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} |
|
499 | 499 | .btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0} |
|
500 | 500 | .btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px} |
|
501 | 501 | .btn-mini{padding:0 6px;font-size:9.75px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} |
|
502 | 502 | .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} |
|
503 | 503 | .btn-block+.btn-block{margin-top:5px} |
|
504 | 504 | input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%} |
|
505 | 505 | .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)} |
|
506 | 506 | .btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #08c, #04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;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:#fff;background-color:#04c;*background-color:#003bb3} |
|
507 | 507 | .btn-primary:active,.btn-primary.active{background-color:#039 \9} |
|
508 | 508 | .btn-warning{color:#fff;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:#fff;background-color:#f89406;*background-color:#df8505} |
|
509 | 509 | .btn-warning:active,.btn-warning.active{background-color:#c67605 \9} |
|
510 | 510 | .btn-danger{color:#fff;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:#fff;background-color:#bd362f;*background-color:#a9302a} |
|
511 | 511 | .btn-danger:active,.btn-danger.active{background-color:#942a25 \9} |
|
512 | 512 | .btn-success{color:#fff;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:#fff;background-color:#51a351;*background-color:#499249} |
|
513 | 513 | .btn-success:active,.btn-success.active{background-color:#408140 \9} |
|
514 | 514 | .btn-info{color:#fff;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:#fff;background-color:#2f96b4;*background-color:#2a85a0} |
|
515 | 515 | .btn-info:active,.btn-info.active{background-color:#24748c \9} |
|
516 | 516 | .btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444, #222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444), to(#222));background-image:-webkit-linear-gradient(top, #444, #222);background-image:-o-linear-gradient(top, #444, #222);background-image:linear-gradient(to bottom, #444, #222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#222;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:#fff;background-color:#222;*background-color:#151515} |
|
517 | 517 | .btn-inverse:active,.btn-inverse.active{background-color:#080808 \9} |
|
518 | 518 | 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} |
|
519 | 519 | button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px} |
|
520 | 520 | button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px} |
|
521 | 521 | button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px} |
|
522 | 522 | .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} |
|
523 | 523 | .btn-link{border-color:transparent;cursor:pointer;color:#08c;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
524 | 524 | .btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent} |
|
525 | 525 | .btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none} |
|
526 | 526 | .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} |
|
527 | 527 | .btn-group+.btn-group{margin-left:5px} |
|
528 | 528 | .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} |
|
529 | 529 | .btn-group>.btn{position:relative;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
530 | 530 | .btn-group>.btn+.btn{margin-left:-1px} |
|
531 | 531 | .btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:13px} |
|
532 | 532 | .btn-group>.btn-mini{font-size:9.75px} |
|
533 | 533 | .btn-group>.btn-small{font-size:11.049999999999999px} |
|
534 | 534 | .btn-group>.btn-large{font-size:16.25px} |
|
535 | 535 | .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} |
|
536 | 536 | .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} |
|
537 | 537 | .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} |
|
538 | 538 | .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} |
|
539 | 539 | .btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2} |
|
540 | 540 | .btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0} |
|
541 | 541 | .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} |
|
542 | 542 | .btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px} |
|
543 | 543 | .btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px} |
|
544 | 544 | .btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px} |
|
545 | 545 | .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)} |
|
546 | 546 | .btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6} |
|
547 | 547 | .btn-group.open .btn-primary.dropdown-toggle{background-color:#04c} |
|
548 | 548 | .btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406} |
|
549 | 549 | .btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f} |
|
550 | 550 | .btn-group.open .btn-success.dropdown-toggle{background-color:#51a351} |
|
551 | 551 | .btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4} |
|
552 | 552 | .btn-group.open .btn-inverse.dropdown-toggle{background-color:#222} |
|
553 | 553 | .btn .caret{margin-top:8px;margin-left:0} |
|
554 | 554 | .btn-large .caret{margin-top:6px} |
|
555 | 555 | .btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px} |
|
556 | 556 | .btn-mini .caret,.btn-small .caret{margin-top:8px} |
|
557 | 557 | .dropup .btn-large .caret{border-bottom-width:5px} |
|
558 | 558 | .btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff} |
|
559 | 559 | .btn-group-vertical{display:inline-block;*display:inline;*zoom:1} |
|
560 | 560 | .btn-group-vertical>.btn{display:block;float:none;max-width:100%;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
561 | 561 | .btn-group-vertical>.btn+.btn{margin-left:0;margin-top:-1px} |
|
562 | 562 | .btn-group-vertical>.btn:first-child{border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0} |
|
563 | 563 | .btn-group-vertical>.btn:last-child{border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px} |
|
564 | 564 | .btn-group-vertical>.btn-large:first-child{border-radius:6px 6px 0 0;-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0} |
|
565 | 565 | .btn-group-vertical>.btn-large:last-child{border-radius:0 0 6px 6px;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px} |
|
566 | 566 | .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;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} |
|
567 | 567 | .alert,.alert h4{color:#c09853} |
|
568 | 568 | .alert h4{margin:0} |
|
569 | 569 | .alert .close{position:relative;top:-2px;right:-21px;line-height:20px} |
|
570 | 570 | .alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847} |
|
571 | 571 | .alert-success h4{color:#468847} |
|
572 | 572 | .alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48} |
|
573 | 573 | .alert-danger h4,.alert-error h4{color:#b94a48} |
|
574 | 574 | .alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad} |
|
575 | 575 | .alert-info h4{color:#3a87ad} |
|
576 | 576 | .alert-block{padding-top:14px;padding-bottom:14px} |
|
577 | 577 | .alert-block>p,.alert-block>ul{margin-bottom:0} |
|
578 | 578 | .alert-block p+p{margin-top:5px} |
|
579 | 579 | .nav{margin-left:0;margin-bottom:20px;list-style:none} |
|
580 | 580 | .nav>li>a{display:block} |
|
581 | 581 | .nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee} |
|
582 | 582 | .nav>li>a>img{max-width:none} |
|
583 | 583 | .nav>.pull-right{float:right} |
|
584 | 584 | .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase} |
|
585 | 585 | .nav li+.nav-header{margin-top:9px} |
|
586 | 586 | .nav-list{padding-left:15px;padding-right:15px;margin-bottom:0} |
|
587 | 587 | .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)} |
|
588 | 588 | .nav-list>li>a{padding:3px 15px} |
|
589 | 589 | .nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c} |
|
590 | 590 | .nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px} |
|
591 | 591 | .nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff} |
|
592 | 592 | .nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0} |
|
593 | 593 | .nav-tabs:after,.nav-pills:after{clear:both} |
|
594 | 594 | .nav-tabs>li,.nav-pills>li{float:left} |
|
595 | 595 | .nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px} |
|
596 | 596 | .nav-tabs{border-bottom:1px solid #ddd} |
|
597 | 597 | .nav-tabs>li{margin-bottom:-1px} |
|
598 | 598 | .nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;border-radius:4px 4px 0 0;-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:#eee #eee #ddd} |
|
599 | 599 | .nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default} |
|
600 | 600 | .nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px} |
|
601 | 601 | .nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c} |
|
602 | 602 | .nav-stacked>li{float:none} |
|
603 | 603 | .nav-stacked>li>a{margin-right:0} |
|
604 | 604 | .nav-tabs.nav-stacked{border-bottom:0} |
|
605 | 605 | .nav-tabs.nav-stacked>li>a{border:1px solid #ddd;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
606 | 606 | .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} |
|
607 | 607 | .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} |
|
608 | 608 | .nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{border-color:#ddd;z-index:2} |
|
609 | 609 | .nav-pills.nav-stacked>li>a{margin-bottom:3px} |
|
610 | 610 | .nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px} |
|
611 | 611 | .nav-tabs .dropdown-menu{border-radius:0 0 6px 6px;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px} |
|
612 | 612 | .nav-pills .dropdown-menu{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} |
|
613 | 613 | .nav .dropdown-toggle .caret{border-top-color:#08c;border-bottom-color:#08c;margin-top:6px} |
|
614 | 614 | .nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580} |
|
615 | 615 | .nav-tabs .dropdown-toggle .caret{margin-top:8px} |
|
616 | 616 | .nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff} |
|
617 | 617 | .nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555} |
|
618 | 618 | .nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer} |
|
619 | 619 | .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:#fff;background-color:#999;border-color:#999} |
|
620 | 620 | .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:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)} |
|
621 | 621 | .tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999} |
|
622 | 622 | .tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0} |
|
623 | 623 | .tabbable:after{clear:both} |
|
624 | 624 | .tab-content{overflow:auto} |
|
625 | 625 | .tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0} |
|
626 | 626 | .tab-content>.tab-pane,.pill-content>.pill-pane{display:none} |
|
627 | 627 | .tab-content>.active,.pill-content>.active{display:block} |
|
628 | 628 | .tabs-below>.nav-tabs{border-top:1px solid #ddd} |
|
629 | 629 | .tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0} |
|
630 | 630 | .tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px;-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} |
|
631 | 631 | .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} |
|
632 | 632 | .tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none} |
|
633 | 633 | .tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px} |
|
634 | 634 | .tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd} |
|
635 | 635 | .tabs-left>.nav-tabs>li>a{margin-right:-1px;border-radius:4px 0 0 4px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px} |
|
636 | 636 | .tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee} |
|
637 | 637 | .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:#fff} |
|
638 | 638 | .tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd} |
|
639 | 639 | .tabs-right>.nav-tabs>li>a{margin-left:-1px;border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0} |
|
640 | 640 | .tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd} |
|
641 | 641 | .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:#fff} |
|
642 | 642 | .nav>.disabled>a{color:#999} |
|
643 | 643 | .nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;background-color:transparent;cursor:default} |
|
644 | 644 | .navbar{overflow:visible;margin-bottom:20px;*position:relative;*z-index:2} |
|
645 | 645 | .navbar-inner{min-height:36px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #fff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #fff, #f2f2f2);background-image:-o-linear-gradient(top, #fff, #f2f2f2);background-image:linear-gradient(to bottom, #fff, #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} |
|
646 | 646 | .navbar-inner:after{clear:both} |
|
647 | 647 | .navbar .container{width:auto} |
|
648 | 648 | .nav-collapse.collapse{height:auto;overflow:visible} |
|
649 | 649 | .navbar .brand{float:left;display:block;padding:8px 20px 8px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none} |
|
650 | 650 | .navbar-text{margin-bottom:0;line-height:36px;color:#777} |
|
651 | 651 | .navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333} |
|
652 | 652 | .navbar .divider-vertical{height:36px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #fff} |
|
653 | 653 | .navbar .btn,.navbar .btn-group{margin-top:3px} |
|
654 | 654 | .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} |
|
655 | 655 | .navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0} |
|
656 | 656 | .navbar-form:after{clear:both} |
|
657 | 657 | .navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:3px} |
|
658 | 658 | .navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0} |
|
659 | 659 | .navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px} |
|
660 | 660 | .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} |
|
661 | 661 | .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;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px} |
|
662 | 662 | .navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
663 | 663 | .navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0} |
|
664 | 664 | .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px} |
|
665 | 665 | .navbar-fixed-bottom .navbar-inner{border-width:1px 0 0} |
|
666 | 666 | .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
667 | 667 | .navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px} |
|
668 | 668 | .navbar-fixed-top{top:0} |
|
669 | 669 | .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)} |
|
670 | 670 | .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)} |
|
671 | 671 | .navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0} |
|
672 | 672 | .navbar .nav.pull-right{float:right;margin-right:0} |
|
673 | 673 | .navbar .nav>li{float:left} |
|
674 | 674 | .navbar .nav>li>a{float:none;padding:8px 15px 8px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff} |
|
675 | 675 | .navbar .nav .dropdown-toggle .caret{margin-top:8px} |
|
676 | 676 | .navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333;text-decoration:none} |
|
677 | 677 | .navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;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)} |
|
678 | 678 | .navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#fff;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:#fff;background-color:#e5e5e5;*background-color:#d9d9d9} |
|
679 | 679 | .navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9} |
|
680 | 680 | .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)} |
|
681 | 681 | .btn-navbar .icon-bar+.icon-bar{margin-top:3px} |
|
682 | 682 | .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} |
|
683 | 683 | .navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:10px} |
|
684 | 684 | .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} |
|
685 | 685 | .navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #fff;border-bottom:0;bottom:-6px;top:auto} |
|
686 | 686 | .navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333} |
|
687 | 687 | .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:#555} |
|
688 | 688 | .navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777} |
|
689 | 689 | .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:#555;border-bottom-color:#555} |
|
690 | 690 | .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} |
|
691 | 691 | .navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px} |
|
692 | 692 | .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;border-radius:6px 0 6px 6px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px} |
|
693 | 693 | .navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222, #111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222), to(#111));background-image:-webkit-linear-gradient(top, #222, #111);background-image:-o-linear-gradient(top, #222, #111);background-image:linear-gradient(to bottom, #222, #111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525} |
|
694 | 694 | .navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;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:#fff} |
|
695 | 695 | .navbar-inverse .brand{color:#999} |
|
696 | 696 | .navbar-inverse .navbar-text{color:#999} |
|
697 | 697 | .navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#fff} |
|
698 | 698 | .navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111} |
|
699 | 699 | .navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff} |
|
700 | 700 | .navbar-inverse .divider-vertical{border-left-color:#111;border-right-color:#222} |
|
701 | 701 | .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:#111;color:#fff} |
|
702 | 702 | .navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff} |
|
703 | 703 | .navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999} |
|
704 | 704 | .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:#fff;border-bottom-color:#fff} |
|
705 | 705 | .navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-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:#ccc} |
|
706 | 706 | .navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc} |
|
707 | 707 | .navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc} |
|
708 | 708 | .navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;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} |
|
709 | 709 | .navbar-inverse .btn-navbar{color:#fff;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 #000;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:#fff;background-color:#040404;*background-color:#000} |
|
710 | 710 | .navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9} |
|
711 | 711 | .breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;border-radius:4px;-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 #fff}.breadcrumb>li>.divider{padding:0 5px;color:#ccc} |
|
712 | 712 | .breadcrumb>.active{color:#999} |
|
713 | 713 | .pagination{margin:20px 0} |
|
714 | 714 | .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)} |
|
715 | 715 | .pagination ul>li{display:inline} |
|
716 | 716 | .pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0} |
|
717 | 717 | .pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5} |
|
718 | 718 | .pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default} |
|
719 | 719 | .pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;background-color:transparent;cursor:default} |
|
720 | 720 | .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} |
|
721 | 721 | .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} |
|
722 | 722 | .pagination-centered{text-align:center} |
|
723 | 723 | .pagination-right{text-align:right} |
|
724 | 724 | .pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:16.25px} |
|
725 | 725 | .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} |
|
726 | 726 | .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} |
|
727 | 727 | .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} |
|
728 | 728 | .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} |
|
729 | 729 | .pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.049999999999999px} |
|
730 | 730 | .pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:9.75px} |
|
731 | 731 | .pager{margin:20px 0;list-style:none;text-align:center;*zoom:1}.pager:before,.pager:after{display:table;content:"";line-height:0} |
|
732 | 732 | .pager:after{clear:both} |
|
733 | 733 | .pager li{display:inline} |
|
734 | 734 | .pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px} |
|
735 | 735 | .pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5} |
|
736 | 736 | .pager .next>a,.pager .next>span{float:right} |
|
737 | 737 | .pager .previous>a,.pager .previous>span{float:left} |
|
738 | 738 | .pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:default} |
|
739 | 739 | .modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0} |
|
740 | 740 | .modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)} |
|
741 | 741 | .modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;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%} |
|
742 | 742 | .modal.fade.in{top:10%} |
|
743 | 743 | .modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px} |
|
744 | 744 | .modal-header h3{margin:0;line-height:30px} |
|
745 | 745 | .modal-body{position:relative;overflow-y:auto;max-height:400px;padding:15px} |
|
746 | 746 | .modal-form{margin-bottom:0} |
|
747 | 747 | .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 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff;*zoom:1}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0} |
|
748 | 748 | .modal-footer:after{clear:both} |
|
749 | 749 | .modal-footer .btn+.btn{margin-left:5px;margin-bottom:0} |
|
750 | 750 | .modal-footer .btn-group .btn+.btn{margin-left:-1px} |
|
751 | 751 | .modal-footer .btn-block+.btn-block{margin-left:0} |
|
752 | 752 | .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:.8;filter:alpha(opacity=80)} |
|
753 | 753 | .tooltip.top{margin-top:-3px;padding:5px 0} |
|
754 | 754 | .tooltip.right{margin-left:3px;padding:0 5px} |
|
755 | 755 | .tooltip.bottom{margin-top:3px;padding:5px 0} |
|
756 | 756 | .tooltip.left{margin-left:-3px;padding:0 5px} |
|
757 | 757 | .tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} |
|
758 | 758 | .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid} |
|
759 | 759 | .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000} |
|
760 | 760 | .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000} |
|
761 | 761 | .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000} |
|
762 | 762 | .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000} |
|
763 | 763 | .popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;-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} |
|
764 | 764 | .popover.right{margin-left:10px} |
|
765 | 765 | .popover.bottom{margin-top:10px} |
|
766 | 766 | .popover.left{margin-left:-10px} |
|
767 | 767 | .popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0;-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} |
|
768 | 768 | .popover-content{padding:9px 14px} |
|
769 | 769 | .popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid} |
|
770 | 770 | .popover .arrow{border-width:11px} |
|
771 | 771 | .popover .arrow:after{border-width:10px;content:""} |
|
772 | 772 | .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:#fff} |
|
773 | 773 | .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:#fff} |
|
774 | 774 | .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:#fff} |
|
775 | 775 | .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:#fff;bottom:-10px} |
|
776 | 776 | .thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0} |
|
777 | 777 | .thumbnails:after{clear:both} |
|
778 | 778 | .row-fluid .thumbnails{margin-left:0} |
|
779 | 779 | .thumbnails>li{float:left;margin-bottom:20px;margin-left:20px} |
|
780 | 780 | .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 .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out} |
|
781 | 781 | a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-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)} |
|
782 | 782 | .thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto} |
|
783 | 783 | .thumbnail .caption{padding:9px;color:#555} |
|
784 | 784 | .media,.media-body{overflow:hidden;*overflow:visible;zoom:1} |
|
785 | 785 | .media,.media .media{margin-top:15px} |
|
786 | 786 | .media:first-child{margin-top:0} |
|
787 | 787 | .media-object{display:block} |
|
788 | 788 | .media-heading{margin:0 0 5px} |
|
789 | 789 | .media>.pull-left{margin-right:10px} |
|
790 | 790 | .media>.pull-right{margin-left:10px} |
|
791 | 791 | .media-list{margin-left:0;list-style:none} |
|
792 | 792 | .label,.badge{display:inline-block;padding:2px 4px;font-size:10.998px;font-weight:bold;line-height:14px;color:#fff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#999} |
|
793 | 793 | .label{border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} |
|
794 | 794 | .badge{padding-left:9px;padding-right:9px;border-radius:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px} |
|
795 | 795 | .label:empty,.badge:empty{display:none} |
|
796 | 796 | a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer} |
|
797 | 797 | .label-important,.badge-important{background-color:#b94a48} |
|
798 | 798 | .label-important[href],.badge-important[href]{background-color:#953b39} |
|
799 | 799 | .label-warning,.badge-warning{background-color:#f89406} |
|
800 | 800 | .label-warning[href],.badge-warning[href]{background-color:#c67605} |
|
801 | 801 | .label-success,.badge-success{background-color:#468847} |
|
802 | 802 | .label-success[href],.badge-success[href]{background-color:#356635} |
|
803 | 803 | .label-info,.badge-info{background-color:#3a87ad} |
|
804 | 804 | .label-info[href],.badge-info[href]{background-color:#2d6987} |
|
805 | 805 | .label-inverse,.badge-inverse{background-color:#333} |
|
806 | 806 | .label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a} |
|
807 | 807 | .btn .label,.btn .badge{position:relative;top:-1px} |
|
808 | 808 | .btn-mini .label,.btn-mini .badge{top:0} |
|
809 | 809 | @-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);border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} |
|
810 | 810 | .progress .bar{width:0;height:100%;color:#fff;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 .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease} |
|
811 | 811 | .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)} |
|
812 | 812 | .progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.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} |
|
813 | 813 | .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} |
|
814 | 814 | .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)} |
|
815 | 815 | .progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.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)} |
|
816 | 816 | .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)} |
|
817 | 817 | .progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.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)} |
|
818 | 818 | .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)} |
|
819 | 819 | .progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.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)} |
|
820 | 820 | .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)} |
|
821 | 821 | .progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.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)} |
|
822 | 822 | .accordion{margin-bottom:20px} |
|
823 | 823 | .accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} |
|
824 | 824 | .accordion-heading{border-bottom:0} |
|
825 | 825 | .accordion-heading .accordion-toggle{display:block;padding:8px 15px} |
|
826 | 826 | .accordion-toggle{cursor:pointer} |
|
827 | 827 | .accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5} |
|
828 | 828 | .carousel{position:relative;margin-bottom:20px;line-height:1} |
|
829 | 829 | .carousel-inner{overflow:hidden;width:100%;position:relative} |
|
830 | 830 | .carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1} |
|
831 | 831 | .carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block} |
|
832 | 832 | .carousel-inner>.active{left:0} |
|
833 | 833 | .carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%} |
|
834 | 834 | .carousel-inner>.next{left:100%} |
|
835 | 835 | .carousel-inner>.prev{left:-100%} |
|
836 | 836 | .carousel-inner>.next.left,.carousel-inner>.prev.right{left:0} |
|
837 | 837 | .carousel-inner>.active.left{left:-100%} |
|
838 | 838 | .carousel-inner>.active.right{left:100%} |
|
839 | 839 | .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:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{left:auto;right:15px} |
|
840 | 840 | .carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)} |
|
841 | 841 | .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} |
|
842 | 842 | .carousel-indicators .active{background-color:#fff} |
|
843 | 843 | .carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)} |
|
844 | 844 | .carousel-caption h4,.carousel-caption p{color:#fff;line-height:20px} |
|
845 | 845 | .carousel-caption h4{margin:0 0 5px} |
|
846 | 846 | .carousel-caption p{margin-bottom:0} |
|
847 | 847 | .hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;border-radius:6px;-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} |
|
848 | 848 | .hero-unit li{line-height:30px} |
|
849 | 849 | .pull-right{float:right} |
|
850 | 850 | .pull-left{float:left} |
|
851 | 851 | .hide{display:none} |
|
852 | 852 | .show{display:block} |
|
853 | 853 | .invisible{visibility:hidden} |
|
854 | 854 | .affix{position:fixed} |
|
855 | 855 | .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0} |
|
856 | 856 | .clearfix:after{clear:both} |
|
857 | 857 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} |
|
858 | 858 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} |
|
859 | 859 | @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden} |
|
860 | 860 | .visible-phone{display:none !important} |
|
861 | 861 | .visible-tablet{display:none !important} |
|
862 | 862 | .hidden-desktop{display:none !important} |
|
863 | 863 | .visible-desktop{display:inherit !important} |
|
864 | 864 | @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} |
|
865 | 865 | @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} [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 [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} .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} [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 [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}}@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:#777;text-shadow:none} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;border-radius:4px;-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:#999} .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:#111} .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:#111;border-bottom-color:#111} .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:979px + 1){.nav-collapse.collapse{height:auto !important;overflow:visible !important}}@font-face{font-family:'FontAwesome';src:url('../components/font-awesome/font/fontawesome-webfont.eot?v=3.2.1');src:url('../components/font-awesome/font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'),url('../components/font-awesome/font/fontawesome-webfont.woff?v=3.2.1') format('woff'),url('../components/font-awesome/font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'),url('../components/font-awesome/font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') 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} |
|
866 | 866 | [class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none} |
|
867 | 867 | .icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em} |
|
868 | 868 | a [class^="icon-"],a [class*=" icon-"]{display:inline} |
|
869 | 869 | [class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:.2857142857142857em}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em} |
|
870 | 870 | .icons-ul{margin-left:2.142857142857143em;list-style-type:none}.icons-ul>li{position:relative} |
|
871 | 871 | .icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit} |
|
872 | 872 | [class^="icon-"].hide,[class*=" icon-"].hide{display:none} |
|
873 | 873 | .icon-muted{color:#eee} |
|
874 | 874 | .icon-light{color:#fff} |
|
875 | 875 | .icon-dark{color:#333} |
|
876 | 876 | .icon-border{border:solid 1px #eee;padding:.2em .25em .15em;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} |
|
877 | 877 | .icon-2x{font-size:2em}.icon-2x.icon-border{border-width:2px;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} |
|
878 | 878 | .icon-3x{font-size:3em}.icon-3x.icon-border{border-width:3px;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px} |
|
879 | 879 | .icon-4x{font-size:4em}.icon-4x.icon-border{border-width:4px;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} |
|
880 | 880 | .icon-5x{font-size:5em}.icon-5x.icon-border{border-width:5px;border-radius:7px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px} |
|
881 | 881 | .pull-right{float:right} |
|
882 | 882 | .pull-left{float:left} |
|
883 | 883 | [class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em} |
|
884 | 884 | [class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em} |
|
885 | 885 | [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} |
|
886 | 886 | .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} |
|
887 | 887 | .btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em} |
|
888 | 888 | .btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block} |
|
889 | 889 | .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} |
|
890 | 890 | .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} |
|
891 | 891 | .btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em} |
|
892 | 892 | .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} |
|
893 | 893 | .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} |
|
894 | 894 | .btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em} |
|
895 | 895 | .btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em} |
|
896 | 896 | .nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit} |
|
897 | 897 | .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} |
|
898 | 898 | .icon-stack .icon-stack-base{font-size:2em;*line-height:1em} |
|
899 | 899 | .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} |
|
900 | 900 | a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none} |
|
901 | 901 | @-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)} |
|
902 | 902 | .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)} |
|
903 | 903 | .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)} |
|
904 | 904 | .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)} |
|
905 | 905 | .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)} |
|
906 | 906 | a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block} |
|
907 | 907 | .icon-glass:before{content:"\f000"} |
|
908 | 908 | .icon-music:before{content:"\f001"} |
|
909 | 909 | .icon-search:before{content:"\f002"} |
|
910 | 910 | .icon-envelope-alt:before{content:"\f003"} |
|
911 | 911 | .icon-heart:before{content:"\f004"} |
|
912 | 912 | .icon-star:before{content:"\f005"} |
|
913 | 913 | .icon-star-empty:before{content:"\f006"} |
|
914 | 914 | .icon-user:before{content:"\f007"} |
|
915 | 915 | .icon-film:before{content:"\f008"} |
|
916 | 916 | .icon-th-large:before{content:"\f009"} |
|
917 | 917 | .icon-th:before{content:"\f00a"} |
|
918 | 918 | .icon-th-list:before{content:"\f00b"} |
|
919 | 919 | .icon-ok:before{content:"\f00c"} |
|
920 | 920 | .icon-remove:before{content:"\f00d"} |
|
921 | 921 | .icon-zoom-in:before{content:"\f00e"} |
|
922 | 922 | .icon-zoom-out:before{content:"\f010"} |
|
923 | 923 | .icon-power-off:before,.icon-off:before{content:"\f011"} |
|
924 | 924 | .icon-signal:before{content:"\f012"} |
|
925 | 925 | .icon-gear:before,.icon-cog:before{content:"\f013"} |
|
926 | 926 | .icon-trash:before{content:"\f014"} |
|
927 | 927 | .icon-home:before{content:"\f015"} |
|
928 | 928 | .icon-file-alt:before{content:"\f016"} |
|
929 | 929 | .icon-time:before{content:"\f017"} |
|
930 | 930 | .icon-road:before{content:"\f018"} |
|
931 | 931 | .icon-download-alt:before{content:"\f019"} |
|
932 | 932 | .icon-download:before{content:"\f01a"} |
|
933 | 933 | .icon-upload:before{content:"\f01b"} |
|
934 | 934 | .icon-inbox:before{content:"\f01c"} |
|
935 | 935 | .icon-play-circle:before{content:"\f01d"} |
|
936 | 936 | .icon-rotate-right:before,.icon-repeat:before{content:"\f01e"} |
|
937 | 937 | .icon-refresh:before{content:"\f021"} |
|
938 | 938 | .icon-list-alt:before{content:"\f022"} |
|
939 | 939 | .icon-lock:before{content:"\f023"} |
|
940 | 940 | .icon-flag:before{content:"\f024"} |
|
941 | 941 | .icon-headphones:before{content:"\f025"} |
|
942 | 942 | .icon-volume-off:before{content:"\f026"} |
|
943 | 943 | .icon-volume-down:before{content:"\f027"} |
|
944 | 944 | .icon-volume-up:before{content:"\f028"} |
|
945 | 945 | .icon-qrcode:before{content:"\f029"} |
|
946 | 946 | .icon-barcode:before{content:"\f02a"} |
|
947 | 947 | .icon-tag:before{content:"\f02b"} |
|
948 | 948 | .icon-tags:before{content:"\f02c"} |
|
949 | 949 | .icon-book:before{content:"\f02d"} |
|
950 | 950 | .icon-bookmark:before{content:"\f02e"} |
|
951 | 951 | .icon-print:before{content:"\f02f"} |
|
952 | 952 | .icon-camera:before{content:"\f030"} |
|
953 | 953 | .icon-font:before{content:"\f031"} |
|
954 | 954 | .icon-bold:before{content:"\f032"} |
|
955 | 955 | .icon-italic:before{content:"\f033"} |
|
956 | 956 | .icon-text-height:before{content:"\f034"} |
|
957 | 957 | .icon-text-width:before{content:"\f035"} |
|
958 | 958 | .icon-align-left:before{content:"\f036"} |
|
959 | 959 | .icon-align-center:before{content:"\f037"} |
|
960 | 960 | .icon-align-right:before{content:"\f038"} |
|
961 | 961 | .icon-align-justify:before{content:"\f039"} |
|
962 | 962 | .icon-list:before{content:"\f03a"} |
|
963 | 963 | .icon-indent-left:before{content:"\f03b"} |
|
964 | 964 | .icon-indent-right:before{content:"\f03c"} |
|
965 | 965 | .icon-facetime-video:before{content:"\f03d"} |
|
966 | 966 | .icon-picture:before{content:"\f03e"} |
|
967 | 967 | .icon-pencil:before{content:"\f040"} |
|
968 | 968 | .icon-map-marker:before{content:"\f041"} |
|
969 | 969 | .icon-adjust:before{content:"\f042"} |
|
970 | 970 | .icon-tint:before{content:"\f043"} |
|
971 | 971 | .icon-edit:before{content:"\f044"} |
|
972 | 972 | .icon-share:before{content:"\f045"} |
|
973 | 973 | .icon-check:before{content:"\f046"} |
|
974 | 974 | .icon-move:before{content:"\f047"} |
|
975 | 975 | .icon-step-backward:before{content:"\f048"} |
|
976 | 976 | .icon-fast-backward:before{content:"\f049"} |
|
977 | 977 | .icon-backward:before{content:"\f04a"} |
|
978 | 978 | .icon-play:before{content:"\f04b"} |
|
979 | 979 | .icon-pause:before{content:"\f04c"} |
|
980 | 980 | .icon-stop:before{content:"\f04d"} |
|
981 | 981 | .icon-forward:before{content:"\f04e"} |
|
982 | 982 | .icon-fast-forward:before{content:"\f050"} |
|
983 | 983 | .icon-step-forward:before{content:"\f051"} |
|
984 | 984 | .icon-eject:before{content:"\f052"} |
|
985 | 985 | .icon-chevron-left:before{content:"\f053"} |
|
986 | 986 | .icon-chevron-right:before{content:"\f054"} |
|
987 | 987 | .icon-plus-sign:before{content:"\f055"} |
|
988 | 988 | .icon-minus-sign:before{content:"\f056"} |
|
989 | 989 | .icon-remove-sign:before{content:"\f057"} |
|
990 | 990 | .icon-ok-sign:before{content:"\f058"} |
|
991 | 991 | .icon-question-sign:before{content:"\f059"} |
|
992 | 992 | .icon-info-sign:before{content:"\f05a"} |
|
993 | 993 | .icon-screenshot:before{content:"\f05b"} |
|
994 | 994 | .icon-remove-circle:before{content:"\f05c"} |
|
995 | 995 | .icon-ok-circle:before{content:"\f05d"} |
|
996 | 996 | .icon-ban-circle:before{content:"\f05e"} |
|
997 | 997 | .icon-arrow-left:before{content:"\f060"} |
|
998 | 998 | .icon-arrow-right:before{content:"\f061"} |
|
999 | 999 | .icon-arrow-up:before{content:"\f062"} |
|
1000 | 1000 | .icon-arrow-down:before{content:"\f063"} |
|
1001 | 1001 | .icon-mail-forward:before,.icon-share-alt:before{content:"\f064"} |
|
1002 | 1002 | .icon-resize-full:before{content:"\f065"} |
|
1003 | 1003 | .icon-resize-small:before{content:"\f066"} |
|
1004 | 1004 | .icon-plus:before{content:"\f067"} |
|
1005 | 1005 | .icon-minus:before{content:"\f068"} |
|
1006 | 1006 | .icon-asterisk:before{content:"\f069"} |
|
1007 | 1007 | .icon-exclamation-sign:before{content:"\f06a"} |
|
1008 | 1008 | .icon-gift:before{content:"\f06b"} |
|
1009 | 1009 | .icon-leaf:before{content:"\f06c"} |
|
1010 | 1010 | .icon-fire:before{content:"\f06d"} |
|
1011 | 1011 | .icon-eye-open:before{content:"\f06e"} |
|
1012 | 1012 | .icon-eye-close:before{content:"\f070"} |
|
1013 | 1013 | .icon-warning-sign:before{content:"\f071"} |
|
1014 | 1014 | .icon-plane:before{content:"\f072"} |
|
1015 | 1015 | .icon-calendar:before{content:"\f073"} |
|
1016 | 1016 | .icon-random:before{content:"\f074"} |
|
1017 | 1017 | .icon-comment:before{content:"\f075"} |
|
1018 | 1018 | .icon-magnet:before{content:"\f076"} |
|
1019 | 1019 | .icon-chevron-up:before{content:"\f077"} |
|
1020 | 1020 | .icon-chevron-down:before{content:"\f078"} |
|
1021 | 1021 | .icon-retweet:before{content:"\f079"} |
|
1022 | 1022 | .icon-shopping-cart:before{content:"\f07a"} |
|
1023 | 1023 | .icon-folder-close:before{content:"\f07b"} |
|
1024 | 1024 | .icon-folder-open:before{content:"\f07c"} |
|
1025 | 1025 | .icon-resize-vertical:before{content:"\f07d"} |
|
1026 | 1026 | .icon-resize-horizontal:before{content:"\f07e"} |
|
1027 | 1027 | .icon-bar-chart:before{content:"\f080"} |
|
1028 | 1028 | .icon-twitter-sign:before{content:"\f081"} |
|
1029 | 1029 | .icon-facebook-sign:before{content:"\f082"} |
|
1030 | 1030 | .icon-camera-retro:before{content:"\f083"} |
|
1031 | 1031 | .icon-key:before{content:"\f084"} |
|
1032 | 1032 | .icon-gears:before,.icon-cogs:before{content:"\f085"} |
|
1033 | 1033 | .icon-comments:before{content:"\f086"} |
|
1034 | 1034 | .icon-thumbs-up-alt:before{content:"\f087"} |
|
1035 | 1035 | .icon-thumbs-down-alt:before{content:"\f088"} |
|
1036 | 1036 | .icon-star-half:before{content:"\f089"} |
|
1037 | 1037 | .icon-heart-empty:before{content:"\f08a"} |
|
1038 | 1038 | .icon-signout:before{content:"\f08b"} |
|
1039 | 1039 | .icon-linkedin-sign:before{content:"\f08c"} |
|
1040 | 1040 | .icon-pushpin:before{content:"\f08d"} |
|
1041 | 1041 | .icon-external-link:before{content:"\f08e"} |
|
1042 | 1042 | .icon-signin:before{content:"\f090"} |
|
1043 | 1043 | .icon-trophy:before{content:"\f091"} |
|
1044 | 1044 | .icon-github-sign:before{content:"\f092"} |
|
1045 | 1045 | .icon-upload-alt:before{content:"\f093"} |
|
1046 | 1046 | .icon-lemon:before{content:"\f094"} |
|
1047 | 1047 | .icon-phone:before{content:"\f095"} |
|
1048 | 1048 | .icon-unchecked:before,.icon-check-empty:before{content:"\f096"} |
|
1049 | 1049 | .icon-bookmark-empty:before{content:"\f097"} |
|
1050 | 1050 | .icon-phone-sign:before{content:"\f098"} |
|
1051 | 1051 | .icon-twitter:before{content:"\f099"} |
|
1052 | 1052 | .icon-facebook:before{content:"\f09a"} |
|
1053 | 1053 | .icon-github:before{content:"\f09b"} |
|
1054 | 1054 | .icon-unlock:before{content:"\f09c"} |
|
1055 | 1055 | .icon-credit-card:before{content:"\f09d"} |
|
1056 | 1056 | .icon-rss:before{content:"\f09e"} |
|
1057 | 1057 | .icon-hdd:before{content:"\f0a0"} |
|
1058 | 1058 | .icon-bullhorn:before{content:"\f0a1"} |
|
1059 | 1059 | .icon-bell:before{content:"\f0a2"} |
|
1060 | 1060 | .icon-certificate:before{content:"\f0a3"} |
|
1061 | 1061 | .icon-hand-right:before{content:"\f0a4"} |
|
1062 | 1062 | .icon-hand-left:before{content:"\f0a5"} |
|
1063 | 1063 | .icon-hand-up:before{content:"\f0a6"} |
|
1064 | 1064 | .icon-hand-down:before{content:"\f0a7"} |
|
1065 | 1065 | .icon-circle-arrow-left:before{content:"\f0a8"} |
|
1066 | 1066 | .icon-circle-arrow-right:before{content:"\f0a9"} |
|
1067 | 1067 | .icon-circle-arrow-up:before{content:"\f0aa"} |
|
1068 | 1068 | .icon-circle-arrow-down:before{content:"\f0ab"} |
|
1069 | 1069 | .icon-globe:before{content:"\f0ac"} |
|
1070 | 1070 | .icon-wrench:before{content:"\f0ad"} |
|
1071 | 1071 | .icon-tasks:before{content:"\f0ae"} |
|
1072 | 1072 | .icon-filter:before{content:"\f0b0"} |
|
1073 | 1073 | .icon-briefcase:before{content:"\f0b1"} |
|
1074 | 1074 | .icon-fullscreen:before{content:"\f0b2"} |
|
1075 | 1075 | .icon-group:before{content:"\f0c0"} |
|
1076 | 1076 | .icon-link:before{content:"\f0c1"} |
|
1077 | 1077 | .icon-cloud:before{content:"\f0c2"} |
|
1078 | 1078 | .icon-beaker:before{content:"\f0c3"} |
|
1079 | 1079 | .icon-cut:before{content:"\f0c4"} |
|
1080 | 1080 | .icon-copy:before{content:"\f0c5"} |
|
1081 | 1081 | .icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6"} |
|
1082 | 1082 | .icon-save:before{content:"\f0c7"} |
|
1083 | 1083 | .icon-sign-blank:before{content:"\f0c8"} |
|
1084 | 1084 | .icon-reorder:before{content:"\f0c9"} |
|
1085 | 1085 | .icon-list-ul:before{content:"\f0ca"} |
|
1086 | 1086 | .icon-list-ol:before{content:"\f0cb"} |
|
1087 | 1087 | .icon-strikethrough:before{content:"\f0cc"} |
|
1088 | 1088 | .icon-underline:before{content:"\f0cd"} |
|
1089 | 1089 | .icon-table:before{content:"\f0ce"} |
|
1090 | 1090 | .icon-magic:before{content:"\f0d0"} |
|
1091 | 1091 | .icon-truck:before{content:"\f0d1"} |
|
1092 | 1092 | .icon-pinterest:before{content:"\f0d2"} |
|
1093 | 1093 | .icon-pinterest-sign:before{content:"\f0d3"} |
|
1094 | 1094 | .icon-google-plus-sign:before{content:"\f0d4"} |
|
1095 | 1095 | .icon-google-plus:before{content:"\f0d5"} |
|
1096 | 1096 | .icon-money:before{content:"\f0d6"} |
|
1097 | 1097 | .icon-caret-down:before{content:"\f0d7"} |
|
1098 | 1098 | .icon-caret-up:before{content:"\f0d8"} |
|
1099 | 1099 | .icon-caret-left:before{content:"\f0d9"} |
|
1100 | 1100 | .icon-caret-right:before{content:"\f0da"} |
|
1101 | 1101 | .icon-columns:before{content:"\f0db"} |
|
1102 | 1102 | .icon-sort:before{content:"\f0dc"} |
|
1103 | 1103 | .icon-sort-down:before{content:"\f0dd"} |
|
1104 | 1104 | .icon-sort-up:before{content:"\f0de"} |
|
1105 | 1105 | .icon-envelope:before{content:"\f0e0"} |
|
1106 | 1106 | .icon-linkedin:before{content:"\f0e1"} |
|
1107 | 1107 | .icon-rotate-left:before,.icon-undo:before{content:"\f0e2"} |
|
1108 | 1108 | .icon-legal:before{content:"\f0e3"} |
|
1109 | 1109 | .icon-dashboard:before{content:"\f0e4"} |
|
1110 | 1110 | .icon-comment-alt:before{content:"\f0e5"} |
|
1111 | 1111 | .icon-comments-alt:before{content:"\f0e6"} |
|
1112 | 1112 | .icon-bolt:before{content:"\f0e7"} |
|
1113 | 1113 | .icon-sitemap:before{content:"\f0e8"} |
|
1114 | 1114 | .icon-umbrella:before{content:"\f0e9"} |
|
1115 | 1115 | .icon-paste:before{content:"\f0ea"} |
|
1116 | 1116 | .icon-lightbulb:before{content:"\f0eb"} |
|
1117 | 1117 | .icon-exchange:before{content:"\f0ec"} |
|
1118 | 1118 | .icon-cloud-download:before{content:"\f0ed"} |
|
1119 | 1119 | .icon-cloud-upload:before{content:"\f0ee"} |
|
1120 | 1120 | .icon-user-md:before{content:"\f0f0"} |
|
1121 | 1121 | .icon-stethoscope:before{content:"\f0f1"} |
|
1122 | 1122 | .icon-suitcase:before{content:"\f0f2"} |
|
1123 | 1123 | .icon-bell-alt:before{content:"\f0f3"} |
|
1124 | 1124 | .icon-coffee:before{content:"\f0f4"} |
|
1125 | 1125 | .icon-food:before{content:"\f0f5"} |
|
1126 | 1126 | .icon-file-text-alt:before{content:"\f0f6"} |
|
1127 | 1127 | .icon-building:before{content:"\f0f7"} |
|
1128 | 1128 | .icon-hospital:before{content:"\f0f8"} |
|
1129 | 1129 | .icon-ambulance:before{content:"\f0f9"} |
|
1130 | 1130 | .icon-medkit:before{content:"\f0fa"} |
|
1131 | 1131 | .icon-fighter-jet:before{content:"\f0fb"} |
|
1132 | 1132 | .icon-beer:before{content:"\f0fc"} |
|
1133 | 1133 | .icon-h-sign:before{content:"\f0fd"} |
|
1134 | 1134 | .icon-plus-sign-alt:before{content:"\f0fe"} |
|
1135 | 1135 | .icon-double-angle-left:before{content:"\f100"} |
|
1136 | 1136 | .icon-double-angle-right:before{content:"\f101"} |
|
1137 | 1137 | .icon-double-angle-up:before{content:"\f102"} |
|
1138 | 1138 | .icon-double-angle-down:before{content:"\f103"} |
|
1139 | 1139 | .icon-angle-left:before{content:"\f104"} |
|
1140 | 1140 | .icon-angle-right:before{content:"\f105"} |
|
1141 | 1141 | .icon-angle-up:before{content:"\f106"} |
|
1142 | 1142 | .icon-angle-down:before{content:"\f107"} |
|
1143 | 1143 | .icon-desktop:before{content:"\f108"} |
|
1144 | 1144 | .icon-laptop:before{content:"\f109"} |
|
1145 | 1145 | .icon-tablet:before{content:"\f10a"} |
|
1146 | 1146 | .icon-mobile-phone:before{content:"\f10b"} |
|
1147 | 1147 | .icon-circle-blank:before{content:"\f10c"} |
|
1148 | 1148 | .icon-quote-left:before{content:"\f10d"} |
|
1149 | 1149 | .icon-quote-right:before{content:"\f10e"} |
|
1150 | 1150 | .icon-spinner:before{content:"\f110"} |
|
1151 | 1151 | .icon-circle:before{content:"\f111"} |
|
1152 | 1152 | .icon-mail-reply:before,.icon-reply:before{content:"\f112"} |
|
1153 | 1153 | .icon-github-alt:before{content:"\f113"} |
|
1154 | 1154 | .icon-folder-close-alt:before{content:"\f114"} |
|
1155 | 1155 | .icon-folder-open-alt:before{content:"\f115"} |
|
1156 | 1156 | .icon-expand-alt:before{content:"\f116"} |
|
1157 | 1157 | .icon-collapse-alt:before{content:"\f117"} |
|
1158 | 1158 | .icon-smile:before{content:"\f118"} |
|
1159 | 1159 | .icon-frown:before{content:"\f119"} |
|
1160 | 1160 | .icon-meh:before{content:"\f11a"} |
|
1161 | 1161 | .icon-gamepad:before{content:"\f11b"} |
|
1162 | 1162 | .icon-keyboard:before{content:"\f11c"} |
|
1163 | 1163 | .icon-flag-alt:before{content:"\f11d"} |
|
1164 | 1164 | .icon-flag-checkered:before{content:"\f11e"} |
|
1165 | 1165 | .icon-terminal:before{content:"\f120"} |
|
1166 | 1166 | .icon-code:before{content:"\f121"} |
|
1167 | 1167 | .icon-reply-all:before{content:"\f122"} |
|
1168 | 1168 | .icon-mail-reply-all:before{content:"\f122"} |
|
1169 | 1169 | .icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123"} |
|
1170 | 1170 | .icon-location-arrow:before{content:"\f124"} |
|
1171 | 1171 | .icon-crop:before{content:"\f125"} |
|
1172 | 1172 | .icon-code-fork:before{content:"\f126"} |
|
1173 | 1173 | .icon-unlink:before{content:"\f127"} |
|
1174 | 1174 | .icon-question:before{content:"\f128"} |
|
1175 | 1175 | .icon-info:before{content:"\f129"} |
|
1176 | 1176 | .icon-exclamation:before{content:"\f12a"} |
|
1177 | 1177 | .icon-superscript:before{content:"\f12b"} |
|
1178 | 1178 | .icon-subscript:before{content:"\f12c"} |
|
1179 | 1179 | .icon-eraser:before{content:"\f12d"} |
|
1180 | 1180 | .icon-puzzle-piece:before{content:"\f12e"} |
|
1181 | 1181 | .icon-microphone:before{content:"\f130"} |
|
1182 | 1182 | .icon-microphone-off:before{content:"\f131"} |
|
1183 | 1183 | .icon-shield:before{content:"\f132"} |
|
1184 | 1184 | .icon-calendar-empty:before{content:"\f133"} |
|
1185 | 1185 | .icon-fire-extinguisher:before{content:"\f134"} |
|
1186 | 1186 | .icon-rocket:before{content:"\f135"} |
|
1187 | 1187 | .icon-maxcdn:before{content:"\f136"} |
|
1188 | 1188 | .icon-chevron-sign-left:before{content:"\f137"} |
|
1189 | 1189 | .icon-chevron-sign-right:before{content:"\f138"} |
|
1190 | 1190 | .icon-chevron-sign-up:before{content:"\f139"} |
|
1191 | 1191 | .icon-chevron-sign-down:before{content:"\f13a"} |
|
1192 | 1192 | .icon-html5:before{content:"\f13b"} |
|
1193 | 1193 | .icon-css3:before{content:"\f13c"} |
|
1194 | 1194 | .icon-anchor:before{content:"\f13d"} |
|
1195 | 1195 | .icon-unlock-alt:before{content:"\f13e"} |
|
1196 | 1196 | .icon-bullseye:before{content:"\f140"} |
|
1197 | 1197 | .icon-ellipsis-horizontal:before{content:"\f141"} |
|
1198 | 1198 | .icon-ellipsis-vertical:before{content:"\f142"} |
|
1199 | 1199 | .icon-rss-sign:before{content:"\f143"} |
|
1200 | 1200 | .icon-play-sign:before{content:"\f144"} |
|
1201 | 1201 | .icon-ticket:before{content:"\f145"} |
|
1202 | 1202 | .icon-minus-sign-alt:before{content:"\f146"} |
|
1203 | 1203 | .icon-check-minus:before{content:"\f147"} |
|
1204 | 1204 | .icon-level-up:before{content:"\f148"} |
|
1205 | 1205 | .icon-level-down:before{content:"\f149"} |
|
1206 | 1206 | .icon-check-sign:before{content:"\f14a"} |
|
1207 | 1207 | .icon-edit-sign:before{content:"\f14b"} |
|
1208 | 1208 | .icon-external-link-sign:before{content:"\f14c"} |
|
1209 | 1209 | .icon-share-sign:before{content:"\f14d"} |
|
1210 | 1210 | .icon-compass:before{content:"\f14e"} |
|
1211 | 1211 | .icon-collapse:before{content:"\f150"} |
|
1212 | 1212 | .icon-collapse-top:before{content:"\f151"} |
|
1213 | 1213 | .icon-expand:before{content:"\f152"} |
|
1214 | 1214 | .icon-euro:before,.icon-eur:before{content:"\f153"} |
|
1215 | 1215 | .icon-gbp:before{content:"\f154"} |
|
1216 | 1216 | .icon-dollar:before,.icon-usd:before{content:"\f155"} |
|
1217 | 1217 | .icon-rupee:before,.icon-inr:before{content:"\f156"} |
|
1218 | 1218 | .icon-yen:before,.icon-jpy:before{content:"\f157"} |
|
1219 | 1219 | .icon-renminbi:before,.icon-cny:before{content:"\f158"} |
|
1220 | 1220 | .icon-won:before,.icon-krw:before{content:"\f159"} |
|
1221 | 1221 | .icon-bitcoin:before,.icon-btc:before{content:"\f15a"} |
|
1222 | 1222 | .icon-file:before{content:"\f15b"} |
|
1223 | 1223 | .icon-file-text:before{content:"\f15c"} |
|
1224 | 1224 | .icon-sort-by-alphabet:before{content:"\f15d"} |
|
1225 | 1225 | .icon-sort-by-alphabet-alt:before{content:"\f15e"} |
|
1226 | 1226 | .icon-sort-by-attributes:before{content:"\f160"} |
|
1227 | 1227 | .icon-sort-by-attributes-alt:before{content:"\f161"} |
|
1228 | 1228 | .icon-sort-by-order:before{content:"\f162"} |
|
1229 | 1229 | .icon-sort-by-order-alt:before{content:"\f163"} |
|
1230 | 1230 | .icon-thumbs-up:before{content:"\f164"} |
|
1231 | 1231 | .icon-thumbs-down:before{content:"\f165"} |
|
1232 | 1232 | .icon-youtube-sign:before{content:"\f166"} |
|
1233 | 1233 | .icon-youtube:before{content:"\f167"} |
|
1234 | 1234 | .icon-xing:before{content:"\f168"} |
|
1235 | 1235 | .icon-xing-sign:before{content:"\f169"} |
|
1236 | 1236 | .icon-youtube-play:before{content:"\f16a"} |
|
1237 | 1237 | .icon-dropbox:before{content:"\f16b"} |
|
1238 | 1238 | .icon-stackexchange:before{content:"\f16c"} |
|
1239 | 1239 | .icon-instagram:before{content:"\f16d"} |
|
1240 | 1240 | .icon-flickr:before{content:"\f16e"} |
|
1241 | 1241 | .icon-adn:before{content:"\f170"} |
|
1242 | 1242 | .icon-bitbucket:before{content:"\f171"} |
|
1243 | 1243 | .icon-bitbucket-sign:before{content:"\f172"} |
|
1244 | 1244 | .icon-tumblr:before{content:"\f173"} |
|
1245 | 1245 | .icon-tumblr-sign:before{content:"\f174"} |
|
1246 | 1246 | .icon-long-arrow-down:before{content:"\f175"} |
|
1247 | 1247 | .icon-long-arrow-up:before{content:"\f176"} |
|
1248 | 1248 | .icon-long-arrow-left:before{content:"\f177"} |
|
1249 | 1249 | .icon-long-arrow-right:before{content:"\f178"} |
|
1250 | 1250 | .icon-apple:before{content:"\f179"} |
|
1251 | 1251 | .icon-windows:before{content:"\f17a"} |
|
1252 | 1252 | .icon-android:before{content:"\f17b"} |
|
1253 | 1253 | .icon-linux:before{content:"\f17c"} |
|
1254 | 1254 | .icon-dribbble:before{content:"\f17d"} |
|
1255 | 1255 | .icon-skype:before{content:"\f17e"} |
|
1256 | 1256 | .icon-foursquare:before{content:"\f180"} |
|
1257 | 1257 | .icon-trello:before{content:"\f181"} |
|
1258 | 1258 | .icon-female:before{content:"\f182"} |
|
1259 | 1259 | .icon-male:before{content:"\f183"} |
|
1260 | 1260 | .icon-gittip:before{content:"\f184"} |
|
1261 | 1261 | .icon-sun:before{content:"\f185"} |
|
1262 | 1262 | .icon-moon:before{content:"\f186"} |
|
1263 | 1263 | .icon-archive:before{content:"\f187"} |
|
1264 | 1264 | .icon-bug:before{content:"\f188"} |
|
1265 | 1265 | .icon-vk:before{content:"\f189"} |
|
1266 | 1266 | .icon-weibo:before{content:"\f18a"} |
|
1267 | 1267 | .icon-renren:before{content:"\f18b"} |
|
1268 | 1268 | code{color:#000} |
|
1269 | 1269 | .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} |
|
1270 | 1270 | .corner-all{border-radius:4px} |
|
1271 | 1271 | .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;display:flex;flex-direction:row;align-items:stretch} |
|
1272 | 1272 | .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none} |
|
1273 | 1273 | .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%;display:flex;flex-direction:column;align-items:stretch} |
|
1274 | 1274 | .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none} |
|
1275 | 1275 | .hbox.reverse,.vbox.reverse,.reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:row-reverse} |
|
1276 | 1276 | .hbox.box-flex0,.vbox.box-flex0,.box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none;width:auto} |
|
1277 | 1277 | .hbox.box-flex1,.vbox.box-flex1,.box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} |
|
1278 | 1278 | .hbox.box-flex,.vbox.box-flex,.box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} |
|
1279 | 1279 | .hbox.box-flex2,.vbox.box-flex2,.box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2} |
|
1280 | 1280 | .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1} |
|
1281 | 1281 | .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2} |
|
1282 | 1282 | .hbox.start,.vbox.start,.start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start} |
|
1283 | 1283 | .hbox.end,.vbox.end,.end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end} |
|
1284 | 1284 | .hbox.center,.vbox.center,.center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center} |
|
1285 | 1285 | .hbox.align-start,.vbox.align-start,.align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start} |
|
1286 | 1286 | .hbox.align-end,.vbox.align-end,.align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-items:flex-end} |
|
1287 | 1287 | .hbox.align-center,.vbox.align-center,.align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-items:center} |
|
1288 | 1288 | div.error{margin:2em;text-align:center} |
|
1289 | 1289 | div.error>h1{font-size:500%;line-height:normal} |
|
1290 | 1290 | div.error>p{font-size:200%;line-height:normal} |
|
1291 | 1291 | div.traceback-wrapper{text-align:left;max-width:800px;margin:auto} |
|
1292 | 1292 | body{background-color:#fff;position:absolute;left:0;right:0;top:0;bottom:0;overflow:visible} |
|
1293 | 1293 | div#header{display:none} |
|
1294 | 1294 | #ipython_notebook{padding-left:16px} |
|
1295 | 1295 | #noscript{width:auto;padding-top:16px;padding-bottom:16px;text-align:center;font-size:22px;color:#f00;font-weight:bold} |
|
1296 | 1296 | #ipython_notebook img{font-family:Verdana,"Helvetica Neue",Arial,Helvetica,Geneva,sans-serif;height:24px;text-decoration:none;color:#000} |
|
1297 | 1297 | #site{width:100%;display:none} |
|
1298 | 1298 | .ui-button .ui-button-text{padding:.2em .8em;font-size:77%} |
|
1299 | 1299 | input.ui-button{padding:.3em .9em} |
|
1300 | 1300 | .navbar span{margin-top:3px} |
|
1301 | 1301 | span#login_widget{float:right} |
|
1302 | 1302 | .nav-header{text-transform:none} |
|
1303 | 1303 | .navbar-nobg{background-color:transparent;background-image:none} |
|
1304 | 1304 | #header>span{margin-top:10px} |
|
1305 | 1305 | .modal-body{max-height:500px} |
|
1306 | 1306 | @media (min-width:768px){.modal{width:700px;margin-left:-350px}}.center-nav{display:inline-block;margin-bottom:-4px} |
|
1307 | 1307 | .alternate_upload{background-color:none;display:inline} |
|
1308 | 1308 | .alternate_upload.form{padding:0;margin:0} |
|
1309 | 1309 | .alternate_upload input.fileinput{background-color:#f00;position:relative;opacity:0;z-index:2;width:295px;margin-left:163px;cursor:pointer;height:26px} |
|
1310 | 1310 | ul#tabs{margin-bottom:4px} |
|
1311 | 1311 | ul#tabs a{padding-top:4px;padding-bottom:4px} |
|
1312 | 1312 | ul.breadcrumb a:focus,ul.breadcrumb a:hover{text-decoration:none} |
|
1313 | 1313 | ul.breadcrumb i.icon-home{font-size:16px;margin-right:4px} |
|
1314 | 1314 | ul.breadcrumb span{color:#5e5e5e} |
|
1315 | 1315 | .list_toolbar{padding:4px 0 4px 0} |
|
1316 | 1316 | .list_toolbar [class*="span"]{min-height:26px} |
|
1317 | 1317 | .list_header{font-weight:bold} |
|
1318 | 1318 | .list_container{margin-top:4px;margin-bottom:20px;border:1px solid #ababab;border-radius:4px} |
|
1319 | 1319 | .list_container>div{border-bottom:1px solid #ababab}.list_container>div:hover .list-item{background-color:#f00} |
|
1320 | 1320 | .list_container>div:last-child{border:none} |
|
1321 | 1321 | .list_item:hover .list_item{background-color:#ddd} |
|
1322 | 1322 | .list_item a{text-decoration:none} |
|
1323 | 1323 | .list_header>div,.list_item>div{padding-top:4px;padding-bottom:4px;padding-left:7px;padding-right:7px;height:22px;line-height:22px} |
|
1324 | 1324 | .item_name{line-height:22px;height:26px} |
|
1325 | 1325 | .item_icon{font-size:14px;color:#5e5e5e;margin-right:7px} |
|
1326 | 1326 | .item_buttons{line-height:1em} |
|
1327 | 1327 | .toolbar_info{height:26px;line-height:26px} |
|
1328 | 1328 | input.nbname_input,input.engine_num_input{padding-top:3px;padding-bottom:3px;height:14px;line-height:14px;margin:0} |
|
1329 | 1329 | input.engine_num_input{width:60px} |
|
1330 | 1330 | .highlight_text{color:#00f} |
|
1331 | 1331 | #project_name>.breadcrumb{padding:0;margin-bottom:0;background-color:transparent;font-weight:bold} |
|
1332 | 1332 | .ansibold{font-weight:bold} |
|
1333 | 1333 | .ansiblack{color:#000} |
|
1334 | 1334 | .ansired{color:#8b0000} |
|
1335 | 1335 | .ansigreen{color:#006400} |
|
1336 | 1336 | .ansiyellow{color:#a52a2a} |
|
1337 | 1337 | .ansiblue{color:#00008b} |
|
1338 | 1338 | .ansipurple{color:#9400d3} |
|
1339 | 1339 | .ansicyan{color:#4682b4} |
|
1340 | 1340 | .ansigray{color:#808080} |
|
1341 | 1341 | .ansibgblack{background-color:#000} |
|
1342 | 1342 | .ansibgred{background-color:#f00} |
|
1343 | 1343 | .ansibggreen{background-color:#008000} |
|
1344 | 1344 | .ansibgyellow{background-color:#ff0} |
|
1345 | 1345 | .ansibgblue{background-color:#00f} |
|
1346 | 1346 | .ansibgpurple{background-color:#f0f} |
|
1347 | 1347 | .ansibgcyan{background-color:#0ff} |
|
1348 | 1348 | .ansibggray{background-color:#808080} |
|
1349 | 1349 | 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%;display:flex;flex-direction:column;align-items:stretch}div.cell.selected{border-radius:4px;border:thin #ababab solid} |
|
1350 | 1350 | div.cell.edit_mode{border-radius:4px;border:thin #008000 solid} |
|
1351 | 1351 | div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none} |
|
1352 | 1352 | div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.21429em} |
|
1353 | 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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
1353 | @media (max-width:480px){div.prompt{text-align:left}}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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} | |
|
1354 | 1354 | div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7} |
|
1355 | 1355 | div.prompt:empty{padding-top:0;padding-bottom:0} |
|
1356 | 1356 | 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;display:flex;flex-direction:row;align-items:stretch} |
|
1357 | div.input_prompt{color:#000080;border-top:1px solid transparent} | |
|
1357 | @media (max-width:480px){div.input{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%;display:flex;flex-direction:column;align-items:stretch}}div.input_prompt{color:#000080;border-top:1px solid transparent} | |
|
1358 | 1358 | div.input_area>div.highlight{margin:.4em;border:none;padding:0;background-color:transparent} |
|
1359 | 1359 | div.input_area>div.highlight>pre{margin:0;border:0;padding:0;background-color:transparent;font-size:14px;line-height:1.21429em} |
|
1360 | 1360 | .CodeMirror{line-height:1.21429em;height:auto;background:none;} |
|
1361 | 1361 | .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto} |
|
1362 | 1362 | @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em} |
|
1363 | 1363 | .CodeMirror-linenumber{padding:0 8px 0 4px} |
|
1364 | 1364 | .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px} |
|
1365 | 1365 | .CodeMirror pre{padding:0;border:0;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} |
|
1366 | 1366 | pre code{display:block;padding:.5em} |
|
1367 | 1367 | .highlight-base,pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure .built_in,pre .nginx .title{color:#000} |
|
1368 | 1368 | .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} |
|
1369 | 1369 | .highlight-comment,pre .comment,pre .annotation,pre .template_comment,pre .diff .header,pre .chunk,pre .markdown .blockquote{color:#408080;font-style:italic} |
|
1370 | 1370 | .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} |
|
1371 | 1371 | 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:#88f} |
|
1372 | 1372 | .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} |
|
1373 | 1373 | .highlight-builtin,pre .built_in{color:#008000} |
|
1374 | 1374 | pre .markdown .emphasis{font-style:italic} |
|
1375 | 1375 | pre .nginx .built_in{font-weight:normal} |
|
1376 | 1376 | pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .javascript,pre .xml .vbscript,pre .xml .css,pre .xml .cdata{opacity:.5} |
|
1377 | 1377 | .cm-s-ipython span.cm-variable{color:#000} |
|
1378 | 1378 | .cm-s-ipython span.cm-keyword{color:#008000;font-weight:bold} |
|
1379 | 1379 | .cm-s-ipython span.cm-number{color:#080} |
|
1380 | 1380 | .cm-s-ipython span.cm-comment{color:#408080;font-style:italic} |
|
1381 | 1381 | .cm-s-ipython span.cm-string{color:#ba2121} |
|
1382 | 1382 | .cm-s-ipython span.cm-builtin{color:#008000} |
|
1383 | 1383 | .cm-s-ipython span.cm-error{color:#f00} |
|
1384 | 1384 | .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold} |
|
1385 | 1385 | .cm-s-ipython span.cm-meta{color:#a2f} |
|
1386 | 1386 | .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat} |
|
1387 | 1387 | 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%;display:flex;flex-direction:column;align-items:stretch} |
|
1388 | 1388 | 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);display:block} |
|
1389 | 1389 | div.output_collapsed{margin:0;padding:0;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%;display:flex;flex-direction:column;align-items:stretch} |
|
1390 | 1390 | div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px} |
|
1391 | 1391 | div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000;-moz-box-shadow:inset 0 0 1px #000;box-shadow:inset 0 0 1px #000;background:rgba(240,240,240,0.5)} |
|
1392 | 1392 | div.output_prompt{color:#8b0000} |
|
1393 | 1393 | div.output_area{padding:0;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;display:flex;flex-direction:row;align-items:stretch}div.output_area .MathJax_Display{text-align:left !important} |
|
1394 | 1394 | div.output_area .rendered_html table{margin-left:0;margin-right:0} |
|
1395 | 1395 | div.output_area .rendered_html img{margin-left:0;margin-right:0} |
|
1396 | 1396 | .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%;display:flex;flex-direction:column;align-items:stretch} |
|
1397 | div.output_area pre{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:#000;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit} | |
|
1397 | @media (max-width:480px){div.output_area{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%;display:flex;flex-direction:column;align-items:stretch}}div.output_area pre{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:#000;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit} | |
|
1398 | 1398 | div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} |
|
1399 | 1399 | div.output_text{text-align:left;color:#000;line-height:1.21429em} |
|
1400 | 1400 | div.output_stderr{background:#fdd;} |
|
1401 | 1401 | div.output_latex{text-align:left} |
|
1402 | 1402 | div.output_javascript:empty{padding:0} |
|
1403 | 1403 | .js-error{color:#8b0000} |
|
1404 | 1404 | div.raw_input_container{font-family:monospace;padding-top:5px} |
|
1405 | 1405 | span.raw_input_prompt{} |
|
1406 | 1406 | input.raw_input{font-family:inherit;font-size:inherit;color:inherit;width:auto;vertical-align:baseline;padding:0 .25em;margin:0 .25em} |
|
1407 | 1407 | input.raw_input:focus{box-shadow:none} |
|
1408 | 1408 | p.p-space{margin-bottom:10px} |
|
1409 | 1409 | .rendered_html{color:#000;}.rendered_html em{font-style:italic} |
|
1410 | 1410 | .rendered_html strong{font-weight:bold} |
|
1411 | 1411 | .rendered_html u{text-decoration:underline} |
|
1412 | 1412 | .rendered_html :link{text-decoration:underline} |
|
1413 | 1413 | .rendered_html :visited{text-decoration:underline} |
|
1414 | 1414 | .rendered_html h1{font-size:185.7%;margin:1.08em 0 0 0;font-weight:bold;line-height:1} |
|
1415 | 1415 | .rendered_html h2{font-size:157.1%;margin:1.27em 0 0 0;font-weight:bold;line-height:1} |
|
1416 | 1416 | .rendered_html h3{font-size:128.6%;margin:1.55em 0 0 0;font-weight:bold;line-height:1} |
|
1417 | 1417 | .rendered_html h4{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1} |
|
1418 | 1418 | .rendered_html h5{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1;font-style:italic} |
|
1419 | 1419 | .rendered_html h6{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1;font-style:italic} |
|
1420 | 1420 | .rendered_html h1:first-child{margin-top:.538em} |
|
1421 | 1421 | .rendered_html h2:first-child{margin-top:.636em} |
|
1422 | 1422 | .rendered_html h3:first-child{margin-top:.777em} |
|
1423 | 1423 | .rendered_html h4:first-child{margin-top:1em} |
|
1424 | 1424 | .rendered_html h5:first-child{margin-top:1em} |
|
1425 | 1425 | .rendered_html h6:first-child{margin-top:1em} |
|
1426 | 1426 | .rendered_html ul{list-style:disc;margin:0 2em} |
|
1427 | 1427 | .rendered_html ul ul{list-style:square;margin:0 2em} |
|
1428 | 1428 | .rendered_html ul ul ul{list-style:circle;margin:0 2em} |
|
1429 | 1429 | .rendered_html ol{list-style:decimal;margin:0 2em} |
|
1430 | 1430 | .rendered_html ol ol{list-style:upper-alpha;margin:0 2em} |
|
1431 | 1431 | .rendered_html ol ol ol{list-style:lower-alpha;margin:0 2em} |
|
1432 | 1432 | .rendered_html ol ol ol ol{list-style:lower-roman;margin:0 2em} |
|
1433 | 1433 | .rendered_html ol ol ol ol ol{list-style:decimal;margin:0 2em} |
|
1434 | 1434 | .rendered_html *+ul{margin-top:1em} |
|
1435 | 1435 | .rendered_html *+ol{margin-top:1em} |
|
1436 | 1436 | .rendered_html hr{color:#000;background-color:#000} |
|
1437 | 1437 | .rendered_html pre{margin:1em 2em} |
|
1438 | 1438 | .rendered_html pre,.rendered_html code{border:0;background-color:#fff;color:#000;font-size:100%;padding:0} |
|
1439 | 1439 | .rendered_html blockquote{margin:1em 2em} |
|
1440 | 1440 | .rendered_html table{margin-left:auto;margin-right:auto;border:1px solid #000;border-collapse:collapse} |
|
1441 | 1441 | .rendered_html tr,.rendered_html th,.rendered_html td{border:1px solid #000;border-collapse:collapse;margin:1em 2em} |
|
1442 | 1442 | .rendered_html td,.rendered_html th{text-align:left;vertical-align:middle;padding:4px} |
|
1443 | 1443 | .rendered_html th{font-weight:bold} |
|
1444 | 1444 | .rendered_html *+table{margin-top:1em} |
|
1445 | 1445 | .rendered_html p{text-align:justify} |
|
1446 | 1446 | .rendered_html *+p{margin-top:1em} |
|
1447 | 1447 | .rendered_html img{display:block;margin-left:auto;margin-right:auto} |
|
1448 | 1448 | .rendered_html *+img{margin-top:1em} |
|
1449 | 1449 | div.text_cell{padding:5px 5px 5px 0;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;display:flex;flex-direction:row;align-items:stretch} |
|
1450 | div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000} | |
|
1450 | @media (max-width:480px){div.text_cell>div.prompt{display:none}}div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000} | |
|
1451 | 1451 | a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden} |
|
1452 | 1452 | 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} |
|
1453 | 1453 | div.cell.text_cell.rendered{padding:0} |
|
1454 | 1454 | .widget-area{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;display:flex;flex-direction:row;align-items:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start} |
|
1455 | 1455 | .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top} |
|
1456 | 1456 | .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom} |
|
1457 | 1457 | .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top} |
|
1458 | 1458 | .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top} |
|
1459 | 1459 | .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;} |
|
1460 | 1460 | .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;margin-bottom:10px;border:1px solid #ccc;background:#fff;border-radius:4px;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;display:flex;flex-direction:row;align-items:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;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;display:flex;flex-direction:row;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important} |
|
1461 | 1461 | .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;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%;display:flex;flex-direction:column;align-items:stretch}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px} |
|
1462 | 1462 | .widget-text{width:350px;margin:0 !important} |
|
1463 | 1463 | .widget-listbox{width:364px;margin-bottom:0} |
|
1464 | 1464 | .widget-numeric-text{width:150px;margin:0 !important} |
|
1465 | 1465 | .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none} |
|
1466 | 1466 | .widget-combo-btn{min-width:138px;} |
|
1467 | 1467 | .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start} |
|
1468 | 1468 | .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start;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;display:flex;flex-direction:row;align-items:stretch} |
|
1469 | 1469 | .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start;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;display:flex;flex-direction:row;align-items:stretch;height:30px} |
|
1470 | 1470 | .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start;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%;display:flex;flex-direction:column;align-items:stretch} |
|
1471 | 1471 | .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start;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%;display:flex;flex-direction:column;align-items:stretch;width:30px} |
|
1472 | 1472 | .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important} |
|
1473 | 1473 | .widget-modal-body{max-height:none !important} |
|
1474 | 1474 | .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start} |
|
1475 | 1475 | .widget-radio-box{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%;display:flex;flex-direction:column;align-items:stretch;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding-top:4px} |
|
1476 | 1476 | .docked-widget-modal{overflow:hidden;position:relative !important;top:0 !important;left:0 !important;margin-left:0 !important} |
|
1477 | 1477 | body{background-color:#fff} |
|
1478 | 1478 | body.notebook_app{overflow:hidden} |
|
1479 | span#notebook_name{height:1em;line-height:1em;padding:3px;border:none;font-size:146.5%} | |
|
1479 | @media (max-width:767px){body.notebook_app{padding-left:0;padding-right:0}}span#notebook_name{height:1em;line-height:1em;padding:3px;border:none;font-size:146.5%} | |
|
1480 | 1480 | div#notebook_panel{margin:0 0 0 0;padding:0;-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)} |
|
1481 | 1481 | div#notebook{font-size:14px;line-height:20px;overflow-y:scroll;overflow-x:auto;width:100%;padding:1em 0 1em 0;margin:0;border-top:1px solid #ababab;outline:none;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box} |
|
1482 | 1482 | div.ui-widget-content{border:1px solid #ababab;outline:none} |
|
1483 | 1483 | pre.dialog{background-color:#f7f7f7;border:1px solid #ddd;border-radius:4px;padding:.4em;padding-left:2em} |
|
1484 | 1484 | p.dialog{padding:.2em} |
|
1485 | 1485 | pre,code,kbd,samp{white-space:pre-wrap} |
|
1486 | 1486 | #fonttest{font-family:monospace} |
|
1487 | 1487 | p{margin-bottom:0} |
|
1488 | 1488 | .end_space{height:200px} |
|
1489 | 1489 | .celltoolbar{border:thin solid #cfcfcf;border-bottom:none;background:#eee;border-radius:3px 3px 0 0;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;display:flex;flex-direction:row;align-items:stretch;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:row-reverse} |
|
1490 | 1490 | .ctb_hideshow{display:none;vertical-align:bottom;padding-right:2px} |
|
1491 | 1491 | .celltoolbar>div{padding-top:0} |
|
1492 | 1492 | .ctb_global_show .ctb_show.ctb_hideshow{display:block} |
|
1493 | 1493 | .ctb_global_show .ctb_show+.input_area,.ctb_global_show .ctb_show+div.text_cell_input{border-top-right-radius:0;border-top-left-radius:0} |
|
1494 | 1494 | .celltoolbar .button_container select{margin:10px;margin-top:1px;margin-bottom:0;padding:0;font-size:87%;width:auto;display:inline-block;height:18px;line-height:18px;vertical-align:top} |
|
1495 | 1495 | .celltoolbar label{display:inline-block;height:15px;line-height:15px;vertical-align:top} |
|
1496 | 1496 | .celltoolbar label span{font-size:85%} |
|
1497 | 1497 | .celltoolbar input[type=checkbox]{margin:0;margin-left:4px;margin-right:4px} |
|
1498 | 1498 | .celltoolbar .ui-button{border:none;vertical-align:top;height:20px;min-width:30px} |
|
1499 | 1499 | .completions{position:absolute;z-index:10;overflow:hidden;border:1px solid #ababab;border-radius:4px;-webkit-box-shadow:0 6px 10px -1px #adadad;-moz-box-shadow:0 6px 10px -1px #adadad;box-shadow:0 6px 10px -1px #adadad} |
|
1500 | 1500 | .completions select{background:#fff;outline:none;border:none;padding:0;margin:0;overflow:auto;font-family:monospace;font-size:110%;color:#000;width:auto} |
|
1501 | 1501 | .completions select option.context{color:#0064cd} |
|
1502 | 1502 | #menubar .navbar-inner{min-height:28px;border-top:1px;border-radius:0 0 4px 4px} |
|
1503 | 1503 | #menubar .navbar{margin-bottom:8px} |
|
1504 | 1504 | .nav-wrapper{border-bottom:1px solid #d4d4d4} |
|
1505 | 1505 | #menubar li.dropdown{line-height:12px} |
|
1506 | 1506 | i.menu-icon{padding-top:4px} |
|
1507 | 1507 | ul#help_menu li a{overflow:hidden;padding-right:2.2em}ul#help_menu li a i{margin-right:-1.2em} |
|
1508 | 1508 | #notification_area{z-index:10} |
|
1509 | 1509 | .indicator_area{color:#777;padding:4px 3px;margin:0;width:11px;z-index:10;text-align:center} |
|
1510 | 1510 | #kernel_indicator{margin-right:-16px} |
|
1511 | 1511 | .edit_mode_icon:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:"\f040"} |
|
1512 | 1512 | .command_mode_icon:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:' '} |
|
1513 | 1513 | .kernel_idle_icon:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:"\f10c"} |
|
1514 | 1514 | .kernel_busy_icon:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:"\f111"} |
|
1515 | 1515 | .notification_widget{color:#777;padding:1px 12px;margin:2px 4px;z-index:10;border:1px solid #ccc;border-radius:4px;background:rgba(240,240,240,0.5)}.notification_widget.span{padding-right:2px} |
|
1516 | 1516 | div#pager_splitter{height:8px} |
|
1517 | 1517 | #pager-container{position:relative;padding:15px 0} |
|
1518 | 1518 | div#pager{font-size:14px;line-height:20px;overflow:auto;display:none}div#pager pre{font-size:13px;line-height:1.21429em;color:#000;background-color:#f7f7f7;padding:.4em} |
|
1519 | 1519 | .quickhelp{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;display:flex;flex-direction:row;align-items:stretch} |
|
1520 | 1520 | .shortcut_key{display:inline-block;width:20ex;text-align:right;font-family:monospace} |
|
1521 | 1521 | .shortcut_descr{display:inline-block;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1} |
|
1522 | 1522 | span#save_widget{padding:0 5px;margin-top:12px} |
|
1523 | 1523 | span#checkpoint_status,span#autosave_status{font-size:small} |
|
1524 | 1524 | @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:0 10px;margin-top:-5px}.toolbar select,.toolbar label{width:auto;height:26px;vertical-align:middle;margin-right:2px;margin-bottom:0;display:inline;font-size:92%;margin-left:.3em;margin-right:.3em;padding:0;padding-top:3px} |
|
1525 | 1525 | .toolbar .btn{padding:2px 8px} |
|
1526 | 1526 | .toolbar .btn-group{margin-top:0} |
|
1527 | 1527 | .toolbar-inner{border:none !important;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;box-shadow:none !important} |
|
1528 | 1528 | #maintoolbar{margin-bottom:0} |
|
1529 | 1529 | @-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} |
|
1530 | 1530 | .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} |
|
1531 | 1531 | .tooltipbuttons{position:absolute;padding-right:15px;top:0;right:0} |
|
1532 | 1532 | .tooltiptext{padding-right:30px} |
|
1533 | 1533 | .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:0;padding-left:7px;font-family:monospace;min-height:50px;-moz-box-shadow:0 6px 10px -1px #adadad;-webkit-box-shadow:0 6px 10px -1px #adadad;box-shadow:0 6px 10px -1px #adadad;border-radius:4px;position:absolute;z-index:2}.ipython_tooltip a{float:right} |
|
1534 | 1534 | .ipython_tooltip .tooltiptext pre{border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;font-size:100%;background-color:#f7f7f7} |
|
1535 | 1535 | .pretooltiparrow{left:0;margin:0;top:-16px;width:40px;height:16px;overflow:hidden;position:absolute} |
|
1536 | 1536 | .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,362 +1,362 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/bootstrap-tour/build/css/bootstrap-tour.min.css") }}" type="text/css" /> |
|
15 | 15 | <link rel="stylesheet" href="{{ static_url("components/codemirror/lib/codemirror.css") }}"> |
|
16 | 16 | |
|
17 | 17 | {{super()}} |
|
18 | 18 | |
|
19 | 19 | <link rel="stylesheet" href="{{ static_url("notebook/css/override.css") }}" type="text/css" /> |
|
20 | 20 | |
|
21 | 21 | {% endblock %} |
|
22 | 22 | |
|
23 | 23 | {% block params %} |
|
24 | 24 | |
|
25 | 25 | data-project="{{project}}" |
|
26 | 26 | data-base-url="{{base_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 id="file_menu" 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 | <li id="trust_notebook" |
|
91 | 91 | title="Trust the output of this notebook"> |
|
92 | 92 | <a href="#" >Trust Notebook</a></li> |
|
93 | 93 | <li class="divider"></li> |
|
94 | 94 | <li id="kill_and_exit" |
|
95 | 95 | title="Shutdown this notebook's kernel, and close this window"> |
|
96 | 96 | <a href="#" >Close and halt</a></li> |
|
97 | 97 | </ul> |
|
98 | 98 | </li> |
|
99 | 99 | <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Edit</a> |
|
100 | 100 | <ul id="edit_menu" class="dropdown-menu"> |
|
101 | 101 | <li id="cut_cell"><a href="#">Cut Cell</a></li> |
|
102 | 102 | <li id="copy_cell"><a href="#">Copy Cell</a></li> |
|
103 | 103 | <li id="paste_cell_above" class="disabled"><a href="#">Paste Cell Above</a></li> |
|
104 | 104 | <li id="paste_cell_below" class="disabled"><a href="#">Paste Cell Below</a></li> |
|
105 | 105 | <li id="paste_cell_replace" class="disabled"><a href="#">Paste Cell & Replace</a></li> |
|
106 | 106 | <li id="delete_cell"><a href="#">Delete Cell</a></li> |
|
107 | 107 | <li id="undelete_cell" class="disabled"><a href="#">Undo Delete Cell</a></li> |
|
108 | 108 | <li class="divider"></li> |
|
109 | 109 | <li id="split_cell"><a href="#">Split Cell</a></li> |
|
110 | 110 | <li id="merge_cell_above"><a href="#">Merge Cell Above</a></li> |
|
111 | 111 | <li id="merge_cell_below"><a href="#">Merge Cell Below</a></li> |
|
112 | 112 | <li class="divider"></li> |
|
113 | 113 | <li id="move_cell_up"><a href="#">Move Cell Up</a></li> |
|
114 | 114 | <li id="move_cell_down"><a href="#">Move Cell Down</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 id="view_menu" 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 id="insert_menu" 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 id="cell_menu" 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 | 143 | <li id="run_cell_select_below" title="Run this cell, select below"> |
|
144 | 144 | <a href="#">Run and Select Below</a></li> |
|
145 | 145 | <li id="run_cell_insert_below" title="Run this cell, insert below"> |
|
146 | 146 | <a href="#">Run and Insert Below</a></li> |
|
147 | 147 | <li id="run_all_cells" title="Run all cells in the notebook"> |
|
148 | 148 | <a href="#">Run All</a></li> |
|
149 | 149 | <li id="run_all_cells_above" title="Run all cells above (but not including) this cell"> |
|
150 | 150 | <a href="#">Run All Above</a></li> |
|
151 | 151 | <li id="run_all_cells_below" title="Run this cell and all cells below it"> |
|
152 | 152 | <a href="#">Run All Below</a></li> |
|
153 | 153 | <li class="divider"></li> |
|
154 | 154 | <li id="change_cell_type" class="dropdown-submenu" |
|
155 | 155 | title="All cells in the notebook have a cell type. By default, new cells are created as 'Code' cells"> |
|
156 | 156 | <a href="#">Cell Type</a> |
|
157 | 157 | <ul class="dropdown-menu"> |
|
158 | 158 | <li id="to_code" |
|
159 | 159 | title="Contents will be sent to the kernel for execution, and output will display in the footer of cell"> |
|
160 | 160 | <a href="#">Code</a></li> |
|
161 | 161 | <li id="to_markdown" |
|
162 | 162 | title="Contents will be rendered as HTML and serve as explanatory text"> |
|
163 | 163 | <a href="#">Markdown</a></li> |
|
164 | 164 | <li id="to_raw" |
|
165 | 165 | title="Contents will pass through nbconvert unmodified"> |
|
166 | 166 | <a href="#">Raw NBConvert</a></li> |
|
167 | 167 | <li id="to_heading1"><a href="#">Heading 1</a></li> |
|
168 | 168 | <li id="to_heading2"><a href="#">Heading 2</a></li> |
|
169 | 169 | <li id="to_heading3"><a href="#">Heading 3</a></li> |
|
170 | 170 | <li id="to_heading4"><a href="#">Heading 4</a></li> |
|
171 | 171 | <li id="to_heading5"><a href="#">Heading 5</a></li> |
|
172 | 172 | <li id="to_heading6"><a href="#">Heading 6</a></li> |
|
173 | 173 | </ul> |
|
174 | 174 | </li> |
|
175 | 175 | <li class="divider"></li> |
|
176 | 176 | <li id="current_outputs" class="dropdown-submenu"><a href="#">Current Output</a> |
|
177 | 177 | <ul class="dropdown-menu"> |
|
178 | 178 | <li id="toggle_current_output" |
|
179 | 179 | title="Hide/Show the output of the current cell"> |
|
180 | 180 | <a href="#">Toggle</a> |
|
181 | 181 | </li> |
|
182 | 182 | <li id="toggle_current_output_scroll" |
|
183 | 183 | title="Scroll the output of the current cell"> |
|
184 | 184 | <a href="#">Toggle Scrolling</a> |
|
185 | 185 | </li> |
|
186 | 186 | <li id="clear_current_output" |
|
187 | 187 | title="Clear the output of the current cell"> |
|
188 | 188 | <a href="#">Clear</a> |
|
189 | 189 | </li> |
|
190 | 190 | </ul> |
|
191 | 191 | </li> |
|
192 | 192 | <li id="all_outputs" class="dropdown-submenu"><a href="#">All Output</a> |
|
193 | 193 | <ul class="dropdown-menu"> |
|
194 | 194 | <li id="toggle_all_output" |
|
195 | 195 | title="Hide/Show the output of all cells"> |
|
196 | 196 | <a href="#">Toggle</a> |
|
197 | 197 | </li> |
|
198 | 198 | <li id="toggle_all_output_scroll" |
|
199 | 199 | title="Scroll the output of all cells"> |
|
200 | 200 | <a href="#">Toggle Scrolling</a> |
|
201 | 201 | </li> |
|
202 | 202 | <li id="clear_all_output" |
|
203 | 203 | title="Clear the output of all cells"> |
|
204 | 204 | <a href="#">Clear</a> |
|
205 | 205 | </li> |
|
206 | 206 | </ul> |
|
207 | 207 | </li> |
|
208 | 208 | </ul> |
|
209 | 209 | </li> |
|
210 | 210 | <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Kernel</a> |
|
211 | 211 | <ul id="kernel_menu" class="dropdown-menu"> |
|
212 | 212 | <li id="int_kernel" |
|
213 | 213 | title="Send KeyboardInterrupt (CTRL-C) to the Kernel"> |
|
214 | 214 | <a href="#">Interrupt</a></li> |
|
215 | 215 | <li id="restart_kernel" |
|
216 | 216 | title="Restart the Kernel"> |
|
217 | 217 | <a href="#">Restart</a></li> |
|
218 | 218 | </ul> |
|
219 | 219 | </li> |
|
220 | 220 | <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Help</a> |
|
221 | 221 | <ul id="help_menu" class="dropdown-menu"> |
|
222 | 222 | <li id="notebook_tour" title="A quick tour of the notebook user interface"><a href="#">User Interface Tour</a></li> |
|
223 | 223 | <li id="keyboard_shortcuts" title="Opens a tooltip with all keyboard shortcuts"><a href="#">Keyboard Shortcuts</a></li> |
|
224 | 224 | <li class="divider"></li> |
|
225 | 225 | {% set |
|
226 | 226 | sections = ( |
|
227 | 227 | ( |
|
228 | 228 | ("http://ipython.org/documentation.html","IPython Help",True), |
|
229 | 229 | ("http://nbviewer.ipython.org/github/ipython/ipython/tree/master/examples/notebooks/", "Notebook Examples", True), |
|
230 |
("http://ipython.org/ipython-doc/ |
|
|
231 |
("http://ipython.org/ipython-doc/ |
|
|
230 | ("http://ipython.org/ipython-doc/2/notebook/notebook.html","Notebook Help",True), | |
|
231 | ("http://ipython.org/ipython-doc/2/notebook/cm_keyboard.html","Editor Shortcuts",True), | |
|
232 | 232 | ),( |
|
233 | 233 | ("http://docs.python.org","Python",True), |
|
234 | 234 | ("http://docs.scipy.org/doc/numpy/reference/","NumPy",True), |
|
235 | 235 | ("http://docs.scipy.org/doc/scipy/reference/","SciPy",True), |
|
236 | 236 | ("http://matplotlib.org/contents.html","Matplotlib",True), |
|
237 |
("http://docs.sympy.org/ |
|
|
237 | ("http://docs.sympy.org/latest/index.html","SymPy",True), | |
|
238 | 238 | ("http://pandas.pydata.org/pandas-docs/stable/","pandas", True) |
|
239 | 239 | ) |
|
240 | 240 | ) |
|
241 | 241 | %} |
|
242 | 242 | |
|
243 | 243 | {% for helplinks in sections %} |
|
244 | 244 | {% for link in helplinks %} |
|
245 | 245 | <li><a href="{{link[0]}}" {{'target="_blank" title="Opens in a new window"' if link[2]}}> |
|
246 | 246 | {{'<i class="icon-external-link menu-icon pull-right"></i>' if link[2]}} |
|
247 | 247 | {{link[1]}} |
|
248 | 248 | </a></li> |
|
249 | 249 | {% endfor %} |
|
250 | 250 | {% if not loop.last %} |
|
251 | 251 | <li class="divider"></li> |
|
252 | 252 | {% endif %} |
|
253 | 253 | {% endfor %} |
|
254 | 254 | </li> |
|
255 | 255 | </ul> |
|
256 | 256 | </li> |
|
257 | 257 | </ul> |
|
258 | 258 | <div id="kernel_indicator" class="indicator_area pull-right"> |
|
259 | 259 | <i id="kernel_indicator_icon"></i> |
|
260 | 260 | </div> |
|
261 | 261 | <div id="modal_indicator" class="indicator_area pull-right"> |
|
262 | 262 | <i id="modal_indicator_icon"></i> |
|
263 | 263 | </div> |
|
264 | 264 | <div id="notification_area"></div> |
|
265 | 265 | </div> |
|
266 | 266 | </div> |
|
267 | 267 | </div> |
|
268 | 268 | </div> |
|
269 | 269 | <div id="maintoolbar" class="navbar"> |
|
270 | 270 | <div class="toolbar-inner navbar-inner navbar-nobg"> |
|
271 | 271 | <div id="maintoolbar-container" class="container"></div> |
|
272 | 272 | </div> |
|
273 | 273 | </div> |
|
274 | 274 | </div> |
|
275 | 275 | |
|
276 | 276 | <div id="ipython-main-app"> |
|
277 | 277 | |
|
278 | 278 | <div id="notebook_panel"> |
|
279 | 279 | <div id="notebook"></div> |
|
280 | 280 | <div id="pager_splitter"></div> |
|
281 | 281 | <div id="pager"> |
|
282 | 282 | <div id='pager_button_area'> |
|
283 | 283 | </div> |
|
284 | 284 | <div id="pager-container" class="container"></div> |
|
285 | 285 | </div> |
|
286 | 286 | </div> |
|
287 | 287 | |
|
288 | 288 | </div> |
|
289 | 289 | <div id='tooltip' class='ipython_tooltip' style='display:none'></div> |
|
290 | 290 | |
|
291 | 291 | |
|
292 | 292 | {% endblock %} |
|
293 | 293 | |
|
294 | 294 | |
|
295 | 295 | {% block script %} |
|
296 | 296 | |
|
297 | 297 | {{super()}} |
|
298 | 298 | |
|
299 | 299 | <script src="{{ static_url("components/google-caja/html-css-sanitizer-minified.js") }}" charset="utf-8"></script> |
|
300 | 300 | <script src="{{ static_url("components/codemirror/lib/codemirror.js") }}" charset="utf-8"></script> |
|
301 | 301 | <script type="text/javascript"> |
|
302 | 302 | CodeMirror.modeURL = "{{ static_url("components/codemirror/mode/%N/%N.js", include_version=False) }}"; |
|
303 | 303 | </script> |
|
304 | 304 | <script src="{{ static_url("components/codemirror/addon/mode/loadmode.js") }}" charset="utf-8"></script> |
|
305 | 305 | <script src="{{ static_url("components/codemirror/addon/mode/multiplex.js") }}" charset="utf-8"></script> |
|
306 | 306 | <script src="{{ static_url("components/codemirror/addon/mode/overlay.js") }}" charset="utf-8"></script> |
|
307 | 307 | <script src="{{ static_url("components/codemirror/addon/edit/matchbrackets.js") }}" charset="utf-8"></script> |
|
308 | 308 | <script src="{{ static_url("components/codemirror/addon/edit/closebrackets.js") }}" charset="utf-8"></script> |
|
309 | 309 | <script src="{{ static_url("components/codemirror/addon/comment/comment.js") }}" charset="utf-8"></script> |
|
310 | 310 | <script src="{{ static_url("components/codemirror/mode/htmlmixed/htmlmixed.js") }}" charset="utf-8"></script> |
|
311 | 311 | <script src="{{ static_url("components/codemirror/mode/xml/xml.js") }}" charset="utf-8"></script> |
|
312 | 312 | <script src="{{ static_url("components/codemirror/mode/javascript/javascript.js") }}" charset="utf-8"></script> |
|
313 | 313 | <script src="{{ static_url("components/codemirror/mode/css/css.js") }}" charset="utf-8"></script> |
|
314 | 314 | <script src="{{ static_url("components/codemirror/mode/rst/rst.js") }}" charset="utf-8"></script> |
|
315 | 315 | <script src="{{ static_url("components/codemirror/mode/markdown/markdown.js") }}" charset="utf-8"></script> |
|
316 | 316 | <script src="{{ static_url("components/codemirror/mode/gfm/gfm.js") }}" charset="utf-8"></script> |
|
317 | 317 | <script src="{{ static_url("components/codemirror/mode/python/python.js") }}" charset="utf-8"></script> |
|
318 | 318 | <script src="{{ static_url("notebook/js/codemirror-ipython.js") }}" charset="utf-8"></script> |
|
319 | 319 | |
|
320 | 320 | <script src="{{ static_url("components/highlight.js/build/highlight.pack.js") }}" charset="utf-8"></script> |
|
321 | 321 | |
|
322 | 322 | <script src="{{ static_url("dateformat/date.format.js") }}" charset="utf-8"></script> |
|
323 | 323 | |
|
324 | 324 | <script src="{{ static_url("base/js/events.js") }}" type="text/javascript" charset="utf-8"></script> |
|
325 | 325 | <script src="{{ static_url("base/js/utils.js") }}" type="text/javascript" charset="utf-8"></script> |
|
326 | 326 | <script src="{{ static_url("base/js/keyboard.js") }}" type="text/javascript" charset="utf-8"></script> |
|
327 | 327 | <script src="{{ static_url("base/js/security.js") }}" type="text/javascript" charset="utf-8"></script> |
|
328 | 328 | <script src="{{ static_url("base/js/dialog.js") }}" type="text/javascript" charset="utf-8"></script> |
|
329 | 329 | <script src="{{ static_url("services/kernels/js/kernel.js") }}" type="text/javascript" charset="utf-8"></script> |
|
330 | 330 | <script src="{{ static_url("services/kernels/js/comm.js") }}" type="text/javascript" charset="utf-8"></script> |
|
331 | 331 | <script src="{{ static_url("services/sessions/js/session.js") }}" type="text/javascript" charset="utf-8"></script> |
|
332 | 332 | <script src="{{ static_url("notebook/js/layoutmanager.js") }}" type="text/javascript" charset="utf-8"></script> |
|
333 | 333 | <script src="{{ static_url("notebook/js/mathjaxutils.js") }}" type="text/javascript" charset="utf-8"></script> |
|
334 | 334 | <script src="{{ static_url("notebook/js/outputarea.js") }}" type="text/javascript" charset="utf-8"></script> |
|
335 | 335 | <script src="{{ static_url("notebook/js/cell.js") }}" type="text/javascript" charset="utf-8"></script> |
|
336 | 336 | <script src="{{ static_url("notebook/js/celltoolbar.js") }}" type="text/javascript" charset="utf-8"></script> |
|
337 | 337 | <script src="{{ static_url("notebook/js/codecell.js") }}" type="text/javascript" charset="utf-8"></script> |
|
338 | 338 | <script src="{{ static_url("notebook/js/completer.js") }}" type="text/javascript" charset="utf-8"></script> |
|
339 | 339 | <script src="{{ static_url("notebook/js/textcell.js") }}" type="text/javascript" charset="utf-8"></script> |
|
340 | 340 | <script src="{{ static_url("notebook/js/savewidget.js") }}" type="text/javascript" charset="utf-8"></script> |
|
341 | 341 | <script src="{{ static_url("notebook/js/quickhelp.js") }}" type="text/javascript" charset="utf-8"></script> |
|
342 | 342 | <script src="{{ static_url("notebook/js/pager.js") }}" type="text/javascript" charset="utf-8"></script> |
|
343 | 343 | <script src="{{ static_url("notebook/js/menubar.js") }}" type="text/javascript" charset="utf-8"></script> |
|
344 | 344 | <script src="{{ static_url("notebook/js/toolbar.js") }}" type="text/javascript" charset="utf-8"></script> |
|
345 | 345 | <script src="{{ static_url("notebook/js/maintoolbar.js") }}" type="text/javascript" charset="utf-8"></script> |
|
346 | 346 | <script src="{{ static_url("notebook/js/notebook.js") }}" type="text/javascript" charset="utf-8"></script> |
|
347 | 347 | <script src="{{ static_url("notebook/js/keyboardmanager.js") }}" type="text/javascript" charset="utf-8"></script> |
|
348 | 348 | <script src="{{ static_url("notebook/js/notificationwidget.js") }}" type="text/javascript" charset="utf-8"></script> |
|
349 | 349 | <script src="{{ static_url("notebook/js/notificationarea.js") }}" type="text/javascript" charset="utf-8"></script> |
|
350 | 350 | <script src="{{ static_url("notebook/js/tooltip.js") }}" type="text/javascript" charset="utf-8"></script> |
|
351 | 351 | <script src="{{ static_url("notebook/js/tour.js") }}" type="text/javascript" charset="utf-8"></script> |
|
352 | 352 | |
|
353 | 353 | <script src="{{ static_url("notebook/js/config.js") }}" type="text/javascript" charset="utf-8"></script> |
|
354 | 354 | <script src="{{ static_url("notebook/js/main.js") }}" type="text/javascript" charset="utf-8"></script> |
|
355 | 355 | |
|
356 | 356 | <script src="{{ static_url("notebook/js/contexthint.js") }}" charset="utf-8"></script> |
|
357 | 357 | |
|
358 | 358 | <script src="{{ static_url("notebook/js/celltoolbarpresets/default.js") }}" type="text/javascript" charset="utf-8"></script> |
|
359 | 359 | <script src="{{ static_url("notebook/js/celltoolbarpresets/rawcell.js") }}" type="text/javascript" charset="utf-8"></script> |
|
360 | 360 | <script src="{{ static_url("notebook/js/celltoolbarpresets/slideshow.js") }}" type="text/javascript" charset="utf-8"></script> |
|
361 | 361 | |
|
362 | 362 | {% endblock %} |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file renamed from IPython/html/tests/notebook/merge_cells.js to IPython/html/tests/notebook/merge_cells_api.js | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file renamed from docs/source/_templates/htmlnotebook.html to docs/source/_templates/notebook_redirect.html | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file renamed from docs/source/interactive/cm_keyboard.rst to docs/source/notebook/cm_keyboard.rst |
|
1 | NO CONTENT: file renamed from docs/source/interactive/nbconvert.rst to docs/source/notebook/nbconvert.rst |
|
1 | NO CONTENT: file renamed from docs/source/interactive/notebook.rst to docs/source/notebook/notebook.rst |
|
1 | NO CONTENT: file renamed from docs/source/interactive/public_server.rst to docs/source/notebook/public_server.rst | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed, binary diff hidden |
|
1 | NO CONTENT: file was removed, binary diff hidden |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed, binary diff hidden |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed, binary diff hidden |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
General Comments 0
You need to be logged in to leave comments.
Login now