##// END OF EJS Templates
Using beforeunload to save at exit and kill the kernel.
Brian E. Granger -
Show More
@@ -1,158 +1,158
1 """Tornado handlers for the notebook."""
1 """Tornado handlers for the notebook."""
2
2
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Imports
4 # Imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6
6
7 import json
7 import json
8 import logging
8 import logging
9 import urllib
9 import urllib
10
10
11 from tornado import web
11 from tornado import web
12 from tornado import websocket
12 from tornado import websocket
13
13
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Top-level handlers
16 # Top-level handlers
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19
19
20 class NBBrowserHandler(web.RequestHandler):
20 class NBBrowserHandler(web.RequestHandler):
21 def get(self):
21 def get(self):
22 nbm = self.application.notebook_manager
22 nbm = self.application.notebook_manager
23 project = nbm.notebook_dir
23 project = nbm.notebook_dir
24 self.render('nbbrowser.html', project=project)
24 self.render('nbbrowser.html', project=project)
25
25
26
26
27 class NewHandler(web.RequestHandler):
27 class NewHandler(web.RequestHandler):
28 def get(self):
28 def get(self):
29 notebook_id = self.application.notebook_manager.new_notebook()
29 notebook_id = self.application.notebook_manager.new_notebook()
30 self.render('notebook.html', notebook_id=notebook_id)
30 self.render('notebook.html', notebook_id=notebook_id)
31
31
32
32
33 class NamedNotebookHandler(web.RequestHandler):
33 class NamedNotebookHandler(web.RequestHandler):
34 def get(self, notebook_id):
34 def get(self, notebook_id):
35 nbm = self.application.notebook_manager
35 nbm = self.application.notebook_manager
36 if not nbm.notebook_exists(notebook_id):
36 if not nbm.notebook_exists(notebook_id):
37 raise web.HTTPError(404)
37 raise web.HTTPError(404)
38 self.render('notebook.html', notebook_id=notebook_id)
38 self.render('notebook.html', notebook_id=notebook_id)
39
39
40
40
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42 # Kernel handlers
42 # Kernel handlers
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44
44
45
45
46 class MainKernelHandler(web.RequestHandler):
46 class MainKernelHandler(web.RequestHandler):
47
47
48 def get(self):
48 def get(self):
49 rkm = self.application.routing_kernel_manager
49 rkm = self.application.routing_kernel_manager
50 self.finish(json.dumps(rkm.kernel_ids))
50 self.finish(json.dumps(rkm.kernel_ids))
51
51
52 def post(self):
52 def post(self):
53 rkm = self.application.routing_kernel_manager
53 rkm = self.application.routing_kernel_manager
54 notebook_id = self.get_argument('notebook', default=None)
54 notebook_id = self.get_argument('notebook', default=None)
55 kernel_id = rkm.start_kernel(notebook_id)
55 kernel_id = rkm.start_kernel(notebook_id)
56 self.set_header('Location', '/'+kernel_id)
56 self.set_header('Location', '/'+kernel_id)
57 self.finish(json.dumps(kernel_id))
57 self.finish(json.dumps(kernel_id))
58
58
59
59
60 class KernelHandler(web.RequestHandler):
60 class KernelHandler(web.RequestHandler):
61
61
62 SUPPORTED_METHODS = ('DELETE')
62 SUPPORTED_METHODS = ('DELETE')
63
63
64 def delete(self, kernel_id):
64 def delete(self, kernel_id):
65 rkm = self.application.routing_kernel_manager
65 rkm = self.application.routing_kernel_manager
66 self.kill_kernel(kernel_id)
66 rkm.kill_kernel(kernel_id)
67 self.set_status(204)
67 self.set_status(204)
68 self.finish()
68 self.finish()
69
69
70
70
71 class KernelActionHandler(web.RequestHandler):
71 class KernelActionHandler(web.RequestHandler):
72
72
73 def post(self, kernel_id, action):
73 def post(self, kernel_id, action):
74 rkm = self.application.routing_kernel_manager
74 rkm = self.application.routing_kernel_manager
75 if action == 'interrupt':
75 if action == 'interrupt':
76 rkm.interrupt_kernel(kernel_id)
76 rkm.interrupt_kernel(kernel_id)
77 self.set_status(204)
77 self.set_status(204)
78 if action == 'restart':
78 if action == 'restart':
79 new_kernel_id = rkm.restart_kernel(kernel_id)
79 new_kernel_id = rkm.restart_kernel(kernel_id)
80 self.write(json.dumps(new_kernel_id))
80 self.write(json.dumps(new_kernel_id))
81 self.finish()
81 self.finish()
82
82
83
83
84 class ZMQStreamHandler(websocket.WebSocketHandler):
84 class ZMQStreamHandler(websocket.WebSocketHandler):
85
85
86 def initialize(self, stream_name):
86 def initialize(self, stream_name):
87 self.stream_name = stream_name
87 self.stream_name = stream_name
88
88
89 def open(self, kernel_id):
89 def open(self, kernel_id):
90 rkm = self.application.routing_kernel_manager
90 rkm = self.application.routing_kernel_manager
91 self.router = rkm.get_router(kernel_id, self.stream_name)
91 self.router = rkm.get_router(kernel_id, self.stream_name)
92 self.client_id = self.router.register_client(self)
92 self.client_id = self.router.register_client(self)
93
93
94 def on_message(self, msg):
94 def on_message(self, msg):
95 self.router.forward_msg(self.client_id, msg)
95 self.router.forward_msg(self.client_id, msg)
96
96
97 def on_close(self):
97 def on_close(self):
98 self.router.unregister_client(self.client_id)
98 self.router.unregister_client(self.client_id)
99
99
100
100
101 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
102 # Notebook web service handlers
102 # Notebook web service handlers
103 #-----------------------------------------------------------------------------
103 #-----------------------------------------------------------------------------
104
104
105 class NotebookRootHandler(web.RequestHandler):
105 class NotebookRootHandler(web.RequestHandler):
106
106
107 def get(self):
107 def get(self):
108 nbm = self.application.notebook_manager
108 nbm = self.application.notebook_manager
109 files = nbm.list_notebooks()
109 files = nbm.list_notebooks()
110 self.finish(json.dumps(files))
110 self.finish(json.dumps(files))
111
111
112 def post(self):
112 def post(self):
113 nbm = self.application.notebook_manager
113 nbm = self.application.notebook_manager
114 body = self.request.body.strip()
114 body = self.request.body.strip()
115 format = self.get_argument('format', default='json')
115 format = self.get_argument('format', default='json')
116 name = self.get_argument('name', default=None)
116 name = self.get_argument('name', default=None)
117 if body:
117 if body:
118 notebook_id = nbm.save_new_notebook(body, name=name, format=format)
118 notebook_id = nbm.save_new_notebook(body, name=name, format=format)
119 else:
119 else:
120 notebook_id = nbm.new_notebook()
120 notebook_id = nbm.new_notebook()
121 self.set_header('Location', '/'+notebook_id)
121 self.set_header('Location', '/'+notebook_id)
122 self.finish(json.dumps(notebook_id))
122 self.finish(json.dumps(notebook_id))
123
123
124
124
125 class NotebookHandler(web.RequestHandler):
125 class NotebookHandler(web.RequestHandler):
126
126
127 SUPPORTED_METHODS = ('GET', 'PUT', 'DELETE')
127 SUPPORTED_METHODS = ('GET', 'PUT', 'DELETE')
128
128
129 def get(self, notebook_id):
129 def get(self, notebook_id):
130 nbm = self.application.notebook_manager
130 nbm = self.application.notebook_manager
131 format = self.get_argument('format', default='json')
131 format = self.get_argument('format', default='json')
132 last_mod, name, data = nbm.get_notebook(notebook_id, format)
132 last_mod, name, data = nbm.get_notebook(notebook_id, format)
133 if format == u'json':
133 if format == u'json':
134 self.set_header('Content-Type', 'application/json')
134 self.set_header('Content-Type', 'application/json')
135 self.set_header('Content-Disposition','attachment; filename=%s.json' % name)
135 self.set_header('Content-Disposition','attachment; filename=%s.json' % name)
136 elif format == u'xml':
136 elif format == u'xml':
137 self.set_header('Content-Type', 'application/xml')
137 self.set_header('Content-Type', 'application/xml')
138 self.set_header('Content-Disposition','attachment; filename=%s.ipynb' % name)
138 self.set_header('Content-Disposition','attachment; filename=%s.ipynb' % name)
139 elif format == u'py':
139 elif format == u'py':
140 self.set_header('Content-Type', 'application/x-python')
140 self.set_header('Content-Type', 'application/x-python')
141 self.set_header('Content-Disposition','attachment; filename=%s.py' % name)
141 self.set_header('Content-Disposition','attachment; filename=%s.py' % name)
142 self.set_header('Last-Modified', last_mod)
142 self.set_header('Last-Modified', last_mod)
143 self.finish(data)
143 self.finish(data)
144
144
145 def put(self, notebook_id):
145 def put(self, notebook_id):
146 nbm = self.application.notebook_manager
146 nbm = self.application.notebook_manager
147 format = self.get_argument('format', default='json')
147 format = self.get_argument('format', default='json')
148 name = self.get_argument('name', default=None)
148 name = self.get_argument('name', default=None)
149 nbm.save_notebook(notebook_id, self.request.body, name=name, format=format)
149 nbm.save_notebook(notebook_id, self.request.body, name=name, format=format)
150 self.set_status(204)
150 self.set_status(204)
151 self.finish()
151 self.finish()
152
152
153 def delete(self, notebook_id):
153 def delete(self, notebook_id):
154 nbm = self.application.notebook_manager
154 nbm = self.application.notebook_manager
155 nbm.delete_notebook(notebook_id)
155 nbm.delete_notebook(notebook_id)
156 self.set_status(204)
156 self.set_status(204)
157 self.finish()
157 self.finish()
158
158
@@ -1,278 +1,288
1
1
2 /**
2 /**
3 * Primary styles
3 * Primary styles
4 *
4 *
5 * Author: IPython Development Team
5 * Author: IPython Development Team
6 */
6 */
7
7
8
8
9 body {
9 body {
10 background-color: white;
10 background-color: white;
11 /* This makes sure that the body covers the entire window and needs to
11 /* This makes sure that the body covers the entire window and needs to
12 be in a different element than the display: box in wrapper below */
12 be in a different element than the display: box in wrapper below */
13 position: absolute;
13 position: absolute;
14 left: 0px;
14 left: 0px;
15 right: 0px;
15 right: 0px;
16 top: 0px;
16 top: 0px;
17 bottom: 0px;
17 bottom: 0px;
18 overflow: hidden;
18 overflow: hidden;
19 }
19 }
20
20
21 span#save_widget {
21 span#save_widget {
22 position: absolute;
22 position: absolute;
23 left: 0px;
23 left: 0px;
24 padding: 5px 0px;
24 padding: 5px 0px;
25 margin: 0px 0px 0px 0px;
25 margin: 0px 0px 0px 0px;
26 }
26 }
27
27
28 input#notebook_name {
28 input#notebook_name {
29 height: 1em;
29 height: 1em;
30 line-height: 1em;
30 line-height: 1em;
31 padding: 5px;
31 padding: 5px;
32 }
32 }
33
33
34 span#kernel_status {
34 span#kernel_status {
35 position: absolute;
35 position: absolute;
36 padding: 8px 5px 5px 5px;
36 padding: 8px 5px 5px 5px;
37 right: 10px;
37 right: 10px;
38 font-weight: bold;
38 font-weight: bold;
39 }
39 }
40
40
41 .status_idle {
41 .status_idle {
42 color: gray;
42 color: gray;
43 }
43 }
44
44
45 .status_busy {
45 .status_busy {
46 color: red;
46 color: red;
47 }
47 }
48
48
49 .status_restarting {
49 .status_restarting {
50 color: black;
50 color: black;
51 }
51 }
52
52
53 div#left_panel {
53 div#left_panel {
54 overflow-y: auto;
54 overflow-y: auto;
55 top: 0px;
55 top: 0px;
56 left: 0px;
56 left: 0px;
57 margin: 0px;
57 margin: 0px;
58 padding: 0px;
58 padding: 0px;
59 position: absolute;
59 position: absolute;
60 }
60 }
61
61
62 h3.section_header {
62 h3.section_header {
63 padding: 5px;
63 padding: 5px;
64 }
64 }
65
65
66 div.section_content {
66 div.section_content {
67 padding: 5px;
67 padding: 5px;
68 }
68 }
69
69
70
70
71 span.section_row_buttons > button {
71 span.section_row_buttons > button {
72 width: 60px;
72 width: 60px;
73 }
73 }
74
74
75 .section_row {
75 .section_row {
76 margin: 5px 0px;
76 margin: 5px 0px;
77 }
77 }
78
78
79 .section_row_buttons {
79 .section_row_buttons {
80 float: right;
80 float: right;
81 }
81 }
82
82
83 #kernel_persist {
84 float: right;
85 }
86
87 .checkbox_label {
88 font-size: 85%;
89 float: right;
90 padding: 0.3em;
91 }
92
83 .section_row_header {
93 .section_row_header {
84 float: left;
94 float: left;
85 font-size: 85%;
95 font-size: 85%;
86 padding: 0.2em 0em;
96 padding: 0.4em 0em;
87 font-weight: bold;
97 font-weight: bold;
88 }
98 }
89
99
90 span.button_label {
100 span.button_label {
91 padding: 0.2em 1em;
101 padding: 0.2em 1em;
92 font-size: 77%;
102 font-size: 77%;
93 float: right;
103 float: right;
94 }
104 }
95
105
96 /* This is needed because FF was adding a 2px margin top and bottom. */
106 /* This is needed because FF was adding a 2px margin top and bottom. */
97 .section_row .ui-button {
107 .section_row .ui-button {
98 margin-top: 0px;
108 margin-top: 0px;
99 margin-bottom: 0px;
109 margin-bottom: 0px;
100 }
110 }
101
111
102 #download_format {
112 #download_format {
103 float: right;
113 float: right;
104 font-size: 85%;
114 font-size: 85%;
105 width: 60px;
115 width: 60px;
106 margin: 1px 5px;
116 margin: 1px 5px;
107 }
117 }
108
118
109 div#left_panel_splitter {
119 div#left_panel_splitter {
110 width: 8px;
120 width: 8px;
111 top: 0px;
121 top: 0px;
112 left: 202px;
122 left: 202px;
113 margin: 0px;
123 margin: 0px;
114 padding: 0px;
124 padding: 0px;
115 position: absolute;
125 position: absolute;
116 }
126 }
117
127
118 div#notebook_panel {
128 div#notebook_panel {
119 /* The L margin will be set in the Javascript code*/
129 /* The L margin will be set in the Javascript code*/
120 margin: 0px 0px 0px 0px;
130 margin: 0px 0px 0px 0px;
121 padding: 0px;
131 padding: 0px;
122 }
132 }
123
133
124 div#notebook {
134 div#notebook {
125 overflow-y: scroll;
135 overflow-y: scroll;
126 overflow-x: auto;
136 overflow-x: auto;
127 width: 100%;
137 width: 100%;
128 padding: 0px 15px 0px 15px;
138 padding: 0px 15px 0px 15px;
129 margin: 0px
139 margin: 0px
130 background-color: white;
140 background-color: white;
131 }
141 }
132
142
133 div#pager_splitter {
143 div#pager_splitter {
134 height: 8px;
144 height: 8px;
135 }
145 }
136
146
137 div#pager {
147 div#pager {
138 padding: 15px;
148 padding: 15px;
139 overflow: auto;
149 overflow: auto;
140 }
150 }
141
151
142 div.cell {
152 div.cell {
143 width: 100%;
153 width: 100%;
144 padding: 5px;
154 padding: 5px;
145 /* This acts as a spacer between cells, that is outside the border */
155 /* This acts as a spacer between cells, that is outside the border */
146 margin: 15px 0px 15px 0px;
156 margin: 15px 0px 15px 0px;
147 }
157 }
148
158
149 div.code_cell {
159 div.code_cell {
150 background-color: white;
160 background-color: white;
151 }
161 }
152
162
153 div.prompt {
163 div.prompt {
154 width: 80px;
164 width: 80px;
155 padding: 0.4em;
165 padding: 0.4em;
156 margin: 0px;
166 margin: 0px;
157 font-family: monospace;
167 font-family: monospace;
158 }
168 }
159
169
160 div.input_prompt {
170 div.input_prompt {
161 color: navy;
171 color: navy;
162 }
172 }
163
173
164 div.output {
174 div.output {
165 /* This is a spacer between the input and output of each cell */
175 /* This is a spacer between the input and output of each cell */
166 margin-top: 15px;
176 margin-top: 15px;
167 }
177 }
168
178
169 div.output_prompt {
179 div.output_prompt {
170 color: darkred;
180 color: darkred;
171 }
181 }
172
182
173 div.output_area {
183 div.output_area {
174 text-align: left;
184 text-align: left;
175 color: black;
185 color: black;
176 font-family: monospace;
186 font-family: monospace;
177 }
187 }
178
188
179 div.output_stream {
189 div.output_stream {
180 padding: 0.4em;
190 padding: 0.4em;
181 }
191 }
182
192
183 div.output_latex {
193 div.output_latex {
184 /* Slightly bigger than the rest of the notebook */
194 /* Slightly bigger than the rest of the notebook */
185 font-size: 116%;
195 font-size: 116%;
186 }
196 }
187
197
188 div.output_html {
198 div.output_html {
189 }
199 }
190
200
191 div.output_png {
201 div.output_png {
192 }
202 }
193
203
194 div.text_cell {
204 div.text_cell {
195 background-color: white;
205 background-color: white;
196 }
206 }
197
207
198 textarea.text_cell_input {
208 textarea.text_cell_input {
199 /* Slightly bigger than the rest of the notebook */
209 /* Slightly bigger than the rest of the notebook */
200 font-size: 116%;
210 font-size: 116%;
201 font-family: monospace;
211 font-family: monospace;
202 outline: none;
212 outline: none;
203 resize: none;
213 resize: none;
204 width: inherit;
214 width: inherit;
205 border-style: none;
215 border-style: none;
206 padding: 0px;
216 padding: 0px;
207 margin: 0px;
217 margin: 0px;
208 color: black;
218 color: black;
209 }
219 }
210
220
211 div.text_cell_render {
221 div.text_cell_render {
212 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
222 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
213 /* Slightly bigger than the rest of the notebook */
223 /* Slightly bigger than the rest of the notebook */
214 font-size: 116%;
224 font-size: 116%;
215 outline: none;
225 outline: none;
216 resize: none;
226 resize: none;
217 width: inherit;
227 width: inherit;
218 border-style: none;
228 border-style: none;
219 padding: 5px;
229 padding: 5px;
220 color: black;
230 color: black;
221 }
231 }
222
232
223 div.text_cell_render em {font-style: italic;}
233 div.text_cell_render em {font-style: italic;}
224 div.text_cell_render strong {font-weight: bold;}
234 div.text_cell_render strong {font-weight: bold;}
225 div.text_cell_render u {text-decoration: underline;}
235 div.text_cell_render u {text-decoration: underline;}
226 div.text_cell_render :link { text-decoration: underline }
236 div.text_cell_render :link { text-decoration: underline }
227 div.text_cell_render :visited { text-decoration: underline }
237 div.text_cell_render :visited { text-decoration: underline }
228 div.text_cell_render h1 {font-size: 197%; margin: .67em 0; font-weight: bold;}
238 div.text_cell_render h1 {font-size: 197%; margin: .67em 0; font-weight: bold;}
229 div.text_cell_render h2 {font-size: 153.9%; margin: .75em 0; font-weight: bold;}
239 div.text_cell_render h2 {font-size: 153.9%; margin: .75em 0; font-weight: bold;}
230 div.text_cell_render h3 {font-size: 116%; margin: .83em 0; font-weight: bold;}
240 div.text_cell_render h3 {font-size: 116%; margin: .83em 0; font-weight: bold;}
231 div.text_cell_render h4 {margin: 1.12em 0; font-weight: bold;}
241 div.text_cell_render h4 {margin: 1.12em 0; font-weight: bold;}
232 div.text_cell_render h5 {font-size: 85%.; margin: 1.5em 0; font-weight: bold;}
242 div.text_cell_render h5 {font-size: 85%.; margin: 1.5em 0; font-weight: bold;}
233 div.text_cell_render h6 {font-size: 77%; margin: 1.67em 0; font-weight: bold;}
243 div.text_cell_render h6 {font-size: 77%; margin: 1.67em 0; font-weight: bold;}
234 div.text_cell_render ul {list-style:disc; margin-left: 40px;}
244 div.text_cell_render ul {list-style:disc; margin-left: 40px;}
235 div.text_cell_render ul ul {list-style:square; margin-left: 40px;}
245 div.text_cell_render ul ul {list-style:square; margin-left: 40px;}
236 div.text_cell_render ul ul ul {list-style:circle; margin-left: 40px;}
246 div.text_cell_render ul ul ul {list-style:circle; margin-left: 40px;}
237 div.text_cell_render ol {list-style:upper-roman; margin-left: 40px;}
247 div.text_cell_render ol {list-style:upper-roman; margin-left: 40px;}
238 div.text_cell_render ol ol {list-style:upper-alpha;}
248 div.text_cell_render ol ol {list-style:upper-alpha;}
239 div.text_cell_render ol ol ol {list-style:decimal;}
249 div.text_cell_render ol ol ol {list-style:decimal;}
240 div.text_cell_render ol ol ol ol {list-style:lower-alpha;}
250 div.text_cell_render ol ol ol ol {list-style:lower-alpha;}
241 div.text_cell_render ol ol ol ol ol {list-style:lower-roman;}
251 div.text_cell_render ol ol ol ol ol {list-style:lower-roman;}
242
252
243
253
244 .CodeMirror {
254 .CodeMirror {
245 overflow: hidden; /* Changed from auto to remove scrollbar */
255 overflow: hidden; /* Changed from auto to remove scrollbar */
246 height: auto; /* Changed to auto to autogrow */
256 height: auto; /* Changed to auto to autogrow */
247 line-height: 1.231; /* Changed from 1em to our global default */
257 line-height: 1.231; /* Changed from 1em to our global default */
248 }
258 }
249
259
250 /* CSS font colors for translated ANSI colors. */
260 /* CSS font colors for translated ANSI colors. */
251
261
252
262
253 .ansiblack {color: black;}
263 .ansiblack {color: black;}
254 .ansired {color: darkred;}
264 .ansired {color: darkred;}
255 .ansigreen {color: darkgreen;}
265 .ansigreen {color: darkgreen;}
256 .ansiyellow {color: brown;}
266 .ansiyellow {color: brown;}
257 .ansiblue {color: darkblue;}
267 .ansiblue {color: darkblue;}
258 .ansipurple {color: darkviolet;}
268 .ansipurple {color: darkviolet;}
259 .ansicyan {color: steelblue;}
269 .ansicyan {color: steelblue;}
260 .ansigrey {color: grey;}
270 .ansigrey {color: grey;}
261 .ansibold {font-weight: bold;}
271 .ansibold {font-weight: bold;}
262
272
263 .completions {
273 .completions {
264 position: absolute;
274 position: absolute;
265 z-index: 10;
275 z-index: 10;
266 overflow: auto;
276 overflow: auto;
267 border: 1px solid black;
277 border: 1px solid black;
268 }
278 }
269
279
270 .completions select {
280 .completions select {
271 background: white;
281 background: white;
272 outline: none;
282 outline: none;
273 border: none;
283 border: none;
274 padding: 0px;
284 padding: 0px;
275 margin: 0px;
285 margin: 0px;
276 font-family: monospace;
286 font-family: monospace;
277 }
287 }
278
288
@@ -1,106 +1,114
1
1
2 //============================================================================
2 //============================================================================
3 // Kernel
3 // Kernel
4 //============================================================================
4 //============================================================================
5
5
6 var IPython = (function (IPython) {
6 var IPython = (function (IPython) {
7
7
8 var utils = IPython.utils;
8 var utils = IPython.utils;
9
9
10 var Kernel = function () {
10 var Kernel = function () {
11 this.kernel_id = null;
11 this.kernel_id = null;
12 this.base_url = "/kernels";
12 this.base_url = "/kernels";
13 this.kernel_url = null;
13 this.kernel_url = null;
14 };
14 };
15
15
16
16
17 Kernel.prototype.get_msg = function (msg_type, content) {
17 Kernel.prototype.get_msg = function (msg_type, content) {
18 var msg = {
18 var msg = {
19 header : {
19 header : {
20 msg_id : utils.uuid(),
20 msg_id : utils.uuid(),
21 username : "username",
21 username : "username",
22 session: this.session_id,
22 session: this.session_id,
23 msg_type : msg_type
23 msg_type : msg_type
24 },
24 },
25 content : content,
25 content : content,
26 parent_header : {}
26 parent_header : {}
27 };
27 };
28 return msg;
28 return msg;
29 }
29 }
30
30
31 Kernel.prototype.start_kernel = function (notebook_id, callback) {
31 Kernel.prototype.start_kernel = function (notebook_id, callback) {
32 var that = this;
32 var that = this;
33 var qs = $.param({notebook:notebook_id});
33 var qs = $.param({notebook:notebook_id});
34 $.post(this.base_url + '?' + qs,
34 $.post(this.base_url + '?' + qs,
35 function (kernel_id) {
35 function (kernel_id) {
36 that._handle_start_kernel(kernel_id, callback);
36 that._handle_start_kernel(kernel_id, callback);
37 },
37 },
38 'json'
38 'json'
39 );
39 );
40 };
40 };
41
41
42
42
43 Kernel.prototype._handle_start_kernel = function (kernel_id, callback) {
43 Kernel.prototype._handle_start_kernel = function (kernel_id, callback) {
44 this.kernel_id = kernel_id;
44 this.kernel_id = kernel_id;
45 this.kernel_url = this.base_url + "/" + this.kernel_id;
45 this.kernel_url = this.base_url + "/" + this.kernel_id;
46 this._start_channels();
46 this._start_channels();
47 callback();
47 callback();
48 };
48 };
49
49
50
50
51 Kernel.prototype._start_channels = function () {
51 Kernel.prototype._start_channels = function () {
52 var ws_url = "ws://127.0.0.1:8888" + this.kernel_url;
52 var ws_url = "ws://127.0.0.1:8888" + this.kernel_url;
53 this.shell_channel = new WebSocket(ws_url + "/shell");
53 this.shell_channel = new WebSocket(ws_url + "/shell");
54 this.iopub_channel = new WebSocket(ws_url + "/iopub");
54 this.iopub_channel = new WebSocket(ws_url + "/iopub");
55 }
55 }
56
56
57
57
58 Kernel.prototype.execute = function (code) {
58 Kernel.prototype.execute = function (code) {
59 var content = {
59 var content = {
60 code : code,
60 code : code,
61 silent : false,
61 silent : false,
62 user_variables : [],
62 user_variables : [],
63 user_expressions : {}
63 user_expressions : {}
64 };
64 };
65 var msg = this.get_msg("execute_request", content);
65 var msg = this.get_msg("execute_request", content);
66 this.shell_channel.send(JSON.stringify(msg));
66 this.shell_channel.send(JSON.stringify(msg));
67 return msg.header.msg_id;
67 return msg.header.msg_id;
68 }
68 }
69
69
70
70
71 Kernel.prototype.complete = function (line, cursor_pos) {
71 Kernel.prototype.complete = function (line, cursor_pos) {
72 var content = {
72 var content = {
73 text : '',
73 text : '',
74 line : line,
74 line : line,
75 cursor_pos : cursor_pos
75 cursor_pos : cursor_pos
76 };
76 };
77 var msg = this.get_msg("complete_request", content);
77 var msg = this.get_msg("complete_request", content);
78 this.shell_channel.send(JSON.stringify(msg));
78 this.shell_channel.send(JSON.stringify(msg));
79 return msg.header.msg_id;
79 return msg.header.msg_id;
80 }
80 }
81
81
82
82
83 Kernel.prototype.interrupt = function () {
83 Kernel.prototype.interrupt = function () {
84 $.post(this.kernel_url + "/interrupt");
84 $.post(this.kernel_url + "/interrupt");
85 };
85 };
86
86
87
87
88 Kernel.prototype.restart = function () {
88 Kernel.prototype.restart = function () {
89 IPython.kernel_status_widget.status_restarting();
89 IPython.kernel_status_widget.status_restarting();
90 url = this.kernel_url + "/restart"
90 var url = this.kernel_url + "/restart"
91 var that = this;
91 var that = this;
92 $.post(url, function (kernel_id) {
92 $.post(url, function (kernel_id) {
93 console.log("Kernel restarted: " + kernel_id);
93 console.log("Kernel restarted: " + kernel_id);
94 that.kernel_id = kernel_id;
94 that.kernel_id = kernel_id;
95 that.kernel_url = that.base_url + "/" + that.kernel_id;
95 that.kernel_url = that.base_url + "/" + that.kernel_id;
96 IPython.kernel_status_widget.status_idle();
96 IPython.kernel_status_widget.status_idle();
97 }, 'json');
97 }, 'json');
98 };
98 };
99
99
100
100
101 Kernel.prototype.kill = function () {
102 var settings = {
103 cache : false,
104 type : "DELETE",
105 };
106 $.ajax(this.kernel_url, settings);
107 };
108
101 IPython.Kernel = Kernel;
109 IPython.Kernel = Kernel;
102
110
103 return IPython;
111 return IPython;
104
112
105 }(IPython));
113 }(IPython));
106
114
@@ -1,101 +1,112
1
1
2 //============================================================================
2 //============================================================================
3 // Cell
3 // Cell
4 //============================================================================
4 //============================================================================
5
5
6 var IPython = (function (IPython) {
6 var IPython = (function (IPython) {
7
7
8 var utils = IPython.utils;
8 var utils = IPython.utils;
9
9
10 var SaveWidget = function (selector) {
10 var SaveWidget = function (selector) {
11 this.selector = selector;
11 this.selector = selector;
12 this.notebook_name_re = /[^/\\]+/
12 this.notebook_name_re = /[^/\\]+/
13 if (this.selector !== undefined) {
13 if (this.selector !== undefined) {
14 this.element = $(selector);
14 this.element = $(selector);
15 this.style();
15 this.style();
16 this.bind_events();
16 this.bind_events();
17 }
17 }
18 };
18 };
19
19
20
20
21 SaveWidget.prototype.style = function () {
21 SaveWidget.prototype.style = function () {
22 this.element.find('input#notebook_name').addClass('ui-widget ui-widget-content');
22 this.element.find('input#notebook_name').addClass('ui-widget ui-widget-content');
23 this.element.find('button#save_notebook').button();
23 this.element.find('button#save_notebook').button();
24 var left_panel_width = $('div#left_panel').outerWidth();
24 var left_panel_width = $('div#left_panel').outerWidth();
25 var left_panel_splitter_width = $('div#left_panel_splitter').outerWidth();
25 var left_panel_splitter_width = $('div#left_panel_splitter').outerWidth();
26 $('span#save_widget').css({marginLeft:left_panel_width+left_panel_splitter_width});
26 $('span#save_widget').css({marginLeft:left_panel_width+left_panel_splitter_width});
27 };
27 };
28
28
29
29
30 SaveWidget.prototype.bind_events = function () {
30 SaveWidget.prototype.bind_events = function () {
31 var that = this;
31 var that = this;
32 this.element.find('button#save_notebook').click(function () {
32 this.element.find('button#save_notebook').click(function () {
33 IPython.notebook.save_notebook();
33 IPython.notebook.save_notebook();
34 });
34 });
35
36 $(window).bind('beforeunload', function () {
37 var kill_kernel = $('#kill_kernel').prop('checked');
38 IPython.notebook.save_notebook();
39 if (kill_kernel) {
40 IPython.notebook.kernel.kill();
41 return "You are about to exit this notebook and kill the kernel.";
42 } else {
43 return "You are about the exit this notebook and leave the kernel running.";
44 };
45 });
35 };
46 };
36
47
37
48
38 SaveWidget.prototype.get_notebook_name = function () {
49 SaveWidget.prototype.get_notebook_name = function () {
39 return this.element.find('input#notebook_name').attr('value');
50 return this.element.find('input#notebook_name').attr('value');
40 }
51 }
41
52
42
53
43 SaveWidget.prototype.set_notebook_name = function (nbname) {
54 SaveWidget.prototype.set_notebook_name = function (nbname) {
44 this.element.find('input#notebook_name').attr('value',nbname);
55 this.element.find('input#notebook_name').attr('value',nbname);
45 }
56 }
46
57
47
58
48 SaveWidget.prototype.get_notebook_id = function () {
59 SaveWidget.prototype.get_notebook_id = function () {
49 return this.element.find('span#notebook_id').text()
60 return this.element.find('span#notebook_id').text()
50 };
61 };
51
62
52
63
53 SaveWidget.prototype.update_url = function () {
64 SaveWidget.prototype.update_url = function () {
54 var notebook_id = this.get_notebook_id();
65 var notebook_id = this.get_notebook_id();
55 if (notebook_id !== '') {
66 if (notebook_id !== '') {
56 window.history.replaceState({}, '', notebook_id);
67 window.history.replaceState({}, '', notebook_id);
57 };
68 };
58 };
69 };
59
70
60
71
61 SaveWidget.prototype.test_notebook_name = function () {
72 SaveWidget.prototype.test_notebook_name = function () {
62 var nbname = this.get_notebook_name();
73 var nbname = this.get_notebook_name();
63 if (this.notebook_name_re.test(nbname)) {
74 if (this.notebook_name_re.test(nbname)) {
64 return true;
75 return true;
65 } else {
76 } else {
66 var bad_name = $('<div/>');
77 var bad_name = $('<div/>');
67 bad_name.html(
78 bad_name.html(
68 "The notebook name you entered (" +
79 "The notebook name you entered (" +
69 nbname +
80 nbname +
70 ") is not valid. Notebook names can contain any characters except / and \\"
81 ") is not valid. Notebook names can contain any characters except / and \\"
71 );
82 );
72 bad_name.dialog({title: 'Invalid name', modal: true});
83 bad_name.dialog({title: 'Invalid name', modal: true});
73 return false;
84 return false;
74 };
85 };
75 };
86 };
76
87
77
88
78 SaveWidget.prototype.status_save = function () {
89 SaveWidget.prototype.status_save = function () {
79 this.element.find('span.ui-button-text').text('Save');
90 this.element.find('span.ui-button-text').text('Save');
80 this.element.find('button#save_notebook').button('enable');
91 this.element.find('button#save_notebook').button('enable');
81 };
92 };
82
93
83
94
84 SaveWidget.prototype.status_saving = function () {
95 SaveWidget.prototype.status_saving = function () {
85 this.element.find('span.ui-button-text').text('Saving');
96 this.element.find('span.ui-button-text').text('Saving');
86 this.element.find('button#save_notebook').button('disable');
97 this.element.find('button#save_notebook').button('disable');
87 };
98 };
88
99
89
100
90 SaveWidget.prototype.status_loading = function () {
101 SaveWidget.prototype.status_loading = function () {
91 this.element.find('span.ui-button-text').text('Loading');
102 this.element.find('span.ui-button-text').text('Loading');
92 this.element.find('button#save_notebook').button('disable');
103 this.element.find('button#save_notebook').button('disable');
93 };
104 };
94
105
95
106
96 IPython.SaveWidget = SaveWidget;
107 IPython.SaveWidget = SaveWidget;
97
108
98 return IPython;
109 return IPython;
99
110
100 }(IPython));
111 }(IPython));
101
112
@@ -1,188 +1,194
1 <!DOCTYPE HTML>
1 <!DOCTYPE HTML>
2 <html>
2 <html>
3
3
4 <head>
4 <head>
5 <meta charset="utf-8">
5 <meta charset="utf-8">
6
6
7 <title>IPython Notebook</title>
7 <title>IPython Notebook</title>
8
8
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12
12
13 <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script>
13 <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script>
14 <!-- <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script> -->
14 <!-- <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script> -->
15 <script type="text/javascript">
15 <script type="text/javascript">
16 if (typeof MathJax == 'undefined') {
16 if (typeof MathJax == 'undefined') {
17 console.log("Trying to load local copy of MathJax");
17 console.log("Trying to load local copy of MathJax");
18 document.write(unescape("%3Cscript type='text/javascript' src='static/mathjax/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
18 document.write(unescape("%3Cscript type='text/javascript' src='static/mathjax/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
19 }
19 }
20 </script>
20 </script>
21
21
22 <link rel="stylesheet" href="static/codemirror2/lib/codemirror.css">
22 <link rel="stylesheet" href="static/codemirror2/lib/codemirror.css">
23 <link rel="stylesheet" href="static/codemirror2/mode/python/python.css">
23 <link rel="stylesheet" href="static/codemirror2/mode/python/python.css">
24
24
25 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
25 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
26 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
26 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
27 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
27 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
28 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
28 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
29
29
30 </head>
30 </head>
31
31
32 <body>
32 <body>
33
33
34 <div id="header">
34 <div id="header">
35 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
35 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
36 <span id="save_widget">
36 <span id="save_widget">
37 <input type="text" id="notebook_name" size="20"></textarea>
37 <input type="text" id="notebook_name" size="20"></textarea>
38 <span id="notebook_id" style="display:none">{{notebook_id}}</span>
38 <span id="notebook_id" style="display:none">{{notebook_id}}</span>
39 <button id="save_notebook">Save</button>
39 <button id="save_notebook">Save</button>
40 </span>
40 </span>
41 <span id="kernel_status">Idle</span>
41 <span id="kernel_status">Idle</span>
42 </div>
42 </div>
43
43
44 <div id="main_app">
44 <div id="main_app">
45
45
46 <div id="left_panel">
46 <div id="left_panel">
47
47
48 <div id="notebook_section">
48 <div id="notebook_section">
49 <h3 class="section_header">Notebook</h3>
49 <h3 class="section_header">Notebook</h3>
50 <div class="section_content">
50 <div class="section_content">
51 <div class="section_row">
51 <div class="section_row">
52 <span id="new_open" class="section_row_buttons">
52 <span id="new_open" class="section_row_buttons">
53 <button id="new_notebook">New</button>
53 <button id="new_notebook">New</button>
54 <button id="open_notebook">Open</button>
54 <button id="open_notebook">Open</button>
55 </span>
55 </span>
56 <span class="section_row_header">Actions</span>
56 <span class="section_row_header">Actions</span>
57 </div>
57 </div>
58 <div class="section_row">
58 <div class="section_row">
59 <span class="section_row_buttons">
59 <span class="section_row_buttons">
60 <button id="download_notebook">Export</button>
60 <button id="download_notebook">Export</button>
61 </span>
61 </span>
62 <span>
62 <span>
63 <select id="download_format">
63 <select id="download_format">
64 <option value="xml">xml</option>
64 <option value="xml">xml</option>
65 <option value="json">json</option>
65 <option value="json">json</option>
66 <option value="py">py</option>
66 <option value="py">py</option>
67 </select>
67 </select>
68 </span>
68 </span>
69 </div>
69 </div>
70 </div>
70 </div>
71 </div>
71 </div>
72
72
73 <div id="cell_section">
73 <div id="cell_section">
74 <h3 class="section_header">Cell</h3>
74 <h3 class="section_header">Cell</h3>
75 <div class="section_content">
75 <div class="section_content">
76 <div class="section_row">
76 <div class="section_row">
77 <span class="section_row_buttons">
77 <span class="section_row_buttons">
78 <button id="delete_cell">Delete</button>
78 <button id="delete_cell">Delete</button>
79 </span>
79 </span>
80 <span class="section_row_header">Actions</span>
80 <span class="section_row_header">Actions</span>
81 </div>
81 </div>
82 <div class="section_row">
82 <div class="section_row">
83 <span id="insert" class="section_row_buttons">
83 <span id="insert" class="section_row_buttons">
84 <button id="insert_cell_above">Above</button>
84 <button id="insert_cell_above">Above</button>
85 <button id="insert_cell_below">Below</button>
85 <button id="insert_cell_below">Below</button>
86 </span>
86 </span>
87 <span class="button_label">Insert</span>
87 <span class="button_label">Insert</span>
88 </div>
88 </div>
89 <div class="section_row">
89 <div class="section_row">
90 <span id="move" class="section_row_buttons">
90 <span id="move" class="section_row_buttons">
91 <button id="move_cell_up">Up</button>
91 <button id="move_cell_up">Up</button>
92 <button id="move_cell_down">Down</button>
92 <button id="move_cell_down">Down</button>
93 </span>
93 </span>
94 <span class="button_label">Move</span>
94 <span class="button_label">Move</span>
95 </div>
95 </div>
96 <div class="section_row">
96 <div class="section_row">
97 <span id="cell_type" class="section_row_buttons">
97 <span id="cell_type" class="section_row_buttons">
98 <button id="to_code">Code</button>
98 <button id="to_code">Code</button>
99 <button id="to_text">Text</button>
99 <button id="to_text">Text</button>
100 </span>
100 </span>
101 <span class="button_label">Cell Type</span>
101 <span class="button_label">Cell Type</span>
102 </div>
102 </div>
103 <div class="section_row">
103 <div class="section_row">
104 <span id="toggle_output" class="section_row_buttons">
104 <span id="toggle_output" class="section_row_buttons">
105 <button id="collapse_cell">Collapse</button>
105 <button id="collapse_cell">Collapse</button>
106 <button id="expand_cell">Expand</button>
106 <button id="expand_cell">Expand</button>
107 </span>
107 </span>
108 <span class="button_label">Output</span>
108 <span class="button_label">Output</span>
109 </div>
109 </div>
110 <div class="section_row">
110 <div class="section_row">
111 <span id="run_cells" class="section_row_buttons">
111 <span id="run_cells" class="section_row_buttons">
112 <button id="run_selected_cell">Selected</button>
112 <button id="run_selected_cell">Selected</button>
113 <button id="run_all_cells">All</button>
113 <button id="run_all_cells">All</button>
114 </span>
114 </span>
115 <span class="button_label">Run</span>
115 <span class="button_label">Run</span>
116 </div>
116 </div>
117 </div>
117 </div>
118 </div>
118 </div>
119
119
120 <div id="kernel_section">
120 <div id="kernel_section">
121 <h3 class="section_header">Kernel</h3>
121 <h3 class="section_header">Kernel</h3>
122 <div class="section_content">
122 <div class="section_content">
123 <div class="section_row">
123 <div class="section_row">
124 <span id="int_restart" class="section_row_buttons">
124 <span id="int_restart" class="section_row_buttons">
125 <button id="int_kernel">Interrupt</button>
125 <button id="int_kernel">Interrupt</button>
126 <button id="restart_kernel">Restart</button>
126 <button id="restart_kernel">Restart</button>
127 </span>
127 </span>
128 <span class="section_row_header">Actions</span>
128 <span class="section_row_header">Actions</span>
129 </div>
129 </div>
130 <div class="section_row">
131 <span id="kernel_persist">
132 <input type="checkbox" id="kill_kernel"></input>
133 </span>
134 <span class="checkbox_label">Kill kernel upon exit:</span>
135 </div>
130 </div>
136 </div>
131 </div>
137 </div>
132
138
133 <div id="help_section">
139 <div id="help_section">
134 <h3 class="section_header">Help</h3>
140 <h3 class="section_header">Help</h3>
135 <div class="section_content">
141 <div class="section_content">
136 <div class="section_row">
142 <div class="section_row">
137 <span id="help_buttons0" class="section_row_buttons">
143 <span id="help_buttons0" class="section_row_buttons">
138 <button id="python_help"><a href="http://docs.python.org" target="_blank">Python</a></button>
144 <button id="python_help"><a href="http://docs.python.org" target="_blank">Python</a></button>
139 <button id="ipython_help"><a href="http://ipython.org/documentation.html" target="_blank">IPython</a></button>
145 <button id="ipython_help"><a href="http://ipython.org/documentation.html" target="_blank">IPython</a></button>
140 <button id="numpy_help"><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></button>
146 <button id="numpy_help"><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></button>
141 </span>
147 </span>
142 <span class="section_row_header">Links</span>
148 <span class="section_row_header">Links</span>
143 </div>
149 </div>
144 <div class="section_row">
150 <div class="section_row">
145 <span id="help_buttons1" class="section_row_buttons">
151 <span id="help_buttons1" class="section_row_buttons">
146 <button id="matplotlib_help"><a href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a></button>
152 <button id="matplotlib_help"><a href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a></button>
147 <button id="scipy_help"><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></button>
153 <button id="scipy_help"><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></button>
148 <button id="sympy_help"><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></button>
154 <button id="sympy_help"><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></button>
149 </span>
155 </span>
150 </div>
156 </div>
151 </div>
157 </div>
152 </div>
158 </div>
153
159
154 </div>
160 </div>
155 <div id="left_panel_splitter"></div>
161 <div id="left_panel_splitter"></div>
156 <div id="notebook_panel">
162 <div id="notebook_panel">
157 <div id="notebook"></div>
163 <div id="notebook"></div>
158 <div id="pager_splitter"></div>
164 <div id="pager_splitter"></div>
159 <div id="pager"></div>
165 <div id="pager"></div>
160 </div>
166 </div>
161
167
162 </div>
168 </div>
163
169
164 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
170 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
165 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
171 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
166 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
172 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
167 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
173 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
168 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
174 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
169 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
175 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
170 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
176 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
171 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
177 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
172 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
178 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
173 <script src="static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
179 <script src="static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
174 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
180 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
175 <script src="static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
181 <script src="static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
176 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
182 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
177 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
183 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
178 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
184 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
179 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
185 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
180 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
186 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
181 <script src="static/codemirror2/lib/codemirror.js"></script>
187 <script src="static/codemirror2/lib/codemirror.js"></script>
182 <script src="static/codemirror2/mode/python/python.js"></script>
188 <script src="static/codemirror2/mode/python/python.js"></script>
183
189
184 </body>
190 </body>
185
191
186 </html>
192 </html>
187
193
188
194
General Comments 0
You need to be logged in to leave comments. Login now