puppet-lint-halyard 1.1.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +10 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +210 -0
- data/Rakefile +14 -0
- data/bin/puppet-lint +7 -0
- data/lib/puppet-lint.rb +214 -0
- data/lib/puppet-lint/bin.rb +79 -0
- data/lib/puppet-lint/checkplugin.rb +176 -0
- data/lib/puppet-lint/checks.rb +91 -0
- data/lib/puppet-lint/configuration.rb +153 -0
- data/lib/puppet-lint/data.rb +521 -0
- data/lib/puppet-lint/lexer.rb +373 -0
- data/lib/puppet-lint/lexer/token.rb +101 -0
- data/lib/puppet-lint/monkeypatches.rb +2 -0
- data/lib/puppet-lint/monkeypatches/string_percent.rb +52 -0
- data/lib/puppet-lint/monkeypatches/string_prepend.rb +13 -0
- data/lib/puppet-lint/optparser.rb +118 -0
- data/lib/puppet-lint/plugins.rb +74 -0
- data/lib/puppet-lint/plugins/check_classes.rb +285 -0
- data/lib/puppet-lint/plugins/check_comments.rb +55 -0
- data/lib/puppet-lint/plugins/check_conditionals.rb +65 -0
- data/lib/puppet-lint/plugins/check_documentation.rb +31 -0
- data/lib/puppet-lint/plugins/check_nodes.rb +29 -0
- data/lib/puppet-lint/plugins/check_resources.rb +194 -0
- data/lib/puppet-lint/plugins/check_strings.rb +174 -0
- data/lib/puppet-lint/plugins/check_variables.rb +19 -0
- data/lib/puppet-lint/plugins/check_whitespace.rb +170 -0
- data/lib/puppet-lint/tasks/puppet-lint.rb +91 -0
- data/lib/puppet-lint/version.rb +3 -0
- data/puppet-lint.gemspec +24 -0
- data/spec/fixtures/test/manifests/fail.pp +2 -0
- data/spec/fixtures/test/manifests/ignore.pp +1 -0
- data/spec/fixtures/test/manifests/ignore_multiple_block.pp +6 -0
- data/spec/fixtures/test/manifests/ignore_multiple_line.pp +2 -0
- data/spec/fixtures/test/manifests/ignore_reason.pp +1 -0
- data/spec/fixtures/test/manifests/init.pp +3 -0
- data/spec/fixtures/test/manifests/malformed.pp +1 -0
- data/spec/fixtures/test/manifests/url_interpolation.pp +12 -0
- data/spec/fixtures/test/manifests/warning.pp +2 -0
- data/spec/puppet-lint/bin_spec.rb +326 -0
- data/spec/puppet-lint/configuration_spec.rb +56 -0
- data/spec/puppet-lint/ignore_overrides_spec.rb +109 -0
- data/spec/puppet-lint/lexer/token_spec.rb +18 -0
- data/spec/puppet-lint/lexer_spec.rb +783 -0
- data/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb +105 -0
- data/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb +35 -0
- data/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb +33 -0
- data/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb +76 -0
- data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +73 -0
- data/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb +25 -0
- data/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb +196 -0
- data/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +84 -0
- data/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb +98 -0
- data/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb +36 -0
- data/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb +52 -0
- data/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb +146 -0
- data/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb +100 -0
- data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +55 -0
- data/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb +89 -0
- data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +113 -0
- data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb +216 -0
- data/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb +199 -0
- data/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb +114 -0
- data/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb +62 -0
- data/spec/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb +129 -0
- data/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb +17 -0
- data/spec/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb +73 -0
- data/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb +37 -0
- data/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb +21 -0
- data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +54 -0
- data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +524 -0
- data/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb +101 -0
- data/spec/puppet-lint_spec.rb +20 -0
- data/spec/spec_helper.rb +129 -0
- metadata +229 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'slash_comments' do
|
4
|
+
let(:msg) { '// comment found' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'slash comments' do
|
8
|
+
let(:code) { "// foo" }
|
9
|
+
|
10
|
+
it 'should only detect a single problem' do
|
11
|
+
expect(problems).to have(1).problem
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should create a warning' do
|
15
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with fix enabled' do
|
21
|
+
before do
|
22
|
+
PuppetLint.configuration.fix = true
|
23
|
+
end
|
24
|
+
|
25
|
+
after do
|
26
|
+
PuppetLint.configuration.fix = false
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'slash comments' do
|
30
|
+
let(:code) { '// foo' }
|
31
|
+
|
32
|
+
it 'should only detect a single problem' do
|
33
|
+
expect(problems).to have(1).problem
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should fix the manifest' do
|
37
|
+
expect(problems).to contain_fixed(msg).on_line(1).in_column(1)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should replace the double slash with a hash' do
|
41
|
+
expect(manifest).to eq("# foo")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'star_comments' do
|
4
|
+
let(:msg) { '/* */ comment found' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'multiline comment w/ one line of content' do
|
8
|
+
let(:code) { "
|
9
|
+
/* foo
|
10
|
+
*/
|
11
|
+
"}
|
12
|
+
|
13
|
+
it 'should only detect a single problem' do
|
14
|
+
expect(problems).to have(1).problem
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should create a warning' do
|
18
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(9)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with fix enabled' do
|
24
|
+
before do
|
25
|
+
PuppetLint.configuration.fix = true
|
26
|
+
end
|
27
|
+
|
28
|
+
after do
|
29
|
+
PuppetLint.configuration.fix = false
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'multiline comment w/ one line of content' do
|
33
|
+
let(:code) { "
|
34
|
+
/* foo
|
35
|
+
*/
|
36
|
+
"}
|
37
|
+
|
38
|
+
let(:fixed) { "
|
39
|
+
# foo
|
40
|
+
"}
|
41
|
+
|
42
|
+
it 'should only detect a single problem' do
|
43
|
+
expect(problems).to have(1).problem
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should create a warning' do
|
47
|
+
expect(problems).to contain_fixed(msg).on_line(2).in_column(9)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should convert the multiline comment' do
|
51
|
+
expect(manifest).to eq(fixed)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'multiline comment w/ multiple line of content' do
|
56
|
+
let(:code) { "
|
57
|
+
/* foo
|
58
|
+
* bar
|
59
|
+
* baz
|
60
|
+
*/
|
61
|
+
notify { 'foo': }
|
62
|
+
"}
|
63
|
+
|
64
|
+
let(:fixed) { "
|
65
|
+
# foo
|
66
|
+
# bar
|
67
|
+
# baz
|
68
|
+
notify { 'foo': }
|
69
|
+
"}
|
70
|
+
|
71
|
+
it 'should only detect a single problem' do
|
72
|
+
expect(problems).to have(1).problem
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should create a warning' do
|
76
|
+
expect(problems).to contain_fixed(msg).on_line(2).in_column(9)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should convert the multiline comment' do
|
80
|
+
expect(manifest).to eq(fixed)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'case_without_default' do
|
4
|
+
let(:msg) { 'case statement without a default case' }
|
5
|
+
|
6
|
+
context 'case statement with a default case' do
|
7
|
+
let(:code) { "
|
8
|
+
case $foo {
|
9
|
+
bar: { }
|
10
|
+
default: { }
|
11
|
+
}"
|
12
|
+
}
|
13
|
+
|
14
|
+
it 'should not detect any problems' do
|
15
|
+
expect(problems).to have(0).problems
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'case statement without a default case' do
|
20
|
+
let(:code) { "
|
21
|
+
case $foo {
|
22
|
+
bar: { }
|
23
|
+
baz: { }
|
24
|
+
}"
|
25
|
+
}
|
26
|
+
|
27
|
+
it 'should only detect a single problem' do
|
28
|
+
expect(problems).to have(1).problem
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should create a warning' do
|
32
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(7)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'nested case statements without a default case on the outermost' do
|
37
|
+
let(:code) { "
|
38
|
+
case $foo {
|
39
|
+
case $foop {
|
40
|
+
bar: {}
|
41
|
+
default: {}
|
42
|
+
}
|
43
|
+
}"
|
44
|
+
}
|
45
|
+
|
46
|
+
it 'should only detect a single problem' do
|
47
|
+
expect(problems).to have(1).problem
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should create a warning' do
|
51
|
+
expect(problems).to contain_warning(msg)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'three nested case statements with two missing default cases' do
|
56
|
+
let(:code) { "
|
57
|
+
case $foo {
|
58
|
+
case $foop {
|
59
|
+
bar: {}
|
60
|
+
case $woop {
|
61
|
+
baz: {}
|
62
|
+
}
|
63
|
+
default: {}
|
64
|
+
}
|
65
|
+
}"
|
66
|
+
}
|
67
|
+
|
68
|
+
it 'should detect two problems' do
|
69
|
+
expect(problems).to have(2).problems
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should create two warnings' do
|
73
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(7)
|
74
|
+
expect(problems).to contain_warning(msg).on_line(5).in_column(4)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'issue-117' do
|
79
|
+
let(:code) { "
|
80
|
+
$mem = inline_template('<%
|
81
|
+
mem,unit = scope.lookupvar(\'::memorysize\').split
|
82
|
+
mem = mem.to_f
|
83
|
+
# Normalize mem to bytes
|
84
|
+
case unit
|
85
|
+
when nil: mem *= (1<<0)
|
86
|
+
when \'kB\': mem *= (1<<10)
|
87
|
+
when \'MB\': mem *= (1<<20)
|
88
|
+
when \'GB\': mem *= (1<<30)
|
89
|
+
when \'TB\': mem *= (1<<40)
|
90
|
+
end
|
91
|
+
%><%= mem.to_i %>')
|
92
|
+
"}
|
93
|
+
|
94
|
+
it 'should not detect any problems' do
|
95
|
+
expect(problems).to have(0).problems
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'selector_inside_resource' do
|
4
|
+
let(:msg) { 'selector inside resource block' }
|
5
|
+
|
6
|
+
context 'resource with a selector' do
|
7
|
+
let(:code) { "
|
8
|
+
file { 'foo':
|
9
|
+
ensure => $bar ? {
|
10
|
+
true => present,
|
11
|
+
default => absent,
|
12
|
+
},
|
13
|
+
}"
|
14
|
+
}
|
15
|
+
|
16
|
+
it 'should only detect a single problem' do
|
17
|
+
expect(problems).to have(1).problem
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should create a warning' do
|
21
|
+
expect(problems).to contain_warning(msg).on_line(3).in_column(16)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'resource with a variable as a attr value' do
|
26
|
+
let(:code) { "
|
27
|
+
file { 'foo',
|
28
|
+
ensure => $bar,
|
29
|
+
}"
|
30
|
+
}
|
31
|
+
|
32
|
+
it 'should not detect any problems' do
|
33
|
+
expect(problems).to have(0).problems
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'documentation' do
|
4
|
+
let(:class_msg) { 'class not documented' }
|
5
|
+
let(:define_msg) { 'defined type not documented' }
|
6
|
+
|
7
|
+
describe 'undocumented class' do
|
8
|
+
let(:code) { "class test {}" }
|
9
|
+
|
10
|
+
it 'should only detect a single problem' do
|
11
|
+
expect(problems).to have(1).problem
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should create a warning' do
|
15
|
+
expect(problems).to contain_warning(class_msg).on_line(1).in_column(1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'documented class' do
|
20
|
+
let(:code) { "
|
21
|
+
# foo
|
22
|
+
class test {}
|
23
|
+
"}
|
24
|
+
|
25
|
+
it 'should not detect any problems' do
|
26
|
+
expect(problems).to have(0).problems
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'undocumented defined type' do
|
31
|
+
let(:code) { "define test {}" }
|
32
|
+
|
33
|
+
it 'should only detect a single problem' do
|
34
|
+
expect(problems).to have(1).problem
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should create a warning' do
|
38
|
+
expect(problems).to contain_warning(define_msg).on_line(1).in_column(1)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'documented defined type' do
|
43
|
+
let(:code) { "
|
44
|
+
# foo
|
45
|
+
define test {}
|
46
|
+
"}
|
47
|
+
|
48
|
+
it 'should not detect any problems' do
|
49
|
+
expect(problems).to have(0).problems
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'unquoted_node_name' do
|
4
|
+
let(:msg) { 'unquoted node name found' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'unquoted node name' do
|
8
|
+
let(:code) { "node foo { }" }
|
9
|
+
|
10
|
+
it 'should only detect a single problem' do
|
11
|
+
expect(problems).to have(1).problem
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should create a warning' do
|
15
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(6)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'default node' do
|
20
|
+
let(:code) { "node default { }" }
|
21
|
+
|
22
|
+
it 'should not detect any problems' do
|
23
|
+
expect(problems).to have(0).problems
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'single quoted node name' do
|
28
|
+
let(:code) { "node 'foo' { }" }
|
29
|
+
|
30
|
+
it 'should not detect any problems' do
|
31
|
+
expect(problems).to have(0).problems
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'regex node name' do
|
36
|
+
let(:code) { "node /foo/ { }" }
|
37
|
+
|
38
|
+
it 'should not detect any problems' do
|
39
|
+
expect(problems).to have(0).problems
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'multiple bare node names' do
|
44
|
+
let(:code) { "node foo, bar, baz { }" }
|
45
|
+
|
46
|
+
it 'should detect 3 problems' do
|
47
|
+
expect(problems).to have(3).problems
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should create 3 warnings' do
|
51
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(6)
|
52
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(11)
|
53
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(16)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'mixed node name types' do
|
58
|
+
let(:code) { "node foo, 'bar', baz { }" }
|
59
|
+
|
60
|
+
it 'should detect 2 problems' do
|
61
|
+
expect(problems).to have(2).problems
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should create 2 warnings' do
|
65
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(6)
|
66
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(18)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'multiple node blocks' do
|
71
|
+
let(:code) { "node foo { } node bar { }" }
|
72
|
+
|
73
|
+
it 'should detect 2 problems' do
|
74
|
+
expect(problems).to have(2).problems
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should create 2 warnings' do
|
78
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(6)
|
79
|
+
expect(problems).to contain_warning(msg).on_line(1).in_column(19)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'with fix enabled' do
|
85
|
+
before do
|
86
|
+
PuppetLint.configuration.fix = true
|
87
|
+
end
|
88
|
+
|
89
|
+
after do
|
90
|
+
PuppetLint.configuration.fix = false
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'unquoted node name' do
|
94
|
+
let(:code) { "node foo { }" }
|
95
|
+
|
96
|
+
it 'should only detect a single problem' do
|
97
|
+
expect(problems).to have(1).problem
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should fix the manifest' do
|
101
|
+
expect(problems).to contain_fixed(msg).on_line(1).in_column(6)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should quote the node name' do
|
105
|
+
expect(manifest).to eq("node 'foo' { }")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'multiple bare node names' do
|
110
|
+
let(:code) { "node foo, bar, baz { }" }
|
111
|
+
let(:fixed) { "node 'foo', 'bar', 'baz' { }" }
|
112
|
+
|
113
|
+
it 'should detect 3 problems' do
|
114
|
+
expect(problems).to have(3).problems
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should fix the 3 problems' do
|
118
|
+
expect(problems).to contain_fixed(msg).on_line(1).in_column(6)
|
119
|
+
expect(problems).to contain_fixed(msg).on_line(1).in_column(11)
|
120
|
+
expect(problems).to contain_fixed(msg).on_line(1).in_column(16)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should quote all three node names' do
|
124
|
+
expect(manifest).to eq(fixed)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'mixed node name types' do
|
129
|
+
let(:code) { "node foo, 'bar', baz { }" }
|
130
|
+
let(:fixed) { "node 'foo', 'bar', 'baz' { }" }
|
131
|
+
|
132
|
+
it 'should detect 2 problems' do
|
133
|
+
expect(problems).to have(2).problems
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should fix the 2 problems' do
|
137
|
+
expect(problems).to contain_fixed(msg).on_line(1).in_column(6)
|
138
|
+
expect(problems).to contain_fixed(msg).on_line(1).in_column(18)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should quote the 2 unquoted node names' do
|
142
|
+
expect(manifest).to eq(fixed)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|