ronin-web 1.0.1 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +3 -2
- data/.gitignore +1 -0
- data/.rubocop.yml +5 -0
- data/ChangeLog.md +46 -1
- data/Gemfile +25 -12
- data/README.md +486 -39
- data/Rakefile +9 -0
- data/data/completions/ronin-web +203 -0
- data/gemspec.yml +18 -5
- data/lib/ronin/web/cli/browser_options.rb +92 -0
- data/lib/ronin/web/cli/browser_shell.rb +448 -0
- data/lib/ronin/web/cli/command.rb +1 -1
- data/lib/ronin/web/cli/commands/browser.rb +373 -0
- data/lib/ronin/web/cli/commands/completion.rb +63 -0
- data/lib/ronin/web/cli/commands/diff.rb +60 -8
- data/lib/ronin/web/cli/commands/html.rb +21 -33
- data/lib/ronin/web/cli/commands/irb.rb +1 -1
- data/lib/ronin/web/cli/commands/new/{webapp.rb → app.rb} +8 -8
- data/lib/ronin/web/cli/commands/new/nokogiri.rb +4 -4
- data/lib/ronin/web/cli/commands/new/server.rb +1 -1
- data/lib/ronin/web/cli/commands/new/spider.rb +1 -1
- data/lib/ronin/web/cli/commands/new.rb +5 -3
- data/lib/ronin/web/cli/commands/reverse_proxy.rb +1 -1
- data/lib/ronin/web/cli/commands/screenshot.rb +186 -0
- data/lib/ronin/web/cli/commands/server.rb +3 -3
- data/lib/ronin/web/cli/commands/session_cookie.rb +265 -0
- data/lib/ronin/web/cli/commands/spider.rb +60 -466
- data/lib/ronin/web/cli/commands/user_agent.rb +177 -0
- data/lib/ronin/web/cli/commands/vulns.rb +463 -0
- data/lib/ronin/web/cli/commands/wordlist.rb +484 -0
- data/lib/ronin/web/cli/commands/xml.rb +149 -0
- data/lib/ronin/web/cli/js_shell.rb +69 -0
- data/lib/ronin/web/cli/ruby_shell.rb +1 -1
- data/lib/ronin/web/cli/spider_options.rb +919 -0
- data/lib/ronin/web/cli.rb +3 -1
- data/lib/ronin/web/html.rb +1 -1
- data/lib/ronin/web/root.rb +1 -1
- data/lib/ronin/web/version.rb +2 -2
- data/lib/ronin/web/xml.rb +1 -1
- data/lib/ronin/web.rb +4 -364
- data/man/ronin-web-browser.1 +92 -0
- data/man/ronin-web-browser.1.md +96 -0
- data/man/ronin-web-completion.1 +76 -0
- data/man/ronin-web-completion.1.md +78 -0
- data/man/ronin-web-diff.1 +14 -21
- data/man/ronin-web-diff.1.md +13 -6
- data/man/ronin-web-html.1 +30 -46
- data/man/ronin-web-html.1.md +27 -17
- data/man/ronin-web-irb.1 +9 -16
- data/man/ronin-web-irb.1.md +6 -2
- data/man/ronin-web-new-app.1.md +39 -0
- data/man/ronin-web-new-nokogiri.1 +9 -20
- data/man/ronin-web-new-nokogiri.1.md +5 -5
- data/man/ronin-web-new-server.1 +11 -23
- data/man/ronin-web-new-server.1.md +5 -5
- data/man/ronin-web-new-spider.1 +44 -88
- data/man/ronin-web-new-spider.1.md +37 -37
- data/man/ronin-web-new.1 +18 -30
- data/man/ronin-web-new.1.md +15 -11
- data/man/ronin-web-reverse-proxy.1 +33 -38
- data/man/ronin-web-reverse-proxy.1.md +20 -14
- data/man/ronin-web-screenshot.1 +56 -0
- data/man/ronin-web-screenshot.1.md +56 -0
- data/man/ronin-web-server.1 +15 -29
- data/man/ronin-web-server.1.md +13 -9
- data/man/ronin-web-session-cookie.1 +38 -0
- data/man/ronin-web-session-cookie.1.md +41 -0
- data/man/ronin-web-spider.1 +121 -130
- data/man/ronin-web-spider.1.md +115 -66
- data/man/ronin-web-user-agent.1 +44 -0
- data/man/ronin-web-user-agent.1.md +46 -0
- data/man/ronin-web-vulns.1 +175 -0
- data/man/ronin-web-vulns.1.md +177 -0
- data/man/ronin-web-wordlist.1 +258 -0
- data/man/ronin-web-wordlist.1.md +263 -0
- data/man/ronin-web-xml.1 +43 -0
- data/man/ronin-web-xml.1.md +46 -0
- data/man/ronin-web.1 +67 -18
- data/man/ronin-web.1.md +55 -4
- data/scripts/setup +58 -0
- metadata +122 -31
- data/lib/ronin/web/mechanize.rb +0 -82
- data/man/ronin-web-new-webapp.1.md +0 -39
- /data/data/new/{webapp → app}/.gitignore +0 -0
- /data/data/new/{webapp → app}/.ruby-version.erb +0 -0
- /data/data/new/{webapp → app}/Dockerfile.erb +0 -0
- /data/data/new/{webapp → app}/Gemfile +0 -0
- /data/data/new/{webapp → app}/app.rb.erb +0 -0
- /data/data/new/{webapp → app}/config.ru +0 -0
- /data/data/new/{webapp → app}/docker-compose.yml.erb +0 -0
@@ -1,42 +1,48 @@
|
|
1
|
-
# ronin-web-proxy 1 "2022-01-01" Ronin "User Manuals"
|
1
|
+
# ronin-web-reverse-proxy 1 "2022-01-01" Ronin "User Manuals"
|
2
|
+
|
3
|
+
## NAME
|
4
|
+
|
5
|
+
ronin-web-reverse-proxy - Starts a HTTP proxy server
|
2
6
|
|
3
7
|
## SYNOPSIS
|
4
8
|
|
5
|
-
`ronin-web proxy` [*options*] [`--host` *HOST*] [`--port` *PORT*]
|
9
|
+
`ronin-web reverse-proxy` [*options*] [`--host` *HOST*] [`--port` *PORT*]
|
6
10
|
|
7
11
|
## DESCRIPTION
|
8
12
|
|
9
|
-
Starts a HTTP proxy server.
|
13
|
+
Starts a HTTP reverse proxy server.
|
10
14
|
|
11
15
|
## OPTIONS
|
12
16
|
|
13
17
|
`-H`, `--host` *HOST*
|
14
|
-
|
18
|
+
: The host that the proxy server will listen on. Defaults to `localhost`.
|
15
19
|
|
16
20
|
`-p`, `--port` *PORT*
|
17
|
-
|
21
|
+
: The port that the proxy server will listen on. Default to `8080`.
|
18
22
|
|
19
23
|
`-b`, `--show-body`
|
20
|
-
|
24
|
+
: Controls whether to display the request/response bodies or not.
|
21
25
|
|
22
26
|
`--rewrite-requests` {*STRING*:*REPLACE*|/*REGEXP*/:*REPLACE*}
|
23
|
-
|
27
|
+
: Rewrites all request bodies by replacing the *STRING* or *REGEXP* with the
|
24
28
|
given *REPLACE* string.
|
25
29
|
|
26
30
|
`--rewrite-responses` {*STRING*:*REPLACE*|/*REGEXP*/:*REPLACE*}
|
27
|
-
|
31
|
+
: Rewrites all response bodies by replacing the *STRING* or *REGEXP* with the
|
28
32
|
given *REPLACE* string.
|
29
33
|
|
30
34
|
`-h`, `--help`
|
31
|
-
|
35
|
+
: prints help information.
|
32
36
|
|
33
37
|
## EXAMPLES
|
34
38
|
|
35
|
-
|
36
|
-
|
39
|
+
Listen on the external interface on port 80:
|
40
|
+
|
41
|
+
$ sudo ronin-web reverse-proxy --host 0.0.0.0 --port 80
|
42
|
+
|
43
|
+
Replace every occurrence of `https` with `http` in the response bodies:
|
37
44
|
|
38
|
-
|
39
|
-
Replace every occurrence of `https` with `http` in the response bodies.
|
45
|
+
$ ronin-web reverse-proxy --rewrite-responses https:http
|
40
46
|
|
41
47
|
## AUTHOR
|
42
48
|
|
@@ -44,4 +50,4 @@ Postmodern <postmodern.mod3@gmail.com>
|
|
44
50
|
|
45
51
|
## SEE ALSO
|
46
52
|
|
47
|
-
ronin-web-server(1)
|
53
|
+
[ronin-web-server](ronin-web-server.1.md)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
.\" Generated by kramdown-man 1.0.1
|
2
|
+
.\" https://github.com/postmodern/kramdown-man#readme
|
3
|
+
.TH ronin-web-screenshot 1 "2023-05-01" Ronin Web "User Manuals"
|
4
|
+
.SH NAME
|
5
|
+
.PP
|
6
|
+
ronin\-web\-screenshot \- Screenshots one or more URLs
|
7
|
+
.SH SYNOPSIS
|
8
|
+
.PP
|
9
|
+
\fBronin\-web\-screenshot\fR \[lB]\fIoptions\fP\[rB] \[lC]\fIURL\fP \[lB]\.\.\.\[rB] \[or] \fB\-\-file\fR \fIFILE\fP\[rC]
|
10
|
+
.SH DESCRIPTION
|
11
|
+
.PP
|
12
|
+
Screenshots one or more URLs\.
|
13
|
+
.SH ARGUMENTS
|
14
|
+
.TP
|
15
|
+
\fIURL\fP
|
16
|
+
A \fBhttps:\[sl]\[sl]\fR or \fBhttp:\[sl]\[sl]\fR URL of the web page to diff\.
|
17
|
+
.SH OPTIONS
|
18
|
+
.TP
|
19
|
+
\fB\-B\fR, \fB\-\-browser\fR \fINAME\fP\[or]\fIPATH\fP
|
20
|
+
The browser name or path to execute\.
|
21
|
+
.TP
|
22
|
+
\fB\-W\fR, \fB\-\-width\fR \fIWIDTH\fP
|
23
|
+
Sets the width of the browser viewport\. Defaults to \fB1024\fR if not given\.
|
24
|
+
\.
|
25
|
+
\fB\-H\fR, \fB\-\-height\fR \fIHEIGHT\fP
|
26
|
+
.RS
|
27
|
+
.PP
|
28
|
+
Sets the height of the browser viewport\. Defaults to \fB768\fR if not given\.
|
29
|
+
.RE
|
30
|
+
.TP
|
31
|
+
\fB\-f\fR, \fB\-\-file\fR \fIFILE\fP
|
32
|
+
Input file to read URLs from\.
|
33
|
+
.TP
|
34
|
+
\fB\-F\fR, \fB\-\-format\fR \fBpng\fR\[or]\fBjpg\fR
|
35
|
+
Screenshot image file format to use\. Defaults to \fBpng\fR if not given\.
|
36
|
+
.TP
|
37
|
+
\fB\-d\fR, \fB\-\-directory\fR \fIDIR\fP
|
38
|
+
Directory to save images to\. Defaults to the current working directory if not
|
39
|
+
given\.
|
40
|
+
.TP
|
41
|
+
\fB\-f\fR, \fB\-\-full\fR
|
42
|
+
Screenshots the full page\.
|
43
|
+
.TP
|
44
|
+
\fB\-C\fR, \fB\-\-css\-path\fR \fICSSPath\fP
|
45
|
+
The CSSpath selector to screenshot\.
|
46
|
+
.TP
|
47
|
+
\fB\-h\fR, \fB\-\-help\fR
|
48
|
+
Print help information
|
49
|
+
.SH AUTHOR
|
50
|
+
.PP
|
51
|
+
Postmodern
|
52
|
+
.MT postmodern\.mod3\[at]gmail\.com
|
53
|
+
.ME
|
54
|
+
.SH SEE ALSO
|
55
|
+
.PP
|
56
|
+
.BR ronin\-web\-browser (1)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# ronin-web-screenshot 1 "2023-05-01" Ronin Web "User Manuals"
|
2
|
+
|
3
|
+
## NAME
|
4
|
+
|
5
|
+
ronin-web-screenshot - Screenshots one or more URLs
|
6
|
+
|
7
|
+
## SYNOPSIS
|
8
|
+
|
9
|
+
`ronin-web-screenshot` [*options*] {*URL* [...] \| `--file` *FILE*}
|
10
|
+
|
11
|
+
## DESCRIPTION
|
12
|
+
|
13
|
+
Screenshots one or more URLs.
|
14
|
+
|
15
|
+
## ARGUMENTS
|
16
|
+
|
17
|
+
*URL*
|
18
|
+
: A `https://` or `http://` URL of the web page to diff.
|
19
|
+
|
20
|
+
## OPTIONS
|
21
|
+
|
22
|
+
`-B`, `--browser` *NAME*\|*PATH*
|
23
|
+
: The browser name or path to execute.
|
24
|
+
|
25
|
+
`-W`, `--width` *WIDTH*
|
26
|
+
: Sets the width of the browser viewport. Defaults to `1024` if not given.
|
27
|
+
.
|
28
|
+
`-H`, `--height` *HEIGHT*
|
29
|
+
: Sets the height of the browser viewport. Defaults to `768` if not given.
|
30
|
+
|
31
|
+
`-f`, `--file` *FILE*
|
32
|
+
: Input file to read URLs from.
|
33
|
+
|
34
|
+
`-F`, `--format` `png`\|`jpg`
|
35
|
+
: Screenshot image file format to use. Defaults to `png` if not given.
|
36
|
+
|
37
|
+
`-d`, `--directory` *DIR*
|
38
|
+
: Directory to save images to. Defaults to the current working directory if not
|
39
|
+
given.
|
40
|
+
|
41
|
+
`-f`, `--full`
|
42
|
+
: Screenshots the full page.
|
43
|
+
|
44
|
+
`-C`, `--css-path` *CSSPath*
|
45
|
+
: The CSSpath selector to screenshot.
|
46
|
+
|
47
|
+
`-h`, `--help`
|
48
|
+
: Print help information
|
49
|
+
|
50
|
+
## AUTHOR
|
51
|
+
|
52
|
+
Postmodern <postmodern.mod3@gmail.com>
|
53
|
+
|
54
|
+
## SEE ALSO
|
55
|
+
|
56
|
+
[ronin-web-browser](ronin-web-browser.1.md)
|
data/man/ronin-web-server.1
CHANGED
@@ -1,59 +1,45 @@
|
|
1
|
-
.\" Generated by kramdown-man 0.1
|
1
|
+
.\" Generated by kramdown-man 1.0.1
|
2
2
|
.\" https://github.com/postmodern/kramdown-man#readme
|
3
3
|
.TH ronin-web-server 1 "2022-01-01" Ronin Web "User Manuals"
|
4
|
-
.
|
4
|
+
.SH NAME
|
5
|
+
.PP
|
6
|
+
ronin\-web\-server \- Starts a web server
|
5
7
|
.SH SYNOPSIS
|
6
|
-
.
|
7
|
-
|
8
|
-
\fBronin-web-server\fR \[lB]\fIoptions\fP\[rB]
|
9
|
-
.LP
|
8
|
+
.PP
|
9
|
+
\fBronin\-web\-server\fR \[lB]\fIoptions\fP\[rB]
|
10
10
|
.SH DESCRIPTION
|
11
|
-
.LP
|
12
11
|
.PP
|
13
12
|
Starts a web server\.
|
14
|
-
.LP
|
15
13
|
.SH OPTIONS
|
16
|
-
.LP
|
17
14
|
.TP
|
18
|
-
\fB
|
15
|
+
\fB\-H\fR, \fB\-\-host\fR \fIHOST\fP
|
19
16
|
Host name or IP to bind to\. Defaults to \fBlocalhost\fR\.
|
20
|
-
.LP
|
21
17
|
.TP
|
22
|
-
\fB
|
18
|
+
\fB\-p\fR, \fB\-\-port\fR \fIPORT\fP
|
23
19
|
Port number to listen on\. Defaults to \fB8000\fR\.
|
24
|
-
.LP
|
25
20
|
.TP
|
26
|
-
\fB
|
21
|
+
\fB\-A\fR, \fB\-\-basic\-auth\fR \fIUSER\fP:\fIPASSWORD\fP
|
27
22
|
Sets up Basic\-Authentication with the given \fIUSER\fP and \fIPASSWORD\fP\.
|
28
|
-
.LP
|
29
23
|
.TP
|
30
|
-
\fB
|
24
|
+
\fB\-d\fR, \fB\-\-dir\fR \[sl]\fIPATH\fP:\fIDIR\fP
|
31
25
|
Mounts a directory to the given \fIPATH\fP\.
|
32
|
-
.LP
|
33
26
|
.TP
|
34
|
-
\fB
|
27
|
+
\fB\-f\fR, \fB\-\-file\fR \[sl]\fIPATH\fP:\fIFILE\fP
|
35
28
|
Mounts a file to the given \fIPATH\fP\.
|
36
|
-
.LP
|
37
29
|
.TP
|
38
|
-
\fB
|
30
|
+
\fB\-r\fR, \fB\-\-root\fR \fIDIR\fP
|
39
31
|
Root directory to serve\.
|
40
|
-
.LP
|
41
32
|
.TP
|
42
|
-
\fB
|
33
|
+
\fB\-R\fR, \fB\-\-redirect\fR \[sl]\fIPATH\fP:\fIURL\fP
|
43
34
|
Registers a \fB302 Found\fR redirect at the given \fIPATH\fP
|
44
|
-
.LP
|
45
35
|
.TP
|
46
|
-
\fB
|
36
|
+
\fB\-h\fR, \fB\-\-help\fR
|
47
37
|
Print help information
|
48
|
-
.LP
|
49
38
|
.SH AUTHOR
|
50
|
-
.LP
|
51
39
|
.PP
|
52
40
|
Postmodern
|
53
41
|
.MT postmodern\.mod3\[at]gmail\.com
|
54
42
|
.ME
|
55
|
-
.LP
|
56
43
|
.SH SEE ALSO
|
57
|
-
.LP
|
58
44
|
.PP
|
59
|
-
ronin\-web\-proxy(1)
|
45
|
+
.BR ronin\-web\-proxy (1)
|
data/man/ronin-web-server.1.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# ronin-web-server 1 "2022-01-01" Ronin Web "User Manuals"
|
2
2
|
|
3
|
+
## NAME
|
4
|
+
|
5
|
+
ronin-web-server - Starts a web server
|
6
|
+
|
3
7
|
## SYNOPSIS
|
4
8
|
|
5
9
|
`ronin-web-server` [*options*]
|
@@ -11,28 +15,28 @@ Starts a web server.
|
|
11
15
|
## OPTIONS
|
12
16
|
|
13
17
|
`-H`, `--host` *HOST*
|
14
|
-
|
18
|
+
: Host name or IP to bind to. Defaults to `localhost`.
|
15
19
|
|
16
20
|
`-p`, `--port` *PORT*
|
17
|
-
|
21
|
+
: Port number to listen on. Defaults to `8000`.
|
18
22
|
|
19
23
|
`-A`, `--basic-auth` *USER*:*PASSWORD*
|
20
|
-
|
24
|
+
: Sets up Basic-Authentication with the given *USER* and *PASSWORD*.
|
21
25
|
|
22
26
|
`-d`, `--dir` /*PATH*:*DIR*
|
23
|
-
|
27
|
+
: Mounts a directory to the given *PATH*.
|
24
28
|
|
25
29
|
`-f`, `--file` /*PATH*:*FILE*
|
26
|
-
|
30
|
+
: Mounts a file to the given *PATH*.
|
27
31
|
|
28
32
|
`-r`, `--root` *DIR*
|
29
|
-
|
33
|
+
: Root directory to serve.
|
30
34
|
|
31
35
|
`-R`, `--redirect` /*PATH*:*URL*
|
32
|
-
|
36
|
+
: Registers a `302 Found` redirect at the given *PATH*
|
33
37
|
|
34
38
|
`-h`, `--help`
|
35
|
-
|
39
|
+
: Print help information
|
36
40
|
|
37
41
|
## AUTHOR
|
38
42
|
|
@@ -40,4 +44,4 @@ Postmodern <postmodern.mod3@gmail.com>
|
|
40
44
|
|
41
45
|
## SEE ALSO
|
42
46
|
|
43
|
-
ronin-web-proxy(1)
|
47
|
+
[ronin-web-proxy](ronin-web-proxy.1.md)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
.\" Generated by kramdown-man 1.0.1
|
2
|
+
.\" https://github.com/postmodern/kramdown-man#readme
|
3
|
+
.TH ronin-web-session-cookie 1 "2023-03-01" Ronin "User Manuals"
|
4
|
+
.SH NAME
|
5
|
+
.PP
|
6
|
+
ronin\-web\-session\-cookie \- Parses and deserializes various session cookie formats
|
7
|
+
.SH SYNOPSIS
|
8
|
+
.PP
|
9
|
+
\fBronin\-web session\-cookie\fR \[lB]\fIoptions\fP\[rB] \[lC]\fIURL\fP \[or] \fISTRING\fP\[rC]
|
10
|
+
.SH DESCRIPTION
|
11
|
+
.PP
|
12
|
+
Parses and deserializes various session cookie formats\. Currently supports
|
13
|
+
Python Django (JSON and Pickle), JSON Web Token (JWT), and Ruby Rack session
|
14
|
+
cookies\.
|
15
|
+
.SH ARGUMENTS
|
16
|
+
.TP
|
17
|
+
\fIURL\fP
|
18
|
+
The \fBhttp:\[sl]\[sl]\fR or \fBhttps:\[sl]\[sl]\fR URL to request and extract the session cookie
|
19
|
+
from\.
|
20
|
+
.TP
|
21
|
+
\fISTRING\fP
|
22
|
+
The session cookie string to parse\.
|
23
|
+
.SH OPTIONS
|
24
|
+
.TP
|
25
|
+
\fB\-F\fR, \fB\-\-format\fR \[lB]\fBruby\fR \[or] \fBjson\fR \[or] \fByaml\fR\[rB]
|
26
|
+
The format to print the session cookie params\. Defaults to \fBruby\fR if not
|
27
|
+
given\.
|
28
|
+
.TP
|
29
|
+
\fB\-v\fR, \fB\-\-verbose\fR
|
30
|
+
Enables verbose output\.
|
31
|
+
.TP
|
32
|
+
\fB\-h\fR, \fB\-\-help\fR
|
33
|
+
Print help information\.
|
34
|
+
.SH AUTHOR
|
35
|
+
.PP
|
36
|
+
Postmodern
|
37
|
+
.MT postmodern\.mod3\[at]gmail\.com
|
38
|
+
.ME
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# ronin-web-session-cookie 1 "2023-03-01" Ronin "User Manuals"
|
2
|
+
|
3
|
+
## NAME
|
4
|
+
|
5
|
+
ronin-web-session-cookie - Parses and deserializes various session cookie formats
|
6
|
+
|
7
|
+
## SYNOPSIS
|
8
|
+
|
9
|
+
`ronin-web session-cookie` [*options*] {*URL* \| *STRING*}
|
10
|
+
|
11
|
+
## DESCRIPTION
|
12
|
+
|
13
|
+
Parses and deserializes various session cookie formats. Currently supports
|
14
|
+
Python Django (JSON and Pickle), JSON Web Token (JWT), and Ruby Rack session
|
15
|
+
cookies.
|
16
|
+
|
17
|
+
## ARGUMENTS
|
18
|
+
|
19
|
+
*URL*
|
20
|
+
: The `http://` or `https://` URL to request and extract the session cookie
|
21
|
+
from.
|
22
|
+
|
23
|
+
*STRING*
|
24
|
+
: The session cookie string to parse.
|
25
|
+
|
26
|
+
## OPTIONS
|
27
|
+
|
28
|
+
`-F`, `--format` [`ruby` \| `json` \| `yaml`]
|
29
|
+
: The format to print the session cookie params. Defaults to `ruby` if not
|
30
|
+
given.
|
31
|
+
|
32
|
+
`-v`, `--verbose`
|
33
|
+
: Enables verbose output.
|
34
|
+
|
35
|
+
`-h`, `--help`
|
36
|
+
: Print help information.
|
37
|
+
|
38
|
+
## AUTHOR
|
39
|
+
|
40
|
+
Postmodern <postmodern.mod3@gmail.com>
|
41
|
+
|