vimcolorscheme 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.
- data/Gemfile.lock +28 -0
- data/README.md +293 -0
- data/examples/simple_theme.rb +20 -0
- data/examples/vimscheme1.rb +27 -0
- data/lib/vimcolorscheme.rb +13 -0
- data/lib/vimcolorscheme/base.rb +11 -0
- data/lib/vimcolorscheme/comment_node.rb +15 -0
- data/lib/vimcolorscheme/document.rb +149 -0
- data/lib/vimcolorscheme/hex2term.rb +357 -0
- data/lib/vimcolorscheme/highlight_node.rb +114 -0
- data/lib/vimcolorscheme/raw_node.rb +15 -0
- data/spec/base_spec.rb +92 -0
- data/spec/comment_node_spec.rb +22 -0
- data/spec/hex2term_spec.rb +25 -0
- data/spec/highlight_node_spec.rb +77 -0
- data/spec/raw_node_spec.rb +12 -0
- data/spec/spec_helper.rb +1 -0
- data/vimcolorscheme.gemspec +16 -0
- metadata +64 -0
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
coderay (1.0.6)
|
5
|
+
diff-lcs (1.1.3)
|
6
|
+
method_source (0.7.1)
|
7
|
+
pry (0.9.9.4)
|
8
|
+
coderay (~> 1.0.5)
|
9
|
+
method_source (~> 0.7.1)
|
10
|
+
slop (>= 2.4.4, < 3)
|
11
|
+
rake (0.9.2.2)
|
12
|
+
rspec (2.9.0)
|
13
|
+
rspec-core (~> 2.9.0)
|
14
|
+
rspec-expectations (~> 2.9.0)
|
15
|
+
rspec-mocks (~> 2.9.0)
|
16
|
+
rspec-core (2.9.0)
|
17
|
+
rspec-expectations (2.9.1)
|
18
|
+
diff-lcs (~> 1.1.3)
|
19
|
+
rspec-mocks (2.9.0)
|
20
|
+
slop (2.4.4)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
pry
|
27
|
+
rake
|
28
|
+
rspec
|
data/README.md
ADDED
@@ -0,0 +1,293 @@
|
|
1
|
+
This is a Ruby DSL for creating Vim color schemes. I personally found color
|
2
|
+
schemes difficult to get working in both terminal and graphical interfaces, this
|
3
|
+
DSL tries to remedy that by, for example, automatically filling in the value of
|
4
|
+
guibg by looking at ctermbg.
|
5
|
+
|
6
|
+
[](http://travis-ci.org/samwho/vimcolorscheme)
|
7
|
+
|
8
|
+
# Installation
|
9
|
+
|
10
|
+
Installation is standard for a Ruby gem:
|
11
|
+
|
12
|
+
gem install vimcolorscheme
|
13
|
+
|
14
|
+
# Usage
|
15
|
+
|
16
|
+
Let's start by showing you a really small example:
|
17
|
+
|
18
|
+
``` ruby
|
19
|
+
require 'vimcolorscheme'
|
20
|
+
|
21
|
+
scheme = VimColorScheme.new :scheme_name, :dark do
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
scheme.save_to_vim!
|
26
|
+
```
|
27
|
+
|
28
|
+
Here we're starting a new vim color scheme with the name of `:scheme_name`
|
29
|
+
(which will be converted into a string later) and it's going to be a dark theme.
|
30
|
+
|
31
|
+
At the end of this script we save the color scheme to our vim directory with the
|
32
|
+
`save_to_vim!` method on the scheme object. This will write our color scheme to
|
33
|
+
the file `~/.vim/colors/scheme_name.vim`. The exclamation mark means it will
|
34
|
+
overwrite if a file with that name exists. You can omit the exclamation mark if
|
35
|
+
you would rather be prompted.
|
36
|
+
|
37
|
+
## Adding highlights
|
38
|
+
|
39
|
+
Let's expand this example to actually do something useful: highlight!
|
40
|
+
|
41
|
+
``` ruby
|
42
|
+
require 'vimcolorscheme'
|
43
|
+
|
44
|
+
scheme = VimColorScheme.new :scheme_name, :dark do
|
45
|
+
highlight :Normal do
|
46
|
+
guifg '#ffffff'
|
47
|
+
guibg '#000000'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
scheme.save_to_vim!
|
52
|
+
```
|
53
|
+
|
54
|
+
The `highlight` method takes a name argument, which can be anything with a
|
55
|
+
`to_s` method and a block, which gives us access to some really cool methods.
|
56
|
+
|
57
|
+
There are methods for all of the following attributes: `gui`, `guifg`, `guibg`,
|
58
|
+
`cterm`, `ctermfg`, and `ctermbg`. Calling them with no arguments will return
|
59
|
+
their value, which is nil by default, and calling them with arguments will set
|
60
|
+
their value.
|
61
|
+
|
62
|
+
Let's have a look at what that outputs when we save the file as `vimscheme1.rb`
|
63
|
+
and run it with:
|
64
|
+
|
65
|
+
ruby vimscheme1.rb
|
66
|
+
|
67
|
+
And the output is:
|
68
|
+
|
69
|
+
``` vim
|
70
|
+
set background=dark
|
71
|
+
|
72
|
+
highlight clear
|
73
|
+
|
74
|
+
if exists('syntax_on')
|
75
|
+
syntax reset
|
76
|
+
endif
|
77
|
+
|
78
|
+
let g:colors_name = 'scheme_name'
|
79
|
+
|
80
|
+
highlight Normal gui=NONE guifg=#ffffff guibg=#000000 cterm=NONE ctermfg=231
|
81
|
+
ctermbg=16
|
82
|
+
```
|
83
|
+
|
84
|
+
The top part of the file is some obligatory boilerplate stuff such as setting
|
85
|
+
the background to light or dark, clearing the current highlighting and syntax
|
86
|
+
and setting the color scheme name inside of vim itself.
|
87
|
+
|
88
|
+
The last line is what we're interested in. The highlight line. Notice how it
|
89
|
+
has values for both the guifg _and_ ctermfg? Internally it works out what the
|
90
|
+
closest match is for the color and sets it for you.
|
91
|
+
|
92
|
+
You don't need to accept this automatic color defaulting if you don't want. To
|
93
|
+
stop it happening, just explicitly set what you want the ctermfg attribute to
|
94
|
+
be:
|
95
|
+
|
96
|
+
``` ruby
|
97
|
+
require 'vimcolorscheme'
|
98
|
+
|
99
|
+
scheme = VimColorScheme.new :scheme_name, :dark do
|
100
|
+
highlight :Normal do
|
101
|
+
guifg '#ffffff'
|
102
|
+
guibg '#000000'
|
103
|
+
|
104
|
+
ctermfg :none
|
105
|
+
ctermbg :none
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
scheme.save_to_vim!
|
110
|
+
```
|
111
|
+
|
112
|
+
### What about bold and underline and stuff?
|
113
|
+
|
114
|
+
Setting the gui and cterm elements works slightly differently. These methods
|
115
|
+
take as many arguments you give them. Let's see an example:
|
116
|
+
|
117
|
+
``` ruby
|
118
|
+
require 'vimcolorscheme'
|
119
|
+
|
120
|
+
scheme = VimColorScheme.new :scheme_name, :dark do
|
121
|
+
highlight :Normal do
|
122
|
+
guifg '#ffffff'
|
123
|
+
guibg '#000000'
|
124
|
+
|
125
|
+
ctermfg :none
|
126
|
+
ctermbg :none
|
127
|
+
|
128
|
+
gui :bold, :italic
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
scheme.save_to_vim!
|
133
|
+
```
|
134
|
+
|
135
|
+
And the corresponding output:
|
136
|
+
|
137
|
+
``` vim
|
138
|
+
set background=dark
|
139
|
+
|
140
|
+
highlight clear
|
141
|
+
|
142
|
+
if exists('syntax_on')
|
143
|
+
syntax reset
|
144
|
+
endif
|
145
|
+
|
146
|
+
let g:colors_name = 'scheme_name'
|
147
|
+
|
148
|
+
highlight Normal gui=bold,italic guifg=#ffffff guibg=#000000 cterm=bold,italic
|
149
|
+
ctermfg=NONE ctermbg=NONE
|
150
|
+
```
|
151
|
+
|
152
|
+
Notice how both `gui` _and_ `cterm` have been given bold and italic properties?
|
153
|
+
This should hopefully make color scheme development simpler and more
|
154
|
+
expressive by harnessing the power of Ruby.
|
155
|
+
|
156
|
+
## Comments
|
157
|
+
|
158
|
+
If you want to add comments into your resulting color scheme file that's
|
159
|
+
possible too! Check this out:
|
160
|
+
|
161
|
+
``` ruby
|
162
|
+
require 'vimcolorscheme'
|
163
|
+
|
164
|
+
scheme = VimColorScheme.new :scheme_name, :dark do
|
165
|
+
comment "author: Sam Rose <samwho@lbak.co.uk>"
|
166
|
+
|
167
|
+
highlight :Normal do
|
168
|
+
guifg '#ffffff'
|
169
|
+
guibg '#000000'
|
170
|
+
|
171
|
+
ctermfg :none
|
172
|
+
ctermbg :none
|
173
|
+
|
174
|
+
gui :bold, :italic
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
scheme.save_to_vim!
|
179
|
+
```
|
180
|
+
|
181
|
+
See that `comment` line near the top? That tells people that I authored this
|
182
|
+
theme. Let's see what it looks like in the vim file:
|
183
|
+
|
184
|
+
``` vim
|
185
|
+
" author: Sam Rose <samwho@lbak.co.uk>
|
186
|
+
|
187
|
+
set background=dark
|
188
|
+
|
189
|
+
highlight clear
|
190
|
+
|
191
|
+
if exists('syntax_on')
|
192
|
+
syntax reset
|
193
|
+
endif
|
194
|
+
|
195
|
+
let g:colors_name = 'scheme_name'
|
196
|
+
|
197
|
+
highlight Normal gui=bold,italic guifg=#ffffff guibg=#000000 cterm=bold,italic
|
198
|
+
ctermfg=NONE ctermbg=NONE
|
199
|
+
```
|
200
|
+
|
201
|
+
We now have a comment at the top! Sweet. The astute among you may be curious
|
202
|
+
about the placement of the boilerplate code. Why isn't it above the comment?
|
203
|
+
Comments at the start of a document are treated specially. Before the document
|
204
|
+
is created, vimcolorscheme looks through what we've done and all comments that
|
205
|
+
happen before anything else are placed at the very top of the file. In short,
|
206
|
+
all comments that you create before you create anything else will end up at the
|
207
|
+
very top of the file.
|
208
|
+
|
209
|
+
### Block comments
|
210
|
+
|
211
|
+
You can also insert comments using blocks. This following snippet of code is
|
212
|
+
exactly the same as the last one:
|
213
|
+
|
214
|
+
``` ruby
|
215
|
+
require 'vimcolorscheme'
|
216
|
+
|
217
|
+
scheme = VimColorScheme.new :scheme_name, :dark do
|
218
|
+
comment do
|
219
|
+
"author: Sam Rose <samwho@lbak.co.uk>"
|
220
|
+
end
|
221
|
+
|
222
|
+
highlight :Normal do
|
223
|
+
guifg '#ffffff'
|
224
|
+
guibg '#000000'
|
225
|
+
|
226
|
+
ctermfg :none
|
227
|
+
ctermbg :none
|
228
|
+
|
229
|
+
gui :bold, :italic
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
scheme.save_to_vim!
|
234
|
+
```
|
235
|
+
|
236
|
+
## Raw input
|
237
|
+
|
238
|
+
This DSL isn't perfect. There are things you can't do. Because of this, the
|
239
|
+
ability to implement raw strings into the document is present. With this we can
|
240
|
+
do things such as define vim variable or insert if statements into our color
|
241
|
+
scheme file. Example:
|
242
|
+
|
243
|
+
``` ruby
|
244
|
+
require 'vimcolorscheme'
|
245
|
+
|
246
|
+
scheme = VimColorScheme.new :scheme_name, :dark do
|
247
|
+
comment do
|
248
|
+
"author: Sam Rose <samwho@lbak.co.uk>"
|
249
|
+
end
|
250
|
+
|
251
|
+
raw "if version < 700"
|
252
|
+
raw " finish"
|
253
|
+
raw "endif\n"
|
254
|
+
|
255
|
+
highlight :Normal do
|
256
|
+
guifg '#ffffff'
|
257
|
+
guibg '#000000'
|
258
|
+
|
259
|
+
ctermfg :none
|
260
|
+
ctermbg :none
|
261
|
+
|
262
|
+
gui :bold, :italic
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
scheme.save_to_vim!
|
267
|
+
```
|
268
|
+
|
269
|
+
Let's see what that gives us:
|
270
|
+
|
271
|
+
``` vim
|
272
|
+
" author: Sam Rose <samwho@lbak.co.uk>
|
273
|
+
|
274
|
+
set background=dark
|
275
|
+
|
276
|
+
highlight clear
|
277
|
+
|
278
|
+
if exists('syntax_on')
|
279
|
+
syntax reset
|
280
|
+
endif
|
281
|
+
|
282
|
+
let g:colors_name = 'scheme_name'
|
283
|
+
|
284
|
+
if version < 700
|
285
|
+
finish
|
286
|
+
endif
|
287
|
+
|
288
|
+
highlight Normal gui=bold,italic guifg=#ffffff guibg=#000000
|
289
|
+
cterm=bold,italic ctermfg=NONE ctermbg=NONE
|
290
|
+
```
|
291
|
+
|
292
|
+
As expected, the if statement is just pasted in verbatim. It's not pretty, but
|
293
|
+
it lets us do things the DSL wouldn't let us do "natively".
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# In your code, this LOAD_PATH malarky won't be necessary because the gem will
|
2
|
+
# already be on your load path. This is just here for my own testing purposes so
|
3
|
+
# that I can test the examples against the latest code base.
|
4
|
+
libdir = File.absolute_path(File.dirname(__FILE__)) + '/../lib'
|
5
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
6
|
+
|
7
|
+
require 'vimcolorscheme'
|
8
|
+
|
9
|
+
VimColorScheme.new :simple_theme, :dark do
|
10
|
+
highlight :Normal do
|
11
|
+
ctermfg 231
|
12
|
+
ctermbg :none
|
13
|
+
end
|
14
|
+
|
15
|
+
comment "Highlighting for a constant in Ruby."
|
16
|
+
highlight :rubyConstant do
|
17
|
+
guifg '#ff0000'
|
18
|
+
gui :bold
|
19
|
+
end
|
20
|
+
end.save_to_vim!
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# In your code, this LOAD_PATH malarky won't be necessary because the gem will
|
2
|
+
# already be on your load path. This is just here for my own testing purposes so
|
3
|
+
# that I can test the examples against the latest code base.
|
4
|
+
libdir = File.absolute_path(File.dirname(__FILE__)) + '/../lib'
|
5
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
6
|
+
|
7
|
+
require 'vimcolorscheme'
|
8
|
+
|
9
|
+
scheme = VimColorScheme.new :scheme_name, :dark do
|
10
|
+
comment "author: Sam Rose <samwho@lbak.co.uk>"
|
11
|
+
|
12
|
+
raw "if version < 700"
|
13
|
+
raw " finish"
|
14
|
+
raw "endif\n"
|
15
|
+
|
16
|
+
highlight :Normal do
|
17
|
+
guifg '#ffffff'
|
18
|
+
guibg '#000000'
|
19
|
+
|
20
|
+
ctermfg :none
|
21
|
+
ctermbg :none
|
22
|
+
|
23
|
+
gui :bold, :italic
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
scheme.save_to_vim!
|
@@ -0,0 +1,13 @@
|
|
1
|
+
libdir = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
3
|
+
|
4
|
+
module VimColorScheme
|
5
|
+
ROOTDIR = File.expand_path(File.dirname(__FILE__) + '/..')
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'vimcolorscheme/hex2term'
|
9
|
+
require 'vimcolorscheme/highlight_node'
|
10
|
+
require 'vimcolorscheme/comment_node'
|
11
|
+
require 'vimcolorscheme/raw_node'
|
12
|
+
require 'vimcolorscheme/document'
|
13
|
+
require 'vimcolorscheme/base'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module VimColorScheme
|
2
|
+
class CommentNode
|
3
|
+
# Initializes the comment node with a comment string.
|
4
|
+
def initialize comment
|
5
|
+
@comment = comment
|
6
|
+
end
|
7
|
+
|
8
|
+
# Renders the comment node by splitting the string at newlines and then
|
9
|
+
# appending the " comment character at the start of each line and joining
|
10
|
+
# the result with newlines.
|
11
|
+
def to_s
|
12
|
+
@comment.split(/\n/).map { |str| str = '" ' + str }.join("\n") + "\n"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module VimColorScheme
|
2
|
+
class Document
|
3
|
+
# Creates a new color scheme document. The user will never call this method
|
4
|
+
# themselves but an object of this class is what they will be working with
|
5
|
+
# through the DSL.
|
6
|
+
#
|
7
|
+
# This constructor takes the name of the color scheme, whether it is light
|
8
|
+
# or dark and an optional option hash as arguments.
|
9
|
+
def initialize name, lightordark, options = {}
|
10
|
+
@name = name
|
11
|
+
@lightordark = lightordark
|
12
|
+
@options = options
|
13
|
+
@nodes = []
|
14
|
+
end
|
15
|
+
|
16
|
+
# Creates a highlight node in the document. You need to give this method
|
17
|
+
# call a name and a clock. Here's a usage example:
|
18
|
+
#
|
19
|
+
# highlight :Normal do
|
20
|
+
# cterm :bold, :underline
|
21
|
+
# end
|
22
|
+
def highlight name, &block
|
23
|
+
@nodes << HighlightNode.new(name)
|
24
|
+
@nodes.last.instance_eval(&block)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates a comment node in the document. It takes a single argument, which
|
28
|
+
# is the string that will be in the comment. You don't need to include the "
|
29
|
+
# comment character in the string, that will be done for you when the vim
|
30
|
+
# color scheme document is created.
|
31
|
+
#
|
32
|
+
# Example:
|
33
|
+
#
|
34
|
+
# comment "This is a comment!"
|
35
|
+
#
|
36
|
+
# Alternately, you can create a comment by returning a string from a block:
|
37
|
+
#
|
38
|
+
# comment do
|
39
|
+
# "This is a comment!"
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# Both examples above yield the same result.
|
43
|
+
def comment string = nil
|
44
|
+
if block_given?
|
45
|
+
@nodes << CommentNode.new(yield)
|
46
|
+
else
|
47
|
+
@nodes << CommentNode.new(string)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Creates a raw node in the current document. Raw nodes are inteded for
|
52
|
+
# users that want to insert code into their vim color scheme that we don't
|
53
|
+
# currently have a native implementation for.
|
54
|
+
#
|
55
|
+
# Example:
|
56
|
+
#
|
57
|
+
# raw "let g:my_var = 'variable!'"
|
58
|
+
#
|
59
|
+
# You can also give raw a block that returns a string:
|
60
|
+
#
|
61
|
+
# raw do
|
62
|
+
# "let g:my_var = 'variable!'"
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# The two examples above are functionally the same. The strings that are
|
66
|
+
# passed to raw will be printed as-is into the vim color scheme file.
|
67
|
+
def raw string = nil
|
68
|
+
if block_given?
|
69
|
+
@nodes << RawNode.new(yield)
|
70
|
+
else
|
71
|
+
@nodes << RawNode.new(string)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Saves this color scheme to a file. If the file exists, the user will be
|
76
|
+
# prompted as to whether or not they want to overwrite the file.
|
77
|
+
def save path
|
78
|
+
if File.exists?(path)
|
79
|
+
puts "#{path} already exists! Overwrite? y/n"
|
80
|
+
answer = gets
|
81
|
+
unless answer == 'n' or answer == 'N'
|
82
|
+
File.open(path, 'w') do |file|
|
83
|
+
file.write(to_s)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Does exactly the same as the save method excpet it doesn't prompt the user
|
90
|
+
# if the file exists, it just goes ahead and overwrites it.
|
91
|
+
def save! path
|
92
|
+
File.open(path, 'w') do |file|
|
93
|
+
file.write(to_s)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# This method will save the color scheme into the user's ~/.vim/colors
|
98
|
+
# directory. If the scheme already exists, the user will be prompted asking
|
99
|
+
# if they want to overwrite it.
|
100
|
+
def save_to_vim
|
101
|
+
save(File.expand_path("~/.vim/colors/#{@name.to_s}.vim"))
|
102
|
+
end
|
103
|
+
|
104
|
+
# This method does exactly the same as the save_to_vim method but it will
|
105
|
+
# not ask if you want to overwrite a file if it exists already, it will just
|
106
|
+
# overwrite it.
|
107
|
+
def save_to_vim!
|
108
|
+
save!(File.expand_path("~/.vim/colors/#{@name.to_s}.vim"))
|
109
|
+
end
|
110
|
+
|
111
|
+
# This method converts the object into a valid vim color scheme document. It
|
112
|
+
# is what is used to create the color schemes at the end of the DSL block.
|
113
|
+
def to_s
|
114
|
+
result = ''
|
115
|
+
|
116
|
+
# If the document starts with comments, we want to print those at the top.
|
117
|
+
top_comments = @nodes.take_while { |node| node.is_a? CommentNode }
|
118
|
+
top_comments.each do |comment|
|
119
|
+
result += comment.to_s
|
120
|
+
end
|
121
|
+
|
122
|
+
# Vanity new lines ftw.
|
123
|
+
result += "\n"
|
124
|
+
|
125
|
+
# Pop the top comments off the node list.
|
126
|
+
top_comments.length.times do
|
127
|
+
@nodes.shift
|
128
|
+
end
|
129
|
+
|
130
|
+
if @lightordark == :dark
|
131
|
+
result += "set background=dark\n\n"
|
132
|
+
else
|
133
|
+
result += "set background=light\n\n"
|
134
|
+
end
|
135
|
+
|
136
|
+
result += "highlight clear\n\n"
|
137
|
+
result += "if exists('syntax_on')\n"
|
138
|
+
result += " syntax reset\n"
|
139
|
+
result += "endif\n\n"
|
140
|
+
result += "let g:colors_name = '#{@name.to_s}'\n\n"
|
141
|
+
|
142
|
+
@nodes.each do |node|
|
143
|
+
result += node.to_s
|
144
|
+
end
|
145
|
+
|
146
|
+
return result
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|