dcell 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.travis.yml +4 -1
  2. data/CHANGES.md +11 -0
  3. data/Gemfile +6 -3
  4. data/LICENSE.txt +1 -1
  5. data/README.md +27 -243
  6. data/benchmarks/receiver.rb +2 -2
  7. data/dcell.gemspec +7 -7
  8. data/explorer/css/bootstrap-responsive.css +686 -0
  9. data/explorer/css/bootstrap-responsive.min.css +12 -0
  10. data/explorer/css/bootstrap.css +3990 -0
  11. data/explorer/css/bootstrap.min.css +689 -0
  12. data/explorer/css/explorer.css +28 -0
  13. data/explorer/ico/favicon.ico +0 -0
  14. data/explorer/img/glyphicons-halflings-white.png +0 -0
  15. data/explorer/img/glyphicons-halflings.png +0 -0
  16. data/explorer/img/logo.png +0 -0
  17. data/explorer/index.html.erb +94 -0
  18. data/explorer/js/bootstrap.js +1726 -0
  19. data/explorer/js/bootstrap.min.js +6 -0
  20. data/lib/dcell.rb +27 -2
  21. data/lib/dcell/celluloid_ext.rb +14 -3
  22. data/lib/dcell/directory.rb +15 -3
  23. data/lib/dcell/explorer.rb +76 -0
  24. data/lib/dcell/future_proxy.rb +32 -0
  25. data/lib/dcell/info_service.rb +117 -0
  26. data/lib/dcell/mailbox_proxy.rb +6 -7
  27. data/lib/dcell/messages.rb +5 -6
  28. data/lib/dcell/node.rb +25 -55
  29. data/lib/dcell/node_manager.rb +81 -0
  30. data/lib/dcell/registries/cassandra_adapter.rb +86 -0
  31. data/lib/dcell/registries/gossip/core.rb +235 -0
  32. data/lib/dcell/registries/gossip_adapter.rb +26 -0
  33. data/lib/dcell/registries/moneta_adapter.rb +0 -7
  34. data/lib/dcell/registries/redis_adapter.rb +0 -31
  35. data/lib/dcell/registries/zk_adapter.rb +1 -39
  36. data/lib/dcell/router.rb +37 -30
  37. data/lib/dcell/rpc.rb +23 -23
  38. data/lib/dcell/server.rb +5 -2
  39. data/lib/dcell/version.rb +1 -1
  40. data/logo.png +0 -0
  41. data/spec/dcell/actor_proxy_spec.rb +4 -0
  42. data/spec/dcell/celluloid_ext_spec.rb +11 -0
  43. data/spec/dcell/directory_spec.rb +1 -1
  44. data/spec/dcell/explorer_spec.rb +17 -0
  45. data/spec/dcell/global_spec.rb +4 -0
  46. data/spec/dcell/registries/gossip_adapter_spec.rb +6 -0
  47. data/spec/spec_helper.rb +14 -7
  48. data/spec/support/registry_examples.rb +0 -18
  49. data/tasks/cassandra.task +84 -0
  50. metadata +55 -35
  51. data/celluloid-zmq/.gitignore +0 -17
  52. data/celluloid-zmq/.rspec +0 -4
  53. data/celluloid-zmq/CHANGES.md +0 -31
  54. data/celluloid-zmq/Gemfile +0 -7
  55. data/celluloid-zmq/README.md +0 -56
  56. data/celluloid-zmq/Rakefile +0 -7
  57. data/celluloid-zmq/celluloid-zmq.gemspec +0 -28
  58. data/celluloid-zmq/lib/celluloid/zmq.rb +0 -36
  59. data/celluloid-zmq/lib/celluloid/zmq/reactor.rb +0 -90
  60. data/celluloid-zmq/lib/celluloid/zmq/sockets.rb +0 -130
  61. data/celluloid-zmq/lib/celluloid/zmq/version.rb +0 -5
  62. data/celluloid-zmq/lib/celluloid/zmq/waker.rb +0 -55
  63. data/celluloid-zmq/spec/celluloid/zmq/actor_spec.rb +0 -6
  64. data/celluloid-zmq/spec/spec_helper.rb +0 -2
@@ -5,6 +5,9 @@ rvm:
5
5
  - jruby-19mode
6
6
  - jruby-head
7
7
 
8
- # Rubies I would like to support, but they deadlock
8
+ # https://github.com/rubinius/rubinius/issues/1628
9
9
  # - rbx-18mode
10
10
  # - rbx-19mode
11
+
12
+ notifications:
13
+ irc: "irc.freenode.org#celluloid"
data/CHANGES.md CHANGED
@@ -1,3 +1,14 @@
1
+ 0.10.0
2
+ ------
3
+ * DCell::Explorer provides a web UI with Reel
4
+ * Info service at DCell::Node#[:info]
5
+ * Distributed gossip protocol, now default adapter
6
+ * Support for marshaling Celluloid::Futures
7
+ * Cassandra registry
8
+ * Initial DCell::NodeManager
9
+ * celluloid-zmq split out into a separate gem
10
+ * Use Celluloid.uuid for mailbox and call IDs
11
+
1
12
  0.9.0
2
13
  -----
3
14
  * Use new Celluloid::ZMQ APIs
data/Gemfile CHANGED
@@ -1,8 +1,11 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem 'celluloid', :git => 'git://github.com/tarcieri/celluloid'
4
- gem 'celluloid-io', :git => 'git://github.com/tarcieri/celluloid-io'
5
- gem 'celluloid-zmq', :path => 'celluloid-zmq'
3
+ gem 'celluloid', :git => 'git://github.com/celluloid/celluloid'
4
+ gem 'celluloid-io', :git => 'git://github.com/celluloid/celluloid-io'
5
+ gem 'celluloid-zmq', :git => 'git://github.com/celluloid/celluloid-zmq'
6
+ #gem 'reel', :git => 'git://github.com/celluloid/reel'
7
+
8
+ gem 'jruby-openssl', :platform => :jruby
6
9
 
7
10
  # Specify your gem's dependencies in dcell.gemspec
8
11
  gemspec
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Tony Arcieri
1
+ Copyright (c) 2012 Tony Arcieri
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
- ![DCell](https://github.com/tarcieri/dcell/raw/master/logo.png)
1
+ ![DCell](https://github.com/celluloid/dcell/raw/master/logo.png)
2
2
  =====
3
- [![Build Status](http://travis-ci.org/tarcieri/dcell.png)](http://travis-ci.org/tarcieri/dcell)
3
+ [![Build Status](http://travis-ci.org/celluloid/dcell.png)](http://travis-ci.org/celluloid/dcell)
4
+ [![Dependency Status](https://gemnasium.com/celluloid/dcell.png)](https://gemnasium.com/celluloid/dcell)
4
5
 
5
6
  > "Objects can message objects transparently that live on other machines
6
7
  > over the network, and you don't have to worry about the networking gunk,
@@ -17,15 +18,28 @@ and register several available services on a given node, obtain handles to
17
18
  them, and easily pass these handles around the network just like any other
18
19
  objects.
19
20
 
20
- DCell is a distributed extension to Celluloid, which provides concurrent
21
- objects for Ruby with many of the features of Erlang, such as the ability
22
- to supervise objects and restart them when they crash, and also link to
21
+ DCell is a distributed extension to [Celluloid][celluloid], which provides
22
+ concurrent objects for Ruby with many of the features of Erlang, such as the
23
+ ability to supervise objects and restart them when they crash, and also link to
23
24
  other objects and receive event notifications of when they crash. This makes
24
25
  it easier to build robust, fault-tolerant distributed systems.
25
26
 
26
- You can read more about Celluloid at: http://celluloid.github.com
27
+ DCell uses the [0MQ][zeromq] messaging protocol which provides a robust,
28
+ fault-tolerant brokerless transport for asynchronous messages sent between
29
+ nodes. DCell is built on top of the [Celluloid::ZMQ][celluloid-zmq] library,
30
+ which provides a Celluloid-oriented wrapper around the underlying
31
+ [ffi-rzmq][ffi-rzmq] library.
27
32
 
28
- Like DCell? [Join the Celluloid Google Group](http://groups.google.com/group/celluloid-ruby)
33
+ [Please see the DCell Wiki](https://github.com/celluloid/dcell/wiki)
34
+ for more detailed documentation and usage notes.
35
+
36
+ Like DCell? [Join the Celluloid Google Group][googlegroup]
37
+
38
+ [celluloid]: http://celluloid.io/
39
+ [zeromq]: http://www.zeromq.org/
40
+ [celluloid-zmq]: https://github.com/celluloid/celluloid-zmq
41
+ [ffi-rzmq]: https://github.com/chuckremes/ffi-rzmq
42
+ [googlegroup]: http://groups.google.com/group/celluloid-ruby
29
43
 
30
44
  ### Is It Good?
31
45
 
@@ -38,245 +52,15 @@ Not entirely, but eager early adopters are welcome!
38
52
  Supported Platforms
39
53
  -------------------
40
54
 
41
- DCell works on Ruby 1.9.2/1.9.3, JRuby 1.6 (in 1.9 mode), JRuby 1.7, and Rubinius 2.0.
42
-
43
- To use JRuby 1.6 in 1.9 mode, you'll need to pass the "--1.9" command line
44
- option to the JRuby executable, or set the "JRUBY_OPTS=--1.9" environment
45
- variable:
46
-
47
- export JRUBY_OPTS=--1.9
48
-
49
- (Note: I'd recommend putting the above in your .bashrc/.zshrc/etc in
50
- general. 1.9 is the future, time to embrace it)
51
-
52
- To use JRuby 1.7 in 1.9 mode...just use it :)
53
-
54
- Celluloid works on Rubinius in either 1.8 or 1.9 mode.
55
-
56
- All components, including the 0MQ bindings, Redis, and Zookeeper adapters
57
- are all certified to work on the above platforms. The 0MQ binding is FFI.
58
- The Redis adapter is pure Ruby. The Zookeeper adapter uses an MRI-style
59
- native extension but also supplies a pure-Java backend for JRuby.
60
-
61
- Prerequisites
62
- -------------
63
-
64
- DCell requires 0MQ. On OS X, this is available through Homebrew by running:
65
-
66
- brew install zeromq
67
-
68
- DCell keeps the state of all connected nodes and global configuration data
69
- in a service it calls the "registry". There are presently two supported
70
- registry services:
71
-
72
- * Redis (Fast and Loose): Redis is a persistent data structures server.
73
- It's simple and easy to use for development and prototyping, but lacks a
74
- good distribution story.
75
-
76
- * Zookeeper (Serious Business): Zookeeper is a high-performance coordination
77
- service for distributed applications. It exposes common services such as
78
- naming, configuration management, synchronization, and group management.
79
- Unfortunately, it has slightly more annoying client-side dependencies and is
80
- more difficult to deploy than Redis.
81
-
82
- You may pick either one of these services to use as DCell's registry. The
83
- default is Redis.
84
-
85
- To install a local copy of Redis on OS X with Homebrew, run:
86
-
87
- brew install redis
88
-
89
- To install a local copy Zookeeper for testing purposes, run:
90
-
91
- rake zookeeper:install
92
-
93
- and to start it run:
94
-
95
- rake zookeeper:start
96
-
97
- Configuration
98
- -------------
99
-
100
- The simplest way to configure and start DCell is with the following:
101
-
102
- ```ruby
103
- require 'dcell'
104
-
105
- DCell.start
106
- ```
107
-
108
- This configures DCell with all the default options, however there are many
109
- options you can override, e.g.:
110
-
111
- ```ruby
112
- DCell.start :id => "node42", :addr => "tcp://127.0.0.1:2042"
113
- ```
114
-
115
- DCell identifies each node with a unique node ID, that defaults to your
116
- hostname. Each node needs to be reachable over 0MQ, and the addr option
117
- specifies the 0MQ address where the host can be reached. When giving a tcp://
118
- URL, you *must* specify an IP address and not a hostname.
119
-
120
- To join a cluster you'll need to provide the location of the registry server.
121
- This can be done through the "registry" configuration key:
122
-
123
- ```ruby
124
- DCell.start :id => "node24", :addr => "tcp://127.0.0.1:2042",
125
- :registry => {
126
- :adapter => 'redis',
127
- :host => 'mycluster.example.org',
128
- :port => 6379
129
- }
130
- ```
131
-
132
- When configuring DCell to use Redis, use the following options:
133
-
134
- - **adapter**: "redis" (*optional, alternatively "zk"*)
135
- - **host**: hostname or IP address of the Redis server (*optional, default localhost*)
136
- - **port**: port of the Redis server (*optional, default 6379*)
137
- - **password**: password to the Redis server (*optional*)
138
-
139
- Usage
140
- -----
141
-
142
- You've now configured a single node in a DCell cluster. You can obtain the
143
- DCell::Node object representing the local node by calling DCell.me:
144
-
145
- ```ruby
146
- >> DCell.start
147
- => #<Celluloid::Supervisor(DCell::Application):0xed6>
148
- >> DCell.me
149
- => #<DCell::Node[cryptosphere.local] @addr="tcp://127.0.0.1:7777">
150
- ```
151
-
152
- DCell::Node objects are the entry point for locating actors on the system.
153
- DCell.me returns the local node. Other nodes can be obtained by their
154
- node IDs:
155
-
156
- ```ruby
157
- >> node = DCell::Node["cryptosphere.local"]
158
- => #<DCell::Node[cryptosphere.local] @addr="tcp://127.0.0.1:7777">
159
- ```
160
-
161
- DCell::Node.all returns all connected nodes in the cluster:
162
-
163
- ```ruby
164
- >> DCell::Node.all
165
- => [#<DCell::Node[test_node] @addr="tcp://127.0.0.1:21264">, #<DCell::Node[cryptosphere.local] @addr="tcp://127.0.0.1:7777">]
166
- ```
167
-
168
- DCell::Node is a Ruby Enumerable. You can iterate across all nodes with
169
- DCell::Node.each.
170
-
171
- Once you've obtained a node, you can look up services it exports and call them
172
- just like you'd invoke methods on any other Ruby object:
173
-
174
- ```ruby
175
- >> node = DCell::Node["cryptosphere.local"]
176
- => #<DCell::Node[cryptosphere.local] @addr="tcp://127.0.0.1:7777">
177
- >> time_server = node[:time_server]
178
- => #<Celluloid::Actor(TimeServer:0xee8)>
179
- >> time_server.time
180
- => "The time is: 2011-11-10 20:23:47 -0800"
181
- ```
182
-
183
- You can also find all available services on a node with DCell::Node#all:
184
-
185
- ```ruby
186
- >> node = DCell::Node["cryptosphere.local"]
187
- => #<DCell::Node[cryptosphere.local] @addr="tcp://127.0.0.1:7777">
188
- >> node.all
189
- => [:time_server]
190
- ```
191
-
192
- Registering Actors
193
- ------------------
194
-
195
- All services exposed by DCell must take the form of registered Celluloid actors.
196
- What follows is an extremely brief introduction to creating and registering
197
- actors, but for more information, you should definitely [read the Celluloid
198
- documentation](http://celluloid.github.com).
199
-
200
- DCell exposes all Celluloid actors you've registered directly onto the network.
201
- The best way to register an actor is by supervising it. Below is an example of
202
- how to create an actor and register it on the network:
203
-
204
- ```ruby
205
- class TimeServer
206
- include Celluloid
207
-
208
- def time
209
- "The time is: #{Time.now}"
210
- end
211
- end
212
- ```
213
-
214
- Now that we've defined the TimeServer, we're going to supervise it and register
215
- it in the local registry:
216
-
217
- ```ruby
218
- >> TimeServer.supervise_as :time_server
219
- => #<Celluloid::Supervisor(TimeServer):0xee4>
220
- ```
221
-
222
- Supervising actors means that if they crash, they're automatically restarted
223
- and registered under the same name. We can access registered actors by using
224
- Celluloid::Actor#[]:
225
-
226
- ```ruby
227
- >> Celluloid::Actor[:time_server]
228
- => #<Celluloid::Actor(TimeServer:0xee8)>
229
- >> Celluloid::Actor[:time_server].time
230
- => "The time is: 2011-11-10 20:17:48 -0800"
231
- ```
232
-
233
- This same actor is now available using the DCell::Node#[] syntax:
234
-
235
- ```ruby
236
- >> node = DCell.me
237
- => #<DCell::Node[cryptosphere.local] @addr="tcp://127.0.0.1:1870">
238
- >> node[:time_server].time
239
- => "The time is: 2011-11-10 20:28:27 -0800"
240
- ```
241
-
242
- Globals
243
- -------
244
-
245
- DCell provides a registry global for storing configuration data and actors you
246
- wish to publish globally to the entire cluster:
247
-
248
- ```ruby
249
- >> actor = Celluloid::Actor[:dcell_server]
250
- => #<Celluloid::Actor(DCell::Server:0xf2e) @addr="tcp://127.0.0.1:7777">
251
- >> DCell::Global[:sweet_server] = actor
252
- => #<Celluloid::Actor(DCell::Server:0xf2e) @addr="tcp://127.0.0.1:7777">
253
- >> DCell::Global[:sweet_server]
254
- => #<Celluloid::Actor(DCell::Server:0xf2e) @addr="tcp://127.0.0.1:7777">
255
- ```
256
-
257
- What about DRb?
258
- ---------------
259
-
260
- Ruby already has a distributed object system as part of its standard library:
261
- DRb, which stands for Distributed Ruby. What's wrong with DRb? Why do we need
262
- a new system? DRb has one major drawback: it's inherently synchronous. The
263
- only thing you can do to an object is to make a method call, which sends a
264
- remote object a message, executes the method, and returns a response.
55
+ DCell works on Ruby 1.9.3, JRuby 1.6, and Rubinius 2.0.
265
56
 
266
- Under the covers, DCell uses an asynchronous message protocol. As noted in the
267
- last section, asynchronous messaging allows many more modes of messaging than
268
- the standard reqeust/response pattern afforded by DRb. DCell also supports the
269
- Erlang-style approach to fault-tolerance, advocating that actors shouldn't handle
270
- errors but should crash and restart in a clean state. Linking to actors on remote
271
- nodes can be used to detect these sorts of errors and have dependent actors
272
- restart in a clean state.
57
+ DCell requires Ruby 1.9 mode on all interpreters. This works out of the
58
+ box on MRI/YARV, and requires the following flags elsewhere:
273
59
 
274
- By far the biggest difference between DCell and DRb is how the underlying
275
- Celluloid framework has you think about the problem. Celluloid provides a useful
276
- concurrent in-process messaging system in its own right without the distributed
277
- components.
60
+ * JRuby: --1.9 command line option, or JRUBY_OPTS=--1.9 environment variable
61
+ * rbx: -X19 command line option
278
62
 
279
63
  Copyright
280
64
  ---------
281
65
 
282
- Copyright (c) 2011 Tony Arcieri. See LICENSE.txt for further details.
66
+ Copyright (c) 2012 Tony Arcieri. See LICENSE.txt for further details.
@@ -29,8 +29,8 @@ class Progenator
29
29
  end
30
30
  end
31
31
 
32
- class BenchmarkApplication < Celluloid::Application
33
- supervise DCell::Application
32
+ class BenchmarkApplication < Celluloid::Group
33
+ supervise DCell::Group
34
34
  supervise Progenator, :as => :progenator
35
35
  end
36
36
 
@@ -7,7 +7,7 @@ Gem::Specification.new do |gem|
7
7
  gem.version = DCell::VERSION
8
8
  gem.authors = ["Tony Arcieri"]
9
9
  gem.email = ["tony.arcieri@gmail.com"]
10
- gem.homepage = "http://github.com/tarcieri/dcell"
10
+ gem.homepage = "http://github.com/celluloid/dcell"
11
11
  gem.summary = "An asynchronous distributed object framework based on Celluloid"
12
12
  gem.description = "DCell is an distributed object framework based on Celluloid built on 0MQ and Zookeeper"
13
13
 
@@ -16,13 +16,13 @@ Gem::Specification.new do |gem|
16
16
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
17
  gem.require_paths = ["lib"]
18
18
 
19
- gem.add_dependency "celluloid", "~> 0.9.0"
20
- gem.add_dependency "celluloid-zmq", "~> 0.9.0"
21
- gem.add_dependency "redis"
22
- gem.add_dependency "redis-namespace"
23
- gem.add_dependency "moneta"
19
+ gem.add_runtime_dependency "celluloid", "~> 0.10.0"
20
+ gem.add_runtime_dependency "celluloid-zmq", "~> 0.10.0"
21
+ gem.add_runtime_dependency "reel", "~> 0.0.1"
22
+ gem.add_runtime_dependency "redis"
23
+ gem.add_runtime_dependency "redis-namespace"
24
+ gem.add_runtime_dependency "moneta"
24
25
 
25
26
  gem.add_development_dependency "rake"
26
27
  gem.add_development_dependency "rspec"
27
- #gem.add_development_dependency "zk"
28
28
  end
@@ -0,0 +1,686 @@
1
+ /*!
2
+ * Bootstrap Responsive v2.0.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
+ .clearfix {
11
+ *zoom: 1;
12
+ }
13
+ .clearfix:before,
14
+ .clearfix:after {
15
+ display: table;
16
+ content: "";
17
+ }
18
+ .clearfix:after {
19
+ clear: both;
20
+ }
21
+ .hide-text {
22
+ overflow: hidden;
23
+ text-indent: 100%;
24
+ white-space: nowrap;
25
+ }
26
+ .input-block-level {
27
+ display: block;
28
+ width: 100%;
29
+ min-height: 28px;
30
+ /* Make inputs at least the height of their button counterpart */
31
+
32
+ /* Makes inputs behave like true block-level elements */
33
+
34
+ -webkit-box-sizing: border-box;
35
+ -moz-box-sizing: border-box;
36
+ -ms-box-sizing: border-box;
37
+ box-sizing: border-box;
38
+ }
39
+ .hidden {
40
+ display: none;
41
+ visibility: hidden;
42
+ }
43
+ .visible-phone {
44
+ display: none;
45
+ }
46
+ .visible-tablet {
47
+ display: none;
48
+ }
49
+ .visible-desktop {
50
+ display: block;
51
+ }
52
+ .hidden-phone {
53
+ display: block;
54
+ }
55
+ .hidden-tablet {
56
+ display: block;
57
+ }
58
+ .hidden-desktop {
59
+ display: none;
60
+ }
61
+ @media (max-width: 767px) {
62
+ .visible-phone {
63
+ display: block;
64
+ }
65
+ .hidden-phone {
66
+ display: none;
67
+ }
68
+ .hidden-desktop {
69
+ display: block;
70
+ }
71
+ .visible-desktop {
72
+ display: none;
73
+ }
74
+ }
75
+ @media (min-width: 768px) and (max-width: 979px) {
76
+ .visible-tablet {
77
+ display: block;
78
+ }
79
+ .hidden-tablet {
80
+ display: none;
81
+ }
82
+ .hidden-desktop {
83
+ display: block;
84
+ }
85
+ .visible-desktop {
86
+ display: none;
87
+ }
88
+ }
89
+ @media (max-width: 480px) {
90
+ .nav-collapse {
91
+ -webkit-transform: translate3d(0, 0, 0);
92
+ }
93
+ .page-header h1 small {
94
+ display: block;
95
+ line-height: 18px;
96
+ }
97
+ input[type="checkbox"],
98
+ input[type="radio"] {
99
+ border: 1px solid #ccc;
100
+ }
101
+ .form-horizontal .control-group > label {
102
+ float: none;
103
+ width: auto;
104
+ padding-top: 0;
105
+ text-align: left;
106
+ }
107
+ .form-horizontal .controls {
108
+ margin-left: 0;
109
+ }
110
+ .form-horizontal .control-list {
111
+ padding-top: 0;
112
+ }
113
+ .form-horizontal .form-actions {
114
+ padding-left: 10px;
115
+ padding-right: 10px;
116
+ }
117
+ .modal {
118
+ position: absolute;
119
+ top: 10px;
120
+ left: 10px;
121
+ right: 10px;
122
+ width: auto;
123
+ margin: 0;
124
+ }
125
+ .modal.fade.in {
126
+ top: auto;
127
+ }
128
+ .modal-header .close {
129
+ padding: 10px;
130
+ margin: -10px;
131
+ }
132
+ .carousel-caption {
133
+ position: static;
134
+ }
135
+ }
136
+ @media (max-width: 767px) {
137
+ body {
138
+ padding-left: 20px;
139
+ padding-right: 20px;
140
+ }
141
+ .navbar-fixed-top {
142
+ margin-left: -20px;
143
+ margin-right: -20px;
144
+ }
145
+ .container {
146
+ width: auto;
147
+ }
148
+ .row-fluid {
149
+ width: 100%;
150
+ }
151
+ .row {
152
+ margin-left: 0;
153
+ }
154
+ .row > [class*="span"],
155
+ .row-fluid > [class*="span"] {
156
+ float: none;
157
+ display: block;
158
+ width: auto;
159
+ margin: 0;
160
+ }
161
+ .thumbnails [class*="span"] {
162
+ width: auto;
163
+ }
164
+ input[class*="span"],
165
+ select[class*="span"],
166
+ textarea[class*="span"],
167
+ .uneditable-input {
168
+ display: block;
169
+ width: 100%;
170
+ min-height: 28px;
171
+ /* Make inputs at least the height of their button counterpart */
172
+
173
+ /* Makes inputs behave like true block-level elements */
174
+
175
+ -webkit-box-sizing: border-box;
176
+ -moz-box-sizing: border-box;
177
+ -ms-box-sizing: border-box;
178
+ box-sizing: border-box;
179
+ }
180
+ .input-prepend input[class*="span"],
181
+ .input-append input[class*="span"] {
182
+ width: auto;
183
+ }
184
+ }
185
+ @media (min-width: 768px) and (max-width: 979px) {
186
+ .row {
187
+ margin-left: -20px;
188
+ *zoom: 1;
189
+ }
190
+ .row:before,
191
+ .row:after {
192
+ display: table;
193
+ content: "";
194
+ }
195
+ .row:after {
196
+ clear: both;
197
+ }
198
+ [class*="span"] {
199
+ float: left;
200
+ margin-left: 20px;
201
+ }
202
+ .container,
203
+ .navbar-fixed-top .container,
204
+ .navbar-fixed-bottom .container {
205
+ width: 724px;
206
+ }
207
+ .span12 {
208
+ width: 724px;
209
+ }
210
+ .span11 {
211
+ width: 662px;
212
+ }
213
+ .span10 {
214
+ width: 600px;
215
+ }
216
+ .span9 {
217
+ width: 538px;
218
+ }
219
+ .span8 {
220
+ width: 476px;
221
+ }
222
+ .span7 {
223
+ width: 414px;
224
+ }
225
+ .span6 {
226
+ width: 352px;
227
+ }
228
+ .span5 {
229
+ width: 290px;
230
+ }
231
+ .span4 {
232
+ width: 228px;
233
+ }
234
+ .span3 {
235
+ width: 166px;
236
+ }
237
+ .span2 {
238
+ width: 104px;
239
+ }
240
+ .span1 {
241
+ width: 42px;
242
+ }
243
+ .offset12 {
244
+ margin-left: 764px;
245
+ }
246
+ .offset11 {
247
+ margin-left: 702px;
248
+ }
249
+ .offset10 {
250
+ margin-left: 640px;
251
+ }
252
+ .offset9 {
253
+ margin-left: 578px;
254
+ }
255
+ .offset8 {
256
+ margin-left: 516px;
257
+ }
258
+ .offset7 {
259
+ margin-left: 454px;
260
+ }
261
+ .offset6 {
262
+ margin-left: 392px;
263
+ }
264
+ .offset5 {
265
+ margin-left: 330px;
266
+ }
267
+ .offset4 {
268
+ margin-left: 268px;
269
+ }
270
+ .offset3 {
271
+ margin-left: 206px;
272
+ }
273
+ .offset2 {
274
+ margin-left: 144px;
275
+ }
276
+ .offset1 {
277
+ margin-left: 82px;
278
+ }
279
+ .row-fluid {
280
+ width: 100%;
281
+ *zoom: 1;
282
+ }
283
+ .row-fluid:before,
284
+ .row-fluid:after {
285
+ display: table;
286
+ content: "";
287
+ }
288
+ .row-fluid:after {
289
+ clear: both;
290
+ }
291
+ .row-fluid > [class*="span"] {
292
+ float: left;
293
+ margin-left: 2.762430939%;
294
+ }
295
+ .row-fluid > [class*="span"]:first-child {
296
+ margin-left: 0;
297
+ }
298
+ .row-fluid > .span12 {
299
+ width: 99.999999993%;
300
+ }
301
+ .row-fluid > .span11 {
302
+ width: 91.436464082%;
303
+ }
304
+ .row-fluid > .span10 {
305
+ width: 82.87292817100001%;
306
+ }
307
+ .row-fluid > .span9 {
308
+ width: 74.30939226%;
309
+ }
310
+ .row-fluid > .span8 {
311
+ width: 65.74585634900001%;
312
+ }
313
+ .row-fluid > .span7 {
314
+ width: 57.182320438000005%;
315
+ }
316
+ .row-fluid > .span6 {
317
+ width: 48.618784527%;
318
+ }
319
+ .row-fluid > .span5 {
320
+ width: 40.055248616%;
321
+ }
322
+ .row-fluid > .span4 {
323
+ width: 31.491712705%;
324
+ }
325
+ .row-fluid > .span3 {
326
+ width: 22.928176794%;
327
+ }
328
+ .row-fluid > .span2 {
329
+ width: 14.364640883%;
330
+ }
331
+ .row-fluid > .span1 {
332
+ width: 5.801104972%;
333
+ }
334
+ input,
335
+ textarea,
336
+ .uneditable-input {
337
+ margin-left: 0;
338
+ }
339
+ input.span12, textarea.span12, .uneditable-input.span12 {
340
+ width: 714px;
341
+ }
342
+ input.span11, textarea.span11, .uneditable-input.span11 {
343
+ width: 652px;
344
+ }
345
+ input.span10, textarea.span10, .uneditable-input.span10 {
346
+ width: 590px;
347
+ }
348
+ input.span9, textarea.span9, .uneditable-input.span9 {
349
+ width: 528px;
350
+ }
351
+ input.span8, textarea.span8, .uneditable-input.span8 {
352
+ width: 466px;
353
+ }
354
+ input.span7, textarea.span7, .uneditable-input.span7 {
355
+ width: 404px;
356
+ }
357
+ input.span6, textarea.span6, .uneditable-input.span6 {
358
+ width: 342px;
359
+ }
360
+ input.span5, textarea.span5, .uneditable-input.span5 {
361
+ width: 280px;
362
+ }
363
+ input.span4, textarea.span4, .uneditable-input.span4 {
364
+ width: 218px;
365
+ }
366
+ input.span3, textarea.span3, .uneditable-input.span3 {
367
+ width: 156px;
368
+ }
369
+ input.span2, textarea.span2, .uneditable-input.span2 {
370
+ width: 94px;
371
+ }
372
+ input.span1, textarea.span1, .uneditable-input.span1 {
373
+ width: 32px;
374
+ }
375
+ }
376
+ @media (max-width: 979px) {
377
+ body {
378
+ padding-top: 0;
379
+ }
380
+ .navbar-fixed-top {
381
+ position: static;
382
+ margin-bottom: 18px;
383
+ }
384
+ .navbar-fixed-top .navbar-inner {
385
+ padding: 5px;
386
+ }
387
+ .navbar .container {
388
+ width: auto;
389
+ padding: 0;
390
+ }
391
+ .navbar .brand {
392
+ padding-left: 10px;
393
+ padding-right: 10px;
394
+ margin: 0 0 0 -5px;
395
+ }
396
+ .navbar .nav-collapse {
397
+ clear: left;
398
+ }
399
+ .navbar .nav {
400
+ float: none;
401
+ margin: 0 0 9px;
402
+ }
403
+ .navbar .nav > li {
404
+ float: none;
405
+ }
406
+ .navbar .nav > li > a {
407
+ margin-bottom: 2px;
408
+ }
409
+ .navbar .nav > .divider-vertical {
410
+ display: none;
411
+ }
412
+ .navbar .nav .nav-header {
413
+ color: #999999;
414
+ text-shadow: none;
415
+ }
416
+ .navbar .nav > li > a,
417
+ .navbar .dropdown-menu a {
418
+ padding: 6px 15px;
419
+ font-weight: bold;
420
+ color: #999999;
421
+ -webkit-border-radius: 3px;
422
+ -moz-border-radius: 3px;
423
+ border-radius: 3px;
424
+ }
425
+ .navbar .dropdown-menu li + li a {
426
+ margin-bottom: 2px;
427
+ }
428
+ .navbar .nav > li > a:hover,
429
+ .navbar .dropdown-menu a:hover {
430
+ background-color: #222222;
431
+ }
432
+ .navbar .dropdown-menu {
433
+ position: static;
434
+ top: auto;
435
+ left: auto;
436
+ float: none;
437
+ display: block;
438
+ max-width: none;
439
+ margin: 0 15px;
440
+ padding: 0;
441
+ background-color: transparent;
442
+ border: none;
443
+ -webkit-border-radius: 0;
444
+ -moz-border-radius: 0;
445
+ border-radius: 0;
446
+ -webkit-box-shadow: none;
447
+ -moz-box-shadow: none;
448
+ box-shadow: none;
449
+ }
450
+ .navbar .dropdown-menu:before,
451
+ .navbar .dropdown-menu:after {
452
+ display: none;
453
+ }
454
+ .navbar .dropdown-menu .divider {
455
+ display: none;
456
+ }
457
+ .navbar-form,
458
+ .navbar-search {
459
+ float: none;
460
+ padding: 9px 15px;
461
+ margin: 9px 0;
462
+ border-top: 1px solid #222222;
463
+ border-bottom: 1px solid #222222;
464
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
465
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
466
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
467
+ }
468
+ .navbar .nav.pull-right {
469
+ float: none;
470
+ margin-left: 0;
471
+ }
472
+ .navbar-static .navbar-inner {
473
+ padding-left: 10px;
474
+ padding-right: 10px;
475
+ }
476
+ .btn-navbar {
477
+ display: block;
478
+ }
479
+ .nav-collapse {
480
+ overflow: hidden;
481
+ height: 0;
482
+ }
483
+ }
484
+ @media (min-width: 980px) {
485
+ .nav-collapse.collapse {
486
+ height: auto !important;
487
+ overflow: visible !important;
488
+ }
489
+ }
490
+ @media (min-width: 1200px) {
491
+ .row {
492
+ margin-left: -30px;
493
+ *zoom: 1;
494
+ }
495
+ .row:before,
496
+ .row:after {
497
+ display: table;
498
+ content: "";
499
+ }
500
+ .row:after {
501
+ clear: both;
502
+ }
503
+ [class*="span"] {
504
+ float: left;
505
+ margin-left: 30px;
506
+ }
507
+ .container,
508
+ .navbar-fixed-top .container,
509
+ .navbar-fixed-bottom .container {
510
+ width: 1170px;
511
+ }
512
+ .span12 {
513
+ width: 1170px;
514
+ }
515
+ .span11 {
516
+ width: 1070px;
517
+ }
518
+ .span10 {
519
+ width: 970px;
520
+ }
521
+ .span9 {
522
+ width: 870px;
523
+ }
524
+ .span8 {
525
+ width: 770px;
526
+ }
527
+ .span7 {
528
+ width: 670px;
529
+ }
530
+ .span6 {
531
+ width: 570px;
532
+ }
533
+ .span5 {
534
+ width: 470px;
535
+ }
536
+ .span4 {
537
+ width: 370px;
538
+ }
539
+ .span3 {
540
+ width: 270px;
541
+ }
542
+ .span2 {
543
+ width: 170px;
544
+ }
545
+ .span1 {
546
+ width: 70px;
547
+ }
548
+ .offset12 {
549
+ margin-left: 1230px;
550
+ }
551
+ .offset11 {
552
+ margin-left: 1130px;
553
+ }
554
+ .offset10 {
555
+ margin-left: 1030px;
556
+ }
557
+ .offset9 {
558
+ margin-left: 930px;
559
+ }
560
+ .offset8 {
561
+ margin-left: 830px;
562
+ }
563
+ .offset7 {
564
+ margin-left: 730px;
565
+ }
566
+ .offset6 {
567
+ margin-left: 630px;
568
+ }
569
+ .offset5 {
570
+ margin-left: 530px;
571
+ }
572
+ .offset4 {
573
+ margin-left: 430px;
574
+ }
575
+ .offset3 {
576
+ margin-left: 330px;
577
+ }
578
+ .offset2 {
579
+ margin-left: 230px;
580
+ }
581
+ .offset1 {
582
+ margin-left: 130px;
583
+ }
584
+ .row-fluid {
585
+ width: 100%;
586
+ *zoom: 1;
587
+ }
588
+ .row-fluid:before,
589
+ .row-fluid:after {
590
+ display: table;
591
+ content: "";
592
+ }
593
+ .row-fluid:after {
594
+ clear: both;
595
+ }
596
+ .row-fluid > [class*="span"] {
597
+ float: left;
598
+ margin-left: 2.564102564%;
599
+ }
600
+ .row-fluid > [class*="span"]:first-child {
601
+ margin-left: 0;
602
+ }
603
+ .row-fluid > .span12 {
604
+ width: 100%;
605
+ }
606
+ .row-fluid > .span11 {
607
+ width: 91.45299145300001%;
608
+ }
609
+ .row-fluid > .span10 {
610
+ width: 82.905982906%;
611
+ }
612
+ .row-fluid > .span9 {
613
+ width: 74.358974359%;
614
+ }
615
+ .row-fluid > .span8 {
616
+ width: 65.81196581200001%;
617
+ }
618
+ .row-fluid > .span7 {
619
+ width: 57.264957265%;
620
+ }
621
+ .row-fluid > .span6 {
622
+ width: 48.717948718%;
623
+ }
624
+ .row-fluid > .span5 {
625
+ width: 40.170940171000005%;
626
+ }
627
+ .row-fluid > .span4 {
628
+ width: 31.623931624%;
629
+ }
630
+ .row-fluid > .span3 {
631
+ width: 23.076923077%;
632
+ }
633
+ .row-fluid > .span2 {
634
+ width: 14.529914530000001%;
635
+ }
636
+ .row-fluid > .span1 {
637
+ width: 5.982905983%;
638
+ }
639
+ input,
640
+ textarea,
641
+ .uneditable-input {
642
+ margin-left: 0;
643
+ }
644
+ input.span12, textarea.span12, .uneditable-input.span12 {
645
+ width: 1160px;
646
+ }
647
+ input.span11, textarea.span11, .uneditable-input.span11 {
648
+ width: 1060px;
649
+ }
650
+ input.span10, textarea.span10, .uneditable-input.span10 {
651
+ width: 960px;
652
+ }
653
+ input.span9, textarea.span9, .uneditable-input.span9 {
654
+ width: 860px;
655
+ }
656
+ input.span8, textarea.span8, .uneditable-input.span8 {
657
+ width: 760px;
658
+ }
659
+ input.span7, textarea.span7, .uneditable-input.span7 {
660
+ width: 660px;
661
+ }
662
+ input.span6, textarea.span6, .uneditable-input.span6 {
663
+ width: 560px;
664
+ }
665
+ input.span5, textarea.span5, .uneditable-input.span5 {
666
+ width: 460px;
667
+ }
668
+ input.span4, textarea.span4, .uneditable-input.span4 {
669
+ width: 360px;
670
+ }
671
+ input.span3, textarea.span3, .uneditable-input.span3 {
672
+ width: 260px;
673
+ }
674
+ input.span2, textarea.span2, .uneditable-input.span2 {
675
+ width: 160px;
676
+ }
677
+ input.span1, textarea.span1, .uneditable-input.span1 {
678
+ width: 60px;
679
+ }
680
+ .thumbnails {
681
+ margin-left: -30px;
682
+ }
683
+ .thumbnails > li {
684
+ margin-left: 30px;
685
+ }
686
+ }