nasl-pedant 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +14 -2
- data/lib/pedant/checks/plugin_type_not_specified.rb +2 -2
- data/lib/pedant/checks/script_family_not_specified.rb +87 -0
- data/lib/pedant/test.rb +4 -0
- data/lib/pedant/version.rb +1 -1
- data/pedant.gemspec +7 -5
- data/test/unit/checks/{conditional_or_loop_is_empty.rb → test_conditional_or_loop_is_empty.rb} +0 -0
- data/test/unit/checks/{contains_ip_address_literals.rb → test_contains_ip_address_literals.rb} +0 -0
- data/test/unit/checks/{contains_no_carriage_returns.rb → test_contains_no_carriage_returns.rb} +0 -0
- data/test/unit/checks/{contains_no_tabs.rb → test_contains_no_tabs.rb} +0 -0
- data/test/unit/checks/{contains_registration_section.rb → test_contains_registration_section.rb} +0 -0
- data/test/unit/checks/{contains_unreachable_code.rb → test_contains_unreachable_code.rb} +0 -0
- data/test/unit/checks/{ends_with_newline.rb → test_ends_with_newline.rb} +0 -0
- data/test/unit/checks/{plugin_type_not_specified.rb → test_plugin_type_not_specified.rb} +2 -2
- data/test/unit/checks/test_script_family_not_specified.rb +86 -0
- metadata +50 -27
data/Rakefile
CHANGED
@@ -1,8 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
|
1
3
|
require 'bundler/gem_tasks'
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/clean'
|
2
6
|
require 'rake/testtask'
|
3
7
|
|
4
8
|
Rake::TestTask.new do |t|
|
5
9
|
t.libs << 'test'
|
6
|
-
t.test_files = FileList['test/**/
|
7
|
-
t.verbose = true
|
10
|
+
t.test_files = FileList['test/**/test_*.rb']
|
8
11
|
end
|
12
|
+
|
13
|
+
desc "Produce a fully-functional application."
|
14
|
+
task :compile => :test
|
15
|
+
|
16
|
+
task :build => :compile do
|
17
|
+
system "gem build pedant.gemspec"
|
18
|
+
end
|
19
|
+
|
20
|
+
task :default => :compile
|
@@ -1,5 +1,5 @@
|
|
1
1
|
################################################################################
|
2
|
-
# Copyright (c) 2011, Mak Kolybabi
|
2
|
+
# Copyright (c) 2011-2012, Mak Kolybabi
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
5
5
|
# Redistribution and use in source and binary forms, with or without
|
@@ -52,7 +52,7 @@ module Pedant
|
|
52
52
|
next if !arg.is_a? Nasl::String
|
53
53
|
|
54
54
|
# Ensure that the plugin type is valid.
|
55
|
-
unless ['combined', 'local', 'remote'].include? arg.text
|
55
|
+
unless ['combined', 'local', 'reputation', 'remote', 'settings', 'thirdparty'].include? arg.text
|
56
56
|
report(:info, "Plugin is of unknown type #{arg.text}:\n#{arg.context(node)}")
|
57
57
|
return fail
|
58
58
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2012, Mak Kolybabi
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
################################################################################
|
26
|
+
|
27
|
+
module Pedant
|
28
|
+
class CheckScriptFamilyNotSpecified < Check
|
29
|
+
def self.requires
|
30
|
+
super + [:main, :trees]
|
31
|
+
end
|
32
|
+
|
33
|
+
def run
|
34
|
+
# This check only applies to plugins.
|
35
|
+
return skip unless @kb[:main].extname == '.nasl'
|
36
|
+
|
37
|
+
args = []
|
38
|
+
|
39
|
+
tree = @kb[:trees][@kb[:main]]
|
40
|
+
|
41
|
+
tree.all(:Call).each do |node|
|
42
|
+
next unless node.name.name == 'script_family'
|
43
|
+
next if node.args.empty?
|
44
|
+
next unless node.args.first.expr.is_a? Nasl::String
|
45
|
+
|
46
|
+
# Pull out argument
|
47
|
+
arg = node.args.first.expr
|
48
|
+
|
49
|
+
# Ensure that the script family is valid.
|
50
|
+
unless ["AIX Local Security Checks", "Backdoors", "Brute force attacks",
|
51
|
+
"CentOS Local Security Checks", "CGI abuses", "CISCO", "Databases",
|
52
|
+
"Debian Local Security Checks", "Default Unix Accounts",
|
53
|
+
"Denial of Service", "DNS", "Fedora Local Security Checks",
|
54
|
+
"Finger abuses", "Firewalls", "FTP", "Gain a shell remotely",
|
55
|
+
"General", "Gentoo Local Security Checks", "HP-UX Local Security Checks",
|
56
|
+
"MacOS X Local Security Checks", "Mandriva Local Security Checks",
|
57
|
+
"Misc.", "Netware", "Peer-To-Peer File Sharing", "Port scanners",
|
58
|
+
"Red Hat Local Security Checks", "RPC", "SCADA", "Service detection",
|
59
|
+
"Settings", "Slackware Local Security Checks", "SMTP problems",
|
60
|
+
"SNMP", "Solaris Local Security Checks", "SuSE Local Security Checks",
|
61
|
+
"Ubuntu Local Security Checks", "VMware ESX Local Security Checks",
|
62
|
+
"Web Servers", "Windows"].include? arg.text
|
63
|
+
|
64
|
+
report(:info, "Plugin belongs to unknown #{arg.text}:\n#{arg.context(node)}")
|
65
|
+
return fail
|
66
|
+
end
|
67
|
+
|
68
|
+
args << [arg, node]
|
69
|
+
end
|
70
|
+
|
71
|
+
case args.length
|
72
|
+
when 0
|
73
|
+
report(:error, "Plugin does not specify a script_family.")
|
74
|
+
fail
|
75
|
+
when 1
|
76
|
+
arg = args.first[0]
|
77
|
+
call = args.first[1]
|
78
|
+
report(:info, "Plugin belongs to script family #{arg.text}:\n#{arg.context(call)}")
|
79
|
+
pass
|
80
|
+
else
|
81
|
+
report(:error, "Plugin specifies multiple script family's.")
|
82
|
+
args.each { |arg, call| report(:error, arg.context(call)) }
|
83
|
+
fail
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/pedant/test.rb
CHANGED
data/lib/pedant/version.rb
CHANGED
data/pedant.gemspec
CHANGED
@@ -1,25 +1,27 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
|
3
4
|
require 'pedant/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
6
7
|
s.name = 'nasl-pedant'
|
7
8
|
s.version = Pedant::VERSION
|
9
|
+
s.license = 'BSD'
|
10
|
+
s.homepage = 'http://github.com/tenable/pedant'
|
11
|
+
s.summary = 'A static analysis framework for the Nessus Attack Scripting Language.'
|
12
|
+
|
8
13
|
s.authors = ['Mak Kolybabi']
|
9
14
|
s.email = ['mak@kolybabi.com']
|
10
|
-
s.homepage = 'http://github.com/mogigoma/pedant'
|
11
|
-
s.summary = %q{A static analysis framework for the Nessus Attack Scripting Language.}
|
12
15
|
|
13
16
|
s.rubyforge_project = 'nasl-pedant'
|
14
17
|
|
15
18
|
s.files = `git ls-files`.split("\n")
|
16
|
-
s.test_files = `git ls-files --
|
19
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
17
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
21
|
s.require_paths = ['lib']
|
19
22
|
|
20
23
|
s.add_development_dependency 'rake'
|
21
|
-
s.add_development_dependency 'minitest'
|
22
24
|
|
23
25
|
s.add_runtime_dependency 'rainbow'
|
24
|
-
s.add_runtime_dependency 'nasl', '>= 0.0.
|
26
|
+
s.add_runtime_dependency 'nasl', '>= 0.0.7'
|
25
27
|
end
|
data/test/unit/checks/{conditional_or_loop_is_empty.rb → test_conditional_or_loop_is_empty.rb}
RENAMED
File without changes
|
data/test/unit/checks/{contains_ip_address_literals.rb → test_contains_ip_address_literals.rb}
RENAMED
File without changes
|
data/test/unit/checks/{contains_no_carriage_returns.rb → test_contains_no_carriage_returns.rb}
RENAMED
File without changes
|
File without changes
|
data/test/unit/checks/{contains_registration_section.rb → test_contains_registration_section.rb}
RENAMED
File without changes
|
File without changes
|
File without changes
|
@@ -1,5 +1,5 @@
|
|
1
1
|
################################################################################
|
2
|
-
# Copyright (c) 2011, Mak Kolybabi
|
2
|
+
# Copyright (c) 2011-2012, Mak Kolybabi
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
5
5
|
# Redistribution and use in source and binary forms, with or without
|
@@ -53,7 +53,7 @@ class TestPluginTypeNotSpecified < Test::Unit::TestCase
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def test_valid
|
56
|
-
['combined', 'local', 'remote'].each do |type|
|
56
|
+
['combined', 'local', 'reputation', 'remote', 'settings', 'thirdparty'].each do |type|
|
57
57
|
check(
|
58
58
|
:pass,
|
59
59
|
:CheckPluginTypeNotSpecified,
|
@@ -0,0 +1,86 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2012, Mak Kolybabi
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
################################################################################
|
26
|
+
|
27
|
+
class TestScriptFamilyNotSpecified < Test::Unit::TestCase
|
28
|
+
include Pedant::Test
|
29
|
+
|
30
|
+
def test_none
|
31
|
+
check(
|
32
|
+
:fail,
|
33
|
+
:CheckScriptFamilyNotSpecified,
|
34
|
+
%q||
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_one
|
39
|
+
check(
|
40
|
+
:pass,
|
41
|
+
:CheckScriptFamilyNotSpecified,
|
42
|
+
%q|script_family("Windows");|
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_many
|
47
|
+
check(
|
48
|
+
:fail,
|
49
|
+
:CheckScriptFamilyNotSpecified,
|
50
|
+
%q|script_family("Windows");| +
|
51
|
+
%q|script_family("FTP");|
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_valid
|
56
|
+
[
|
57
|
+
"AIX Local Security Checks", "Backdoors", "Brute force attacks",
|
58
|
+
"CentOS Local Security Checks", "CGI abuses", "CISCO", "Databases",
|
59
|
+
"Debian Local Security Checks", "Default Unix Accounts",
|
60
|
+
"Denial of Service", "DNS", "Fedora Local Security Checks",
|
61
|
+
"Finger abuses", "Firewalls", "FTP", "Gain a shell remotely",
|
62
|
+
"General", "Gentoo Local Security Checks", "HP-UX Local Security Checks",
|
63
|
+
"MacOS X Local Security Checks", "Mandriva Local Security Checks",
|
64
|
+
"Misc.", "Netware", "Peer-To-Peer File Sharing", "Port scanners",
|
65
|
+
"Red Hat Local Security Checks", "RPC", "SCADA", "Service detection",
|
66
|
+
"Settings", "Slackware Local Security Checks", "SMTP problems",
|
67
|
+
"SNMP", "Solaris Local Security Checks", "SuSE Local Security Checks",
|
68
|
+
"Ubuntu Local Security Checks", "VMware ESX Local Security Checks",
|
69
|
+
"Web Servers", "Windows"
|
70
|
+
].each do |type|
|
71
|
+
check(
|
72
|
+
:pass,
|
73
|
+
:CheckScriptFamilyNotSpecified,
|
74
|
+
%Q|script_family("#{type}");|
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_invalid
|
80
|
+
check(
|
81
|
+
:fail,
|
82
|
+
:CheckScriptFamilyNotSpecified,
|
83
|
+
%q|script_family("foo bar");|
|
84
|
+
)
|
85
|
+
end
|
86
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nasl-pedant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,21 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: minitest
|
27
|
-
requirement: &17202278900 !ruby/object:Gem::Requirement
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
25
|
none: false
|
29
26
|
requirements:
|
30
27
|
- - ! '>='
|
31
28
|
- !ruby/object:Gem::Version
|
32
29
|
version: '0'
|
33
|
-
type: :development
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *17202278900
|
36
30
|
- !ruby/object:Gem::Dependency
|
37
31
|
name: rainbow
|
38
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
39
33
|
none: false
|
40
34
|
requirements:
|
41
35
|
- - ! '>='
|
@@ -43,18 +37,28 @@ dependencies:
|
|
43
37
|
version: '0'
|
44
38
|
type: :runtime
|
45
39
|
prerelease: false
|
46
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
47
46
|
- !ruby/object:Gem::Dependency
|
48
47
|
name: nasl
|
49
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
50
49
|
none: false
|
51
50
|
requirements:
|
52
51
|
- - ! '>='
|
53
52
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.0.
|
53
|
+
version: 0.0.7
|
55
54
|
type: :runtime
|
56
55
|
prerelease: false
|
57
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.0.7
|
58
62
|
description:
|
59
63
|
email:
|
60
64
|
- mak@kolybabi.com
|
@@ -79,6 +83,7 @@ files:
|
|
79
83
|
- lib/pedant/checks/files_parse_without_error.rb
|
80
84
|
- lib/pedant/checks/parse_test_code.rb
|
81
85
|
- lib/pedant/checks/plugin_type_not_specified.rb
|
86
|
+
- lib/pedant/checks/script_family_not_specified.rb
|
82
87
|
- lib/pedant/cli.rb
|
83
88
|
- lib/pedant/command.rb
|
84
89
|
- lib/pedant/commands/check.rb
|
@@ -88,16 +93,18 @@ files:
|
|
88
93
|
- lib/pedant/version.rb
|
89
94
|
- pedant.gemspec
|
90
95
|
- test/test_helper.rb
|
91
|
-
- test/unit/checks/
|
92
|
-
- test/unit/checks/
|
93
|
-
- test/unit/checks/
|
94
|
-
- test/unit/checks/
|
95
|
-
- test/unit/checks/
|
96
|
-
- test/unit/checks/
|
97
|
-
- test/unit/checks/
|
98
|
-
- test/unit/checks/
|
99
|
-
|
100
|
-
|
96
|
+
- test/unit/checks/test_conditional_or_loop_is_empty.rb
|
97
|
+
- test/unit/checks/test_contains_ip_address_literals.rb
|
98
|
+
- test/unit/checks/test_contains_no_carriage_returns.rb
|
99
|
+
- test/unit/checks/test_contains_no_tabs.rb
|
100
|
+
- test/unit/checks/test_contains_registration_section.rb
|
101
|
+
- test/unit/checks/test_contains_unreachable_code.rb
|
102
|
+
- test/unit/checks/test_ends_with_newline.rb
|
103
|
+
- test/unit/checks/test_plugin_type_not_specified.rb
|
104
|
+
- test/unit/checks/test_script_family_not_specified.rb
|
105
|
+
homepage: http://github.com/tenable/pedant
|
106
|
+
licenses:
|
107
|
+
- BSD
|
101
108
|
post_install_message:
|
102
109
|
rdoc_options: []
|
103
110
|
require_paths:
|
@@ -108,16 +115,32 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
115
|
- - ! '>='
|
109
116
|
- !ruby/object:Gem::Version
|
110
117
|
version: '0'
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
hash: -4147162296377566136
|
111
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
122
|
none: false
|
113
123
|
requirements:
|
114
124
|
- - ! '>='
|
115
125
|
- !ruby/object:Gem::Version
|
116
126
|
version: '0'
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
hash: -4147162296377566136
|
117
130
|
requirements: []
|
118
131
|
rubyforge_project: nasl-pedant
|
119
|
-
rubygems_version: 1.8.
|
132
|
+
rubygems_version: 1.8.24
|
120
133
|
signing_key:
|
121
134
|
specification_version: 3
|
122
135
|
summary: A static analysis framework for the Nessus Attack Scripting Language.
|
123
|
-
test_files:
|
136
|
+
test_files:
|
137
|
+
- test/test_helper.rb
|
138
|
+
- test/unit/checks/test_conditional_or_loop_is_empty.rb
|
139
|
+
- test/unit/checks/test_contains_ip_address_literals.rb
|
140
|
+
- test/unit/checks/test_contains_no_carriage_returns.rb
|
141
|
+
- test/unit/checks/test_contains_no_tabs.rb
|
142
|
+
- test/unit/checks/test_contains_registration_section.rb
|
143
|
+
- test/unit/checks/test_contains_unreachable_code.rb
|
144
|
+
- test/unit/checks/test_ends_with_newline.rb
|
145
|
+
- test/unit/checks/test_plugin_type_not_specified.rb
|
146
|
+
- test/unit/checks/test_script_family_not_specified.rb
|