clive 0.2.3 → 0.3.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.
- data/README.md +11 -5
- data/VERSION +1 -1
- data/clive.gemspec +10 -6
- data/lib/clive.rb +9 -50
- data/lib/clive/bool.rb +64 -0
- data/lib/clive/command.rb +288 -0
- data/lib/clive/exceptions.rb +48 -0
- data/lib/clive/ext.rb +3 -12
- data/lib/clive/flag.rb +71 -0
- data/lib/clive/option.rb +77 -0
- data/lib/clive/switch.rb +40 -0
- data/lib/clive/tokens.rb +4 -4
- data/test/bin_test +20 -4
- data/test/test_boolean.rb +13 -6
- data/test/test_clive.rb +36 -3
- data/test/test_command.rb +44 -0
- data/test/test_flag.rb +40 -1
- data/test/test_token.rb +22 -9
- metadata +12 -8
- data/lib/clive/booleans.rb +0 -37
- data/lib/clive/commands.rb +0 -317
- data/lib/clive/flags.rb +0 -17
- data/lib/clive/switches.rb +0 -39
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestCommand < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "A new command" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@c = Clive.new do
|
9
|
+
command(:add, "Add something") {puts "called!"}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "with multiple names" do
|
14
|
+
setup do
|
15
|
+
@c = Clive.new do
|
16
|
+
command(:add, :init, :new, "Add something") {puts "called!"}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
should "be called with first name" do
|
21
|
+
mock($stdout).puts("called!")
|
22
|
+
@c.parse ["add"]
|
23
|
+
end
|
24
|
+
|
25
|
+
should "be called with second name" do
|
26
|
+
mock($stdout).puts("called!")
|
27
|
+
@c.parse ["init"]
|
28
|
+
end
|
29
|
+
|
30
|
+
should "be called with third name" do
|
31
|
+
mock($stdout).puts("called!")
|
32
|
+
@c.parse ["new"]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
should "only execute it's block when called" do
|
38
|
+
mock($stdout).puts("called!")
|
39
|
+
@c.parse(["a"])
|
40
|
+
@c.parse(["add"])
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/test/test_flag.rb
CHANGED
@@ -6,7 +6,7 @@ class TestFlag < Test::Unit::TestCase
|
|
6
6
|
|
7
7
|
setup do
|
8
8
|
@c = Clive.new do
|
9
|
-
flag(:t, :type, "
|
9
|
+
flag(:t, :type, "TEXT", "Change type to TYPE") {|i| $stdout.puts(i)}
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -15,5 +15,44 @@ class TestFlag < Test::Unit::TestCase
|
|
15
15
|
@c.parse(["--type", "text"])
|
16
16
|
end
|
17
17
|
|
18
|
+
should "have an arg name" do
|
19
|
+
assert_equal "TEXT", @c.flags["t"].arg_name
|
20
|
+
end
|
21
|
+
|
22
|
+
should "not be optional" do
|
23
|
+
assert_equal false, @c.flags["t"].optional
|
24
|
+
end
|
25
|
+
|
18
26
|
end
|
27
|
+
|
28
|
+
context "A new flag with default" do
|
29
|
+
|
30
|
+
setup do
|
31
|
+
@c = Clive.new do
|
32
|
+
flag(:t, :type, "[TEXT]", "Change type to TYPE") do |i|
|
33
|
+
i ||= 'dog'
|
34
|
+
$stdout.puts(i)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
should "have an arg name" do
|
40
|
+
assert_equal "TEXT", @c.flags["t"].arg_name
|
41
|
+
end
|
42
|
+
|
43
|
+
should "be optional" do
|
44
|
+
assert_equal true, @c.flags["t"].optional
|
45
|
+
end
|
46
|
+
|
47
|
+
should "pass an argument to block" do
|
48
|
+
mock($stdout).puts("text")
|
49
|
+
@c.parse(["--type", "text"])
|
50
|
+
end
|
51
|
+
|
52
|
+
should "pass nil to the block if no argument" do
|
53
|
+
mock($stdout).puts("dog")
|
54
|
+
@c.parse(["--type"])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
19
58
|
end
|
data/test/test_token.rb
CHANGED
@@ -10,8 +10,7 @@ class TestToken < Test::Unit::TestCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
should "convert an array to tokens" do
|
13
|
-
|
14
|
-
assert_equal @tokens, t.tokens
|
13
|
+
assert_equal @tokens, Clive::Tokens.to_tokens(@array)
|
15
14
|
end
|
16
15
|
|
17
16
|
should "convert tokens to an array" do
|
@@ -25,9 +24,6 @@ class TestToken < Test::Unit::TestCase
|
|
25
24
|
@array = ["add", "-al", "--verbose"]
|
26
25
|
@array_split = ["add", "-a", "-l", "--verbose"]
|
27
26
|
@tokens = [[:word, "add"], [:short, "a"], [:short, "l"], [:long, "verbose"]]
|
28
|
-
|
29
|
-
@t = Clive::Tokens.new
|
30
|
-
@t << "add" << "-al" << "--verbose"
|
31
27
|
end
|
32
28
|
|
33
29
|
should "be created from an array" do
|
@@ -41,13 +37,30 @@ class TestToken < Test::Unit::TestCase
|
|
41
37
|
assert_equal @tokens, t.tokens
|
42
38
|
assert_equal @array_split, t.array
|
43
39
|
end
|
44
|
-
|
45
|
-
should "
|
46
|
-
|
40
|
+
|
41
|
+
should "tell whether an array is a token" do
|
42
|
+
t = Clive::Tokens.new
|
43
|
+
assert_equal false, t.token?(["a", "normal", "array"])
|
44
|
+
assert_equal true, t.token?([:word, "help"])
|
47
45
|
end
|
48
46
|
|
49
|
-
should "
|
47
|
+
should "turn token to string" do
|
48
|
+
t = Clive::Tokens.new
|
49
|
+
assert_equal "-v", t.token_to_string([:short, "v"])
|
50
|
+
assert_equal "--verbose", t.token_to_string([:long, "verbose"])
|
51
|
+
assert_equal "word", t.token_to_string([:word, "word"])
|
52
|
+
end
|
50
53
|
|
54
|
+
should "add new string values" do
|
55
|
+
t = Clive::Tokens.new
|
56
|
+
t << "add" << "-al" << "--verbose"
|
57
|
+
assert_equal @tokens, t.tokens
|
58
|
+
end
|
59
|
+
|
60
|
+
should "add new token values" do
|
61
|
+
t = Clive::Tokens.new
|
62
|
+
t << [:word, "add"] << [:short, "a"] << [:short, "l"] << [:long, "verbose"]
|
63
|
+
assert_equal @array_split, t.array
|
51
64
|
end
|
52
65
|
|
53
66
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 2
|
9
8
|
- 3
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joshua Hawxwell
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-21 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -64,16 +64,19 @@ files:
|
|
64
64
|
- VERSION
|
65
65
|
- clive.gemspec
|
66
66
|
- lib/clive.rb
|
67
|
-
- lib/clive/
|
68
|
-
- lib/clive/
|
67
|
+
- lib/clive/bool.rb
|
68
|
+
- lib/clive/command.rb
|
69
|
+
- lib/clive/exceptions.rb
|
69
70
|
- lib/clive/ext.rb
|
70
|
-
- lib/clive/
|
71
|
-
- lib/clive/
|
71
|
+
- lib/clive/flag.rb
|
72
|
+
- lib/clive/option.rb
|
73
|
+
- lib/clive/switch.rb
|
72
74
|
- lib/clive/tokens.rb
|
73
75
|
- test/bin_test
|
74
76
|
- test/helper.rb
|
75
77
|
- test/test_boolean.rb
|
76
78
|
- test/test_clive.rb
|
79
|
+
- test/test_command.rb
|
77
80
|
- test/test_exceptions.rb
|
78
81
|
- test/test_flag.rb
|
79
82
|
- test/test_switch.rb
|
@@ -116,6 +119,7 @@ test_files:
|
|
116
119
|
- test/helper.rb
|
117
120
|
- test/test_boolean.rb
|
118
121
|
- test/test_clive.rb
|
122
|
+
- test/test_command.rb
|
119
123
|
- test/test_exceptions.rb
|
120
124
|
- test/test_flag.rb
|
121
125
|
- test/test_switch.rb
|
data/lib/clive/booleans.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
class Clive
|
2
|
-
|
3
|
-
# A switch which can be triggered with either --no-verbose or --verbose
|
4
|
-
# for example.
|
5
|
-
class Boolean < Switch
|
6
|
-
attr_accessor :truth
|
7
|
-
|
8
|
-
def initialize(short, long, desc, truth, &block)
|
9
|
-
@short = short
|
10
|
-
@long = long
|
11
|
-
@desc = desc
|
12
|
-
@truth = truth
|
13
|
-
@block = block
|
14
|
-
end
|
15
|
-
|
16
|
-
def run
|
17
|
-
@block.call(@truth)
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [String] summary for help or nil if +@truth = false+
|
21
|
-
def summary(width=30, prepend=5)
|
22
|
-
return nil unless @truth
|
23
|
-
a = ""
|
24
|
-
a << "-#{@short}" if @short
|
25
|
-
a << ", " if @short && @long
|
26
|
-
a << "--[no-]#{@long}" if @long
|
27
|
-
b = @desc
|
28
|
-
s, p = '', ''
|
29
|
-
# want at least one space between name and desc
|
30
|
-
spaces = width-a.length < 0 ? 1 : width-a.length
|
31
|
-
(0...spaces).each {s << ' '}
|
32
|
-
(0...prepend).each {p << ' '}
|
33
|
-
"#{p}#{a}#{s}#{b}"
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
data/lib/clive/commands.rb
DELETED
@@ -1,317 +0,0 @@
|
|
1
|
-
class Clive
|
2
|
-
|
3
|
-
# A string which describes the command to execute
|
4
|
-
# eg. git add
|
5
|
-
# git pull
|
6
|
-
#
|
7
|
-
class Command
|
8
|
-
|
9
|
-
attr_accessor :switches, :flags, :commands
|
10
|
-
attr_accessor :name, :desc, :block, :argv
|
11
|
-
attr_accessor :base
|
12
|
-
attr_accessor :banner
|
13
|
-
|
14
|
-
# Create a new Command instance
|
15
|
-
#
|
16
|
-
# @overload initialize(base, &block)
|
17
|
-
# Creates a new base Command to house everything else
|
18
|
-
# @param [Boolean] base whether the command is the base
|
19
|
-
#
|
20
|
-
# @overload initialize(name, desc, &block)
|
21
|
-
# Creates a new Command as part of the base Command
|
22
|
-
# @param [Symbol] name the name of the command
|
23
|
-
# @param [String] desc the description of the command
|
24
|
-
#
|
25
|
-
# @yield A block to run, containing switches, flags and commands
|
26
|
-
#
|
27
|
-
def initialize(*args, &block)
|
28
|
-
@argv = []
|
29
|
-
@switches = Clive::Array.new
|
30
|
-
@flags = Clive::Array.new
|
31
|
-
@commands = Clive::Array.new
|
32
|
-
|
33
|
-
if args.length == 1 && args[0] == true
|
34
|
-
@base = true
|
35
|
-
self.instance_eval(&block)
|
36
|
-
else
|
37
|
-
@base = false
|
38
|
-
args.each do |i|
|
39
|
-
case i
|
40
|
-
when Symbol
|
41
|
-
@name = i.to_s
|
42
|
-
when String
|
43
|
-
@desc = i
|
44
|
-
end
|
45
|
-
end
|
46
|
-
@block = block
|
47
|
-
end
|
48
|
-
|
49
|
-
@banner = "Usage: #{File.basename($0, '.*')} "
|
50
|
-
@banner << (@base ? "[commands]" : @name)
|
51
|
-
@banner << " [options]"
|
52
|
-
|
53
|
-
self.build_help
|
54
|
-
end
|
55
|
-
|
56
|
-
# Getter to find booleans
|
57
|
-
def booleans
|
58
|
-
@switches.find_all {|i| i.is_a?(Boolean)}
|
59
|
-
end
|
60
|
-
|
61
|
-
# Run the block that was passed to find switches, flags, etc.
|
62
|
-
#
|
63
|
-
# This should only be called if the command has been called
|
64
|
-
# as the block could contain other actions to perform only
|
65
|
-
# when called.
|
66
|
-
#
|
67
|
-
def find
|
68
|
-
return nil if @base
|
69
|
-
self.instance_eval(&@block)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Parse the ARGV passed from the command line, and run
|
73
|
-
#
|
74
|
-
# @param [Array] argv the command line input, usually just ARGV
|
75
|
-
# @return [Array] any arguments that were present in the input but not used
|
76
|
-
#
|
77
|
-
def run(argv=[])
|
78
|
-
tokens = argv
|
79
|
-
tokens = tokenize(argv) if @base
|
80
|
-
|
81
|
-
r = []
|
82
|
-
tokens.each do |i|
|
83
|
-
k, v = i[0], i[1]
|
84
|
-
case k
|
85
|
-
when :command
|
86
|
-
v.run(i[2])
|
87
|
-
when :switch
|
88
|
-
v.run
|
89
|
-
when :flag
|
90
|
-
raise MissingArgument.new(v.long||v.short) unless i[2]
|
91
|
-
v.run(i[2])
|
92
|
-
when :argument
|
93
|
-
r << v
|
94
|
-
end
|
95
|
-
end
|
96
|
-
r
|
97
|
-
end
|
98
|
-
|
99
|
-
# Turns the command line input into a series of tokens.
|
100
|
-
# It will only raise errors if this is the base command instance.
|
101
|
-
#
|
102
|
-
# @param [Array] argv the command line input
|
103
|
-
# @return [Array] a series of tokens
|
104
|
-
#
|
105
|
-
# @example
|
106
|
-
#
|
107
|
-
# c.tokenize(["add", "-al", "--verbose"])
|
108
|
-
# #=> [[:command, #<Clive::Command>, ...args...], [:switch, "a",
|
109
|
-
# #<Clive::Switch>], [:switch, "l", #<Clive::Switch>], [:switch,
|
110
|
-
# "verbose", #<Clive::Switch>]]
|
111
|
-
#
|
112
|
-
def tokenize(argv)
|
113
|
-
tokens = []
|
114
|
-
pre = Tokens.to_tokens(argv)
|
115
|
-
command = nil
|
116
|
-
@argv = argv unless @base
|
117
|
-
|
118
|
-
pre.each do |i|
|
119
|
-
k, v = i[0], i[1]
|
120
|
-
case k
|
121
|
-
when :word
|
122
|
-
if @commands[v]
|
123
|
-
command = @commands[v]
|
124
|
-
pre -= [[:word, v]]
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
if command
|
130
|
-
command.find
|
131
|
-
# tokenify the command
|
132
|
-
tokens << [:command, command, command.tokenize(Tokens.to_array(pre))]
|
133
|
-
pre = Tokens.to_tokens(command.argv)
|
134
|
-
end
|
135
|
-
|
136
|
-
pre.each do |i|
|
137
|
-
k, v = i[0], i[1]
|
138
|
-
case k
|
139
|
-
when :short, :long
|
140
|
-
if switch = @switches[v]
|
141
|
-
tokens << [:switch, switch]
|
142
|
-
pre -= [[k, v]] unless @base
|
143
|
-
elsif flag = @flags[v]
|
144
|
-
tokens << [:flag, flag]
|
145
|
-
pre -= [[k, v]] unless @base
|
146
|
-
else
|
147
|
-
raise InvalidOption.new(v) if @base
|
148
|
-
end
|
149
|
-
when :word
|
150
|
-
if tokens.last
|
151
|
-
case tokens.last[0]
|
152
|
-
when :flag
|
153
|
-
tokens.last[2] = v
|
154
|
-
else
|
155
|
-
tokens << [:argument, v] if @base
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
@argv = Tokens.to_array(pre)
|
161
|
-
|
162
|
-
tokens
|
163
|
-
end
|
164
|
-
|
165
|
-
#### CREATION HELPERS ####
|
166
|
-
|
167
|
-
# Add a new switch to +@switches+
|
168
|
-
#
|
169
|
-
# @overload switch(short, long, desc, &block)
|
170
|
-
# Creates a new switch
|
171
|
-
# @param [Symbol] short single character for short switch, eg. +:v+ => +-v+
|
172
|
-
# @param [Symbol] long longer switch to be used, eg. +:verbose+ => +--verbose+
|
173
|
-
# @param [String] desc the description for the switch
|
174
|
-
#
|
175
|
-
# @yield A block to run if the switch is triggered
|
176
|
-
#
|
177
|
-
def switch(*args, &block)
|
178
|
-
short, long, desc = nil
|
179
|
-
args.each do |i|
|
180
|
-
if i.is_a? String
|
181
|
-
desc = i
|
182
|
-
elsif i.length == 1
|
183
|
-
short = i.to_s
|
184
|
-
else
|
185
|
-
long = i.to_s
|
186
|
-
end
|
187
|
-
end
|
188
|
-
@switches << Switch.new(short, long, desc, &block)
|
189
|
-
end
|
190
|
-
|
191
|
-
# Add a new command to +@commands+
|
192
|
-
#
|
193
|
-
# @overload command(name, desc, &block)
|
194
|
-
# Creates a new command
|
195
|
-
# @param [Symbol] name the name of the command, eg. +:add+ for +git add+
|
196
|
-
# @param [String] desc description of the command
|
197
|
-
#
|
198
|
-
# @yield A block to run when the command is called, can contain switches
|
199
|
-
# and flags
|
200
|
-
#
|
201
|
-
def command(*args, &block)
|
202
|
-
name, desc = nil
|
203
|
-
args.each do |i|
|
204
|
-
if i.is_a? String
|
205
|
-
desc = i
|
206
|
-
else
|
207
|
-
name = i
|
208
|
-
end
|
209
|
-
end
|
210
|
-
@commands << Command.new(name, desc, &block)
|
211
|
-
end
|
212
|
-
|
213
|
-
# Add a new flag to +@flags+
|
214
|
-
#
|
215
|
-
# @overload flag(short, long, desc, &block)
|
216
|
-
# Creates a new flag
|
217
|
-
# @param [Symbol] short single character for short flag, eg. +:t+ => +-t 10+
|
218
|
-
# @param [Symbol] long longer switch to be used, eg. +:tries+ => +--tries=10+
|
219
|
-
# @param [String] desc the description for the flag
|
220
|
-
#
|
221
|
-
# @yield [String] A block to be run if switch is triggered
|
222
|
-
def flag(*args, &block)
|
223
|
-
short, long, desc = nil
|
224
|
-
args.each do |i|
|
225
|
-
if i.is_a? String
|
226
|
-
desc = i
|
227
|
-
elsif i.length == 1
|
228
|
-
short = i.to_s
|
229
|
-
else
|
230
|
-
long = i.to_s
|
231
|
-
end
|
232
|
-
end
|
233
|
-
@flags << Flag.new(short, long, desc, &block)
|
234
|
-
end
|
235
|
-
|
236
|
-
# Creates a boolean switch. This is done by adding two switches of
|
237
|
-
# Boolean type to +@switches+, one is created normally the other has
|
238
|
-
# "no-" appended to the long name and has no short name.
|
239
|
-
#
|
240
|
-
# @overload boolean(short, long, desc, &block)
|
241
|
-
# Creates a new boolean switch
|
242
|
-
# @param [Symbol] short single character for short label
|
243
|
-
# @param [Symbol] long longer name to be used
|
244
|
-
# @param [String] desc the description of the boolean
|
245
|
-
#
|
246
|
-
# @yield [Boolean] A block to be run if switch is triggered
|
247
|
-
def boolean(*args, &block)
|
248
|
-
short, long, desc = nil
|
249
|
-
args.each do |i|
|
250
|
-
if i.is_a? String
|
251
|
-
desc = i
|
252
|
-
elsif i.length == 1
|
253
|
-
short = i.to_s
|
254
|
-
else
|
255
|
-
long = i.to_s
|
256
|
-
end
|
257
|
-
end
|
258
|
-
raise "Boolean switch must have long name" unless long
|
259
|
-
@switches << Boolean.new(short, long, desc, true, &block)
|
260
|
-
@switches << Boolean.new(nil, "no-#{long}", desc, false, &block)
|
261
|
-
end
|
262
|
-
|
263
|
-
#### HELP STUFF ####
|
264
|
-
|
265
|
-
# This actually creates a switch with "-h" and "--help" that control
|
266
|
-
# the help on this command. If this is the base class it will also
|
267
|
-
# creates a "help [command]" command.
|
268
|
-
def build_help
|
269
|
-
@switches << Switch.new("h", "help", "Display help") do
|
270
|
-
puts self.help
|
271
|
-
exit 0
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
# Set the banner
|
276
|
-
def banner(val)
|
277
|
-
@banner = val
|
278
|
-
end
|
279
|
-
|
280
|
-
def summary(width=30, prepend=5)
|
281
|
-
a = @name
|
282
|
-
b = @desc
|
283
|
-
s, p = '', ''
|
284
|
-
(0..width-a.length).each {s << ' '}
|
285
|
-
(0..prepend).each {p << ' '}
|
286
|
-
"#{p}#{a}#{s}#{b}"
|
287
|
-
end
|
288
|
-
|
289
|
-
# Generate the summary for help, show all flags and switches, but do not
|
290
|
-
# show the flags and switches within each command. Should also prepend the
|
291
|
-
# banner.
|
292
|
-
def help(width=30, prepend=5)
|
293
|
-
summary = "#{@banner}\n"
|
294
|
-
|
295
|
-
if @switches.length > 0 || @flags.length > 0
|
296
|
-
summary << "\n Options:\n"
|
297
|
-
@switches.each do |i|
|
298
|
-
summary << i.summary(width, prepend) << "\n" if i.summary
|
299
|
-
end
|
300
|
-
@flags.each do |i|
|
301
|
-
summary << i.summary(width, prepend) << "\n"
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
if @commands.length > 0
|
306
|
-
summary << "\nCommands:\n"
|
307
|
-
@commands.each do |i|
|
308
|
-
summary << i.summary(width, prepend) << "\n"
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
summary
|
313
|
-
end
|
314
|
-
|
315
|
-
|
316
|
-
end
|
317
|
-
end
|