ardtweeno 0.0.2 → 0.2.5

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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +179 -1
  3. data/COPYING +4 -3
  4. data/Gemfile +29 -0
  5. data/Gemfile.lock +76 -0
  6. data/INSTALL +12 -0
  7. data/Procfile +1 -0
  8. data/README.md +26 -2
  9. data/Rakefile +14 -7
  10. data/lib/ardtweeno/api.rb +542 -0
  11. data/lib/ardtweeno/configreader.rb +65 -0
  12. data/lib/ardtweeno/db.rb +51 -0
  13. data/lib/ardtweeno/dispatcher.rb +538 -0
  14. data/lib/ardtweeno/exceptions.rb +33 -0
  15. data/lib/ardtweeno/node.rb +117 -0
  16. data/lib/ardtweeno/nodemanager.rb +300 -0
  17. data/lib/ardtweeno/packet.rb +98 -0
  18. data/lib/ardtweeno/restapi.rb +266 -0
  19. data/lib/ardtweeno/serialparser.rb +221 -0
  20. data/lib/ardtweeno.rb +120 -1
  21. data/public/glossy_green_button.svg +123 -0
  22. data/public/glossy_red_button.svg +75 -0
  23. data/public/main.css +129 -0
  24. data/public/raspberrypi.jpg +0 -0
  25. data/resources/conf.yaml +41 -0
  26. data/resources/nodelist.yaml +26 -0
  27. data/resources/serialparser.js +84 -0
  28. data/test/api_test.rb +255 -0
  29. data/test/dispatcher_test.rb +115 -0
  30. data/test/node_test.rb +105 -0
  31. data/test/nodemanager_test.rb +167 -0
  32. data/test/packet_test.rb +75 -0
  33. data/test/parser_test.rb +147 -0
  34. data/test/post_watch +11 -0
  35. data/test/rest_api_test.rb +248 -0
  36. data/test/run_mock +17 -0
  37. data/test/run_packet_push +14 -0
  38. data/test/serialport_mock.rb +43 -0
  39. data/test/test_helper.rb +15 -0
  40. data/test/tty0tty-1.1/AUTHORS +1 -0
  41. data/test/tty0tty-1.1/COPYING +340 -0
  42. data/test/tty0tty-1.1/INSTALL +18 -0
  43. data/test/tty0tty-1.1/README +52 -0
  44. data/test/tty0tty-1.1/THANKS +4 -0
  45. data/test/tty0tty-1.1/TODO +3 -0
  46. data/test/tty0tty-1.1/VERSION +4 -0
  47. data/test/tty0tty-1.1/module/Makefile +41 -0
  48. data/{bin/ardtweeno → test/tty0tty-1.1/module/Module.symvers} +0 -0
  49. data/test/tty0tty-1.1/module/modules.order +1 -0
  50. data/test/tty0tty-1.1/module/tty0tty.c +678 -0
  51. data/test/tty0tty-1.1/module/tty0tty.ko +0 -0
  52. data/test/tty0tty-1.1/module/tty0tty.mod.c +51 -0
  53. data/test/tty0tty-1.1/module/tty0tty.mod.o +0 -0
  54. data/test/tty0tty-1.1/module/tty0tty.o +0 -0
  55. data/test/tty0tty-1.1/pts/Makefile +10 -0
  56. data/test/tty0tty-1.1/pts/tty0tty +0 -0
  57. data/test/tty0tty-1.1/pts/tty0tty.c +222 -0
  58. data/views/createpost.erb +45 -0
  59. data/views/home.erb +59 -0
  60. metadata +89 -37
  61. data/README +0 -1
  62. data/test/Rakefile +0 -6
  63. data/test/features/ardtweeno.feature +0 -14
  64. data/test/features/step_definitions/ardtweeno_steps.rb +0 -24
@@ -0,0 +1,221 @@
1
+ ####################################################################################################
2
+ # @author David Kirwan <davidkirwanirl@gmail.com>
3
+ # @description Core functions for the Ardtweeno SerialParser system
4
+ #
5
+ # @date 15-11-2012
6
+ ####################################################################################################
7
+
8
+ # Imports
9
+ require 'rubygems'
10
+ require 'serialport'
11
+ require 'logger'
12
+ require 'yaml'
13
+ require 'json'
14
+
15
+ module Ardtweeno
16
+
17
+ ##
18
+ # Ardtweeno::SerialParser class for the Ardtweeno system
19
+ #
20
+ class SerialParser
21
+
22
+ attr_accessor :sp, :log, :seqNo, :manager
23
+
24
+ ##
25
+ # Ardtweeno::SerialParser#new constructor for the Ardtweeno system
26
+ #
27
+ # * *Args* :
28
+ # - ++ -> device String, speed Fixnum, timeout Fixnum, {:log}
29
+ # * *Returns* :
30
+ # -
31
+ # * *Raises* :
32
+ # -
33
+ #
34
+ def initialize(dev, speed, timeout, options={})
35
+ @log = options[:log] ||= Logger.new(STDOUT)
36
+ @log.level = Logger::WARN
37
+
38
+ @log.debug "Creating instance of Ardtweeno::SerialParser"
39
+
40
+ # Injection of NodeManager into the SerialParser
41
+ @manager = options[:manager] ||= nil
42
+
43
+ @seqNo = 0
44
+
45
+ begin
46
+ @sp = SerialPort.new(dev, speed)
47
+ @sp.read_timeout = timeout
48
+ rescue Exception => e
49
+ @log.fatal e.message
50
+ raise e
51
+ end
52
+ end
53
+
54
+
55
+
56
+ ##
57
+ # Ardtweeno::SerialParser#read Reads data from the active SerialPort device and then validates
58
+ # returns data if valid JSON, otherwise returns empty JSON hash
59
+ #
60
+ # * *Args* :
61
+ # - ++ -> String, Fixnum, Fixnum, {:log}
62
+ # * *Returns* :
63
+ # - JSON if valid, otherwise empty JSON hash
64
+ # * *Raises* :
65
+ # -
66
+ #
67
+ def read()
68
+ data = @sp.read
69
+
70
+ @log.debug "Validating JSON data"
71
+ if SerialParser.valid_json?(data)
72
+ @log.debug "Data is valid JSON"
73
+ return data
74
+ else
75
+ @log.debug "Data is invalid JSON"
76
+ return '{}'
77
+ end
78
+
79
+ end
80
+
81
+
82
+ ##
83
+ # Ardtweeno::SerialParser#convert Converts JSON string to Ardtweeno::Packet if possible
84
+ #
85
+ # * *Args* :
86
+ # - ++ -> JSON String
87
+ # * *Returns* :
88
+ # - Ardtweeno::Packet
89
+ # * *Raises* :
90
+ # - Ardtweeno::InvalidData
91
+ #
92
+ # {"seqNo":5,"data":[23.5,997.5,65],"key":"1234567890abcdef"}
93
+ def convert(packetdata)
94
+ if packetdata["data"].nil? then raise Ardtweeno::InvalidData, "Packet missing data" end
95
+ if packetdata["key"].nil? then raise Ardtweeno::InvalidData, "Packet missing key" end
96
+
97
+ return Ardtweeno::Packet.new(nextSeq(), packetdata["key"], packetdata["data"])
98
+ end
99
+
100
+
101
+ ##
102
+ # Ardtweeno::SerialParser#store initiates the storage of an Ardtweeno::Packet
103
+ #
104
+ # * *Args* :
105
+ # - ++ -> Ardtweeno::Packet
106
+ # * *Returns* :
107
+ # - true
108
+ # * *Raises* :
109
+ # - Ardtweeno::InvalidData or Ardtweeno::ManagerNotDefined if manager is nil
110
+ #
111
+ def store(data)
112
+
113
+ if data.class == Ardtweeno::Packet
114
+ if @manager.nil?
115
+ raise Ardtweeno::ManagerNotDefined, "Error the SerialParser is not currently assigned a manager"
116
+ else
117
+ begin
118
+ # Search for the node which corresponds with this key
119
+ node = @manager.search({:key=>data.key})
120
+
121
+ # Then store the packet in its list
122
+ node.enqueue(data)
123
+ rescue Ardtweeno::NotInNodeList => e
124
+ raise Ardtweeno::NodeNotAuthorised, "Node is not authorised for this network, ignoring"
125
+ end
126
+ end
127
+
128
+ # packet should be successfully added to its corresponding node
129
+ return true
130
+ else
131
+ raise Ardtweeno::InvalidData, "Data is invalid, ignoring"
132
+ end
133
+
134
+ end
135
+
136
+
137
+ ##
138
+ # Ardtweeno::SerialParser#write initiates the conversion of an Ardtweeno::Packet to JSON
139
+ # before writing to a SerialPort device
140
+ #
141
+ # * *Args* :
142
+ # - ++ -> Ardtweeno::Packet
143
+ # * *Returns* :
144
+ # - true || false
145
+ # * *Raises* :
146
+ # -
147
+ #
148
+ def write(data)
149
+ @log.debug "Validating data"
150
+ if SerialParser.valid_json?(data)
151
+ @log.debug "Data validated"
152
+ @sp.write(data)
153
+ return true
154
+ else
155
+ @log.debug "Data is invalid"
156
+ return false
157
+ end
158
+ end
159
+
160
+
161
+ ##
162
+ # Ardtweeno::SerialParser#valid_json? validates JSON data
163
+ #
164
+ # * *Args* :
165
+ # - ++ -> JSON String
166
+ # * *Returns* :
167
+ # - true || false
168
+ # * *Raises* :
169
+ # -
170
+ #
171
+ def self.valid_json?(json_)
172
+ begin
173
+ JSON.parse(json_)
174
+ return true
175
+ rescue Exception => e
176
+ return false
177
+ end
178
+ end
179
+
180
+
181
+
182
+ ##
183
+ # Ardtweeno::SerialParser#nextSeq returns the next available sequence number
184
+ #
185
+ # * *Args* :
186
+ # - ++ ->
187
+ # * *Returns* :
188
+ # - Fixnum
189
+ # * *Raises* :
190
+ # -
191
+ #
192
+ def nextSeq()
193
+ @log.debug "Current Sequence Number: " + @seqNo.to_s
194
+ theSeq = @seqNo
195
+ @seqNo += 1
196
+ @log.debug "Current Sequence Number Incremented: " + @seqNo.to_s
197
+
198
+ return theSeq
199
+ end
200
+
201
+
202
+ ##
203
+ # Ardtweeno::SerialParser#close Closes the SerialPort instance
204
+ #
205
+ # * *Args* :
206
+ # - ++ ->
207
+ # * *Returns* :
208
+ # -
209
+ # * *Raises* :
210
+ # -
211
+ #
212
+ def close()
213
+ @log.debug "Closing SerialPort device"
214
+ @sp.close
215
+ end
216
+
217
+ end
218
+ end
219
+
220
+
221
+
data/lib/ardtweeno.rb CHANGED
@@ -1,2 +1,121 @@
1
- require ''
1
+ ####################################################################################################
2
+ # @author David Kirwan <davidkirwanirl@gmail.com>
3
+ # @description Ardtweeno Mesh Network Application Gateway
4
+ #
5
+ # @date 15-05-2013
6
+ ####################################################################################################
7
+
8
+ require 'rubygems'
9
+ require 'logger'
10
+ require 'fileutils'
11
+ require 'ardtweeno/serialparser'
12
+ require 'ardtweeno/dispatcher'
13
+ require 'ardtweeno/exceptions'
14
+ require 'ardtweeno/packet'
15
+ require 'ardtweeno/nodemanager'
16
+ require 'ardtweeno/node'
17
+ require 'ardtweeno/configreader'
18
+ require 'ardtweeno/api'
19
+ require 'ardtweeno/db'
20
+
21
+
22
+ ##
23
+ # Ardtweeno Mesh Network Application Gateway
24
+ #
25
+ # Software Gateway to allow collecting/broadcasting to/from a Mesh Network over serial. All data is
26
+ # stored to a database by default to allow later analysis and inclusion in automated reports
27
+ # generated by the system.
28
+ #
29
+ module Ardtweeno
30
+ class << self
31
+
32
+
33
+ # Constants
34
+ Ardtweeno::VERSION = "0.2.5" unless defined? Ardtweeno::VERSION
35
+ Ardtweeno::CONFIGPATH = ENV['HOME'] + "/.ardtweeno" unless defined? Ardtweeno::CONFIGPATH
36
+ Ardtweeno::DBPATH = Ardtweeno::CONFIGPATH + "/conf.yaml" unless defined? Ardtweeno::DBPATH
37
+ Ardtweeno::NODEPATH = Ardtweeno::CONFIGPATH + "/nodelist.yaml" unless defined? Ardtweeno::NODEPATH
38
+
39
+ # Class Variables
40
+ @@seqCount = 0 unless defined? @@seqCount
41
+ @@options = {} unless defined? @@options
42
+
43
+
44
+
45
+ ##
46
+ # Ardtweeno#options returns the options hash
47
+ #
48
+ # * *Args* :
49
+ # - ++ ->
50
+ # * *Returns* :
51
+ # - Hash
52
+ # * *Raises* :
53
+ # -
54
+ #
55
+ def options()
56
+ return @@options
57
+ end
58
+
59
+
60
+ ##
61
+ # Ardtweeno#nextSeq returns the next available sequence number
62
+ #
63
+ # * *Args* :
64
+ # - ++ ->
65
+ # * *Returns* :
66
+ # - Fixnum
67
+ # * *Raises* :
68
+ # -
69
+ #
70
+ def nextSeq()
71
+ @log = @@options[:log] ||= Logger.new(STDOUT)
72
+ @log.level = @@options[:level] ||= Logger::DEBUG
73
+
74
+ @log.debug "Current Sequence Number: " + @@seqCount.to_s
75
+ theSeq = @@seqCount
76
+ @@seqCount += 1
77
+ @log.debug "Current Sequence Number Incremented: " + @@seqCount.to_s
78
+
79
+ return theSeq
80
+ end
81
+
82
+
83
+ # Setup the system for the first time
84
+ def setup(options={})
85
+ @@options = options
86
+
87
+ @log = @@options[:log] ||= Logger.new(STDOUT)
88
+ @log.level = @@options[:level] ||= Logger::DEBUG
89
+
90
+
91
+ @log.debug "Checking to see if the configuration folder exists."
92
+ resourceDir = Ardtweeno::CONFIGPATH
93
+ @log.debug resourceDir
94
+
95
+ if File.directory?(resourceDir)
96
+ @log.debug "The folder already exists, do nothing."
97
+ else
98
+ @log.debug "Creating ~/.ardtweeno/ and installing the resources there."
99
+
100
+ begin
101
+ FileUtils.mkdir(resourceDir)
102
+ dbpath = File.expand_path(File.dirname(__FILE__) + '/../resources/conf.yaml')
103
+ nodepath = File.expand_path(File.dirname(__FILE__) + '/../resources/nodelist.yaml')
104
+ FileUtils.cp(dbpath, resourceDir)
105
+ FileUtils.cp(nodepath, resourceDir)
106
+ @log.debug "Successfully copied ~/.ardtweeno/conf.yaml"
107
+ @log.debug "Successfully copied ~/.ardtweeno/nodelist.yaml"
108
+ rescue Exception => e
109
+ @log.fatal e.message
110
+ @log.fatal e.backtrace
111
+ exit()
112
+ end
113
+ end
114
+
115
+ end
116
+
117
+
118
+ end
119
+ end
120
+
2
121
 
@@ -0,0 +1,123 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+ <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="400" height="400" id="svg11772" version="1.1" inkscape:version="0.48.0 r9654" sodipodi:docname="glossy_yellow_button.svg">
4
+ <defs id="defs11774">
5
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4156" id="linearGradient11748" gradientUnits="userSpaceOnUse" x1="241.40979" y1="287.49377" x2="315.47369" y2="367.88477"/>
6
+ <linearGradient id="linearGradient4156" inkscape:collect="always">
7
+ <stop id="stop4158" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
8
+ <stop id="stop4160" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
9
+ </linearGradient>
10
+ <filter id="filter6126" inkscape:collect="always" color-interpolation-filters="sRGB">
11
+ <feGaussianBlur id="feGaussianBlur6128" stdDeviation="0.53035713" inkscape:collect="always"/>
12
+ </filter>
13
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient7171" id="linearGradient11750" gradientUnits="userSpaceOnUse" x1="275.60828" y1="300.86383" x2="341.99622" y2="391.44925"/>
14
+ <linearGradient id="linearGradient7171">
15
+ <stop id="stop7173" offset="0" style="stop-color:#00112b;stop-opacity:1"/>
16
+ <stop id="stop7175" offset="1" style="stop-color:#0055d4;stop-opacity:1"/>
17
+ </linearGradient>
18
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient7111" id="radialGradient11752" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.5932658,-0.5932658,0.7150464,-0.7150486,243.27022,849.03358)" cx="312.78131" cy="386.57211" fx="312.78131" fy="386.57211" r="53.035713"/>
19
+ <linearGradient id="linearGradient7111">
20
+ <stop id="stop7113" offset="0" style="stop-color:#ffffff;stop-opacity:0.40816328;"/>
21
+ <stop id="stop7115" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
22
+ </linearGradient>
23
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4148" id="linearGradient11754" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9553353,0,0,0.9553353,55.103173,472.67243)" x1="255.31609" y1="286.66653" x2="300.26785" y2="338.81863"/>
24
+ <linearGradient id="linearGradient4148" inkscape:collect="always">
25
+ <stop id="stop4150" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
26
+ <stop id="stop4152" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
27
+ </linearGradient>
28
+ <linearGradient y2="338.81863" x2="300.26785" y1="286.66653" x1="255.31609" gradientTransform="matrix(0.9553353,0,0,0.9553353,55.103173,472.67243)" gradientUnits="userSpaceOnUse" id="linearGradient11820" xlink:href="#linearGradient4148" inkscape:collect="always"/>
29
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4156-1" id="linearGradient11732" gradientUnits="userSpaceOnUse" x1="241.40979" y1="287.49377" x2="315.47369" y2="367.88477"/>
30
+ <linearGradient id="linearGradient4156-1" inkscape:collect="always">
31
+ <stop id="stop4158-0" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
32
+ <stop id="stop4160-0" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
33
+ </linearGradient>
34
+ <filter id="filter6126-7" inkscape:collect="always" color-interpolation-filters="sRGB">
35
+ <feGaussianBlur id="feGaussianBlur6128-1" stdDeviation="0.53035713" inkscape:collect="always"/>
36
+ </filter>
37
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient7199" id="linearGradient11734" gradientUnits="userSpaceOnUse" x1="275.60828" y1="300.86383" x2="341.99622" y2="391.44925"/>
38
+ <linearGradient id="linearGradient7199">
39
+ <stop style="stop-color:#550000;stop-opacity:1" offset="0" id="stop7201"/>
40
+ <stop style="stop-color:#ff0000;stop-opacity:1" offset="1" id="stop7203"/>
41
+ </linearGradient>
42
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient7111-1" id="radialGradient11736" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.5932658,-0.5932658,0.7150464,-0.7150486,243.27022,849.03358)" cx="312.78131" cy="386.57211" fx="312.78131" fy="386.57211" r="53.035713"/>
43
+ <linearGradient id="linearGradient7111-1">
44
+ <stop id="stop7113-1" offset="0" style="stop-color:#ffffff;stop-opacity:0.40816328;"/>
45
+ <stop id="stop7115-8" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
46
+ </linearGradient>
47
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4148-9" id="linearGradient11738" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9553353,0,0,0.9553353,-84.896827,472.67243)" x1="255.31609" y1="286.66653" x2="300.26785" y2="338.81863"/>
48
+ <linearGradient id="linearGradient4148-9" inkscape:collect="always">
49
+ <stop id="stop4150-3" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
50
+ <stop id="stop4152-8" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
51
+ </linearGradient>
52
+ <linearGradient y2="338.81863" x2="300.26785" y1="286.66653" x1="255.31609" gradientTransform="matrix(0.9553353,0,0,0.9553353,-84.896827,472.67243)" gradientUnits="userSpaceOnUse" id="linearGradient11925" xlink:href="#linearGradient4148-9" inkscape:collect="always"/>
53
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4156-9" id="linearGradient11724" gradientUnits="userSpaceOnUse" x1="241.40979" y1="287.49377" x2="315.47369" y2="367.88477"/>
54
+ <linearGradient id="linearGradient4156-9" inkscape:collect="always">
55
+ <stop id="stop4158-08" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
56
+ <stop id="stop4160-1" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
57
+ </linearGradient>
58
+ <filter id="filter6126-75" inkscape:collect="always" color-interpolation-filters="sRGB">
59
+ <feGaussianBlur id="feGaussianBlur6128-0" stdDeviation="0.53035713" inkscape:collect="always"/>
60
+ </filter>
61
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient7228" id="linearGradient11726" gradientUnits="userSpaceOnUse" x1="275.60828" y1="300.86383" x2="341.99622" y2="391.44925"/>
62
+ <linearGradient id="linearGradient7228">
63
+ <stop id="stop7230" offset="0" style="stop-color:#806600;stop-opacity:1"/>
64
+ <stop id="stop7232" offset="1" style="stop-color:#ffcc00;stop-opacity:1"/>
65
+ </linearGradient>
66
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient7111-4" id="radialGradient11728" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.5932658,-0.5932658,0.7150464,-0.7150486,243.27022,849.03358)" cx="312.78131" cy="386.57211" fx="312.78131" fy="386.57211" r="53.035713"/>
67
+ <linearGradient id="linearGradient7111-4">
68
+ <stop id="stop7113-6" offset="0" style="stop-color:#ffffff;stop-opacity:0.40816328;"/>
69
+ <stop id="stop7115-7" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
70
+ </linearGradient>
71
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4148-4" id="linearGradient11730" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9553353,0,0,0.9553353,-84.896827,592.67243)" x1="255.31609" y1="286.66653" x2="300.26785" y2="338.81863"/>
72
+ <linearGradient id="linearGradient4148-4" inkscape:collect="always">
73
+ <stop id="stop4150-5" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
74
+ <stop id="stop4152-5" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
75
+ </linearGradient>
76
+ <linearGradient y2="338.81863" x2="300.26785" y1="286.66653" x1="255.31609" gradientTransform="matrix(0.9553353,0,0,0.9553353,-84.896827,592.67243)" gradientUnits="userSpaceOnUse" id="linearGradient12030" xlink:href="#linearGradient4148-4" inkscape:collect="always"/>
77
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4156-18" id="linearGradient11740" gradientUnits="userSpaceOnUse" x1="241.40979" y1="287.49377" x2="315.47369" y2="367.88477"/>
78
+ <linearGradient id="linearGradient4156-18" inkscape:collect="always">
79
+ <stop id="stop4158-5" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
80
+ <stop id="stop4160-5" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
81
+ </linearGradient>
82
+ <filter id="filter6126-4" inkscape:collect="always" color-interpolation-filters="sRGB">
83
+ <feGaussianBlur id="feGaussianBlur6128-4" stdDeviation="0.53035713" inkscape:collect="always"/>
84
+ </filter>
85
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient7256" id="linearGradient11742" gradientUnits="userSpaceOnUse" x1="275.60828" y1="300.86383" x2="341.99622" y2="391.44925"/>
86
+ <linearGradient id="linearGradient7256">
87
+ <stop style="stop-color:#112b00;stop-opacity:1" offset="0" id="stop7258"/>
88
+ <stop style="stop-color:#66ff00;stop-opacity:1" offset="1" id="stop7260"/>
89
+ </linearGradient>
90
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient7111-0" id="radialGradient11744" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.5932658,-0.5932658,0.7150464,-0.7150486,243.27022,849.03358)" cx="312.78131" cy="386.57211" fx="312.78131" fy="386.57211" r="53.035713"/>
91
+ <linearGradient id="linearGradient7111-0">
92
+ <stop id="stop7113-5" offset="0" style="stop-color:#ffffff;stop-opacity:0.40816328;"/>
93
+ <stop id="stop7115-9" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
94
+ </linearGradient>
95
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4148-1" id="linearGradient11746" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9553353,0,0,0.9553353,55.103173,592.67243)" x1="255.31609" y1="286.66653" x2="300.26785" y2="338.81863"/>
96
+ <linearGradient id="linearGradient4148-1" inkscape:collect="always">
97
+ <stop id="stop4150-9" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
98
+ <stop id="stop4152-86" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
99
+ </linearGradient>
100
+ <linearGradient y2="338.81863" x2="300.26785" y1="286.66653" x1="255.31609" gradientTransform="matrix(0.9553353,0,0,0.9553353,55.103173,592.67243)" gradientUnits="userSpaceOnUse" id="linearGradient12135" xlink:href="#linearGradient4148-1" inkscape:collect="always"/>
101
+ </defs>
102
+ <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.98994949" inkscape:cx="211.24527" inkscape:cy="230.76804" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1280" inkscape:window-height="748" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1"/>
103
+ <metadata id="metadata11777">
104
+ <rdf:RDF>
105
+ <cc:Work rdf:about="">
106
+ <dc:format>image/svg+xml</dc:format>
107
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
108
+ <dc:title/>
109
+ </cc:Work>
110
+ </rdf:RDF>
111
+ </metadata>
112
+ <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-652.36218)">
113
+ <g id="g11707" transform="matrix(2.9051461,0,0,2.9051461,-770.20152,-1760.1027)">
114
+ <path sodipodi:type="arc" style="fill:#999999;fill-opacity:1;stroke:none" id="path7234" sodipodi:cx="303.75" sodipodi:cy="346.11218" sodipodi:rx="53.035713" sodipodi:ry="53.035713" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" transform="matrix(0.9735424,0,0,0.9735424,39.076793,565.98894)"/>
115
+ <path sodipodi:type="arc" style="fill:url(#linearGradient11740);fill-opacity:1;stroke:none" id="path7236" sodipodi:cx="303.75" sodipodi:cy="346.11218" sodipodi:rx="53.035713" sodipodi:ry="53.035713" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" transform="matrix(0.9595959,0,0,0.9595959,43.313063,570.81603)"/>
116
+ <path transform="matrix(0.8735475,0,0,0.8735475,69.450248,600.5984)" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" sodipodi:ry="53.035713" sodipodi:rx="53.035713" sodipodi:cy="346.11218" sodipodi:cx="303.75" id="path7238" style="fill:#ececec;fill-opacity:1;stroke:none;filter:url(#filter6126-4)" sodipodi:type="arc"/>
117
+ <path sodipodi:type="arc" style="fill:#999999;fill-opacity:1;stroke:none;filter:url(#filter6126-4)" id="path7240" sodipodi:cx="303.75" sodipodi:cy="346.11218" sodipodi:rx="53.035713" sodipodi:ry="53.035713" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" transform="matrix(0.8383837,0,0,0.8383837,80.131258,612.76902)"/>
118
+ <path sodipodi:type="arc" style="fill:url(#linearGradient11742);fill-opacity:1;stroke:none" id="path7242" sodipodi:cx="303.75" sodipodi:cy="346.11218" sodipodi:rx="53.035713" sodipodi:ry="53.035713" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" transform="matrix(0.8058691,0,0,0.8058691,90.007588,624.02274)"/>
119
+ <path transform="matrix(0.7582525,0,0,0.7582525,105.73382,642.52374)" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" sodipodi:ry="53.035713" sodipodi:rx="53.035713" sodipodi:cy="346.11218" sodipodi:cx="303.75" id="path7244" style="fill:url(#radialGradient11744);fill-opacity:1;stroke:none" sodipodi:type="arc"/>
120
+ <path id="path7246" d="m 333.78625,862.76451 c -13.3306,0.30069 -26.18606,7.35801 -33.33579,19.74172 -7.69026,13.31988 -6.71392,29.26602 1.15447,41.33061 0.85306,-26.53161 21.13176,-46.51511 46.32378,-45.05384 8.25891,0.47907 16.05431,3.20007 22.85883,7.59075 -3.25775,-7.44975 -8.8171,-13.95312 -16.3937,-18.32748 -6.48672,-3.74508 -13.62489,-5.43927 -20.60759,-5.28176 z" style="opacity:0.31770833;fill:url(#linearGradient12135);fill-opacity:1;stroke:none" inkscape:connector-curvature="0"/>
121
+ </g>
122
+ </g>
123
+ </svg>
@@ -0,0 +1,75 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+ <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="400" height="400" id="svg11772" version="1.1" inkscape:version="0.48.0 r9654" sodipodi:docname="glossy_blue_button.svg">
4
+ <defs id="defs11774">
5
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4156" id="linearGradient11748" gradientUnits="userSpaceOnUse" x1="241.40979" y1="287.49377" x2="315.47369" y2="367.88477"/>
6
+ <linearGradient id="linearGradient4156" inkscape:collect="always">
7
+ <stop id="stop4158" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
8
+ <stop id="stop4160" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
9
+ </linearGradient>
10
+ <filter id="filter6126" inkscape:collect="always" color-interpolation-filters="sRGB">
11
+ <feGaussianBlur id="feGaussianBlur6128" stdDeviation="0.53035713" inkscape:collect="always"/>
12
+ </filter>
13
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient7171" id="linearGradient11750" gradientUnits="userSpaceOnUse" x1="275.60828" y1="300.86383" x2="341.99622" y2="391.44925"/>
14
+ <linearGradient id="linearGradient7171">
15
+ <stop id="stop7173" offset="0" style="stop-color:#00112b;stop-opacity:1"/>
16
+ <stop id="stop7175" offset="1" style="stop-color:#0055d4;stop-opacity:1"/>
17
+ </linearGradient>
18
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient7111" id="radialGradient11752" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.5932658,-0.5932658,0.7150464,-0.7150486,243.27022,849.03358)" cx="312.78131" cy="386.57211" fx="312.78131" fy="386.57211" r="53.035713"/>
19
+ <linearGradient id="linearGradient7111">
20
+ <stop id="stop7113" offset="0" style="stop-color:#ffffff;stop-opacity:0.40816328;"/>
21
+ <stop id="stop7115" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
22
+ </linearGradient>
23
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4148" id="linearGradient11754" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9553353,0,0,0.9553353,55.103173,472.67243)" x1="255.31609" y1="286.66653" x2="300.26785" y2="338.81863"/>
24
+ <linearGradient id="linearGradient4148" inkscape:collect="always">
25
+ <stop id="stop4150" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
26
+ <stop id="stop4152" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
27
+ </linearGradient>
28
+ <linearGradient y2="338.81863" x2="300.26785" y1="286.66653" x1="255.31609" gradientTransform="matrix(0.9553353,0,0,0.9553353,55.103173,472.67243)" gradientUnits="userSpaceOnUse" id="linearGradient11820" xlink:href="#linearGradient4148" inkscape:collect="always"/>
29
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4156-1" id="linearGradient11732" gradientUnits="userSpaceOnUse" x1="241.40979" y1="287.49377" x2="315.47369" y2="367.88477"/>
30
+ <linearGradient id="linearGradient4156-1" inkscape:collect="always">
31
+ <stop id="stop4158-0" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
32
+ <stop id="stop4160-0" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
33
+ </linearGradient>
34
+ <filter id="filter6126-7" inkscape:collect="always" color-interpolation-filters="sRGB">
35
+ <feGaussianBlur id="feGaussianBlur6128-1" stdDeviation="0.53035713" inkscape:collect="always"/>
36
+ </filter>
37
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient7199" id="linearGradient11734" gradientUnits="userSpaceOnUse" x1="275.60828" y1="300.86383" x2="341.99622" y2="391.44925"/>
38
+ <linearGradient id="linearGradient7199">
39
+ <stop style="stop-color:#550000;stop-opacity:1" offset="0" id="stop7201"/>
40
+ <stop style="stop-color:#ff0000;stop-opacity:1" offset="1" id="stop7203"/>
41
+ </linearGradient>
42
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient7111-1" id="radialGradient11736" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.5932658,-0.5932658,0.7150464,-0.7150486,243.27022,849.03358)" cx="312.78131" cy="386.57211" fx="312.78131" fy="386.57211" r="53.035713"/>
43
+ <linearGradient id="linearGradient7111-1">
44
+ <stop id="stop7113-1" offset="0" style="stop-color:#ffffff;stop-opacity:0.40816328;"/>
45
+ <stop id="stop7115-8" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
46
+ </linearGradient>
47
+ <linearGradient inkscape:collect="always" xlink:href="#linearGradient4148-9" id="linearGradient11738" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9553353,0,0,0.9553353,-84.896827,472.67243)" x1="255.31609" y1="286.66653" x2="300.26785" y2="338.81863"/>
48
+ <linearGradient id="linearGradient4148-9" inkscape:collect="always">
49
+ <stop id="stop4150-3" offset="0" style="stop-color:#ffffff;stop-opacity:1;"/>
50
+ <stop id="stop4152-8" offset="1" style="stop-color:#ffffff;stop-opacity:0;"/>
51
+ </linearGradient>
52
+ <linearGradient y2="338.81863" x2="300.26785" y1="286.66653" x1="255.31609" gradientTransform="matrix(0.9553353,0,0,0.9553353,-84.896827,472.67243)" gradientUnits="userSpaceOnUse" id="linearGradient11925" xlink:href="#linearGradient4148-9" inkscape:collect="always"/>
53
+ </defs>
54
+ <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.98994949" inkscape:cx="211.24527" inkscape:cy="230.76804" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1280" inkscape:window-height="748" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1"/>
55
+ <metadata id="metadata11777">
56
+ <rdf:RDF>
57
+ <cc:Work rdf:about="">
58
+ <dc:format>image/svg+xml</dc:format>
59
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
60
+ <dc:title/>
61
+ </cc:Work>
62
+ </rdf:RDF>
63
+ </metadata>
64
+ <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-652.36218)">
65
+ <g id="g11689" transform="matrix(2.9051461,0,0,2.9051461,-368.53183,-1417.5461)">
66
+ <path sodipodi:type="arc" style="fill:#999999;fill-opacity:1;stroke:none" id="path7177" sodipodi:cx="303.75" sodipodi:cy="346.11218" sodipodi:rx="53.035713" sodipodi:ry="53.035713" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" transform="matrix(0.9735424,0,0,0.9735424,-100.92321,445.98894)"/>
67
+ <path sodipodi:type="arc" style="fill:url(#linearGradient11732);fill-opacity:1;stroke:none" id="path7179" sodipodi:cx="303.75" sodipodi:cy="346.11218" sodipodi:rx="53.035713" sodipodi:ry="53.035713" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" transform="matrix(0.9595959,0,0,0.9595959,-96.686937,450.81603)"/>
68
+ <path transform="matrix(0.8735475,0,0,0.8735475,-70.549757,480.5984)" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" sodipodi:ry="53.035713" sodipodi:rx="53.035713" sodipodi:cy="346.11218" sodipodi:cx="303.75" id="path7181" style="fill:#ececec;fill-opacity:1;stroke:none;filter:url(#filter6126-7)" sodipodi:type="arc"/>
69
+ <path sodipodi:type="arc" style="fill:#999999;fill-opacity:1;stroke:none;filter:url(#filter6126-7)" id="path7183" sodipodi:cx="303.75" sodipodi:cy="346.11218" sodipodi:rx="53.035713" sodipodi:ry="53.035713" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" transform="matrix(0.8383837,0,0,0.8383837,-59.868747,492.76902)"/>
70
+ <path sodipodi:type="arc" style="fill:url(#linearGradient11734);fill-opacity:1;stroke:none" id="path7185" sodipodi:cx="303.75" sodipodi:cy="346.11218" sodipodi:rx="53.035713" sodipodi:ry="53.035713" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" transform="matrix(0.8058691,0,0,0.8058691,-49.992417,504.02274)"/>
71
+ <path transform="matrix(0.7582525,0,0,0.7582525,-34.266187,522.52374)" d="m 356.78571,346.11218 c 0,29.29082 -23.74489,53.03572 -53.03571,53.03572 -29.29082,0 -53.03571,-23.7449 -53.03571,-53.03572 0,-29.29081 23.74489,-53.03571 53.03571,-53.03571 29.29082,0 53.03571,23.7449 53.03571,53.03571 z" sodipodi:ry="53.035713" sodipodi:rx="53.035713" sodipodi:cy="346.11218" sodipodi:cx="303.75" id="path7187" style="fill:url(#radialGradient11736);fill-opacity:1;stroke:none" sodipodi:type="arc"/>
72
+ <path id="path7189" d="m 193.78625,742.76451 c -13.3306,0.30069 -26.18606,7.35801 -33.33579,19.74172 -7.69026,13.31988 -6.71392,29.26602 1.15447,41.33061 0.85306,-26.53161 21.13176,-46.51511 46.32378,-45.05384 8.25891,0.47907 16.05431,3.20007 22.85883,7.59075 -3.25775,-7.44975 -8.8171,-13.95312 -16.3937,-18.32748 -6.48672,-3.74508 -13.62489,-5.43927 -20.60759,-5.28176 z" style="opacity:0.31770833;fill:url(#linearGradient11925);fill-opacity:1;stroke:none" inkscape:connector-curvature="0"/>
73
+ </g>
74
+ </g>
75
+ </svg>