gaddag 0.1.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 +5 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +38 -0
- data/Rakefile +1 -0
- data/gaddag.gemspec +31 -0
- data/lib/gaddag.rb +47 -0
- data/lib/gaddag/arc.rb +41 -0
- data/lib/gaddag/node.rb +115 -0
- data/lib/gaddag/path.rb +72 -0
- data/lib/gaddag/word.rb +39 -0
- data/spec/shared/unit/gaddag/arc_context.rb +6 -0
- data/spec/shared/unit/gaddag/node/create_arc_behaviour.rb +41 -0
- data/spec/shared/unit/gaddag/node/create_final_path_behaviour.rb +33 -0
- data/spec/shared/unit/gaddag/node/create_path_behaviour.rb +15 -0
- data/spec/shared/unit/gaddag/node/create_path_context.rb +6 -0
- data/spec/unit/gaddag/add_spec.rb +46 -0
- data/spec/unit/gaddag/arc/add_final_letter_spec.rb +24 -0
- data/spec/unit/gaddag/arc/final_paths_spec.rb +49 -0
- data/spec/unit/gaddag/arc/initialize_spec.rb +16 -0
- data/spec/unit/gaddag/find_spec.rb +66 -0
- data/spec/unit/gaddag/initialize_spec.rb +11 -0
- data/spec/unit/gaddag/node/arc_spec.rb +23 -0
- data/spec/unit/gaddag/node/create_arc_spec.rb +8 -0
- data/spec/unit/gaddag/node/create_final_arc_spec.rb +18 -0
- data/spec/unit/gaddag/node/create_final_path_spec.rb +43 -0
- data/spec/unit/gaddag/node/create_path_spec.rb +44 -0
- data/spec/unit/gaddag/node/final_path_spec.rb +30 -0
- data/spec/unit/gaddag/node/final_paths_spec.rb +48 -0
- data/spec/unit/gaddag/node/follow_arc_spec.rb +24 -0
- data/spec/unit/gaddag/node/follow_path_spec.rb +41 -0
- data/spec/unit/gaddag/node/path_spec.rb +30 -0
- data/spec/unit/gaddag/path/equal_value_spec.rb +17 -0
- data/spec/unit/gaddag/path/include_delimiter_spec.rb +15 -0
- data/spec/unit/gaddag/path/initialize_spec.rb +12 -0
- data/spec/unit/gaddag/path/reversed_prefix_letters_spec.rb +34 -0
- data/spec/unit/gaddag/path/start_with_spec.rb +39 -0
- data/spec/unit/gaddag/path/suffix_letters_spec.rb +34 -0
- data/spec/unit/gaddag/path/to_ary_spec.rb +15 -0
- data/spec/unit/gaddag/path/to_s_spec.rb +18 -0
- data/spec/unit/gaddag/path/to_word_spec.rb +37 -0
- data/spec/unit/gaddag/word/equal_value_spec.rb +17 -0
- data/spec/unit/gaddag/word/initialize_spec.rb +12 -0
- data/spec/unit/gaddag/word/to_delimited_paths_spec.rb +29 -0
- data/spec/unit/gaddag/word/to_s_spec.rb +18 -0
- metadata +252 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
shared_examples 'GADDAG::Node#create_arc/behaviour' do
|
4
|
+
subject { GADDAG::Node.new }
|
5
|
+
|
6
|
+
let(:letter) { 'L' }
|
7
|
+
let(:destination) { GADDAG::Node.new }
|
8
|
+
|
9
|
+
let(:create_arc) { ->(*args) { subject.create_arc(*args) } }
|
10
|
+
|
11
|
+
let(:arc) { create_arc.call(letter) }
|
12
|
+
let(:another_arc) { create_arc.call(letter) }
|
13
|
+
|
14
|
+
let(:arc_with_destination) { create_arc.call(letter, destination) }
|
15
|
+
|
16
|
+
it 'returns the newly created arc' do
|
17
|
+
expect(arc).to be_an_instance_of(GADDAG::Arc)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'adds the arc to the mapping of outgoing arcs' do
|
21
|
+
expect(subject.outgoing_arcs).to include(letter.to_sym => arc)
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when not provided with a destination node' do
|
25
|
+
it 'points the arc to a newly created destination node' do
|
26
|
+
expect(arc.destination).to eq(GADDAG::Node.new)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when provided with a destination node' do
|
31
|
+
it 'points the arc to the given destination node' do
|
32
|
+
expect(arc_with_destination.destination).to equal(destination)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when created again for the same letter' do
|
37
|
+
it 'returns the original arc' do
|
38
|
+
expect(another_arc).to equal(arc)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
shared_examples 'GADDAG::Node#create_final_path/behaviour' do
|
4
|
+
include_context 'GADDAG::Node#create_path/context'
|
5
|
+
|
6
|
+
let!(:final_node) { subject.create_final_path(letters) }
|
7
|
+
|
8
|
+
let(:letters_without_last_one) { letters[0..-2] }
|
9
|
+
let(:letters_without_last_two) { letters[0..-3]}
|
10
|
+
|
11
|
+
let(:last_letter) { letters[-1] }
|
12
|
+
let(:second_last_letter) { letters[-2] }
|
13
|
+
|
14
|
+
it 'creates the path for the given letters up till the second last letter' do
|
15
|
+
expect { subject.follow_path(letters_without_last_one) }.to_not raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'does not create an arc for the last letter' do
|
19
|
+
expect { subject.follow_path(letters) }.to raise_error(KeyError)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'adds the last letter to the last arc as final letter' do
|
23
|
+
expect(subject.follow_path(letters_without_last_two).outgoing_arcs).to eq({
|
24
|
+
second_last_letter.to_sym => GADDAG::Arc.new(GADDAG::Node.new).tap do |arc|
|
25
|
+
arc.add_final_letter(last_letter)
|
26
|
+
end
|
27
|
+
})
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns the last created node' do
|
31
|
+
expect(final_node).to equal(subject.follow_path(letters_without_last_one))
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
shared_examples 'GADDAG::Node#create_path/behaviour' do
|
4
|
+
include_context 'GADDAG::Node#create_path/context'
|
5
|
+
|
6
|
+
let!(:final_node) { subject.create_path(letters) }
|
7
|
+
|
8
|
+
it 'creates the path for the given letters' do
|
9
|
+
expect { subject.follow_path(letters) }.to_not raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns the last created node' do
|
13
|
+
expect(final_node).to equal(subject.follow_path(letters))
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
|
5
|
+
describe GADDAG, '#add' do
|
6
|
+
subject { GADDAG.new }
|
7
|
+
let(:path_delimiter) { GADDAG::Path::DELIMITER }
|
8
|
+
|
9
|
+
it 'returns itself' do
|
10
|
+
expect(subject.add('ANYTHING')).to equal(subject)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'given that the word BREAK is added' do
|
14
|
+
before { subject.add('BREAK') }
|
15
|
+
|
16
|
+
it 'creates a final path for K-A-E-R-B-♢' do
|
17
|
+
final_node = subject.root.follow_path(%w[K A E R])
|
18
|
+
expect(final_node.outgoing_arcs).to have_key(:B)
|
19
|
+
expect(final_node.outgoing_arcs[:B].final_letters).to eq([path_delimiter].to_set)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'creates a final path for B-♢-R-E-A-K' do
|
23
|
+
final_node = subject.root.follow_path(%w[B] + [path_delimiter] + %w[R E])
|
24
|
+
expect(final_node.outgoing_arcs).to have_key(:A)
|
25
|
+
expect(final_node.outgoing_arcs[:A].final_letters).to eq(['K'].to_set)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'creates a final path for R-B-♢-E-A-K' do
|
29
|
+
final_node = subject.root.follow_path(%w[R B] + [path_delimiter] + %w[E])
|
30
|
+
expect(final_node.outgoing_arcs).to have_key(:A)
|
31
|
+
expect(final_node.outgoing_arcs[:A].final_letters).to eq(['K'].to_set)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'creates a final path for E-R-B-♢-A-K' do
|
35
|
+
final_node = subject.root.follow_path(%w[E R B] + [path_delimiter])
|
36
|
+
expect(final_node.outgoing_arcs).to have_key(:A)
|
37
|
+
expect(final_node.outgoing_arcs[:A].final_letters).to eq(['K'].to_set)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'creates a final path for A-E-R-B-♢-K' do
|
41
|
+
final_node = subject.root.follow_path(%w[A E R B])
|
42
|
+
expect(final_node.outgoing_arcs).to have_key(path_delimiter.to_sym)
|
43
|
+
expect(final_node.outgoing_arcs[path_delimiter.to_sym].final_letters).to eq(['K'].to_set)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
require 'shared/unit/gaddag/arc_context'
|
5
|
+
|
6
|
+
describe GADDAG::Arc, '#add_final_letter' do
|
7
|
+
include_context 'GADDAG::Arc/context'
|
8
|
+
|
9
|
+
context 'when adding a final letter' do
|
10
|
+
before { subject.add_final_letter('K') }
|
11
|
+
|
12
|
+
it 'is added' do
|
13
|
+
expect(subject.final_letters).to eq(%w[K].to_set)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when adding a final letter twice' do
|
18
|
+
before { 2.times { subject.add_final_letter('L') } }
|
19
|
+
|
20
|
+
it 'is only added once' do
|
21
|
+
expect(subject.final_letters).to eq(%w[L].to_set)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
require 'shared/unit/gaddag/arc_context'
|
5
|
+
|
6
|
+
describe GADDAG::Arc, '#final_paths' do
|
7
|
+
include_context 'GADDAG::Arc/context'
|
8
|
+
|
9
|
+
let(:first_final_path) { GADDAG::Path.new(%w[A B C]) }
|
10
|
+
let(:second_final_path) { GADDAG::Path.new(%w[D E F]) }
|
11
|
+
|
12
|
+
context 'when the arc includes no final letters' do
|
13
|
+
context 'when the destination node has no final paths' do
|
14
|
+
specify { expect(subject.final_paths).to be_empty }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the destination node has final paths' do
|
18
|
+
before { destination.create_final_path(first_final_path.letters) }
|
19
|
+
before { destination.create_final_path(second_final_path.letters) }
|
20
|
+
|
21
|
+
specify { expect(subject.final_paths).to include(first_final_path) }
|
22
|
+
specify { expect(subject.final_paths).to include(second_final_path) }
|
23
|
+
specify { expect(subject.final_paths.count).to eq(2) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when the arc does include final letters' do
|
28
|
+
before { %w(X Y).each { |l| subject.add_final_letter(l) } }
|
29
|
+
|
30
|
+
context 'when the destination node has no final paths' do
|
31
|
+
specify { expect(subject.final_paths).to include(GADDAG::Path.new(%w[X])) }
|
32
|
+
specify { expect(subject.final_paths).to include(GADDAG::Path.new(%w[Y])) }
|
33
|
+
specify { expect(subject.final_paths.count).to eq(2) }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when the destination node has final paths' do
|
37
|
+
before { destination.create_final_path(first_final_path.letters) }
|
38
|
+
before { destination.create_final_path(second_final_path.letters) }
|
39
|
+
|
40
|
+
specify { expect(subject.final_paths).to include(GADDAG::Path.new(%w[X])) }
|
41
|
+
specify { expect(subject.final_paths).to include(GADDAG::Path.new(%w[Y])) }
|
42
|
+
|
43
|
+
specify { expect(subject.final_paths).to include(first_final_path) }
|
44
|
+
specify { expect(subject.final_paths).to include(second_final_path) }
|
45
|
+
|
46
|
+
specify { expect(subject.final_paths.count).to eq(4) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
require 'shared/unit/gaddag/arc_context'
|
5
|
+
|
6
|
+
describe GADDAG::Arc, '#initialize' do
|
7
|
+
include_context 'GADDAG::Arc/context'
|
8
|
+
|
9
|
+
it 'initializes an empty set of final letters' do
|
10
|
+
expect(subject.final_letters).to be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'stores the destination node' do
|
14
|
+
expect(subject.destination).to equal(destination)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
|
5
|
+
describe GADDAG, '#find' do
|
6
|
+
subject { GADDAG.new }
|
7
|
+
|
8
|
+
context 'given that the words BREAK and AKIN are added' do
|
9
|
+
before { subject.add('BREAK') }
|
10
|
+
before { subject.add('AKIN') }
|
11
|
+
|
12
|
+
context 'when searching for any word or substring that has not been added' do
|
13
|
+
it 'yields no results' do
|
14
|
+
expect(subject.find('ZOMBIES')).to be_empty
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when searching for an empty substring' do
|
19
|
+
let(:results) { subject.find('') }
|
20
|
+
|
21
|
+
it 'yields all words that have been added' do
|
22
|
+
expect(results).to eq(['BREAK', 'AKIN'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when searching for the letter E' do
|
27
|
+
let(:results) { subject.find('E') }
|
28
|
+
|
29
|
+
it 'yields one result, namely BREAK' do
|
30
|
+
expect(results).to eq(['BREAK'])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when searching for the word BREAK' do
|
35
|
+
let(:results) { subject.find('BREAK') }
|
36
|
+
|
37
|
+
it 'yields one result, namely BREAK' do
|
38
|
+
expect(results).to eq(['BREAK'])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when searching for the substring BREA' do
|
43
|
+
let(:results) { subject.find('BREA') }
|
44
|
+
|
45
|
+
it 'yields one result, namely BREAK' do
|
46
|
+
expect(results).to eq(['BREAK'])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when searching for the substring REAK' do
|
51
|
+
let(:results) { subject.find('REAK') }
|
52
|
+
|
53
|
+
it 'yields one result, namely BREAK' do
|
54
|
+
expect(results).to eq(['BREAK'])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when searching for the substring AK' do
|
59
|
+
let(:results) { subject.find('AK') }
|
60
|
+
|
61
|
+
it 'yields two results, namely BREAK and AKIN' do
|
62
|
+
expect(results).to eq(['BREAK', 'AKIN'])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
|
5
|
+
describe GADDAG::Node, '#arc?' do
|
6
|
+
subject { GADDAG::Node.new }
|
7
|
+
|
8
|
+
let(:letter) { 'L' }
|
9
|
+
|
10
|
+
context 'when the arc for the given letter exists' do
|
11
|
+
before { subject.create_arc(letter) }
|
12
|
+
|
13
|
+
it 'returns true' do
|
14
|
+
expect(subject.arc?(letter)).to eq(true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when the arc for the given letter does not exist' do
|
19
|
+
it 'returns false' do
|
20
|
+
expect(subject.arc?(letter)).to eq(false)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
require 'shared/unit/gaddag/node/create_arc_behaviour'
|
5
|
+
|
6
|
+
describe GADDAG::Node, '#create_final_arc' do
|
7
|
+
it_behaves_like 'GADDAG::Node#create_arc/behaviour' do
|
8
|
+
let(:final_letter) { 'Z' }
|
9
|
+
|
10
|
+
let(:create_arc) do
|
11
|
+
->(*args) { subject.create_final_arc(*args.insert(1, final_letter)) }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'adds the final letter to the arc' do
|
15
|
+
expect(arc.final_letters).to include(final_letter)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
require 'shared/unit/gaddag/node/create_path_context'
|
5
|
+
require 'shared/unit/gaddag/node/create_final_path_behaviour'
|
6
|
+
|
7
|
+
describe GADDAG::Node, '#create_final_path' do
|
8
|
+
context 'when not given a list of destination nodes' do
|
9
|
+
it_behaves_like 'GADDAG::Node#create_final_path/behaviour'
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when given a list of destination nodes' do
|
13
|
+
it_behaves_like 'GADDAG::Node#create_final_path/behaviour' do
|
14
|
+
let(:letters) { %w[B ♢ R E A K] }
|
15
|
+
|
16
|
+
let!(:destinations) { 6.times.map { GADDAG::Node.new } }
|
17
|
+
let!(:final_node) { subject.create_final_path(letters, destinations) }
|
18
|
+
|
19
|
+
it 'creates the path for the given letters through the given destination nodes' do
|
20
|
+
expect(subject.follow_path(%w[B])).to equal(destinations[0])
|
21
|
+
expect(subject.follow_path(%w[B ♢])).to equal(destinations[1])
|
22
|
+
expect(subject.follow_path(%w[B ♢ R])).to equal(destinations[2])
|
23
|
+
expect(subject.follow_path(%w[B ♢ R E])).to equal(destinations[3])
|
24
|
+
expect(subject.follow_path(%w[B ♢ R E A])).to equal(destinations[4])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when given a shortened list of destination nodes' do
|
30
|
+
it_behaves_like 'GADDAG::Node#create_final_path/behaviour' do
|
31
|
+
let(:letters) { %w[B ♢ R E A K] }
|
32
|
+
|
33
|
+
let(:destinations) { 3.times.map { GADDAG::Node.new } }
|
34
|
+
let!(:final_node) { subject.create_final_path(letters, destinations) }
|
35
|
+
|
36
|
+
it 'creates a path through the shortened list of destination nodes' do
|
37
|
+
expect(subject.follow_path(%w[B])).to equal(destinations[0])
|
38
|
+
expect(subject.follow_path(%w[B ♢])).to equal(destinations[1])
|
39
|
+
expect(subject.follow_path(%w[B ♢ R])).to equal(destinations[2])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'gaddag'
|
4
|
+
require 'shared/unit/gaddag/node/create_path_context'
|
5
|
+
require 'shared/unit/gaddag/node/create_path_behaviour'
|
6
|
+
|
7
|
+
describe GADDAG::Node, '#create_path' do
|
8
|
+
context 'when not given a list of destination nodes' do
|
9
|
+
it_behaves_like 'GADDAG::Node#create_path/behaviour'
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when given a list of destination nodes' do
|
13
|
+
it_behaves_like 'GADDAG::Node#create_path/behaviour' do
|
14
|
+
let(:letters) { %w[B ♢ R E A K] }
|
15
|
+
|
16
|
+
let(:destinations) { 6.times.map { GADDAG::Node.new } }
|
17
|
+
let!(:final_node) { subject.create_path(letters, destinations) }
|
18
|
+
|
19
|
+
it 'creates a path through the given destination nodes' do
|
20
|
+
expect(subject.follow_path(%w[B])).to equal(destinations[0])
|
21
|
+
expect(subject.follow_path(%w[B ♢])).to equal(destinations[1])
|
22
|
+
expect(subject.follow_path(%w[B ♢ R])).to equal(destinations[2])
|
23
|
+
expect(subject.follow_path(%w[B ♢ R E])).to equal(destinations[3])
|
24
|
+
expect(subject.follow_path(%w[B ♢ R E A])).to equal(destinations[4])
|
25
|
+
expect(subject.follow_path(%w[B ♢ R E A K])).to equal(destinations[5])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when given a shortened list of destination nodes' do
|
31
|
+
it_behaves_like 'GADDAG::Node#create_path/behaviour' do
|
32
|
+
let(:letters) { %w[B ♢ R E A K] }
|
33
|
+
|
34
|
+
let(:destinations) { 3.times.map { GADDAG::Node.new } }
|
35
|
+
let!(:final_node) { subject.create_path(letters, destinations) }
|
36
|
+
|
37
|
+
it 'creates a path through the shortened list of destination nodes' do
|
38
|
+
expect(subject.follow_path(%w[B])).to equal(destinations[0])
|
39
|
+
expect(subject.follow_path(%w[B ♢])).to equal(destinations[1])
|
40
|
+
expect(subject.follow_path(%w[B ♢ R])).to equal(destinations[2])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|