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 |
|
|
131 | -webkit-box-align: start; | |
107 |
|
|
132 | -moz-box-align: start; | |
108 |
|
|
133 | box-align: start; | |
|
134 | align-content: flex-start; | |||
109 | } |
|
135 | } | |
110 |
|
136 | |||
111 | .align-end { |
|
137 | .align-end { | |
112 |
|
|
138 | -webkit-box-align: end; | |
113 |
|
|
139 | -moz-box-align: end; | |
114 |
|
|
140 | box-align: end; | |
|
141 | align-content: flex-end; | |||
115 | } |
|
142 | } | |
116 |
|
143 | |||
117 | .align-center { |
|
144 | .align-center { | |
118 |
|
|
145 | -webkit-box-align: center; | |
119 |
|
|
146 | -moz-box-align: center; | |
120 |
|
|
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 |
|
25 | @-moz-document { | |
26 |
|
|
26 | /* Firefox does weird and terrible things (#3549) when overflow-x is auto */ | |
27 |
|
|
27 | /* It doesn't respect the overflow setting anyway, so we can workaround it with this */ | |
28 |
|
|
28 | .CodeMirror-scroll { | |
29 |
|
|
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; |
|
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 |
|
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; |
|
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 |
|
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( |
|
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( |
|
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, |
|
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 Test |
|
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 |
|
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 = |
|
988 | c = link((a, 'value'), (b, 'value')) | |
989 |
|
989 | |||
990 |
# Make sure the values are the same at the point of |
|
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_ |
|
999 | def test_link_different(self): | |
1000 |
"""Verify two traitlets of different types can be |
|
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 = |
|
1011 | c = link((a, 'value'), (b, 'count')) | |
1012 |
|
1012 | |||
1013 |
# Make sure the values are the same at the point of |
|
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_un |
|
1022 | def test_unlink(self): | |
1023 |
"""Verify two |
|
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 |
# Con |
|
1031 | # Connect the two classes. | |
1032 |
c = |
|
1032 | c = link((a, 'value'), (b, 'value')) | |
1033 | a.value = 4 |
|
1033 | a.value = 4 | |
1034 |
c.un |
|
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 |
|
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 |
# Con |
|
1060 | # Connect the two classes. | |
1061 |
c = |
|
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 |
|
187 | class link(object): | |
188 |
""" |
|
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 = |
|
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 un |
|
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 |
|
|
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