stickler 2.2.4 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. data/CONTRIBUTING.md +48 -0
  2. data/{HISTORY.asciidoc → HISTORY.md} +8 -2
  3. data/Manifest.txt +86 -0
  4. data/{README.asciidoc → README.rdoc} +18 -20
  5. data/Rakefile +25 -59
  6. data/bin/stickler +10 -3
  7. data/examples/gemcutter_repo.ru +1 -2
  8. data/lib/stickler.rb +6 -2
  9. data/lib/stickler/client.rb +5 -4
  10. data/lib/stickler/client/delete.rb +50 -0
  11. data/lib/stickler/client/unyank.rb +50 -0
  12. data/lib/stickler/middleware.rb +7 -0
  13. data/lib/stickler/middleware/compression.rb +0 -2
  14. data/lib/stickler/middleware/gemcutter.rb +16 -7
  15. data/lib/stickler/middleware/helpers.rb +1 -3
  16. data/lib/stickler/middleware/index.rb +0 -8
  17. data/lib/stickler/middleware/local.rb +1 -5
  18. data/lib/stickler/middleware/mirror.rb +0 -4
  19. data/lib/stickler/middleware/not_found.rb +0 -1
  20. data/lib/stickler/repository.rb +9 -5
  21. data/lib/stickler/repository/index.rb +0 -1
  22. data/lib/stickler/repository/local.rb +12 -4
  23. data/lib/stickler/repository/null.rb +0 -1
  24. data/lib/stickler/repository/remote.rb +40 -20
  25. data/lib/stickler/repository/remote_mirror.rb +1 -1
  26. data/lib/stickler/server.rb +1 -9
  27. data/lib/stickler/server/public/css/blueprint/ie.css +35 -0
  28. data/lib/stickler/server/public/css/blueprint/screen.css +266 -0
  29. data/lib/stickler/server/public/css/style.css +19 -0
  30. data/man/stickler-passenger-config.1 +83 -0
  31. data/man/stickler-passenger-config.1.ronn +70 -0
  32. data/man/stickler-server.1 +168 -0
  33. data/man/stickler-server.1.ronn +84 -0
  34. data/man/stickler.1 +321 -0
  35. data/man/stickler.1.ronn +144 -0
  36. data/spec/data/gemcutter/gems/foo-1.0.0.gem +0 -0
  37. data/spec/middleware/local_spec.rb +1 -4
  38. data/spec/middleware/not_found_spec.rb +1 -2
  39. data/spec/paths_spec.rb +1 -3
  40. data/spec/repository/api_behavior.rb +34 -4
  41. data/spec/repository/api_spec.rb +2 -3
  42. data/spec/repository/index_spec.rb +10 -11
  43. data/spec/repository/local_spec.rb +10 -12
  44. data/spec/repository/null_spec.rb +2 -5
  45. data/spec/repository/remote_spec.rb +3 -5
  46. data/spec/spec_helper.rb +7 -2
  47. data/spec/spec_lite_spec.rb +1 -3
  48. data/tasks/default.rake +274 -0
  49. data/tasks/this.rb +209 -0
  50. metadata +142 -85
  51. data/.bnsignore +0 -14
  52. data/.gitignore +0 -23
  53. data/TODO.asciidoc +0 -6
  54. data/lib/stickler/version.rb +0 -36
  55. data/man/asciidoc.conf +0 -25
  56. data/man/stickler-passenger-config.asciidoc +0 -74
  57. data/man/stickler-server.asciidoc +0 -87
  58. data/man/stickler.asciidoc +0 -150
  59. data/tasks/asciidoc.rake +0 -32
  60. data/tasks/bundler.rake +0 -13
  61. data/tasks/contribute.rake +0 -36
  62. data/tasks/man.rake +0 -19
@@ -0,0 +1,50 @@
1
+ module Stickler
2
+ class Client
3
+ class Unyank < Stickler::Client
4
+ def self.banner
5
+ <<-_
6
+ Restore a yanked gem to the gemserver's index.
7
+
8
+ Usage: stickler unyank [options] --gem-version x.y.z gem
9
+
10
+ Options:
11
+ _
12
+ end
13
+
14
+ def parser
15
+ unless @parser then
16
+ @parser = super
17
+ @parser.opt( :gem_version, "The version of the gem to unyank (required)", :type => :string, :required => true )
18
+ @parser.opt( :platform, "The platform of the gem to unyank", :type => :string, :default => ::Gem::Platform::RUBY )
19
+ end
20
+ return @parser
21
+ end
22
+
23
+ def parse( argv )
24
+ gem_name = nil
25
+ opts = super( argv ) do |p|
26
+ raise Trollop::CommandlineError, "At least one gem is required to unyank" if p.leftovers.empty?
27
+ gem_name = p.leftovers.shift
28
+ end
29
+ opts[:gem_name] = gem_name
30
+ return opts
31
+ end
32
+
33
+ def run
34
+ opts = parse( self.argv )
35
+ repo = remote_repo_for( opts )
36
+ spec = Stickler::SpecLite.new( opts[:gem_name], opts[:gem_version], opts[:platform] )
37
+
38
+ $stdout.write "Unyanking gem #{spec.full_name} from #{repo.uri} : "
39
+ $stdout.flush
40
+ if spec = repo.unyank( spec ) then
41
+ $stdout.puts "OK"
42
+ else
43
+ $stdout.puts "FAILURE"
44
+ end
45
+ rescue Stickler::Repository::Error => e
46
+ $stdout.puts "ERROR: #{e.message}"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -2,3 +2,10 @@ module Stickler
2
2
  module Middleware
3
3
  end
4
4
  end
5
+ require 'stickler/middleware/helpers'
6
+ require 'stickler/middleware/compression'
7
+ require 'stickler/middleware/gemcutter'
8
+ require 'stickler/middleware/index'
9
+ require 'stickler/middleware/local'
10
+ require 'stickler/middleware/mirror'
11
+ require 'stickler/middleware/not_found'
@@ -1,5 +1,3 @@
1
- require 'rack/utils'
2
- require 'stickler/middleware'
3
1
  module Stickler::Middleware
4
2
  class Compression
5
3
  def initialize( app )
@@ -1,8 +1,4 @@
1
- require 'sinatra/base'
2
- require 'stickler/middleware'
3
1
  require 'stickler/middleware/local'
4
- require 'stickler/repository/local'
5
-
6
2
  module Stickler::Middleware
7
3
  #
8
4
  # A rack middleware for implementing the gemcutter api
@@ -41,10 +37,23 @@ module Stickler::Middleware
41
37
  end
42
38
  end
43
39
 
40
+ # gemcutter unyank
41
+ post '/api/v1/gems/unyank' do
42
+ begin
43
+ spec = Stickler::SpecLite.new( params[:spec_name], params[:version] )
44
+ @repo.unyank( spec )
45
+ logger.info( "Unyanked #{spec.full_name}" )
46
+ return spec.to_s
47
+ rescue Stickler::Repository::Error => e
48
+ logger.error( "Error unyanking #{spec.full_name} to repo : #{e}" )
49
+ error( 500, "Error unyanking gem to repo: #{e}" )
50
+ end
51
+ end
52
+
44
53
  # gemcutter yank
45
54
  delete '/api/v1/gems/yank' do
46
55
  spec = Stickler::SpecLite.new( params[:gem_name], params[:version] )
47
- if s = @repo.yank( spec ) then
56
+ if @repo.yank( spec ) then
48
57
  logger.info( "Yanked #{spec.full_name}" )
49
58
  return "Yanked #{spec.full_name}"
50
59
  else
@@ -54,8 +63,8 @@ module Stickler::Middleware
54
63
  end
55
64
 
56
65
  # direct delete
57
- delete %r{\A/gems/((.*?)-([0-9.]+)(-.*?)?)\.gem\Z} do
58
- full_name, name, version, platform = *params[:captures]
66
+ delete %r{\A/gems/#{NAME_VERSION_PLATFORM_REGEX}\.gem\Z} do
67
+ name, version, platform = *params[:captures]
59
68
  spec = Stickler::SpecLite.new( name, version, platform )
60
69
  @repo.delete( spec )
61
70
  logger.info( "Deleted #{spec.full_name}" )
@@ -1,5 +1,3 @@
1
- require 'stickler/middleware'
2
- require 'stickler/repository/local'
3
1
  module Stickler::Middleware
4
2
  module Helpers
5
3
  #
@@ -106,6 +104,6 @@ module Stickler::Middleware
106
104
  end
107
105
  return by_name
108
106
  end
109
- end
107
+ end
110
108
  end
111
109
  end
@@ -1,11 +1,3 @@
1
- require 'sinatra'
2
- require 'stickler/middleware'
3
- require 'stickler/middleware/helpers'
4
- require 'stickler/repository/null'
5
- require 'stickler/spec_lite'
6
- require 'stickler/logable'
7
- require 'stickler/paths'
8
-
9
1
  module Stickler::Middleware
10
2
  # Index is a Rack middleware that passes all requests through except for the
11
3
  # following urls:
@@ -1,8 +1,4 @@
1
- require 'sinatra'
2
- require 'stickler/middleware'
3
1
  require 'stickler/middleware/index'
4
- require 'stickler/repository/local'
5
-
6
2
  module Stickler::Middleware
7
3
  #
8
4
  # A Sinatra middleware that implements the HTTP portions of a Modern gem server.
@@ -27,7 +23,7 @@ module Stickler::Middleware
27
23
  # use Stickler::Middleware::Local, :repo_root => '/path/to/repository',
28
24
  # :serve_indexes => true
29
25
  #
30
- class Local < Index
26
+ class Local < ::Stickler::Middleware::Index
31
27
  def initialize( app = nil, opts = {} )
32
28
  super( app, opts )
33
29
  # overwrite the repo that is set in the parent
@@ -1,7 +1,3 @@
1
- require 'sinatra/base'
2
- require 'stickler/middleware/index'
3
- require 'stickler/repository/mirror'
4
-
5
1
  module Stickler::Middleware
6
2
  #
7
3
  # A Mirror server keeps gems from one or more upstream gem servers in local
@@ -1,4 +1,3 @@
1
- require 'stickler/middleware'
2
1
  module Stickler::Middleware
3
2
  #
4
3
  # Idea completely taken from rack-contrib, it can function as a middleware
@@ -1,10 +1,14 @@
1
- require 'stickler/error'
2
- require 'rubygems/format'
3
- require 'rubygems/platform'
4
- require 'rubygems/dependency'
5
-
6
1
  module Stickler
7
2
  module Repository
8
3
  class Error < ::Stickler::Error ; end
9
4
  end
10
5
  end
6
+ require 'stickler/repository/api'
7
+ require 'stickler/repository/basic_authenticator'
8
+ require 'stickler/repository/index'
9
+ require 'stickler/repository/local'
10
+ require 'stickler/repository/mirror'
11
+ require 'stickler/repository/null'
12
+ require 'stickler/repository/remote'
13
+ require 'stickler/repository/remote_mirror'
14
+ require 'stickler/repository/rubygems_authenticator'
@@ -1,5 +1,4 @@
1
1
  require 'stickler/spec_lite'
2
- require 'stickler/repository'
3
2
 
4
3
  module Stickler::Repository
5
4
  #
@@ -1,10 +1,8 @@
1
- require 'stickler/spec_lite'
2
- require 'stickler/logable'
3
- require 'stickler/repository'
4
1
  require 'stickler/repository/index'
5
2
  require 'addressable/uri'
6
3
  require 'tempfile'
7
4
  require 'forwardable'
5
+ require 'rubygems/format'
8
6
 
9
7
  module Stickler::Repository
10
8
  #
@@ -162,6 +160,15 @@ module Stickler::Repository
162
160
  return uri_for_gem( spec )
163
161
  end
164
162
 
163
+ #
164
+ # See Api#unyank
165
+ #
166
+ def unyank( spec )
167
+ return nil if specification_file_exist?( spec )
168
+ return nil unless gem_file_exist?( spec )
169
+ install_specification( spec )
170
+ end
171
+
165
172
 
166
173
  #
167
174
  # :call-seq:
@@ -194,7 +201,8 @@ module Stickler::Repository
194
201
  # See Api#push
195
202
  #
196
203
  def push( path )
197
- spec = specification_from_gem_file( path )
204
+ # is this line needed? Never used.
205
+ # spec = specification_from_gem_file( path )
198
206
  result = nil
199
207
  File.open( path ) do |io|
200
208
  result = add( io )
@@ -1,4 +1,3 @@
1
- require 'stickler/repository'
2
1
  module Stickler::Repository
3
2
  #
4
3
  # A null repository. It is in most respecs like a Repository::Local that has
@@ -1,6 +1,4 @@
1
1
  require 'excon'
2
- require 'stickler/version'
3
- require 'stickler/repository'
4
2
  require 'stickler/repository/api'
5
3
  require 'stickler/repository/rubygems_authenticator'
6
4
  require 'stickler/repository/basic_authenticator'
@@ -76,7 +74,7 @@ module ::Stickler::Repository
76
74
  def push( path )
77
75
  spec = speclite_from_gem_file( path )
78
76
  raise Stickler::Repository::Error, "gem #{spec.full_name} already exists in remote repository" if remote_gem_file_exist?( spec )
79
- resp = resource_request( push_resource, :body => IO.read( path ) )
77
+ resource_request( push_resource, :body => IO.read( path ) )
80
78
  return spec
81
79
  rescue Excon::Errors::Error => e
82
80
  msg = "Failure pushing #{path} to remote repository : response code => #{e.response.status}, response message => '#{e.response.body}'"
@@ -89,12 +87,24 @@ module ::Stickler::Repository
89
87
  def yank( spec )
90
88
  return nil unless remote_gem_file_exist?( spec )
91
89
  query = { :gem_name => spec.name, :version => spec.version.to_s }
92
- resp = resource_request( yank_resource, :query => query )
90
+ resource_request( yank_resource, :query => query )
93
91
  return full_uri_to_gem( spec )
94
92
  rescue Excon::Errors::Error => e
95
93
  raise Stickler::Repository::Error, "Failure yanking: #{e.inspect}"
96
94
  end
97
95
 
96
+ #
97
+ # See Api#unyank
98
+ #
99
+ def unyank( spec )
100
+ return nil unless remote_gem_file_exist?( spec )
101
+ query = { :spec_name => spec.name, :version => spec.version.to_s }
102
+ resource_request( unyank_resource, :query => query )
103
+ true
104
+ rescue Excon::Errors::Error => e
105
+ raise Stickler::Repository::Error, "Failure unyanking: #{e.inspect}"
106
+ end
107
+
98
108
  #
99
109
  # See Api#delete
100
110
  #
@@ -102,7 +112,7 @@ module ::Stickler::Repository
102
112
  return false unless remote_gem_file_exist?( spec )
103
113
  resource_request( gem_resource( spec ), :method => :delete )
104
114
  return true
105
- rescue Excon::Errors::Error => e
115
+ rescue Excon::Errors::Error
106
116
  return false
107
117
  end
108
118
 
@@ -168,25 +178,36 @@ module ::Stickler::Repository
168
178
  end
169
179
 
170
180
  def push_resource
171
- unless @push_resource then
181
+ @push_resource ||= begin
172
182
  params = { :method => :post, :headers => { 'Content-Type' => 'application/octet-stream' }, :expects => [ 201, 200 ] }
173
- @push_resource = Excon.new( push_uri.to_s, params )
183
+ Excon.new( push_uri.to_s, params )
174
184
  end
175
- return @push_resource
176
185
  end
177
186
 
178
187
  def yank_uri
179
188
  Addressable::URI.join( uri, "api/v1/gems/yank" )
180
189
  end
181
190
 
191
+ def unyank_uri
192
+ Addressable::URI.join( uri, "api/v1/gems/unyank" )
193
+ end
194
+
182
195
  def yank_resource
183
- unless @yank_resource then
196
+ @yank_resource ||= begin
184
197
  params = { :method => :delete,
185
198
  :headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
186
199
  :expects => [200] }
187
- @yank_resource = Excon.new( yank_uri.to_s, params )
200
+ Excon.new( yank_uri.to_s, params )
201
+ end
202
+ end
203
+
204
+ def unyank_resource
205
+ @unyank_resource ||= begin
206
+ params = { :method => :post,
207
+ :headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
208
+ :expects => [200] }
209
+ Excon.new( unyank_uri.to_s, params )
188
210
  end
189
- return @yank_resource
190
211
  end
191
212
 
192
213
  def gem_resource( spec )
@@ -222,9 +243,9 @@ module ::Stickler::Repository
222
243
  end
223
244
 
224
245
  def remote_uri_exist?( uri )
225
- rc = resource_request( Excon.new( uri.to_s ), :method => :head, :expects => [200] )
246
+ resource_request( Excon.new( uri.to_s ), :method => :head, :expects => [200] )
226
247
  return true
227
- rescue Excon::Errors::Error => e
248
+ rescue Excon::Errors::Error
228
249
  return false
229
250
  end
230
251
 
@@ -244,10 +265,10 @@ module ::Stickler::Repository
244
265
  def resource_request( resource, params = {} )
245
266
  trys = 0
246
267
  begin
247
- resource.connection[:headers]['User-Agent'] = "Stickler Client v#{Stickler::VERSION}"
248
- resource.connection[:headers].delete('Authorization')
268
+ resource.data[:headers]['User-Agent'] = "Stickler Client v#{Stickler::VERSION}"
269
+ resource.data[:headers].delete('Authorization')
249
270
  if authenticator then
250
- resource.connection[:headers]['Authorization'] = authenticator.credentials
271
+ resource.data[:headers]['Authorization'] = authenticator.credentials
251
272
  end
252
273
  trys += 1
253
274
  resource.request( params )
@@ -260,10 +281,9 @@ module ::Stickler::Repository
260
281
  # HEAD request. Only follow a few times though.
261
282
  raise redirect unless [ :get, :head ].include?( redirect.request[:method] )
262
283
  raise redirect if trys > 5
263
- resource = Excon::Connection.new( redirect.response.headers['Location'],
264
- { :headers => resource.connection[:headers],
265
- :query => resource.connection[:headers],
266
- :method => resource.connection[:method] } )
284
+ resource = Excon.new( redirect.response.headers['Location'],
285
+ { :headers => resource.data[:headers],
286
+ :method => resource.data[:method] } )
267
287
  retry
268
288
  end
269
289
  end
@@ -13,7 +13,7 @@ module ::Stickler::Repository
13
13
  # repository
14
14
  def mirror( spec, upstream_host )
15
15
  raise Stickler::Repository::Error, "gem #{spec.full_name} already exists in remote repository" if remote_gem_file_exist?( spec )
16
- resp = resource_request( mirror_resource( spec, upstream_host ) )
16
+ resource_request( mirror_resource( spec, upstream_host ) )
17
17
  end
18
18
 
19
19
  private
@@ -1,11 +1,3 @@
1
- require 'stickler/error'
2
- require 'stickler/middleware/compression'
3
- require 'stickler/middleware/gemcutter'
4
- require 'stickler/middleware/mirror'
5
- require 'stickler/middleware/index'
6
- require 'stickler/middleware/not_found'
7
- require 'rack/commonlogger'
8
-
9
1
  module Stickler
10
2
  class Server
11
3
 
@@ -30,5 +22,5 @@ module Stickler
30
22
  run Sinatra::Base
31
23
  end
32
24
  end
33
- end
25
+ end
34
26
  end
@@ -0,0 +1,35 @@
1
+ /* -----------------------------------------------------------------------
2
+
3
+
4
+ Blueprint CSS Framework 0.9
5
+ http://blueprintcss.org
6
+
7
+ * Copyright (c) 2007-Present. See LICENSE for more info.
8
+ * See README for instructions on how to use Blueprint.
9
+ * For credits and origins, see AUTHORS.
10
+ * This is a compressed file. See the sources in the 'src' directory.
11
+
12
+ ----------------------------------------------------------------------- */
13
+
14
+ /* ie.css */
15
+ body {text-align:center;}
16
+ .container {text-align:left;}
17
+ * html .column, * html .span-1, * html .span-2, * html .span-3, * html .span-4, * html .span-5, * html .span-6, * html .span-7, * html .span-8, * html .span-9, * html .span-10, * html .span-11, * html .span-12, * html .span-13, * html .span-14, * html .span-15, * html .span-16, * html .span-17, * html .span-18, * html .span-19, * html .span-20, * html .span-21, * html .span-22, * html .span-23, * html .span-24 {display:inline;overflow-x:hidden;}
18
+ * html legend {margin:0px -8px 16px 0;padding:0;}
19
+ sup {vertical-align:text-top;}
20
+ sub {vertical-align:text-bottom;}
21
+ html>body p code {*white-space:normal;}
22
+ hr {margin:-8px auto 11px;}
23
+ img {-ms-interpolation-mode:bicubic;}
24
+ .clearfix, .container {display:inline-block;}
25
+ * html .clearfix, * html .container {height:1%;}
26
+ fieldset {padding-top:0;}
27
+ textarea {overflow:auto;}
28
+ input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;}
29
+ input.text:focus, input.title:focus {border-color:#666;}
30
+ input.text, input.title, textarea, select {margin:0.5em 0;}
31
+ input.checkbox, input.radio {position:relative;top:.25em;}
32
+ form.inline div, form.inline p {vertical-align:middle;}
33
+ form.inline label {position:relative;top:-0.25em;}
34
+ form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;}
35
+ button, input.button {position:relative;top:0.25em;}
@@ -0,0 +1,266 @@
1
+ /* -----------------------------------------------------------------------
2
+
3
+
4
+ Blueprint CSS Framework 0.9
5
+ http://blueprintcss.org
6
+
7
+ * Copyright (c) 2007-Present. See LICENSE for more info.
8
+ * See README for instructions on how to use Blueprint.
9
+ * For credits and origins, see AUTHORS.
10
+ * This is a compressed file. See the sources in the 'src' directory.
11
+
12
+ ----------------------------------------------------------------------- */
13
+
14
+ /* reset.css */
15
+ html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, dialog, figure, footer, header, hgroup, nav, section {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
16
+ article, aside, dialog, figure, footer, header, hgroup, nav, section {display:block;}
17
+ body {line-height:1.5;}
18
+ table {border-collapse:separate;border-spacing:0;}
19
+ caption, th, td {text-align:left;font-weight:normal;}
20
+ table, td, th {vertical-align:middle;}
21
+ blockquote:before, blockquote:after, q:before, q:after {content:"";}
22
+ blockquote, q {quotes:"" "";}
23
+ a img {border:none;}
24
+
25
+ /* typography.css */
26
+ html {font-size:100.01%;}
27
+ body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}
28
+ h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
29
+ h1 {font-size:3em;line-height:1;margin-bottom:0.5em;}
30
+ h2 {font-size:2em;margin-bottom:0.75em;}
31
+ h3 {font-size:1.5em;line-height:1;margin-bottom:1em;}
32
+ h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;}
33
+ h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
34
+ h6 {font-size:1em;font-weight:bold;}
35
+ h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
36
+ p {margin:0 0 1.5em;}
37
+ p img.left {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;}
38
+ p img.right {float:right;margin:1.5em 0 1.5em 1.5em;}
39
+ a:focus, a:hover {color:#08d;}
40
+ a {color:#009;text-decoration:underline;}
41
+ blockquote {margin:1.5em;color:#666;font-style:italic;}
42
+ strong {font-weight:bold;}
43
+ em, dfn {font-style:italic;}
44
+ dfn {font-weight:bold;}
45
+ sup, sub {line-height:0;}
46
+ abbr, acronym {border-bottom:1px dotted #666;}
47
+ address {margin:0 0 1.5em;font-style:italic;}
48
+ del {color:#666;}
49
+ pre {margin:1.5em 0;white-space:pre;}
50
+ pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;}
51
+ li ul, li ol {margin:0;}
52
+ ul, ol {margin:0 1.5em 1.5em 0;padding-left:3.333em;}
53
+ ul {list-style-type:disc;}
54
+ ol {list-style-type:decimal;}
55
+ dl {margin:0 0 1.5em 0;}
56
+ dl dt {font-weight:bold;}
57
+ dd {margin-left:1.5em;}
58
+ table {margin-bottom:1.4em;width:100%;}
59
+ th {font-weight:bold;}
60
+ thead th {background:#c3d9ff;}
61
+ th, td, caption {padding:4px 10px 4px 5px;}
62
+ tr.even td {background:#e5ecf9;}
63
+ tfoot {font-style:italic;}
64
+ caption {background:#eee;}
65
+ .small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;}
66
+ .large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;}
67
+ .hide {display:none;}
68
+ .quiet {color:#666;}
69
+ .loud {color:#000;}
70
+ .highlight {background:#ff0;}
71
+ .added {background:#060;color:#fff;}
72
+ .removed {background:#900;color:#fff;}
73
+ .first {margin-left:0;padding-left:0;}
74
+ .last {margin-right:0;padding-right:0;}
75
+ .top {margin-top:0;padding-top:0;}
76
+ .bottom {margin-bottom:0;padding-bottom:0;}
77
+
78
+ /* forms.css */
79
+ label {font-weight:bold;}
80
+ fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;}
81
+ legend {font-weight:bold;font-size:1.2em;}
82
+ input[type=text], input[type=password], input.text, input.title, textarea, select {background-color:#fff;border:1px solid #bbb;}
83
+ input[type=text]:focus, input[type=password]:focus, input.text:focus, input.title:focus, textarea:focus, select:focus {border-color:#666;}
84
+ input[type=text], input[type=password], input.text, input.title, textarea, select {margin:0.5em 0;}
85
+ input.text, input.title {width:300px;padding:5px;}
86
+ input.title {font-size:1.5em;}
87
+ textarea {width:390px;height:250px;padding:5px;}
88
+ input[type=checkbox], input[type=radio], input.checkbox, input.radio {position:relative;top:.25em;}
89
+ form.inline {line-height:3;}
90
+ form.inline p {margin-bottom:0;}
91
+ .error, .notice, .success, .info {padding:0.8em;margin-bottom:1em;border:2px solid #ddd;}
92
+ .error {background:#fbe3e4;color:#8a1f11;border-color:#fbc2c4;}
93
+ .notice {background:#fff6bf;color:#514721;border-color:#ffd324;}
94
+ .success {background:#e6efc2;color:#264409;border-color:#c6d880;}
95
+ .info {background:#d5edf8;color:#205791;border-color:#92cae4;}
96
+ .error a {color:#8a1f11;}
97
+ .notice a {color:#514721;}
98
+ .success a {color:#264409;}
99
+ .info a {color:#205791;}
100
+
101
+ /* grid.css */
102
+ .container {width:740px;margin:0 auto;}
103
+ .showgrid {background:url(src/grid.png);}
104
+ .column, .span-1, .span-2, .span-3, .span-4, .span-5, .span-6, .span-7, .span-8, .span-9, .span-10, .span-11, .span-12, .span-13, .span-14, .span-15, .span-16, .span-17, .span-18, .span-19, .span-20, .span-21, .span-22, .span-23, .span-24, .span-25 {float:left;margin-right:10px;}
105
+ .last {margin-right:0;}
106
+ .span-1 {width:20px;}
107
+ .span-2 {width:50px;}
108
+ .span-3 {width:80px;}
109
+ .span-4 {width:110px;}
110
+ .span-5 {width:140px;}
111
+ .span-6 {width:170px;}
112
+ .span-7 {width:200px;}
113
+ .span-8 {width:230px;}
114
+ .span-9 {width:260px;}
115
+ .span-10 {width:290px;}
116
+ .span-11 {width:320px;}
117
+ .span-12 {width:350px;}
118
+ .span-13 {width:380px;}
119
+ .span-14 {width:410px;}
120
+ .span-15 {width:440px;}
121
+ .span-16 {width:470px;}
122
+ .span-17 {width:500px;}
123
+ .span-18 {width:530px;}
124
+ .span-19 {width:560px;}
125
+ .span-20 {width:590px;}
126
+ .span-21 {width:620px;}
127
+ .span-22 {width:650px;}
128
+ .span-23 {width:680px;}
129
+ .span-24 {width:710px;}
130
+ .span-25 {width:740px;margin-right:0;}
131
+ input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12, input.span-13, textarea.span-13, input.span-14, textarea.span-14, input.span-15, textarea.span-15, input.span-16, textarea.span-16, input.span-17, textarea.span-17, input.span-18, textarea.span-18, input.span-19, textarea.span-19, input.span-20, textarea.span-20, input.span-21, textarea.span-21, input.span-22, textarea.span-22, input.span-23, textarea.span-23, input.span-24, textarea.span-24, input.span-25, textarea.span-25 {border-left-width:1px;border-right-width:1px;padding-left:5px;padding-right:5px;}
132
+ input.span-1, textarea.span-1 {width:8px;}
133
+ input.span-2, textarea.span-2 {width:38px;}
134
+ input.span-3, textarea.span-3 {width:68px;}
135
+ input.span-4, textarea.span-4 {width:98px;}
136
+ input.span-5, textarea.span-5 {width:128px;}
137
+ input.span-6, textarea.span-6 {width:158px;}
138
+ input.span-7, textarea.span-7 {width:188px;}
139
+ input.span-8, textarea.span-8 {width:218px;}
140
+ input.span-9, textarea.span-9 {width:248px;}
141
+ input.span-10, textarea.span-10 {width:278px;}
142
+ input.span-11, textarea.span-11 {width:308px;}
143
+ input.span-12, textarea.span-12 {width:338px;}
144
+ input.span-13, textarea.span-13 {width:368px;}
145
+ input.span-14, textarea.span-14 {width:398px;}
146
+ input.span-15, textarea.span-15 {width:428px;}
147
+ input.span-16, textarea.span-16 {width:458px;}
148
+ input.span-17, textarea.span-17 {width:488px;}
149
+ input.span-18, textarea.span-18 {width:518px;}
150
+ input.span-19, textarea.span-19 {width:548px;}
151
+ input.span-20, textarea.span-20 {width:578px;}
152
+ input.span-21, textarea.span-21 {width:608px;}
153
+ input.span-22, textarea.span-22 {width:638px;}
154
+ input.span-23, textarea.span-23 {width:668px;}
155
+ input.span-24, textarea.span-24 {width:698px;}
156
+ input.span-25, textarea.span-25 {width:728px;}
157
+ .append-1 {padding-right:30px;}
158
+ .append-2 {padding-right:60px;}
159
+ .append-3 {padding-right:90px;}
160
+ .append-4 {padding-right:120px;}
161
+ .append-5 {padding-right:150px;}
162
+ .append-6 {padding-right:180px;}
163
+ .append-7 {padding-right:210px;}
164
+ .append-8 {padding-right:240px;}
165
+ .append-9 {padding-right:270px;}
166
+ .append-10 {padding-right:300px;}
167
+ .append-11 {padding-right:330px;}
168
+ .append-12 {padding-right:360px;}
169
+ .append-13 {padding-right:390px;}
170
+ .append-14 {padding-right:420px;}
171
+ .append-15 {padding-right:450px;}
172
+ .append-16 {padding-right:480px;}
173
+ .append-17 {padding-right:510px;}
174
+ .append-18 {padding-right:540px;}
175
+ .append-19 {padding-right:570px;}
176
+ .append-20 {padding-right:600px;}
177
+ .append-21 {padding-right:630px;}
178
+ .append-22 {padding-right:660px;}
179
+ .append-23 {padding-right:690px;}
180
+ .append-24 {padding-right:720px;}
181
+ .prepend-1 {padding-left:30px;}
182
+ .prepend-2 {padding-left:60px;}
183
+ .prepend-3 {padding-left:90px;}
184
+ .prepend-4 {padding-left:120px;}
185
+ .prepend-5 {padding-left:150px;}
186
+ .prepend-6 {padding-left:180px;}
187
+ .prepend-7 {padding-left:210px;}
188
+ .prepend-8 {padding-left:240px;}
189
+ .prepend-9 {padding-left:270px;}
190
+ .prepend-10 {padding-left:300px;}
191
+ .prepend-11 {padding-left:330px;}
192
+ .prepend-12 {padding-left:360px;}
193
+ .prepend-13 {padding-left:390px;}
194
+ .prepend-14 {padding-left:420px;}
195
+ .prepend-15 {padding-left:450px;}
196
+ .prepend-16 {padding-left:480px;}
197
+ .prepend-17 {padding-left:510px;}
198
+ .prepend-18 {padding-left:540px;}
199
+ .prepend-19 {padding-left:570px;}
200
+ .prepend-20 {padding-left:600px;}
201
+ .prepend-21 {padding-left:630px;}
202
+ .prepend-22 {padding-left:660px;}
203
+ .prepend-23 {padding-left:690px;}
204
+ .prepend-24 {padding-left:720px;}
205
+ .border {padding-right:4px;margin-right:5px;border-right:1px solid #ddd;}
206
+ .colborder {padding-right:19px;margin-right:20px;border-right:1px solid #ddd;}
207
+ .pull-1 {margin-left:-30px;}
208
+ .pull-2 {margin-left:-60px;}
209
+ .pull-3 {margin-left:-90px;}
210
+ .pull-4 {margin-left:-120px;}
211
+ .pull-5 {margin-left:-150px;}
212
+ .pull-6 {margin-left:-180px;}
213
+ .pull-7 {margin-left:-210px;}
214
+ .pull-8 {margin-left:-240px;}
215
+ .pull-9 {margin-left:-270px;}
216
+ .pull-10 {margin-left:-300px;}
217
+ .pull-11 {margin-left:-330px;}
218
+ .pull-12 {margin-left:-360px;}
219
+ .pull-13 {margin-left:-390px;}
220
+ .pull-14 {margin-left:-420px;}
221
+ .pull-15 {margin-left:-450px;}
222
+ .pull-16 {margin-left:-480px;}
223
+ .pull-17 {margin-left:-510px;}
224
+ .pull-18 {margin-left:-540px;}
225
+ .pull-19 {margin-left:-570px;}
226
+ .pull-20 {margin-left:-600px;}
227
+ .pull-21 {margin-left:-630px;}
228
+ .pull-22 {margin-left:-660px;}
229
+ .pull-23 {margin-left:-690px;}
230
+ .pull-24 {margin-left:-720px;}
231
+ .pull-25 {margin-left:-750px;}
232
+ .pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24, .pull-25 {float:left;position:relative;}
233
+ .push-1 {margin:0 -30px 1.5em 30px;}
234
+ .push-2 {margin:0 -60px 1.5em 60px;}
235
+ .push-3 {margin:0 -90px 1.5em 90px;}
236
+ .push-4 {margin:0 -120px 1.5em 120px;}
237
+ .push-5 {margin:0 -150px 1.5em 150px;}
238
+ .push-6 {margin:0 -180px 1.5em 180px;}
239
+ .push-7 {margin:0 -210px 1.5em 210px;}
240
+ .push-8 {margin:0 -240px 1.5em 240px;}
241
+ .push-9 {margin:0 -270px 1.5em 270px;}
242
+ .push-10 {margin:0 -300px 1.5em 300px;}
243
+ .push-11 {margin:0 -330px 1.5em 330px;}
244
+ .push-12 {margin:0 -360px 1.5em 360px;}
245
+ .push-13 {margin:0 -390px 1.5em 390px;}
246
+ .push-14 {margin:0 -420px 1.5em 420px;}
247
+ .push-15 {margin:0 -450px 1.5em 450px;}
248
+ .push-16 {margin:0 -480px 1.5em 480px;}
249
+ .push-17 {margin:0 -510px 1.5em 510px;}
250
+ .push-18 {margin:0 -540px 1.5em 540px;}
251
+ .push-19 {margin:0 -570px 1.5em 570px;}
252
+ .push-20 {margin:0 -600px 1.5em 600px;}
253
+ .push-21 {margin:0 -630px 1.5em 630px;}
254
+ .push-22 {margin:0 -660px 1.5em 660px;}
255
+ .push-23 {margin:0 -690px 1.5em 690px;}
256
+ .push-24 {margin:0 -720px 1.5em 720px;}
257
+ .push-25 {margin:0 -750px 1.5em 750px;}
258
+ .push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24, .push-25 {float:right;position:relative;}
259
+ div.prepend-top, .prepend-top {margin-top:1.5em;}
260
+ div.append-bottom, .append-bottom {margin-bottom:1.5em;}
261
+ .box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;}
262
+ hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:1px;margin:0 0 1.45em;border:none;}
263
+ hr.space {background:#fff;color:#fff;visibility:hidden;}
264
+ .clearfix:after, .container:after {content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
265
+ .clearfix, .container {display:block;}
266
+ .clear {clear:both;}