pact_broker 0.0.10 → 1.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +0 -3
  3. data/README.md +28 -1
  4. data/Rakefile +4 -2
  5. data/assets/d3.v3.js +9263 -0
  6. data/assets/force.csv +29 -0
  7. data/assets/index.html +186 -0
  8. data/assets/index2.html +224 -0
  9. data/assets/relationships +4 -0
  10. data/assets/stylesheets/github.css +387 -0
  11. data/bethtest.rb +67 -0
  12. data/config.ru +10 -4
  13. data/config/boot.rb +4 -0
  14. data/example/Gemfile +5 -0
  15. data/example/config.ru +18 -0
  16. data/lib/db.rb +52 -0
  17. data/lib/pact_broker.rb +2 -0
  18. data/lib/pact_broker/api.rb +2 -0
  19. data/lib/pact_broker/api/decorators/pact_collection_decorator.rb +1 -1
  20. data/lib/pact_broker/api/decorators/pacticipant_collection_decorator.rb +1 -1
  21. data/lib/pact_broker/api/decorators/relationships_csv_decorator.rb +32 -0
  22. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +43 -0
  23. data/lib/pact_broker/api/resources/latest_pact.rb +7 -1
  24. data/lib/pact_broker/api/resources/relationships.rb +29 -0
  25. data/lib/pact_broker/app.rb +82 -0
  26. data/lib/pact_broker/configuration.rb +47 -0
  27. data/lib/pact_broker/db.rb +7 -39
  28. data/lib/pact_broker/models/relationship.rb +27 -0
  29. data/lib/pact_broker/project_root.rb +7 -0
  30. data/lib/pact_broker/services/pacticipant_service.rb +6 -0
  31. data/lib/pact_broker/ui/controllers/base_controller.rb +15 -0
  32. data/lib/pact_broker/ui/controllers/clusters.rb +28 -0
  33. data/lib/pact_broker/ui/controllers/relationships.rb +21 -0
  34. data/lib/pact_broker/ui/view_models/clusters.rb +0 -0
  35. data/lib/pact_broker/ui/view_models/relationship.rb +35 -0
  36. data/lib/pact_broker/ui/view_models/relationships.rb +21 -0
  37. data/lib/pact_broker/ui/views/clusters/show.haml +2 -0
  38. data/lib/pact_broker/ui/views/layouts/main.haml +2 -0
  39. data/lib/pact_broker/ui/views/relationships/show.haml +44 -0
  40. data/lib/pact_broker/version.rb +1 -1
  41. data/lib/rack/hal_browser.rb +1 -0
  42. data/lib/rack/hal_browser/redirect.rb +45 -0
  43. data/pact_broker.gemspec +10 -8
  44. data/public/bootstrap.zip +0 -0
  45. data/public/config.json +412 -0
  46. data/public/css/bootstrap-theme.css +346 -0
  47. data/public/css/bootstrap-theme.min.css +7 -0
  48. data/public/css/bootstrap.css +5780 -0
  49. data/public/css/bootstrap.min.css +7 -0
  50. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  51. data/public/fonts/glyphicons-halflings-regular.svg +229 -0
  52. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  53. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  54. data/public/javascripts/jquery-2.1.1.min.js +4 -0
  55. data/public/javascripts/jquery.tablesorter.js +1765 -0
  56. data/public/javascripts/jquery.tablesorter.min.js +5 -0
  57. data/public/js/bootstrap.js +1943 -0
  58. data/public/js/bootstrap.min.js +7 -0
  59. data/public/stylesheets/github.css +387 -0
  60. data/public/stylesheets/relationships.css +18 -0
  61. data/script/update-hal-browser +6 -0
  62. data/spec/fixtures/renderer_pact.json +34 -0
  63. data/spec/lib/pact_broker/api/decorators/relationships_csv_decorator_spec.rb +30 -0
  64. data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +29 -0
  65. data/spec/lib/pact_broker/api/resources/latest_pact_spec.rb +57 -0
  66. data/spec/lib/pact_broker/configuration_spec.rb +21 -0
  67. data/spec/lib/pact_broker/services/pacticipant_service_spec.rb +30 -0
  68. data/spec/lib/pact_broker/ui/controllers/clusters_spec.rb +27 -0
  69. data/spec/lib/pact_broker/ui/controllers/relationships_spec.rb +37 -0
  70. data/spec/lib/pact_broker/ui/view_models/relationship_spec.rb +29 -0
  71. data/spec/lib/rack/hal_browser/redirect_spec.rb +63 -0
  72. data/spec/service_consumers/pact_helper.rb +1 -1
  73. data/spec/spec_helper.rb +10 -3
  74. data/tasks/database.rb +57 -0
  75. data/tasks/db.rake +57 -12
  76. data/tasks/pact.rake +1 -1
  77. data/tasks/rspec.rake +1 -9
  78. data/vendor/hal-browser/.gitignore +1 -0
  79. data/vendor/hal-browser/MIT-LICENSE.txt +20 -0
  80. data/vendor/hal-browser/README.md +35 -0
  81. data/vendor/hal-browser/browser.html +246 -0
  82. data/vendor/hal-browser/js/hal.js +57 -0
  83. data/vendor/hal-browser/js/hal/browser.js +60 -0
  84. data/vendor/hal-browser/js/hal/http/client.js +38 -0
  85. data/vendor/hal-browser/js/hal/resource.js +34 -0
  86. data/vendor/hal-browser/js/hal/views/browser.js +29 -0
  87. data/vendor/hal-browser/js/hal/views/documentation.js +7 -0
  88. data/vendor/hal-browser/js/hal/views/embedded_resource.js +56 -0
  89. data/vendor/hal-browser/js/hal/views/embedded_resources.js +41 -0
  90. data/vendor/hal-browser/js/hal/views/explorer.js +23 -0
  91. data/vendor/hal-browser/js/hal/views/inspector.js +39 -0
  92. data/vendor/hal-browser/js/hal/views/links.js +54 -0
  93. data/vendor/hal-browser/js/hal/views/location_bar.js +40 -0
  94. data/vendor/hal-browser/js/hal/views/navigation.js +19 -0
  95. data/vendor/hal-browser/js/hal/views/non_safe_request_dialog.js +53 -0
  96. data/vendor/hal-browser/js/hal/views/properties.js +14 -0
  97. data/vendor/hal-browser/js/hal/views/query_uri_dialog.js +69 -0
  98. data/vendor/hal-browser/js/hal/views/request_headers.js +30 -0
  99. data/vendor/hal-browser/js/hal/views/resource.js +38 -0
  100. data/vendor/hal-browser/js/hal/views/response.js +24 -0
  101. data/vendor/hal-browser/js/hal/views/response_body.js +40 -0
  102. data/vendor/hal-browser/js/hal/views/response_headers.js +19 -0
  103. data/vendor/hal-browser/styles.css +67 -0
  104. data/vendor/hal-browser/vendor/css/bootstrap-responsive.css +1109 -0
  105. data/vendor/hal-browser/vendor/css/bootstrap.css +6158 -0
  106. data/vendor/hal-browser/vendor/img/ajax-loader.gif +0 -0
  107. data/vendor/hal-browser/vendor/img/glyphicons-halflings-white.png +0 -0
  108. data/vendor/hal-browser/vendor/img/glyphicons-halflings.png +0 -0
  109. data/vendor/hal-browser/vendor/js/backbone.js +1487 -0
  110. data/vendor/hal-browser/vendor/js/bootstrap.js +2276 -0
  111. data/vendor/hal-browser/vendor/js/jquery-1.9.1.js +9597 -0
  112. data/vendor/hal-browser/vendor/js/underscore.js +1227 -0
  113. data/vendor/hal-browser/vendor/js/uritemplates.js +438 -0
  114. metadata +162 -47
  115. data/Gemfile.lock +0 -110
@@ -0,0 +1,47 @@
1
+ module PactBroker
2
+
3
+ def self.configuration
4
+ @@configuration ||= Configuration.default_configuration
5
+ end
6
+
7
+ class Configuration
8
+
9
+ attr_accessor :log_dir, :database_connection, :auto_migrate_db, :use_hal_browser, :html_pact_renderer
10
+ attr_writer :logger
11
+
12
+ def logger
13
+ @logger ||= create_logger log_path
14
+ end
15
+
16
+ def self.default_configuration
17
+ config = Configuration.new
18
+ config.log_dir = File.expand_path("./log")
19
+ config.auto_migrate_db = true
20
+ config.use_hal_browser = true
21
+ config.html_pact_renderer = default_html_pact_render
22
+ config
23
+ end
24
+
25
+ def self.default_html_pact_render
26
+ lambda { |json_content|
27
+ require 'pact_broker/api/renderers/html_pact_renderer'
28
+ PactBroker::Api::Renderers::HtmlPactRenderer.call json_content
29
+ }
30
+ end
31
+
32
+ private
33
+
34
+ def create_logger path
35
+ FileUtils::mkdir_p File.dirname(path)
36
+ logger = Logger.new(path)
37
+ logger.level = Logger::DEBUG
38
+ logger
39
+ end
40
+
41
+ def log_path
42
+ log_dir + "/pact_broker.log"
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -1,45 +1,13 @@
1
1
  require 'sequel'
2
- require 'sequel/connection_pool/threaded'
3
- require 'yaml'
4
- require 'pact_broker/logging'
5
- require 'erb'
6
2
 
7
- module DB
8
- include PactBroker::Logging
9
- ##
10
- # Sequel by default does not test connections in its' connection pool before
11
- # handing them to a client. To enable connection testing you need to load the
12
- # "connection_validator" extension like below. The connection validator
13
- # extension is configurable, by default it only checks connections once per
14
- # hour:
15
- #
16
- # http://sequel.rubyforge.org/rdoc-plugins/files/lib/sequel/extensions/connection_validator_rb.html
17
- #
18
- # Because most of our applications so far are accessed infrequently, there is
19
- # very little overhead in checking each connection when it is requested. This
20
- # takes care of stale connections.
21
- #
22
- # A gotcha here is that it is not enough to enable the "connection_validator"
23
- # extension, we also need to specify that we want to use the threaded connection
24
- # pool, as noted in the documentation for the extension.
25
- #
26
- def self.connect db_credentials
27
- con = Sequel.connect(db_credentials.merge(:logger => logger, :pool_class => Sequel::ThreadedConnectionPool))
28
- con.extension(:connection_validator)
29
- con.pool.connection_validation_timeout = -1 #Check the connection on every request
30
- con
31
- end
3
+ module PactBroker
4
+ module DB
32
5
 
33
- PACT_BROKER_DB ||= begin
34
- config = YAML.load(::ERB.new(File.read(File.join('./config', 'database.yml'))).result)
35
- rack_env = ENV['RACK_ENV'] || 'development'
36
- puts "Connecting using config #{rack_env}"
37
- connect config[rack_env]
38
- end
6
+ MIGRATIONS_DIR = File.expand_path("../../../db/migrations", __FILE__)
39
7
 
40
- def self.health_check
41
- PACT_BROKER_DB.synchronize do |c| c
42
- PACT_BROKER_DB.valid_connection? c
8
+ def self.run_migrations database_connection
9
+ Sequel.extension :migration
10
+ Sequel::Migrator.run(database_connection, PactBroker::DB::MIGRATIONS_DIR)
43
11
  end
44
12
  end
45
- end
13
+ end
@@ -0,0 +1,27 @@
1
+ module PactBroker
2
+ module Models
3
+
4
+ class Relationship
5
+
6
+ attr_reader :consumer, :provider
7
+
8
+ def initialize consumer, provider
9
+ @consumer = consumer
10
+ @provider = provider
11
+ end
12
+
13
+ def self.create consumer, provider
14
+ new consumer, provider
15
+ end
16
+
17
+ def eq? other
18
+ Relationship === other && other.consumer == consumer && other.provider == provider
19
+ end
20
+
21
+ def == other
22
+ eq?(other)
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ require 'pathname'
2
+
3
+ module PactBroker
4
+ def self.project_root
5
+ @project_root ||= Pathname.new(File.expand_path('../../../',__FILE__)).freeze
6
+ end
7
+ end
@@ -1,4 +1,5 @@
1
1
  require 'pact_broker/repositories'
2
+ require 'pact_broker/models/relationship'
2
3
 
3
4
  module PactBroker
4
5
 
@@ -6,6 +7,7 @@ module PactBroker
6
7
  class PacticipantService
7
8
 
8
9
  extend PactBroker::Repositories
10
+ extend PactBroker::Repositories
9
11
 
10
12
  def self.find_all_pacticipants
11
13
  pacticipant_repository.find_all
@@ -24,6 +26,10 @@ module PactBroker
24
26
  end
25
27
  end
26
28
 
29
+ def self.find_relationships
30
+ pact_repository.find_latest_pacts.collect{ | pact| PactBroker::Models::Relationship.create pact.consumer, pact.provider }
31
+ end
32
+
27
33
  def self.update params
28
34
  pacticipant = pacticipant_repository.find_by_name(params.fetch(:name))
29
35
  pacticipant.update(params)
@@ -0,0 +1,15 @@
1
+ require 'padrino'
2
+ require 'haml'
3
+ require 'pact_broker/services'
4
+
5
+ module PactBroker
6
+ module UI
7
+ module Controllers
8
+ class Base < Padrino::Application
9
+
10
+ set :root, File.join(File.dirname(__FILE__), '..')
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ require 'padrino'
2
+ require 'haml'
3
+ require 'pact_broker/services'
4
+
5
+ module PactBroker
6
+ module UI
7
+ module Controllers
8
+ class Clusters < Padrino::Application
9
+
10
+ set :root, File.join(File.dirname(__FILE__), '..')
11
+
12
+ class Cluster
13
+
14
+ def initialize pacticipants, relationships
15
+
16
+ end
17
+
18
+ end
19
+
20
+ get "/" do
21
+ view_model = ViewModels::Relationships.new(pacticipant_service.find_relationships)
22
+ haml 'clusters/show', locals: {relationships: view_model}
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ require 'pact_broker/ui/controllers/base_controller'
2
+ require 'pact_broker/ui/view_models/relationships'
3
+
4
+ module PactBroker
5
+ module UI
6
+ module Controllers
7
+ class Relationships < Base
8
+
9
+ include PactBroker::Services
10
+
11
+ set :root, File.join(File.dirname(__FILE__), '..')
12
+
13
+ get "/" do
14
+ view_model = ViewModels::Relationships.new(pacticipant_service.find_relationships)
15
+ render 'relationships/show', locals: {relationships: view_model}, layout: 'layouts/main'
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
File without changes
@@ -0,0 +1,35 @@
1
+ require 'pact_broker/api/pact_broker_urls'
2
+
3
+ module PactBroker
4
+ module UI
5
+ module ViewModels
6
+ class Relationship
7
+
8
+ include PactBroker::Api::PactBrokerUrls
9
+
10
+ def initialize relationship
11
+ @relationship = relationship
12
+ end
13
+
14
+ def consumer_name
15
+ @relationship.consumer.name
16
+ end
17
+
18
+ def provider_name
19
+ @relationship.provider.name
20
+ end
21
+
22
+ def latest_pact_url
23
+ "#{pactigration_base_url('', @relationship)}/latest"
24
+ end
25
+
26
+ def <=> other
27
+ comp = consumer_name <=> other.consumer_name
28
+ return comp unless comp == 0
29
+ provider_name <=> other.provider_name
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require 'pact_broker/ui/view_models/relationship'
2
+
3
+ module PactBroker
4
+ module UI
5
+ module ViewModels
6
+ class Relationships
7
+
8
+ attr_reader :relationships
9
+
10
+ def initialize relationships
11
+ @relationships = relationships.collect{ |relationship| Relationship.new(relationship) }
12
+ end
13
+
14
+ def each(&block)
15
+ relationships.each(&block)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,2 @@
1
+ %p
2
+ Hellos
@@ -0,0 +1,2 @@
1
+ %html
2
+ = yield
@@ -0,0 +1,44 @@
1
+ %head
2
+ %title
3
+ Relationships
4
+ %link{rel: 'stylesheet', href: '/css/bootstrap.min.css'}
5
+ %link{rel: 'stylesheet', href: '/stylesheets/relationships.css'}
6
+ %script{type: 'text/javascript', src:'/javascripts/jquery-2.1.1.min.js'}
7
+ %script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
8
+ %body
9
+ %nav.navbase-default.navbar-right{role: "navigation"}
10
+ .container
11
+ %ul
12
+ %li.navbar-right
13
+ %a{href: '/hal-browser/browser.html'}
14
+ HAL Browser
15
+ .container
16
+ %h1.page-header
17
+ Relationships
18
+ %table.table.table-bordered.table-striped{id: 'relationships'}
19
+ %thead
20
+ %th.consumer
21
+ Consumer
22
+ %span.glyphicon.glyphicon-sort.relationships-sort
23
+ %th.pact
24
+
25
+ %th.provider
26
+ Provider
27
+ %span.glyphicon.glyphicon-sort.relationships-sort
28
+ %tbody
29
+
30
+ - relationships.each do | relationship |
31
+ %tr
32
+ %td.consumer
33
+ = relationship.consumer_name
34
+ %td.pact
35
+ %a.btn.btn-primary{:href => relationship.latest_pact_url}
36
+ %span.glyphicon.glyphicon-arrow-right
37
+ %td.provider
38
+ = relationship.provider_name
39
+
40
+ :javascript
41
+ $(function(){
42
+ $("#relationships").tablesorter();
43
+ });
44
+
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '0.0.10'
2
+ VERSION = '1.0.0.alpha1'
3
3
  end
@@ -0,0 +1 @@
1
+ require_relative 'hal_browser/redirect'
@@ -0,0 +1,45 @@
1
+ require 'uri'
2
+ require 'rack/request'
3
+ require 'rack/static'
4
+
5
+ module Rack
6
+ module HalBrowser
7
+ class Redirect
8
+
9
+ def initialize(app, options = {}, &block)
10
+ @app = app
11
+ @excluded_paths = Array(options[:exclude]) << '/hal-browser'
12
+ end
13
+
14
+ def call(env)
15
+ request = Rack::Request.new(env)
16
+ if match?(request)
17
+ return [303, {'Location' => hal_browser_url_from_request(request)}, []]
18
+ end
19
+ Rack::Static.new(@app, :urls => ['/hal-browser'], :root => ::File.expand_path('../../../../vendor', __FILE__)).call(env)
20
+ end
21
+
22
+ private
23
+
24
+ def match?(request)
25
+ request.get? && prefers_html?(request) && path_not_excluded?(request)
26
+ end
27
+
28
+ def prefers_html?(request)
29
+ # TODO: actually follow real HTTP content negotiation rules
30
+ request.env.fetch('HTTP_ACCEPT', '').start_with?('text/html') && request.env.fetch('HTTP_ACCEPT', '').include?('json')
31
+ end
32
+
33
+ def path_not_excluded?(request)
34
+ !@excluded_paths.detect{|excluded_path| request.path.start_with?(excluded_path) }
35
+ end
36
+
37
+ def hal_browser_url_from_request(request)
38
+ url = URI.parse('/hal-browser/browser.html')
39
+ url.fragment = request.path_info
40
+ url.to_s
41
+ end
42
+
43
+ end
44
+ end
45
+ end
data/pact_broker.gemspec CHANGED
@@ -27,14 +27,16 @@ Gem::Specification.new do |gem|
27
27
  gem.add_runtime_dependency 'sqlite3'
28
28
  gem.add_runtime_dependency 'webmachine'
29
29
  gem.add_runtime_dependency 'versionomy'
30
+ gem.add_runtime_dependency 'rack'
31
+ gem.add_runtime_dependency 'redcarpet', '~>3.1.1'
32
+ gem.add_runtime_dependency 'pact', '~>1.1.0'
33
+ gem.add_runtime_dependency 'padrino', '~>0.9.29'
34
+ gem.add_runtime_dependency 'haml'
30
35
 
31
- gem.add_development_dependency 'rake', '~> 10.0.3'
32
36
  gem.add_development_dependency 'pry'
33
- gem.add_development_dependency 'fakefs', '~> 0.4'
34
- gem.add_development_dependency 'rspec-fire'
35
- gem.add_development_dependency 'debugger'
36
- gem.add_development_dependency 'ci_reporter'
37
- gem.add_development_dependency 'simplecov'
38
- gem.add_development_dependency 'shotgun'
39
- gem.add_development_dependency 'pact', '1.1.0.rc1'
37
+ gem.add_development_dependency 'rake', '~>10.0'
38
+ gem.add_development_dependency 'fakefs', '~>0.4'
39
+ gem.add_development_dependency 'rspec-fire', '~>1.2.0'
40
+ gem.add_development_dependency 'mysql2', '~>0.3.15'
41
+
40
42
  end
Binary file
@@ -0,0 +1,412 @@
1
+ {
2
+ "vars": {
3
+ "@gray-darker": "lighten(#000, 13.5%)",
4
+ "@gray-dark": "lighten(#000, 20%)",
5
+ "@gray": "lighten(#000, 33.5%)",
6
+ "@gray-light": "lighten(#000, 60%)",
7
+ "@gray-lighter": "lighten(#000, 93.5%)",
8
+ "@brand-primary": "#428bca",
9
+ "@brand-success": "#5cb85c",
10
+ "@brand-info": "#5bc0de",
11
+ "@brand-warning": "#f0ad4e",
12
+ "@brand-danger": "#d9534f",
13
+ "@body-bg": "#fff",
14
+ "@text-color": "@gray-dark",
15
+ "@link-color": "@brand-primary",
16
+ "@link-hover-color": "darken(@link-color, 15%)",
17
+ "@font-family-sans-serif": "\"Helvetica Neue\", Helvetica, Arial, sans-serif",
18
+ "@font-family-serif": "Georgia, \"Times New Roman\", Times, serif",
19
+ "@font-family-monospace": "Menlo, Monaco, Consolas, \"Courier New\", monospace",
20
+ "@font-family-base": "@font-family-sans-serif",
21
+ "@font-size-base": "14px",
22
+ "@font-size-large": "ceil((@font-size-base * 1.25))",
23
+ "@font-size-small": "ceil((@font-size-base * 0.85))",
24
+ "@font-size-h1": "floor((@font-size-base * 2.6))",
25
+ "@font-size-h2": "floor((@font-size-base * 2.15))",
26
+ "@font-size-h3": "ceil((@font-size-base * 1.7))",
27
+ "@font-size-h4": "ceil((@font-size-base * 1.25))",
28
+ "@font-size-h5": "@font-size-base",
29
+ "@font-size-h6": "ceil((@font-size-base * 0.85))",
30
+ "@line-height-base": "1.428571429",
31
+ "@line-height-computed": "floor((@font-size-base * @line-height-base))",
32
+ "@headings-font-family": "inherit",
33
+ "@headings-font-weight": "500",
34
+ "@headings-line-height": "1.1",
35
+ "@headings-color": "inherit",
36
+ "@padding-base-vertical": "6px",
37
+ "@padding-base-horizontal": "12px",
38
+ "@padding-large-vertical": "10px",
39
+ "@padding-large-horizontal": "16px",
40
+ "@padding-small-vertical": "5px",
41
+ "@padding-small-horizontal": "10px",
42
+ "@padding-xs-vertical": "1px",
43
+ "@padding-xs-horizontal": "5px",
44
+ "@line-height-large": "1.33",
45
+ "@line-height-small": "1.5",
46
+ "@border-radius-base": "4px",
47
+ "@border-radius-large": "6px",
48
+ "@border-radius-small": "3px",
49
+ "@component-active-color": "#fff",
50
+ "@component-active-bg": "@brand-primary",
51
+ "@caret-width-base": "4px",
52
+ "@caret-width-large": "5px",
53
+ "@table-cell-padding": "8px",
54
+ "@table-condensed-cell-padding": "5px",
55
+ "@table-bg": "transparent",
56
+ "@table-bg-accent": "#f9f9f9",
57
+ "@table-bg-hover": "#f5f5f5",
58
+ "@table-bg-active": "@table-bg-hover",
59
+ "@table-border-color": "#ddd",
60
+ "@btn-font-weight": "normal",
61
+ "@btn-default-color": "#333",
62
+ "@btn-default-bg": "#fff",
63
+ "@btn-default-border": "#ccc",
64
+ "@btn-primary-color": "#fff",
65
+ "@btn-primary-bg": "@brand-primary",
66
+ "@btn-primary-border": "darken(@btn-primary-bg, 5%)",
67
+ "@btn-success-color": "#fff",
68
+ "@btn-success-bg": "@brand-success",
69
+ "@btn-success-border": "darken(@btn-success-bg, 5%)",
70
+ "@btn-info-color": "#fff",
71
+ "@btn-info-bg": "@brand-info",
72
+ "@btn-info-border": "darken(@btn-info-bg, 5%)",
73
+ "@btn-warning-color": "#fff",
74
+ "@btn-warning-bg": "@brand-warning",
75
+ "@btn-warning-border": "darken(@btn-warning-bg, 5%)",
76
+ "@btn-danger-color": "#fff",
77
+ "@btn-danger-bg": "@brand-danger",
78
+ "@btn-danger-border": "darken(@btn-danger-bg, 5%)",
79
+ "@btn-link-disabled-color": "@gray-light",
80
+ "@input-bg": "#fff",
81
+ "@input-bg-disabled": "@gray-lighter",
82
+ "@input-color": "@gray",
83
+ "@input-border": "#ccc",
84
+ "@input-border-radius": "@border-radius-base",
85
+ "@input-border-focus": "#66afe9",
86
+ "@input-color-placeholder": "@gray-light",
87
+ "@input-height-base": "(@line-height-computed + (@padding-base-vertical * 2) + 2)",
88
+ "@input-height-large": "(ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2)",
89
+ "@input-height-small": "(floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2)",
90
+ "@legend-color": "@gray-dark",
91
+ "@legend-border-color": "#e5e5e5",
92
+ "@input-group-addon-bg": "@gray-lighter",
93
+ "@input-group-addon-border-color": "@input-border",
94
+ "@dropdown-bg": "#fff",
95
+ "@dropdown-border": "rgba(0,0,0,.15)",
96
+ "@dropdown-fallback-border": "#ccc",
97
+ "@dropdown-divider-bg": "#e5e5e5",
98
+ "@dropdown-link-color": "@gray-dark",
99
+ "@dropdown-link-hover-color": "darken(@gray-dark, 5%)",
100
+ "@dropdown-link-hover-bg": "#f5f5f5",
101
+ "@dropdown-link-active-color": "@component-active-color",
102
+ "@dropdown-link-active-bg": "@component-active-bg",
103
+ "@dropdown-link-disabled-color": "@gray-light",
104
+ "@dropdown-header-color": "@gray-light",
105
+ "@dropdown-caret-color": "#000",
106
+ "@screen-xs": "480px",
107
+ "@screen-xs-min": "@screen-xs",
108
+ "@screen-phone": "@screen-xs-min",
109
+ "@screen-sm": "768px",
110
+ "@screen-sm-min": "@screen-sm",
111
+ "@screen-tablet": "@screen-sm-min",
112
+ "@screen-md": "992px",
113
+ "@screen-md-min": "@screen-md",
114
+ "@screen-desktop": "@screen-md-min",
115
+ "@screen-lg": "1200px",
116
+ "@screen-lg-min": "@screen-lg",
117
+ "@screen-lg-desktop": "@screen-lg-min",
118
+ "@screen-xs-max": "(@screen-sm-min - 1)",
119
+ "@screen-sm-max": "(@screen-md-min - 1)",
120
+ "@screen-md-max": "(@screen-lg-min - 1)",
121
+ "@grid-columns": "12",
122
+ "@grid-gutter-width": "30px",
123
+ "@grid-float-breakpoint": "@screen-sm-min",
124
+ "@grid-float-breakpoint-max": "(@grid-float-breakpoint - 1)",
125
+ "@container-tablet": "((720px + @grid-gutter-width))",
126
+ "@container-sm": "@container-tablet",
127
+ "@container-desktop": "((940px + @grid-gutter-width))",
128
+ "@container-md": "@container-desktop",
129
+ "@container-large-desktop": "((1140px + @grid-gutter-width))",
130
+ "@container-lg": "@container-large-desktop",
131
+ "@navbar-height": "50px",
132
+ "@navbar-margin-bottom": "@line-height-computed",
133
+ "@navbar-border-radius": "@border-radius-base",
134
+ "@navbar-padding-horizontal": "floor((@grid-gutter-width / 2))",
135
+ "@navbar-padding-vertical": "((@navbar-height - @line-height-computed) / 2)",
136
+ "@navbar-collapse-max-height": "340px",
137
+ "@navbar-default-color": "#777",
138
+ "@navbar-default-bg": "#f8f8f8",
139
+ "@navbar-default-border": "darken(@navbar-default-bg, 6.5%)",
140
+ "@navbar-default-link-color": "#777",
141
+ "@navbar-default-link-hover-color": "#333",
142
+ "@navbar-default-link-hover-bg": "transparent",
143
+ "@navbar-default-link-active-color": "#555",
144
+ "@navbar-default-link-active-bg": "darken(@navbar-default-bg, 6.5%)",
145
+ "@navbar-default-link-disabled-color": "#ccc",
146
+ "@navbar-default-link-disabled-bg": "transparent",
147
+ "@navbar-default-brand-color": "@navbar-default-link-color",
148
+ "@navbar-default-brand-hover-color": "darken(@navbar-default-brand-color, 10%)",
149
+ "@navbar-default-brand-hover-bg": "transparent",
150
+ "@navbar-default-toggle-hover-bg": "#ddd",
151
+ "@navbar-default-toggle-icon-bar-bg": "#888",
152
+ "@navbar-default-toggle-border-color": "#ddd",
153
+ "@navbar-inverse-color": "@gray-light",
154
+ "@navbar-inverse-bg": "#222",
155
+ "@navbar-inverse-border": "darken(@navbar-inverse-bg, 10%)",
156
+ "@navbar-inverse-link-color": "@gray-light",
157
+ "@navbar-inverse-link-hover-color": "#fff",
158
+ "@navbar-inverse-link-hover-bg": "transparent",
159
+ "@navbar-inverse-link-active-color": "@navbar-inverse-link-hover-color",
160
+ "@navbar-inverse-link-active-bg": "darken(@navbar-inverse-bg, 10%)",
161
+ "@navbar-inverse-link-disabled-color": "#444",
162
+ "@navbar-inverse-link-disabled-bg": "transparent",
163
+ "@navbar-inverse-brand-color": "@navbar-inverse-link-color",
164
+ "@navbar-inverse-brand-hover-color": "#fff",
165
+ "@navbar-inverse-brand-hover-bg": "transparent",
166
+ "@navbar-inverse-toggle-hover-bg": "#333",
167
+ "@navbar-inverse-toggle-icon-bar-bg": "#fff",
168
+ "@navbar-inverse-toggle-border-color": "#333",
169
+ "@nav-link-padding": "10px 15px",
170
+ "@nav-link-hover-bg": "@gray-lighter",
171
+ "@nav-disabled-link-color": "@gray-light",
172
+ "@nav-disabled-link-hover-color": "@gray-light",
173
+ "@nav-open-link-hover-color": "#fff",
174
+ "@nav-tabs-border-color": "#ddd",
175
+ "@nav-tabs-link-hover-border-color": "@gray-lighter",
176
+ "@nav-tabs-active-link-hover-bg": "@body-bg",
177
+ "@nav-tabs-active-link-hover-color": "@gray",
178
+ "@nav-tabs-active-link-hover-border-color": "#ddd",
179
+ "@nav-tabs-justified-link-border-color": "#ddd",
180
+ "@nav-tabs-justified-active-link-border-color": "@body-bg",
181
+ "@nav-pills-border-radius": "@border-radius-base",
182
+ "@nav-pills-active-link-hover-bg": "@component-active-bg",
183
+ "@nav-pills-active-link-hover-color": "@component-active-color",
184
+ "@pagination-color": "@link-color",
185
+ "@pagination-bg": "#fff",
186
+ "@pagination-border": "#ddd",
187
+ "@pagination-hover-color": "@link-hover-color",
188
+ "@pagination-hover-bg": "@gray-lighter",
189
+ "@pagination-hover-border": "#ddd",
190
+ "@pagination-active-color": "#fff",
191
+ "@pagination-active-bg": "@brand-primary",
192
+ "@pagination-active-border": "@brand-primary",
193
+ "@pagination-disabled-color": "@gray-light",
194
+ "@pagination-disabled-bg": "#fff",
195
+ "@pagination-disabled-border": "#ddd",
196
+ "@pager-bg": "@pagination-bg",
197
+ "@pager-border": "@pagination-border",
198
+ "@pager-border-radius": "15px",
199
+ "@pager-hover-bg": "@pagination-hover-bg",
200
+ "@pager-active-bg": "@pagination-active-bg",
201
+ "@pager-active-color": "@pagination-active-color",
202
+ "@pager-disabled-color": "@pagination-disabled-color",
203
+ "@jumbotron-padding": "30px",
204
+ "@jumbotron-color": "inherit",
205
+ "@jumbotron-bg": "@gray-lighter",
206
+ "@jumbotron-heading-color": "inherit",
207
+ "@jumbotron-font-size": "ceil((@font-size-base * 1.5))",
208
+ "@state-success-text": "#3c763d",
209
+ "@state-success-bg": "#dff0d8",
210
+ "@state-success-border": "darken(spin(@state-success-bg, -10), 5%)",
211
+ "@state-info-text": "#31708f",
212
+ "@state-info-bg": "#d9edf7",
213
+ "@state-info-border": "darken(spin(@state-info-bg, -10), 7%)",
214
+ "@state-warning-text": "#8a6d3b",
215
+ "@state-warning-bg": "#fcf8e3",
216
+ "@state-warning-border": "darken(spin(@state-warning-bg, -10), 5%)",
217
+ "@state-danger-text": "#a94442",
218
+ "@state-danger-bg": "#f2dede",
219
+ "@state-danger-border": "darken(spin(@state-danger-bg, -10), 5%)",
220
+ "@tooltip-max-width": "200px",
221
+ "@tooltip-color": "#fff",
222
+ "@tooltip-bg": "#000",
223
+ "@tooltip-opacity": ".9",
224
+ "@tooltip-arrow-width": "5px",
225
+ "@tooltip-arrow-color": "@tooltip-bg",
226
+ "@popover-bg": "#fff",
227
+ "@popover-max-width": "276px",
228
+ "@popover-border-color": "rgba(0,0,0,.2)",
229
+ "@popover-fallback-border-color": "#ccc",
230
+ "@popover-title-bg": "darken(@popover-bg, 3%)",
231
+ "@popover-arrow-width": "10px",
232
+ "@popover-arrow-color": "#fff",
233
+ "@popover-arrow-outer-width": "(@popover-arrow-width + 1)",
234
+ "@popover-arrow-outer-color": "fadein(@popover-border-color, 5%)",
235
+ "@popover-arrow-outer-fallback-color": "darken(@popover-fallback-border-color, 20%)",
236
+ "@label-default-bg": "@gray-light",
237
+ "@label-primary-bg": "@brand-primary",
238
+ "@label-success-bg": "@brand-success",
239
+ "@label-info-bg": "@brand-info",
240
+ "@label-warning-bg": "@brand-warning",
241
+ "@label-danger-bg": "@brand-danger",
242
+ "@label-color": "#fff",
243
+ "@label-link-hover-color": "#fff",
244
+ "@modal-inner-padding": "20px",
245
+ "@modal-title-padding": "15px",
246
+ "@modal-title-line-height": "@line-height-base",
247
+ "@modal-content-bg": "#fff",
248
+ "@modal-content-border-color": "rgba(0,0,0,.2)",
249
+ "@modal-content-fallback-border-color": "#999",
250
+ "@modal-backdrop-bg": "#000",
251
+ "@modal-backdrop-opacity": ".5",
252
+ "@modal-header-border-color": "#e5e5e5",
253
+ "@modal-footer-border-color": "@modal-header-border-color",
254
+ "@modal-lg": "900px",
255
+ "@modal-md": "600px",
256
+ "@modal-sm": "300px",
257
+ "@alert-padding": "15px",
258
+ "@alert-border-radius": "@border-radius-base",
259
+ "@alert-link-font-weight": "bold",
260
+ "@alert-success-bg": "@state-success-bg",
261
+ "@alert-success-text": "@state-success-text",
262
+ "@alert-success-border": "@state-success-border",
263
+ "@alert-info-bg": "@state-info-bg",
264
+ "@alert-info-text": "@state-info-text",
265
+ "@alert-info-border": "@state-info-border",
266
+ "@alert-warning-bg": "@state-warning-bg",
267
+ "@alert-warning-text": "@state-warning-text",
268
+ "@alert-warning-border": "@state-warning-border",
269
+ "@alert-danger-bg": "@state-danger-bg",
270
+ "@alert-danger-text": "@state-danger-text",
271
+ "@alert-danger-border": "@state-danger-border",
272
+ "@progress-bg": "#f5f5f5",
273
+ "@progress-bar-color": "#fff",
274
+ "@progress-bar-bg": "@brand-primary",
275
+ "@progress-bar-success-bg": "@brand-success",
276
+ "@progress-bar-warning-bg": "@brand-warning",
277
+ "@progress-bar-danger-bg": "@brand-danger",
278
+ "@progress-bar-info-bg": "@brand-info",
279
+ "@list-group-bg": "#fff",
280
+ "@list-group-border": "#ddd",
281
+ "@list-group-border-radius": "@border-radius-base",
282
+ "@list-group-hover-bg": "#f5f5f5",
283
+ "@list-group-active-color": "@component-active-color",
284
+ "@list-group-active-bg": "@component-active-bg",
285
+ "@list-group-active-border": "@list-group-active-bg",
286
+ "@list-group-active-text-color": "lighten(@list-group-active-bg, 40%)",
287
+ "@list-group-link-color": "#555",
288
+ "@list-group-link-heading-color": "#333",
289
+ "@panel-bg": "#fff",
290
+ "@panel-body-padding": "15px",
291
+ "@panel-border-radius": "@border-radius-base",
292
+ "@panel-inner-border": "#ddd",
293
+ "@panel-footer-bg": "#f5f5f5",
294
+ "@panel-default-text": "@gray-dark",
295
+ "@panel-default-border": "#ddd",
296
+ "@panel-default-heading-bg": "#f5f5f5",
297
+ "@panel-primary-text": "#fff",
298
+ "@panel-primary-border": "@brand-primary",
299
+ "@panel-primary-heading-bg": "@brand-primary",
300
+ "@panel-success-text": "@state-success-text",
301
+ "@panel-success-border": "@state-success-border",
302
+ "@panel-success-heading-bg": "@state-success-bg",
303
+ "@panel-info-text": "@state-info-text",
304
+ "@panel-info-border": "@state-info-border",
305
+ "@panel-info-heading-bg": "@state-info-bg",
306
+ "@panel-warning-text": "@state-warning-text",
307
+ "@panel-warning-border": "@state-warning-border",
308
+ "@panel-warning-heading-bg": "@state-warning-bg",
309
+ "@panel-danger-text": "@state-danger-text",
310
+ "@panel-danger-border": "@state-danger-border",
311
+ "@panel-danger-heading-bg": "@state-danger-bg",
312
+ "@thumbnail-padding": "4px",
313
+ "@thumbnail-bg": "@body-bg",
314
+ "@thumbnail-border": "#ddd",
315
+ "@thumbnail-border-radius": "@border-radius-base",
316
+ "@thumbnail-caption-color": "@text-color",
317
+ "@thumbnail-caption-padding": "9px",
318
+ "@well-bg": "#f5f5f5",
319
+ "@well-border": "darken(@well-bg, 7%)",
320
+ "@badge-color": "#fff",
321
+ "@badge-link-hover-color": "#fff",
322
+ "@badge-bg": "@gray-light",
323
+ "@badge-active-color": "@link-color",
324
+ "@badge-active-bg": "#fff",
325
+ "@badge-font-weight": "bold",
326
+ "@badge-border-radius": "10px",
327
+ "@breadcrumb-padding-vertical": "8px",
328
+ "@breadcrumb-padding-horizontal": "15px",
329
+ "@breadcrumb-bg": "#f5f5f5",
330
+ "@breadcrumb-color": "#ccc",
331
+ "@breadcrumb-active-color": "@gray-light",
332
+ "@breadcrumb-separator": "\"/\"",
333
+ "@carousel-text-shadow": "0 1px 2px rgba(0,0,0,.6)",
334
+ "@carousel-control-color": "#fff",
335
+ "@carousel-control-width": "15%",
336
+ "@carousel-control-opacity": ".5",
337
+ "@carousel-control-font-size": "20px",
338
+ "@carousel-indicator-active-bg": "#fff",
339
+ "@carousel-indicator-border-color": "#fff",
340
+ "@carousel-caption-color": "#fff",
341
+ "@close-font-weight": "bold",
342
+ "@close-color": "#000",
343
+ "@close-text-shadow": "0 1px 0 #fff",
344
+ "@code-color": "#c7254e",
345
+ "@code-bg": "#f9f2f4",
346
+ "@kbd-color": "#fff",
347
+ "@kbd-bg": "#333",
348
+ "@pre-bg": "#f5f5f5",
349
+ "@pre-color": "@gray-dark",
350
+ "@pre-border-color": "#ccc",
351
+ "@pre-scrollable-max-height": "340px",
352
+ "@text-muted": "@gray-light",
353
+ "@abbr-border-color": "@gray-light",
354
+ "@headings-small-color": "@gray-light",
355
+ "@blockquote-small-color": "@gray-light",
356
+ "@blockquote-font-size": "(@font-size-base * 1.25)",
357
+ "@blockquote-border-color": "@gray-lighter",
358
+ "@page-header-border-color": "@gray-lighter",
359
+ "@hr-border": "@gray-lighter",
360
+ "@component-offset-horizontal": "180px"
361
+ },
362
+ "css": [
363
+ "print.less",
364
+ "type.less",
365
+ "code.less",
366
+ "grid.less",
367
+ "tables.less",
368
+ "forms.less",
369
+ "buttons.less",
370
+ "glyphicons.less",
371
+ "button-groups.less",
372
+ "input-groups.less",
373
+ "navs.less",
374
+ "navbar.less",
375
+ "breadcrumbs.less",
376
+ "pagination.less",
377
+ "pager.less",
378
+ "labels.less",
379
+ "badges.less",
380
+ "jumbotron.less",
381
+ "thumbnails.less",
382
+ "alerts.less",
383
+ "progress-bars.less",
384
+ "media.less",
385
+ "list-group.less",
386
+ "panels.less",
387
+ "wells.less",
388
+ "close.less",
389
+ "component-animations.less",
390
+ "dropdowns.less",
391
+ "tooltip.less",
392
+ "popovers.less",
393
+ "modals.less",
394
+ "carousel.less",
395
+ "utilities.less",
396
+ "responsive-utilities.less"
397
+ ],
398
+ "js": [
399
+ "alert.js",
400
+ "button.js",
401
+ "carousel.js",
402
+ "dropdown.js",
403
+ "modal.js",
404
+ "tooltip.js",
405
+ "popover.js",
406
+ "tab.js",
407
+ "affix.js",
408
+ "collapse.js",
409
+ "scrollspy.js",
410
+ "transition.js"
411
+ ]
412
+ }