raptors 0.0.1__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.
- raptors-0.0.1/PKG-INFO +46 -0
- raptors-0.0.1/README.md +28 -0
- raptors-0.0.1/pyproject.toml +33 -0
- raptors-0.0.1/python/raptors/__init__.py +22 -0
- raptors-0.0.1/rust/Cargo.lock +245 -0
- raptors-0.0.1/rust/Cargo.toml +24 -0
- raptors-0.0.1/rust/src/lib.rs +20 -0
raptors-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: raptors
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
5
|
+
Classifier: Intended Audience :: Science/Research
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Rust
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering
|
|
10
|
+
Summary: Rust-powered, NumPy-compatible array library scaffold.
|
|
11
|
+
Author-email: Odos Matthews <odosmatthews@gmail.com>
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
14
|
+
Project-URL: Homepage, https://github.com/eddiethedean/raptors
|
|
15
|
+
Project-URL: Source, https://github.com/eddiethedean/raptors
|
|
16
|
+
Project-URL: Issue Tracker, https://github.com/eddiethedean/raptors/issues
|
|
17
|
+
|
|
18
|
+
# Raptors
|
|
19
|
+
|
|
20
|
+
Rust-powered, NumPy-compatible Python array library scaffolding.
|
|
21
|
+
|
|
22
|
+
## Getting Started
|
|
23
|
+
|
|
24
|
+
This repository contains the initial skeleton for `raptors`, a Rust-backed
|
|
25
|
+
array library exposed to Python. The project is being developed by Odos
|
|
26
|
+
Matthews (`odosmatthews@gmail.com`, GitHub: `eddiethedean`).
|
|
27
|
+
|
|
28
|
+
### Layout
|
|
29
|
+
|
|
30
|
+
- `rust/`: Rust crate exposing core functionality via `pyo3`.
|
|
31
|
+
- `python/`: Python package wrapper publishing the `raptors` module.
|
|
32
|
+
- `tests/`: pytest-based test suite comparing behavior to NumPy.
|
|
33
|
+
- `benches/`: Benchmark harnesses for performance tracking.
|
|
34
|
+
- `ci/`: Continuous-integration workflows and scripts.
|
|
35
|
+
- `docs/`: Documentation sources (overview, guides, references).
|
|
36
|
+
|
|
37
|
+
Consult `docs/overview.md` for an expanded project overview and links to the
|
|
38
|
+
full plan.
|
|
39
|
+
|
|
40
|
+
## Continuous Integration
|
|
41
|
+
|
|
42
|
+
An example GitHub Actions workflow is provided in `ci/github-actions.yml`. It
|
|
43
|
+
builds the Rust extension with `maturin`, installs the Python package in
|
|
44
|
+
development mode, and runs both `pytest` and `cargo test`.
|
|
45
|
+
|
|
46
|
+
|
raptors-0.0.1/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Raptors
|
|
2
|
+
|
|
3
|
+
Rust-powered, NumPy-compatible Python array library scaffolding.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
This repository contains the initial skeleton for `raptors`, a Rust-backed
|
|
8
|
+
array library exposed to Python. The project is being developed by Odos
|
|
9
|
+
Matthews (`odosmatthews@gmail.com`, GitHub: `eddiethedean`).
|
|
10
|
+
|
|
11
|
+
### Layout
|
|
12
|
+
|
|
13
|
+
- `rust/`: Rust crate exposing core functionality via `pyo3`.
|
|
14
|
+
- `python/`: Python package wrapper publishing the `raptors` module.
|
|
15
|
+
- `tests/`: pytest-based test suite comparing behavior to NumPy.
|
|
16
|
+
- `benches/`: Benchmark harnesses for performance tracking.
|
|
17
|
+
- `ci/`: Continuous-integration workflows and scripts.
|
|
18
|
+
- `docs/`: Documentation sources (overview, guides, references).
|
|
19
|
+
|
|
20
|
+
Consult `docs/overview.md` for an expanded project overview and links to the
|
|
21
|
+
full plan.
|
|
22
|
+
|
|
23
|
+
## Continuous Integration
|
|
24
|
+
|
|
25
|
+
An example GitHub Actions workflow is provided in `ci/github-actions.yml`. It
|
|
26
|
+
builds the Rust extension with `maturin`, installs the Python package in
|
|
27
|
+
development mode, and runs both `pytest` and `cargo test`.
|
|
28
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["maturin>=1.5,<2.0"]
|
|
3
|
+
build-backend = "maturin"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "raptors"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = "Rust-powered, NumPy-compatible array library scaffold."
|
|
9
|
+
authors = [{ name = "Odos Matthews", email = "odosmatthews@gmail.com" }]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
14
|
+
"Intended Audience :: Science/Research",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Rust",
|
|
18
|
+
"Topic :: Scientific/Engineering",
|
|
19
|
+
]
|
|
20
|
+
dependencies = []
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/eddiethedean/raptors"
|
|
24
|
+
Source = "https://github.com/eddiethedean/raptors"
|
|
25
|
+
"Issue Tracker" = "https://github.com/eddiethedean/raptors/issues"
|
|
26
|
+
|
|
27
|
+
[tool.maturin]
|
|
28
|
+
bindings = "pyo3"
|
|
29
|
+
features = ["pyo3/extension-module"]
|
|
30
|
+
module-name = "raptors._raptors"
|
|
31
|
+
profile = "release"
|
|
32
|
+
python-source = "python"
|
|
33
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Python interface for the Rust-powered Raptors array library.
|
|
3
|
+
|
|
4
|
+
This placeholder module wires through to the Rust extension module generated
|
|
5
|
+
by `maturin`, exposing an initial `array` constructor stub.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from . import _raptors as _core
|
|
11
|
+
|
|
12
|
+
__all__ = ["array", "__version__", "__author__", "__github__"]
|
|
13
|
+
|
|
14
|
+
__version__ = getattr(_core, "__version__", "0.0.1")
|
|
15
|
+
__author__ = getattr(_core, "__author__", "Odos Matthews <odosmatthews@gmail.com>")
|
|
16
|
+
__github__ = getattr(_core, "__github__", "https://github.com/eddiethedean")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def array() -> None:
|
|
20
|
+
"""Create a new Raptors array (placeholder implementation)."""
|
|
21
|
+
return _core.rustarray_new()
|
|
22
|
+
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "autocfg"
|
|
7
|
+
version = "1.5.0"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "bitflags"
|
|
13
|
+
version = "2.10.0"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "cfg-if"
|
|
19
|
+
version = "1.0.4"
|
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
22
|
+
|
|
23
|
+
[[package]]
|
|
24
|
+
name = "heck"
|
|
25
|
+
version = "0.4.1"
|
|
26
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
27
|
+
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
|
28
|
+
|
|
29
|
+
[[package]]
|
|
30
|
+
name = "indoc"
|
|
31
|
+
version = "2.0.7"
|
|
32
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
33
|
+
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
|
34
|
+
dependencies = [
|
|
35
|
+
"rustversion",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[[package]]
|
|
39
|
+
name = "libc"
|
|
40
|
+
version = "0.2.177"
|
|
41
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
42
|
+
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
|
43
|
+
|
|
44
|
+
[[package]]
|
|
45
|
+
name = "lock_api"
|
|
46
|
+
version = "0.4.14"
|
|
47
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
48
|
+
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
|
49
|
+
dependencies = [
|
|
50
|
+
"scopeguard",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[[package]]
|
|
54
|
+
name = "memoffset"
|
|
55
|
+
version = "0.9.1"
|
|
56
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
57
|
+
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
58
|
+
dependencies = [
|
|
59
|
+
"autocfg",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
[[package]]
|
|
63
|
+
name = "once_cell"
|
|
64
|
+
version = "1.21.3"
|
|
65
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
66
|
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
|
67
|
+
|
|
68
|
+
[[package]]
|
|
69
|
+
name = "parking_lot"
|
|
70
|
+
version = "0.12.5"
|
|
71
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
72
|
+
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
|
|
73
|
+
dependencies = [
|
|
74
|
+
"lock_api",
|
|
75
|
+
"parking_lot_core",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
[[package]]
|
|
79
|
+
name = "parking_lot_core"
|
|
80
|
+
version = "0.9.12"
|
|
81
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
82
|
+
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
|
83
|
+
dependencies = [
|
|
84
|
+
"cfg-if",
|
|
85
|
+
"libc",
|
|
86
|
+
"redox_syscall",
|
|
87
|
+
"smallvec",
|
|
88
|
+
"windows-link",
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
[[package]]
|
|
92
|
+
name = "portable-atomic"
|
|
93
|
+
version = "1.11.1"
|
|
94
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
95
|
+
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
|
|
96
|
+
|
|
97
|
+
[[package]]
|
|
98
|
+
name = "proc-macro2"
|
|
99
|
+
version = "1.0.103"
|
|
100
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
101
|
+
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
|
102
|
+
dependencies = [
|
|
103
|
+
"unicode-ident",
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
[[package]]
|
|
107
|
+
name = "pyo3"
|
|
108
|
+
version = "0.21.2"
|
|
109
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
110
|
+
checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8"
|
|
111
|
+
dependencies = [
|
|
112
|
+
"cfg-if",
|
|
113
|
+
"indoc",
|
|
114
|
+
"libc",
|
|
115
|
+
"memoffset",
|
|
116
|
+
"parking_lot",
|
|
117
|
+
"portable-atomic",
|
|
118
|
+
"pyo3-build-config",
|
|
119
|
+
"pyo3-ffi",
|
|
120
|
+
"pyo3-macros",
|
|
121
|
+
"unindent",
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
[[package]]
|
|
125
|
+
name = "pyo3-build-config"
|
|
126
|
+
version = "0.21.2"
|
|
127
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
128
|
+
checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50"
|
|
129
|
+
dependencies = [
|
|
130
|
+
"once_cell",
|
|
131
|
+
"target-lexicon",
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
[[package]]
|
|
135
|
+
name = "pyo3-ffi"
|
|
136
|
+
version = "0.21.2"
|
|
137
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
138
|
+
checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403"
|
|
139
|
+
dependencies = [
|
|
140
|
+
"libc",
|
|
141
|
+
"pyo3-build-config",
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
[[package]]
|
|
145
|
+
name = "pyo3-macros"
|
|
146
|
+
version = "0.21.2"
|
|
147
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
148
|
+
checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c"
|
|
149
|
+
dependencies = [
|
|
150
|
+
"proc-macro2",
|
|
151
|
+
"pyo3-macros-backend",
|
|
152
|
+
"quote",
|
|
153
|
+
"syn",
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
[[package]]
|
|
157
|
+
name = "pyo3-macros-backend"
|
|
158
|
+
version = "0.21.2"
|
|
159
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
160
|
+
checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c"
|
|
161
|
+
dependencies = [
|
|
162
|
+
"heck",
|
|
163
|
+
"proc-macro2",
|
|
164
|
+
"pyo3-build-config",
|
|
165
|
+
"quote",
|
|
166
|
+
"syn",
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
[[package]]
|
|
170
|
+
name = "quote"
|
|
171
|
+
version = "1.0.42"
|
|
172
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
173
|
+
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
|
174
|
+
dependencies = [
|
|
175
|
+
"proc-macro2",
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
[[package]]
|
|
179
|
+
name = "raptors"
|
|
180
|
+
version = "0.0.1"
|
|
181
|
+
dependencies = [
|
|
182
|
+
"pyo3",
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
[[package]]
|
|
186
|
+
name = "redox_syscall"
|
|
187
|
+
version = "0.5.18"
|
|
188
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
189
|
+
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
|
190
|
+
dependencies = [
|
|
191
|
+
"bitflags",
|
|
192
|
+
]
|
|
193
|
+
|
|
194
|
+
[[package]]
|
|
195
|
+
name = "rustversion"
|
|
196
|
+
version = "1.0.22"
|
|
197
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
198
|
+
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
199
|
+
|
|
200
|
+
[[package]]
|
|
201
|
+
name = "scopeguard"
|
|
202
|
+
version = "1.2.0"
|
|
203
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
204
|
+
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|
205
|
+
|
|
206
|
+
[[package]]
|
|
207
|
+
name = "smallvec"
|
|
208
|
+
version = "1.15.1"
|
|
209
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
210
|
+
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|
211
|
+
|
|
212
|
+
[[package]]
|
|
213
|
+
name = "syn"
|
|
214
|
+
version = "2.0.109"
|
|
215
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
216
|
+
checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f"
|
|
217
|
+
dependencies = [
|
|
218
|
+
"proc-macro2",
|
|
219
|
+
"quote",
|
|
220
|
+
"unicode-ident",
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
[[package]]
|
|
224
|
+
name = "target-lexicon"
|
|
225
|
+
version = "0.12.16"
|
|
226
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
227
|
+
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
228
|
+
|
|
229
|
+
[[package]]
|
|
230
|
+
name = "unicode-ident"
|
|
231
|
+
version = "1.0.22"
|
|
232
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
233
|
+
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
|
234
|
+
|
|
235
|
+
[[package]]
|
|
236
|
+
name = "unindent"
|
|
237
|
+
version = "0.2.4"
|
|
238
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
239
|
+
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
240
|
+
|
|
241
|
+
[[package]]
|
|
242
|
+
name = "windows-link"
|
|
243
|
+
version = "0.2.1"
|
|
244
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
245
|
+
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "raptors"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
authors = ["Odos Matthews <odosmatthews@gmail.com>"]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
description = "Rust core crate for the Raptors array library."
|
|
8
|
+
repository = "https://github.com/eddiethedean/raptors"
|
|
9
|
+
|
|
10
|
+
[lib]
|
|
11
|
+
name = "raptors"
|
|
12
|
+
crate-type = ["cdylib"]
|
|
13
|
+
|
|
14
|
+
[dependencies]
|
|
15
|
+
pyo3 = { version = "0.21", features = ["extension-module"] }
|
|
16
|
+
|
|
17
|
+
[profile.release]
|
|
18
|
+
opt-level = 3
|
|
19
|
+
lto = "thin"
|
|
20
|
+
codegen-units = 1
|
|
21
|
+
|
|
22
|
+
[package.metadata.maturin]
|
|
23
|
+
name = "raptors._raptors"
|
|
24
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
use pyo3::prelude::*;
|
|
2
|
+
|
|
3
|
+
/// Placeholder function that will eventually construct a Raptors array.
|
|
4
|
+
#[pyfunction]
|
|
5
|
+
fn rustarray_new() -> PyResult<()> {
|
|
6
|
+
Ok(())
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/// Python module initialization for `_raptors`.
|
|
10
|
+
#[pymodule]
|
|
11
|
+
fn _raptors(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|
12
|
+
m.add_wrapped(pyo3::wrap_pyfunction!(rustarray_new))?;
|
|
13
|
+
m.add("__version__", env!("CARGO_PKG_VERSION"))?;
|
|
14
|
+
m.add("__author__", "Odos Matthews <odosmatthews@gmail.com>")?;
|
|
15
|
+
m.add("__github__", "https://github.com/eddiethedean")?;
|
|
16
|
+
m.add("__doc__", "Rust-backed array core for the Raptors project.")?;
|
|
17
|
+
|
|
18
|
+
Ok(())
|
|
19
|
+
}
|
|
20
|
+
|