usagewatch 0.0.6.beta3 → 0.0.6
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/CHANGELOG +14 -0
- data/LICENSE.txt +1 -1
- data/README.md +3 -14
- data/examples/{linux_example.rb → example.rb} +2 -2
- data/lib/usagewatch.rb +4 -12
- data/lib/usagewatch/linux.rb +21 -50
- data/lib/usagewatch/version.rb +3 -1
- data/usagewatch.gemspec +2 -1
- metadata +6 -10
- data/examples/mac_example.rb +0 -15
- data/lib/usagewatch/mac.rb +0 -109
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
License: (MIT) Copyright (C) 2013 usagewatch Author Phil Chen, contributor Ruben Espinosa.
|
|
2
|
+
|
|
3
|
+
0.0.6 July 23 2013
|
|
4
|
+
====
|
|
5
|
+
* Removed Mac OS methods which will become a different Gem
|
|
6
|
+
* Call methods like a method class
|
|
7
|
+
* Validation to work only in Linux OS
|
|
8
|
+
* Added methods for top ten processes by CPU consumption
|
|
9
|
+
* Added methods for top ten processes by Memory consumption
|
|
10
|
+
|
|
11
|
+
0.0.6.beta3 July 22 2013
|
|
12
|
+
====
|
|
13
|
+
* Fixed a issue causing Disk I/O and Bandwidth methods to break
|
|
14
|
+
|
|
1
15
|
0.0.6.beta2 July 22 2013
|
|
2
16
|
====
|
|
3
17
|
* Added methods for Mac OS
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# usagewatch
|
|
2
2
|
|
|
3
|
-
License: (MIT) Copyright (C) 2013 Author Phil Chen,
|
|
3
|
+
License: (MIT) Copyright (C) 2013 usagewatch Author Phil Chen, contributor Ruben Espinosa.
|
|
4
4
|
|
|
5
5
|
## DESCRIPTION:
|
|
6
6
|
|
|
@@ -36,7 +36,7 @@ usw.uw_memtop
|
|
|
36
36
|
```bash
|
|
37
37
|
Run:
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
ruby example.rb
|
|
40
40
|
|
|
41
41
|
Example Output:
|
|
42
42
|
|
|
@@ -60,7 +60,6 @@ Top Ten Processes By Memory Consumption:
|
|
|
60
60
|
|
|
61
61
|
## Methods available
|
|
62
62
|
|
|
63
|
-
##### Linux
|
|
64
63
|
uw_diskused
|
|
65
64
|
uw_diskused_perc
|
|
66
65
|
uw_cpuused
|
|
@@ -75,16 +74,6 @@ Top Ten Processes By Memory Consumption:
|
|
|
75
74
|
uw_cputop
|
|
76
75
|
uw_memtop
|
|
77
76
|
|
|
78
|
-
##### Mac
|
|
79
|
-
uw_diskused
|
|
80
|
-
uw_diskused_perc
|
|
81
|
-
uw_cputop
|
|
82
|
-
uw_memtop
|
|
83
|
-
uw_load
|
|
84
|
-
uw_cpuused
|
|
85
|
-
uw_memused
|
|
86
|
-
|
|
87
|
-
|
|
88
77
|
## Notes
|
|
89
78
|
|
|
90
79
|
Disk Used is a sum of all partitions calculated in Gigabytes
|
|
@@ -113,4 +102,4 @@ RUBY VERSIONS:
|
|
|
113
102
|
ruby 1.9.3p429 (2013-05-15) [x86_64-linux]
|
|
114
103
|
|
|
115
104
|
OS VERSIONS:
|
|
116
|
-
CENTOS 5x 6x, Ubuntu 12.04, Fedora 18
|
|
105
|
+
CENTOS 5x 6x, Ubuntu 12.04, Fedora 18
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/ruby
|
|
2
2
|
|
|
3
|
-
#License: (MIT), Copyright (C) 2013 Author Phil Chen,
|
|
3
|
+
# License: (MIT), Copyright (C) 2013 usagewatch Author Phil Chen, contributor Ruben Espinosa
|
|
4
4
|
|
|
5
5
|
require 'usagewatch'
|
|
6
|
-
|
|
7
6
|
usw = Usagewatch
|
|
8
7
|
|
|
9
8
|
puts "#{usw.uw_diskused} Gigabytes Used"
|
|
@@ -19,3 +18,4 @@ puts "#{usw.uw_diskioreads}/s Current Disk Reads Completed"
|
|
|
19
18
|
puts "#{usw.uw_diskiowrites}/s Current Disk Writes Completed"
|
|
20
19
|
puts "Top Ten Processes By CPU Consumption: #{usw.uw_cputop}"
|
|
21
20
|
puts "Top Ten Processes By Memory Consumption: #{usw.uw_memtop}"
|
|
21
|
+
|
data/lib/usagewatch.rb
CHANGED
|
@@ -1,20 +1,12 @@
|
|
|
1
|
-
#License: (MIT), Copyright (C) 2013 Author Phil Chen,
|
|
1
|
+
# License: (MIT), Copyright (C) 2013 usagewatch Author Phil Chen, contributor Ruben Espinosa
|
|
2
2
|
|
|
3
3
|
require "usagewatch/version"
|
|
4
4
|
|
|
5
5
|
os = RUBY_PLATFORM
|
|
6
|
-
text = "OS
|
|
6
|
+
text = "Unsupported OS!"
|
|
7
7
|
|
|
8
|
-
if os.include? "
|
|
9
|
-
require "usagewatch/mac"
|
|
10
|
-
puts "Mac version is under development"
|
|
11
|
-
elsif os.include? "linux"
|
|
8
|
+
if os.include? "linux"
|
|
12
9
|
require "usagewatch/linux"
|
|
13
|
-
elsif os =~ /cygwin|mswin|mingw|bccwin|wince|emx/
|
|
14
|
-
puts "Windows" + text
|
|
15
10
|
else
|
|
16
|
-
puts
|
|
11
|
+
puts text
|
|
17
12
|
end
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
data/lib/usagewatch/linux.rb
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# License: (MIT), Copyright (C) 2013 usagewatch Author Phil Chen, contributor Ruben Espinosa
|
|
2
|
+
|
|
1
3
|
module Usagewatch
|
|
4
|
+
# Show the amount of total disk used in Gigabytes
|
|
2
5
|
def self.uw_diskused
|
|
3
6
|
@df = `df`
|
|
4
7
|
@parts = @df.split(" ").map { |s| s.to_i }
|
|
@@ -16,6 +19,7 @@ module Usagewatch
|
|
|
16
19
|
df.split(" ").last.to_f.round(2)
|
|
17
20
|
end
|
|
18
21
|
|
|
22
|
+
# Show the percentage of CPU used
|
|
19
23
|
def self.uw_cpuused
|
|
20
24
|
@proc0 = File.readlines('/proc/stat').grep(/^cpu /).first.split(" ")
|
|
21
25
|
sleep 1
|
|
@@ -51,7 +55,7 @@ module Usagewatch
|
|
|
51
55
|
array
|
|
52
56
|
end
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
# Show the number of TCP connections used
|
|
55
59
|
def self.uw_tcpused
|
|
56
60
|
if File.exists?("/proc/net/sockstat")
|
|
57
61
|
File.open("/proc/net/sockstat", "r") do |ipv4|
|
|
@@ -75,6 +79,7 @@ module Usagewatch
|
|
|
75
79
|
@totaltcpused = @tcp4count.to_i + @tcp6count.to_i
|
|
76
80
|
end
|
|
77
81
|
|
|
82
|
+
# Show the number of UDP connections used
|
|
78
83
|
def self.uw_udpused
|
|
79
84
|
if File.exists?("/proc/net/sockstat")
|
|
80
85
|
File.open("/proc/net/sockstat", "r") do |ipv4|
|
|
@@ -97,6 +102,7 @@ module Usagewatch
|
|
|
97
102
|
@totaludpused = @udp4count.to_i + @udp6count.to_i
|
|
98
103
|
end
|
|
99
104
|
|
|
105
|
+
# Show the percentage of Active Memory used
|
|
100
106
|
def self.uw_memused
|
|
101
107
|
if File.exists?("/proc/meminfo")
|
|
102
108
|
File.open("/proc/meminfo", "r") do |file|
|
|
@@ -123,6 +129,7 @@ module Usagewatch
|
|
|
123
129
|
array
|
|
124
130
|
end
|
|
125
131
|
|
|
132
|
+
# Show the average system load of the past minute
|
|
126
133
|
def self.uw_load
|
|
127
134
|
if File.exists?("/proc/loadavg")
|
|
128
135
|
File.open("/proc/loadavg", "r") do |file|
|
|
@@ -133,6 +140,7 @@ module Usagewatch
|
|
|
133
140
|
end
|
|
134
141
|
end
|
|
135
142
|
|
|
143
|
+
# Bandwidth Received Method
|
|
136
144
|
def self.bandrx
|
|
137
145
|
|
|
138
146
|
if File.exists?("/proc/net/dev")
|
|
@@ -175,7 +183,7 @@ module Usagewatch
|
|
|
175
183
|
@bandrxtx = @arrTotal
|
|
176
184
|
end
|
|
177
185
|
|
|
178
|
-
|
|
186
|
+
# Current Bandwidth Received Calculation in Mbit/s
|
|
179
187
|
def self.uw_bandrx
|
|
180
188
|
|
|
181
189
|
@new0 = bandrx
|
|
@@ -187,6 +195,7 @@ module Usagewatch
|
|
|
187
195
|
@megabitsreceived = (@bitsreceived.to_f / 1024 / 1024).round(3)
|
|
188
196
|
end
|
|
189
197
|
|
|
198
|
+
# Bandwidth Transmitted Method
|
|
190
199
|
def self.bandtx
|
|
191
200
|
|
|
192
201
|
if File.exists?("/proc/net/dev")
|
|
@@ -229,17 +238,19 @@ module Usagewatch
|
|
|
229
238
|
@bandrxtx = @arrTotal
|
|
230
239
|
end
|
|
231
240
|
|
|
241
|
+
# Current Bandwidth Transmitted in Mbit/s
|
|
232
242
|
def self.uw_bandtx
|
|
233
243
|
|
|
234
|
-
@new0 =
|
|
244
|
+
@new0 = bandtx
|
|
235
245
|
sleep 1
|
|
236
|
-
@new1 =
|
|
246
|
+
@new1 = bandtx
|
|
237
247
|
|
|
238
248
|
@bytestransmitted = @new1[1].to_i - @new0[1].to_i
|
|
239
249
|
@bitstransmitted = (@bytestransmitted * 8)
|
|
240
250
|
@megabitstransmitted = (@bitstransmitted.to_f / 1024 / 1024).round(3)
|
|
241
251
|
end
|
|
242
252
|
|
|
253
|
+
# Disk Usage Method
|
|
243
254
|
def self.diskio
|
|
244
255
|
|
|
245
256
|
if File.exists?("/proc/diskstats")
|
|
@@ -280,62 +291,22 @@ module Usagewatch
|
|
|
280
291
|
@diskiorw= @arrTotal
|
|
281
292
|
end
|
|
282
293
|
|
|
283
|
-
|
|
294
|
+
# Current Disk Reads Completed
|
|
284
295
|
def self.uw_diskioreads
|
|
285
296
|
|
|
286
|
-
@new0 =
|
|
297
|
+
@new0 = diskio
|
|
287
298
|
sleep 1
|
|
288
|
-
@new1 =
|
|
299
|
+
@new1 = diskio
|
|
289
300
|
|
|
290
301
|
@diskreads = @new1[0].to_i - @new0[0].to_i
|
|
291
302
|
end
|
|
292
303
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if File.exists?("/proc/diskstats")
|
|
296
|
-
File.open("/proc/diskstats", "r") do |file|
|
|
297
|
-
@result = file.read
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
@arrRows = @result.split("\n")
|
|
302
|
-
|
|
303
|
-
rowcount = (@arrRows.count - 1)
|
|
304
|
-
|
|
305
|
-
for i in (0..rowcount)
|
|
306
|
-
@arrRows[i] = @arrRows[i].gsub(/\s+/m, ' ').strip.split(" ")
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
@arrColumns = Array.new
|
|
310
|
-
for l in (0..rowcount)
|
|
311
|
-
@temp = Array.new
|
|
312
|
-
@temp[0] = @arrRows[l][3]
|
|
313
|
-
@temp[1] = @arrRows[l][7]
|
|
314
|
-
@arrColumns << @temp
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
columncount = (@arrColumns[0].count - 1)
|
|
318
|
-
|
|
319
|
-
@arrTotal = Array.new
|
|
320
|
-
for p in (0..columncount)
|
|
321
|
-
@arrTotal[p] = 0
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
for j in (0..columncount)
|
|
325
|
-
for k in (0..rowcount)
|
|
326
|
-
@arrTotal[j] = @arrColumns[k][j].to_i + @arrTotal[j]
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
@diskiorw= @arrTotal
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
|
|
304
|
+
# Current Disk Writes Completed
|
|
334
305
|
def self.uw_diskiowrites
|
|
335
306
|
|
|
336
|
-
@new0 =
|
|
307
|
+
@new0 = diskio
|
|
337
308
|
sleep 1
|
|
338
|
-
@new1 =
|
|
309
|
+
@new1 = diskio
|
|
339
310
|
|
|
340
311
|
@diskwrites = @new1[1].to_i - @new0[1].to_i
|
|
341
312
|
end
|
data/lib/usagewatch/version.rb
CHANGED
data/usagewatch.gemspec
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# License: (MIT), Copyright (C) 2013 usagewatch Author Phil Chen, contributor Ruben Espinosa
|
|
1
2
|
# coding: utf-8
|
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
@@ -21,5 +22,5 @@ Gem::Specification.new do |spec|
|
|
|
21
22
|
|
|
22
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
|
23
24
|
spec.add_development_dependency "rake"
|
|
24
|
-
spec.post_install_message = "* Linux version are covered for our test.\
|
|
25
|
+
spec.post_install_message = "* Linux version are covered for our test.\nThanks for installing!"
|
|
25
26
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: usagewatch
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.6
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.0.6
|
|
5
|
+
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Phil Chen, Ruben Espinosa
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-07-
|
|
12
|
+
date: 2013-07-23 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: bundler
|
|
@@ -57,11 +57,9 @@ files:
|
|
|
57
57
|
- LICENSE.txt
|
|
58
58
|
- README.md
|
|
59
59
|
- Rakefile
|
|
60
|
-
- examples/
|
|
61
|
-
- examples/mac_example.rb
|
|
60
|
+
- examples/example.rb
|
|
62
61
|
- lib/usagewatch.rb
|
|
63
62
|
- lib/usagewatch/linux.rb
|
|
64
|
-
- lib/usagewatch/mac.rb
|
|
65
63
|
- lib/usagewatch/version.rb
|
|
66
64
|
- usagewatch.gemspec
|
|
67
65
|
homepage: https://github.com/nethacker/usagewatch
|
|
@@ -69,8 +67,6 @@ licenses:
|
|
|
69
67
|
- MIT
|
|
70
68
|
post_install_message: ! '* Linux version are covered for our test.
|
|
71
69
|
|
|
72
|
-
* Mac OS version is in development
|
|
73
|
-
|
|
74
70
|
Thanks for installing!'
|
|
75
71
|
rdoc_options:
|
|
76
72
|
- --main
|
|
@@ -86,9 +82,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
86
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
83
|
none: false
|
|
88
84
|
requirements:
|
|
89
|
-
- - ! '
|
|
85
|
+
- - ! '>='
|
|
90
86
|
- !ruby/object:Gem::Version
|
|
91
|
-
version:
|
|
87
|
+
version: '0'
|
|
92
88
|
requirements: []
|
|
93
89
|
rubyforge_project:
|
|
94
90
|
rubygems_version: 1.8.23
|
data/examples/mac_example.rb
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/ruby
|
|
2
|
-
|
|
3
|
-
#License: (MIT), Copyright (C) 2013 Author Phil Chen, Contributor Ruben Espinosa
|
|
4
|
-
|
|
5
|
-
require 'usagewatch'
|
|
6
|
-
|
|
7
|
-
usw = Usagewatch
|
|
8
|
-
|
|
9
|
-
puts "#{usw.uw_diskused} Gigabytes Used"
|
|
10
|
-
puts "#{usw.uw_diskused_perc} Percentage of Gigabytes Used"
|
|
11
|
-
puts "#{usw.uw_memused}% Active Memory Used"
|
|
12
|
-
puts "#{usw.uw_cpuused}% CPU Used"
|
|
13
|
-
puts "#{usw.uw_load} Average System Load Of The Past Minute"
|
|
14
|
-
puts "Top Ten Processes By CPU Consumption: #{usw.uw_cputop}"
|
|
15
|
-
puts "Top Ten Processes By Memory Consumption: #{usw.uw_memtop}"
|
data/lib/usagewatch/mac.rb
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
module Usagewatch
|
|
2
|
-
|
|
3
|
-
# Show disk used in GB
|
|
4
|
-
def self.uw_diskused
|
|
5
|
-
df = `df -kl`
|
|
6
|
-
sum = 0.00
|
|
7
|
-
df.each_line.with_index do |line, line_index|
|
|
8
|
-
next if line_index.eql? 0
|
|
9
|
-
line = line.split(" ")
|
|
10
|
-
next if line[0] =~ /localhost/ #ignore backup filesystem
|
|
11
|
-
sum += ((line[2].to_f)/1024)/1024
|
|
12
|
-
end
|
|
13
|
-
sum.round(2)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Show the percentage of disk used.
|
|
17
|
-
def self.uw_diskused_perc
|
|
18
|
-
df = `df -kl`
|
|
19
|
-
total = 0.0
|
|
20
|
-
used = 0.0
|
|
21
|
-
df.each_line.with_index do |line, line_index|
|
|
22
|
-
next if line_index.eql? 0
|
|
23
|
-
line = line.split(" ")
|
|
24
|
-
next if line[0] =~ /localhost/ #ignore backup filesystem
|
|
25
|
-
total += ((line[3].to_f)/1024)/1024
|
|
26
|
-
used +=((line[2].to_f)/1024)/1024
|
|
27
|
-
end
|
|
28
|
-
((used/total) * 100).round(2)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Show the percentage of cpu used
|
|
32
|
-
def self.uw_cpuused
|
|
33
|
-
top = `top -l1 | awk '/CPU usage/'`
|
|
34
|
-
top = top.gsub(/[\,a-zA-Z:]/, "").split(" ")
|
|
35
|
-
top[0].to_f
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# return hash of top ten proccesses by cpu consumption
|
|
39
|
-
# example [["apache2", 12.0], ["passenger", 13.2]]
|
|
40
|
-
def self.uw_cputop
|
|
41
|
-
ps = `ps aux | awk '{print $11, $3}' | sort -k2nr | head -n 10`
|
|
42
|
-
array = []
|
|
43
|
-
ps.each_line do |line|
|
|
44
|
-
line = line.chomp.split(" ")
|
|
45
|
-
array << [line.first.gsub(/[\[\]]/, "").split("/").last, line.last]
|
|
46
|
-
end
|
|
47
|
-
array
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# todo
|
|
51
|
-
#def uw_tcpused
|
|
52
|
-
#
|
|
53
|
-
#end
|
|
54
|
-
|
|
55
|
-
# todo
|
|
56
|
-
#def uw_udpused
|
|
57
|
-
#
|
|
58
|
-
#end
|
|
59
|
-
|
|
60
|
-
# return hash of top ten proccesses by mem consumption
|
|
61
|
-
# example [["apache2", 12.0], ["passenger", 13.2]]
|
|
62
|
-
def self.uw_memtop
|
|
63
|
-
ps = `ps aux | awk '{print $11, $4}' | sort -k2nr | head -n 10`
|
|
64
|
-
array = []
|
|
65
|
-
ps.each_line do |line|
|
|
66
|
-
line = line.chomp.split(" ")
|
|
67
|
-
array << [line.first.gsub(/[\[\]]/, "").split("/").last, line.last]
|
|
68
|
-
end
|
|
69
|
-
array
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Percentage of mem used
|
|
73
|
-
def self.uw_memused
|
|
74
|
-
top = `top -l1 | awk '/PhysMem/'`
|
|
75
|
-
top = top.gsub(/[\.\,a-zA-Z:]/, "").split(" ").reverse
|
|
76
|
-
((top[1].to_f / (top[0].to_f + top[1].to_f)) * 100).round(2)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Show the average of load in the last minute
|
|
80
|
-
def self.uw_load
|
|
81
|
-
iostat = `iostat -w1 -c 2 | awk '{print $7}'`
|
|
82
|
-
cpu = 0.0
|
|
83
|
-
iostat.each_line.with_index do |line, line_index|
|
|
84
|
-
next if line_index.eql? 0 or line_index.eql? 1 or line_index.eql? 2
|
|
85
|
-
cpu = line.split(" ").last.to_f.round(2)
|
|
86
|
-
end
|
|
87
|
-
cpu
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
#todo
|
|
91
|
-
#def uw_bandrx
|
|
92
|
-
#
|
|
93
|
-
#end
|
|
94
|
-
|
|
95
|
-
#todo
|
|
96
|
-
#def uw_bandtx
|
|
97
|
-
#
|
|
98
|
-
#end
|
|
99
|
-
|
|
100
|
-
#todo
|
|
101
|
-
#def uw_diskioreads
|
|
102
|
-
#
|
|
103
|
-
#end
|
|
104
|
-
|
|
105
|
-
#todo
|
|
106
|
-
#def uw_diskiowrites
|
|
107
|
-
#
|
|
108
|
-
#end
|
|
109
|
-
end
|