restapi_doc 0.0.1
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/Gemfile +11 -0
- data/Gemfile.lock +36 -0
- data/LICENSE +20 -0
- data/README.rdoc +28 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/lib/restapi_doc/config/restapi_doc.yml +2 -0
- data/lib/restapi_doc/config.rb +46 -0
- data/lib/restapi_doc/method_doc.rb +84 -0
- data/lib/restapi_doc/railtie.rb +9 -0
- data/lib/restapi_doc/resource_doc.rb +104 -0
- data/lib/restapi_doc/tasks/restapi_doc_tasks.rake +28 -0
- data/lib/restapi_doc/template/assets/css/bootstrap-responsive.min.css +12 -0
- data/lib/restapi_doc/template/assets/css/bootstrap.less +9 -0
- data/lib/restapi_doc/template/assets/css/bootstrap.min.css +689 -0
- data/lib/restapi_doc/template/assets/css/prettify.css +30 -0
- data/lib/restapi_doc/template/assets/img/glyphicons-halflings-white.png +0 -0
- data/lib/restapi_doc/template/assets/img/glyphicons-halflings.png +0 -0
- data/lib/restapi_doc/template/assets/js/bootstrap.min.js +6 -0
- data/lib/restapi_doc/template/assets/js/jquery.js +4 -0
- data/lib/restapi_doc/template/assets/js/less.min.js +9 -0
- data/lib/restapi_doc/template/assets/js/prettify.js +28 -0
- data/lib/restapi_doc/template/detail.html.haml +107 -0
- data/lib/restapi_doc/template/index.html.haml +57 -0
- data/lib/restapi_doc.rb +99 -0
- data/restapi_doc.gemspec +79 -0
- metadata +141 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
diff-lcs (1.1.3)
|
|
5
|
+
git (1.2.5)
|
|
6
|
+
haml (3.1.4)
|
|
7
|
+
jeweler (1.8.3)
|
|
8
|
+
bundler (~> 1.0)
|
|
9
|
+
git (>= 1.2.5)
|
|
10
|
+
rake
|
|
11
|
+
rdoc
|
|
12
|
+
json (1.6.6)
|
|
13
|
+
metaclass (0.0.1)
|
|
14
|
+
mocha (0.11.3)
|
|
15
|
+
metaclass (~> 0.0.1)
|
|
16
|
+
rake (0.9.2.2)
|
|
17
|
+
rdoc (3.12)
|
|
18
|
+
json (~> 1.4)
|
|
19
|
+
rspec (2.9.0)
|
|
20
|
+
rspec-core (~> 2.9.0)
|
|
21
|
+
rspec-expectations (~> 2.9.0)
|
|
22
|
+
rspec-mocks (~> 2.9.0)
|
|
23
|
+
rspec-core (2.9.0)
|
|
24
|
+
rspec-expectations (2.9.1)
|
|
25
|
+
diff-lcs (~> 1.1.3)
|
|
26
|
+
rspec-mocks (2.9.0)
|
|
27
|
+
|
|
28
|
+
PLATFORMS
|
|
29
|
+
ruby
|
|
30
|
+
|
|
31
|
+
DEPENDENCIES
|
|
32
|
+
haml (= 3.1.4)
|
|
33
|
+
jeweler
|
|
34
|
+
mocha
|
|
35
|
+
rake
|
|
36
|
+
rspec (>= 2.2.0)
|
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2012 Kevin Haight (kevinjhaight@gmail.com)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
= Rest Api Doc
|
|
2
|
+
|
|
3
|
+
Rest API doc generates an easy way to create a Twitter style document for your RESTful interface
|
|
4
|
+
|
|
5
|
+
Leveraging Twitter Bootstrap to create an easy to read document for your RESTful api.
|
|
6
|
+
|
|
7
|
+
== Installing the gem
|
|
8
|
+
|
|
9
|
+
gem install restapi_doc
|
|
10
|
+
|
|
11
|
+
== Set Up
|
|
12
|
+
Run the following rake command to setup your environment.
|
|
13
|
+
|
|
14
|
+
rake restapi_doc:generate
|
|
15
|
+
|
|
16
|
+
This will create a 'restapi_doc' directory in your Rails config directory.
|
|
17
|
+
In this directory you will now have a "restapi_doc.yml' file with some simple configuration options for your API document.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
== Documenting controllers
|
|
21
|
+
Below is a sample of how to document the controller to generate a document
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
== Creating Api Document
|
|
25
|
+
|
|
26
|
+
rake restapi_doc:generate
|
|
27
|
+
|
|
28
|
+
You will now have a 'apidoc' directory located in your Rails 'public' directory
|
data/Rakefile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'jeweler'
|
|
6
|
+
Jeweler::Tasks.new do |gem|
|
|
7
|
+
gem.name = "restapi_doc"
|
|
8
|
+
gem.summary = %Q{REST API doc generates an easy way to create a twitter style document for your RESTful interface}
|
|
9
|
+
gem.description = %Q{REST API doc generates an easy way to create a twitter style document for your RESTful interface.
|
|
10
|
+
Leveraging Twitter Bootstrap to create an easy to read document for your RESTful api. }
|
|
11
|
+
gem.email = "kevinjhaight@gmail.com"
|
|
12
|
+
gem.homepage = "http://github.com/alayho/restapi_doc"
|
|
13
|
+
gem.authors = ["Kevin Haight"]
|
|
14
|
+
end
|
|
15
|
+
Jeweler::GemcutterTasks.new
|
|
16
|
+
rescue LoadError
|
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
require 'rspec/core/rake_task'
|
|
21
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
22
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
26
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
|
27
|
+
spec.rcov = true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
task :default => :spec
|
|
31
|
+
|
|
32
|
+
require 'rdoc/task'
|
|
33
|
+
Rake::RDocTask.new do |rdoc|
|
|
34
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
|
35
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
36
|
+
rdoc.title = "restapi_doc #{version}"
|
|
37
|
+
rdoc.rdoc_files.include('README*')
|
|
38
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
39
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.1
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module RestApiDoc
|
|
3
|
+
module Config
|
|
4
|
+
def template_dir(f = nil)
|
|
5
|
+
@template_dir ||= File.join(File.dirname(__FILE__), 'template')
|
|
6
|
+
form_file_name @template_dir, f
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def config_template_dir(f = nil)
|
|
10
|
+
@template_dir ||= File.join(File.dirname(__FILE__), 'config')
|
|
11
|
+
form_file_name @template_dir, f
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def asset_dir
|
|
15
|
+
@asset_dir ||= File.join(File.dirname(__FILE__), 'template/assets')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def config_dir(f = nil)
|
|
19
|
+
@config_dir ||= File.join(::Rails.root.to_s, 'config/restapi_doc')
|
|
20
|
+
form_file_name @config_dir, f
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def target_dir(f = nil)
|
|
24
|
+
@target_dir ||= File.join(::Rails.root.to_s, 'public/apidoc/')
|
|
25
|
+
form_file_name @target_dir, f
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def controller_dir(f = nil)
|
|
29
|
+
@controller_dir ||= File.join(::Rails.root.to_s, 'app/controllers/')
|
|
30
|
+
form_file_name @controller_dir, f
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def temp_dir(f = nil)
|
|
34
|
+
@temp_dir ||= "#{Dir.mktmpdir("apidoc")}/"
|
|
35
|
+
form_file_name @temp_dir, f
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def form_file_name(dir, file)
|
|
39
|
+
case file
|
|
40
|
+
when NilClass then dir
|
|
41
|
+
when String then File.join(dir, file)
|
|
42
|
+
else raise ArgumentError, "Invalid argument #{file}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module RestApiDoc
|
|
3
|
+
class MethodDoc
|
|
4
|
+
attr_accessor :scope, :method_order, :content, :request, :response, :output, :params, :defname, :response_formats, :requires_authentication, :request_url, :account_password_required, :http_responses
|
|
5
|
+
|
|
6
|
+
def initialize(resource_name, type, order)
|
|
7
|
+
@resource_name = resource_name
|
|
8
|
+
@scope = type
|
|
9
|
+
@method_order = order
|
|
10
|
+
@content = ""
|
|
11
|
+
@request = ""
|
|
12
|
+
@response = ""
|
|
13
|
+
@output = ""
|
|
14
|
+
@params = []
|
|
15
|
+
@response_formats = []
|
|
16
|
+
@http_responses= []
|
|
17
|
+
@requires_authentication = "No"
|
|
18
|
+
@account_password_required = "No"
|
|
19
|
+
@defname = nil
|
|
20
|
+
@request_url = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def process_line(line, current_scope)
|
|
24
|
+
new_scope = current_scope
|
|
25
|
+
case current_scope
|
|
26
|
+
when :response
|
|
27
|
+
if line =~ /::response-end::/
|
|
28
|
+
new_scope = :function
|
|
29
|
+
else
|
|
30
|
+
@response << line
|
|
31
|
+
end
|
|
32
|
+
when :request
|
|
33
|
+
if line =~ /::request-end::/
|
|
34
|
+
new_scope = :function
|
|
35
|
+
else
|
|
36
|
+
@request << line
|
|
37
|
+
end
|
|
38
|
+
when :output # append output
|
|
39
|
+
if line =~ /::output-end::/
|
|
40
|
+
new_scope = :function
|
|
41
|
+
else
|
|
42
|
+
@output << line
|
|
43
|
+
end
|
|
44
|
+
when :class, :function
|
|
45
|
+
result = line.scan(/(\w+)\:\:\s*(.+)/)
|
|
46
|
+
if not result.empty?
|
|
47
|
+
key, value = result[0]
|
|
48
|
+
case key
|
|
49
|
+
when "response", "request"
|
|
50
|
+
new_scope = key.to_sym
|
|
51
|
+
when "output"
|
|
52
|
+
new_scope = key.to_sym
|
|
53
|
+
when "param"
|
|
54
|
+
@params << value
|
|
55
|
+
when "http_response"
|
|
56
|
+
@http_responses << value
|
|
57
|
+
when "response_format"
|
|
58
|
+
@response_formats << value
|
|
59
|
+
when "requires_authentication"
|
|
60
|
+
@requires_authentication = value
|
|
61
|
+
when "request_url"
|
|
62
|
+
@request_url = value
|
|
63
|
+
when "account_password_required"
|
|
64
|
+
@account_password_required = value
|
|
65
|
+
else # user wants this new shiny variable whose name is the key with value = value
|
|
66
|
+
instance_variable_set("@#{key}".to_sym, value)
|
|
67
|
+
define_singleton_method(key.to_sym) { value } # define accessor for the templates to read it
|
|
68
|
+
end
|
|
69
|
+
else
|
|
70
|
+
# add line to block
|
|
71
|
+
@content << line
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
raise ParsingException, "logic error: unknown current scope #{current_scope}"
|
|
75
|
+
end
|
|
76
|
+
new_scope
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def get_binding
|
|
80
|
+
binding
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require_relative 'method_doc'
|
|
3
|
+
|
|
4
|
+
module RestApiDoc
|
|
5
|
+
class ParsingException < Exception;
|
|
6
|
+
end
|
|
7
|
+
class ResourceDoc
|
|
8
|
+
|
|
9
|
+
attr_reader :name, :resource_location, :controller_name, :class_block, :function_blocks, :resource_header, :resource_methods, :description
|
|
10
|
+
|
|
11
|
+
# Initializes ResourceDoc.
|
|
12
|
+
def initialize(name, action_methods, controller_location, options = {})
|
|
13
|
+
@name = name
|
|
14
|
+
@class_block = nil
|
|
15
|
+
@function_blocks = []
|
|
16
|
+
@resource_methods = action_methods
|
|
17
|
+
@resource_header = ""
|
|
18
|
+
@standard_methods = options[:standard_methods] || [:put, :post, :get, :delete]
|
|
19
|
+
@resource_location = resource_location
|
|
20
|
+
@controller_location = controller_location
|
|
21
|
+
@description = nil
|
|
22
|
+
@controller_name = File.basename(controller_location)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# parse the controller
|
|
26
|
+
def parse_apidoc
|
|
27
|
+
lines = IO.readlines(@controller_location)
|
|
28
|
+
begin
|
|
29
|
+
@class_block, @function_blocks = ResourceDoc.parse_controller_doc(@name, lines)
|
|
30
|
+
rescue ParsingException => ex
|
|
31
|
+
puts "error #{ex} while parsing #{@controller_location}"
|
|
32
|
+
exit
|
|
33
|
+
end
|
|
34
|
+
if !@class_block.nil?
|
|
35
|
+
@description = @class_block.content
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
@resource_methods.each do | req_m |
|
|
39
|
+
req_m << @function_blocks.select{|f| f.defname == req_m[0]}.first
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# This method parses the doc
|
|
44
|
+
def self.parse_controller_doc(name, lines)
|
|
45
|
+
current_api_block = nil
|
|
46
|
+
current_scope = :none
|
|
47
|
+
in_class = false
|
|
48
|
+
class_block = nil
|
|
49
|
+
function_blocks = []
|
|
50
|
+
order = 1
|
|
51
|
+
lines.each_with_index do |line, line_no|
|
|
52
|
+
line.gsub!(/^ *#/, '') # strip the starting '#' on the line
|
|
53
|
+
case line
|
|
54
|
+
when /=begin apidoc/
|
|
55
|
+
# if we get apidoc tag inside class definition, then they are for a method
|
|
56
|
+
current_scope = !in_class ? :class : :function
|
|
57
|
+
current_api_block = MethodDoc.new(name, current_scope, order)
|
|
58
|
+
when /=end/
|
|
59
|
+
if current_api_block.nil?
|
|
60
|
+
raise ParsingException, "#{line_no} - No starttag for '=end' found"
|
|
61
|
+
end
|
|
62
|
+
when /class/ # keep track of whether a resource or an api is being annotated
|
|
63
|
+
in_class = true
|
|
64
|
+
if !current_api_block.nil?
|
|
65
|
+
case current_scope
|
|
66
|
+
when :class
|
|
67
|
+
class_block = current_api_block
|
|
68
|
+
when :function
|
|
69
|
+
function_blocks << current_api_block
|
|
70
|
+
else
|
|
71
|
+
raise ParsingException, "logic error: unknown current scope #{current_scope}"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
current_api_block = nil
|
|
75
|
+
current_scope = :none
|
|
76
|
+
order += 1
|
|
77
|
+
end
|
|
78
|
+
when /def/
|
|
79
|
+
if !current_api_block.nil?
|
|
80
|
+
current_api_block.defname = line.gsub('def ', '').strip
|
|
81
|
+
|
|
82
|
+
case current_scope
|
|
83
|
+
when :class
|
|
84
|
+
class_block = current_api_block
|
|
85
|
+
when :function
|
|
86
|
+
function_blocks << current_api_block
|
|
87
|
+
else
|
|
88
|
+
raise ParsingException, "logic error: unknown current scope #{current_scope}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
current_api_block = nil
|
|
92
|
+
current_scope = :none
|
|
93
|
+
order += 1
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
if current_api_block # process lines only if they are apidoc comments
|
|
97
|
+
current_scope = current_api_block.process_line(line, current_scope)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
[class_block, function_blocks]
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
include RestApiDoc
|
|
3
|
+
|
|
4
|
+
namespace :restapi_doc do
|
|
5
|
+
|
|
6
|
+
desc "Generate the config files"
|
|
7
|
+
task :setup do
|
|
8
|
+
create_structure
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
desc "Generate the api documentation"
|
|
12
|
+
task :generate do
|
|
13
|
+
remove_structure
|
|
14
|
+
resources = get_resources do |controller, controller_url, controller_location|
|
|
15
|
+
end
|
|
16
|
+
if !resources.empty?
|
|
17
|
+
puts "Generating API documentation..."
|
|
18
|
+
generate_doc(resources)
|
|
19
|
+
move_document
|
|
20
|
+
puts "Completed API documentation generation"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc "Generate the config files"
|
|
25
|
+
task :clean do
|
|
26
|
+
remove_structure
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";}
|
|
2
|
+
.clearfix:after{clear:both;}
|
|
3
|
+
.hide-text{overflow:hidden;text-indent:100%;white-space:nowrap;}
|
|
4
|
+
.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;}
|
|
5
|
+
.hidden{display:none;visibility:hidden;}
|
|
6
|
+
.visible-phone{display:none;}
|
|
7
|
+
.visible-tablet{display:none;}
|
|
8
|
+
.visible-desktop{display:block;}
|
|
9
|
+
.hidden-phone{display:block;}
|
|
10
|
+
.hidden-tablet{display:block;}
|
|
11
|
+
.hidden-desktop{display:none;}
|
|
12
|
+
@media (max-width:767px){.visible-phone{display:block;} .hidden-phone{display:none;} .hidden-desktop{display:block;} .visible-desktop{display:none;}}@media (min-width:768px) and (max-width:979px){.visible-tablet{display:block;} .hidden-tablet{display:none;} .hidden-desktop{display:block;} .visible-desktop{display:none;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:18px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .modal{position:absolute;top:10px;left:10px;right:10px;width:auto;margin:0;}.modal.fade.in{top:auto;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top{margin-left:-20px;margin-right:-20px;} .container{width:auto;} .row-fluid{width:100%;} .row{margin-left:0;} .row>[class*="span"],.row-fluid>[class*="span"]{float:none;display:block;width:auto;margin:0;} .thumbnails [class*="span"]{width:auto;} input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} .input-prepend input[class*="span"],.input-append input[class*="span"]{width:auto;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:20px;} .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid>[class*="span"]{float:left;margin-left:2.762430939%;} .row-fluid>[class*="span"]:first-child{margin-left:0;} .row-fluid > .span12{width:99.999999993%;} .row-fluid > .span11{width:91.436464082%;} .row-fluid > .span10{width:82.87292817100001%;} .row-fluid > .span9{width:74.30939226%;} .row-fluid > .span8{width:65.74585634900001%;} .row-fluid > .span7{width:57.182320438000005%;} .row-fluid > .span6{width:48.618784527%;} .row-fluid > .span5{width:40.055248616%;} .row-fluid > .span4{width:31.491712705%;} .row-fluid > .span3{width:22.928176794%;} .row-fluid > .span2{width:14.364640883%;} .row-fluid > .span1{width:5.801104972%;} input,textarea,.uneditable-input{margin-left:0;} input.span12, textarea.span12, .uneditable-input.span12{width:714px;} input.span11, textarea.span11, .uneditable-input.span11{width:652px;} input.span10, textarea.span10, .uneditable-input.span10{width:590px;} input.span9, textarea.span9, .uneditable-input.span9{width:528px;} input.span8, textarea.span8, .uneditable-input.span8{width:466px;} input.span7, textarea.span7, .uneditable-input.span7{width:404px;} input.span6, textarea.span6, .uneditable-input.span6{width:342px;} input.span5, textarea.span5, .uneditable-input.span5{width:280px;} input.span4, textarea.span4, .uneditable-input.span4{width:218px;} input.span3, textarea.span3, .uneditable-input.span3{width:156px;} input.span2, textarea.span2, .uneditable-input.span2{width:94px;} input.span1, textarea.span1, .uneditable-input.span1{width:32px;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top{position:static;margin-bottom:18px;} .navbar-fixed-top .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .navbar .nav-collapse{clear:left;} .navbar .nav{float:none;margin:0 0 9px;} .navbar .nav>li{float:none;} .navbar .nav>li>a{margin-bottom:2px;} .navbar .nav>.divider-vertical{display:none;} .navbar .nav .nav-header{color:#999999;text-shadow:none;} .navbar .nav>li>a,.navbar .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .navbar .dropdown-menu li+li a{margin-bottom:2px;} .navbar .nav>li>a:hover,.navbar .dropdown-menu a:hover{background-color:#222222;} .navbar .dropdown-menu{position:static;top:auto;left:auto;float:none;display:block;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .navbar .dropdown-menu:before,.navbar .dropdown-menu:after{display:none;} .navbar .dropdown-menu .divider{display:none;} .navbar-form,.navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222222;border-bottom:1px solid #222222;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);} .navbar .nav.pull-right{float:none;margin-left:0;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;} .btn-navbar{display:block;} .nav-collapse{overflow:hidden;height:0;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:30px;} .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid>[class*="span"]{float:left;margin-left:2.564102564%;} .row-fluid>[class*="span"]:first-child{margin-left:0;} .row-fluid > .span12{width:100%;} .row-fluid > .span11{width:91.45299145300001%;} .row-fluid > .span10{width:82.905982906%;} .row-fluid > .span9{width:74.358974359%;} .row-fluid > .span8{width:65.81196581200001%;} .row-fluid > .span7{width:57.264957265%;} .row-fluid > .span6{width:48.717948718%;} .row-fluid > .span5{width:40.170940171000005%;} .row-fluid > .span4{width:31.623931624%;} .row-fluid > .span3{width:23.076923077%;} .row-fluid > .span2{width:14.529914530000001%;} .row-fluid > .span1{width:5.982905983%;} input,textarea,.uneditable-input{margin-left:0;} input.span12, textarea.span12, .uneditable-input.span12{width:1160px;} input.span11, textarea.span11, .uneditable-input.span11{width:1060px;} input.span10, textarea.span10, .uneditable-input.span10{width:960px;} input.span9, textarea.span9, .uneditable-input.span9{width:860px;} input.span8, textarea.span8, .uneditable-input.span8{width:760px;} input.span7, textarea.span7, .uneditable-input.span7{width:660px;} input.span6, textarea.span6, .uneditable-input.span6{width:560px;} input.span5, textarea.span5, .uneditable-input.span5{width:460px;} input.span4, textarea.span4, .uneditable-input.span4{width:360px;} input.span3, textarea.span3, .uneditable-input.span3{width:260px;} input.span2, textarea.span2, .uneditable-input.span2{width:160px;} input.span1, textarea.span1, .uneditable-input.span1{width:60px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;}}
|