sass 3.3.0.alpha.93 → 3.3.0.alpha.101
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/REVISION +1 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/bin/sass +2 -1
- data/bin/sass-convert +2 -1
- data/bin/scss +2 -1
- data/lib/sass/cache_stores/chain.rb +1 -1
- data/lib/sass/cache_stores/filesystem.rb +0 -1
- data/lib/sass/engine.rb +7 -1
- data/lib/sass/exec.rb +1 -0
- data/lib/sass/importers/filesystem.rb +1 -1
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +1 -1
- data/lib/sass/script/funcall.rb +43 -8
- data/lib/sass/script/functions.rb +8 -16
- data/lib/sass/script/lexer.rb +0 -2
- data/lib/sass/script/parser.rb +26 -25
- data/lib/sass/scss/parser.rb +13 -1
- data/lib/sass/selector/simple_sequence.rb +1 -1
- data/lib/sass/tree/comment_node.rb +2 -2
- data/lib/sass/tree/visitors/cssize.rb +10 -1
- data/lib/sass/tree/visitors/perform.rb +4 -2
- data/lib/sass/util.rb +54 -1
- data/lib/sass/util/multibyte_string_scanner.rb +29 -8
- data/test/sass/engine_test.rb +20 -4
- data/test/sass/extend_test.rb +15 -0
- data/test/sass/functions_test.rb +20 -1
- data/test/sass/script_test.rb +5 -1
- data/vendor/listen/CHANGELOG.md +76 -2
- data/vendor/listen/CONTRIBUTING.md +38 -0
- data/vendor/listen/Gemfile +8 -1
- data/vendor/listen/Guardfile +1 -1
- data/vendor/listen/LICENSE +1 -1
- data/vendor/listen/README.md +8 -5
- data/vendor/listen/lib/listen.rb +7 -5
- data/vendor/listen/lib/listen/adapter.rb +76 -29
- data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
- data/vendor/listen/lib/listen/adapters/darwin.rb +11 -10
- data/vendor/listen/lib/listen/adapters/linux.rb +33 -30
- data/vendor/listen/lib/listen/adapters/polling.rb +2 -1
- data/vendor/listen/lib/listen/adapters/windows.rb +27 -21
- data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
- data/vendor/listen/lib/listen/directory_record.rb +63 -10
- data/vendor/listen/lib/listen/listener.rb +22 -0
- data/vendor/listen/lib/listen/multi_listener.rb +22 -0
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/listen.gemspec +0 -4
- data/vendor/listen/spec/listen/adapter_spec.rb +45 -4
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +6 -0
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +6 -0
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +7 -1
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
- data/vendor/listen/spec/listen/directory_record_spec.rb +91 -4
- data/vendor/listen/spec/listen/listener_spec.rb +14 -0
- data/vendor/listen/spec/listen/multi_listener_spec.rb +19 -1
- data/vendor/listen/spec/spec_helper.rb +6 -3
- data/vendor/listen/spec/support/adapter_helper.rb +125 -212
- data/vendor/listen/spec/support/listeners_helper.rb +13 -1
- data/vendor/listen/spec/support/platform_helper.rb +4 -0
- metadata +11 -6
@@ -18,7 +18,11 @@ module Listen
|
|
18
18
|
# Defines the used precision based on the type of mtime returned by the
|
19
19
|
# system (whether its in milliseconds or just seconds)
|
20
20
|
#
|
21
|
-
|
21
|
+
begin
|
22
|
+
HIGH_PRECISION_SUPPORTED = File.mtime(__FILE__).to_f.to_s[-2..-1] != '.0'
|
23
|
+
rescue
|
24
|
+
HIGH_PRECISION_SUPPORTED = false
|
25
|
+
end
|
22
26
|
|
23
27
|
# Data structure used to save meta data about a path
|
24
28
|
#
|
@@ -88,6 +92,17 @@ module Listen
|
|
88
92
|
@ignoring_patterns.merge(regexps)
|
89
93
|
end
|
90
94
|
|
95
|
+
# Replaces ignoring patterns in the record.
|
96
|
+
#
|
97
|
+
# @example Ignore only these paths
|
98
|
+
# ignore! %r{^ignored/path/}, /man/
|
99
|
+
#
|
100
|
+
# @param [Regexp] regexp a pattern for ignoring paths
|
101
|
+
#
|
102
|
+
def ignore!(*regexps)
|
103
|
+
@ignoring_patterns.replace(regexps)
|
104
|
+
end
|
105
|
+
|
91
106
|
# Adds filtering patterns to the listener.
|
92
107
|
#
|
93
108
|
# @example Filter some files
|
@@ -99,6 +114,17 @@ module Listen
|
|
99
114
|
@filtering_patterns.merge(regexps)
|
100
115
|
end
|
101
116
|
|
117
|
+
# Replaces filtering patterns in the listener.
|
118
|
+
#
|
119
|
+
# @example Filter only these files
|
120
|
+
# ignore /\.txt$/, /.*\.zip/
|
121
|
+
#
|
122
|
+
# @param [Regexp] regexp a pattern for filtering paths
|
123
|
+
#
|
124
|
+
def filter!(*regexps)
|
125
|
+
@filtering_patterns.replace(regexps)
|
126
|
+
end
|
127
|
+
|
102
128
|
# Returns whether a path should be ignored or not.
|
103
129
|
#
|
104
130
|
# @param [String] path the path to test.
|
@@ -163,6 +189,7 @@ module Listen
|
|
163
189
|
#
|
164
190
|
def relative_to_base(path)
|
165
191
|
return nil unless path[@directory]
|
192
|
+
path = path.force_encoding("BINARY") if path.respond_to?(:force_encoding)
|
166
193
|
path.sub(%r{^#{Regexp.quote(@directory)}#{File::SEPARATOR}?}, '')
|
167
194
|
end
|
168
195
|
|
@@ -198,8 +225,11 @@ module Listen
|
|
198
225
|
|
199
226
|
# First check if we are in the same second (to update checksums)
|
200
227
|
# before checking the time difference
|
201
|
-
if
|
202
|
-
# Update the
|
228
|
+
if (meta_data.mtime.to_i == new_mtime.to_i && content_modified?(path)) || meta_data.mtime < new_mtime
|
229
|
+
# Update the sha1 checksum of the file
|
230
|
+
insert_sha1_checksum(path)
|
231
|
+
|
232
|
+
# Update the meta data of the file
|
203
233
|
meta_data.mtime = new_mtime
|
204
234
|
@paths[directory][basename] = meta_data
|
205
235
|
|
@@ -247,17 +277,40 @@ module Listen
|
|
247
277
|
|
248
278
|
# Returns whether or not a file's content has been modified by
|
249
279
|
# comparing the SHA1-checksum to a stored one.
|
280
|
+
# Ensure that the SHA1-checksum is inserted to the sha1_checksums
|
281
|
+
# array for later comparaison if false.
|
250
282
|
#
|
251
283
|
# @param [String] path the file path
|
252
284
|
#
|
253
285
|
def content_modified?(path)
|
254
|
-
sha1_checksum =
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
286
|
+
@sha1_checksum = sha1_checksum(path)
|
287
|
+
if @sha1_checksums[path] == @sha1_checksum || !@sha1_checksums.key?(path)
|
288
|
+
insert_sha1_checksum(path)
|
289
|
+
false
|
290
|
+
else
|
291
|
+
true
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
# Inserts a SHA1-checksum path in @SHA1-checksums hash.
|
296
|
+
#
|
297
|
+
# @param [String] path the SHA1-checksum path to insert in @sha1_checksums.
|
298
|
+
#
|
299
|
+
def insert_sha1_checksum(path)
|
300
|
+
if @sha1_checksum ||= sha1_checksum(path)
|
301
|
+
@sha1_checksums[path] = @sha1_checksum
|
302
|
+
@sha1_checksum = nil
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
# Returns the SHA1-checksum for the file path.
|
307
|
+
#
|
308
|
+
# @param [String] path the file path
|
309
|
+
#
|
310
|
+
def sha1_checksum(path)
|
311
|
+
Digest::SHA1.file(path).to_s
|
312
|
+
rescue Errno::EACCES, Errno::ENOENT, Errno::ENXIO, Errno::EOPNOTSUPP
|
313
|
+
nil
|
261
314
|
end
|
262
315
|
|
263
316
|
# Traverses the base directory looking for paths that should
|
@@ -93,6 +93,17 @@ module Listen
|
|
93
93
|
self
|
94
94
|
end
|
95
95
|
|
96
|
+
# Replaces ignoring patterns in the listener.
|
97
|
+
#
|
98
|
+
# @param (see Listen::DirectoryRecord#ignore!)
|
99
|
+
#
|
100
|
+
# @return [Listen::Listener] the listener
|
101
|
+
#
|
102
|
+
def ignore!(*regexps)
|
103
|
+
@directory_record.ignore!(*regexps)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
96
107
|
# Adds filtering patterns to the listener.
|
97
108
|
#
|
98
109
|
# @param (see Listen::DirectoryRecord#filter)
|
@@ -104,6 +115,17 @@ module Listen
|
|
104
115
|
self
|
105
116
|
end
|
106
117
|
|
118
|
+
# Replacing filtering patterns in the listener.
|
119
|
+
#
|
120
|
+
# @param (see Listen::DirectoryRecord#filter!)
|
121
|
+
#
|
122
|
+
# @return [Listen::Listener] the listener
|
123
|
+
#
|
124
|
+
def filter!(*regexps)
|
125
|
+
@directory_record.filter!(*regexps)
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
107
129
|
# Sets the latency for the adapter. This is a helper method
|
108
130
|
# to simplify changing the latency directly from the listener.
|
109
131
|
#
|
@@ -65,6 +65,17 @@ module Listen
|
|
65
65
|
self
|
66
66
|
end
|
67
67
|
|
68
|
+
# Replaces ignored paths in the listener.
|
69
|
+
#
|
70
|
+
# @param (see Listen::DirectoryRecord#ignore!)
|
71
|
+
#
|
72
|
+
# @return [Listen::Listener] the listener
|
73
|
+
#
|
74
|
+
def ignore!(*paths)
|
75
|
+
@directories_records.each { |r| r.ignore!(*paths) }
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
68
79
|
# Adds file filters to the listener.
|
69
80
|
#
|
70
81
|
# @param (see Listen::DirectoryRecord#filter)
|
@@ -76,6 +87,17 @@ module Listen
|
|
76
87
|
self
|
77
88
|
end
|
78
89
|
|
90
|
+
# Replaces file filters in the listener.
|
91
|
+
#
|
92
|
+
# @param (see Listen::DirectoryRecord#filter!)
|
93
|
+
#
|
94
|
+
# @return [Listen::Listener] the listener
|
95
|
+
#
|
96
|
+
def filter!(*regexps)
|
97
|
+
@directories_records.each { |r| r.filter!(*regexps) }
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
79
101
|
# Runs the callback passing it the changes if there are any.
|
80
102
|
#
|
81
103
|
# @param (see Listen::DirectoryRecord#fetch_changes)
|
@@ -15,10 +15,6 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.required_rubygems_version = '>= 1.3.6'
|
16
16
|
s.rubyforge_project = 'listen'
|
17
17
|
|
18
|
-
s.add_dependency 'rb-fsevent', '~> 0.9.1'
|
19
|
-
s.add_dependency 'rb-inotify', '~> 0.8.8'
|
20
|
-
s.add_dependency 'rb-fchange', '~> 0.0.5'
|
21
|
-
|
22
18
|
s.add_development_dependency 'bundler'
|
23
19
|
|
24
20
|
s.files = Dir.glob('{lib}/**/*') + %w[CHANGELOG.md LICENSE README.md]
|
@@ -21,6 +21,7 @@ describe Listen::Adapter do
|
|
21
21
|
before do
|
22
22
|
Listen::Adapters::Darwin.stub(:usable_and_works?) { false }
|
23
23
|
Listen::Adapters::Linux.stub(:usable_and_works?) { false }
|
24
|
+
Listen::Adapters::BSD.stub(:usable_and_works?) { false }
|
24
25
|
Listen::Adapters::Windows.stub(:usable_and_works?) { false }
|
25
26
|
end
|
26
27
|
|
@@ -31,14 +32,28 @@ describe Listen::Adapter do
|
|
31
32
|
described_class.select_and_initialize('dir')
|
32
33
|
end
|
33
34
|
|
34
|
-
it
|
35
|
-
Kernel.should_receive(:warn).with(Listen::Adapter::POLLING_FALLBACK_MESSAGE)
|
35
|
+
it 'warns with the default polling fallback message' do
|
36
|
+
Kernel.should_receive(:warn).with(/#{Listen::Adapter::POLLING_FALLBACK_MESSAGE}/)
|
36
37
|
described_class.select_and_initialize('dir')
|
37
38
|
end
|
38
39
|
|
40
|
+
context 'when the dependencies of an adapter are not satisfied' do
|
41
|
+
before do
|
42
|
+
Listen::Adapters::Darwin.stub(:usable_and_works?).and_raise(Listen::DependencyManager::Error)
|
43
|
+
Listen::Adapters::Linux.stub(:usable_and_works?).and_raise(Listen::DependencyManager::Error)
|
44
|
+
Listen::Adapters::BSD.stub(:usable_and_works?).and_raise(Listen::DependencyManager::Error)
|
45
|
+
Listen::Adapters::Windows.stub(:usable_and_works?).and_raise(Listen::DependencyManager::Error)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'invites the user to satisfy the dependencies of the adapter in the warning' do
|
49
|
+
Kernel.should_receive(:warn).with(/#{Listen::Adapter::MISSING_DEPENDENCY_MESSAGE}/)
|
50
|
+
described_class.select_and_initialize('dir')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
39
54
|
context "with custom polling_fallback_message option" do
|
40
55
|
it "warns with the custom polling fallback message" do
|
41
|
-
Kernel.should_receive(:warn).with(
|
56
|
+
Kernel.should_receive(:warn).with(/custom/)
|
42
57
|
described_class.select_and_initialize('dir', :polling_fallback_message => 'custom')
|
43
58
|
end
|
44
59
|
end
|
@@ -83,6 +98,22 @@ describe Listen::Adapter do
|
|
83
98
|
end
|
84
99
|
end
|
85
100
|
|
101
|
+
context "on BSD" do
|
102
|
+
before { Listen::Adapters::BSD.stub(:usable_and_works?) { true } }
|
103
|
+
|
104
|
+
it "uses Listen::Adapters::BSD" do
|
105
|
+
Listen::Adapters::BSD.should_receive(:new).with('dir', {})
|
106
|
+
described_class.select_and_initialize('dir')
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when the use of the polling adapter is forced' do
|
110
|
+
it 'uses Listen::Adapters::Polling' do
|
111
|
+
Listen::Adapters::Polling.should_receive(:new).with('dir', {})
|
112
|
+
described_class.select_and_initialize('dir', :force_polling => true)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
86
117
|
context "on Windows" do
|
87
118
|
before { Listen::Adapters::Windows.stub(:usable_and_works?) { true } }
|
88
119
|
|
@@ -100,8 +131,18 @@ describe Listen::Adapter do
|
|
100
131
|
end
|
101
132
|
end
|
102
133
|
|
103
|
-
[Listen::Adapters::Darwin, Listen::Adapters::Linux,
|
134
|
+
[Listen::Adapters::Darwin, Listen::Adapters::Linux,
|
135
|
+
Listen::Adapters::BSD, Listen::Adapters::Windows].each do
|
136
|
+
|adapter_class|
|
104
137
|
if adapter_class.usable?
|
138
|
+
describe '.usable?' do
|
139
|
+
it 'checks the dependencies' do
|
140
|
+
adapter_class.should_receive(:load_depenencies)
|
141
|
+
adapter_class.should_receive(:dependencies_loaded?)
|
142
|
+
adapter_class.usable?
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
105
146
|
describe '.usable_and_works?' do
|
106
147
|
it 'checks if the adapter is usable' do
|
107
148
|
adapter_class.stub(:works?)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Listen::Adapters::BSD do
|
4
|
+
if bsd?
|
5
|
+
if Listen::Adapters::BSD.usable?
|
6
|
+
it "is usable on BSD" do
|
7
|
+
described_class.should be_usable
|
8
|
+
end
|
9
|
+
|
10
|
+
it_should_behave_like 'a filesystem adapter'
|
11
|
+
it_should_behave_like 'an adapter that call properly listener#on_change'
|
12
|
+
else
|
13
|
+
it "isn't usable on BSD with #{RbConfig::CONFIG['RUBY_INSTALL_NAME']}" do
|
14
|
+
described_class.should_not be_usable
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
if linux?
|
20
|
+
it "isn't usable on Linux" do
|
21
|
+
described_class.should_not be_usable
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
if mac?
|
26
|
+
it "isn't usable on Mac OS X" do
|
27
|
+
described_class.should_not be_usable
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
if windows?
|
32
|
+
it "isn't usable on Windows" do
|
33
|
+
described_class.should_not be_usable
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -7,7 +7,7 @@ describe Listen::Adapters::Windows do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it_should_behave_like 'a filesystem adapter'
|
10
|
-
it_should_behave_like 'an adapter that call properly listener#on_change'
|
10
|
+
it_should_behave_like 'an adapter that call properly listener#on_change'
|
11
11
|
end
|
12
12
|
|
13
13
|
if mac?
|
@@ -16,6 +16,12 @@ describe Listen::Adapters::Windows do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
if bsd?
|
20
|
+
it "isn't usable on BSD" do
|
21
|
+
described_class.should_not be_usable
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
19
25
|
if linux?
|
20
26
|
it "isn't usable on Linux" do
|
21
27
|
described_class.should_not be_usable
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Listen::DependencyManager do
|
4
|
+
let(:dependency) { Listen::DependencyManager::Dependency.new('listen', '~> 0.0.1') }
|
5
|
+
|
6
|
+
subject { Class.new { extend Listen::DependencyManager } }
|
7
|
+
|
8
|
+
before { described_class.clear_loaded }
|
9
|
+
|
10
|
+
describe '.add_loaded' do
|
11
|
+
it 'adds a dependency to the list of loaded dependencies' do
|
12
|
+
described_class.add_loaded dependency
|
13
|
+
described_class.already_loaded?(dependency).should be_true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.already_loaded?' do
|
18
|
+
it 'returns false when a dependency is not in the list of loaded dependencies' do
|
19
|
+
described_class.already_loaded?(dependency).should be_false
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns true when a dependency is in the list of loaded dependencies' do
|
23
|
+
described_class.add_loaded dependency
|
24
|
+
described_class.already_loaded?(dependency).should be_true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '.clear_loaded' do
|
29
|
+
it 'clears the whole list of loaded dependencies' do
|
30
|
+
described_class.add_loaded dependency
|
31
|
+
described_class.already_loaded?(dependency).should be_true
|
32
|
+
described_class.clear_loaded
|
33
|
+
described_class.already_loaded?(dependency).should be_false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#dependency' do
|
38
|
+
it 'registers a new dependency for the managed class' do
|
39
|
+
subject.dependency 'listen', '~> 0.0.1'
|
40
|
+
subject.dependencies_loaded?.should be_false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#load_depenencies' do
|
45
|
+
before { subject.dependency 'listen', '~> 0.0.1' }
|
46
|
+
|
47
|
+
context 'when dependencies can be loaded' do
|
48
|
+
before { subject.stub(:gem, :require) }
|
49
|
+
|
50
|
+
it 'loads all the registerd dependencies' do
|
51
|
+
subject.load_depenencies
|
52
|
+
subject.dependencies_loaded?.should be_true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when dependencies can not be loaded' do
|
57
|
+
it 'raises an error' do
|
58
|
+
expect {
|
59
|
+
subject.load_depenencies
|
60
|
+
}.to raise_error(described_class::Error)
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when running under bundler' do
|
64
|
+
before { subject.should_receive(:running_under_bundler?).and_return(true) }
|
65
|
+
|
66
|
+
it 'includes the Gemfile declaration to satisfy the dependency' do
|
67
|
+
begin
|
68
|
+
subject.load_depenencies
|
69
|
+
rescue described_class::Error => e
|
70
|
+
e.message.should include("gem 'listen', '~> 0.0.1'")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when not running under bundler' do
|
76
|
+
before { subject.should_receive(:running_under_bundler?).and_return(false) }
|
77
|
+
|
78
|
+
it 'includes the command to install the dependency' do
|
79
|
+
begin
|
80
|
+
subject.load_depenencies
|
81
|
+
rescue described_class::Error => e
|
82
|
+
e.message.should include("gem install --version '~> 0.0.1' listen")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#dependencies_loaded?' do
|
90
|
+
it 'return false when dependencies are not loaded' do
|
91
|
+
subject.dependency 'listen', '~> 0.0.1'
|
92
|
+
subject.dependencies_loaded?.should be_false
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'return true when dependencies are loaded' do
|
96
|
+
subject.stub(:gem, :require)
|
97
|
+
|
98
|
+
subject.dependency 'listen', '~> 0.0.1'
|
99
|
+
subject.load_depenencies
|
100
|
+
subject.dependencies_loaded?.should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'return true when there are no dependencies to load' do
|
104
|
+
subject.dependencies_loaded?.should be_true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|