##// END OF EJS Templates
Merge remote-tracking branch 'upstream/master'
Doug Blank -
r15207:16945929 merge
parent child Browse files
Show More

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

@@ -0,0 +1,251 b''
1 """Interact with functions using widgets."""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 from __future__ import print_function
16
17 try: # Python >= 3.3
18 from inspect import signature, Parameter
19 except ImportError:
20 from IPython.utils.signatures import signature, Parameter
21 from inspect import getcallargs
22
23 from IPython.html.widgets import (Widget, TextWidget,
24 FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget,
25 ContainerWidget, DOMWidget)
26 from IPython.display import display, clear_output
27 from IPython.utils.py3compat import string_types, unicode_type
28 from IPython.utils.traitlets import HasTraits, Any, Unicode
29
30 #-----------------------------------------------------------------------------
31 # Classes and Functions
32 #-----------------------------------------------------------------------------
33
34
35 def _matches(o, pattern):
36 """Match a pattern of types in a sequence."""
37 if not len(o) == len(pattern):
38 return False
39 comps = zip(o,pattern)
40 return all(isinstance(obj,kind) for obj,kind in comps)
41
42
43 def _get_min_max_value(min, max, value=None, step=None):
44 """Return min, max, value given input values with possible None."""
45 if value is None:
46 if not max > min:
47 raise ValueError('max must be greater than min: (min={0}, max={1})'.format(min, max))
48 value = min + abs(min-max)/2
49 value = type(min)(value)
50 elif min is None and max is None:
51 if value == 0.0:
52 min, max, value = 0.0, 1.0, 0.5
53 elif value == 0:
54 min, max, value = 0, 1, 0
55 elif isinstance(value, (int, float)):
56 min, max = (-value, 3*value) if value > 0 else (3*value, -value)
57 else:
58 raise TypeError('expected a number, got: %r' % value)
59 else:
60 raise ValueError('unable to infer range, value from: ({0}, {1}, {2})'.format(min, max, value))
61 if step is not None:
62 # ensure value is on a step
63 r = (value - min) % step
64 value = value - r
65 return min, max, value
66
67 def _widget_abbrev_single_value(o):
68 """Make widgets from single values, which can be used as parameter defaults."""
69 if isinstance(o, string_types):
70 return TextWidget(value=unicode_type(o))
71 elif isinstance(o, dict):
72 return DropdownWidget(values=o)
73 elif isinstance(o, bool):
74 return CheckboxWidget(value=o)
75 elif isinstance(o, float):
76 min, max, value = _get_min_max_value(None, None, o)
77 return FloatSliderWidget(value=o, min=min, max=max)
78 elif isinstance(o, int):
79 min, max, value = _get_min_max_value(None, None, o)
80 return IntSliderWidget(value=o, min=min, max=max)
81 else:
82 return None
83
84 def _widget_abbrev(o):
85 """Make widgets from abbreviations: single values, lists or tuples."""
86 float_or_int = (float, int)
87 if isinstance(o, (list, tuple)):
88 if o and all(isinstance(x, string_types) for x in o):
89 return DropdownWidget(values=[unicode_type(k) for k in o])
90 elif _matches(o, (float_or_int, float_or_int)):
91 min, max, value = _get_min_max_value(o[0], o[1])
92 if all(isinstance(_, int) for _ in o):
93 cls = IntSliderWidget
94 else:
95 cls = FloatSliderWidget
96 return cls(value=value, min=min, max=max)
97 elif _matches(o, (float_or_int, float_or_int, float_or_int)):
98 step = o[2]
99 if step <= 0:
100 raise ValueError("step must be >= 0, not %r" % step)
101 min, max, value = _get_min_max_value(o[0], o[1], step=step)
102 if all(isinstance(_, int) for _ in o):
103 cls = IntSliderWidget
104 else:
105 cls = FloatSliderWidget
106 return cls(value=value, min=min, max=max, step=step)
107 else:
108 return _widget_abbrev_single_value(o)
109
110 def _widget_from_abbrev(abbrev):
111 """Build a Widget intstance given an abbreviation or Widget."""
112 if isinstance(abbrev, Widget) or isinstance(abbrev, fixed):
113 return abbrev
114
115 widget = _widget_abbrev(abbrev)
116 if widget is None:
117 raise ValueError("%r cannot be transformed to a Widget" % (abbrev,))
118 return widget
119
120 def _yield_abbreviations_for_parameter(param, kwargs):
121 """Get an abbreviation for a function parameter."""
122 name = param.name
123 kind = param.kind
124 ann = param.annotation
125 default = param.default
126 empty = Parameter.empty
127 not_found = (None, None)
128 if kind == Parameter.POSITIONAL_OR_KEYWORD:
129 if name in kwargs:
130 yield name, kwargs.pop(name)
131 elif ann is not empty:
132 if default is empty:
133 yield name, ann
134 else:
135 yield name, ann
136 elif default is not empty:
137 yield name, default
138 else:
139 yield not_found
140 elif kind == Parameter.KEYWORD_ONLY:
141 if name in kwargs:
142 yield name, kwargs.pop(name)
143 elif ann is not empty:
144 yield name, ann
145 elif default is not empty:
146 yield name, default
147 else:
148 yield not_found
149 elif kind == Parameter.VAR_KEYWORD:
150 # In this case name=kwargs and we yield the items in kwargs with their keys.
151 for k, v in kwargs.copy().items():
152 kwargs.pop(k)
153 yield k, v
154
155 def _find_abbreviations(f, kwargs):
156 """Find the abbreviations for a function and kwargs passed to interact."""
157 new_kwargs = []
158 for param in signature(f).parameters.values():
159 for name, value in _yield_abbreviations_for_parameter(param, kwargs):
160 if value is None:
161 raise ValueError('cannot find widget or abbreviation for argument: {!r}'.format(name))
162 new_kwargs.append((name, value))
163 return new_kwargs
164
165 def _widgets_from_abbreviations(seq):
166 """Given a sequence of (name, abbrev) tuples, return a sequence of Widgets."""
167 result = []
168 for name, abbrev in seq:
169 widget = _widget_from_abbrev(abbrev)
170 widget.description = name
171 result.append(widget)
172 return result
173
174 def interactive(__interact_f, **kwargs):
175 """Build a group of widgets to interact with a function."""
176 f = __interact_f
177 co = kwargs.pop('clear_output', True)
178 kwargs_widgets = []
179 container = ContainerWidget()
180 container.result = None
181 container.args = []
182 container.kwargs = dict()
183 kwargs = kwargs.copy()
184
185 new_kwargs = _find_abbreviations(f, kwargs)
186 # Before we proceed, let's make sure that the user has passed a set of args+kwargs
187 # that will lead to a valid call of the function. This protects against unspecified
188 # and doubly-specified arguments.
189 getcallargs(f, **{n:v for n,v in new_kwargs})
190 # Now build the widgets from the abbreviations.
191 kwargs_widgets.extend(_widgets_from_abbreviations(new_kwargs))
192 kwargs_widgets.extend(_widgets_from_abbreviations(sorted(kwargs.items(), key = lambda x: x[0])))
193
194 # This has to be done as an assignment, not using container.children.append,
195 # so that traitlets notices the update. We skip any objects (such as fixed) that
196 # are not DOMWidgets.
197 c = [w for w in kwargs_widgets if isinstance(w, DOMWidget)]
198 container.children = c
199
200 # Build the callback
201 def call_f(name, old, new):
202 container.kwargs = {}
203 for widget in kwargs_widgets:
204 value = widget.value
205 container.kwargs[widget.description] = value
206 if co:
207 clear_output(wait=True)
208 container.result = f(**container.kwargs)
209
210 # Wire up the widgets
211 for widget in kwargs_widgets:
212 widget.on_trait_change(call_f, 'value')
213
214 container.on_displayed(lambda _: call_f(None, None, None))
215
216 return container
217
218 def interact(__interact_f=None, **kwargs):
219 """interact(f, **kwargs)
220
221 Interact with a function using widgets."""
222 # positional arg support in: https://gist.github.com/8851331
223 if __interact_f is not None:
224 # This branch handles the cases:
225 # 1. interact(f, **kwargs)
226 # 2. @interact
227 # def f(*args, **kwargs):
228 # ...
229 f = __interact_f
230 w = interactive(f, **kwargs)
231 f.widget = w
232 display(w)
233 return f
234 else:
235 # This branch handles the case:
236 # @interact(a=30, b=40)
237 # def f(*args, **kwargs):
238 # ...
239 def dec(f):
240 w = interactive(f, **kwargs)
241 f.widget = w
242 display(w)
243 return f
244 return dec
245
246 class fixed(HasTraits):
247 """A pseudo-widget whose value is fixed and never synced to the client."""
248 value = Any(help="Any Python object")
249 description = Unicode('', help="Any Python object")
250 def __init__(self, value, **kwargs):
251 super(fixed, self).__init__(value=value, **kwargs)
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,408 b''
1 """Test interact and interactive."""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2014 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 from __future__ import print_function
15
16 from collections import OrderedDict
17
18 import nose.tools as nt
19 import IPython.testing.tools as tt
20
21 # from IPython.core.getipython import get_ipython
22 from IPython.html import widgets
23 from IPython.html.widgets import interact, interactive, Widget, interaction
24 from IPython.utils.py3compat import annotate
25 # from IPython.utils.capture import capture_output
26
27 #-----------------------------------------------------------------------------
28 # Utility stuff
29 #-----------------------------------------------------------------------------
30
31 class DummyComm(object):
32 comm_id = 'a-b-c-d'
33 def send(self, *args, **kwargs):
34 pass
35
36 def close(self, *args, **kwargs):
37 pass
38
39 _widget_attrs = {}
40 displayed = []
41
42 def setup():
43 _widget_attrs['comm'] = Widget.comm
44 Widget.comm = DummyComm()
45 _widget_attrs['_ipython_display_'] = Widget._ipython_display_
46 def raise_not_implemented(*args, **kwargs):
47 raise NotImplementedError()
48 Widget._ipython_display_ = raise_not_implemented
49
50 def teardown():
51 for attr, value in _widget_attrs.items():
52 setattr(Widget, attr, value)
53
54 def f(**kwargs):
55 pass
56
57 def clear_display():
58 global displayed
59 displayed = []
60
61 def record_display(*args):
62 displayed.extend(args)
63
64 #-----------------------------------------------------------------------------
65 # Actual tests
66 #-----------------------------------------------------------------------------
67
68 def check_widget(w, **d):
69 """Check a single widget against a dict"""
70 for attr, expected in d.items():
71 if attr == 'cls':
72 nt.assert_is(w.__class__, expected)
73 else:
74 value = getattr(w, attr)
75 nt.assert_equal(value, expected,
76 "%s.%s = %r != %r" % (w.__class__.__name__, attr, value, expected)
77 )
78
79 def check_widgets(container, **to_check):
80 """Check that widgets are created as expected"""
81 # build a widget dictionary, so it matches
82 widgets = {}
83 for w in container.children:
84 widgets[w.description] = w
85
86 for key, d in to_check.items():
87 nt.assert_in(key, widgets)
88 check_widget(widgets[key], **d)
89
90
91 def test_single_value_string():
92 a = u'hello'
93 c = interactive(f, a=a)
94 w = c.children[0]
95 check_widget(w,
96 cls=widgets.TextWidget,
97 description='a',
98 value=a,
99 )
100
101 def test_single_value_bool():
102 for a in (True, False):
103 c = interactive(f, a=a)
104 w = c.children[0]
105 check_widget(w,
106 cls=widgets.CheckboxWidget,
107 description='a',
108 value=a,
109 )
110
111 def test_single_value_dict():
112 for d in [
113 dict(a=5),
114 dict(a=5, b='b', c=dict),
115 ]:
116 c = interactive(f, d=d)
117 w = c.children[0]
118 check_widget(w,
119 cls=widgets.DropdownWidget,
120 description='d',
121 values=d,
122 value=next(iter(d.values())),
123 )
124
125 def test_single_value_float():
126 for a in (2.25, 1.0, -3.5):
127 c = interactive(f, a=a)
128 w = c.children[0]
129 check_widget(w,
130 cls=widgets.FloatSliderWidget,
131 description='a',
132 value=a,
133 min= -a if a > 0 else 3*a,
134 max= 3*a if a > 0 else -a,
135 step=0.1,
136 readout=True,
137 )
138
139 def test_single_value_int():
140 for a in (1, 5, -3):
141 c = interactive(f, a=a)
142 nt.assert_equal(len(c.children), 1)
143 w = c.children[0]
144 check_widget(w,
145 cls=widgets.IntSliderWidget,
146 description='a',
147 value=a,
148 min= -a if a > 0 else 3*a,
149 max= 3*a if a > 0 else -a,
150 step=1,
151 readout=True,
152 )
153
154 def test_list_tuple_2_int():
155 with nt.assert_raises(ValueError):
156 c = interactive(f, tup=(1,1))
157 with nt.assert_raises(ValueError):
158 c = interactive(f, tup=(1,-1))
159 for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]:
160 c = interactive(f, tup=(min, max), lis=[min, max])
161 nt.assert_equal(len(c.children), 2)
162 d = dict(
163 cls=widgets.IntSliderWidget,
164 min=min,
165 max=max,
166 step=1,
167 readout=True,
168 )
169 check_widgets(c, tup=d, lis=d)
170
171 def test_list_tuple_3_int():
172 with nt.assert_raises(ValueError):
173 c = interactive(f, tup=(1,2,0))
174 with nt.assert_raises(ValueError):
175 c = interactive(f, tup=(1,2,-1))
176 for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]:
177 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
178 nt.assert_equal(len(c.children), 2)
179 d = dict(
180 cls=widgets.IntSliderWidget,
181 min=min,
182 max=max,
183 step=step,
184 readout=True,
185 )
186 check_widgets(c, tup=d, lis=d)
187
188 def test_list_tuple_2_float():
189 with nt.assert_raises(ValueError):
190 c = interactive(f, tup=(1.0,1.0))
191 with nt.assert_raises(ValueError):
192 c = interactive(f, tup=(0.5,-0.5))
193 for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]:
194 c = interactive(f, tup=(min, max), lis=[min, max])
195 nt.assert_equal(len(c.children), 2)
196 d = dict(
197 cls=widgets.FloatSliderWidget,
198 min=min,
199 max=max,
200 step=.1,
201 readout=True,
202 )
203 check_widgets(c, tup=d, lis=d)
204
205 def test_list_tuple_3_float():
206 with nt.assert_raises(ValueError):
207 c = interactive(f, tup=(1,2,0.0))
208 with nt.assert_raises(ValueError):
209 c = interactive(f, tup=(-1,-2,1.))
210 with nt.assert_raises(ValueError):
211 c = interactive(f, tup=(1,2.,-1.))
212 for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]:
213 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
214 nt.assert_equal(len(c.children), 2)
215 d = dict(
216 cls=widgets.FloatSliderWidget,
217 min=min,
218 max=max,
219 step=step,
220 readout=True,
221 )
222 check_widgets(c, tup=d, lis=d)
223
224 def test_list_tuple_str():
225 values = ['hello', 'there', 'guy']
226 first = values[0]
227 dvalues = OrderedDict((v,v) for v in values)
228 c = interactive(f, tup=tuple(values), lis=list(values))
229 nt.assert_equal(len(c.children), 2)
230 d = dict(
231 cls=widgets.DropdownWidget,
232 value=first,
233 values=dvalues
234 )
235 check_widgets(c, tup=d, lis=d)
236
237 def test_list_tuple_invalid():
238 for bad in [
239 (),
240 (5, 'hi'),
241 ('hi', 5),
242 ({},),
243 (None,),
244 ]:
245 with nt.assert_raises(ValueError):
246 print(bad) # because there is no custom message in assert_raises
247 c = interactive(f, tup=bad)
248
249 def test_defaults():
250 @annotate(n=10)
251 def f(n, f=4.5):
252 pass
253
254 c = interactive(f)
255 check_widgets(c,
256 n=dict(
257 cls=widgets.IntSliderWidget,
258 value=10,
259 ),
260 f=dict(
261 cls=widgets.FloatSliderWidget,
262 value=4.5,
263 ),
264 )
265
266 def test_annotations():
267 @annotate(n=10, f=widgets.FloatTextWidget())
268 def f(n, f):
269 pass
270
271 c = interactive(f)
272 check_widgets(c,
273 n=dict(
274 cls=widgets.IntSliderWidget,
275 value=10,
276 ),
277 f=dict(
278 cls=widgets.FloatTextWidget,
279 ),
280 )
281
282 def test_priority():
283 @annotate(annotate='annotate', kwarg='annotate')
284 def f(kwarg='default', annotate='default', default='default'):
285 pass
286
287 c = interactive(f, kwarg='kwarg')
288 check_widgets(c,
289 kwarg=dict(
290 cls=widgets.TextWidget,
291 value='kwarg',
292 ),
293 annotate=dict(
294 cls=widgets.TextWidget,
295 value='annotate',
296 ),
297 )
298
299 @nt.with_setup(clear_display)
300 def test_decorator_kwarg():
301 with tt.monkeypatch(interaction, 'display', record_display):
302 @interact(a=5)
303 def foo(a):
304 pass
305 nt.assert_equal(len(displayed), 1)
306 w = displayed[0].children[0]
307 check_widget(w,
308 cls=widgets.IntSliderWidget,
309 value=5,
310 )
311
312 @nt.with_setup(clear_display)
313 def test_decorator_no_call():
314 with tt.monkeypatch(interaction, 'display', record_display):
315 @interact
316 def foo(a='default'):
317 pass
318 nt.assert_equal(len(displayed), 1)
319 w = displayed[0].children[0]
320 check_widget(w,
321 cls=widgets.TextWidget,
322 value='default',
323 )
324
325 @nt.with_setup(clear_display)
326 def test_call_interact():
327 def foo(a='default'):
328 pass
329 with tt.monkeypatch(interaction, 'display', record_display):
330 ifoo = interact(foo)
331 nt.assert_equal(len(displayed), 1)
332 w = displayed[0].children[0]
333 check_widget(w,
334 cls=widgets.TextWidget,
335 value='default',
336 )
337
338 @nt.with_setup(clear_display)
339 def test_call_interact_kwargs():
340 def foo(a='default'):
341 pass
342 with tt.monkeypatch(interaction, 'display', record_display):
343 ifoo = interact(foo, a=10)
344 nt.assert_equal(len(displayed), 1)
345 w = displayed[0].children[0]
346 check_widget(w,
347 cls=widgets.IntSliderWidget,
348 value=10,
349 )
350
351 @nt.with_setup(clear_display)
352 def test_call_decorated_on_trait_change():
353 """test calling @interact decorated functions"""
354 d = {}
355 with tt.monkeypatch(interaction, 'display', record_display):
356 @interact
357 def foo(a='default'):
358 d['a'] = a
359 return a
360 nt.assert_equal(len(displayed), 1)
361 w = displayed[0].children[0]
362 check_widget(w,
363 cls=widgets.TextWidget,
364 value='default',
365 )
366 # test calling the function directly
367 a = foo('hello')
368 nt.assert_equal(a, 'hello')
369 nt.assert_equal(d['a'], 'hello')
370
371 # test that setting trait values calls the function
372 w.value = 'called'
373 nt.assert_equal(d['a'], 'called')
374
375 @nt.with_setup(clear_display)
376 def test_call_decorated_kwargs_on_trait_change():
377 """test calling @interact(foo=bar) decorated functions"""
378 d = {}
379 with tt.monkeypatch(interaction, 'display', record_display):
380 @interact(a='kwarg')
381 def foo(a='default'):
382 d['a'] = a
383 return a
384 nt.assert_equal(len(displayed), 1)
385 w = displayed[0].children[0]
386 check_widget(w,
387 cls=widgets.TextWidget,
388 value='kwarg',
389 )
390 # test calling the function directly
391 a = foo('hello')
392 nt.assert_equal(a, 'hello')
393 nt.assert_equal(d['a'], 'hello')
394
395 # test that setting trait values calls the function
396 w.value = 'called'
397 nt.assert_equal(d['a'], 'called')
398
399 def test_fixed():
400 c = interactive(f, a=widgets.fixed(5), b='text')
401 nt.assert_equal(len(c.children), 1)
402 w = c.children[0]
403 check_widget(w,
404 cls=widgets.TextWidget,
405 value='text',
406 description='b',
407 )
408
This diff has been collapsed as it changes many lines, (819 lines changed) Show them Hide them
@@ -0,0 +1,819 b''
1 """Function signature objects for callables
2
3 Back port of Python 3.3's function signature tools from the inspect module,
4 modified to be compatible with Python 2.6, 2.7 and 3.2+.
5 """
6
7 #-----------------------------------------------------------------------------
8 # Python 3.3 stdlib inspect.py is public domain
9 #
10 # Backports Copyright (C) 2013 Aaron Iles
11 # Used under Apache License Version 2.0
12 #
13 # Further Changes are Copyright (C) 2013 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 from __future__ import absolute_import, division, print_function
20 import itertools
21 import functools
22 import re
23 import types
24
25
26 # patch for single-file
27 # we don't support 2.6, so we can just import OrderedDict
28 from collections import OrderedDict
29
30 __version__ = '0.3'
31 # end patch
32
33 __all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']
34
35
36 _WrapperDescriptor = type(type.__call__)
37 _MethodWrapper = type(all.__call__)
38
39 _NonUserDefinedCallables = (_WrapperDescriptor,
40 _MethodWrapper,
41 types.BuiltinFunctionType)
42
43
44 def formatannotation(annotation, base_module=None):
45 if isinstance(annotation, type):
46 if annotation.__module__ in ('builtins', '__builtin__', base_module):
47 return annotation.__name__
48 return annotation.__module__+'.'+annotation.__name__
49 return repr(annotation)
50
51
52 def _get_user_defined_method(cls, method_name, *nested):
53 try:
54 if cls is type:
55 return
56 meth = getattr(cls, method_name)
57 for name in nested:
58 meth = getattr(meth, name, meth)
59 except AttributeError:
60 return
61 else:
62 if not isinstance(meth, _NonUserDefinedCallables):
63 # Once '__signature__' will be added to 'C'-level
64 # callables, this check won't be necessary
65 return meth
66
67
68 def signature(obj):
69 '''Get a signature object for the passed callable.'''
70
71 if not callable(obj):
72 raise TypeError('{0!r} is not a callable object'.format(obj))
73
74 if isinstance(obj, types.MethodType):
75 # In this case we skip the first parameter of the underlying
76 # function (usually `self` or `cls`).
77 sig = signature(obj.__func__)
78 return sig.replace(parameters=tuple(sig.parameters.values())[1:])
79
80 try:
81 sig = obj.__signature__
82 except AttributeError:
83 pass
84 else:
85 if sig is not None:
86 return sig
87
88 try:
89 # Was this function wrapped by a decorator?
90 wrapped = obj.__wrapped__
91 except AttributeError:
92 pass
93 else:
94 return signature(wrapped)
95
96 if isinstance(obj, types.FunctionType):
97 return Signature.from_function(obj)
98
99 if isinstance(obj, functools.partial):
100 sig = signature(obj.func)
101
102 new_params = OrderedDict(sig.parameters.items())
103
104 partial_args = obj.args or ()
105 partial_keywords = obj.keywords or {}
106 try:
107 ba = sig.bind_partial(*partial_args, **partial_keywords)
108 except TypeError as ex:
109 msg = 'partial object {0!r} has incorrect arguments'.format(obj)
110 raise ValueError(msg)
111
112 for arg_name, arg_value in ba.arguments.items():
113 param = new_params[arg_name]
114 if arg_name in partial_keywords:
115 # We set a new default value, because the following code
116 # is correct:
117 #
118 # >>> def foo(a): print(a)
119 # >>> print(partial(partial(foo, a=10), a=20)())
120 # 20
121 # >>> print(partial(partial(foo, a=10), a=20)(a=30))
122 # 30
123 #
124 # So, with 'partial' objects, passing a keyword argument is
125 # like setting a new default value for the corresponding
126 # parameter
127 #
128 # We also mark this parameter with '_partial_kwarg'
129 # flag. Later, in '_bind', the 'default' value of this
130 # parameter will be added to 'kwargs', to simulate
131 # the 'functools.partial' real call.
132 new_params[arg_name] = param.replace(default=arg_value,
133 _partial_kwarg=True)
134
135 elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and
136 not param._partial_kwarg):
137 new_params.pop(arg_name)
138
139 return sig.replace(parameters=new_params.values())
140
141 sig = None
142 if isinstance(obj, type):
143 # obj is a class or a metaclass
144
145 # First, let's see if it has an overloaded __call__ defined
146 # in its metaclass
147 call = _get_user_defined_method(type(obj), '__call__')
148 if call is not None:
149 sig = signature(call)
150 else:
151 # Now we check if the 'obj' class has a '__new__' method
152 new = _get_user_defined_method(obj, '__new__')
153 if new is not None:
154 sig = signature(new)
155 else:
156 # Finally, we should have at least __init__ implemented
157 init = _get_user_defined_method(obj, '__init__')
158 if init is not None:
159 sig = signature(init)
160 elif not isinstance(obj, _NonUserDefinedCallables):
161 # An object with __call__
162 # We also check that the 'obj' is not an instance of
163 # _WrapperDescriptor or _MethodWrapper to avoid
164 # infinite recursion (and even potential segfault)
165 call = _get_user_defined_method(type(obj), '__call__', 'im_func')
166 if call is not None:
167 sig = signature(call)
168
169 if sig is not None:
170 return sig
171
172 if isinstance(obj, types.BuiltinFunctionType):
173 # Raise a nicer error message for builtins
174 msg = 'no signature found for builtin function {0!r}'.format(obj)
175 raise ValueError(msg)
176
177 raise ValueError('callable {0!r} is not supported by signature'.format(obj))
178
179
180 class _void(object):
181 '''A private marker - used in Parameter & Signature'''
182
183
184 class _empty(object):
185 pass
186
187
188 class _ParameterKind(int):
189 def __new__(self, *args, **kwargs):
190 obj = int.__new__(self, *args)
191 obj._name = kwargs['name']
192 return obj
193
194 def __str__(self):
195 return self._name
196
197 def __repr__(self):
198 return '<_ParameterKind: {0!r}>'.format(self._name)
199
200
201 _POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY')
202 _POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')
203 _VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL')
204 _KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY')
205 _VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD')
206
207
208 class Parameter(object):
209 '''Represents a parameter in a function signature.
210
211 Has the following public attributes:
212
213 * name : str
214 The name of the parameter as a string.
215 * default : object
216 The default value for the parameter if specified. If the
217 parameter has no default value, this attribute is not set.
218 * annotation
219 The annotation for the parameter if specified. If the
220 parameter has no annotation, this attribute is not set.
221 * kind : str
222 Describes how argument values are bound to the parameter.
223 Possible values: `Parameter.POSITIONAL_ONLY`,
224 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
225 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
226 '''
227
228 __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')
229
230 POSITIONAL_ONLY = _POSITIONAL_ONLY
231 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
232 VAR_POSITIONAL = _VAR_POSITIONAL
233 KEYWORD_ONLY = _KEYWORD_ONLY
234 VAR_KEYWORD = _VAR_KEYWORD
235
236 empty = _empty
237
238 def __init__(self, name, kind, default=_empty, annotation=_empty,
239 _partial_kwarg=False):
240
241 if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
242 _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
243 raise ValueError("invalid value for 'Parameter.kind' attribute")
244 self._kind = kind
245
246 if default is not _empty:
247 if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
248 msg = '{0} parameters cannot have default values'.format(kind)
249 raise ValueError(msg)
250 self._default = default
251 self._annotation = annotation
252
253 if name is None:
254 if kind != _POSITIONAL_ONLY:
255 raise ValueError("None is not a valid name for a "
256 "non-positional-only parameter")
257 self._name = name
258 else:
259 name = str(name)
260 if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\w*$', name, re.I):
261 msg = '{0!r} is not a valid parameter name'.format(name)
262 raise ValueError(msg)
263 self._name = name
264
265 self._partial_kwarg = _partial_kwarg
266
267 @property
268 def name(self):
269 return self._name
270
271 @property
272 def default(self):
273 return self._default
274
275 @property
276 def annotation(self):
277 return self._annotation
278
279 @property
280 def kind(self):
281 return self._kind
282
283 def replace(self, name=_void, kind=_void, annotation=_void,
284 default=_void, _partial_kwarg=_void):
285 '''Creates a customized copy of the Parameter.'''
286
287 if name is _void:
288 name = self._name
289
290 if kind is _void:
291 kind = self._kind
292
293 if annotation is _void:
294 annotation = self._annotation
295
296 if default is _void:
297 default = self._default
298
299 if _partial_kwarg is _void:
300 _partial_kwarg = self._partial_kwarg
301
302 return type(self)(name, kind, default=default, annotation=annotation,
303 _partial_kwarg=_partial_kwarg)
304
305 def __str__(self):
306 kind = self.kind
307
308 formatted = self._name
309 if kind == _POSITIONAL_ONLY:
310 if formatted is None:
311 formatted = ''
312 formatted = '<{0}>'.format(formatted)
313
314 # Add annotation and default value
315 if self._annotation is not _empty:
316 formatted = '{0}:{1}'.format(formatted,
317 formatannotation(self._annotation))
318
319 if self._default is not _empty:
320 formatted = '{0}={1}'.format(formatted, repr(self._default))
321
322 if kind == _VAR_POSITIONAL:
323 formatted = '*' + formatted
324 elif kind == _VAR_KEYWORD:
325 formatted = '**' + formatted
326
327 return formatted
328
329 def __repr__(self):
330 return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__,
331 id(self), self.name)
332
333 def __hash__(self):
334 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
335 raise TypeError(msg)
336
337 def __eq__(self, other):
338 return (issubclass(other.__class__, Parameter) and
339 self._name == other._name and
340 self._kind == other._kind and
341 self._default == other._default and
342 self._annotation == other._annotation)
343
344 def __ne__(self, other):
345 return not self.__eq__(other)
346
347
348 class BoundArguments(object):
349 '''Result of `Signature.bind` call. Holds the mapping of arguments
350 to the function's parameters.
351
352 Has the following public attributes:
353
354 * arguments : OrderedDict
355 An ordered mutable mapping of parameters' names to arguments' values.
356 Does not contain arguments' default values.
357 * signature : Signature
358 The Signature object that created this instance.
359 * args : tuple
360 Tuple of positional arguments values.
361 * kwargs : dict
362 Dict of keyword arguments values.
363 '''
364
365 def __init__(self, signature, arguments):
366 self.arguments = arguments
367 self._signature = signature
368
369 @property
370 def signature(self):
371 return self._signature
372
373 @property
374 def args(self):
375 args = []
376 for param_name, param in self._signature.parameters.items():
377 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
378 param._partial_kwarg):
379 # Keyword arguments mapped by 'functools.partial'
380 # (Parameter._partial_kwarg is True) are mapped
381 # in 'BoundArguments.kwargs', along with VAR_KEYWORD &
382 # KEYWORD_ONLY
383 break
384
385 try:
386 arg = self.arguments[param_name]
387 except KeyError:
388 # We're done here. Other arguments
389 # will be mapped in 'BoundArguments.kwargs'
390 break
391 else:
392 if param.kind == _VAR_POSITIONAL:
393 # *args
394 args.extend(arg)
395 else:
396 # plain argument
397 args.append(arg)
398
399 return tuple(args)
400
401 @property
402 def kwargs(self):
403 kwargs = {}
404 kwargs_started = False
405 for param_name, param in self._signature.parameters.items():
406 if not kwargs_started:
407 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
408 param._partial_kwarg):
409 kwargs_started = True
410 else:
411 if param_name not in self.arguments:
412 kwargs_started = True
413 continue
414
415 if not kwargs_started:
416 continue
417
418 try:
419 arg = self.arguments[param_name]
420 except KeyError:
421 pass
422 else:
423 if param.kind == _VAR_KEYWORD:
424 # **kwargs
425 kwargs.update(arg)
426 else:
427 # plain keyword argument
428 kwargs[param_name] = arg
429
430 return kwargs
431
432 def __hash__(self):
433 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
434 raise TypeError(msg)
435
436 def __eq__(self, other):
437 return (issubclass(other.__class__, BoundArguments) and
438 self.signature == other.signature and
439 self.arguments == other.arguments)
440
441 def __ne__(self, other):
442 return not self.__eq__(other)
443
444
445 class Signature(object):
446 '''A Signature object represents the overall signature of a function.
447 It stores a Parameter object for each parameter accepted by the
448 function, as well as information specific to the function itself.
449
450 A Signature object has the following public attributes and methods:
451
452 * parameters : OrderedDict
453 An ordered mapping of parameters' names to the corresponding
454 Parameter objects (keyword-only arguments are in the same order
455 as listed in `code.co_varnames`).
456 * return_annotation : object
457 The annotation for the return type of the function if specified.
458 If the function has no annotation for its return type, this
459 attribute is not set.
460 * bind(*args, **kwargs) -> BoundArguments
461 Creates a mapping from positional and keyword arguments to
462 parameters.
463 * bind_partial(*args, **kwargs) -> BoundArguments
464 Creates a partial mapping from positional and keyword arguments
465 to parameters (simulating 'functools.partial' behavior.)
466 '''
467
468 __slots__ = ('_return_annotation', '_parameters')
469
470 _parameter_cls = Parameter
471 _bound_arguments_cls = BoundArguments
472
473 empty = _empty
474
475 def __init__(self, parameters=None, return_annotation=_empty,
476 __validate_parameters__=True):
477 '''Constructs Signature from the given list of Parameter
478 objects and 'return_annotation'. All arguments are optional.
479 '''
480
481 if parameters is None:
482 params = OrderedDict()
483 else:
484 if __validate_parameters__:
485 params = OrderedDict()
486 top_kind = _POSITIONAL_ONLY
487
488 for idx, param in enumerate(parameters):
489 kind = param.kind
490 if kind < top_kind:
491 msg = 'wrong parameter order: {0} before {1}'
492 msg = msg.format(top_kind, param.kind)
493 raise ValueError(msg)
494 else:
495 top_kind = kind
496
497 name = param.name
498 if name is None:
499 name = str(idx)
500 param = param.replace(name=name)
501
502 if name in params:
503 msg = 'duplicate parameter name: {0!r}'.format(name)
504 raise ValueError(msg)
505 params[name] = param
506 else:
507 params = OrderedDict(((param.name, param)
508 for param in parameters))
509
510 self._parameters = params
511 self._return_annotation = return_annotation
512
513 @classmethod
514 def from_function(cls, func):
515 '''Constructs Signature for the given python function'''
516
517 if not isinstance(func, types.FunctionType):
518 raise TypeError('{0!r} is not a Python function'.format(func))
519
520 Parameter = cls._parameter_cls
521
522 # Parameter information.
523 func_code = func.__code__
524 pos_count = func_code.co_argcount
525 arg_names = func_code.co_varnames
526 positional = tuple(arg_names[:pos_count])
527 keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)
528 keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
529 annotations = getattr(func, '__annotations__', {})
530 defaults = func.__defaults__
531 kwdefaults = getattr(func, '__kwdefaults__', None)
532
533 if defaults:
534 pos_default_count = len(defaults)
535 else:
536 pos_default_count = 0
537
538 parameters = []
539
540 # Non-keyword-only parameters w/o defaults.
541 non_default_count = pos_count - pos_default_count
542 for name in positional[:non_default_count]:
543 annotation = annotations.get(name, _empty)
544 parameters.append(Parameter(name, annotation=annotation,
545 kind=_POSITIONAL_OR_KEYWORD))
546
547 # ... w/ defaults.
548 for offset, name in enumerate(positional[non_default_count:]):
549 annotation = annotations.get(name, _empty)
550 parameters.append(Parameter(name, annotation=annotation,
551 kind=_POSITIONAL_OR_KEYWORD,
552 default=defaults[offset]))
553
554 # *args
555 if func_code.co_flags & 0x04:
556 name = arg_names[pos_count + keyword_only_count]
557 annotation = annotations.get(name, _empty)
558 parameters.append(Parameter(name, annotation=annotation,
559 kind=_VAR_POSITIONAL))
560
561 # Keyword-only parameters.
562 for name in keyword_only:
563 default = _empty
564 if kwdefaults is not None:
565 default = kwdefaults.get(name, _empty)
566
567 annotation = annotations.get(name, _empty)
568 parameters.append(Parameter(name, annotation=annotation,
569 kind=_KEYWORD_ONLY,
570 default=default))
571 # **kwargs
572 if func_code.co_flags & 0x08:
573 index = pos_count + keyword_only_count
574 if func_code.co_flags & 0x04:
575 index += 1
576
577 name = arg_names[index]
578 annotation = annotations.get(name, _empty)
579 parameters.append(Parameter(name, annotation=annotation,
580 kind=_VAR_KEYWORD))
581
582 return cls(parameters,
583 return_annotation=annotations.get('return', _empty),
584 __validate_parameters__=False)
585
586 @property
587 def parameters(self):
588 try:
589 return types.MappingProxyType(self._parameters)
590 except AttributeError:
591 return OrderedDict(self._parameters.items())
592
593 @property
594 def return_annotation(self):
595 return self._return_annotation
596
597 def replace(self, parameters=_void, return_annotation=_void):
598 '''Creates a customized copy of the Signature.
599 Pass 'parameters' and/or 'return_annotation' arguments
600 to override them in the new copy.
601 '''
602
603 if parameters is _void:
604 parameters = self.parameters.values()
605
606 if return_annotation is _void:
607 return_annotation = self._return_annotation
608
609 return type(self)(parameters,
610 return_annotation=return_annotation)
611
612 def __hash__(self):
613 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
614 raise TypeError(msg)
615
616 def __eq__(self, other):
617 if (not issubclass(type(other), Signature) or
618 self.return_annotation != other.return_annotation or
619 len(self.parameters) != len(other.parameters)):
620 return False
621
622 other_positions = dict((param, idx)
623 for idx, param in enumerate(other.parameters.keys()))
624
625 for idx, (param_name, param) in enumerate(self.parameters.items()):
626 if param.kind == _KEYWORD_ONLY:
627 try:
628 other_param = other.parameters[param_name]
629 except KeyError:
630 return False
631 else:
632 if param != other_param:
633 return False
634 else:
635 try:
636 other_idx = other_positions[param_name]
637 except KeyError:
638 return False
639 else:
640 if (idx != other_idx or
641 param != other.parameters[param_name]):
642 return False
643
644 return True
645
646 def __ne__(self, other):
647 return not self.__eq__(other)
648
649 def _bind(self, args, kwargs, partial=False):
650 '''Private method. Don't use directly.'''
651
652 arguments = OrderedDict()
653
654 parameters = iter(self.parameters.values())
655 parameters_ex = ()
656 arg_vals = iter(args)
657
658 if partial:
659 # Support for binding arguments to 'functools.partial' objects.
660 # See 'functools.partial' case in 'signature()' implementation
661 # for details.
662 for param_name, param in self.parameters.items():
663 if (param._partial_kwarg and param_name not in kwargs):
664 # Simulating 'functools.partial' behavior
665 kwargs[param_name] = param.default
666
667 while True:
668 # Let's iterate through the positional arguments and corresponding
669 # parameters
670 try:
671 arg_val = next(arg_vals)
672 except StopIteration:
673 # No more positional arguments
674 try:
675 param = next(parameters)
676 except StopIteration:
677 # No more parameters. That's it. Just need to check that
678 # we have no `kwargs` after this while loop
679 break
680 else:
681 if param.kind == _VAR_POSITIONAL:
682 # That's OK, just empty *args. Let's start parsing
683 # kwargs
684 break
685 elif param.name in kwargs:
686 if param.kind == _POSITIONAL_ONLY:
687 msg = '{arg!r} parameter is positional only, ' \
688 'but was passed as a keyword'
689 msg = msg.format(arg=param.name)
690 raise TypeError(msg)
691 parameters_ex = (param,)
692 break
693 elif (param.kind == _VAR_KEYWORD or
694 param.default is not _empty):
695 # That's fine too - we have a default value for this
696 # parameter. So, lets start parsing `kwargs`, starting
697 # with the current parameter
698 parameters_ex = (param,)
699 break
700 else:
701 if partial:
702 parameters_ex = (param,)
703 break
704 else:
705 msg = '{arg!r} parameter lacking default value'
706 msg = msg.format(arg=param.name)
707 raise TypeError(msg)
708 else:
709 # We have a positional argument to process
710 try:
711 param = next(parameters)
712 except StopIteration:
713 raise TypeError('too many positional arguments')
714 else:
715 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
716 # Looks like we have no parameter for this positional
717 # argument
718 raise TypeError('too many positional arguments')
719
720 if param.kind == _VAR_POSITIONAL:
721 # We have an '*args'-like argument, let's fill it with
722 # all positional arguments we have left and move on to
723 # the next phase
724 values = [arg_val]
725 values.extend(arg_vals)
726 arguments[param.name] = tuple(values)
727 break
728
729 if param.name in kwargs:
730 raise TypeError('multiple values for argument '
731 '{arg!r}'.format(arg=param.name))
732
733 arguments[param.name] = arg_val
734
735 # Now, we iterate through the remaining parameters to process
736 # keyword arguments
737 kwargs_param = None
738 for param in itertools.chain(parameters_ex, parameters):
739 if param.kind == _POSITIONAL_ONLY:
740 # This should never happen in case of a properly built
741 # Signature object (but let's have this check here
742 # to ensure correct behaviour just in case)
743 raise TypeError('{arg!r} parameter is positional only, '
744 'but was passed as a keyword'. \
745 format(arg=param.name))
746
747 if param.kind == _VAR_KEYWORD:
748 # Memorize that we have a '**kwargs'-like parameter
749 kwargs_param = param
750 continue
751
752 param_name = param.name
753 try:
754 arg_val = kwargs.pop(param_name)
755 except KeyError:
756 # We have no value for this parameter. It's fine though,
757 # if it has a default value, or it is an '*args'-like
758 # parameter, left alone by the processing of positional
759 # arguments.
760 if (not partial and param.kind != _VAR_POSITIONAL and
761 param.default is _empty):
762 raise TypeError('{arg!r} parameter lacking default value'. \
763 format(arg=param_name))
764
765 else:
766 arguments[param_name] = arg_val
767
768 if kwargs:
769 if kwargs_param is not None:
770 # Process our '**kwargs'-like parameter
771 arguments[kwargs_param.name] = kwargs
772 else:
773 raise TypeError('too many keyword arguments')
774
775 return self._bound_arguments_cls(self, arguments)
776
777 def bind(self, *args, **kwargs):
778 '''Get a BoundArguments object, that maps the passed `args`
779 and `kwargs` to the function's signature. Raises `TypeError`
780 if the passed arguments can not be bound.
781 '''
782 return self._bind(args, kwargs)
783
784 def bind_partial(self, *args, **kwargs):
785 '''Get a BoundArguments object, that partially maps the
786 passed `args` and `kwargs` to the function's signature.
787 Raises `TypeError` if the passed arguments can not be bound.
788 '''
789 return self._bind(args, kwargs, partial=True)
790
791 def __str__(self):
792 result = []
793 render_kw_only_separator = True
794 for idx, param in enumerate(self.parameters.values()):
795 formatted = str(param)
796
797 kind = param.kind
798 if kind == _VAR_POSITIONAL:
799 # OK, we have an '*args'-like parameter, so we won't need
800 # a '*' to separate keyword-only arguments
801 render_kw_only_separator = False
802 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
803 # We have a keyword-only parameter to render and we haven't
804 # rendered an '*args'-like parameter before, so add a '*'
805 # separator to the parameters list ("foo(arg1, *, arg2)" case)
806 result.append('*')
807 # This condition should be only triggered once, so
808 # reset the flag
809 render_kw_only_separator = False
810
811 result.append(formatted)
812
813 rendered = '({0})'.format(', '.join(result))
814
815 if self.return_annotation is not _empty:
816 anno = formatannotation(self.return_annotation)
817 rendered += ' -> {0}'.format(anno)
818
819 return rendered
1 NO CONTENT: new file 100644
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
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -14,12 +14,17 b''
14 display: box;
14 display: box;
15 box-orient: horizontal;
15 box-orient: horizontal;
16 box-align: stretch;
16 box-align: stretch;
17
18 display: flex;
19 flex-direction: row;
20 align-items: stretch;
17 }
21 }
18
22
19 .hbox > * {
23 .hbox > * {
20 -webkit-box-flex: 0;
24 -webkit-box-flex: 0;
21 -moz-box-flex: 0;
25 -moz-box-flex: 0;
22 box-flex: 0;
26 box-flex: 0;
27 flex: auto;
23 }
28 }
24
29
25 .vbox {
30 .vbox {
@@ -36,30 +41,38 b''
36 box-align: stretch;
41 box-align: stretch;
37 /* width must be 100% to force FF to behave like webkit */
42 /* width must be 100% to force FF to behave like webkit */
38 width: 100%;
43 width: 100%;
44
45 display: flex;
46 flex-direction: column;
47 align-items: stretch;
39 }
48 }
40
49
41 .vbox > * {
50 .vbox > * {
42 -webkit-box-flex: 0;
51 -webkit-box-flex: 0;
43 -moz-box-flex: 0;
52 -moz-box-flex: 0;
44 box-flex: 0;
53 box-flex: 0;
54 flex: auto;
45 }
55 }
46
56
47 .reverse {
57 .reverse {
48 -webkit-box-direction: reverse;
58 -webkit-box-direction: reverse;
49 -moz-box-direction: reverse;
59 -moz-box-direction: reverse;
50 box-direction: reverse;
60 box-direction: reverse;
61 flex-direction: column-reverse;
51 }
62 }
52
63
53 .box-flex0 {
64 .box-flex0 {
54 -webkit-box-flex: 0;
65 -webkit-box-flex: 0;
55 -moz-box-flex: 0;
66 -moz-box-flex: 0;
56 box-flex: 0;
67 box-flex: 0;
68 flex: auto;
57 }
69 }
58
70
59 .box-flex1 {
71 .box-flex1 {
60 -webkit-box-flex: 1;
72 -webkit-box-flex: 1;
61 -moz-box-flex: 1;
73 -moz-box-flex: 1;
62 box-flex: 1;
74 box-flex: 1;
75 flex: 1;
63 }
76 }
64
77
65 .box-flex {
78 .box-flex {
@@ -70,15 +83,24 b''
70 -webkit-box-flex: 2;
83 -webkit-box-flex: 2;
71 -moz-box-flex: 2;
84 -moz-box-flex: 2;
72 box-flex: 2;
85 box-flex: 2;
86 flex: 2;
73 }
87 }
74
88
75 .box-group1 {
89 .box-group1 {
90 /*
91 Deprecated
92 Grouping isn't supported in http://dev.w3.org/csswg/css-flexbox/
93 */
76 -webkit-box-flex-group: 1;
94 -webkit-box-flex-group: 1;
77 -moz-box-flex-group: 1;
95 -moz-box-flex-group: 1;
78 box-flex-group: 1;
96 box-flex-group: 1;
79 }
97 }
80
98
81 .box-group2 {
99 .box-group2 {
100 /*
101 Deprecated
102 Grouping isn't supported in http://dev.w3.org/csswg/css-flexbox/
103 */
82 -webkit-box-flex-group: 2;
104 -webkit-box-flex-group: 2;
83 -moz-box-flex-group: 2;
105 -moz-box-flex-group: 2;
84 box-flex-group: 2;
106 box-flex-group: 2;
@@ -88,34 +110,40 b''
88 -webkit-box-pack: start;
110 -webkit-box-pack: start;
89 -moz-box-pack: start;
111 -moz-box-pack: start;
90 box-pack: start;
112 box-pack: start;
113 justify-content: flex-start;
91 }
114 }
92
115
93 .end {
116 .end {
94 -webkit-box-pack: end;
117 -webkit-box-pack: end;
95 -moz-box-pack: end;
118 -moz-box-pack: end;
96 box-pack: end;
119 box-pack: end;
120 justify-content: flex-end;
97 }
121 }
98
122
99 .center {
123 .center {
100 -webkit-box-pack: center;
124 -webkit-box-pack: center;
101 -moz-box-pack: center;
125 -moz-box-pack: center;
102 box-pack: center;
126 box-pack: center;
127 justify-content: center;
103 }
128 }
104
129
105 .align-start {
130 .align-start {
106 -webkit-box-align: start;
131 -webkit-box-align: start;
107 -moz-box-align: start;
132 -moz-box-align: start;
108 box-align: start;
133 box-align: start;
134 align-content: flex-start;
109 }
135 }
110
136
111 .align-end {
137 .align-end {
112 -webkit-box-align: end;
138 -webkit-box-align: end;
113 -moz-box-align: end;
139 -moz-box-align: end;
114 box-align: end;
140 box-align: end;
141 align-content: flex-end;
115 }
142 }
116
143
117 .align-center {
144 .align-center {
118 -webkit-box-align: center;
145 -webkit-box-align: center;
119 -moz-box-align: center;
146 -moz-box-align: center;
120 box-align: center;
147 box-align: center;
148 align-content: center;
121 }
149 }
@@ -540,6 +540,7 b' var IPython = (function (IPython) {'
540 var ShortcutManager = function (delay) {
540 var ShortcutManager = function (delay) {
541 this._shortcuts = {}
541 this._shortcuts = {}
542 this._counts = {}
542 this._counts = {}
543 this._timers = {}
543 this.delay = delay || 800; // delay in milliseconds
544 this.delay = delay || 800; // delay in milliseconds
544 }
545 }
545
546
@@ -633,17 +634,21 b' var IPython = (function (IPython) {'
633 ShortcutManager.prototype.count_handler = function (shortcut, event, data) {
634 ShortcutManager.prototype.count_handler = function (shortcut, event, data) {
634 var that = this;
635 var that = this;
635 var c = this._counts;
636 var c = this._counts;
637 var t = this._timers;
638 var timer = null;
636 if (c[shortcut] === data.count-1) {
639 if (c[shortcut] === data.count-1) {
637 c[shortcut] = 0;
640 c[shortcut] = 0;
641 var timer = t[shortcut];
642 if (timer) {clearTimeout(timer); delete t[shortcut];}
638 return data.handler(event);
643 return data.handler(event);
639 } else {
644 } else {
640 c[shortcut] = c[shortcut] + 1;
645 c[shortcut] = c[shortcut] + 1;
641 setTimeout(function () {
646 timer = setTimeout(function () {
642 c[shortcut] = 0;
647 c[shortcut] = 0;
643 }, that.delay);
648 }, that.delay);
649 t[shortcut] = timer;
644 }
650 }
645 return false;
651 return false;
646
647 }
652 }
648
653
649 ShortcutManager.prototype.call_handler = function (event) {
654 ShortcutManager.prototype.call_handler = function (event) {
@@ -36,9 +36,6 b' div.prompt {'
36 div.inner_cell {
36 div.inner_cell {
37 .vbox();
37 .vbox();
38 .box-flex1();
38 .box-flex1();
39
40 /* This is required for FF to add scrollbars when code cells overflow. */
41 overflow: auto;
42 }
39 }
43
40
44 /* This is needed so that empty prompt areas can collapse to zero height when there
41 /* This is needed so that empty prompt areas can collapse to zero height when there
@@ -22,12 +22,12 b''
22 overflow-x: auto;
22 overflow-x: auto;
23 }
23 }
24
24
25 @-moz-document url-prefix() {
25 @-moz-document {
26 /* Firefox does weird and terrible things (#3549) when overflow-x is auto */
26 /* Firefox does weird and terrible things (#3549) when overflow-x is auto */
27 /* It doesn't respect the overflow setting anyway, so we can workaround it with this */
27 /* It doesn't respect the overflow setting anyway, so we can workaround it with this */
28 .CodeMirror-scroll {
28 .CodeMirror-scroll {
29 overflow-x: hidden;
29 overflow-x: hidden;
30 }
30 }
31 }
31 }
32
32
33 .CodeMirror-lines {
33 .CodeMirror-lines {
@@ -4,23 +4,23 b''
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}
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 .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
5 .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
6 .corner-all{border-radius:4px}
6 .corner-all{border-radius:4px}
7 .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
7 .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
8 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
8 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
9 .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%}
9 .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;display:flex;flex-direction:column;align-items:stretch}
10 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
10 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
11 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse}
11 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:column-reverse}
12 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
12 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
13 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
13 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
14 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
14 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
15 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2}
15 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2}
16 .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1}
16 .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1}
17 .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2}
17 .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2}
18 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start}
18 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start}
19 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end}
19 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end}
20 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center}
20 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center}
21 .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start}
21 .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-content:flex-start}
22 .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end}
22 .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-content:flex-end}
23 .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center}
23 .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-content:center}
24 div.error{margin:2em;text-align:center}
24 div.error{margin:2em;text-align:center}
25 div.error>h1{font-size:500%;line-height:normal}
25 div.error>h1{font-size:500%;line-height:normal}
26 div.error>p{font-size:200%;line-height:normal}
26 div.error>p{font-size:200%;line-height:normal}
@@ -68,18 +68,18 b' input.engine_num_input{width:60px}'
68 .ansibgpurple{background-color:#f0f}
68 .ansibgpurple{background-color:#f0f}
69 .ansibgcyan{background-color:#0ff}
69 .ansibgcyan{background-color:#0ff}
70 .ansibggray{background-color:#808080}
70 .ansibggray{background-color:#808080}
71 div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%}div.cell.selected{border-radius:4px;border:thin #ababab solid}
71 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}
72 div.cell.edit_mode{border-radius:4px;border:thin #008000 solid}
72 div.cell.edit_mode{border-radius:4px;border:thin #008000 solid}
73 div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none}
73 div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none}
74 div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.231em}
74 div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.231em}
75 div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;overflow:auto}
75 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 div.prompt:empty{padding-top:0;padding-bottom:0}
76 div.prompt:empty{padding-top:0;padding-bottom:0}
77 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}
77 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}
78 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
78 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
79 div.input_prompt{color:#000080;border-top:1px solid transparent}
79 div.input_prompt{color:#000080;border-top:1px solid transparent}
80 .CodeMirror{line-height:1.231em;height:auto;background:none;}
80 .CodeMirror{line-height:1.231em;height:auto;background:none;}
81 .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto}
81 .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto}
82 @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em}
82 @-moz-document {.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em}
83 .CodeMirror-linenumber{padding:0 8px 0 4px}
83 .CodeMirror-linenumber{padding:0 8px 0 4px}
84 .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px}
84 .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px}
85 .CodeMirror pre{padding:0;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
85 .CodeMirror pre{padding:0;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
@@ -104,18 +104,18 b' pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .j'
104 .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold}
104 .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold}
105 .cm-s-ipython span.cm-meta{color:#a2f}
105 .cm-s-ipython span.cm-meta{color:#a2f}
106 .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat}
106 .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat}
107 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%}
107 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}
108 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)}
108 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)}
109 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%}
109 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}
110 div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px}
110 div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px}
111 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)}
111 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)}
112 div.output_prompt{color:#8b0000}
112 div.output_prompt{color:#8b0000}
113 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}div.output_area .MathJax_Display{text-align:left !important}
113 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}
114 div.output_area .rendered_html table{margin-left:0;margin-right:0}
114 div.output_area .rendered_html table{margin-left:0;margin-right:0}
115 div.output_area .rendered_html img{margin-left:0;margin-right:0}
115 div.output_area .rendered_html img{margin-left:0;margin-right:0}
116 .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%}
116 .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}
117 div.output_area pre{font-family:monospace;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}
117 div.output_area pre{font-family:monospace;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}
118 div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
118 div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
119 div.output_text{text-align:left;color:#000;font-family:monospace;line-height:1.231em}
119 div.output_text{text-align:left;color:#000;font-family:monospace;line-height:1.231em}
120 div.output_stderr{background:#fdd;}
120 div.output_stderr{background:#fdd;}
121 div.output_latex{text-align:left}
121 div.output_latex{text-align:left}
@@ -165,30 +165,30 b' p.p-space{margin-bottom:10px}'
165 .rendered_html *+p{margin-top:1em}
165 .rendered_html *+p{margin-top:1em}
166 .rendered_html img{display:block;margin-left:auto;margin-right:auto}
166 .rendered_html img{display:block;margin-left:auto;margin-right:auto}
167 .rendered_html *+img{margin-top:1em}
167 .rendered_html *+img{margin-top:1em}
168 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}
168 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}
169 div.text_cell_input{color:#000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
169 div.text_cell_input{color:#000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
170 div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000}
170 div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000}
171 a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden}
171 a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden}
172 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}
172 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}
173 div.cell.text_cell.rendered{padding:0}
173 div.cell.text_cell.rendered{padding:0}
174 .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}.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%;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2}
174 .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}
175 .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top}
175 .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top}
176 .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom}
176 .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom}
177 .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top}
177 .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top}
178 .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top}
178 .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top}
179 .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;}
179 .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;}
180 .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;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}.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;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important}
180 .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;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}
181 .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%}.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%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px}
181 .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}
182 .widget-text{width:350px;margin-bottom:0}
182 .widget-text{width:350px;margin-bottom:0}
183 .widget-listbox{width:364px;margin-bottom:0}
183 .widget-listbox{width:364px;margin-bottom:0}
184 .widget-numeric-text{width:150px}
184 .widget-numeric-text{width:150px}
185 .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}
185 .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}
186 .widget-combo-btn{min-width:138px;}
186 .widget-combo-btn{min-width:138px;}
187 .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
187 .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}
188 .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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}
188 .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;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}
189 .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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;height:30px}
189 .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;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}
190 .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;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%}
190 .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;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}
191 .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;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%;width:30px}
191 .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;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}
192 .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important}
192 .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important}
193 .widget-modal-body{max-height:none !important}
193 .widget-modal-body{max-height:none !important}
194 .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
194 .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
@@ -1,7 +1,3 b''
1 .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}
2 .clearfix:after{clear:both}
3 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}
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 article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}
1 article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}
6 audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
2 audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
7 audio:not([controls]){display:none}
3 audio:not([controls]){display:none}
@@ -856,6 +852,10 b' a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decorati'
856 .show{display:block}
852 .show{display:block}
857 .invisible{visibility:hidden}
853 .invisible{visibility:hidden}
858 .affix{position:fixed}
854 .affix{position:fixed}
855 .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}
856 .clearfix:after{clear:both}
857 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}
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 @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}
859 @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}
860 .visible-phone{display:none !important}
860 .visible-phone{display:none !important}
861 .visible-tablet{display:none !important}
861 .visible-tablet{display:none !important}
@@ -1267,23 +1267,23 b' a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .'
1267 .icon-renren:before{content:"\f18b"}
1267 .icon-renren:before{content:"\f18b"}
1268 .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1268 .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1269 .corner-all{border-radius:4px}
1269 .corner-all{border-radius:4px}
1270 .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}
1270 .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}
1271 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
1271 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
1272 .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%}
1272 .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}
1273 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
1273 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
1274 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse}
1274 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:column-reverse}
1275 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
1275 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
1276 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
1276 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
1277 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
1277 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
1278 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2}
1278 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2}
1279 .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1}
1279 .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1}
1280 .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2}
1280 .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2}
1281 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start}
1281 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start}
1282 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end}
1282 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end}
1283 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center}
1283 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center}
1284 .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start}
1284 .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-content:flex-start}
1285 .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end}
1285 .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-content:flex-end}
1286 .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center}
1286 .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-content:center}
1287 div.error{margin:2em;text-align:center}
1287 div.error{margin:2em;text-align:center}
1288 div.error>h1{font-size:500%;line-height:normal}
1288 div.error>h1{font-size:500%;line-height:normal}
1289 div.error>p{font-size:200%;line-height:normal}
1289 div.error>p{font-size:200%;line-height:normal}
@@ -1345,18 +1345,18 b' input.engine_num_input{width:60px}'
1345 .ansibgpurple{background-color:#f0f}
1345 .ansibgpurple{background-color:#f0f}
1346 .ansibgcyan{background-color:#0ff}
1346 .ansibgcyan{background-color:#0ff}
1347 .ansibggray{background-color:#808080}
1347 .ansibggray{background-color:#808080}
1348 div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%}div.cell.selected{border-radius:4px;border:thin #ababab solid}
1348 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}
1349 div.cell.edit_mode{border-radius:4px;border:thin #008000 solid}
1349 div.cell.edit_mode{border-radius:4px;border:thin #008000 solid}
1350 div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none}
1350 div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none}
1351 div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.231em}
1351 div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.231em}
1352 div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;overflow:auto}
1352 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 div.prompt:empty{padding-top:0;padding-bottom:0}
1353 div.prompt:empty{padding-top:0;padding-bottom:0}
1354 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}
1354 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}
1355 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
1355 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
1356 div.input_prompt{color:#000080;border-top:1px solid transparent}
1356 div.input_prompt{color:#000080;border-top:1px solid transparent}
1357 .CodeMirror{line-height:1.231em;height:auto;background:none;}
1357 .CodeMirror{line-height:1.231em;height:auto;background:none;}
1358 .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto}
1358 .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto}
1359 @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em}
1359 @-moz-document {.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em}
1360 .CodeMirror-linenumber{padding:0 8px 0 4px}
1360 .CodeMirror-linenumber{padding:0 8px 0 4px}
1361 .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px}
1361 .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px}
1362 .CodeMirror pre{padding:0;border:0;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
1362 .CodeMirror pre{padding:0;border:0;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
@@ -1381,18 +1381,18 b' pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .j'
1381 .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold}
1381 .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold}
1382 .cm-s-ipython span.cm-meta{color:#a2f}
1382 .cm-s-ipython span.cm-meta{color:#a2f}
1383 .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat}
1383 .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat}
1384 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%}
1384 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}
1385 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)}
1385 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)}
1386 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%}
1386 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}
1387 div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px}
1387 div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px}
1388 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)}
1388 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)}
1389 div.output_prompt{color:#8b0000}
1389 div.output_prompt{color:#8b0000}
1390 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}div.output_area .MathJax_Display{text-align:left !important}
1390 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}
1391 div.output_area .rendered_html table{margin-left:0;margin-right:0}
1391 div.output_area .rendered_html table{margin-left:0;margin-right:0}
1392 div.output_area .rendered_html img{margin-left:0;margin-right:0}
1392 div.output_area .rendered_html img{margin-left:0;margin-right:0}
1393 .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%}
1393 .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}
1394 div.output_area pre{font-family:monospace;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}
1394 div.output_area pre{font-family:monospace;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}
1395 div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
1395 div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
1396 div.output_text{text-align:left;color:#000;font-family:monospace;line-height:1.231em}
1396 div.output_text{text-align:left;color:#000;font-family:monospace;line-height:1.231em}
1397 div.output_stderr{background:#fdd;}
1397 div.output_stderr{background:#fdd;}
1398 div.output_latex{text-align:left}
1398 div.output_latex{text-align:left}
@@ -1442,30 +1442,30 b' p.p-space{margin-bottom:10px}'
1442 .rendered_html *+p{margin-top:1em}
1442 .rendered_html *+p{margin-top:1em}
1443 .rendered_html img{display:block;margin-left:auto;margin-right:auto}
1443 .rendered_html img{display:block;margin-left:auto;margin-right:auto}
1444 .rendered_html *+img{margin-top:1em}
1444 .rendered_html *+img{margin-top:1em}
1445 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}
1445 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}
1446 div.text_cell_input{color:#000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
1446 div.text_cell_input{color:#000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
1447 div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000}
1447 div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000}
1448 a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden}
1448 a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden}
1449 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}
1449 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}
1450 div.cell.text_cell.rendered{padding:0}
1450 div.cell.text_cell.rendered{padding:0}
1451 .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}.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%;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2}
1451 .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}
1452 .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top}
1452 .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top}
1453 .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom}
1453 .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom}
1454 .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top}
1454 .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top}
1455 .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top}
1455 .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top}
1456 .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;}
1456 .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;}
1457 .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;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}.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;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important}
1457 .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;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}
1458 .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%}.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%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px}
1458 .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}
1459 .widget-text{width:350px;margin-bottom:0}
1459 .widget-text{width:350px;margin-bottom:0}
1460 .widget-listbox{width:364px;margin-bottom:0}
1460 .widget-listbox{width:364px;margin-bottom:0}
1461 .widget-numeric-text{width:150px}
1461 .widget-numeric-text{width:150px}
1462 .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}
1462 .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}
1463 .widget-combo-btn{min-width:138px;}
1463 .widget-combo-btn{min-width:138px;}
1464 .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1464 .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}
1465 .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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}
1465 .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;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}
1466 .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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;height:30px}
1466 .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;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}
1467 .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;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%}
1467 .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;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}
1468 .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;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%;width:30px}
1468 .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;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}
1469 .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important}
1469 .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important}
1470 .widget-modal-body{max-height:none !important}
1470 .widget-modal-body{max-height:none !important}
1471 .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1471 .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
@@ -1482,7 +1482,7 b' pre,code,kbd,samp{white-space:pre-wrap}'
1482 #fonttest{font-family:monospace}
1482 #fonttest{font-family:monospace}
1483 p{margin-bottom:0}
1483 p{margin-bottom:0}
1484 .end_space{height:200px}
1484 .end_space{height:200px}
1485 .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;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse}
1485 .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:column-reverse}
1486 .ctb_hideshow{display:none;vertical-align:bottom;padding-right:2px}
1486 .ctb_hideshow{display:none;vertical-align:bottom;padding-right:2px}
1487 .celltoolbar>div{padding-top:0}
1487 .celltoolbar>div{padding-top:0}
1488 .ctb_global_show .ctb_show.ctb_hideshow{display:block}
1488 .ctb_global_show .ctb_show.ctb_hideshow{display:block}
@@ -9,3 +9,4 b' from .widget_int import IntTextWidget, BoundedIntTextWidget, IntSliderWidget, In'
9 from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget
9 from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget
10 from .widget_selectioncontainer import TabWidget, AccordionWidget
10 from .widget_selectioncontainer import TabWidget, AccordionWidget
11 from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget
11 from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget
12 from .interaction import interact, interactive, fixed
@@ -53,7 +53,7 b' class FloatSliderWidget(_BoundedFloatWidget):'
53 _view_name = Unicode('FloatSliderView', sync=True)
53 _view_name = Unicode('FloatSliderView', sync=True)
54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
55 help="Vertical or horizontal.", sync=True)
55 help="Vertical or horizontal.", sync=True)
56 readout = Bool(False, help="Display the current value of the slider next to it.", sync=True)
56 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
57
57
58
58
59 class FloatProgressWidget(_BoundedFloatWidget):
59 class FloatProgressWidget(_BoundedFloatWidget):
@@ -53,7 +53,7 b' class IntSliderWidget(_BoundedIntWidget):'
53 _view_name = Unicode('IntSliderView', sync=True)
53 _view_name = Unicode('IntSliderView', sync=True)
54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
55 help="Vertical or horizontal.", sync=True)
55 help="Vertical or horizontal.", sync=True)
56 readout = Bool(False, help="Display the current value of the slider next to it.", sync=True)
56 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
57
57
58
58
59 class IntProgressWidget(_BoundedIntWidget):
59 class IntProgressWidget(_BoundedIntWidget):
@@ -86,6 +86,7 b' class InProcessShellChannel(InProcessChannel):'
86 'object_info',
86 'object_info',
87 'history',
87 'history',
88 'shutdown',
88 'shutdown',
89 'kernel_info',
89 ]
90 ]
90
91
91 #--------------------------------------------------------------------------
92 #--------------------------------------------------------------------------
@@ -127,6 +128,12 b' class InProcessShellChannel(InProcessChannel):'
127 # FIXME: What to do here?
128 # FIXME: What to do here?
128 raise NotImplementedError('Cannot shutdown in-process kernel')
129 raise NotImplementedError('Cannot shutdown in-process kernel')
129
130
131 def kernel_info(self):
132 """Request kernel info."""
133 msg = self.client.session.msg('kernel_info_request')
134 self._dispatch_to_kernel(msg)
135 return msg['header']['msg_id']
136
130 #--------------------------------------------------------------------------
137 #--------------------------------------------------------------------------
131 # Protected interface
138 # Protected interface
132 #--------------------------------------------------------------------------
139 #--------------------------------------------------------------------------
@@ -223,6 +223,21 b' else:'
223 filename = fname
223 filename = fname
224 builtin_mod.execfile(filename, *where)
224 builtin_mod.execfile(filename, *where)
225
225
226
227 def annotate(**kwargs):
228 """Python 3 compatible function annotation for Python 2."""
229 if not kwargs:
230 raise ValueError('annotations must be provided as keyword arguments')
231 def dec(f):
232 if hasattr(f, '__annotations__'):
233 for k, v in kwargs.items():
234 f.__annotations__[k] = v
235 else:
236 f.__annotations__ = kwargs
237 return f
238 return dec
239
240
226 # Parts below taken from six:
241 # Parts below taken from six:
227 # Copyright (c) 2010-2013 Benjamin Peterson
242 # Copyright (c) 2010-2013 Benjamin Peterson
228 #
243 #
@@ -32,7 +32,7 b' from IPython.utils.traitlets import ('
32 HasTraits, MetaHasTraits, TraitType, Any, CBytes, Dict,
32 HasTraits, MetaHasTraits, TraitType, Any, CBytes, Dict,
33 Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError,
33 Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError,
34 Undefined, Type, This, Instance, TCPAddress, List, Tuple,
34 Undefined, Type, This, Instance, TCPAddress, List, Tuple,
35 ObjectName, DottedObjectName, CRegExp, bind
35 ObjectName, DottedObjectName, CRegExp, link
36 )
36 )
37 from IPython.utils import py3compat
37 from IPython.utils import py3compat
38 from IPython.testing.decorators import skipif
38 from IPython.testing.decorators import skipif
@@ -974,9 +974,9 b' def test_dict_assignment():'
974 nt.assert_equal(d, c.value)
974 nt.assert_equal(d, c.value)
975 nt.assert_true(c.value is d)
975 nt.assert_true(c.value is d)
976
976
977 class TestBind(TestCase):
977 class TestLink(TestCase):
978 def test_connect_same(self):
978 def test_connect_same(self):
979 """Verify two traitlets of the same type can be bound together using bind."""
979 """Verify two traitlets of the same type can be linked together using link."""
980
980
981 # Create two simple classes with Int traitlets.
981 # Create two simple classes with Int traitlets.
982 class A(HasTraits):
982 class A(HasTraits):
@@ -985,9 +985,9 b' class TestBind(TestCase):'
985 b = A(value=8)
985 b = A(value=8)
986
986
987 # Conenct the two classes.
987 # Conenct the two classes.
988 c = bind((a, 'value'), (b, 'value'))
988 c = link((a, 'value'), (b, 'value'))
989
989
990 # Make sure the values are the same at the point of binding.
990 # Make sure the values are the same at the point of linking.
991 self.assertEqual(a.value, b.value)
991 self.assertEqual(a.value, b.value)
992
992
993 # Change one of the values to make sure they stay in sync.
993 # Change one of the values to make sure they stay in sync.
@@ -996,8 +996,8 b' class TestBind(TestCase):'
996 b.value = 6
996 b.value = 6
997 self.assertEqual(a.value, b.value)
997 self.assertEqual(a.value, b.value)
998
998
999 def test_bind_different(self):
999 def test_link_different(self):
1000 """Verify two traitlets of different types can be bound together using bind."""
1000 """Verify two traitlets of different types can be linked together using link."""
1001
1001
1002 # Create two simple classes with Int traitlets.
1002 # Create two simple classes with Int traitlets.
1003 class A(HasTraits):
1003 class A(HasTraits):
@@ -1008,9 +1008,9 b' class TestBind(TestCase):'
1008 b = B(count=8)
1008 b = B(count=8)
1009
1009
1010 # Conenct the two classes.
1010 # Conenct the two classes.
1011 c = bind((a, 'value'), (b, 'count'))
1011 c = link((a, 'value'), (b, 'count'))
1012
1012
1013 # Make sure the values are the same at the point of binding.
1013 # Make sure the values are the same at the point of linking.
1014 self.assertEqual(a.value, b.count)
1014 self.assertEqual(a.value, b.count)
1015
1015
1016 # Change one of the values to make sure they stay in sync.
1016 # Change one of the values to make sure they stay in sync.
@@ -1019,8 +1019,8 b' class TestBind(TestCase):'
1019 b.count = 4
1019 b.count = 4
1020 self.assertEqual(a.value, b.count)
1020 self.assertEqual(a.value, b.count)
1021
1021
1022 def test_unbind(self):
1022 def test_unlink(self):
1023 """Verify two binded traitlets can be unbinded."""
1023 """Verify two linked traitlets can be unlinked."""
1024
1024
1025 # Create two simple classes with Int traitlets.
1025 # Create two simple classes with Int traitlets.
1026 class A(HasTraits):
1026 class A(HasTraits):
@@ -1028,17 +1028,17 b' class TestBind(TestCase):'
1028 a = A(value=9)
1028 a = A(value=9)
1029 b = A(value=8)
1029 b = A(value=8)
1030
1030
1031 # Conenct the two classes.
1031 # Connect the two classes.
1032 c = bind((a, 'value'), (b, 'value'))
1032 c = link((a, 'value'), (b, 'value'))
1033 a.value = 4
1033 a.value = 4
1034 c.unbind()
1034 c.unlink()
1035
1035
1036 # Change one of the values to make sure they stay in sync.
1036 # Change one of the values to make sure they don't stay in sync.
1037 a.value = 5
1037 a.value = 5
1038 self.assertNotEqual(a.value, b.value)
1038 self.assertNotEqual(a.value, b.value)
1039
1039
1040 def test_callbacks(self):
1040 def test_callbacks(self):
1041 """Verify two binded traitlets have their callbacks called once."""
1041 """Verify two linked traitlets have their callbacks called once."""
1042
1042
1043 # Create two simple classes with Int traitlets.
1043 # Create two simple classes with Int traitlets.
1044 class A(HasTraits):
1044 class A(HasTraits):
@@ -1057,8 +1057,8 b' class TestBind(TestCase):'
1057 callback_count.append('b')
1057 callback_count.append('b')
1058 b.on_trait_change(b_callback, 'count')
1058 b.on_trait_change(b_callback, 'count')
1059
1059
1060 # Conenct the two classes.
1060 # Connect the two classes.
1061 c = bind((a, 'value'), (b, 'count'))
1061 c = link((a, 'value'), (b, 'count'))
1062
1062
1063 # Make sure b's count was set to a's value once.
1063 # Make sure b's count was set to a's value once.
1064 self.assertEqual(''.join(callback_count), 'b')
1064 self.assertEqual(''.join(callback_count), 'b')
@@ -184,8 +184,8 b' def getmembers(object, predicate=None):'
184 return results
184 return results
185
185
186 @skip_doctest
186 @skip_doctest
187 class bind(object):
187 class link(object):
188 """Bind traits from different objects together so they remain in sync.
188 """Link traits from different objects together so they remain in sync.
189
189
190 Parameters
190 Parameters
191 ----------
191 ----------
@@ -194,7 +194,7 b' class bind(object):'
194 Examples
194 Examples
195 --------
195 --------
196
196
197 >>> c = bind((obj1, 'value'), (obj2, 'value'), (obj3, 'value'))
197 >>> c = link((obj1, 'value'), (obj2, 'value'), (obj3, 'value'))
198 >>> obj1.value = 5 # updates other objects as well
198 >>> obj1.value = 5 # updates other objects as well
199 """
199 """
200 updating = False
200 updating = False
@@ -233,7 +233,7 b' class bind(object):'
233 if obj is not sending_obj or attr != sending_attr:
233 if obj is not sending_obj or attr != sending_attr:
234 setattr(obj, attr, new)
234 setattr(obj, attr, new)
235
235
236 def unbind(self):
236 def unlink(self):
237 for key, callback in self.objects.items():
237 for key, callback in self.objects.items():
238 (obj,attr) = key
238 (obj,attr) = key
239 obj.on_trait_change(callback, attr, remove=True)
239 obj.on_trait_change(callback, attr, remove=True)
@@ -14,35 +14,29 b' Authors'
14 * MinRK
14 * MinRK
15 """
15 """
16
16
17 import os
18 import sys
17 import sys
19 import json
18 import json
20 import zmq
19 import zmq
21
20
22 from IPython.kernel.zmq.session import Session
21 from IPython.kernel.zmq.session import Session
23 from IPython.parallel.util import disambiguate_url
24 from IPython.utils.py3compat import str_to_bytes
22 from IPython.utils.py3compat import str_to_bytes
25 from IPython.utils.path import get_security_file
23 from IPython.utils.path import get_security_file
26
24
27 def main(connection_file):
25 def main(connection_file):
28 """watch iopub channel, and print messages"""
26 """watch iopub channel, and print messages"""
29
27
30 ctx = zmq.Context.instance()
28 ctx = zmq.Context.instance()
31
29
32 with open(connection_file) as f:
30 with open(connection_file) as f:
33 cfg = json.loads(f.read())
31 cfg = json.loads(f.read())
34
32
35 location = cfg['location']
33 reg_url = cfg['interface']
36 reg_url = cfg['url']
34 iopub_port = cfg['iopub']
37 session = Session(key=str_to_bytes(cfg['exec_key']))
35 iopub_url = "%s:%s"%(reg_url, iopub_port)
38
36
39 query = ctx.socket(zmq.DEALER)
37 session = Session(key=str_to_bytes(cfg['key']))
40 query.connect(disambiguate_url(cfg['url'], location))
41 session.send(query, "connection_request")
42 idents,msg = session.recv(query, mode=0)
43 c = msg['content']
44 iopub_url = disambiguate_url(c['iopub'], location)
45 sub = ctx.socket(zmq.SUB)
38 sub = ctx.socket(zmq.SUB)
39
46 # This will subscribe to all messages:
40 # This will subscribe to all messages:
47 sub.setsockopt(zmq.SUBSCRIBE, b'')
41 sub.setsockopt(zmq.SUBSCRIBE, b'')
48 # replace with b'' with b'engine.1.stdout' to subscribe only to engine 1's stdout
42 # replace with b'' with b'engine.1.stdout' to subscribe only to engine 1's stdout
1 NO CONTENT: modified file
NO CONTENT: modified file
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