├── .gitignore ├── .rbenv-version ├── .travis.yml ├── .yardopts ├── Gemfile ├── README.md ├── Rakefile ├── cuid.gemspec ├── doc ├── Cuid.html ├── _index.html ├── class_list.html ├── css │ ├── common.css │ ├── full_list.css │ └── style.css ├── file.README.html ├── file_list.html ├── frames.html ├── index.html ├── js │ ├── app.js │ ├── full_list.js │ └── jquery.js ├── method_list.html └── top-level-namespace.html ├── lib ├── cuid.rb └── cuid │ └── version.rb └── test └── test_cuid.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | vendor/bundle 6 | .yardoc/* 7 | -------------------------------------------------------------------------------- /.rbenv-version: -------------------------------------------------------------------------------- 1 | 1.9.3-p286 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 1.8.7 4 | - 1.9.2 5 | - 1.9.3 6 | - jruby-19mode 7 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --no-private 2 | --protected 3 | --markup="markdown" lib/cuid.rb 4 | --main README.md 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | group :test do 4 | gem "rake" 5 | end 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cuid.rb - CUID ported to Ruby 2 | Last updated: December 16, 2012 3 | 4 | Version: 1.0.1 5 | [![Build Status](https://travis-ci.org/iyshannon/cuid.png)](https://travis-ci.org/iyshannon/cuid) 6 | 7 | Documentation: [http://rubydoc.info/gems/cuid](http://rubydoc.info/gems/cuid) 8 | Repository: [http://github.com/iyshannon/cuid](http://github.com/iyshanonn/cuid) 9 | 10 | ## Introduction 11 | 12 | cuid.rb is a ruby library that provides collision-resistant ids optimized for horizontal scaling and sequential lookup performance. 13 | 14 | This is just going to cover the basics and the Ruby-specific implementation details. 15 | 16 | **Please refer to the [main project site](http://usecuid.org) for the full story.** 17 | 18 | ## Sample CUID 19 | 20 | ch72gsb320000udocl363eofy 21 | 22 | ### Explanation 23 | 24 | `c - h72gsb32 - 0000 - udoc - l363eofy` 25 | 26 | The groups, in order, are: 27 | 28 | * 'c' - identifies this as a cuid, and allows you to use it in html entity ids. The fixed value helps keep the ids sequential. 29 | * Timestamp 30 | * Measured in milliseconds since the epoch 31 | * Will rollover in May 2059 32 | * Counter 33 | * A single process might generate the same random string. The weaker the pseudo-random source, the higher the probability. That problem gets worse as processors get faster. 34 | * The counter will roll over after 1,679,615 cuids are generated by one process. 35 | * Client fingerprint 36 | * In Ruby, the first two characters are based on the process ID and the next two characters are based on the hostname. This is the same method used in the Node implementation. 37 | * Pseudo random number 38 | * By default, Ruby uses the `Kernel#rand` function, a Mersenne Twister PRNG. 39 | * On Ruby 1.9.2 and up, it can optionally use the `SecureRandom` library (which uses OpenSSL), but there is a significant performance cost. 40 | 41 | ## Performance 42 | 43 | My development system runs Ubuntu 12.04 on an Intel Wolfdale E5200 Dual Core 2.5GHz with 4GB RAM. 44 | I did some very unscientific testing and the results were as follows: 45 | 46 | * Ruby 1.9.3-p286 using `Kernel#rand`: Generated 600,000 cuids in 8.16 seconds 47 | * Ruby 1.9.3-p286 using `SecureRandom#random_number` : Generated 600,000 cuids in 20.74 seconds 48 | 49 | *Each test was run three times and the mean is reported.* 50 | 51 | ### Analysis 52 | 53 | The timestamp segment of the cuid is measured in milliseconds. In the faster test result, it generated about 74 cuids per millisecond. Even 54 | without considering the random segment of the cuid, one process could safely generate up to 1,679,615 unique cuids per millisecond (36^4 - 1) without a 55 | collision due to the counter segment. 56 | 57 | ## System Requirements 58 | 59 | This gem was developed under `ruby1.9.3-p286` but is tested under multiple versions thanks to [Travis CI](http://www.travis-ci.org). 60 | 61 | Tested under: 62 | 63 | * Ruby 1.8.7 64 | * Ruby 1.9.2 65 | * Ruby 1.9.3 66 | * JRuby 1.9 (jruby19mode) 67 | 68 | ## Installation 69 | 70 | gem install cuid 71 | 72 | ## Example Usage 73 | 74 | irb(main):001:0> require "cuid" 75 | => true 76 | irb(main):002:0> g = Cuid::generate 77 | => "ch8qypsnz0000a4welw8anyra" 78 | irb(main):003:0> Cuid::validate(g) 79 | => true 80 | irb(main):004:0> Cuid::generate(4) 81 | => ["ch8qyq35f0002a4wekjcwmh30", "ch8qyq35f0003a4weewy22izq", "ch8qyq35f0004a4webzzelvdv", "ch8qyq35f0005a4wesg3tfjk5"] 82 | 83 | ## Credit 84 | 85 | * Ian Shannon [(ported to Ruby)](http://github.com/iyshannon/cuid) 86 | * Eric Elliott [(original JavaScript version)](http://github.com/dilvie/cuid) 87 | 88 | ## MIT Open Source License 89 | 90 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 91 | 92 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 93 | 94 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 95 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require "bundler/gem_tasks" 3 | require "rake/testtask" 4 | Rake::TestTask.new do |t| 5 | t.libs << 'lib/cuid' 6 | t.verbose = true 7 | end 8 | task :default => :test 9 | -------------------------------------------------------------------------------- /cuid.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "cuid/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "cuid" 7 | s.version = Cuid::VERSION 8 | s.authors = ["Ian Shannon"] 9 | s.email = ["iyshannon@gmail.com"] 10 | s.homepage = "http://github.com/iyshannon/cuid" 11 | s.summary = %q{Collision-resistant ids optimized for horizontal scaling and performance} 12 | s.description = %q{Ruby implementation of Eric Elliot's javascript cuid} 13 | 14 | s.files = `git ls-files`.split("\n") 15 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 16 | s.require_paths = ["lib"] 17 | end 18 | -------------------------------------------------------------------------------- /doc/Cuid.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | Module: Cuid 8 | 9 | — Documentation by YARD 0.8.3 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 63 | 64 | 65 | 66 |

Module: Cuid 67 | 68 | 69 | 70 |

71 | 72 |
73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
Defined in:
82 |
lib/cuid.rb
83 | 84 |
85 |
86 | 87 |

Overview

88 |
89 |

Cuid is a library for generating unique collision-resistant IDs optimized for horizontal scaling and performance

90 | 91 | 92 |
93 |
94 |
95 | 96 |
97 |

Examples:

98 | 99 | 100 |

Generate a hash

101 |

102 | 103 |
hash = Cuid::generate #=> "ch8qypsnz0000a4welw8anyr"
104 | 105 | 106 |

Generate 2 hashes

107 |

108 | 109 |
hashes = Cuid::generate(2) #=> ["ch8qyq35f0002a4wekjcwmh30", "ch8qyq35f0003a4weewy22izq"]
110 | 111 |
112 | 113 | 114 |

See Also:

115 | 120 | 121 |
122 |

Constant Summary

123 | 124 |
125 | 126 |
BLOCK_SIZE = 127 |
128 |
129 |

length of each segment of the hash

130 | 131 | 132 |
133 |
134 |
135 | 136 | 137 |
138 |
139 |
4
140 | 141 |
BASE = 142 |
143 |
144 |

size of the alphabet (e.g. base36 is [a-z0-9])

145 | 146 | 147 |
148 |
149 |
150 | 151 | 152 |
153 |
154 |
36
155 | 156 |
RAND_SIZE = 157 |
158 |
159 |

size of the random segment of the block

160 | 161 | 162 |
163 |
164 |
165 | 166 | 167 |
168 |
169 |
BLOCK_SIZE * 2
170 | 171 |
172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 |

182 | Class Method Summary 183 | (collapse) 184 |

185 | 186 | 235 | 236 | 237 | 238 | 239 |
240 |

Class Method Details

241 | 242 | 243 |
244 |

245 | 246 | 247 | + (String) generate 248 | 249 | + (Array<String>) generate(quantity) 250 | 251 | + (Array<String>) generate(quantity, secure_random) 252 | 253 | 254 | 255 | 256 | 257 | 258 |

259 |
260 |

Returns one or more hashes based on the parameter supplied

261 | 262 | 263 |
264 |
265 |
266 | 267 |

Overloads:

268 |
    269 | 270 | 271 |
  • 272 | + (String) generate 273 |
    274 |
    275 |

    Returns one hash when called with no parameters or a parameter of 1

    276 | 277 | 278 |
    279 |
    280 |
    281 |

    Parameters:

    282 |
      283 | 284 |
    • 285 | 286 | quantity 287 | 288 | 289 | (optional, Integer) 290 | 291 | 292 | 293 | — 294 |

      determines number of hashes returned (must be nil, 0 or 1)

      295 |
      296 | 297 |
    • 298 | 299 |
    300 | 301 |

    Returns:

    302 |
      303 | 304 |
    • 305 | 306 | 307 | (String) 308 | 309 | 310 | 311 |
    • 312 | 313 |
    314 | 315 |
    316 |
  • 317 | 318 | 319 |
  • 320 | + (Array<String>) generate(quantity) 321 |
    322 |
    323 |

    Returns an array of hashes when called with a parameter greater than 1

    324 | 325 | 326 |
    327 |
    328 |
    329 |

    Parameters:

    330 |
      331 | 332 |
    • 333 | 334 | quantity 335 | 336 | 337 | (Integer) 338 | 339 | 340 | 341 | — 342 |

      determines number of hashes returned (must be greater than 1)

      343 |
      344 | 345 |
    • 346 | 347 |
    348 | 349 |

    Returns:

    350 |
      351 | 352 |
    • 353 | 354 | 355 | (Array<String>) 356 | 357 | 358 | 359 |
    • 360 | 361 |
    362 | 363 |
    364 |
  • 365 | 366 | 367 |
  • 368 | + (Array<String>) generate(quantity, secure_random) 369 |
    370 |
    371 |

    Returns an array of hashes when called with a parameter greater than 1

    372 | 373 | 374 |
    375 |
    376 |
    377 |

    Parameters:

    378 |
      379 | 380 |
    • 381 | 382 | quantity 383 | 384 | 385 | (Integer) 386 | 387 | 388 | 389 | — 390 |

      determines number of hashes returned (must be greater than 1)

      391 |
      392 | 393 |
    • 394 | 395 |
    • 396 | 397 | secure_random 398 | 399 | 400 | (Boolean) 401 | 402 | 403 | 404 | — 405 |

      attempts to use SecureRandom if set to True (Ruby 1.9.2 and up; reverts to Kernel#rand if SecureRandom is not supported)

      406 |
      407 | 408 |
    • 409 | 410 |
    411 | 412 |

    Returns:

    413 |
      414 | 415 |
    • 416 | 417 | 418 | (Array<String>) 419 | 420 | 421 | 422 |
    • 423 | 424 |
    425 | 426 |
    427 |
  • 428 | 429 |
430 | 431 | 432 |
433 | 434 | 447 | 459 | 460 |
435 |
436 | 
437 | 
438 | 79
439 | 80
440 | 81
441 | 82
442 | 83
443 | 84
444 | 85
445 | 86
446 |
448 |
# File 'lib/cuid.rb', line 79
449 | 
450 | def generate(quantity=1,secure_random=false)
451 |   @use_secure_random = secure_random
452 |   @fingerprint = get_fingerprint # only need to get the fingerprint once because it is constant per-run
453 |   return api unless quantity > 1
454 | 
455 |   values = Array(1.upto(quantity)) # create an array of the correct size
456 |   return values.collect { api } # fill array with hashes
457 | end
458 |
461 |
462 | 463 |
464 |

465 | 466 | + (Boolean) validate(str) 467 | 468 | 469 | 470 | 471 | 472 |

473 |
474 |

Validates (minimally) the supplied string is in the correct format to be a hash

475 | 476 |

Validation checks that the first letter is correct and that the rest of the 477 | string is the correct length and consists of lower case letters and numbers.

478 | 479 | 480 |
481 |
482 |
483 |

Parameters:

484 |
    485 | 486 |
  • 487 | 488 | str 489 | 490 | 491 | (String) 492 | 493 | 494 | 495 | — 496 |

    string to check

    497 |
    498 | 499 |
  • 500 | 501 |
502 | 503 |

Returns:

504 |
    505 | 506 |
  • 507 | 508 | 509 | (Boolean) 510 | 511 | 512 | 513 | — 514 |

    returns true if the format is correct

    515 |
    516 | 517 |
  • 518 | 519 |
520 | 521 |
522 | 523 | 532 | 540 | 541 |
524 |
525 | 
526 | 
527 | 96
528 | 97
529 | 98
530 | 99
531 |
533 |
# File 'lib/cuid.rb', line 96
534 | 
535 | def validate(str)
536 |   blen = BLOCK_SIZE * 6
537 |   !!str.match(/#{LETTER}[a-z0-9]{#{blen}}/)
538 | end
539 |
542 |
543 | 544 |
545 | 546 |
547 | 548 | 553 | 554 | 555 | -------------------------------------------------------------------------------- /doc/_index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | Documentation by YARD 0.8.3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 56 | 57 | 58 | 59 |

Documentation by YARD 0.8.3

60 |
61 |

Alphabetic Index

62 | 63 |

File Listing

64 | 71 | 72 |
73 |

Namespace Listing A-Z

74 | 75 | 76 | 77 | 78 | 79 | 80 | 96 | 97 |
81 | 82 | 83 |
    84 |
  • C
  • 85 |
      86 | 87 |
    • 88 | Cuid 89 | 90 |
    • 91 | 92 |
    93 |
94 | 95 |
98 | 99 |
100 | 101 |
102 | 103 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /doc/class_list.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 |
28 |

Class List

29 | 44 | 45 | 46 | 51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /doc/css/common.css: -------------------------------------------------------------------------------- 1 | /* Override this file with custom rules */ -------------------------------------------------------------------------------- /doc/css/full_list.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; 4 | font-size: 13px; 5 | height: 101%; 6 | overflow-x: hidden; 7 | } 8 | 9 | h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } 10 | .clear { clear: both; } 11 | #search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } 12 | #content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } 13 | #full_list { padding: 0; list-style: none; margin-left: 0; } 14 | #full_list ul { padding: 0; } 15 | #full_list li { padding: 5px; padding-left: 12px; margin: 0; font-size: 1.1em; list-style: none; } 16 | #noresults { padding: 7px 12px; } 17 | #content.insearch #noresults { margin-left: 7px; } 18 | ul.collapsed ul, ul.collapsed li { display: none; } 19 | ul.collapsed.search_uncollapsed { display: block; } 20 | ul.collapsed.search_uncollapsed li { display: list-item; } 21 | li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } 22 | li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } 23 | li { color: #888; cursor: pointer; } 24 | li.deprecated { text-decoration: line-through; font-style: italic; } 25 | li.r1 { background: #f0f0f0; } 26 | li.r2 { background: #fafafa; } 27 | li:hover { background: #ddd; } 28 | li small:before { content: "("; } 29 | li small:after { content: ")"; } 30 | li small.search_info { display: none; } 31 | a:link, a:visited { text-decoration: none; color: #05a; } 32 | li.clicked { background: #05a; color: #ccc; } 33 | li.clicked a:link, li.clicked a:visited { color: #eee; } 34 | li.clicked a.toggle { opacity: 0.5; background-position: bottom right; } 35 | li.collapsed.clicked a.toggle { background-position: top right; } 36 | #search input { border: 1px solid #bbb; -moz-border-radius: 3px; -webkit-border-radius: 3px; } 37 | #nav { margin-left: 10px; font-size: 0.9em; display: none; color: #aaa; } 38 | #nav a:link, #nav a:visited { color: #358; } 39 | #nav a:hover { background: transparent; color: #5af; } 40 | .frames #nav span:after { content: ' | '; } 41 | .frames #nav span:last-child:after { content: ''; } 42 | 43 | .frames #content h1 { margin-top: 0; } 44 | .frames li { white-space: nowrap; cursor: normal; } 45 | .frames li small { display: block; font-size: 0.8em; } 46 | .frames li small:before { content: ""; } 47 | .frames li small:after { content: ""; } 48 | .frames li small.search_info { display: none; } 49 | .frames #search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } 50 | .frames #content.insearch #search { background-position: center right; } 51 | .frames #search input { width: 110px; } 52 | .frames #nav { display: block; } 53 | 54 | #full_list.insearch li { display: none; } 55 | #full_list.insearch li.found { display: list-item; padding-left: 10px; } 56 | #full_list.insearch li a.toggle { display: none; } 57 | #full_list.insearch li small.search_info { display: block; } 58 | -------------------------------------------------------------------------------- /doc/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0 20px; 3 | font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; 4 | font-size: 13px; 5 | } 6 | body.frames { padding: 0 5px; } 7 | h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } 8 | h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } 9 | h1.title { margin-bottom: 10px; } 10 | h1.alphaindex { margin-top: 0; font-size: 22px; } 11 | h2 { 12 | padding: 0; 13 | padding-bottom: 3px; 14 | border-bottom: 1px #aaa solid; 15 | font-size: 1.4em; 16 | margin: 1.8em 0 0.5em; 17 | } 18 | h2 small { font-weight: normal; font-size: 0.7em; display: block; float: right; } 19 | .clear { clear: both; } 20 | .inline { display: inline; } 21 | .inline p:first-child { display: inline; } 22 | .docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } 23 | .docstring h1 { font-size: 1.2em; } 24 | .docstring h2 { font-size: 1.1em; } 25 | .docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } 26 | .summary_desc .object_link, .docstring .object_link { font-family: monospace; } 27 | .rdoc-term { padding-right: 25px; font-weight: bold; } 28 | .rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } 29 | 30 | /* style for