puppet-ghostbuster 0.9.0 → 1.1.0

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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/.github/dependabot.yml +17 -0
  3. data/.github/workflows/release.yml +33 -0
  4. data/.github/workflows/test.yml +57 -0
  5. data/.gitignore +5 -4
  6. data/.rubocop.yml +8 -0
  7. data/.rubocop_todo.yml +170 -0
  8. data/CHANGELOG.md +206 -96
  9. data/Gemfile +13 -1
  10. data/README.md +15 -5
  11. data/Rakefile +31 -9
  12. data/lib/puppet-ghostbuster/puppetdb.rb +24 -9
  13. data/lib/puppet-ghostbuster/version.rb +1 -1
  14. data/lib/puppet-lint/plugins/check_ghostbuster_classes.rb +4 -4
  15. data/lib/puppet-lint/plugins/check_ghostbuster_defines.rb +4 -5
  16. data/lib/puppet-lint/plugins/check_ghostbuster_facts.rb +14 -15
  17. data/lib/puppet-lint/plugins/check_ghostbuster_files.rb +9 -9
  18. data/lib/puppet-lint/plugins/check_ghostbuster_functions.rb +8 -8
  19. data/lib/puppet-lint/plugins/check_ghostbuster_hiera_files.rb +30 -31
  20. data/lib/puppet-lint/plugins/check_ghostbuster_templates.rb +13 -10
  21. data/lib/puppet-lint/plugins/check_ghostbuster_types.rb +4 -4
  22. data/puppet-ghostbuster.gemspec +21 -19
  23. data/spec/fixtures/hiera.yaml +11 -12
  24. data/spec/fixtures/modules/foo/lib/facter/bar.rb +2 -0
  25. data/spec/fixtures/modules/foo/lib/facter/baz.rb +2 -0
  26. data/spec/fixtures/modules/foo/lib/facter/foo.rb +2 -0
  27. data/spec/fixtures/modules/foo/lib/facter/multi.rb +2 -0
  28. data/spec/fixtures/modules/foo/lib/facter/quux.rb +2 -0
  29. data/spec/fixtures/modules/foo/lib/puppet/parser/functions/bar.rb +8 -2
  30. data/spec/fixtures/modules/foo/lib/puppet/parser/functions/baz.rb +8 -2
  31. data/spec/fixtures/modules/foo/lib/puppet/parser/functions/foo.rb +8 -2
  32. data/spec/fixtures/modules/foo/lib/puppet/parser/functions/quux.rb +8 -2
  33. data/spec/fixtures/modules/foo/lib/puppet/type/bar.rb +2 -0
  34. data/spec/fixtures/modules/foo/lib/puppet/type/foo.rb +2 -0
  35. data/spec/puppet-lint/plugins/ghostbuster_classes_spec.rb +10 -9
  36. data/spec/puppet-lint/plugins/ghostbuster_defines_spec.rb +11 -11
  37. data/spec/puppet-lint/plugins/ghostbuster_facts_spec.rb +21 -20
  38. data/spec/puppet-lint/plugins/ghostbuster_files_spec.rb +25 -25
  39. data/spec/puppet-lint/plugins/ghostbuster_functions_spec.rb +16 -15
  40. data/spec/puppet-lint/plugins/ghostbuster_hiera_files_spec.rb +30 -30
  41. data/spec/puppet-lint/plugins/ghostbuster_templates_spec.rb +17 -16
  42. data/spec/puppet-lint/plugins/ghostbuster_types_spec.rb +10 -9
  43. data/spec/spec_helper.rb +33 -34
  44. metadata +76 -36
  45. data/.travis.yml +0 -20
@@ -1,55 +1,56 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'ghostbuster_facts' do
4
6
  let(:code) { "Facter.add('foo')" }
5
7
 
6
8
  context 'with fix disabled' do
7
-
8
9
  context 'when fact is not used' do
9
- let(:path) { "./spec/fixtures/modules/foo/lib/facter/multi.rb" }
10
+ let(:path) { './spec/fixtures/modules/foo/lib/facter/multi.rb' }
10
11
 
11
- it 'should detect one problem' do
12
- expect(problems).to have(2).problems
12
+ it 'detects one problem' do
13
+ expect(problems.size).to eq(2)
13
14
  end
14
15
 
15
- it 'should create a warning' do
16
- expect(problems).to contain_warning("Fact multi1 seems unused")
16
+ it 'creates a warning' do
17
+ expect(problems).to contain_warning('Fact multi1 seems unused')
17
18
  end
18
19
 
19
- it 'should create a warning' do
20
- expect(problems).to contain_warning("Fact multi2 seems unused")
20
+ it 'creates a warning' do
21
+ expect(problems).to contain_warning('Fact multi2 seems unused')
21
22
  end
22
23
  end
23
24
 
24
25
  context 'when fact is used in a string' do
25
- let(:path) { "./spec/fixtures/modules/foo/lib/facter/foo.rb" }
26
+ let(:path) { './spec/fixtures/modules/foo/lib/facter/foo.rb' }
26
27
 
27
- it 'should not detect any problem' do
28
- expect(problems).to have(0).problems
28
+ it 'does not detect any problem' do
29
+ expect(problems.size).to eq(0)
29
30
  end
30
31
  end
31
32
 
32
33
  context 'when fact is used in manifest' do
33
- let(:path) { "./spec/fixtures/modules/foo/lib/facter/bar.rb" }
34
+ let(:path) { './spec/fixtures/modules/foo/lib/facter/bar.rb' }
34
35
 
35
- it 'should not detect any problem' do
36
- expect(problems).to have(0).problems
36
+ it 'does not detect any problem' do
37
+ expect(problems.size).to eq(0)
37
38
  end
38
39
  end
39
40
 
40
41
  context 'when fact is used in a template' do
41
- let(:path) { "./spec/fixtures/modules/foo/lib/facter/baz.rb" }
42
+ let(:path) { './spec/fixtures/modules/foo/lib/facter/baz.rb' }
42
43
 
43
- it 'should not detect any problem' do
44
- expect(problems).to have(0).problems
44
+ it 'does not detect any problem' do
45
+ expect(problems.size).to eq(0)
45
46
  end
46
47
  end
47
48
 
48
49
  context 'when fact is used in an inline_template' do
49
- let(:path) { "./spec/fixtures/modules/foo/lib/facter/quux.rb" }
50
+ let(:path) { './spec/fixtures/modules/foo/lib/facter/quux.rb' }
50
51
 
51
- it 'should not detect any problem' do
52
- expect(problems).to have(0).problems
52
+ it 'does not detect any problem' do
53
+ expect(problems.size).to eq(0)
53
54
  end
54
55
  end
55
56
  end
@@ -1,64 +1,64 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'ghostbuster_files' do
4
-
5
- let(:code) { "" }
6
+ let(:code) { '' }
6
7
 
7
8
  context 'with fix disabled' do
8
-
9
9
  context 'when file usage is found in puppetdb' do
10
- let(:path) { "./modules/foo/files/bar" }
10
+ let(:path) { './modules/foo/files/bar' }
11
11
 
12
- it 'should not detect any problem' do
13
- expect(problems).to have(0).problems
12
+ it 'does not detect any problem' do
13
+ expect(problems.size).to eq(0)
14
14
  end
15
15
  end
16
16
 
17
17
  context 'when parent directory with recurse => true usage is found in puppetdb' do
18
- let(:path) { "./modules/foo/files/baz/baz" }
18
+ let(:path) { './modules/foo/files/baz/baz' }
19
19
 
20
- it 'should not detect any problem' do
21
- expect(problems).to have(0).problems
20
+ it 'does not detect any problem' do
21
+ expect(problems.size).to eq(0)
22
22
  end
23
23
  end
24
24
 
25
25
  context 'when using full module name syntax' do
26
- let(:path) { "./modules/foo/files/used_with_file" }
26
+ let(:path) { './modules/foo/files/used_with_file' }
27
27
 
28
- it 'should not detect any problem' do
29
- expect(problems).to have(0).problems
28
+ it 'does not detect any problem' do
29
+ expect(problems.size).to eq(0)
30
30
  end
31
31
  end
32
32
 
33
33
  context 'when using $module_name syntax' do
34
- let(:path) { "./modules/foo/files/used_with_file_and_module_name" }
34
+ let(:path) { './modules/foo/files/used_with_file_and_module_name' }
35
35
 
36
- it 'should not detect any problem' do
37
- expect(problems).to have(0).problems
36
+ it 'does not detect any problem' do
37
+ expect(problems.size).to eq(0)
38
38
  end
39
39
  end
40
40
 
41
41
  context 'when file in ROOT is not used' do
42
- let(:path) { "./modules/bar/files/foo" }
42
+ let(:path) { './modules/bar/files/foo' }
43
43
 
44
- it 'should detect one problem' do
45
- expect(problems).to have(1).problems
44
+ it 'detects one problem' do
45
+ expect(problems.size).to eq(1)
46
46
  end
47
47
 
48
- it 'should create a warning' do
49
- expect(problems).to contain_warning("File bar/foo seems unused")
48
+ it 'creates a warning' do
49
+ expect(problems).to contain_warning('File bar/foo seems unused')
50
50
  end
51
51
  end
52
52
 
53
53
  context 'when file in subdir is not used' do
54
- let(:path) { "./modules/bar/files/foo/bar" }
54
+ let(:path) { './modules/bar/files/foo/bar' }
55
55
 
56
- it 'should detect one problem' do
57
- expect(problems).to have(1).problems
56
+ it 'detects one problem' do
57
+ expect(problems.size).to eq(1)
58
58
  end
59
59
 
60
- it 'should create a warning' do
61
- expect(problems).to contain_warning("File bar/foo/bar seems unused")
60
+ it 'creates a warning' do
61
+ expect(problems).to contain_warning('File bar/foo/bar seems unused')
62
62
  end
63
63
  end
64
64
  end
@@ -1,43 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'ghostbuster_functions' do
4
6
  let(:code) { '' }
5
7
 
6
8
  context 'with fix disabled' do
7
-
8
9
  context 'when function is not used' do
9
- let(:path) { "./spec/fixtures/modules/foo/lib/puppet/parser/functions/foo.rb" }
10
+ let(:path) { './spec/fixtures/modules/foo/lib/puppet/parser/functions/foo.rb' }
10
11
 
11
- it 'should detect one problem' do
12
- expect(problems).to have(1).problems
12
+ it 'detects one problem' do
13
+ expect(problems.size).to eq(1)
13
14
  end
14
15
 
15
- it 'should create a warning' do
16
- expect(problems).to contain_warning("Function foo seems unused")
16
+ it 'creates a warning' do
17
+ expect(problems).to contain_warning('Function foo seems unused')
17
18
  end
18
19
  end
19
20
 
20
21
  context 'when function is used in a manifest' do
21
- let(:path) { "./spec/fixtures/modules/foo/lib/puppet/parser/functions/bar.rb" }
22
+ let(:path) { './spec/fixtures/modules/foo/lib/puppet/parser/functions/bar.rb' }
22
23
 
23
- it 'should not detect any problem' do
24
- expect(problems).to have(0).problems
24
+ it 'does not detect any problem' do
25
+ expect(problems.size).to eq(0)
25
26
  end
26
27
  end
27
28
 
28
29
  context 'when function is used in a template using scope.function_baz()' do
29
- let(:path) { "./spec/fixtures/modules/foo/lib/puppet/parser/functions/baz.rb" }
30
+ let(:path) { './spec/fixtures/modules/foo/lib/puppet/parser/functions/baz.rb' }
30
31
 
31
- it 'should not detect any problem' do
32
- expect(problems).to have(0).problems
32
+ it 'does not detect any problem' do
33
+ expect(problems.size).to eq(0)
33
34
  end
34
35
  end
35
36
 
36
37
  context 'when function is used in a template using Puppet::Parser::Functions.function(:quux)' do
37
- let(:path) { "./spec/fixtures/modules/foo/lib/puppet/parser/functions/quux.rb" }
38
+ let(:path) { './spec/fixtures/modules/foo/lib/puppet/parser/functions/quux.rb' }
38
39
 
39
- it 'should not detect any problem' do
40
- expect(problems).to have(0).problems
40
+ it 'does not detect any problem' do
41
+ expect(problems.size).to eq(0)
41
42
  end
42
43
  end
43
44
  end
@@ -1,78 +1,78 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  ENV['HIERA_YAML_PATH'] = './spec/fixtures/hiera.yaml'
4
6
 
5
7
  describe 'ghostbuster_hiera_files' do
6
-
7
- let(:code) { "" }
8
+ let(:code) { '' }
8
9
 
9
10
  context 'with fix disabled' do
10
-
11
11
  context 'when a certname file is NOT used' do
12
- let(:path) { "./hieradata/nodes/foo.example.com.yaml" }
12
+ let(:path) { './hieradata/nodes/foo.example.com.yaml' }
13
13
 
14
- it 'should detect one problem' do
15
- expect(problems).to have(1).problems
14
+ it 'detects one problem' do
15
+ expect(problems.size).to eq(1)
16
16
  end
17
17
 
18
- it 'should create a warning' do
19
- expect(problems).to contain_warning("Hiera File nodes/foo.example.com.yaml seems unused")
18
+ it 'creates a warning' do
19
+ expect(problems).to contain_warning('Hiera File nodes/foo.example.com.yaml seems unused')
20
20
  end
21
21
  end
22
22
 
23
23
  context 'when a certname file is used' do
24
- let(:path) { "./hieradata/nodes/bar.example.com.yaml" }
24
+ let(:path) { './hieradata/nodes/bar.example.com.yaml' }
25
25
 
26
- it 'should not detect any problem' do
27
- expect(problems).to have(0).problems
26
+ it 'does not detect any problem' do
27
+ expect(problems.size).to eq(0)
28
28
  end
29
29
  end
30
30
 
31
31
  context 'when an environment file is NOT used' do
32
- let(:path) { "./hieradata/environment/foo.yaml" }
32
+ let(:path) { './hieradata/environment/foo.yaml' }
33
33
 
34
- it 'should detect one problem' do
35
- expect(problems).to have(1).problems
34
+ it 'detects one problem' do
35
+ expect(problems.size).to eq(1)
36
36
  end
37
37
 
38
- it 'should create a warning' do
39
- expect(problems).to contain_warning("Hiera File environment/foo.yaml seems unused")
38
+ it 'creates a warning' do
39
+ expect(problems).to contain_warning('Hiera File environment/foo.yaml seems unused')
40
40
  end
41
41
  end
42
42
 
43
43
  context 'when an environment file is used' do
44
- let(:path) { "./hieradata/environment/production.yaml" }
44
+ let(:path) { './hieradata/environment/production.yaml' }
45
45
 
46
- it 'should not detect any problem' do
47
- expect(problems).to have(0).problems
46
+ it 'does not detect any problem' do
47
+ expect(problems.size).to eq(0)
48
48
  end
49
49
  end
50
50
 
51
51
  context 'when an fact is NOT used' do
52
- let(:path) { "./hieradata/virtual/false.yaml" }
52
+ let(:path) { './hieradata/virtual/false.yaml' }
53
53
 
54
- it 'should detect one problem' do
55
- expect(problems).to have(1).problems
54
+ it 'detects one problem' do
55
+ expect(problems.size).to eq(1)
56
56
  end
57
57
 
58
- it 'should create a warning' do
59
- expect(problems).to contain_warning("Hiera File virtual/false.yaml seems unused")
58
+ it 'creates a warning' do
59
+ expect(problems).to contain_warning('Hiera File virtual/false.yaml seems unused')
60
60
  end
61
61
  end
62
62
 
63
63
  context 'when an fact file is used' do
64
- let(:path) { "./hieradata/virtual/true.yaml" }
64
+ let(:path) { './hieradata/virtual/true.yaml' }
65
65
 
66
- it 'should not detect any problem' do
67
- expect(problems).to have(0).problems
66
+ it 'does not detect any problem' do
67
+ expect(problems.size).to eq(0)
68
68
  end
69
69
  end
70
70
 
71
71
  context 'when using a variable in hierarchy' do
72
- let(:path) { "./hieradata/domain/example.com.yaml" }
72
+ let(:path) { './hieradata/domain/example.com.yaml' }
73
73
 
74
- it 'should not detect any problem' do
75
- expect(problems).to have(0).problems
74
+ it 'does not detect any problem' do
75
+ expect(problems.size).to eq(0)
76
76
  end
77
77
  end
78
78
  end
@@ -1,43 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'ghostbuster_templates' do
4
- let(:code) { "" }
6
+ let(:code) { '' }
5
7
 
6
8
  context 'with fix disabled' do
7
-
8
9
  context 'when using full module name syntax' do
9
- let(:path) { "./modules/foo/templates/used_with_template" }
10
+ let(:path) { './modules/foo/templates/used_with_template' }
10
11
 
11
- it 'should not detect any problem' do
12
- expect(problems).to have(0).problems
12
+ it 'does not detect any problem' do
13
+ expect(problems.size).to eq(0)
13
14
  end
14
15
  end
15
16
 
16
17
  context 'when using $module_name syntax' do
17
- let(:path) { "./modules/foo/templates/used_with_template_and_module_name" }
18
+ let(:path) { './modules/foo/templates/used_with_template_and_module_name' }
18
19
 
19
- it 'should not detect any problem' do
20
- expect(problems).to have(0).problems
20
+ it 'does not detect any problem' do
21
+ expect(problems.size).to eq(0)
21
22
  end
22
23
  end
23
24
 
24
25
  context 'when using template in template' do
25
- let(:path) { "./modules/foo/templates/used_in_template.erb" }
26
+ let(:path) { './modules/foo/templates/used_in_template.erb' }
26
27
 
27
- it 'should not detect any problem' do
28
- expect(problems).to have(0).problems
28
+ it 'does not detect any problem' do
29
+ expect(problems.size).to eq(0)
29
30
  end
30
31
  end
31
32
 
32
33
  context 'when template usage is not found in manifests' do
33
- let(:path) { "./modules/foo/templates/unused" }
34
+ let(:path) { './modules/foo/templates/unused' }
34
35
 
35
- it 'should detect one problem' do
36
- expect(problems).to have(1).problems
36
+ it 'detects one problem' do
37
+ expect(problems.size).to eq(1)
37
38
  end
38
39
 
39
- it 'should create a warning' do
40
- expect(problems).to contain_warning("Template foo/unused seems unused")
40
+ it 'creates a warning' do
41
+ expect(problems).to contain_warning('Template foo/unused seems unused')
41
42
  end
42
43
  end
43
44
  end
@@ -1,27 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'ghostbuster_types' do
4
6
  let(:code) { '' }
5
7
 
6
8
  context 'with fix disabled' do
7
-
8
9
  context 'when type is not used' do
9
- let(:path) { "./spec/fixtures/modules/foo/lib/puppet/type/foo.rb" }
10
+ let(:path) { './spec/fixtures/modules/foo/lib/puppet/type/foo.rb' }
10
11
 
11
- it 'should detect one problem' do
12
- expect(problems).to have(1).problems
12
+ it 'detects one problem' do
13
+ expect(problems.size).to eq(1)
13
14
  end
14
15
 
15
- it 'should create a warning' do
16
- expect(problems).to contain_warning("Type Foo seems unused")
16
+ it 'creates a warning' do
17
+ expect(problems).to contain_warning('Type Foo seems unused')
17
18
  end
18
19
  end
19
20
 
20
21
  context 'when type is used in a manifest' do
21
- let(:path) { "./spec/fixtures/modules/foo/lib/puppet/type/bar.rb" }
22
+ let(:path) { './spec/fixtures/modules/foo/lib/puppet/type/bar.rb' }
22
23
 
23
- it 'should not detect any problem' do
24
- expect(problems).to have(0).problems
24
+ it 'does not detect any problem' do
25
+ expect(problems.size).to eq(0)
25
26
  end
26
27
  end
27
28
  end
data/spec/spec_helper.rb CHANGED
@@ -5,7 +5,7 @@ PuppetLint::Plugins.load_spec_helper
5
5
 
6
6
  class PuppetDB::Client
7
7
  def puppetdb_to_jgrep(query)
8
- if query[0] == :'and' || query[0] == :'or'
8
+ if query[0] == :and || query[0] == :or
9
9
  "(#{puppetdb_to_jgrep(query[1])} #{query[0]} #{puppetdb_to_jgrep(query[2])})"
10
10
  else
11
11
  "#{[query[1]].flatten.join('.')}#{query[0]}#{query[2]}"
@@ -13,50 +13,49 @@ class PuppetDB::Client
13
13
  end
14
14
 
15
15
  def process_pql_kv(q)
16
- k, v = q.split(/\s*=\s*/)
17
- ".#{k}=#{v}"
16
+ k, v = q.split(/\s*=\s*/)
17
+ ".#{k}=#{v}"
18
18
  end
19
19
 
20
20
  def pql_to_jgrep(query)
21
- endpoint_cols = query.split('{').first
22
- endpoint = endpoint_cols.split(/[\s\[]/).first
23
- query.sub!(/^#{Regexp.quote(endpoint_cols)}\{\s*/, '')
24
- query.sub!(/\s*}\s*/, '')
25
- query.sub!(/(and\s+)?nodes\s*\{\s*deactivated\s+is\s+null\s*\}/, '')
26
-
27
- return endpoint, '' if query == ''
28
-
29
- query.gsub!('parameters.', 'parameter.')
30
- query.sub!(/\s*=\s*/, '=')
31
-
32
- jgrep_query_and_parts = []
33
- query.split(/\s+and\s+/).each do |q|
34
- newq = ''
35
- if q.start_with?('(')
36
- newq << '('
37
- newq << q.split(/\s+or\s+/).map do |qq|
38
- process_pql_kv(qq.sub(/^\(/, '').sub(/\)$/, ''))
39
- end.join(' or ')
40
- newq << ')'
41
- else
42
- newq << process_pql_kv(q)
43
- end
44
- jgrep_query_and_parts << newq
21
+ endpoint_cols = query.split('{').first
22
+ endpoint = endpoint_cols.split(/[\s\[]/).first
23
+ query.sub!(/^#{Regexp.quote(endpoint_cols)}\{\s*/, '')
24
+ query.sub!(/\s*}\s*/, '')
25
+ query.sub!(/(and\s+)?nodes\s*\{\s*deactivated\s+is\s+null\s*\}/, '')
26
+
27
+ return endpoint, '' if query == ''
28
+
29
+ query.gsub!('parameters.', 'parameter.')
30
+ query.sub!(/\s*=\s*/, '=')
31
+
32
+ jgrep_query_and_parts = []
33
+ query.split(/\s+and\s+/).each do |q|
34
+ newq = ''
35
+ if q.start_with?('(')
36
+ newq << '('
37
+ newq << q.split(/\s+or\s+/).map do |qq|
38
+ process_pql_kv(qq.sub(/^\(/, '').sub(/\)$/, ''))
39
+ end.join(' or ')
40
+ newq << ')'
41
+ else
42
+ newq << process_pql_kv(q)
45
43
  end
46
- jgrep_query = jgrep_query_and_parts.join(" and ")
47
- jgrep_query.rstrip!
44
+ jgrep_query_and_parts << newq
45
+ end
46
+ jgrep_query = jgrep_query_and_parts.join(' and ')
47
+ jgrep_query.rstrip!
48
48
 
49
- return endpoint, jgrep_query
49
+ [endpoint, jgrep_query]
50
50
  end
51
51
 
52
- def request(endpoint, query, opts={})
52
+ def request(endpoint, query, _opts = {})
53
53
  if endpoint == ''
54
- endpoint, query = pql_to_jgrep(query)
54
+ endpoint, query = pql_to_jgrep(query)
55
55
  else
56
- query = puppetdb_to_jgrep(query)
56
+ query = puppetdb_to_jgrep(query)
57
57
  end
58
58
  ret = JGrep.jgrep(File.read("spec/fixtures/#{endpoint}.json"), query)
59
59
  PuppetDB::Response.new(ret, ret.size)
60
60
  end
61
61
  end
62
-