mininterface 0.5.0__tar.gz → 0.6.0rc2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mininterface-0.6.0rc2/PKG-INFO +303 -0
- mininterface-0.6.0rc2/README.md +279 -0
- mininterface-0.6.0rc2/mininterface/__init__.py +187 -0
- {mininterface-0.5.0 → mininterface-0.6.0rc2}/mininterface/__main__.py +8 -4
- {mininterface-0.5.0 → mininterface-0.6.0rc2}/mininterface/auxiliary.py +7 -15
- mininterface-0.6.0rc2/mininterface/cli_parser.py +200 -0
- mininterface-0.6.0rc2/mininterface/common.py +8 -0
- mininterface-0.6.0rc2/mininterface/experimental.py +54 -0
- mininterface-0.6.0rc2/mininterface/facet.py +56 -0
- mininterface-0.6.0rc2/mininterface/form_dict.py +144 -0
- mininterface-0.6.0rc2/mininterface/gui_interface/__init__.py +58 -0
- mininterface-0.6.0rc2/mininterface/gui_interface/tk_facet.py +20 -0
- mininterface-0.6.0rc2/mininterface/gui_interface/tk_window.py +139 -0
- mininterface-0.6.0rc2/mininterface/gui_interface/utils.py +161 -0
- mininterface-0.6.0rc2/mininterface/mininterface.py +253 -0
- mininterface-0.5.0/mininterface/Redirectable.py → mininterface-0.6.0rc2/mininterface/redirectable.py +6 -2
- mininterface-0.6.0rc2/mininterface/tag.py +601 -0
- mininterface-0.5.0/mininterface/TextInterface.py → mininterface-0.6.0rc2/mininterface/text_interface.py +9 -7
- mininterface-0.6.0rc2/mininterface/textual_interface/__init__.py +59 -0
- mininterface-0.6.0rc2/mininterface/textual_interface/textual_app.py +144 -0
- mininterface-0.6.0rc2/mininterface/textual_interface/textual_button_app.py +96 -0
- mininterface-0.6.0rc2/mininterface/textual_interface/textual_facet.py +18 -0
- mininterface-0.6.0rc2/mininterface/textual_interface/widgets.py +71 -0
- mininterface-0.6.0rc2/mininterface/types.py +71 -0
- mininterface-0.6.0rc2/mininterface/validators.py +143 -0
- {mininterface-0.5.0 → mininterface-0.6.0rc2}/pyproject.toml +6 -2
- mininterface-0.5.0/PKG-INFO +0 -254
- mininterface-0.5.0/README.md +0 -230
- mininterface-0.5.0/mininterface/FormDict.py +0 -128
- mininterface-0.5.0/mininterface/FormField.py +0 -163
- mininterface-0.5.0/mininterface/GuiInterface.py +0 -172
- mininterface-0.5.0/mininterface/Mininterface.py +0 -144
- mininterface-0.5.0/mininterface/TextualInterface.py +0 -234
- mininterface-0.5.0/mininterface/__init__.py +0 -95
- mininterface-0.5.0/mininterface/common.py +0 -2
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: mininterface
|
|
3
|
+
Version: 0.6.0rc2
|
|
4
|
+
Summary: A minimal access to GUI, TUI, CLI and config
|
|
5
|
+
Home-page: https://github.com/CZ-NIC/mininterface
|
|
6
|
+
License: GPL-3.0-or-later
|
|
7
|
+
Author: Edvard Rejthar
|
|
8
|
+
Author-email: edvard.rejthar@nic.cz
|
|
9
|
+
Requires-Python: >=3.10,<4.0
|
|
10
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Dist: envelope
|
|
16
|
+
Requires-Dist: pyyaml
|
|
17
|
+
Requires-Dist: requests
|
|
18
|
+
Requires-Dist: textual
|
|
19
|
+
Requires-Dist: tkinter-tooltip
|
|
20
|
+
Requires-Dist: tkinter_form (==0.1.5.2)
|
|
21
|
+
Requires-Dist: tyro
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Mininterface – access to GUI, TUI, CLI and config files
|
|
25
|
+
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
26
|
+
[](https://github.com/CZ-NIC/mininterface/actions)
|
|
27
|
+
|
|
28
|
+
Write the program core, do not bother with the input/output.
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
Check out the code, which is surprisingly short, that displays such a window or its textual fallback.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from dataclasses import dataclass
|
|
37
|
+
from mininterface import run
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class Env:
|
|
41
|
+
"""Set of options."""
|
|
42
|
+
|
|
43
|
+
test: bool = False
|
|
44
|
+
""" My testing flag """
|
|
45
|
+
|
|
46
|
+
important_number: int = 4
|
|
47
|
+
""" This number is very important """
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
env = run(Env, prog="My application").env
|
|
51
|
+
# Attributes are suggested by the IDE
|
|
52
|
+
# along with the hint text 'This number is very important'.
|
|
53
|
+
print(env.important_number)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
# Contents
|
|
57
|
+
- [You got CLI](#you-got-cli)
|
|
58
|
+
- [You got config file management](#you-got-config-file-management)
|
|
59
|
+
- [You got dialogues](#you-got-dialogues)
|
|
60
|
+
- [Background](#background)
|
|
61
|
+
- [Installation](#installation)
|
|
62
|
+
- [Docs](#docs)
|
|
63
|
+
- [Examples](#examples)
|
|
64
|
+
|
|
65
|
+
## You got CLI
|
|
66
|
+
It was all the code you need. No lengthy blocks of code imposed by an external dependency. Besides the GUI/TUI, you receive powerful YAML-configurable CLI parsing.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
$ ./hello.py
|
|
70
|
+
usage: My application [-h] [--test | --no-test] [--important-number INT]
|
|
71
|
+
|
|
72
|
+
Set of options.
|
|
73
|
+
|
|
74
|
+
╭─ options ──────────────────────────────────────────────────────────╮
|
|
75
|
+
│ -h, --help show this help message and exit │
|
|
76
|
+
│ --test, --no-test My testing flag (default: False) │
|
|
77
|
+
│ --important-number INT This number is very important (default: 4) │
|
|
78
|
+
╰────────────────────────────────────────────────────────────────────╯
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## You got config file management
|
|
82
|
+
Loading config file is a piece of cake. Alongside `program.py`, put `program.yaml` and put there some of the arguments. They are seamlessly taken as defaults.
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
important_number: 555
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## You got dialogues
|
|
89
|
+
Check out several useful methods to handle user dialogues. Here we bound the interface to a `with` statement that redirects stdout directly to the window.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
with run(Env) as m:
|
|
93
|
+
print(f"Your important number is {m.env.important_number}")
|
|
94
|
+
boolean = m.is_yes("Is that alright?")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+

|
|
98
|
+

|
|
99
|
+
|
|
100
|
+
# Background
|
|
101
|
+
|
|
102
|
+
Wrapper between the [tyro](https://github.com/brentyi/tyro) `argparse` replacement and [tkinter_form](https://github.com/JohanEstebanCuervo/tkinter_form/) that converts dicts into a GUI.
|
|
103
|
+
|
|
104
|
+
Writing a small and useful program might be a task that takes fifteen minutes. Adding a CLI to specify the parameters is not so much overhead. But building a simple GUI around it? HOURS! Hours spent on researching GUI libraries, wondering why the Python desktop app ecosystem lags so far behind the web world. All you need is a few input fields validated through a clickable window... You do not deserve to add hundred of lines of the code just to define some editable fields. `Mininterface` is here to help.
|
|
105
|
+
|
|
106
|
+
The config variables needed by your program are kept in cozy dataclasses. Write less! The syntax of [tyro](https://github.com/brentyi/tyro) does not require any overhead (as its `argparse` alternatives do). You just annotate a class attribute, append a simple docstring and get a fully functional application:
|
|
107
|
+
* Call it as `program.py --help` to display full help.
|
|
108
|
+
* Use any flag in CLI: `program.py --test` causes `env.test` be set to `True`.
|
|
109
|
+
* The main benefit: Launch it without parameters as `program.py` to get a full working window with all the flags ready to be edited.
|
|
110
|
+
* Running on a remote machine? Automatic regression to the text interface.
|
|
111
|
+
|
|
112
|
+
# Installation
|
|
113
|
+
|
|
114
|
+
Install with a single command from [PyPi](https://pypi.org/project/mininterface/).
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pip install mininterface
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
# Docs
|
|
121
|
+
See the docs overview at [https://cz-nic.github.io/mininterface/](https://cz-nic.github.io/mininterface/Overview/).
|
|
122
|
+
|
|
123
|
+
# Examples
|
|
124
|
+
|
|
125
|
+
## A complex dataclass.
|
|
126
|
+
|
|
127
|
+
```python3
|
|
128
|
+
from typing import Annotated
|
|
129
|
+
from dataclasses import dataclass
|
|
130
|
+
from mininterface.validators import not_empty
|
|
131
|
+
from mininterface import run, Tag, Validation
|
|
132
|
+
|
|
133
|
+
@dataclass
|
|
134
|
+
class NestedEnv:
|
|
135
|
+
another_number: int = 7
|
|
136
|
+
""" This field is nested """
|
|
137
|
+
|
|
138
|
+
@dataclass
|
|
139
|
+
class Env:
|
|
140
|
+
nested_config: NestedEnv
|
|
141
|
+
|
|
142
|
+
mandatory_str: str
|
|
143
|
+
""" As there is not default value, you will be prompted automatically to fill up the field """
|
|
144
|
+
|
|
145
|
+
my_number: int | None = None
|
|
146
|
+
""" This is not just a dummy number, if left empty, it is None. """
|
|
147
|
+
|
|
148
|
+
my_string: str = "Hello"
|
|
149
|
+
""" A dummy string """
|
|
150
|
+
|
|
151
|
+
my_flag: bool = False
|
|
152
|
+
""" Checkbox test """
|
|
153
|
+
|
|
154
|
+
my_validated: Annotated[str, Validation(not_empty)] = "hello"
|
|
155
|
+
""" A validated field """
|
|
156
|
+
|
|
157
|
+
m = run(Env, title="My program")
|
|
158
|
+
# See some values
|
|
159
|
+
print(m.env.nested_config.another_number) # 7
|
|
160
|
+
print(m.env)
|
|
161
|
+
# Env(nested_config=NestedEnv(another_number=7), my_number=5, my_string='Hello', my_flag=False, my_validated='hello')
|
|
162
|
+
|
|
163
|
+
# Edit values in a dialog
|
|
164
|
+
m.form()
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Form with paths
|
|
168
|
+
|
|
169
|
+
We have a dict with some paths. Here is how it looks.
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from pathlib import Path
|
|
173
|
+
from mininterface import run, Tag
|
|
174
|
+
|
|
175
|
+
m = run(title="My program")
|
|
176
|
+
my_dictionary = {
|
|
177
|
+
"paths": Tag("", annotation=list[Path]),
|
|
178
|
+
"default_paths": Tag([Path("/tmp"), Path("/usr")], annotation=list[Path])
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
# Edit values in a dialog
|
|
182
|
+
m.form(my_dictionary)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+

|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Mininterface – access to GUI, TUI, CLI and config files
|
|
2
|
+
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
3
|
+
[](https://github.com/CZ-NIC/mininterface/actions)
|
|
4
|
+
|
|
5
|
+
Write the program core, do not bother with the input/output.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
Check out the code, which is surprisingly short, that displays such a window or its textual fallback.
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from mininterface import run
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class Env:
|
|
18
|
+
"""Set of options."""
|
|
19
|
+
|
|
20
|
+
test: bool = False
|
|
21
|
+
""" My testing flag """
|
|
22
|
+
|
|
23
|
+
important_number: int = 4
|
|
24
|
+
""" This number is very important """
|
|
25
|
+
|
|
26
|
+
if __name__ == "__main__":
|
|
27
|
+
env = run(Env, prog="My application").env
|
|
28
|
+
# Attributes are suggested by the IDE
|
|
29
|
+
# along with the hint text 'This number is very important'.
|
|
30
|
+
print(env.important_number)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
# Contents
|
|
34
|
+
- [You got CLI](#you-got-cli)
|
|
35
|
+
- [You got config file management](#you-got-config-file-management)
|
|
36
|
+
- [You got dialogues](#you-got-dialogues)
|
|
37
|
+
- [Background](#background)
|
|
38
|
+
- [Installation](#installation)
|
|
39
|
+
- [Docs](#docs)
|
|
40
|
+
- [Examples](#examples)
|
|
41
|
+
|
|
42
|
+
## You got CLI
|
|
43
|
+
It was all the code you need. No lengthy blocks of code imposed by an external dependency. Besides the GUI/TUI, you receive powerful YAML-configurable CLI parsing.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
$ ./hello.py
|
|
47
|
+
usage: My application [-h] [--test | --no-test] [--important-number INT]
|
|
48
|
+
|
|
49
|
+
Set of options.
|
|
50
|
+
|
|
51
|
+
╭─ options ──────────────────────────────────────────────────────────╮
|
|
52
|
+
│ -h, --help show this help message and exit │
|
|
53
|
+
│ --test, --no-test My testing flag (default: False) │
|
|
54
|
+
│ --important-number INT This number is very important (default: 4) │
|
|
55
|
+
╰────────────────────────────────────────────────────────────────────╯
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## You got config file management
|
|
59
|
+
Loading config file is a piece of cake. Alongside `program.py`, put `program.yaml` and put there some of the arguments. They are seamlessly taken as defaults.
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
important_number: 555
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## You got dialogues
|
|
66
|
+
Check out several useful methods to handle user dialogues. Here we bound the interface to a `with` statement that redirects stdout directly to the window.
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
with run(Env) as m:
|
|
70
|
+
print(f"Your important number is {m.env.important_number}")
|
|
71
|
+
boolean = m.is_yes("Is that alright?")
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+

|
|
76
|
+
|
|
77
|
+
# Background
|
|
78
|
+
|
|
79
|
+
Wrapper between the [tyro](https://github.com/brentyi/tyro) `argparse` replacement and [tkinter_form](https://github.com/JohanEstebanCuervo/tkinter_form/) that converts dicts into a GUI.
|
|
80
|
+
|
|
81
|
+
Writing a small and useful program might be a task that takes fifteen minutes. Adding a CLI to specify the parameters is not so much overhead. But building a simple GUI around it? HOURS! Hours spent on researching GUI libraries, wondering why the Python desktop app ecosystem lags so far behind the web world. All you need is a few input fields validated through a clickable window... You do not deserve to add hundred of lines of the code just to define some editable fields. `Mininterface` is here to help.
|
|
82
|
+
|
|
83
|
+
The config variables needed by your program are kept in cozy dataclasses. Write less! The syntax of [tyro](https://github.com/brentyi/tyro) does not require any overhead (as its `argparse` alternatives do). You just annotate a class attribute, append a simple docstring and get a fully functional application:
|
|
84
|
+
* Call it as `program.py --help` to display full help.
|
|
85
|
+
* Use any flag in CLI: `program.py --test` causes `env.test` be set to `True`.
|
|
86
|
+
* The main benefit: Launch it without parameters as `program.py` to get a full working window with all the flags ready to be edited.
|
|
87
|
+
* Running on a remote machine? Automatic regression to the text interface.
|
|
88
|
+
|
|
89
|
+
# Installation
|
|
90
|
+
|
|
91
|
+
Install with a single command from [PyPi](https://pypi.org/project/mininterface/).
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pip install mininterface
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
# Docs
|
|
98
|
+
See the docs overview at [https://cz-nic.github.io/mininterface/](https://cz-nic.github.io/mininterface/Overview/).
|
|
99
|
+
|
|
100
|
+
# Examples
|
|
101
|
+
|
|
102
|
+
## A complex dataclass.
|
|
103
|
+
|
|
104
|
+
```python3
|
|
105
|
+
from typing import Annotated
|
|
106
|
+
from dataclasses import dataclass
|
|
107
|
+
from mininterface.validators import not_empty
|
|
108
|
+
from mininterface import run, Tag, Validation
|
|
109
|
+
|
|
110
|
+
@dataclass
|
|
111
|
+
class NestedEnv:
|
|
112
|
+
another_number: int = 7
|
|
113
|
+
""" This field is nested """
|
|
114
|
+
|
|
115
|
+
@dataclass
|
|
116
|
+
class Env:
|
|
117
|
+
nested_config: NestedEnv
|
|
118
|
+
|
|
119
|
+
mandatory_str: str
|
|
120
|
+
""" As there is not default value, you will be prompted automatically to fill up the field """
|
|
121
|
+
|
|
122
|
+
my_number: int | None = None
|
|
123
|
+
""" This is not just a dummy number, if left empty, it is None. """
|
|
124
|
+
|
|
125
|
+
my_string: str = "Hello"
|
|
126
|
+
""" A dummy string """
|
|
127
|
+
|
|
128
|
+
my_flag: bool = False
|
|
129
|
+
""" Checkbox test """
|
|
130
|
+
|
|
131
|
+
my_validated: Annotated[str, Validation(not_empty)] = "hello"
|
|
132
|
+
""" A validated field """
|
|
133
|
+
|
|
134
|
+
m = run(Env, title="My program")
|
|
135
|
+
# See some values
|
|
136
|
+
print(m.env.nested_config.another_number) # 7
|
|
137
|
+
print(m.env)
|
|
138
|
+
# Env(nested_config=NestedEnv(another_number=7), my_number=5, my_string='Hello', my_flag=False, my_validated='hello')
|
|
139
|
+
|
|
140
|
+
# Edit values in a dialog
|
|
141
|
+
m.form()
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Form with paths
|
|
145
|
+
|
|
146
|
+
We have a dict with some paths. Here is how it looks.
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from pathlib import Path
|
|
150
|
+
from mininterface import run, Tag
|
|
151
|
+
|
|
152
|
+
m = run(title="My program")
|
|
153
|
+
my_dictionary = {
|
|
154
|
+
"paths": Tag("", annotation=list[Path]),
|
|
155
|
+
"default_paths": Tag([Path("/tmp"), Path("/usr")], annotation=list[Path])
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
# Edit values in a dialog
|
|
159
|
+
m.form(my_dictionary)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+

|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
|