oshpark-rqrcode 0.10.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/CHANGELOG +97 -0
- data/LICENSE +19 -0
- data/README.md +230 -0
- data/lib/rqrcode.rb +20 -0
- data/lib/rqrcode/core_ext.rb +5 -0
- data/lib/rqrcode/core_ext/array.rb +5 -0
- data/lib/rqrcode/core_ext/array/behavior.rb +12 -0
- data/lib/rqrcode/core_ext/integer.rb +5 -0
- data/lib/rqrcode/core_ext/integer/bitwise.rb +13 -0
- data/lib/rqrcode/export/ansi.rb +78 -0
- data/lib/rqrcode/export/gerber.rb +93 -0
- data/lib/rqrcode/export/html.rb +53 -0
- data/lib/rqrcode/export/png.rb +117 -0
- data/lib/rqrcode/export/svg.rb +53 -0
- data/lib/rqrcode/qrcode.rb +4 -0
- data/lib/rqrcode/qrcode/qr_8bit_byte.rb +36 -0
- data/lib/rqrcode/qrcode/qr_alphanumeric.rb +47 -0
- data/lib/rqrcode/qrcode/qr_bit_buffer.rb +99 -0
- data/lib/rqrcode/qrcode/qr_code.rb +585 -0
- data/lib/rqrcode/qrcode/qr_math.rb +63 -0
- data/lib/rqrcode/qrcode/qr_numeric.rb +57 -0
- data/lib/rqrcode/qrcode/qr_polynomial.rb +78 -0
- data/lib/rqrcode/qrcode/qr_rs_block.rb +314 -0
- data/lib/rqrcode/qrcode/qr_util.rb +272 -0
- data/lib/rqrcode/version.rb +3 -0
- data/test/data.rb +25 -0
- data/test/test_helper.rb +5 -0
- data/test/test_regresions.rb +10 -0
- data/test/test_rqrcode.rb +155 -0
- data/test/test_rqrcode_export.rb +27 -0
- metadata +128 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRMath
|
15
|
+
|
16
|
+
module_eval {
|
17
|
+
exp_table = Array.new(256)
|
18
|
+
log_table = Array.new(256)
|
19
|
+
|
20
|
+
( 0...8 ).each do |i|
|
21
|
+
exp_table[i] = 1 << i
|
22
|
+
end
|
23
|
+
|
24
|
+
( 8...256 ).each do |i|
|
25
|
+
exp_table[i] = exp_table[i - 4] \
|
26
|
+
^ exp_table[i - 5] \
|
27
|
+
^ exp_table[i - 6] \
|
28
|
+
^ exp_table[i - 8]
|
29
|
+
end
|
30
|
+
|
31
|
+
( 0...255 ).each do |i|
|
32
|
+
log_table[exp_table[i] ] = i
|
33
|
+
end
|
34
|
+
|
35
|
+
EXP_TABLE = exp_table
|
36
|
+
LOG_TABLE = log_table
|
37
|
+
}
|
38
|
+
|
39
|
+
class << self
|
40
|
+
|
41
|
+
def glog(n)
|
42
|
+
raise QRCodeRunTimeError, "glog(#{n})" if ( n < 1 )
|
43
|
+
LOG_TABLE[n]
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def gexp(n)
|
48
|
+
while n < 0
|
49
|
+
n = n + 255
|
50
|
+
end
|
51
|
+
|
52
|
+
while n >= 256
|
53
|
+
n = n - 255
|
54
|
+
end
|
55
|
+
|
56
|
+
EXP_TABLE[n]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module RQRCode
|
2
|
+
|
3
|
+
NUMERIC = ['0','1','2','3','4','5','6','7','8','9'].freeze
|
4
|
+
|
5
|
+
class QRNumeric
|
6
|
+
attr_reader :mode
|
7
|
+
|
8
|
+
def initialize( data )
|
9
|
+
@mode = QRMODE[:mode_number]
|
10
|
+
|
11
|
+
raise QRCodeArgumentError, "Not a numeric string `#{data}`" unless QRNumeric.valid_data?(data)
|
12
|
+
|
13
|
+
@data = data;
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def get_length
|
18
|
+
@data.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.valid_data? data
|
22
|
+
data.each_char do |s|
|
23
|
+
return false if NUMERIC.index(s).nil?
|
24
|
+
end
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def write( buffer)
|
30
|
+
buffer.numeric_encoding_start(get_length)
|
31
|
+
|
32
|
+
(@data.size).times do |i|
|
33
|
+
if i % 3 == 0
|
34
|
+
chars = @data[i, 3]
|
35
|
+
bit_length = get_bit_length(chars.length)
|
36
|
+
buffer.put( get_code(chars), bit_length )
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
NUMBER_LENGTH = {
|
44
|
+
3 => 10,
|
45
|
+
2 => 7,
|
46
|
+
1 => 4
|
47
|
+
}.freeze
|
48
|
+
|
49
|
+
def get_bit_length(length)
|
50
|
+
NUMBER_LENGTH[length]
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_code(chars)
|
54
|
+
chars.to_i
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRPolynomial
|
15
|
+
|
16
|
+
def initialize( num, shift )
|
17
|
+
raise QRCodeRunTimeError, "#{num.size}/#{shift}" if num.empty?
|
18
|
+
offset = 0
|
19
|
+
|
20
|
+
while offset < num.size && num[offset] == 0
|
21
|
+
offset = offset + 1
|
22
|
+
end
|
23
|
+
|
24
|
+
@num = Array.new( num.size - offset + shift )
|
25
|
+
|
26
|
+
( 0...num.size - offset ).each do |i|
|
27
|
+
@num[i] = num[i + offset]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def get( index )
|
33
|
+
@num[index]
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def get_length
|
38
|
+
@num.size
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def multiply( e )
|
43
|
+
num = Array.new( get_length + e.get_length - 1 )
|
44
|
+
|
45
|
+
( 0...get_length ).each do |i|
|
46
|
+
( 0...e.get_length ).each do |j|
|
47
|
+
tmp = num[i + j].nil? ? 0 : num[i + j]
|
48
|
+
num[i + j] = tmp ^ QRMath.gexp(QRMath.glog( get(i) ) + QRMath.glog(e.get(j)))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
return QRPolynomial.new( num, 0 )
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def mod( e )
|
57
|
+
if get_length - e.get_length < 0
|
58
|
+
return self
|
59
|
+
end
|
60
|
+
|
61
|
+
ratio = QRMath.glog(get(0)) - QRMath.glog(e.get(0))
|
62
|
+
num = Array.new(get_length)
|
63
|
+
|
64
|
+
( 0...get_length ).each do |i|
|
65
|
+
num[i] = get(i)
|
66
|
+
end
|
67
|
+
|
68
|
+
( 0...e.get_length ).each do |i|
|
69
|
+
tmp = num[i].nil? ? 0 : num[i]
|
70
|
+
num[i] = tmp ^ QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
|
71
|
+
end
|
72
|
+
|
73
|
+
return QRPolynomial.new( num, 0 ).mod(e)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,314 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRRSBlock
|
15
|
+
attr_reader :data_count, :total_count
|
16
|
+
|
17
|
+
def initialize( total_count, data_count )
|
18
|
+
@total_count = total_count
|
19
|
+
@data_count = data_count
|
20
|
+
end
|
21
|
+
|
22
|
+
# http://www.thonky.com/qr-code-tutorial/error-correction-table/
|
23
|
+
RQRCode::QRRSBlock::RS_BLOCK_TABLE = [
|
24
|
+
|
25
|
+
# L
|
26
|
+
# M
|
27
|
+
# Q
|
28
|
+
# H
|
29
|
+
|
30
|
+
# 1
|
31
|
+
[1, 26, 19],
|
32
|
+
[1, 26, 16],
|
33
|
+
[1, 26, 13],
|
34
|
+
[1, 26, 9],
|
35
|
+
|
36
|
+
# 2
|
37
|
+
[1, 44, 34],
|
38
|
+
[1, 44, 28],
|
39
|
+
[1, 44, 22],
|
40
|
+
[1, 44, 16],
|
41
|
+
|
42
|
+
# 3
|
43
|
+
[1, 70, 55],
|
44
|
+
[1, 70, 44],
|
45
|
+
[2, 35, 17],
|
46
|
+
[2, 35, 13],
|
47
|
+
|
48
|
+
# 4
|
49
|
+
[1, 100, 80],
|
50
|
+
[2, 50, 32],
|
51
|
+
[2, 50, 24],
|
52
|
+
[4, 25, 9],
|
53
|
+
|
54
|
+
# 5
|
55
|
+
[1, 134, 108],
|
56
|
+
[2, 67, 43],
|
57
|
+
[2, 33, 15, 2, 34, 16],
|
58
|
+
[2, 33, 11, 2, 34, 12],
|
59
|
+
|
60
|
+
# 6
|
61
|
+
[2, 86, 68],
|
62
|
+
[4, 43, 27],
|
63
|
+
[4, 43, 19],
|
64
|
+
[4, 43, 15],
|
65
|
+
|
66
|
+
# 7
|
67
|
+
[2, 98, 78],
|
68
|
+
[4, 49, 31],
|
69
|
+
[2, 32, 14, 4, 33, 15],
|
70
|
+
[4, 39, 13, 1, 40, 14],
|
71
|
+
|
72
|
+
# 8
|
73
|
+
[2, 121, 97],
|
74
|
+
[2, 60, 38, 2, 61, 39],
|
75
|
+
[4, 40, 18, 2, 41, 19],
|
76
|
+
[4, 40, 14, 2, 41, 15],
|
77
|
+
|
78
|
+
# 9
|
79
|
+
[2, 146, 116],
|
80
|
+
[3, 58, 36, 2, 59, 37],
|
81
|
+
[4, 36, 16, 4, 37, 17],
|
82
|
+
[4, 36, 12, 4, 37, 13],
|
83
|
+
|
84
|
+
# 10
|
85
|
+
[2, 86, 68, 2, 87, 69],
|
86
|
+
[4, 69, 43, 1, 70, 44],
|
87
|
+
[6, 43, 19, 2, 44, 20],
|
88
|
+
[6, 43, 15, 2, 44, 16],
|
89
|
+
|
90
|
+
# 11
|
91
|
+
[4, 101, 81],
|
92
|
+
[1, 80, 50, 4, 81, 51],
|
93
|
+
[4, 50, 22, 4, 51, 23],
|
94
|
+
[3, 36, 12, 8, 37, 13],
|
95
|
+
|
96
|
+
# 12
|
97
|
+
[2, 116, 92, 2, 117, 93],
|
98
|
+
[6, 58, 36, 2, 59, 37],
|
99
|
+
[4, 46, 20, 6, 47, 21],
|
100
|
+
[7, 42, 14, 4, 43, 15],
|
101
|
+
|
102
|
+
# 13
|
103
|
+
[4, 133, 107],
|
104
|
+
[8, 59, 37, 1, 60, 38],
|
105
|
+
[8, 44, 20, 4, 45, 21],
|
106
|
+
[12, 33, 11, 4, 34, 12],
|
107
|
+
|
108
|
+
# 14
|
109
|
+
[3, 145, 115, 1, 146, 116],
|
110
|
+
[4, 64, 40, 5, 65, 41],
|
111
|
+
[11, 36, 16, 5, 37, 17],
|
112
|
+
[11, 36, 12, 5, 37, 13],
|
113
|
+
|
114
|
+
# 15
|
115
|
+
[5, 109, 87, 1, 110, 88],
|
116
|
+
[5, 65, 41, 5, 66, 42],
|
117
|
+
[5, 54, 24, 7, 55, 25],
|
118
|
+
[11, 36, 12, 7, 37, 13],
|
119
|
+
|
120
|
+
# 16
|
121
|
+
[5, 122, 98, 1, 123, 99],
|
122
|
+
[7, 73, 45, 3, 74, 46],
|
123
|
+
[15, 43, 19, 2, 44, 20],
|
124
|
+
[3, 45, 15, 13, 46, 16],
|
125
|
+
|
126
|
+
# 17
|
127
|
+
[1, 135, 107, 5, 136, 108],
|
128
|
+
[10, 74, 46, 1, 75, 47],
|
129
|
+
[1, 50, 22, 15, 51, 23],
|
130
|
+
[2, 42, 14, 17, 43, 15],
|
131
|
+
|
132
|
+
# 18
|
133
|
+
[5, 150, 120, 1, 151, 121],
|
134
|
+
[9, 69, 43, 4, 70, 44],
|
135
|
+
[17, 50, 22, 1, 51, 23],
|
136
|
+
[2, 42, 14, 19, 43, 15],
|
137
|
+
|
138
|
+
# 19
|
139
|
+
[3, 141, 113, 4, 142, 114],
|
140
|
+
[3, 70, 44, 11, 71, 45],
|
141
|
+
[17, 47, 21, 4, 48, 22],
|
142
|
+
[9, 39, 13, 16, 40, 14],
|
143
|
+
|
144
|
+
# 20
|
145
|
+
[3, 135, 107, 5, 136, 108],
|
146
|
+
[3, 67, 41, 13, 68, 42],
|
147
|
+
[15, 54, 24, 5, 55, 25],
|
148
|
+
[15, 43, 15, 10, 44, 16],
|
149
|
+
|
150
|
+
# 21
|
151
|
+
[4, 144, 116, 4, 145, 117],
|
152
|
+
[17, 68, 42],
|
153
|
+
[17, 50, 22, 6, 51, 23],
|
154
|
+
[19, 46, 16, 6, 47, 17],
|
155
|
+
|
156
|
+
# 22
|
157
|
+
[2, 139, 111, 7, 140, 112],
|
158
|
+
[17, 74, 46],
|
159
|
+
[7, 54, 24, 16, 55, 25],
|
160
|
+
[34, 37, 13],
|
161
|
+
|
162
|
+
# 23
|
163
|
+
[4, 151, 121, 5, 152, 122],
|
164
|
+
[4, 75, 47, 14, 76, 48],
|
165
|
+
[11, 54, 24, 14, 55, 25],
|
166
|
+
[16, 45, 15, 14, 46, 16],
|
167
|
+
|
168
|
+
# 24
|
169
|
+
[6, 147, 117, 4, 148, 118],
|
170
|
+
[6, 73, 45, 14, 74, 46],
|
171
|
+
[11, 54, 24, 16, 55, 25],
|
172
|
+
[30, 46, 16, 2, 47, 17],
|
173
|
+
|
174
|
+
# 25
|
175
|
+
[8, 132, 106, 4, 133, 107],
|
176
|
+
[8, 75, 47, 13, 76, 48],
|
177
|
+
[7, 54, 24, 22, 55, 25],
|
178
|
+
[22, 45, 15, 13, 46, 16],
|
179
|
+
|
180
|
+
# 26
|
181
|
+
[10, 142, 114, 2, 143, 115],
|
182
|
+
[19, 74, 46, 4, 75, 47],
|
183
|
+
[28, 50, 22, 6, 51, 23],
|
184
|
+
[33, 46, 16, 4, 47, 17],
|
185
|
+
|
186
|
+
# 27
|
187
|
+
[8, 152, 122, 4, 153, 123],
|
188
|
+
[22, 73, 45, 3, 74, 46],
|
189
|
+
[8, 53, 23, 26, 54, 24],
|
190
|
+
[12, 45, 15, 28, 46, 16],
|
191
|
+
|
192
|
+
# 28
|
193
|
+
[3, 147, 117, 10, 148, 118],
|
194
|
+
[3, 73, 45, 23, 74, 46],
|
195
|
+
[4, 54, 24, 31, 55, 25],
|
196
|
+
[11, 45, 15, 31, 46, 16],
|
197
|
+
|
198
|
+
# 29
|
199
|
+
[7, 146, 116, 7, 147, 117],
|
200
|
+
[21, 73, 45, 7, 74, 46],
|
201
|
+
[1, 53, 23, 37, 54, 24],
|
202
|
+
[19, 45, 15, 26, 46, 16],
|
203
|
+
|
204
|
+
# 30
|
205
|
+
[5, 145, 115, 10, 146, 116],
|
206
|
+
[19, 75, 47, 10, 76, 48],
|
207
|
+
[15, 54, 24, 25, 55, 25],
|
208
|
+
[23, 45, 15, 25, 46, 16],
|
209
|
+
|
210
|
+
# 31
|
211
|
+
[13, 145, 115, 3, 146, 116],
|
212
|
+
[2, 74, 46, 29, 75, 47],
|
213
|
+
[42, 54, 24, 1, 55, 25],
|
214
|
+
[23, 45, 15, 28, 46, 16],
|
215
|
+
|
216
|
+
# 32
|
217
|
+
[17, 145, 115],
|
218
|
+
[10, 74, 46, 23, 75, 47],
|
219
|
+
[10, 54, 24, 35, 55, 25],
|
220
|
+
[19, 45, 15, 35, 46, 16],
|
221
|
+
|
222
|
+
# 33
|
223
|
+
[17, 145, 115, 1, 146, 116],
|
224
|
+
[14, 74, 46, 21, 75, 47],
|
225
|
+
[29, 54, 24, 19, 55, 25],
|
226
|
+
[11, 45, 15, 46, 46, 16],
|
227
|
+
|
228
|
+
# 34
|
229
|
+
[13, 145, 115, 6, 146, 116],
|
230
|
+
[14, 74, 46, 23, 75, 47],
|
231
|
+
[44, 54, 24, 7, 55, 25],
|
232
|
+
[59, 46, 16, 1, 47, 17],
|
233
|
+
|
234
|
+
# 35
|
235
|
+
[12, 151, 121, 7, 152, 122],
|
236
|
+
[12, 75, 47, 26, 76, 48],
|
237
|
+
[39, 54, 24, 14, 55, 25],
|
238
|
+
[22, 45, 15, 41, 46, 16],
|
239
|
+
|
240
|
+
# 36
|
241
|
+
[6, 151, 121, 14, 152, 122],
|
242
|
+
[6, 75, 47, 34, 76, 48],
|
243
|
+
[46, 54, 24, 10, 55, 25],
|
244
|
+
[2, 45, 15, 64, 46, 16],
|
245
|
+
|
246
|
+
# 37
|
247
|
+
[17, 152, 122, 4, 153, 123],
|
248
|
+
[29, 74, 46, 14, 75, 47],
|
249
|
+
[49, 54, 24, 10, 55, 25],
|
250
|
+
[24, 45, 15, 46, 46, 16],
|
251
|
+
|
252
|
+
# 38
|
253
|
+
[4, 152, 122, 18, 153, 123],
|
254
|
+
[13, 74, 46, 32, 75, 47],
|
255
|
+
[48, 54, 24, 14, 55, 25],
|
256
|
+
[42, 45, 15, 32, 46, 16],
|
257
|
+
|
258
|
+
# 39
|
259
|
+
[20, 147, 117, 4, 148, 118],
|
260
|
+
[40, 75, 47, 7, 76, 48],
|
261
|
+
[43, 54, 24, 22, 55, 25],
|
262
|
+
[10, 45, 15, 67, 46, 16],
|
263
|
+
|
264
|
+
# 40
|
265
|
+
[19, 148, 118, 6, 149, 119],
|
266
|
+
[18, 75, 47, 31, 76, 48],
|
267
|
+
[34, 54, 24, 34, 55, 25],
|
268
|
+
[20, 45, 15, 61, 46, 16]
|
269
|
+
|
270
|
+
]
|
271
|
+
|
272
|
+
def QRRSBlock.get_rs_blocks(version, error_correct_level)
|
273
|
+
rs_block = QRRSBlock.get_rs_block_table(version, error_correct_level)
|
274
|
+
|
275
|
+
if rs_block.nil?
|
276
|
+
raise QRCodeRunTimeError,
|
277
|
+
"bad rsblock @ version: #{version}/error_correct_level:#{error_correct_level}"
|
278
|
+
end
|
279
|
+
|
280
|
+
length = rs_block.size / 3
|
281
|
+
list = []
|
282
|
+
|
283
|
+
( 0...length ).each do |i|
|
284
|
+
count = rs_block[i * 3 + 0]
|
285
|
+
total_count = rs_block[i * 3 + 1]
|
286
|
+
data_count = rs_block[i * 3 + 2]
|
287
|
+
|
288
|
+
( 0...count ).each do |j|
|
289
|
+
list << QRRSBlock.new( total_count, data_count )
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
list
|
294
|
+
end
|
295
|
+
|
296
|
+
|
297
|
+
def QRRSBlock.get_rs_block_table(version, error_correct_level)
|
298
|
+
case error_correct_level
|
299
|
+
when QRERRORCORRECTLEVEL[:l]
|
300
|
+
QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 0]
|
301
|
+
when QRERRORCORRECTLEVEL[:m]
|
302
|
+
QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 1]
|
303
|
+
when QRERRORCORRECTLEVEL[:q]
|
304
|
+
QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 2]
|
305
|
+
when QRERRORCORRECTLEVEL[:h]
|
306
|
+
QRRSBlock::RS_BLOCK_TABLE[(version - 1) * 4 + 3]
|
307
|
+
else
|
308
|
+
nil
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
end
|