dafiti-rabbit-hutch 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require "mongo"
4
+
5
+ module RabbitHutch
6
+ class MongoConsumer
7
+
8
+ def initialize(rabbitmq_host, config)
9
+ puts "\tInitializing MongoDb Consumer"
10
+ @config = config
11
+ @rabbitmq_host = rabbitmq_host
12
+
13
+ @config.consumers.each do |consumer|
14
+ if consumer["name"] == 'mongo_consumer'
15
+ @host = consumer['hostname']
16
+ @port = consumer["port"]
17
+ @database_prefix = consumer['database_prefix']
18
+ @database = "#{@database_prefix}#{rabbitmq_host["displayname"]}"
19
+ end
20
+ end
21
+ @connection = Mongo::Connection.new(@host, @port)
22
+ end
23
+
24
+ def log_event(item)
25
+ begin
26
+ puts "mongo"
27
+ db = @connection.db(@database)
28
+ coll = db.collection(item[:exchange])
29
+ coll.insert(item)
30
+ rescue Exception => e
31
+ puts "Error occurred Message Handler trying to write messages to MONGODB #{e.inspect}"
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/logger.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'log4r'
2
+ require 'log4r/yamlconfigurator'
3
+ require 'log4r/outputter/syslogoutputter'
4
+
5
+ class Logger
6
+ @@log = nil
7
+ def self.init(config)
8
+ if !@@log.nil?
9
+ return @@log
10
+ end
11
+
12
+ configurator = Log4r::YamlConfigurator
13
+ configurator.decode_yaml config.log_config
14
+ @@log = Log4r::Logger['main']
15
+ end
16
+ end
@@ -0,0 +1,78 @@
1
+ require 'rubygems'
2
+ require "amqp"
3
+ require_relative "configurator"
4
+ require_relative "consumers/mongo_consumer"
5
+ require_relative "consumers/log4r_consumer"
6
+ require_relative "consumers/console_consumer"
7
+ require_relative "worker"
8
+
9
+ @config = RabbitHutch::Configurator.new({})
10
+
11
+ puts "\tEnvironment Settings"
12
+ @config.rabbitmq_hosts.each do |rabbitmq_host|
13
+ puts "\tDisplay Name: #{rabbitmq_host["displayname"]}, host: #{rabbitmq_host["hostname"]}, username: #{rabbitmq_host["username"]}, enabled #{rabbitmq_host["enabled"]}"
14
+ end
15
+
16
+ # Initialize all enabled consumners
17
+ # NOTE: this method will be replaced with a routine to reflect through all valid consumers and initialze them implicitly
18
+ def initialize_consumers(rabbitmq_host)
19
+ puts "Initializing Consumers for #{rabbitmq_host["displayname"]}"
20
+ consumers = []
21
+ @config.consumers.each do |consumer|
22
+ # if consumer["enabled"] == true
23
+ case consumer["name"]
24
+ when "console_consumer"
25
+ consumers << RabbitHutch::ConsoleConsumer.new()
26
+ when "mongo_consumer"
27
+ consumers << RabbitHutch::MongoConsumer.new(rabbitmq_host, @config)
28
+ when "log4r_consumer"
29
+ consumers << RabbitHutch::Log4rConsumer.new(rabbitmq_host, @config)
30
+ end
31
+ end
32
+ #end
33
+ puts "\tdone"
34
+ consumers
35
+ end
36
+
37
+ # Start the worker process to listen to a RabbitMq Node
38
+ def start_worker(rabbitmq_host)
39
+ displayname = rabbitmq_host["displayname"]
40
+ hostname = rabbitmq_host["hostname"]
41
+ username = rabbitmq_host["username"]
42
+ password = rabbitmq_host["password"]
43
+
44
+ consumers = initialize_consumers(rabbitmq_host)
45
+
46
+ puts "Listening to RabbitMq #{displayname}, host: #{hostname}, username #{username}"
47
+ AMQP.connect(:host => hostname, :user => username, :password => password) do |connection|
48
+ channel = AMQP::Channel.new(connection)
49
+ worker = RabbitHutch::Worker.new(channel, @config, consumers)
50
+ worker.start
51
+ end
52
+ end
53
+
54
+ # Entry Point to the application, Begins queue listener and initializes all consmers
55
+ def start
56
+ begin
57
+ EventMachine.run do
58
+
59
+ @config.rabbitmq_hosts.each do |rabbitmq_host|
60
+ if rabbitmq_host["enabled"] == true
61
+ start_worker(rabbitmq_host)
62
+ end
63
+ end
64
+ Signal.trap("INT"){EventMachine.stop}
65
+ Signal.trap("QUIT"){EventMachine.stop}
66
+ Signal.trap("TERM"){EventMachine.stop}
67
+ Signal.trap("TSTP"){EventMachine.stop}
68
+ end
69
+ rescue Exception=>e
70
+ puts "#{e.message} #{e.backtrace}"
71
+ end
72
+ end
73
+
74
+ # Kick off the App
75
+ start
76
+
77
+
78
+
@@ -0,0 +1,48 @@
1
+ require 'thor'
2
+ require 'mustache'
3
+ require_relative 'configurator.rb'
4
+
5
+ module RabbitHutch
6
+ #This class controls the Command Line Interface
7
+ class CLI < Thor
8
+
9
+ StandardTemplate =<<-TEMPLATE
10
+ {{#config}}
11
+
12
+ {{#application}}
13
+ Application
14
+ +------------------------+------------------------+
15
+ |Exchange |Queue |
16
+ +------------------------+------------------------+
17
+ |{{exchangename}} | {{queuename}} |
18
+ +------------------------+------------------------+
19
+ {{/application}}
20
+
21
+ {{#rabbitmq}}
22
+ RabbitMq Servers
23
+ +------------------------+------------------------+
24
+ |Display Name |Host |
25
+ +------------------------+------------------------+
26
+ {{#hosts}}
27
+ |{{displayname}} | {{hostname}} |
28
+ +------------------------+------------------------+
29
+ {{/hosts}}
30
+ {{/rabbitmq}}
31
+
32
+ {{/config}}
33
+ TEMPLATE
34
+
35
+ desc "list", "List all config settings"
36
+ #method_option :errors, :aliases => "-e", :type => :boolean, :default => false, :desc => "true = display files that could not be processed, false = do not display skipped files"
37
+ #method_option :hashtype, :aliases => "-h", :default => "cmd5", :desc => "Choose the hash algorithm to use - md5 or sha"
38
+ method_option :config, :aliases => "-c", :default => nil, :desc => "parse the config file from a specified location "
39
+ #method_option :recursive, :aliases => "-r", :type => :boolean, :default => "false", :desc => "true = recurse through sub directories, false = only do top directory"
40
+ def list()
41
+ @config = RabbitHutch::Configurator.new(options)
42
+ puts Mustache.render(StandardTemplate, :config => @config);
43
+ end
44
+
45
+ end
46
+
47
+ CLI.start()
48
+ end
data/lib/worker.rb ADDED
@@ -0,0 +1,33 @@
1
+ require "rubygems"
2
+ require "amqp"
3
+ require_relative "configurator"
4
+ require_relative "consumer"
5
+
6
+ module RabbitHutch
7
+ @exchange_name = "amq.rabbitmq.trace"
8
+
9
+ class Worker
10
+
11
+ def initialize(channel, config, consumers)
12
+ @channel = channel
13
+ @channel.on_error(&method(:handle_channel_exception))
14
+ @consumer = Consumer.new(consumers)
15
+ @exchange_name = config.application['exchangename']
16
+ @queue_name = config.application['queuename']
17
+ end
18
+
19
+ # begin listening for all topics in publish.#
20
+ def start
21
+ @exchange = @channel.topic(@exchange_name, :durable => true, :auto_delete => false, :internal => true)
22
+ @queue = @channel.queue(@queue_name, :durable => true, :auto_delete => false)
23
+ @queue.bind(@exchange, :routing_key => 'publish.#')
24
+ @queue.subscribe(&@consumer.method(:handle_message))
25
+ end
26
+
27
+ def handle_channel_exception(channel, channel_close)
28
+ puts "Oops... a channel-level exception: code = #{channel_close.reply_code}, message = #{channel_close.reply_text}"
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('/lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = 'dafiti-rabbit-hutch'
7
+ gem.version = '0.1.4'
8
+ gem.licenses = ['MIT']
9
+ gem.summary = "Logger for rabbitMQ!"
10
+ gem.description = "Logger for rabbitMQ!"
11
+ gem.authors = ["Luiz Bartolomeu"]
12
+ gem.email = 'luizbart@gmail.com'
13
+ #gem.files = ["lib/example.rb"]
14
+ gem.homepage = 'https://rubygems.org/gems/example'
15
+ gem.metadata = { "source_code_uri" => "https://github.com/ext-luiz-filho/rabbit-hutch" }
16
+ gem.extra_rdoc_files = ["LICENSE.txt","README.md" ]
17
+ gem.files = `git ls-files`.split($/)
18
+ #gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ #gem.executable = ['rabbithutch', 'bin/rabbithutch']
20
+ gem.executables = ['rabbithutch', 'rabbithutchweb']
21
+ gem.require_paths = ["lib"]
22
+
23
+ gem.rdoc_options << '--exclude spec/testfiles'
24
+
25
+ gem.add_dependency "amqp"
26
+ gem.add_dependency "bson_ext"
27
+ gem.add_dependency "daemons"
28
+ gem.add_dependency "eventmachine"
29
+ gem.add_dependency "logger"
30
+ gem.add_dependency "log4r"
31
+ gem.add_dependency "mustache"
32
+ gem.add_dependency "mq"
33
+ gem.add_dependency "mongo"
34
+ gem.add_dependency "mongo_ext"
35
+ gem.add_dependency "thor"
36
+ gem.add_dependency "yard"
37
+
38
+ gem.add_dependency "haml"
39
+ gem.add_dependency "sinatra"
40
+ gem.add_dependency "thin"
41
+ gem.add_dependency "shotgun"
42
+
43
+ end
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'daemons'
3
+
4
+ # The Service controller.
5
+ def start_service
6
+ begin
7
+ puts "-------------------------"
8
+ puts "Starting RabbitHutch #1"
9
+ Daemons.run(File.dirname(__FILE__) + '/lib/rabbithutch.rb')
10
+ rescue SystemExit=>e
11
+ puts e.inspect
12
+ rescue Exception=>e
13
+ puts e.inspect
14
+ end
15
+ end
16
+
17
+ start_service()
18
+
@@ -0,0 +1,1092 @@
1
+ /*!
2
+ * Bootstrap Responsive v2.2.2
3
+ *
4
+ * Copyright 2012 Twitter, Inc
5
+ * Licensed under the Apache License v2.0
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
9
+ */
10
+
11
+ @-ms-viewport {
12
+ width: device-width;
13
+ }
14
+
15
+ .clearfix {
16
+ *zoom: 1;
17
+ }
18
+
19
+ .clearfix:before,
20
+ .clearfix:after {
21
+ display: table;
22
+ line-height: 0;
23
+ content: "";
24
+ }
25
+
26
+ .clearfix:after {
27
+ clear: both;
28
+ }
29
+
30
+ .hide-text {
31
+ font: 0/0 a;
32
+ color: transparent;
33
+ text-shadow: none;
34
+ background-color: transparent;
35
+ border: 0;
36
+ }
37
+
38
+ .input-block-level {
39
+ display: block;
40
+ width: 100%;
41
+ min-height: 30px;
42
+ -webkit-box-sizing: border-box;
43
+ -moz-box-sizing: border-box;
44
+ box-sizing: border-box;
45
+ }
46
+
47
+ .hidden {
48
+ display: none;
49
+ visibility: hidden;
50
+ }
51
+
52
+ .visible-phone {
53
+ display: none !important;
54
+ }
55
+
56
+ .visible-tablet {
57
+ display: none !important;
58
+ }
59
+
60
+ .hidden-desktop {
61
+ display: none !important;
62
+ }
63
+
64
+ .visible-desktop {
65
+ display: inherit !important;
66
+ }
67
+
68
+ @media (min-width: 768px) and (max-width: 979px) {
69
+ .hidden-desktop {
70
+ display: inherit !important;
71
+ }
72
+ .visible-desktop {
73
+ display: none !important ;
74
+ }
75
+ .visible-tablet {
76
+ display: inherit !important;
77
+ }
78
+ .hidden-tablet {
79
+ display: none !important;
80
+ }
81
+ }
82
+
83
+ @media (max-width: 767px) {
84
+ .hidden-desktop {
85
+ display: inherit !important;
86
+ }
87
+ .visible-desktop {
88
+ display: none !important;
89
+ }
90
+ .visible-phone {
91
+ display: inherit !important;
92
+ }
93
+ .hidden-phone {
94
+ display: none !important;
95
+ }
96
+ }
97
+
98
+ @media (min-width: 1200px) {
99
+ .row {
100
+ margin-left: -30px;
101
+ *zoom: 1;
102
+ }
103
+ .row:before,
104
+ .row:after {
105
+ display: table;
106
+ line-height: 0;
107
+ content: "";
108
+ }
109
+ .row:after {
110
+ clear: both;
111
+ }
112
+ [class*="span"] {
113
+ float: left;
114
+ min-height: 1px;
115
+ margin-left: 30px;
116
+ }
117
+ .container,
118
+ .navbar-static-top .container,
119
+ .navbar-fixed-top .container,
120
+ .navbar-fixed-bottom .container {
121
+ width: 1170px;
122
+ }
123
+ .span12 {
124
+ width: 1170px;
125
+ }
126
+ .span11 {
127
+ width: 1070px;
128
+ }
129
+ .span10 {
130
+ width: 970px;
131
+ }
132
+ .span9 {
133
+ width: 870px;
134
+ }
135
+ .span8 {
136
+ width: 770px;
137
+ }
138
+ .span7 {
139
+ width: 670px;
140
+ }
141
+ .span6 {
142
+ width: 570px;
143
+ }
144
+ .span5 {
145
+ width: 470px;
146
+ }
147
+ .span4 {
148
+ width: 370px;
149
+ }
150
+ .span3 {
151
+ width: 270px;
152
+ }
153
+ .span2 {
154
+ width: 170px;
155
+ }
156
+ .span1 {
157
+ width: 70px;
158
+ }
159
+ .offset12 {
160
+ margin-left: 1230px;
161
+ }
162
+ .offset11 {
163
+ margin-left: 1130px;
164
+ }
165
+ .offset10 {
166
+ margin-left: 1030px;
167
+ }
168
+ .offset9 {
169
+ margin-left: 930px;
170
+ }
171
+ .offset8 {
172
+ margin-left: 830px;
173
+ }
174
+ .offset7 {
175
+ margin-left: 730px;
176
+ }
177
+ .offset6 {
178
+ margin-left: 630px;
179
+ }
180
+ .offset5 {
181
+ margin-left: 530px;
182
+ }
183
+ .offset4 {
184
+ margin-left: 430px;
185
+ }
186
+ .offset3 {
187
+ margin-left: 330px;
188
+ }
189
+ .offset2 {
190
+ margin-left: 230px;
191
+ }
192
+ .offset1 {
193
+ margin-left: 130px;
194
+ }
195
+ .row-fluid {
196
+ width: 100%;
197
+ *zoom: 1;
198
+ }
199
+ .row-fluid:before,
200
+ .row-fluid:after {
201
+ display: table;
202
+ line-height: 0;
203
+ content: "";
204
+ }
205
+ .row-fluid:after {
206
+ clear: both;
207
+ }
208
+ .row-fluid [class*="span"] {
209
+ display: block;
210
+ float: left;
211
+ width: 100%;
212
+ min-height: 30px;
213
+ margin-left: 2.564102564102564%;
214
+ *margin-left: 2.5109110747408616%;
215
+ -webkit-box-sizing: border-box;
216
+ -moz-box-sizing: border-box;
217
+ box-sizing: border-box;
218
+ }
219
+ .row-fluid [class*="span"]:first-child {
220
+ margin-left: 0;
221
+ }
222
+ .row-fluid .controls-row [class*="span"] + [class*="span"] {
223
+ margin-left: 2.564102564102564%;
224
+ }
225
+ .row-fluid .span12 {
226
+ width: 100%;
227
+ *width: 99.94680851063829%;
228
+ }
229
+ .row-fluid .span11 {
230
+ width: 91.45299145299145%;
231
+ *width: 91.39979996362975%;
232
+ }
233
+ .row-fluid .span10 {
234
+ width: 82.90598290598291%;
235
+ *width: 82.8527914166212%;
236
+ }
237
+ .row-fluid .span9 {
238
+ width: 74.35897435897436%;
239
+ *width: 74.30578286961266%;
240
+ }
241
+ .row-fluid .span8 {
242
+ width: 65.81196581196582%;
243
+ *width: 65.75877432260411%;
244
+ }
245
+ .row-fluid .span7 {
246
+ width: 57.26495726495726%;
247
+ *width: 57.21176577559556%;
248
+ }
249
+ .row-fluid .span6 {
250
+ width: 48.717948717948715%;
251
+ *width: 48.664757228587014%;
252
+ }
253
+ .row-fluid .span5 {
254
+ width: 40.17094017094017%;
255
+ *width: 40.11774868157847%;
256
+ }
257
+ .row-fluid .span4 {
258
+ width: 31.623931623931625%;
259
+ *width: 31.570740134569924%;
260
+ }
261
+ .row-fluid .span3 {
262
+ width: 23.076923076923077%;
263
+ *width: 23.023731587561375%;
264
+ }
265
+ .row-fluid .span2 {
266
+ width: 14.52991452991453%;
267
+ *width: 14.476723040552828%;
268
+ }
269
+ .row-fluid .span1 {
270
+ width: 5.982905982905983%;
271
+ *width: 5.929714493544281%;
272
+ }
273
+ .row-fluid .offset12 {
274
+ margin-left: 105.12820512820512%;
275
+ *margin-left: 105.02182214948171%;
276
+ }
277
+ .row-fluid .offset12:first-child {
278
+ margin-left: 102.56410256410257%;
279
+ *margin-left: 102.45771958537915%;
280
+ }
281
+ .row-fluid .offset11 {
282
+ margin-left: 96.58119658119658%;
283
+ *margin-left: 96.47481360247316%;
284
+ }
285
+ .row-fluid .offset11:first-child {
286
+ margin-left: 94.01709401709402%;
287
+ *margin-left: 93.91071103837061%;
288
+ }
289
+ .row-fluid .offset10 {
290
+ margin-left: 88.03418803418803%;
291
+ *margin-left: 87.92780505546462%;
292
+ }
293
+ .row-fluid .offset10:first-child {
294
+ margin-left: 85.47008547008548%;
295
+ *margin-left: 85.36370249136206%;
296
+ }
297
+ .row-fluid .offset9 {
298
+ margin-left: 79.48717948717949%;
299
+ *margin-left: 79.38079650845607%;
300
+ }
301
+ .row-fluid .offset9:first-child {
302
+ margin-left: 76.92307692307693%;
303
+ *margin-left: 76.81669394435352%;
304
+ }
305
+ .row-fluid .offset8 {
306
+ margin-left: 70.94017094017094%;
307
+ *margin-left: 70.83378796144753%;
308
+ }
309
+ .row-fluid .offset8:first-child {
310
+ margin-left: 68.37606837606839%;
311
+ *margin-left: 68.26968539734497%;
312
+ }
313
+ .row-fluid .offset7 {
314
+ margin-left: 62.393162393162385%;
315
+ *margin-left: 62.28677941443899%;
316
+ }
317
+ .row-fluid .offset7:first-child {
318
+ margin-left: 59.82905982905982%;
319
+ *margin-left: 59.72267685033642%;
320
+ }
321
+ .row-fluid .offset6 {
322
+ margin-left: 53.84615384615384%;
323
+ *margin-left: 53.739770867430444%;
324
+ }
325
+ .row-fluid .offset6:first-child {
326
+ margin-left: 51.28205128205128%;
327
+ *margin-left: 51.175668303327875%;
328
+ }
329
+ .row-fluid .offset5 {
330
+ margin-left: 45.299145299145295%;
331
+ *margin-left: 45.1927623204219%;
332
+ }
333
+ .row-fluid .offset5:first-child {
334
+ margin-left: 42.73504273504273%;
335
+ *margin-left: 42.62865975631933%;
336
+ }
337
+ .row-fluid .offset4 {
338
+ margin-left: 36.75213675213675%;
339
+ *margin-left: 36.645753773413354%;
340
+ }
341
+ .row-fluid .offset4:first-child {
342
+ margin-left: 34.18803418803419%;
343
+ *margin-left: 34.081651209310785%;
344
+ }
345
+ .row-fluid .offset3 {
346
+ margin-left: 28.205128205128204%;
347
+ *margin-left: 28.0987452264048%;
348
+ }
349
+ .row-fluid .offset3:first-child {
350
+ margin-left: 25.641025641025642%;
351
+ *margin-left: 25.53464266230224%;
352
+ }
353
+ .row-fluid .offset2 {
354
+ margin-left: 19.65811965811966%;
355
+ *margin-left: 19.551736679396257%;
356
+ }
357
+ .row-fluid .offset2:first-child {
358
+ margin-left: 17.094017094017094%;
359
+ *margin-left: 16.98763411529369%;
360
+ }
361
+ .row-fluid .offset1 {
362
+ margin-left: 11.11111111111111%;
363
+ *margin-left: 11.004728132387708%;
364
+ }
365
+ .row-fluid .offset1:first-child {
366
+ margin-left: 8.547008547008547%;
367
+ *margin-left: 8.440625568285142%;
368
+ }
369
+ input,
370
+ textarea,
371
+ .uneditable-input {
372
+ margin-left: 0;
373
+ }
374
+ .controls-row [class*="span"] + [class*="span"] {
375
+ margin-left: 30px;
376
+ }
377
+ input.span12,
378
+ textarea.span12,
379
+ .uneditable-input.span12 {
380
+ width: 1156px;
381
+ }
382
+ input.span11,
383
+ textarea.span11,
384
+ .uneditable-input.span11 {
385
+ width: 1056px;
386
+ }
387
+ input.span10,
388
+ textarea.span10,
389
+ .uneditable-input.span10 {
390
+ width: 956px;
391
+ }
392
+ input.span9,
393
+ textarea.span9,
394
+ .uneditable-input.span9 {
395
+ width: 856px;
396
+ }
397
+ input.span8,
398
+ textarea.span8,
399
+ .uneditable-input.span8 {
400
+ width: 756px;
401
+ }
402
+ input.span7,
403
+ textarea.span7,
404
+ .uneditable-input.span7 {
405
+ width: 656px;
406
+ }
407
+ input.span6,
408
+ textarea.span6,
409
+ .uneditable-input.span6 {
410
+ width: 556px;
411
+ }
412
+ input.span5,
413
+ textarea.span5,
414
+ .uneditable-input.span5 {
415
+ width: 456px;
416
+ }
417
+ input.span4,
418
+ textarea.span4,
419
+ .uneditable-input.span4 {
420
+ width: 356px;
421
+ }
422
+ input.span3,
423
+ textarea.span3,
424
+ .uneditable-input.span3 {
425
+ width: 256px;
426
+ }
427
+ input.span2,
428
+ textarea.span2,
429
+ .uneditable-input.span2 {
430
+ width: 156px;
431
+ }
432
+ input.span1,
433
+ textarea.span1,
434
+ .uneditable-input.span1 {
435
+ width: 56px;
436
+ }
437
+ .thumbnails {
438
+ margin-left: -30px;
439
+ }
440
+ .thumbnails > li {
441
+ margin-left: 30px;
442
+ }
443
+ .row-fluid .thumbnails {
444
+ margin-left: 0;
445
+ }
446
+ }
447
+
448
+ @media (min-width: 768px) and (max-width: 979px) {
449
+ .row {
450
+ margin-left: -20px;
451
+ *zoom: 1;
452
+ }
453
+ .row:before,
454
+ .row:after {
455
+ display: table;
456
+ line-height: 0;
457
+ content: "";
458
+ }
459
+ .row:after {
460
+ clear: both;
461
+ }
462
+ [class*="span"] {
463
+ float: left;
464
+ min-height: 1px;
465
+ margin-left: 20px;
466
+ }
467
+ .container,
468
+ .navbar-static-top .container,
469
+ .navbar-fixed-top .container,
470
+ .navbar-fixed-bottom .container {
471
+ width: 724px;
472
+ }
473
+ .span12 {
474
+ width: 724px;
475
+ }
476
+ .span11 {
477
+ width: 662px;
478
+ }
479
+ .span10 {
480
+ width: 600px;
481
+ }
482
+ .span9 {
483
+ width: 538px;
484
+ }
485
+ .span8 {
486
+ width: 476px;
487
+ }
488
+ .span7 {
489
+ width: 414px;
490
+ }
491
+ .span6 {
492
+ width: 352px;
493
+ }
494
+ .span5 {
495
+ width: 290px;
496
+ }
497
+ .span4 {
498
+ width: 228px;
499
+ }
500
+ .span3 {
501
+ width: 166px;
502
+ }
503
+ .span2 {
504
+ width: 104px;
505
+ }
506
+ .span1 {
507
+ width: 42px;
508
+ }
509
+ .offset12 {
510
+ margin-left: 764px;
511
+ }
512
+ .offset11 {
513
+ margin-left: 702px;
514
+ }
515
+ .offset10 {
516
+ margin-left: 640px;
517
+ }
518
+ .offset9 {
519
+ margin-left: 578px;
520
+ }
521
+ .offset8 {
522
+ margin-left: 516px;
523
+ }
524
+ .offset7 {
525
+ margin-left: 454px;
526
+ }
527
+ .offset6 {
528
+ margin-left: 392px;
529
+ }
530
+ .offset5 {
531
+ margin-left: 330px;
532
+ }
533
+ .offset4 {
534
+ margin-left: 268px;
535
+ }
536
+ .offset3 {
537
+ margin-left: 206px;
538
+ }
539
+ .offset2 {
540
+ margin-left: 144px;
541
+ }
542
+ .offset1 {
543
+ margin-left: 82px;
544
+ }
545
+ .row-fluid {
546
+ width: 100%;
547
+ *zoom: 1;
548
+ }
549
+ .row-fluid:before,
550
+ .row-fluid:after {
551
+ display: table;
552
+ line-height: 0;
553
+ content: "";
554
+ }
555
+ .row-fluid:after {
556
+ clear: both;
557
+ }
558
+ .row-fluid [class*="span"] {
559
+ display: block;
560
+ float: left;
561
+ width: 100%;
562
+ min-height: 30px;
563
+ margin-left: 2.7624309392265194%;
564
+ *margin-left: 2.709239449864817%;
565
+ -webkit-box-sizing: border-box;
566
+ -moz-box-sizing: border-box;
567
+ box-sizing: border-box;
568
+ }
569
+ .row-fluid [class*="span"]:first-child {
570
+ margin-left: 0;
571
+ }
572
+ .row-fluid .controls-row [class*="span"] + [class*="span"] {
573
+ margin-left: 2.7624309392265194%;
574
+ }
575
+ .row-fluid .span12 {
576
+ width: 100%;
577
+ *width: 99.94680851063829%;
578
+ }
579
+ .row-fluid .span11 {
580
+ width: 91.43646408839778%;
581
+ *width: 91.38327259903608%;
582
+ }
583
+ .row-fluid .span10 {
584
+ width: 82.87292817679558%;
585
+ *width: 82.81973668743387%;
586
+ }
587
+ .row-fluid .span9 {
588
+ width: 74.30939226519337%;
589
+ *width: 74.25620077583166%;
590
+ }
591
+ .row-fluid .span8 {
592
+ width: 65.74585635359117%;
593
+ *width: 65.69266486422946%;
594
+ }
595
+ .row-fluid .span7 {
596
+ width: 57.18232044198895%;
597
+ *width: 57.12912895262725%;
598
+ }
599
+ .row-fluid .span6 {
600
+ width: 48.61878453038674%;
601
+ *width: 48.56559304102504%;
602
+ }
603
+ .row-fluid .span5 {
604
+ width: 40.05524861878453%;
605
+ *width: 40.00205712942283%;
606
+ }
607
+ .row-fluid .span4 {
608
+ width: 31.491712707182323%;
609
+ *width: 31.43852121782062%;
610
+ }
611
+ .row-fluid .span3 {
612
+ width: 22.92817679558011%;
613
+ *width: 22.87498530621841%;
614
+ }
615
+ .row-fluid .span2 {
616
+ width: 14.3646408839779%;
617
+ *width: 14.311449394616199%;
618
+ }
619
+ .row-fluid .span1 {
620
+ width: 5.801104972375691%;
621
+ *width: 5.747913483013988%;
622
+ }
623
+ .row-fluid .offset12 {
624
+ margin-left: 105.52486187845304%;
625
+ *margin-left: 105.41847889972962%;
626
+ }
627
+ .row-fluid .offset12:first-child {
628
+ margin-left: 102.76243093922652%;
629
+ *margin-left: 102.6560479605031%;
630
+ }
631
+ .row-fluid .offset11 {
632
+ margin-left: 96.96132596685082%;
633
+ *margin-left: 96.8549429881274%;
634
+ }
635
+ .row-fluid .offset11:first-child {
636
+ margin-left: 94.1988950276243%;
637
+ *margin-left: 94.09251204890089%;
638
+ }
639
+ .row-fluid .offset10 {
640
+ margin-left: 88.39779005524862%;
641
+ *margin-left: 88.2914070765252%;
642
+ }
643
+ .row-fluid .offset10:first-child {
644
+ margin-left: 85.6353591160221%;
645
+ *margin-left: 85.52897613729868%;
646
+ }
647
+ .row-fluid .offset9 {
648
+ margin-left: 79.8342541436464%;
649
+ *margin-left: 79.72787116492299%;
650
+ }
651
+ .row-fluid .offset9:first-child {
652
+ margin-left: 77.07182320441989%;
653
+ *margin-left: 76.96544022569647%;
654
+ }
655
+ .row-fluid .offset8 {
656
+ margin-left: 71.2707182320442%;
657
+ *margin-left: 71.16433525332079%;
658
+ }
659
+ .row-fluid .offset8:first-child {
660
+ margin-left: 68.50828729281768%;
661
+ *margin-left: 68.40190431409427%;
662
+ }
663
+ .row-fluid .offset7 {
664
+ margin-left: 62.70718232044199%;
665
+ *margin-left: 62.600799341718584%;
666
+ }
667
+ .row-fluid .offset7:first-child {
668
+ margin-left: 59.94475138121547%;
669
+ *margin-left: 59.838368402492065%;
670
+ }
671
+ .row-fluid .offset6 {
672
+ margin-left: 54.14364640883978%;
673
+ *margin-left: 54.037263430116376%;
674
+ }
675
+ .row-fluid .offset6:first-child {
676
+ margin-left: 51.38121546961326%;
677
+ *margin-left: 51.27483249088986%;
678
+ }
679
+ .row-fluid .offset5 {
680
+ margin-left: 45.58011049723757%;
681
+ *margin-left: 45.47372751851417%;
682
+ }
683
+ .row-fluid .offset5:first-child {
684
+ margin-left: 42.81767955801105%;
685
+ *margin-left: 42.71129657928765%;
686
+ }
687
+ .row-fluid .offset4 {
688
+ margin-left: 37.01657458563536%;
689
+ *margin-left: 36.91019160691196%;
690
+ }
691
+ .row-fluid .offset4:first-child {
692
+ margin-left: 34.25414364640884%;
693
+ *margin-left: 34.14776066768544%;
694
+ }
695
+ .row-fluid .offset3 {
696
+ margin-left: 28.45303867403315%;
697
+ *margin-left: 28.346655695309746%;
698
+ }
699
+ .row-fluid .offset3:first-child {
700
+ margin-left: 25.69060773480663%;
701
+ *margin-left: 25.584224756083227%;
702
+ }
703
+ .row-fluid .offset2 {
704
+ margin-left: 19.88950276243094%;
705
+ *margin-left: 19.783119783707537%;
706
+ }
707
+ .row-fluid .offset2:first-child {
708
+ margin-left: 17.12707182320442%;
709
+ *margin-left: 17.02068884448102%;
710
+ }
711
+ .row-fluid .offset1 {
712
+ margin-left: 11.32596685082873%;
713
+ *margin-left: 11.219583872105325%;
714
+ }
715
+ .row-fluid .offset1:first-child {
716
+ margin-left: 8.56353591160221%;
717
+ *margin-left: 8.457152932878806%;
718
+ }
719
+ input,
720
+ textarea,
721
+ .uneditable-input {
722
+ margin-left: 0;
723
+ }
724
+ .controls-row [class*="span"] + [class*="span"] {
725
+ margin-left: 20px;
726
+ }
727
+ input.span12,
728
+ textarea.span12,
729
+ .uneditable-input.span12 {
730
+ width: 710px;
731
+ }
732
+ input.span11,
733
+ textarea.span11,
734
+ .uneditable-input.span11 {
735
+ width: 648px;
736
+ }
737
+ input.span10,
738
+ textarea.span10,
739
+ .uneditable-input.span10 {
740
+ width: 586px;
741
+ }
742
+ input.span9,
743
+ textarea.span9,
744
+ .uneditable-input.span9 {
745
+ width: 524px;
746
+ }
747
+ input.span8,
748
+ textarea.span8,
749
+ .uneditable-input.span8 {
750
+ width: 462px;
751
+ }
752
+ input.span7,
753
+ textarea.span7,
754
+ .uneditable-input.span7 {
755
+ width: 400px;
756
+ }
757
+ input.span6,
758
+ textarea.span6,
759
+ .uneditable-input.span6 {
760
+ width: 338px;
761
+ }
762
+ input.span5,
763
+ textarea.span5,
764
+ .uneditable-input.span5 {
765
+ width: 276px;
766
+ }
767
+ input.span4,
768
+ textarea.span4,
769
+ .uneditable-input.span4 {
770
+ width: 214px;
771
+ }
772
+ input.span3,
773
+ textarea.span3,
774
+ .uneditable-input.span3 {
775
+ width: 152px;
776
+ }
777
+ input.span2,
778
+ textarea.span2,
779
+ .uneditable-input.span2 {
780
+ width: 90px;
781
+ }
782
+ input.span1,
783
+ textarea.span1,
784
+ .uneditable-input.span1 {
785
+ width: 28px;
786
+ }
787
+ }
788
+
789
+ @media (max-width: 767px) {
790
+ body {
791
+ padding-right: 20px;
792
+ padding-left: 20px;
793
+ }
794
+ .navbar-fixed-top,
795
+ .navbar-fixed-bottom,
796
+ .navbar-static-top {
797
+ margin-right: -20px;
798
+ margin-left: -20px;
799
+ }
800
+ .container-fluid {
801
+ padding: 0;
802
+ }
803
+ .dl-horizontal dt {
804
+ float: none;
805
+ width: auto;
806
+ clear: none;
807
+ text-align: left;
808
+ }
809
+ .dl-horizontal dd {
810
+ margin-left: 0;
811
+ }
812
+ .container {
813
+ width: auto;
814
+ }
815
+ .row-fluid {
816
+ width: 100%;
817
+ }
818
+ .row,
819
+ .thumbnails {
820
+ margin-left: 0;
821
+ }
822
+ .thumbnails > li {
823
+ float: none;
824
+ margin-left: 0;
825
+ }
826
+ [class*="span"],
827
+ .uneditable-input[class*="span"],
828
+ .row-fluid [class*="span"] {
829
+ display: block;
830
+ float: none;
831
+ width: 100%;
832
+ margin-left: 0;
833
+ -webkit-box-sizing: border-box;
834
+ -moz-box-sizing: border-box;
835
+ box-sizing: border-box;
836
+ }
837
+ .span12,
838
+ .row-fluid .span12 {
839
+ width: 100%;
840
+ -webkit-box-sizing: border-box;
841
+ -moz-box-sizing: border-box;
842
+ box-sizing: border-box;
843
+ }
844
+ .row-fluid [class*="offset"]:first-child {
845
+ margin-left: 0;
846
+ }
847
+ .input-large,
848
+ .input-xlarge,
849
+ .input-xxlarge,
850
+ input[class*="span"],
851
+ select[class*="span"],
852
+ textarea[class*="span"],
853
+ .uneditable-input {
854
+ display: block;
855
+ width: 100%;
856
+ min-height: 30px;
857
+ -webkit-box-sizing: border-box;
858
+ -moz-box-sizing: border-box;
859
+ box-sizing: border-box;
860
+ }
861
+ .input-prepend input,
862
+ .input-append input,
863
+ .input-prepend input[class*="span"],
864
+ .input-append input[class*="span"] {
865
+ display: inline-block;
866
+ width: auto;
867
+ }
868
+ .controls-row [class*="span"] + [class*="span"] {
869
+ margin-left: 0;
870
+ }
871
+ .modal {
872
+ position: fixed;
873
+ top: 20px;
874
+ right: 20px;
875
+ left: 20px;
876
+ width: auto;
877
+ margin: 0;
878
+ }
879
+ .modal.fade {
880
+ top: -100px;
881
+ }
882
+ .modal.fade.in {
883
+ top: 20px;
884
+ }
885
+ }
886
+
887
+ @media (max-width: 480px) {
888
+ .nav-collapse {
889
+ -webkit-transform: translate3d(0, 0, 0);
890
+ }
891
+ .page-header h1 small {
892
+ display: block;
893
+ line-height: 20px;
894
+ }
895
+ input[type="checkbox"],
896
+ input[type="radio"] {
897
+ border: 1px solid #ccc;
898
+ }
899
+ .form-horizontal .control-label {
900
+ float: none;
901
+ width: auto;
902
+ padding-top: 0;
903
+ text-align: left;
904
+ }
905
+ .form-horizontal .controls {
906
+ margin-left: 0;
907
+ }
908
+ .form-horizontal .control-list {
909
+ padding-top: 0;
910
+ }
911
+ .form-horizontal .form-actions {
912
+ padding-right: 10px;
913
+ padding-left: 10px;
914
+ }
915
+ .media .pull-left,
916
+ .media .pull-right {
917
+ display: block;
918
+ float: none;
919
+ margin-bottom: 10px;
920
+ }
921
+ .media-object {
922
+ margin-right: 0;
923
+ margin-left: 0;
924
+ }
925
+ .modal {
926
+ top: 10px;
927
+ right: 10px;
928
+ left: 10px;
929
+ }
930
+ .modal-header .close {
931
+ padding: 10px;
932
+ margin: -10px;
933
+ }
934
+ .carousel-caption {
935
+ position: static;
936
+ }
937
+ }
938
+
939
+ @media (max-width: 979px) {
940
+ body {
941
+ padding-top: 0;
942
+ }
943
+ .navbar-fixed-top,
944
+ .navbar-fixed-bottom {
945
+ position: static;
946
+ }
947
+ .navbar-fixed-top {
948
+ margin-bottom: 20px;
949
+ }
950
+ .navbar-fixed-bottom {
951
+ margin-top: 20px;
952
+ }
953
+ .navbar-fixed-top .navbar-inner,
954
+ .navbar-fixed-bottom .navbar-inner {
955
+ padding: 5px;
956
+ }
957
+ .navbar .container {
958
+ width: auto;
959
+ padding: 0;
960
+ }
961
+ .navbar .brand {
962
+ padding-right: 10px;
963
+ padding-left: 10px;
964
+ margin: 0 0 0 -5px;
965
+ }
966
+ .nav-collapse {
967
+ clear: both;
968
+ }
969
+ .nav-collapse .nav {
970
+ float: none;
971
+ margin: 0 0 10px;
972
+ }
973
+ .nav-collapse .nav > li {
974
+ float: none;
975
+ }
976
+ .nav-collapse .nav > li > a {
977
+ margin-bottom: 2px;
978
+ }
979
+ .nav-collapse .nav > .divider-vertical {
980
+ display: none;
981
+ }
982
+ .nav-collapse .nav .nav-header {
983
+ color: #777777;
984
+ text-shadow: none;
985
+ }
986
+ .nav-collapse .nav > li > a,
987
+ .nav-collapse .dropdown-menu a {
988
+ padding: 9px 15px;
989
+ font-weight: bold;
990
+ color: #777777;
991
+ -webkit-border-radius: 3px;
992
+ -moz-border-radius: 3px;
993
+ border-radius: 3px;
994
+ }
995
+ .nav-collapse .btn {
996
+ padding: 4px 10px 4px;
997
+ font-weight: normal;
998
+ -webkit-border-radius: 4px;
999
+ -moz-border-radius: 4px;
1000
+ border-radius: 4px;
1001
+ }
1002
+ .nav-collapse .dropdown-menu li + li a {
1003
+ margin-bottom: 2px;
1004
+ }
1005
+ .nav-collapse .nav > li > a:hover,
1006
+ .nav-collapse .dropdown-menu a:hover {
1007
+ background-color: #f2f2f2;
1008
+ }
1009
+ .navbar-inverse .nav-collapse .nav > li > a,
1010
+ .navbar-inverse .nav-collapse .dropdown-menu a {
1011
+ color: #999999;
1012
+ }
1013
+ .navbar-inverse .nav-collapse .nav > li > a:hover,
1014
+ .navbar-inverse .nav-collapse .dropdown-menu a:hover {
1015
+ background-color: #111111;
1016
+ }
1017
+ .nav-collapse.in .btn-group {
1018
+ padding: 0;
1019
+ margin-top: 5px;
1020
+ }
1021
+ .nav-collapse .dropdown-menu {
1022
+ position: static;
1023
+ top: auto;
1024
+ left: auto;
1025
+ display: none;
1026
+ float: none;
1027
+ max-width: none;
1028
+ padding: 0;
1029
+ margin: 0 15px;
1030
+ background-color: transparent;
1031
+ border: none;
1032
+ -webkit-border-radius: 0;
1033
+ -moz-border-radius: 0;
1034
+ border-radius: 0;
1035
+ -webkit-box-shadow: none;
1036
+ -moz-box-shadow: none;
1037
+ box-shadow: none;
1038
+ }
1039
+ .nav-collapse .open > .dropdown-menu {
1040
+ display: block;
1041
+ }
1042
+ .nav-collapse .dropdown-menu:before,
1043
+ .nav-collapse .dropdown-menu:after {
1044
+ display: none;
1045
+ }
1046
+ .nav-collapse .dropdown-menu .divider {
1047
+ display: none;
1048
+ }
1049
+ .nav-collapse .nav > li > .dropdown-menu:before,
1050
+ .nav-collapse .nav > li > .dropdown-menu:after {
1051
+ display: none;
1052
+ }
1053
+ .nav-collapse .navbar-form,
1054
+ .nav-collapse .navbar-search {
1055
+ float: none;
1056
+ padding: 10px 15px;
1057
+ margin: 10px 0;
1058
+ border-top: 1px solid #f2f2f2;
1059
+ border-bottom: 1px solid #f2f2f2;
1060
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
1061
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
1062
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
1063
+ }
1064
+ .navbar-inverse .nav-collapse .navbar-form,
1065
+ .navbar-inverse .nav-collapse .navbar-search {
1066
+ border-top-color: #111111;
1067
+ border-bottom-color: #111111;
1068
+ }
1069
+ .navbar .nav-collapse .nav.pull-right {
1070
+ float: none;
1071
+ margin-left: 0;
1072
+ }
1073
+ .nav-collapse,
1074
+ .nav-collapse.collapse {
1075
+ height: 0;
1076
+ overflow: hidden;
1077
+ }
1078
+ .navbar .btn-navbar {
1079
+ display: block;
1080
+ }
1081
+ .navbar-static .navbar-inner {
1082
+ padding-right: 10px;
1083
+ padding-left: 10px;
1084
+ }
1085
+ }
1086
+
1087
+ @media (min-width: 980px) {
1088
+ .nav-collapse.collapse {
1089
+ height: auto !important;
1090
+ overflow: visible !important;
1091
+ }
1092
+ }