locat 0.1.0

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.
@@ -0,0 +1,39 @@
1
+ module LOCat
2
+
3
+ #
4
+ class Matcher
5
+ include Enumerable
6
+
7
+ #
8
+ def initialize(*config_files)
9
+ @rules = []
10
+
11
+ if config_files.empty?
12
+ raise ArgumentError, 'no configuration files'
13
+ end
14
+
15
+ config_files.each do |f|
16
+ instance_eval(File.read(f))
17
+ end
18
+ end
19
+
20
+ #
21
+ attr :rules
22
+
23
+ #
24
+ def match(files, &block)
25
+ @rules << [files, block]
26
+ end
27
+
28
+ #
29
+ def each(&block)
30
+ @rules.each(&block)
31
+ end
32
+
33
+ #
34
+ def size
35
+ @rules.size
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,104 @@
1
+ module LOCat
2
+
3
+ #
4
+ class Template
5
+
6
+ #
7
+ DIRECTORY = File.dirname(__FILE__) + '/template'
8
+
9
+ #
10
+ def initialize(counter)
11
+ @counter = counter
12
+ end
13
+
14
+ #
15
+ attr :counter
16
+
17
+ #
18
+ def total
19
+ counter.total
20
+ end
21
+
22
+ #
23
+ def counts
24
+ counter.counts
25
+ end
26
+
27
+ #
28
+ def table_loc
29
+ counter.loc
30
+ end
31
+
32
+ #
33
+ def table_pcnt
34
+ counter.percent
35
+ end
36
+
37
+ #
38
+ alias_method :table_percentages, :table_pcnt
39
+
40
+ #
41
+ def table_ratio
42
+ counter.ratio
43
+ end
44
+
45
+ #
46
+ def table_scm
47
+ counter.scm
48
+ end
49
+
50
+ #
51
+ def to_json
52
+ h = {}
53
+ h[:loc] = table_loc
54
+ h[:pcnt] = table_pcnt
55
+ h[:ratio] = table_ratio
56
+ h[:scm] = table_scm if scm?
57
+ h.to_json
58
+ end
59
+
60
+ #
61
+ def scm?
62
+ File.directory?('.git')
63
+ end
64
+
65
+ #
66
+ def title
67
+ "The LOCat on " + metadata['title']
68
+ end
69
+
70
+ #
71
+ def javascript
72
+ @javascript ||= (
73
+ File.read(File.join(DIRECTORY, 'javascript.js'))
74
+ )
75
+ end
76
+
77
+ #
78
+ def render(template)
79
+ file = File.join(DIRECTORY, template + '.rhtml')
80
+ erb = ERB.new(File.read(file))
81
+ erb.result(__binding__)
82
+ end
83
+
84
+ private
85
+
86
+ # Access to .ruby metadata.
87
+ def metadata
88
+ @metadata ||= (
89
+ if File.file?('.ruby')
90
+ YAML.load(File.new('.ruby'))
91
+ else
92
+ {}
93
+ end
94
+ )
95
+ end
96
+
97
+ #
98
+ def __binding__
99
+ binding
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,257 @@
1
+ <html>
2
+
3
+ <head>
4
+ <title>LOCat - <%= config.title %></title>
5
+
6
+ <style>
7
+ body{ background: white; padding: 5px 30px; }
8
+ table{ border-collapse:collapse; }
9
+ table,th,td{ border: 1px solid #ccc; }
10
+ th,td{ padding: 0.5em 1em; margin: 0; }
11
+ h1{ font-size: 2.5em; }
12
+ h2{ font-size: 2.0em; }
13
+ button{ background: transparent; border: 1px solid #ccc; padding: 10px;
14
+ border-bottom: 0; font-weight: bold;
15
+ }
16
+ button:hover{ background: yellow; }
17
+
18
+ #footer{ font-size: 0.8em; color: #666; padding-top: 5px; }
19
+
20
+ .tab{ padding: 20px; border: 1px solid #ccc; }
21
+ .chart{ padding-bottom: 40px; }
22
+ .chart-select{ text-align: center; font-size: 12px; }
23
+ </style>
24
+
25
+ <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
26
+ <script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/1.5.2/raphael-min.js" type="text/javascript"></script>
27
+
28
+ <!-- http://cdnjs.cloudflare.com/ajax/libs/graphael/0.4.1/g.raphael-min.js" -->
29
+ <script src="https://raw.github.com/DmitryBaranovskiy/g.raphael/master/g.raphael-min.js" type="text/javascript"></script>
30
+ <script src="https://raw.github.com/DmitryBaranovskiy/g.raphael/master/g.pie-min.js" type="text/javascript"></script>
31
+ <script src="https://raw.github.com/DmitryBaranovskiy/g.raphael/master/g.bar-min.js" type="text/javascript"></script>
32
+ <script src="https://raw.github.com/DmitryBaranovskiy/g.raphael/master/g.line-min.js" type="text/javascript"></script>
33
+ <script src="https://raw.github.com/DmitryBaranovskiy/g.raphael/master/g.dot-min.js" type="text/javascript"></script>
34
+
35
+ <script>
36
+ var data = <%= to_json %>;
37
+ </script>
38
+
39
+ <script>
40
+ //var chart = {};
41
+ $(document).ready(function() {
42
+ draw_chart('loc', 'bar');
43
+ draw_chart('pcnt', 'bar');
44
+ draw_chart('ratio', 'bar');
45
+ });
46
+ </script>
47
+
48
+ <script>
49
+ //r.g.text(160, 10, "Single Series Chart");
50
+ //r.g.text(480, 10, "Multiline Series Stacked Chart");
51
+ //r.g.text(160, 250, "Multiple Series Chart");
52
+ //r.g.text(480, 250, "Multiline Series Stacked Chart\nColumn Hover");
53
+
54
+ function draw_chart(chart_id) {
55
+ var r = Raphael("chart-" + chart_id),
56
+ fin = function () {
57
+ this.flag = r.g.popup(this.bar.x, this.bar.y, this.bar.value || "0").insertBefore(this);
58
+ },
59
+ fout = function () {
60
+ this.flag.animate({opacity: 0}, 300, function () {this.remove();});
61
+ };
62
+ var d = [];
63
+ var l = [];
64
+ $.each(data[chart_id], function(lineNo, line) {
65
+ l = [];
66
+ if (lineNo == 0) {
67
+ $.each(line, function(itemNo, item) {
68
+ // do something with header
69
+ });
70
+ } else {
71
+ $.each(line, function(itemNo, item) {
72
+ if (itemNo == 0) {
73
+ // do something with row header
74
+ } else {
75
+ l.push(parseFloat(item));
76
+ }
77
+ });
78
+ }
79
+ d.push(l);
80
+ });
81
+
82
+ r.g.txtattr.font = "12px 'Fontin Sans', Fontin-Sans, sans-serif";
83
+
84
+ //r.g.barchart(0, 0, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]]).hover(fin, fout);
85
+ r.g.barchart(0, 0, 500, 500, d, {stacked: true, type: "soft"}).hover(fin, fout);
86
+ };
87
+
88
+ function rechart(chart_id, chart_type){
89
+ //chart[chart_id] = build_chart(chart_id, chart_type);
90
+ draw_chart(chart_id); //, chart_type);
91
+ };
92
+
93
+ function change_tab(chart_id){
94
+ $('.tab').hide();
95
+ $('#tab-' + chart_id).fadeIn();
96
+ };
97
+ </script>
98
+ </head>
99
+
100
+ <body>
101
+ <h1><%= config.title %></h1>
102
+
103
+ <div id="nav">
104
+ <button onclick="change_tab('loc');">LOC</button>
105
+ <button onclick="change_tab('pcnt');">Percent</button>
106
+ <button onclick="change_tab('ratio');">Ratio</button>
107
+ </div>
108
+
109
+ <!-- LOC CHART -->
110
+
111
+ <div id="tab-loc" class="tab">
112
+
113
+ <h2>LOC</h2>
114
+
115
+ <div class="chart">
116
+ <table id="table-loc" border="1">
117
+ <thead>
118
+ <tr>
119
+ <% counts.keys.each do |h| %>
120
+ <th><%= h %></th>
121
+ <% end %>
122
+ <th>Total</th>
123
+ </tr>
124
+ </thead>
125
+ <tbody>
126
+ <tr>
127
+ <% counts.values.each do |v| %>
128
+ <td><%= v %></td>
129
+ <% end %>
130
+ <td><%= total %></td>
131
+ </tr>
132
+ </tbody>
133
+ </table>
134
+ </div>
135
+
136
+ <div id="chart-loc" style="width: 95%; height: 450px;">
137
+ </div>
138
+
139
+ <div class="chart-select">
140
+ <input type="radio" name="ratio" value="column" onclick="rechart('loc', 'column');" /> Column
141
+ <input type="radio" name="ratio" value="bar" onclick="rechart('loc', 'bar');" /> Bar
142
+ <input type="radio" name="ratio" value="scatter" onclick="rechart('loc', 'scatter');" /> Scatter
143
+ <!--
144
+ <input type="radio" name="ratio" value="line" onclick="rechart('loc', 'line');" /> Line
145
+ <input type="radio" name="ratio" value="spline" onclick="rechart('loc', 'spline');" /> Spline
146
+ <input type="radio" name="ratio" value="area" onclick="rechart('loc', 'area');" /> Area
147
+ <input type="radio" name="ratio" value="areaspline" onclick="rechart('loc', 'areaspline');" /> Area Spline
148
+ -->
149
+ <input type="radio" name="ratio" value="pie" onclick="rechart('loc', 'pie');" /> Pie Chart
150
+ </div>
151
+
152
+ </div>
153
+
154
+ <!-- PERCENTAGE CHART -->
155
+
156
+ <div id="tab-pcnt" class="tab" style="display: none;">
157
+
158
+ <h2>PERECNT</h2>
159
+
160
+ <div class="chart">
161
+ <table id="table-pcnt">
162
+ <thead>
163
+ <tr>
164
+ <% percent[0].each do |h| %>
165
+ <th scope="col"><%= h %></th>
166
+ <% end %>
167
+ </tr>
168
+ </thead>
169
+ <tbody>
170
+ <% percent[1..-1].each do |c| %>
171
+ <tr>
172
+ <% c.each_with_index do |v, j| %>
173
+ <% if j == 0 %>
174
+ <th><%= v %></th>
175
+ <% else %>
176
+ <td><%= v %></td>
177
+ <% end %>
178
+ <% end %>
179
+ </tr>
180
+ <% end %>
181
+ </tbody>
182
+ </table>
183
+ </div>
184
+
185
+ <div id="chart-pcnt" style="width: 95%; height: 450px;"></div>
186
+
187
+ <div class="chart-select">
188
+ <input type="radio" name="ratio" value="column" onclick="rechart('pcnt', 'column');" /> Column
189
+ <input type="radio" name="ratio" value="bar" onclick="rechart('pcnt', 'bar');" /> Bar
190
+ <input type="radio" name="ratio" value="scatter" onclick="rechart('pcnt', 'scatter');" /> Scatter
191
+ <!--
192
+ <input type="radio" name="ratio" value="line" onclick="rechart('pcnt', 'line');" /> Line
193
+ <input type="radio" name="ratio" value="spline" onclick="rechart('pcnt', 'spline');" /> Spline
194
+ <input type="radio" name="ratio" value="area" onclick="rechart('pcnt', 'area');" /> Area
195
+ <input type="radio" name="ratio" value="areaspline" onclick="rechart('pcnt', 'areaspline');" /> Area Spline
196
+ -->
197
+ <input type="radio" name="ratio" value="pie" onclick="rechart('pcnt', 'pie');" /> Pie Chart
198
+ </div>
199
+
200
+ </div>
201
+
202
+ <!-- RATIO CHART -->
203
+
204
+ <div id="tab-ratio" class="tab" style="display: none;">
205
+
206
+ <h2>RATIOS</h2>
207
+
208
+ <div class="chart">
209
+ <table id="table-ratio">
210
+ <thead>
211
+ <tr>
212
+ <% ratio[0].each do |h| %>
213
+ <th scope="col"><%= h %></th>
214
+ <% end %>
215
+ </tr>
216
+ </thead>
217
+ <tbody>
218
+ <% ratio[1..-1].each do |c| %>
219
+ <tr>
220
+ <% c.each_with_index do |v, j| %>
221
+ <% if j == 0 %>
222
+ <th><%= v %></th>
223
+ <% else %>
224
+ <td><%= v %></td>
225
+ <% end %>
226
+ <% end %>
227
+ </tr>
228
+ <% end %>
229
+ </tbody>
230
+ </table>
231
+ </div>
232
+
233
+ <div id="chart-ratio" style="width: 95%; height: 450px;"></div>
234
+
235
+ <div class="chart-select">
236
+ <input type="radio" name="ratio" value="column" onclick="rechart('ratio', 'column');" /> Column
237
+ <input type="radio" name="ratio" value="bar" onclick="rechart('ratio', 'bar');" /> Bar
238
+ <input type="radio" name="ratio" value="scatter" onclick="rechart('ratio', 'scatter');" /> Scatter
239
+ <!--
240
+ <input type="radio" name="ratio" value="line" onclick="rechart('ratio', 'line');" /> Line
241
+ <input type="radio" name="ratio" value="spline" onclick="rechart('ratio', 'spline');" /> Spline
242
+ <input type="radio" name="ratio" value="area" onclick="rechart('ratio', 'area');" /> Area
243
+ <input type="radio" name="ratio" value="areaspline" onclick="rechart('ratio', 'areaspline');" /> Area Spline
244
+ <input type="radio" name="ratio" value="pie" onclick="rechart('ratio', 'pie');" /> Pie Chart
245
+ -->
246
+ </div>
247
+
248
+ </div>
249
+
250
+ <div id="footer">
251
+ <a href="http://rubyworks.github.com/locat">LOCat v0.1.0</a>,
252
+ Copyright &copy; 2011 Thomas Sawyer, <a href="http://rubyworks.github.com">Rubyworks</a>
253
+ </div>
254
+
255
+ </body>
256
+
257
+ </html>
@@ -0,0 +1,249 @@
1
+ <html>
2
+
3
+ <head>
4
+ <title>LOCat - <%= title %></title>
5
+ <link rel="icon" type="image/jpg" href="http://rubyworks.github.com/locat/assets/images/icon.jpg" />
6
+
7
+ <style>
8
+ body{ background: white; padding: 5px 30px; }
9
+ table{ border-collapse:collapse; }
10
+ table,th,td{ border: 1px solid #ccc; }
11
+ th,td{ padding: 0.5em 1em; margin: 0; }
12
+ h1{ font-size: 2.5em; }
13
+ h2{ font-size: 2.0em; }
14
+ button{ background: transparent; border: 1px solid #ccc; padding: 10px;
15
+ border-bottom: 0; font-weight: bold;
16
+ }
17
+ button:hover{ background: yellow; }
18
+
19
+ #footer{ font-size: 0.8em; color: #666; padding-top: 5px; }
20
+
21
+ .tab{ padding: 20px; border: 1px solid #ccc; }
22
+ .chart{ padding-bottom: 40px; }
23
+ .chart-select{ text-align: left; font-size: 12px; padding-left: 20px; }
24
+ </style>
25
+
26
+ <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
27
+ <script src="http://cdnjs.cloudflare.com/ajax/libs/highcharts/2.1.5/highcharts.js" type="text/javascript"></script>
28
+
29
+ <script>
30
+ <%= javascript %>
31
+ </script>
32
+
33
+ <script>
34
+ var data = <%= to_json %>;
35
+ </script>
36
+
37
+ <script>
38
+ var chart = {};
39
+
40
+ $(document).ready(function() {
41
+ chart['pcnt'] = create_chart('pcnt', data['pcnt'], 'pie');
42
+ chart['loc'] = create_chart('loc', data['loc'], 'column');
43
+ chart['ratio'] = create_chart('ratio', data['ratio'], 'column');
44
+ chart['scm'] = create_chart('scm', data['scm'], 'line');
45
+ });
46
+ </script>
47
+
48
+ <script>
49
+ function rechart(chart_id, chart_type){
50
+ chart[chart_id].destroy();
51
+ chart[chart_id] = create_chart(chart_id, data[chart_id], chart_type);
52
+ };
53
+
54
+ function change_tab(chart_id){
55
+ $('.tab').hide(function(){
56
+ $('#tab-' + chart_id).show();
57
+ });
58
+ };
59
+ </script>
60
+ </head>
61
+
62
+ <body>
63
+ <h1><%= title %></h1>
64
+
65
+ <div id="nav">
66
+ <button onclick="change_tab('loc');">Counts</button>
67
+ <button onclick="change_tab('pcnt');">Percentages</button>
68
+ <button onclick="change_tab('ratio');">Ratios</button>
69
+ <% if scm? %>
70
+ <button onclick="change_tab('scm');">Timeline</button>
71
+ <% end %>
72
+ </div>
73
+
74
+ <!-- LOC CHART -->
75
+
76
+ <div id="tab-loc" class="tab">
77
+
78
+ <h2>LINE COUNTS</h2>
79
+
80
+ <div class="chart">
81
+ <table id="loc" border="1">
82
+ <thead>
83
+ <tr>
84
+ <% counts.keys.each do |h| %>
85
+ <th><%= h %></th>
86
+ <% end %>
87
+ <th>Total</th>
88
+ </tr>
89
+ </thead>
90
+ <tbody>
91
+ <tr>
92
+ <% counts.values.each do |v| %>
93
+ <td><%= v %></td>
94
+ <% end %>
95
+ <td><%= total %></td>
96
+ </tr>
97
+ </tbody>
98
+ </table>
99
+ </div>
100
+
101
+ <div id="container-loc" style="width: 95%; height: 450px;"></div>
102
+
103
+ <div class="chart-select">
104
+ <input type="radio" name="loc" value="column" onclick="rechart('loc', 'column');" /> Column
105
+ <input type="radio" name="loc" value="bar" onclick="rechart('loc', 'bar');" /> Bar
106
+ <input type="radio" name="loc" value="scatter" onclick="rechart('loc', 'scatter');" /> Scatter
107
+ <!--
108
+ <input type="radio" name="loc" value="line" onclick="rechart('loc', 'line');" /> Line
109
+ <input type="radio" name="loc" value="spline" onclick="rechart('loc', 'spline');" /> Spline
110
+ <input type="radio" name="loc" value="area" onclick="rechart('loc', 'area');" /> Area
111
+ <input type="radio" name="loc" value="areaspline" onclick="rechart('loc', 'areaspline');" /> Area Spline
112
+ -->
113
+ <input type="radio" name="loc" value="pie" onclick="rechart('loc', 'pie');" /> Pie Chart
114
+ </div>
115
+
116
+ </div>
117
+
118
+ <!-- PERCENTAGE CHART -->
119
+
120
+ <div id="tab-pcnt" class="tab" style="display: none;">
121
+
122
+ <h2>PERCENTAGES</h2>
123
+
124
+ <div class="chart">
125
+ <table id="pcnt">
126
+ <thead>
127
+ <tr>
128
+ <% table_pcnt[0].each do |h| %>
129
+ <th scope="col"><%= h %></th>
130
+ <% end %>
131
+ </tr>
132
+ </thead>
133
+ <tbody>
134
+ <% table_pcnt[1..-1].each do |c| %>
135
+ <tr>
136
+ <% c.each_with_index do |v, j| %>
137
+ <% if j == 0 %>
138
+ <th><%= v %></th>
139
+ <% else %>
140
+ <td><%= v %></td>
141
+ <% end %>
142
+ <% end %>
143
+ </tr>
144
+ <% end %>
145
+ </tbody>
146
+ </table>
147
+ </div>
148
+
149
+ <div id="container-pcnt" style="width: 95%; height: 450px;"></div>
150
+
151
+ <div class="chart-select">
152
+ <input type="radio" name="pcnt" value="column" onclick="rechart('pcnt', 'column');" /> Column
153
+ <input type="radio" name="pcnt" value="bar" onclick="rechart('pcnt', 'bar');" /> Bar
154
+ <input type="radio" name="pcnt" value="scatter" onclick="rechart('pcnt', 'scatter');" /> Scatter
155
+ <!--
156
+ <input type="radio" name="pcnt" value="line" onclick="rechart('pcnt', 'line');" /> Line
157
+ <input type="radio" name="pcnt" value="spline" onclick="rechart('pcnt', 'spline');" /> Spline
158
+ <input type="radio" name="pcnt" value="area" onclick="rechart('pcnt', 'area');" /> Area
159
+ <input type="radio" name="pcnt" value="areaspline" onclick="rechart('pcnt', 'areaspline');" /> Area Spline
160
+ -->
161
+ <input type="radio" name="pcnt" value="pie" onclick="rechart('pcnt', 'pie');" /> Pie Chart
162
+ </div>
163
+
164
+ </div>
165
+
166
+ <!-- RATIO CHART -->
167
+
168
+ <div id="tab-ratio" class="tab" style="display: none;">
169
+
170
+ <h2>RATIOS</h2>
171
+
172
+ <div class="chart">
173
+ <table id="ratio">
174
+ <thead>
175
+ <tr>
176
+ <% table_ratio[0].each do |h| %>
177
+ <th scope="col"><%= h %></th>
178
+ <% end %>
179
+ </tr>
180
+ </thead>
181
+ <tbody>
182
+ <% table_ratio[1..-1].each do |c| %>
183
+ <tr>
184
+ <% c.each_with_index do |v, j| %>
185
+ <% if j == 0 %>
186
+ <th><%= v %></th>
187
+ <% else %>
188
+ <td><%= v %></td>
189
+ <% end %>
190
+ <% end %>
191
+ </tr>
192
+ <% end %>
193
+ </tbody>
194
+ </table>
195
+ </div>
196
+
197
+ <div id="container-ratio" style="width: 95%; height: 450px;"></div>
198
+
199
+ <div class="chart-select">
200
+ <input type="radio" name="ratio" value="column" onclick="rechart('ratio', 'column');" /> Column
201
+ <input type="radio" name="ratio" value="bar" onclick="rechart('ratio', 'bar');" /> Bar
202
+ <input type="radio" name="ratio" value="scatter" onclick="rechart('ratio', 'scatter');" /> Scatter
203
+ <!--
204
+ <input type="radio" name="ratio" value="line" onclick="rechart('ratio', 'line');" /> Line
205
+ <input type="radio" name="ratio" value="spline" onclick="rechart('ratio', 'spline');" /> Spline
206
+ <input type="radio" name="ratio" value="area" onclick="rechart('ratio', 'area');" /> Area
207
+ <input type="radio" name="ratio" value="areaspline" onclick="rechart('ratio', 'areaspline');" /> Area Spline
208
+ <input type="radio" name="ratio" value="pie" onclick="rechart('ratio', 'pie');" /> Pie Chart
209
+ -->
210
+ </div>
211
+
212
+ </div>
213
+
214
+ <% if scm? %>
215
+
216
+ <!-- SCM CHART -->
217
+
218
+ <div id="tab-scm" class="tab" style="display: none;">
219
+
220
+ <h2>TIMELINE</h2>
221
+
222
+ <div id="container-scm" style="width: 95%; height: 450px;"></div>
223
+
224
+ <div class="chart-select">
225
+ <input type="radio" name="scm" value="column" onclick="rechart('scm', 'column');" /> Column
226
+ <input type="radio" name="scm" value="scatter" onclick="rechart('scm', 'scatter');" /> Scatter
227
+ <input type="radio" name="scm" value="line" onclick="rechart('scm', 'line');" /> Line
228
+ <input type="radio" name="scm" value="spline" onclick="rechart('scm', 'spline');" /> Spline
229
+ <!--
230
+ <input type="radio" name="scm" value="area" onclick="rechart('scm', 'area');" /> Area
231
+ <input type="radio" name="scm" value="areaspline" onclick="rechart('scm', 'areaspline');" /> Area Spline
232
+ <input type="radio" name="scm" value="pie" onclick="rechart('scm', 'pie');" /> Pie Chart
233
+ -->
234
+ </div>
235
+
236
+ </div>
237
+
238
+ <% end %>
239
+
240
+ <!-- FOOTER -->
241
+
242
+ <div id="footer">
243
+ <a href="http://rubyworks.github.com/locat">LOCat v0.1.0</a>,
244
+ Copyright &copy; 2011 Thomas Sawyer, <a href="http://rubyworks.github.com">Rubyworks</a>
245
+ </div>
246
+
247
+ </body>
248
+
249
+ </html>