rsyntaxtree 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.tags +233 -75
- data/README.md +23 -25
- data/Rakefile +71 -0
- data/docs/_examples/001.md +1 -0
- data/docs/_examples/002.md +1 -0
- data/docs/_examples/003.md +1 -0
- data/docs/_examples/004.md +1 -0
- data/docs/_examples/005.md +1 -0
- data/docs/_examples/006.md +1 -0
- data/docs/_examples/007.md +1 -0
- data/docs/_examples/008.md +1 -0
- data/docs/_examples/009.md +1 -0
- data/docs/_examples/010.md +1 -0
- data/docs/_examples/011.md +1 -0
- data/docs/_examples/012.md +1 -0
- data/docs/_examples/013.md +1 -0
- data/docs/_examples/014.md +1 -0
- data/docs/_examples/015.md +1 -0
- data/docs/_examples/016.md +2 -1
- data/docs/_examples/017.md +1 -0
- data/docs/_examples/018.md +1 -0
- data/docs/_examples/019.md +2 -1
- data/docs/_examples/020.md +1 -0
- data/docs/_examples/021.md +43 -0
- data/docs/_examples/022.md +58 -0
- data/docs/_examples/023.md +23 -0
- data/docs/_examples/024.md +23 -0
- data/docs/_examples/025.md +87 -0
- data/docs/_examples/026.md +27 -0
- data/docs/_examples/027.md +54 -0
- data/docs/_examples/028.md +20 -0
- data/docs/_includes/escape_char_table.html +1 -1
- data/docs/assets/img/001.png +0 -0
- data/docs/assets/img/002.png +0 -0
- data/docs/assets/img/003.png +0 -0
- data/docs/assets/img/004.png +0 -0
- data/docs/assets/img/005.png +0 -0
- data/docs/assets/img/006.png +0 -0
- data/docs/assets/img/007.png +0 -0
- data/docs/assets/img/008.png +0 -0
- data/docs/assets/img/009.png +0 -0
- data/docs/assets/img/010.png +0 -0
- data/docs/assets/img/011.png +0 -0
- data/docs/assets/img/012.png +0 -0
- data/docs/assets/img/013.png +0 -0
- data/docs/assets/img/014.png +0 -0
- data/docs/assets/img/015.png +0 -0
- data/docs/assets/img/016.png +0 -0
- data/docs/assets/img/017.png +0 -0
- data/docs/assets/img/018.png +0 -0
- data/docs/assets/img/019.png +0 -0
- data/docs/assets/img/020.png +0 -0
- data/docs/assets/img/021.png +0 -0
- data/docs/assets/img/022.png +0 -0
- data/docs/assets/img/023.png +0 -0
- data/docs/assets/img/024.png +0 -0
- data/docs/assets/img/025.png +0 -0
- data/docs/assets/img/026.png +0 -0
- data/docs/assets/img/027.png +0 -0
- data/docs/assets/img/028.png +0 -0
- data/docs/assets/svg/008.svg +2 -2
- data/docs/assets/svg/021.svg +86 -0
- data/docs/assets/svg/022.svg +163 -0
- data/docs/assets/svg/023.svg +116 -0
- data/docs/assets/svg/024.svg +47 -0
- data/docs/assets/svg/025.svg +170 -0
- data/docs/assets/svg/026.svg +41 -0
- data/docs/assets/svg/027.svg +92 -0
- data/docs/assets/svg/028.svg +42 -0
- data/docs/documentation.md +1 -1
- data/docs/documentation_ja.md +1 -1
- data/docs/examples.html +4 -2
- data/lib/rsyntaxtree/markup_parser.rb +1 -1
- data/lib/rsyntaxtree/version.rb +1 -1
- data/test/example_verify_test.rb +0 -21
- metadata +27 -3
data/README.md
CHANGED
@@ -2,18 +2,15 @@
|
|
2
2
|
|
3
3
|
**RSyntaxTree** is a graphical syntax tree generator written in the Ruby programming language.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
### Documentation
|
5
|
+
## Documentation
|
8
6
|
|
9
7
|
Documentation is currently available in the following languages:
|
10
8
|
|
11
|
-
- [English](https://yohasebe.github.io/rsyntaxtree/documentation)
|
12
|
-
- [
|
13
|
-
|
14
|
-
---
|
9
|
+
- [Documentation in English](https://yohasebe.github.io/rsyntaxtree/documentation)
|
10
|
+
- [日本語ドキュメント](https://yohasebe.github.io/rsyntaxtree/documentation_ja)
|
15
11
|
|
16
|
-
|
12
|
+
- [Example Gallery](https://yohasebe.github.io/rsyntaxtree/examples)
|
13
|
+
## Web Interface
|
17
14
|
|
18
15
|
<img src='https://github.com/yohasebe/rsyntaxtree/blob/master/img/rsyntaxtree-web-screenshot.png?raw=true' width='700px'/>
|
19
16
|
|
@@ -21,9 +18,7 @@ See updates and a working web interface available at <https://yohasebe.com/rsynt
|
|
21
18
|
|
22
19
|
You can run RSyntaxTree's web interface on your local machine using Docker Desktop. See [RSyntaxTree Web UI](https://github.com/yohasebe/rsyntaxtree_web)
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
### Examples
|
21
|
+
## Examples
|
27
22
|
|
28
23
|
See [RSyntaxTree Example Gallery](https://yohasebe.github.io/rsyntaxtree/examples) page for syntax tree samples for
|
29
24
|
|
@@ -54,15 +49,11 @@ See [RSyntaxTree Example Gallery](https://yohasebe.github.io/rsyntaxtree/example
|
|
54
49
|
|
55
50
|
<img src='https://github.com/yohasebe/rsyntaxtree/blob/master/img/sample.png?raw=true' width='600' />
|
56
51
|
|
57
|
-
|
58
|
-
|
59
|
-
### Installation
|
52
|
+
## Installation
|
60
53
|
|
61
54
|
`# gem install rsyntaxtree`
|
62
55
|
|
63
|
-
|
64
|
-
|
65
|
-
### Usage
|
56
|
+
## Usage
|
66
57
|
|
67
58
|
For the web interface, see Usage section of <https://yohasebe.com/rsyntaxtree>.
|
68
59
|
|
@@ -93,21 +84,28 @@ where [options] are:
|
|
93
84
|
|
94
85
|
See the [documentation](https://yohasebe.github.io/rsyntaxtree/documentation) for more detailed info about the syntax.
|
95
86
|
|
96
|
-
|
87
|
+
## References
|
97
88
|
|
98
|
-
|
89
|
+
Please use the following BibTeX entry when referring to RSyntaxTree.
|
99
90
|
|
100
|
-
|
91
|
+
```
|
92
|
+
@misc{rsyntaxtree_2023,
|
93
|
+
author = {Yoichiro Hasebe},
|
94
|
+
title = {RSyntaxTree: A graphical syntax tree image generator}
|
95
|
+
url = {https://yohasebe.com/rsyntaxtree},
|
96
|
+
year = {2023}
|
97
|
+
}
|
98
|
+
```
|
101
99
|
|
102
|
-
|
100
|
+
## Development
|
103
101
|
|
104
|
-
|
102
|
+
For the latest updates and downloads please visit <http://github.com/yohasebe/rsyntaxtree>
|
105
103
|
|
106
|
-
|
104
|
+
## Author
|
107
105
|
|
108
|
-
|
106
|
+
Yoichiro Hasebe <yohasebe@gmail.com>
|
109
107
|
|
110
|
-
|
108
|
+
## License
|
111
109
|
|
112
110
|
RSyntaxTree is distributed under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
|
113
111
|
|
data/Rakefile
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
require "rake/testtask"
|
5
|
+
require "yaml"
|
6
|
+
require_relative 'lib/rsyntaxtree'
|
7
|
+
require_relative 'lib/rsyntaxtree/utils'
|
5
8
|
|
6
9
|
# task default: "test"
|
7
10
|
|
@@ -9,3 +12,71 @@ Rake::TestTask.new do |task|
|
|
9
12
|
task.pattern = "test/*_test.rb"
|
10
13
|
task.warning = false
|
11
14
|
end
|
15
|
+
|
16
|
+
desc "Generate SVG and PNG example images"
|
17
|
+
task :generate do
|
18
|
+
examples_dir = File.expand_path(File.join(__dir__, "docs", "_examples"))
|
19
|
+
svg_dir = File.expand_path(File.join(__dir__, "docs", "assets", "svg"))
|
20
|
+
png_dir = File.expand_path(File.join(__dir__, "docs", "assets", "img"))
|
21
|
+
Dir.glob("*.md", base: examples_dir).map do |md|
|
22
|
+
md = File.join(examples_dir, md)
|
23
|
+
config = YAML.load_file(md)
|
24
|
+
rst = File.read(md).scan(/```([^`]+)```/m).last.first
|
25
|
+
|
26
|
+
opts = {
|
27
|
+
format: "png",
|
28
|
+
leafstyle: "auto",
|
29
|
+
fontstyle: "sans",
|
30
|
+
fontsize: 16,
|
31
|
+
margin: 1,
|
32
|
+
vheight: 2.0,
|
33
|
+
color: "on",
|
34
|
+
symmetrize: "on",
|
35
|
+
transparent: "off",
|
36
|
+
polyline: "off"
|
37
|
+
}
|
38
|
+
name = nil
|
39
|
+
config.each do |key, value|
|
40
|
+
next if value.to_s == ""
|
41
|
+
|
42
|
+
case key
|
43
|
+
when "name"
|
44
|
+
name = value
|
45
|
+
opts[:name] = name
|
46
|
+
when "colorization"
|
47
|
+
opts[:color] = value
|
48
|
+
when "polyline"
|
49
|
+
opts[:polyline] = value
|
50
|
+
when "symmetrization"
|
51
|
+
opts[:symmetrize] = value
|
52
|
+
when "connector"
|
53
|
+
opts[:leafstyle] = value
|
54
|
+
when "font"
|
55
|
+
opts[:fontstyle] = case value
|
56
|
+
when /sans/i
|
57
|
+
"sans"
|
58
|
+
when /serif/i
|
59
|
+
"serif"
|
60
|
+
when /wqy/i
|
61
|
+
"cjk"
|
62
|
+
else
|
63
|
+
"sans"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
opts[:data] = rst
|
68
|
+
rsg = RSyntaxTree::RSGenerator.new(opts)
|
69
|
+
|
70
|
+
File.open(File.join(svg_dir, "#{name}.svg"), "w") do |f|
|
71
|
+
puts "Creating svg file: #{name}.svg"
|
72
|
+
svg = rsg.draw_svg
|
73
|
+
f.write(svg)
|
74
|
+
end
|
75
|
+
|
76
|
+
File.open(File.join(png_dir, "#{name}.png"), "w") do |f|
|
77
|
+
puts "Creating png file: #{name}.png"
|
78
|
+
png = rsg.draw_png
|
79
|
+
f.write(png)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/docs/_examples/001.md
CHANGED
data/docs/_examples/002.md
CHANGED
data/docs/_examples/003.md
CHANGED
data/docs/_examples/004.md
CHANGED
data/docs/_examples/005.md
CHANGED
data/docs/_examples/006.md
CHANGED
data/docs/_examples/007.md
CHANGED
data/docs/_examples/008.md
CHANGED
data/docs/_examples/009.md
CHANGED
data/docs/_examples/010.md
CHANGED
data/docs/_examples/011.md
CHANGED
data/docs/_examples/012.md
CHANGED
data/docs/_examples/013.md
CHANGED
data/docs/_examples/014.md
CHANGED
data/docs/_examples/015.md
CHANGED
data/docs/_examples/016.md
CHANGED
data/docs/_examples/017.md
CHANGED
data/docs/_examples/018.md
CHANGED
data/docs/_examples/019.md
CHANGED
data/docs/_examples/020.md
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
---
|
2
|
+
name: "021"
|
3
|
+
caption: "Types of meaning"
|
4
|
+
colorization: "off"
|
5
|
+
category: "Pragmatics"
|
6
|
+
polyline: "on"
|
7
|
+
symmetrization: "off"
|
8
|
+
connector: "bar"
|
9
|
+
font: "Noto Serif"
|
10
|
+
reference: "Zufferey, Moeschler, and Reboul 2014"
|
11
|
+
---
|
12
|
+
```
|
13
|
+
[Types<>of<>meaning
|
14
|
+
[conventional
|
15
|
+
[semantic
|
16
|
+
[entailment]
|
17
|
+
[presupposition]
|
18
|
+
]
|
19
|
+
[pragmatic
|
20
|
+
[conventional\
|
21
|
+
implicature]
|
22
|
+
]
|
23
|
+
]
|
24
|
+
[non\-conventional
|
25
|
+
[explicit
|
26
|
+
[explicature]
|
27
|
+
]
|
28
|
+
[implicit
|
29
|
+
[conventional
|
30
|
+
[generalized\
|
31
|
+
implicature]
|
32
|
+
[particularized\
|
33
|
+
implicature]
|
34
|
+
]
|
35
|
+
[non\-\
|
36
|
+
conventional
|
37
|
+
[pragmatic\
|
38
|
+
presupposition]
|
39
|
+
]
|
40
|
+
]
|
41
|
+
]
|
42
|
+
]
|
43
|
+
```
|
@@ -0,0 +1,58 @@
|
|
1
|
+
---
|
2
|
+
name: "022"
|
3
|
+
caption: "Arithmetic parser"
|
4
|
+
colorization: "off"
|
5
|
+
category: "Computer Science"
|
6
|
+
polyline: "on"
|
7
|
+
symmetrization: "off"
|
8
|
+
connector: "bar"
|
9
|
+
font: "Noto Serif"
|
10
|
+
reference: ""
|
11
|
+
---
|
12
|
+
```
|
13
|
+
[\<expression\>
|
14
|
+
[\<term\>
|
15
|
+
[\<term\>
|
16
|
+
[\<factor\>
|
17
|
+
\(
|
18
|
+
[\<expression\>
|
19
|
+
[\<expression\>
|
20
|
+
[\<term\>
|
21
|
+
[\<factor\>
|
22
|
+
{A}
|
23
|
+
]
|
24
|
+
]
|
25
|
+
]
|
26
|
+
[{+}]
|
27
|
+
[\<term\>
|
28
|
+
[\<factor\>
|
29
|
+
{B}
|
30
|
+
]
|
31
|
+
]
|
32
|
+
]
|
33
|
+
\)
|
34
|
+
]
|
35
|
+
]
|
36
|
+
[{*}]
|
37
|
+
[\<factor\>
|
38
|
+
\(
|
39
|
+
[\<expression\>
|
40
|
+
[\<expression\>
|
41
|
+
[\<term\>
|
42
|
+
[\<factor\>
|
43
|
+
{C}
|
44
|
+
]
|
45
|
+
]
|
46
|
+
]
|
47
|
+
[{+}]
|
48
|
+
[\<term\>
|
49
|
+
[\<factor\>
|
50
|
+
{D}
|
51
|
+
]
|
52
|
+
]
|
53
|
+
]
|
54
|
+
\)
|
55
|
+
]
|
56
|
+
]
|
57
|
+
]
|
58
|
+
```
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
name: "023"
|
3
|
+
caption: "Tournament"
|
4
|
+
colorization: "off"
|
5
|
+
category: "Miscellaneous"
|
6
|
+
polyline: "on"
|
7
|
+
symmetrization: "off"
|
8
|
+
connector: "bar"
|
9
|
+
font: "Noto Sans"
|
10
|
+
reference: ""
|
11
|
+
---
|
12
|
+
```
|
13
|
+
[{**D**}
|
14
|
+
[{**D**}
|
15
|
+
[A [{A}] [B]]
|
16
|
+
[{**D**} [C] [{**D**}]]
|
17
|
+
]
|
18
|
+
[G
|
19
|
+
[F [E] [{F}]]
|
20
|
+
[{G} [{G}] [H]]
|
21
|
+
]
|
22
|
+
]
|
23
|
+
```
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
name: "024"
|
3
|
+
caption: "X-bar model"
|
4
|
+
colorization: "off"
|
5
|
+
category: "Generative Grammar"
|
6
|
+
polyline: "off"
|
7
|
+
symmetrization: "off"
|
8
|
+
connector: "none"
|
9
|
+
font: "Noto Serif"
|
10
|
+
reference:
|
11
|
+
---
|
12
|
+
```
|
13
|
+
[XP
|
14
|
+
[W Specifier]
|
15
|
+
[X'
|
16
|
+
[X'
|
17
|
+
[X Head]
|
18
|
+
[Y Complement]
|
19
|
+
]
|
20
|
+
[Z Modifier]
|
21
|
+
]
|
22
|
+
]
|
23
|
+
```
|
@@ -0,0 +1,87 @@
|
|
1
|
+
---
|
2
|
+
name: "025"
|
3
|
+
caption: "Network of non-prototypical sentence constructions"
|
4
|
+
colorization: "off"
|
5
|
+
category: "Construction Grammar"
|
6
|
+
polyline: "on"
|
7
|
+
symmetrization: "off"
|
8
|
+
connector: "bar"
|
9
|
+
font: "Noto Serif"
|
10
|
+
reference: "Goldberg 2006: 177"
|
11
|
+
---
|
12
|
+
```
|
13
|
+
[#**Non\-prototypical<>sentence**\
|
14
|
+
---\
|
15
|
+
NON\-POSITIVE,\
|
16
|
+
non\-predicate<>focus,\
|
17
|
+
non\-assertive,\
|
18
|
+
dependent,\
|
19
|
+
non\-declarative
|
20
|
+
[#**Y/N<>questions**\
|
21
|
+
---\
|
22
|
+
NON\-POSITIVE,\
|
23
|
+
non\-declarative\
|
24
|
+
---\
|
25
|
+
*Did<>she<>go?*
|
26
|
+
[#**Wh\-Questions**\
|
27
|
+
---\
|
28
|
+
non\-declarative\
|
29
|
+
---\
|
30
|
+
*Where<>did<>she<>go?*
|
31
|
+
]
|
32
|
+
[#**Exclamatives**\
|
33
|
+
---\
|
34
|
+
non\-assertive\
|
35
|
+
---\
|
36
|
+
*Boy<>did<>she<>go!*
|
37
|
+
]
|
38
|
+
]
|
39
|
+
[#**Counterfactual<>conditionals**\
|
40
|
+
---\
|
41
|
+
NON\-POSITIVE\
|
42
|
+
dependent,<>non\-asserted\
|
43
|
+
---\
|
44
|
+
*Had<>he<>found<>a<>solution,<>he*\
|
45
|
+
*would<>take<>time<>off<>and<>relax.*
|
46
|
+
]
|
47
|
+
[#**Initial<>negative**\
|
48
|
+
**adverb<>clauses**\
|
49
|
+
---\
|
50
|
+
NON\-POSITIVE\
|
51
|
+
---\
|
52
|
+
*Not<>until<>yesterday<>did*\
|
53
|
+
*he<>take<>a<>break.*\
|
54
|
+
]
|
55
|
+
[#**Negative<>rejoinder**\
|
56
|
+
---\
|
57
|
+
NON\-POSITIVE,\
|
58
|
+
dependent\
|
59
|
+
---\
|
60
|
+
*Neither<>is<>this<>construction*\
|
61
|
+
*unexpected.*
|
62
|
+
[#**Positive<>conjunct<>clauses**\
|
63
|
+
---\
|
64
|
+
non\-predicate<>focus,\
|
65
|
+
dependent\
|
66
|
+
---\
|
67
|
+
*So<>was<>I.*
|
68
|
+
]
|
69
|
+
]
|
70
|
+
[#**Comparatives**\
|
71
|
+
---\
|
72
|
+
non\-topic\-comment,\
|
73
|
+
dependent\
|
74
|
+
---\
|
75
|
+
*He<>was<>faster<>at<>it*\
|
76
|
+
*than<>was<>she.*
|
77
|
+
]
|
78
|
+
[#**Wishes,<>curses**\
|
79
|
+
---\
|
80
|
+
NON\-POSITIVE,\
|
81
|
+
non\-declarative\
|
82
|
+
---\
|
83
|
+
*May<>a<>million<>flies*\
|
84
|
+
*infest<>his<>armpits!*
|
85
|
+
]
|
86
|
+
]
|
87
|
+
```
|
@@ -0,0 +1,27 @@
|
|
1
|
+
---
|
2
|
+
name: "026"
|
3
|
+
caption: "Types of reference"
|
4
|
+
colorization: "off"
|
5
|
+
category: "Pragmatics"
|
6
|
+
polyline: "on"
|
7
|
+
symmetrization: "off"
|
8
|
+
connector: "bar"
|
9
|
+
font: "Noto Serif"
|
10
|
+
reference: "Halliday and Hasan 1976: 33"
|
11
|
+
---
|
12
|
+
```
|
13
|
+
[Reference:
|
14
|
+
[\[situational\]\
|
15
|
+
exophora
|
16
|
+
]
|
17
|
+
[\[textual\]\
|
18
|
+
endophora
|
19
|
+
[\[to<>preceding<>text\]\
|
20
|
+
anaphora
|
21
|
+
]
|
22
|
+
[\[to<>following<>text\]\
|
23
|
+
cataphora
|
24
|
+
]
|
25
|
+
]
|
26
|
+
]
|
27
|
+
```
|
@@ -0,0 +1,54 @@
|
|
1
|
+
---
|
2
|
+
name: "027"
|
3
|
+
caption: "Types of rejoinder"
|
4
|
+
colorization: "off"
|
5
|
+
category: "Pragmatics"
|
6
|
+
polyline: "on"
|
7
|
+
symmetrization: "off"
|
8
|
+
connector: "bar"
|
9
|
+
font: "Noto Serif"
|
10
|
+
reference: "Halliday and Hasan 1976: 207"
|
11
|
+
---
|
12
|
+
```
|
13
|
+
[REJOINDER\
|
14
|
+
(any<>cohesive<>sequel<>by<>different<>speaker)
|
15
|
+
[(following<>a<>question)\
|
16
|
+
RESPONSE
|
17
|
+
[(answering)\
|
18
|
+
DIRECT\
|
19
|
+
RESPONSE
|
20
|
+
]
|
21
|
+
[(not<>answering)\
|
22
|
+
INDIRECT<>RESPONSE
|
23
|
+
[(attitude<>to<>answer)\
|
24
|
+
COMMENTARY
|
25
|
+
]
|
26
|
+
[(evading<>answer)\
|
27
|
+
DISCLAIMER
|
28
|
+
]
|
29
|
+
[(implying<>answer)\
|
30
|
+
SUPPLEMENTARY\
|
31
|
+
RESPONSE
|
32
|
+
]
|
33
|
+
]
|
34
|
+
]
|
35
|
+
[(not<>following<>a<>question)\
|
36
|
+
\[other<>rejoinders\]
|
37
|
+
[(following<>a<>statement)
|
38
|
+
[ASSENT]
|
39
|
+
[CONTRADICTION]
|
40
|
+
]
|
41
|
+
[(following<>a\
|
42
|
+
statement<>or\
|
43
|
+
command)\
|
44
|
+
QUESTION\
|
45
|
+
REJOINDER
|
46
|
+
]
|
47
|
+
[(following<>\
|
48
|
+
a<>command)
|
49
|
+
[CONSENT]
|
50
|
+
[REFUSAL]
|
51
|
+
]
|
52
|
+
]
|
53
|
+
]
|
54
|
+
```
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
name: "028"
|
3
|
+
caption: "Basic tree with triangles"
|
4
|
+
colorization: "on"
|
5
|
+
category: "General"
|
6
|
+
polyline: "off"
|
7
|
+
symmetrization: "off"
|
8
|
+
connector: "auto"
|
9
|
+
font: "Noto Serif"
|
10
|
+
reference:
|
11
|
+
---
|
12
|
+
```
|
13
|
+
[NP
|
14
|
+
[NP a picture]
|
15
|
+
[PP
|
16
|
+
[P of]
|
17
|
+
[NP ^cats]
|
18
|
+
]
|
19
|
+
]
|
20
|
+
```
|