josh-rack-cache 0.5.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.
@@ -0,0 +1,112 @@
1
+ Configuration
2
+ =============
3
+
4
+ __Rack::Cache__ includes a configuration system that can be used to specify
5
+ fairly sophisticated cache policy on a global or per-request basis.
6
+
7
+ <a id='setopt'></a>
8
+
9
+ Setting Cache Options
10
+ ---------------------
11
+
12
+ Cache options can be set when the __Rack::Cache__ object is created,
13
+ or by setting a `rack-cache.<option>` variable in __Rack__'s
14
+ __Environment__.
15
+
16
+ When the __Rack::Cache__ object is instantiated:
17
+
18
+ use Rack::Cache,
19
+ :verbose => true,
20
+ :metastore => 'memcached://localhost:11211/',
21
+ :entitystore => 'file:/var/cache/rack'
22
+
23
+ Using __Rack__'s __Environment__:
24
+
25
+ env.merge!(
26
+ 'rack-cache.verbose' => true,
27
+ 'rack-cache.metastore' => 'memcached://localhost:11211/',
28
+ 'rack-cache.entitystore' => 'file:/var/cache/rack'
29
+ )
30
+
31
+ <a id='options'></a>
32
+
33
+ Cache Option Reference
34
+ ----------------------
35
+
36
+ Use the following options to customize __Rack::Cache__:
37
+
38
+ ### `verbose`
39
+
40
+ Boolean specifying whether verbose trace logging is enabled. This option is
41
+ currently enabled (`true`) by default but is likely to be disabled (`false`) in
42
+ a future release. All log output is written to the `rack.errors` stream, which
43
+ is typically set to `STDERR`.
44
+
45
+ The `trace`, `info`, `warn`, and `error` methods can be used within the
46
+ configuration context to write messages to the errors stream.
47
+
48
+ ### `default_ttl`
49
+
50
+ An integer specifying the number of seconds a cached object should be considered
51
+ "fresh" when no explicit freshness information is provided in a response.
52
+ Explicit `Cache-Control` or `Expires` response headers always override this
53
+ value. The `default_ttl` option defaults to `0`, meaning responses without
54
+ explicit freshness information are considered immediately "stale" and will not
55
+ be served from cache without validation.
56
+
57
+ ### `metastore`
58
+
59
+ A URI specifying the __MetaStore__ implementation used to store request/response
60
+ meta information. See the [Rack::Cache Storage Documentation](storage.html)
61
+ for detailed information on different storage implementations.
62
+
63
+ If no metastore is specified, the `heap:/` store is assumed. This implementation
64
+ has significant draw-backs so explicit configuration is recommended.
65
+
66
+ ### `entitystore`
67
+
68
+ A URI specifying the __EntityStore__ implementation used to store
69
+ response bodies. See the [Rack::Cache Storage Documentation](storage.html)
70
+ for detailed information on different storage implementations.
71
+
72
+ If no entitystore is specified, the `heap:/` store is assumed. This
73
+ implementation has significant draw-backs so explicit configuration is
74
+ recommended.
75
+
76
+ ### `private_headers`
77
+
78
+ An array of request header names that cause the response to be treated with
79
+ private cache control semantics. The default value is `['Authorization', 'Cookie']`.
80
+ If any of these headers are present in the request, the response is considered
81
+ private and will not be cached _unless_ the response is explicitly marked public
82
+ (e.g., `Cache-Control: public`).
83
+
84
+ ### `allow_reload`
85
+
86
+ A boolean specifying whether reload requests sent by the client should be
87
+ honored by the cache. When this option is enabled (`rack-cache.allow_reload`
88
+ is `true`), requests that include a `Cache-Control: no-cache` header cause
89
+ the cache to discard anything it has stored for the request and ask that the
90
+ response be fully generated.
91
+
92
+ Most browsers include a `Cache-Control: no-cache` header when the user performs
93
+ a "hard refresh" (e.g., holding `Shift` while clicking the "Refresh" button).
94
+
95
+ *IMPORTANT: Enabling this option globally allows all clients to break your cache.*
96
+
97
+ ### `allow_revalidate`
98
+
99
+ A boolean specifying whether revalidate requests sent by the client should be
100
+ honored by the cache. When this option is enabled (`rack-cache.allow_revalidate`
101
+ is `true`), requests that include a `Cache-Control: max-age=0` header cause the
102
+ cache to assume its copy of the response is stale, resulting in a conditional
103
+ GET / validation request to be sent to the server.
104
+
105
+ Most browsers include a `Cache-Control: max-age=0` header when the user performs
106
+ a refresh (e.g., clicking the "Refresh" button).
107
+
108
+ *IMPORTANT: Enabling this option globally allows all clients to break your cache.*
109
+
110
+ ### `cache_key`
111
+
112
+ TODO: Document custom cache keys
@@ -0,0 +1,141 @@
1
+ Frequently Asked Questions
2
+ ==========================
3
+
4
+ <p class='intro'>
5
+ <strong>NOTE:</strong> This is a work in progress. Please send questions, comments, or
6
+ suggestions to <a href="mailto:r@tomayko.com">r@tomayko.com</a>.
7
+ </p>
8
+
9
+ General
10
+ -------
11
+
12
+
13
+ <a class='hash' id='rails' href='#rails'>#</a>
14
+
15
+ ### Q: Can I use Rack::Cache with Rails?
16
+
17
+ Rack::Cache can be used with Rails 2.3 or above. Documentation and a
18
+ sample application is forthcoming; in the mean time, see
19
+ [this example of using Rack::Cache with Rails 2.3](http://snippets.aktagon.com/snippets/302-How-to-setup-and-use-Rack-Cache-with-Rails-2-3-0-RC-1).
20
+
21
+ <a class='hash' id='why-not-squid' href='#why-not-squid'>#</a>
22
+
23
+ ### Q: Why Rack::Cache? Why not Squid, Varnish, Perlbol, etc.?
24
+
25
+ __Rack::Cache__ is often easier to setup as part of your existing Ruby
26
+ application than a separate caching system. __Rack::Cache__ runs entirely inside
27
+ your backend application processes - no separate / external process is required.
28
+ This lets __Rack::Cache__ scale down to development environments and simple
29
+ deployments very easily while not sacrificing the benefits of a standards-based
30
+ approach to caching.
31
+
32
+
33
+ <a class='hash' id='why-not-rails' href='#why-not-rails'>#</a>
34
+
35
+ ### Q: Why Rack::Cache? Why not use Rails/Merb/FrameworkX's caching system?
36
+
37
+ __Rack::Cache__ takes a standards-based approach to caching that provides some
38
+ benefits over framework-integrated systems. It uses standard HTTP headers
39
+ (`Expires`, `Cache-Control`, `Etag`, `Last-Modified`, etc.) to determine
40
+ what/when to cache. Designing applications to support these standard HTTP
41
+ mechanisms gives the benefit of being able to switch to a different HTTP
42
+ cache implementation in the future.
43
+
44
+ In addition, using a standards-based approach to caching creates a clear
45
+ separation between application and caching logic. The application need only
46
+ specify a basic set of information about the response and all decisions
47
+ regarding how and when to cache is moved into the caching layer.
48
+
49
+
50
+ <a class='hash' id='scale' href='#scale'>#</a>
51
+
52
+ ### Q: Will Rack::Cache make my app scale?
53
+
54
+ No. Your design is the only thing that can make your app scale.
55
+
56
+ Also, __Rack::Cache__ is not overly optimized for performance. The main goal of
57
+ the project is to provide a portable, easy-to-configure, and standards-based
58
+ caching solution for small to medium sized deployments. More sophisticated /
59
+ performant caching systems (e.g., [Varnish][v], [Squid][s],
60
+ [httpd/mod-cache][h]) may be more appropriate for large deployments with
61
+ crazy-land throughput requirements.
62
+
63
+ [v]: http://varnish.projects.linpro.no/
64
+ [s]: http://www.squid-cache.org/
65
+ [h]: http://httpd.apache.org/docs/2.0/mod/mod_cache.html
66
+
67
+
68
+ Features
69
+ --------
70
+
71
+
72
+ <a class='hash' id='validation' href='#validation'>#</a>
73
+
74
+ ### Q: Does Rack::Cache support validation?
75
+
76
+ Yes. Both freshness and validation-based caching is supported. A response
77
+ will be cached if it has a freshness lifetime (e.g., `Expires` or
78
+ `Cache-Control: max-age=N` headers) and/or includes a validator (e.g.,
79
+ `Last-Modified` or `ETag` headers). When the cache hits and the response is
80
+ fresh, it's delivered immediately without talking to the backend application;
81
+ when the cache is stale, the cached response is validated using a conditional
82
+ GET request.
83
+
84
+
85
+ <a class='hash' id='fragments' href='#fragments'>#</a>
86
+
87
+ ### Q: Does Rack::Cache support fragment caching?
88
+
89
+ Not really. __Rack::Cache__ deals with entire responses and doesn't know
90
+ anything about how your application constructs them.
91
+
92
+ However, something like [ESI](http://www.w3.org/TR/esi-lang) may be implemented
93
+ in the future (likely as a separate Rack middleware component that could be
94
+ situated upstream from Rack::Cache), which would allow applications to compose
95
+ responses based on several "fragment resources". Each fragment would have its
96
+ own cache policy.
97
+
98
+
99
+ <a class='hash' id='manual-purge' href='#manual-purge'>#</a>
100
+
101
+ ### Q: How do I manually purge or expire a cached entry?
102
+
103
+ Although planned, there is currently no mechanism for manually purging
104
+ an entry stored in the cache.
105
+
106
+ Note that using an `Expires` or `Cache-Control: max-age=N` header and relying on
107
+ manual purge to invalidate cached entry can often be implemented more simply
108
+ using efficient validation based caching (`Last-Modified`, `Etag`). Many web
109
+ frameworks are based entirely on manual purge and do not support validation at
110
+ the cache level.
111
+
112
+
113
+ <a class='hash' id='efficient-validation' href='#efficient-validation'>#</a>
114
+
115
+ ### Q: What does "Efficient Validation" mean?
116
+
117
+ It means that your application performs only the processing necessary to
118
+ determine if a response is valid before sending a `304 Not Modified` in response
119
+ to a conditional GET request. Many applications that perform validation do so
120
+ only after the entire response has been generated, which provides bandwidth
121
+ savings but results in no CPU/IO savings. Implementing validation efficiently
122
+ can increase backend application throughput significantly when fronted by a
123
+ validating caching system (like __Rack::Cache__).
124
+
125
+ [Here's an example Rack application](http://gist.github.com/9395) that performs
126
+ efficient validation.
127
+
128
+
129
+ <a class='hash' id='orly' href='#orly'>#</a>
130
+
131
+ ### Q: Did you just make that up?
132
+
133
+ Yes.
134
+
135
+
136
+ <a class='hash' id='https' href='#https'>#</a>
137
+
138
+ ### Q: Can I do HTTPS with Rack::Cache?
139
+
140
+ Sure. HTTPS is typically managed by a front-end web server so this isn't really
141
+ relevant to Rack::Cache.
@@ -0,0 +1,121 @@
1
+ __Rack::Cache__ is suitable as a quick drop-in component to enable HTTP caching
2
+ for [Rack][]-based applications that produce freshness (`Expires`,
3
+ `Cache-Control`) and/or validation (`Last-Modified`, `ETag`) information.
4
+
5
+ * Standards-based (see [RFC 2616][rfc] / [Section 13][s13]).
6
+ * Freshness/expiration based caching
7
+ * Validation
8
+ * Vary support
9
+ * Portable: 100% Ruby / works with any [Rack][]-enabled framework.
10
+ * Disk, memcached, and heap memory [storage backends][storage].
11
+
12
+ News
13
+ ----
14
+
15
+ * Rack::Cache 0.5 was released on May 25, 2009. See the
16
+ [`CHANGES`](http://github.com/rtomayko/rack-cache/blob/0.5.0/CHANGES) file
17
+ for details.
18
+ * [How to use Rack::Cache with Rails 2.3](http://snippets.aktagon.com/snippets/302-How-to-setup-and-use-Rack-Cache-with-Rails-2-3-0-RC-1) - it's really easy.
19
+ * [RailsLab's Advanced HTTP Caching Screencast](http://railslab.newrelic.com/2009/02/26/episode-11-advanced-http-caching)
20
+ is a really great review of HTTP caching concepts and shows how to
21
+ use Rack::Cache with Rails.
22
+
23
+ Installation
24
+ ------------
25
+
26
+ $ sudo gem install rack-cache
27
+
28
+ Or, from a local working copy:
29
+
30
+ $ git clone git://github.com/rtomayko/rack-cache.git
31
+ $ rake package && sudo rake install
32
+
33
+ Basic Usage
34
+ -----------
35
+
36
+ __Rack::Cache__ is implemented as a piece of [Rack][] middleware and can be used
37
+ with any __Rack__-based application. If your application includes a rackup
38
+ (`.ru`) file or uses __Rack::Builder__ to construct the application pipeline,
39
+ simply `require` and `use` as follows:
40
+
41
+ require 'rack/cache'
42
+
43
+ use Rack::Cache,
44
+ :verbose => true,
45
+ :metastore => 'file:/var/cache/rack/meta'
46
+ :entitystore => 'file:/var/cache/rack/body'
47
+
48
+ run app
49
+
50
+ Assuming you've designed your backend application to take advantage of HTTP's
51
+ caching features, no further code or configuration is required for basic
52
+ caching.
53
+
54
+ More
55
+ ----
56
+
57
+ * [Configuration Options][config] - how to set cache options.
58
+
59
+ * [Cache Storage Documentation][storage] - detailed information on the various
60
+ storage implementations available in __Rack::Cache__ and how to choose the one
61
+ that's best for your application.
62
+
63
+ * [Things Caches Do][things] - an illustrated guide to how HTTP gateway
64
+ caches work with pointers to other useful resources on HTTP caching.
65
+
66
+ * [GitHub Repository](http://github.com/rtomayko/rack-cache/) - get your
67
+ fork on.
68
+
69
+ * [Mailing List](http://groups.google.com/group/rack-cache) - for hackers
70
+ and users (`rack-cache@groups.google.com`).
71
+
72
+ * [FAQ](./faq) - Frequently Asked Questions about __Rack::Cache__.
73
+
74
+ * [RDoc API Documentation](./api/) - Mostly worthless if you just want to use
75
+ __Rack::Cache__ in your application but mildly insightful if you'd like to
76
+ get a feel for how the system has been put together; I recommend
77
+ [reading the source](http://github.com/rtomayko/rack-cache/master/lib/rack/cache).
78
+
79
+
80
+ See Also
81
+ --------
82
+
83
+ The overall design of __Rack::Cache__ is based largely on the work of the
84
+ internet standards community. The following resources provide a good starting
85
+ point for exploring the basic concepts of HTTP caching:
86
+
87
+ * Mark Nottingham's [Caching Tutorial](http://www.mnot.net/cache_docs/),
88
+ especially the short section on
89
+ [How Web Caches Work](http://www.mnot.net/cache_docs/#WORK)
90
+
91
+ * Joe Gregorio's [Doing HTTP Caching Right](http://www.xml.com/lpt/a/1642)
92
+
93
+ * [RFC 2616](http://www.ietf.org/rfc/rfc2616.txt), especially
94
+ [Section 13, "Caching in HTTP"](http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html)
95
+
96
+ __Rack::Cache__ takes (_liberally_) various concepts from
97
+ [Varnish](http://varnish.projects.linpro.no/) and
98
+ [Django's cache framework](http://docs.djangoproject.com/en/dev/topics/cache/).
99
+
100
+ License
101
+ -------
102
+
103
+ __Rack::Cache__ is Copyright &copy; 2008
104
+ by [Ryan Tomayko](http://tomayko.com/about)
105
+ and is provided under [the MIT license](./license)
106
+
107
+ [config]: ./configuration "Rack::Cache Configuration Language Documentation"
108
+ [storage]: ./storage "Rack::Cache Storage Documentation"
109
+ [things]: http://tomayko.com/writings/things-caches-do
110
+
111
+ [rfc]: http://tools.ietf.org/html/rfc2616
112
+ "RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1 [ietf.org]"
113
+
114
+ [s13]: http://tools.ietf.org/html/rfc2616#section-13
115
+ "RFC 2616 / Section 13 Caching in HTTP"
116
+
117
+ [rack]: http://rack.rubyforge.org/
118
+ "Rack: a Ruby Webserver Interface"
119
+
120
+ [vcl]: http://tomayko.com/man/vcl
121
+ "VCL(7) -- Varnish Configuration Language Manual Page"
@@ -0,0 +1,34 @@
1
+ <!DOCTYPE html>
2
+ <html lang='en'>
3
+ <head>
4
+ <meta http-equiv='Content-Type' content='text/html;charset=utf-8'>
5
+ <title>Rack::Cache <%= title %></title>
6
+ <link rel='stylesheet' href='rack-cache.css' type='text/css' media='all'>
7
+ <script type='text/javascript' src='http://code.jquery.com/jquery-1.2.3.js'></script>
8
+ <script type='text/javascript' src='http://tomayko.com/js/tomayko.js'></script>
9
+ </head>
10
+ <body>
11
+ <div id='container'>
12
+ <div id='header'>
13
+ <h1><a href="./">rack-cache</a></h1>
14
+ <p>
15
+ <a href="./configuration" title='Configuration Language Documentation'>Config</a> |
16
+ <a href="./storage" title='Cache Storage Documentation'>Storage</a> |
17
+ <a href="http://tomayko.com/writings/things-caches-do" title="Things Caches Do">Things</a> |
18
+ <a href="./faq" title='Frequently Asked Questions'>FAQ</a> |
19
+ <a href="./api/" title='Fucking Sucks.'>RDoc</a>
20
+ </p>
21
+ </div>
22
+ <div id='content'><%= content %></div>
23
+ <div id='footer'>
24
+ <p class='rights'>
25
+ Copyright
26
+ <a href="./license" rel="license">&copy;</a>
27
+ 2003-2008
28
+ by
29
+ <a href='http://tomayko.com/about' rel='me author'>Ryan Tomayko</a>
30
+ </p>
31
+ </div>
32
+ </div>
33
+ </body>
34
+ </html>
@@ -0,0 +1,24 @@
1
+ License (MIT)
2
+ =============
3
+
4
+ __Rack::Cache__ is Copyright &copy; 2008
5
+ by [Ryan Tomayko](http://tomayko.com/about)
6
+
7
+ <pre class='license'>
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to
10
+ deal in the Software without restriction, including without limitation the
11
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
+ sell copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in
16
+ all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ </pre>
@@ -0,0 +1,362 @@
1
+ /* rack-cache.css
2
+ *---------------------------------------------------------------------------
3
+ * Copyright (C) 2005-08 Ryan Tomayko <r@tomayko.com>
4
+ */
5
+
6
+
7
+ /* 18px base font size / 25px baseline */
8
+ body {
9
+ font-size:112.5%; /* 18px (probably) */
10
+ line-height:1.3888; /* 25px */
11
+ letter-spacing:-0.02em;
12
+ margin:0 10px;
13
+ font-family: 'lucida sans unicode', 'lucida grande',
14
+ helvetica, 'bitstream vera sans', sans-serif;
15
+ color:#556;
16
+ background-color:#fff;
17
+ }
18
+
19
+ #container {
20
+ max-width:45em;
21
+ margin:0 auto;
22
+ }
23
+
24
+ h1, h2, h3 {
25
+ font-family:georgia, 'bitstream vera sans serif', 'lucida grande',
26
+ helvetica, verdana, sans-serif;
27
+ font-weight:normal;
28
+ letter-spacing:-0.05em;
29
+ color:#000;
30
+ }
31
+ i, em {
32
+ font-style:italic;
33
+ }
34
+ b, strong {
35
+ font-weight:normal;
36
+ color:#000;
37
+ }
38
+ blockquote {
39
+ color:#555;
40
+ }
41
+ blockquote em {
42
+ color:#333;
43
+ font-style:italic;
44
+ }
45
+ blockquote strong {
46
+ color:#333;
47
+ font-weight: normal;
48
+ }
49
+ dt {
50
+ font-weight:bold;
51
+ color:#000;
52
+ }
53
+ tt, pre, code, samp, kbd {
54
+ font-family: consolas, 'lucida console', 'bitstream vera sans mono',
55
+ 'courier new', monospace;
56
+ color: #000;
57
+ }
58
+ pre {
59
+ color:#333;
60
+ background-color:#f9f9f9;
61
+ }
62
+ code {
63
+ color:#007A00;
64
+ }
65
+ pre code {
66
+ color:#333;
67
+ }
68
+ pre.license {
69
+ border:0;
70
+ background:#fff;
71
+ padding:0;
72
+ font-size:1.1em;
73
+ }
74
+ a, a:link {
75
+ color:#023;
76
+ background:#eef;
77
+ }
78
+ a:visited {
79
+ color:#345;
80
+ background:#fff;
81
+ }
82
+ a:hover {
83
+ background:#ccf;
84
+ color:#000;
85
+ text-decoration:none;
86
+ }
87
+
88
+
89
+ /* TYPOGRAPHY */
90
+
91
+ p, ul, ol, dl, pre, blockquote, table, form {
92
+ margin:1em 0;
93
+ }
94
+ dl {
95
+ margin-left:2em;
96
+ }
97
+ hr {
98
+ color:#eee;
99
+ background-color:#ccc;
100
+ border:0;
101
+ height:1px;
102
+ margin:1.5em 0;
103
+ }
104
+ blockquote {
105
+ font-size:0.83333em; /* 15px */
106
+ line-height:1.66666; /* 25px */
107
+ margin:1.2em 3em;
108
+ padding:0;
109
+ }
110
+ tt, pre, code, samp, kbd {
111
+ font-size: 16px;
112
+ line-height:1.1;
113
+ }
114
+ pre {
115
+ margin:1.5em 0;
116
+ padding:6px 4px 4px 6px;
117
+ border:1px solid #eee;
118
+ border-left-width:20px;
119
+ overflow:auto;
120
+ }
121
+ h1 {
122
+ font-size:2.3333em; /* 42px */
123
+ line-height:1.1904; /* 50px */
124
+ margin:0.5952em 0; /* 25px */
125
+ }
126
+ h2 {
127
+ font-size:1.66666667em; /* 30px */
128
+ line-height:1.2; /* 36px */
129
+ margin:1em 0;
130
+ }
131
+ h3 {
132
+ font-size:1.33333333em; /* 22px */
133
+ line-height:1.13636363; /* 25px */
134
+ margin:1em 0;
135
+ }
136
+ h3 code{
137
+ font-size:0.95em;
138
+ color:#000;
139
+ }
140
+ h4 {
141
+ font-size:1em;
142
+ font-weight:bold;
143
+ line-height:1.5;
144
+ margin:1em 0;
145
+ }
146
+ p small {
147
+ font-size:0.8333; /* 15px */
148
+ line-height:1.2;
149
+ }
150
+
151
+ /* Tables
152
+ --------------------------------------------------------------------------- */
153
+
154
+ table {
155
+ width:100%;
156
+ border-style:none;
157
+ border-color:#ddd;
158
+ padding:0;
159
+ }
160
+
161
+ th, td {
162
+ padding: 4px 10px 4px 5px;
163
+ border-style:solid;
164
+ border-color:#fff;
165
+ }
166
+
167
+ th {
168
+ font-weight: bold;
169
+ background: #eef;
170
+ }
171
+
172
+ td {
173
+ background: #f9f9f9;
174
+ }
175
+
176
+ tfoot {
177
+ font-style: italic;
178
+ }
179
+
180
+ caption {
181
+ background: #eee;
182
+ }
183
+
184
+ /* Header / Titling
185
+ --------------------------------------------------------------------------- */
186
+
187
+ #header {
188
+ text-align:left;
189
+ margin:1.5em auto 2em;
190
+ float:left;
191
+ width:100%;
192
+ padding-bottom:1.5em;
193
+ border-bottom:1px solid #777;
194
+ }
195
+ #header h1 {
196
+ font-family: 'lucida sans unicode', 'lucida grande',
197
+ helvetica, 'bitstream vera sans', sans-serif;
198
+ font-size:5em;
199
+ font-weight:bold;
200
+ line-height:1;
201
+ margin:0;
202
+ float:left;
203
+ color:#000;
204
+ letter-spacing:-0.08em;
205
+ }
206
+ #header h1 a, #header h1 a:link, #header h1 a:visited, #header h1 a:hover {
207
+ color:#000;
208
+ text-decoration:none;
209
+ background:transparent;
210
+ }
211
+ #header p {
212
+ margin: 0;
213
+ line-height:1.8;
214
+ color: #777;
215
+ text-transform:capitalize;
216
+ font-variant:small-caps;
217
+ float:right;
218
+ }
219
+ #header a, #header a:link, #header a:visited {
220
+ color:#445;
221
+ background:#fff;
222
+ }
223
+ #header a:hover {
224
+ background:#ccf;
225
+ color:#000;
226
+ text-decoration:none;
227
+ }
228
+ #content {
229
+ clear:both;
230
+ }
231
+
232
+ /* FOOTER */
233
+
234
+ #footer {
235
+ clear:both;
236
+ color:#555;
237
+ font-size:0.88888888em;
238
+ line-height:1.5625;
239
+ border-top:1px solid #ddd;
240
+ padding:19px 0 0 0;
241
+ margin:40px 0 20px 0;
242
+ text-align:center;
243
+ }
244
+ #footer p {
245
+ margin:0;
246
+ }
247
+ #footer form {
248
+ float:right;
249
+ }
250
+ #footer input{
251
+ font-size:10px;
252
+ }
253
+
254
+ /* MISC HELPER STYLES */
255
+
256
+ ul.clean, ol.clean {
257
+ list-style-type: none;
258
+ padding-left: 0;
259
+ }
260
+ .caps {
261
+ font-variant:small-caps;
262
+ }
263
+ .clear {
264
+ clear:both;
265
+ }
266
+ .left{
267
+ float:left;
268
+ }
269
+ .right{
270
+ float:right;
271
+ }
272
+ .center{
273
+ text-align:center;
274
+ }
275
+ .intro {
276
+ font-size:0.833333em; /* 15px */
277
+ line-height:1.666667; /* 25px */
278
+ border:1px solid #ccc;
279
+ padding:0.5em;
280
+ font-style:italic;
281
+ color:#555;
282
+ }
283
+ a.hash,
284
+ a.hash:link,
285
+ a.hash:visited {
286
+ display:block;
287
+ float:right;
288
+ background:#fff;
289
+ font-size:0.8em;
290
+ text-decoration:none;
291
+ line-height:2;
292
+ color:#999;
293
+ }
294
+ a.hash:hover {
295
+ color:MediumOrchid;
296
+ }
297
+
298
+ /* PRINT */
299
+
300
+ @media print {
301
+ html, body, #container {
302
+ margin:0;
303
+ }
304
+ #container {
305
+ width:100%;
306
+ max-width:100%;
307
+ }
308
+ #header {
309
+ margin-top:0;
310
+ }
311
+ #header p {
312
+ display:none;
313
+ }
314
+ #footer {
315
+ display:none;
316
+ }
317
+ a, a:link, a:visited {
318
+ color:#000;
319
+ background:#fff;
320
+ text-decoration:none;
321
+ }
322
+ pre.license {
323
+ font-size:0.95em;
324
+ }
325
+ @page {
326
+ size:8.5in 11in;
327
+ }
328
+ }
329
+
330
+ /* PRETTIFICATION OF SOURCE CODE */
331
+
332
+ .str { color: #181; font-style:italic; }
333
+ .kwd { color: #369; }
334
+ .com { color: #666; }
335
+ .typ { color: #c40; }
336
+ .lit { color: #900; }
337
+ .pun { color: #000; font-weight: bold; }
338
+ .pln { color: #333; }
339
+ .tag { color: #369; font-weight: bold; }
340
+ .atn { color: #939; font-weight: bold }
341
+ .atv { color: #181; }
342
+ .dec { color: #606; }
343
+
344
+ @media print {
345
+ .str { color: #060; }
346
+ .kwd { color: #006; font-weight: bold; }
347
+ .com { color: #600; font-style: italic; }
348
+ .typ { color: #404; font-weight: bold; }
349
+ .lit { color: #044; }
350
+ .pun { color: #440; }
351
+ .pln { color: #000; }
352
+ .tag { color: #006; font-weight: bold; }
353
+ .atn { color: #404; }
354
+ .atv { color: #060; }
355
+ }
356
+
357
+ /* FUCKING IE */
358
+
359
+ * html body{width:40em}
360
+ * html div.index{width:34.5em}
361
+
362
+ /* vim: set ft=css ts=4 sw=4 noexpandtab: */