geostats 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.
- data/LICENSE +13 -0
- data/README.md +58 -0
- data/bin/geostats +33 -0
- data/lib/geostats.rb +36 -0
- data/lib/geostats/commands/base.rb +73 -0
- data/lib/geostats/commands/console.rb +17 -0
- data/lib/geostats/commands/generate.rb +21 -0
- data/lib/geostats/commands/help.rb +20 -0
- data/lib/geostats/commands/init.rb +31 -0
- data/lib/geostats/commands/migrate.rb +21 -0
- data/lib/geostats/commands/push.rb +41 -0
- data/lib/geostats/commands/set.rb +35 -0
- data/lib/geostats/commands/update.rb +175 -0
- data/lib/geostats/console.rb +2 -0
- data/lib/geostats/core_ext.rb +5 -0
- data/lib/geostats/database.rb +15 -0
- data/lib/geostats/generator.rb +43 -0
- data/lib/geostats/grabber/cache.rb +95 -0
- data/lib/geostats/grabber/log.rb +27 -0
- data/lib/geostats/grabber/logs.rb +37 -0
- data/lib/geostats/grabber/user.rb +15 -0
- data/lib/geostats/http.rb +97 -0
- data/lib/geostats/migrations/001_create_caches.rb +27 -0
- data/lib/geostats/migrations/002_create_cache_types.rb +16 -0
- data/lib/geostats/migrations/003_create_logs.rb +13 -0
- data/lib/geostats/migrations/004_create_log_types.rb +15 -0
- data/lib/geostats/migrations/005_create_settings.rb +9 -0
- data/lib/geostats/migrations/006_add_cito_cache_type.rb +5 -0
- data/lib/geostats/models/cache.rb +47 -0
- data/lib/geostats/models/cache_type.rb +9 -0
- data/lib/geostats/models/log.rb +33 -0
- data/lib/geostats/models/log_type.rb +9 -0
- data/lib/geostats/models/setting.rb +16 -0
- data/lib/geostats/stats.rb +220 -0
- data/lib/geostats/templates/default.mustache +10 -0
- data/lib/geostats/templates/difficulty_terrain_matrix.mustache +40 -0
- data/lib/geostats/templates/founds_by_cache_type.mustache +17 -0
- data/lib/geostats/templates/milestones.mustache +19 -0
- data/lib/geostats/templates/monthly_founds.mustache +18 -0
- data/lib/geostats/templates/stylesheet.css +160 -0
- data/lib/geostats/utils.rb +42 -0
- data/lib/geostats/version.rb +3 -0
- data/lib/geostats/views/base.rb +19 -0
- data/lib/geostats/views/default.rb +13 -0
- data/lib/geostats/views/difficulty_terrain_matrix.rb +34 -0
- data/lib/geostats/views/founds_by_cache_type.rb +24 -0
- data/lib/geostats/views/milestones.rb +23 -0
- data/lib/geostats/views/monthly_founds.rb +24 -0
- metadata +165 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module Geostats
|
2
|
+
class Log < ActiveRecord::Base
|
3
|
+
belongs_to :cache, :class_name => "Geostats::Cache"
|
4
|
+
belongs_to :log_type, :class_name => "Geostats::LogType"
|
5
|
+
|
6
|
+
scope :found_or_attended, lambda { where("logs.log_type_id IN (?)", [1, 12]) }
|
7
|
+
|
8
|
+
def self.create_from_website(uuid)
|
9
|
+
log = Log.new(:uuid => uuid)
|
10
|
+
log.update_from_website
|
11
|
+
log
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_from_website
|
15
|
+
info = Grabber::Log.new(self.uuid)
|
16
|
+
|
17
|
+
[:logged_at, :message].each do |attribute|
|
18
|
+
if value = info.send(attribute)
|
19
|
+
self.attributes = { attribute => value }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
set_type_from_icon(info.icon)
|
24
|
+
self.synced_at = Time.now
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_type_from_icon(icon)
|
28
|
+
if icon and index = LogType::ICON_MAPPING.index(icon)
|
29
|
+
self.log_type = LogType.where(:id => index + 1).first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Geostats
|
2
|
+
class LogType < ActiveRecord::Base
|
3
|
+
has_many :logs, :class_name => "Geostats::Log"
|
4
|
+
|
5
|
+
ICON_MAPPING = %w(icon_smile icon_sad icon_note icon_XXX icon_needsmaint
|
6
|
+
traffic_cone icon_enabled icon_disabled coord_update XXX icon_rsvp
|
7
|
+
icon_attended)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Geostats
|
2
|
+
class Setting < ActiveRecord::Base
|
3
|
+
validates :key, :presence => true, :uniqueness => true
|
4
|
+
|
5
|
+
def self.get(key)
|
6
|
+
setting = where(:key => key.to_s).first
|
7
|
+
setting ? setting.value : nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.set(key, value)
|
11
|
+
setting = where(:key => key.to_s).first || new(:key => key.to_s)
|
12
|
+
setting.update_attribute(:value, value)
|
13
|
+
setting
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
module Geostats
|
2
|
+
class Stats
|
3
|
+
class << self
|
4
|
+
def milestones(step=nil)
|
5
|
+
logs = Log
|
6
|
+
.joins(:cache)
|
7
|
+
.found_or_attended
|
8
|
+
.order("logs.logged_at ASC")
|
9
|
+
.all
|
10
|
+
total = logs.length
|
11
|
+
milestones = []
|
12
|
+
|
13
|
+
step ||= case total
|
14
|
+
when 0 then 0
|
15
|
+
when 1..100 then 50
|
16
|
+
when 101..1000 then 100
|
17
|
+
else 500
|
18
|
+
end
|
19
|
+
|
20
|
+
milestones << { :milestone => 1, :log => logs.first }
|
21
|
+
|
22
|
+
1.upto(total / step) do |i|
|
23
|
+
i *= step
|
24
|
+
log = logs[i - 1]
|
25
|
+
|
26
|
+
milestones << {
|
27
|
+
:milestone => i,
|
28
|
+
:log => logs[i - 1],
|
29
|
+
:distance => (log.logged_at - milestones.last[:log].logged_at) / 60 / 60 / 24
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
milestones << {
|
34
|
+
:milestone => total,
|
35
|
+
:log => logs.last,
|
36
|
+
:distance => (logs.last.logged_at - milestones.last[:log].logged_at) / 60 / 60 / 24
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def total_founds
|
41
|
+
Cache
|
42
|
+
.joins(:logs)
|
43
|
+
.found_or_attended
|
44
|
+
.count
|
45
|
+
end
|
46
|
+
|
47
|
+
def caching_days
|
48
|
+
Cache
|
49
|
+
.joins(:logs)
|
50
|
+
.found_or_attended
|
51
|
+
.group("logs.logged_at")
|
52
|
+
.count
|
53
|
+
.length
|
54
|
+
end
|
55
|
+
|
56
|
+
def avg_founds_per_caching_day
|
57
|
+
Cache
|
58
|
+
.joins(:logs)
|
59
|
+
.found_or_attended
|
60
|
+
.group("logs.logged_at")
|
61
|
+
.count
|
62
|
+
.to_a
|
63
|
+
.map { |a| a[1] }
|
64
|
+
.avg
|
65
|
+
end
|
66
|
+
|
67
|
+
def monthly_founds(months=6)
|
68
|
+
beginning_of_current_month = Time.parse("#{Time.now.strftime("%Y-%m")}-01")
|
69
|
+
|
70
|
+
0.upto(months - 1).map do |x|
|
71
|
+
start = beginning_of_current_month - x.months
|
72
|
+
count = Cache
|
73
|
+
.joins(:logs)
|
74
|
+
.found_or_attended
|
75
|
+
.where("logs.logged_at >= ? AND logs.logged_at < ?", start, start + 1.month)
|
76
|
+
.count
|
77
|
+
|
78
|
+
[start, count]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def daily_founds(days=30)
|
83
|
+
today = Time.parse(Time.now.strftime("%Y-%m-%d"))
|
84
|
+
|
85
|
+
1.upto(days).map do |x|
|
86
|
+
day = today - x.days
|
87
|
+
|
88
|
+
Cache
|
89
|
+
.joins(:logs)
|
90
|
+
.found_or_attended
|
91
|
+
.where("logs.logged_at >= ? AND logs.logged_at < ?", day, day + 1.day)
|
92
|
+
.count
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def day_with_most_founds
|
97
|
+
@day_with_most_founds ||= Cache
|
98
|
+
.joins(:logs)
|
99
|
+
.found_or_attended
|
100
|
+
.group("logs.logged_at")
|
101
|
+
.count
|
102
|
+
.to_a
|
103
|
+
.sort { |a, b| a[1] <=> b[1] }
|
104
|
+
.last
|
105
|
+
end
|
106
|
+
|
107
|
+
def founds_by_cache_type
|
108
|
+
CacheType.all.map do |type|
|
109
|
+
count = Cache
|
110
|
+
.joins(:logs)
|
111
|
+
.found_or_attended
|
112
|
+
.where("caches.cache_type_id = ?", type.id)
|
113
|
+
.count
|
114
|
+
|
115
|
+
[type, count]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def newest_cache
|
120
|
+
@newest_cache ||= Cache
|
121
|
+
.joins(:logs)
|
122
|
+
.found_or_attended
|
123
|
+
.order("caches.hidden_at DESC")
|
124
|
+
.first
|
125
|
+
end
|
126
|
+
|
127
|
+
def oldest_cache
|
128
|
+
@oldest_cache ||= Cache
|
129
|
+
.joins(:logs)
|
130
|
+
.found_or_attended
|
131
|
+
.order("caches.hidden_at ASC")
|
132
|
+
.first
|
133
|
+
end
|
134
|
+
|
135
|
+
def cache_with_most_founds
|
136
|
+
@cache_with_most_founds ||= Cache
|
137
|
+
.joins(:logs)
|
138
|
+
.found_or_attended
|
139
|
+
.order("caches.founds_count DESC")
|
140
|
+
.first
|
141
|
+
end
|
142
|
+
|
143
|
+
def cache_with_most_dnf
|
144
|
+
@cache_with_most_dnf ||= Cache
|
145
|
+
.joins(:logs)
|
146
|
+
.found_or_attended
|
147
|
+
.order("caches.dnf_count DESC")
|
148
|
+
.first
|
149
|
+
end
|
150
|
+
|
151
|
+
def archived_total_ratio
|
152
|
+
@archived_total_ratio ||= begin
|
153
|
+
archived = Cache
|
154
|
+
.joins(:logs)
|
155
|
+
.found_or_attended
|
156
|
+
.where("caches.is_archived = ?", true)
|
157
|
+
.count
|
158
|
+
|
159
|
+
total = Cache
|
160
|
+
.joins(:logs)
|
161
|
+
.found_or_attended
|
162
|
+
.count
|
163
|
+
|
164
|
+
{
|
165
|
+
:archived => archived,
|
166
|
+
:total => total,
|
167
|
+
:percentage => (archived.to_f / total.to_f * 100.0).round
|
168
|
+
}
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def most_northerly_cache
|
173
|
+
@most_northerly_cache ||= Cache
|
174
|
+
.joins(:logs)
|
175
|
+
.found_or_attended
|
176
|
+
.order("caches.latitude DESC")
|
177
|
+
.first
|
178
|
+
end
|
179
|
+
|
180
|
+
def most_southerly_cache
|
181
|
+
@most_southerly_cache ||= Cache
|
182
|
+
.joins(:logs)
|
183
|
+
.found_or_attended
|
184
|
+
.order("caches.latitude ASC")
|
185
|
+
.first
|
186
|
+
end
|
187
|
+
|
188
|
+
def most_westerly_cache
|
189
|
+
@most_westerly_cache ||= Cache
|
190
|
+
.joins(:logs)
|
191
|
+
.found_or_attended
|
192
|
+
.order("caches.longitude ASC")
|
193
|
+
.first
|
194
|
+
end
|
195
|
+
|
196
|
+
def most_easterly_cache
|
197
|
+
@most_easterly_cache ||= Cache
|
198
|
+
.joins(:logs)
|
199
|
+
.found_or_attended
|
200
|
+
.order("caches.longitude DESC")
|
201
|
+
.first
|
202
|
+
end
|
203
|
+
|
204
|
+
def difficulty_terrain_matrix
|
205
|
+
[1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5].map do |difficulty|
|
206
|
+
result = Cache
|
207
|
+
.joins(:logs)
|
208
|
+
.found_or_attended
|
209
|
+
.where("caches.difficulty = ?", difficulty)
|
210
|
+
.group(:terrain)
|
211
|
+
.count
|
212
|
+
|
213
|
+
[1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5].map do |terrain|
|
214
|
+
result[terrain.to_f] || 0
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<div id="geostats">
|
2
|
+
{{{monthly_founds}}}
|
3
|
+
{{{founds_by_cache_type}}}
|
4
|
+
{{{milestones}}}
|
5
|
+
{{{difficulty_terrain_matrix}}}
|
6
|
+
<div id="about" class="box shadow">
|
7
|
+
Statistics generated on {{generation_date}} using
|
8
|
+
<a href="http://nano.github.com/geostats">geostats {{geostats_version}}</a>
|
9
|
+
</div>
|
10
|
+
</div>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<div id="difficulty-terrain-matrix" class="box">
|
2
|
+
<h2>Difficulty Terrain Matrix</h2>
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<td width="9%"></td>
|
6
|
+
<td width="9%" class="label">T1</td>
|
7
|
+
<td width="9%" class="label">T1.5</td>
|
8
|
+
<td width="9%" class="label">T2</td>
|
9
|
+
<td width="9%" class="label">T2.5</td>
|
10
|
+
<td width="9%" class="label">T3</td>
|
11
|
+
<td width="9%" class="label">T3.5</td>
|
12
|
+
<td width="9%" class="label">T4</td>
|
13
|
+
<td width="9%" class="label">T4.5</td>
|
14
|
+
<td width="9%" class="label">T5</td>
|
15
|
+
<td width="9%"></td>
|
16
|
+
</tr>
|
17
|
+
{{#matrix}}
|
18
|
+
<tr>
|
19
|
+
<td class="label">D{{difficulty}}</td>
|
20
|
+
<td class="number">{{t1}}</td>
|
21
|
+
<td class="number">{{t15}}</td>
|
22
|
+
<td class="number">{{t2}}</td>
|
23
|
+
<td class="number">{{t25}}</td>
|
24
|
+
<td class="number">{{t3}}</td>
|
25
|
+
<td class="number">{{t35}}</td>
|
26
|
+
<td class="number">{{t4}}</td>
|
27
|
+
<td class="number">{{t45}}</td>
|
28
|
+
<td class="number">{{t5}}</td>
|
29
|
+
<td class="number sum">{{dsum}}</td>
|
30
|
+
</tr>
|
31
|
+
{{/matrix}}
|
32
|
+
<tr>
|
33
|
+
<td></td>
|
34
|
+
{{#tsums}}
|
35
|
+
<td class="number sum">{{sum}}</td>
|
36
|
+
{{/tsums}}
|
37
|
+
<td></td>
|
38
|
+
</tr>
|
39
|
+
</table>
|
40
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div id="founds-by-cache-type" class="box">
|
2
|
+
<h2>Founds By Cache Type</h2>
|
3
|
+
<div class="charts">
|
4
|
+
{{#founds_by_cache_type}}
|
5
|
+
<div class="section">
|
6
|
+
<div class="name">
|
7
|
+
{{name}}
|
8
|
+
</div>
|
9
|
+
<div class="chartbar" style="width: {{height}}px;"></div>
|
10
|
+
<div class="founds">
|
11
|
+
{{founds}}
|
12
|
+
</div>
|
13
|
+
<br style="clear: both;">
|
14
|
+
</div>
|
15
|
+
{{/founds_by_cache_type}}
|
16
|
+
</div>
|
17
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div id="milestones" class="box">
|
2
|
+
<h2>Milestones</h2>
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th></th>
|
6
|
+
<th align="left">Cache</th>
|
7
|
+
<th align="left">Date</th>
|
8
|
+
<th align="right">Distance in days</th>
|
9
|
+
</tr>
|
10
|
+
{{#milestones}}
|
11
|
+
<tr>
|
12
|
+
<td align="right" width="6%">{{milestone}}</td>
|
13
|
+
<td><a href="{{cache_url}}">{{name}}</a> ({{type}})</td>
|
14
|
+
<td width="16%"><a href="{{log_url}}">{{date}}</a></td>
|
15
|
+
<td align="right" width="16%">{{distance}}</td>
|
16
|
+
</tr>
|
17
|
+
{{/milestones}}
|
18
|
+
</table>
|
19
|
+
</div>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div id="monthly-founds" class="box">
|
2
|
+
<h2>Founds By Month</h2>
|
3
|
+
<div class="charts">
|
4
|
+
{{#monthly_founds}}
|
5
|
+
<div class="section">
|
6
|
+
<div class="chartbox">
|
7
|
+
{{founds}}
|
8
|
+
<div class="chartbar" style="height: {{height}}px;"></div>
|
9
|
+
</div>
|
10
|
+
<div class="date">
|
11
|
+
{{month}}<br>
|
12
|
+
{{year}}
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
{{/monthly_founds}}
|
16
|
+
<br style="clear: both;">
|
17
|
+
</div>
|
18
|
+
</div>
|
@@ -0,0 +1,160 @@
|
|
1
|
+
#geostats {
|
2
|
+
font: normal 13px Helvetica;
|
3
|
+
}
|
4
|
+
|
5
|
+
#geostats a {
|
6
|
+
color: rgb(19, 94, 196);
|
7
|
+
text-decoration: none;
|
8
|
+
}
|
9
|
+
|
10
|
+
#geostats .box {
|
11
|
+
width: 700px;
|
12
|
+
background-color: #eee;
|
13
|
+
background-image: -webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#e0e0e0));
|
14
|
+
-webkit-border-radius: 15px;
|
15
|
+
padding: 20px;
|
16
|
+
margin: 30px auto;
|
17
|
+
}
|
18
|
+
|
19
|
+
#geostats .box h2 {
|
20
|
+
color: rgb(19, 94, 196);
|
21
|
+
text-align: center;
|
22
|
+
text-shadow: #fff 1px 1px;
|
23
|
+
margin: 0 0 10px 0;
|
24
|
+
}
|
25
|
+
|
26
|
+
#geostats .shadow {
|
27
|
+
text-shadow: #fff 1px 1px;
|
28
|
+
color: #888;
|
29
|
+
}
|
30
|
+
|
31
|
+
#about {
|
32
|
+
text-align: center;
|
33
|
+
}
|
34
|
+
|
35
|
+
#milestones {
|
36
|
+
color: #777;
|
37
|
+
text-shadow: #fff 1px 1px;
|
38
|
+
}
|
39
|
+
|
40
|
+
#milestones table {
|
41
|
+
width: 100%;
|
42
|
+
border-spacing: 0;
|
43
|
+
padding: 0 20px;
|
44
|
+
}
|
45
|
+
|
46
|
+
#milestones td, #milestones th {
|
47
|
+
padding: 6px 10px;
|
48
|
+
}
|
49
|
+
|
50
|
+
#milestones th {
|
51
|
+
color: #999;
|
52
|
+
font-size: 11px;
|
53
|
+
font-weight: normal;
|
54
|
+
}
|
55
|
+
|
56
|
+
#founds-by-cache-type h2 {
|
57
|
+
color: rgb(210, 14, 14);
|
58
|
+
margin-bottom: 20px;
|
59
|
+
}
|
60
|
+
|
61
|
+
#founds-by-cache-type .charts {
|
62
|
+
width: 650px;
|
63
|
+
margin: auto;
|
64
|
+
}
|
65
|
+
|
66
|
+
#founds-by-cache-type .section {
|
67
|
+
margin: 10px 0;
|
68
|
+
}
|
69
|
+
|
70
|
+
#founds-by-cache-type .chartbar {
|
71
|
+
float: left;
|
72
|
+
height: 20px;
|
73
|
+
background-color: rgb(210, 14, 14);
|
74
|
+
-webkit-border-top-right-radius: 4px;
|
75
|
+
-webkit-border-bottom-right-radius: 4px;
|
76
|
+
}
|
77
|
+
#founds-by-cache-type .founds {
|
78
|
+
float: left;
|
79
|
+
margin-left: 10px;
|
80
|
+
line-height: 20px;
|
81
|
+
color: rgb(210, 14, 14);
|
82
|
+
font-weight: bold;
|
83
|
+
}
|
84
|
+
|
85
|
+
#founds-by-cache-type .name {
|
86
|
+
float: left;
|
87
|
+
width: 180px;
|
88
|
+
margin-right: 20px;
|
89
|
+
color: #999;
|
90
|
+
text-align: right;
|
91
|
+
text-shadow: #fff 1px 1px;
|
92
|
+
line-height: 20px;
|
93
|
+
}
|
94
|
+
|
95
|
+
#monthly-founds .charts {
|
96
|
+
width: 672px;
|
97
|
+
margin: auto;
|
98
|
+
}
|
99
|
+
|
100
|
+
#monthly-founds .section {
|
101
|
+
float: left;
|
102
|
+
margin: 0 3px;
|
103
|
+
}
|
104
|
+
|
105
|
+
#monthly-founds .chartbox {
|
106
|
+
display: table-cell;
|
107
|
+
vertical-align: bottom;
|
108
|
+
height: 160px;
|
109
|
+
text-align: center;
|
110
|
+
color: rgb(19, 94, 196);
|
111
|
+
font-weight: bold;
|
112
|
+
}
|
113
|
+
|
114
|
+
#monthly-founds .chartbar {
|
115
|
+
background-color: rgb(19, 94, 196);
|
116
|
+
width: 50px;
|
117
|
+
-webkit-border-top-right-radius: 6px 6px;
|
118
|
+
-webkit-border-top-left-radius: 6px 6px;
|
119
|
+
margin-top: 3px;
|
120
|
+
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
121
|
+
}
|
122
|
+
|
123
|
+
#monthly-founds .date {
|
124
|
+
color: #AAA;
|
125
|
+
text-align: center;
|
126
|
+
margin-top: 5px;
|
127
|
+
text-shadow: #FFF 1px 1px;
|
128
|
+
}
|
129
|
+
|
130
|
+
#difficulty-terrain-matrix h2 {
|
131
|
+
color: rgb(36, 191, 19);
|
132
|
+
margin-bottom: 20px;
|
133
|
+
}
|
134
|
+
|
135
|
+
#difficulty-terrain-matrix table {
|
136
|
+
width: 100%;
|
137
|
+
padding: 0 20px;
|
138
|
+
border-spacing: 2px;
|
139
|
+
font-size: 11px;
|
140
|
+
text-align: center;
|
141
|
+
}
|
142
|
+
|
143
|
+
#difficulty-terrain-matrix td.number,
|
144
|
+
#difficulty-terrain-matrix td.label,
|
145
|
+
#difficulty-terrain-matrix td.sum {
|
146
|
+
color: #fff;
|
147
|
+
text-shadow: #888 0px 1px;
|
148
|
+
-webkit-border-radius: 3px;
|
149
|
+
padding: 4px;
|
150
|
+
}
|
151
|
+
|
152
|
+
#difficulty-terrain-matrix td.number {
|
153
|
+
background-color: rgba(36, 191, 19, 0.75);
|
154
|
+
}
|
155
|
+
|
156
|
+
#difficulty-terrain-matrix td.label,
|
157
|
+
#difficulty-terrain-matrix td.sum {
|
158
|
+
font-weight: bold;
|
159
|
+
background-color: rgb(36, 191, 19);
|
160
|
+
}
|