├── MIT-LICENSE ├── README.md ├── amazing ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.rdoc ├── Rakefile ├── app │ ├── assets │ │ ├── images │ │ │ └── .keep │ │ ├── javascripts │ │ │ ├── app.js │ │ │ ├── application.js │ │ │ └── books.js │ │ └── stylesheets │ │ │ ├── application.css │ │ │ ├── books.scss │ │ │ ├── header.scss │ │ │ ├── layout.scss │ │ │ ├── pygments.css │ │ │ └── reset.css │ ├── controllers │ │ ├── application_controller.rb │ │ ├── books_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ └── handlers_controller.rb │ ├── helpers │ │ ├── application_helper.rb │ │ └── books_helper.rb │ ├── mailers │ │ └── .keep │ ├── models │ │ ├── .keep │ │ ├── book.rb │ │ └── concerns │ │ │ └── .keep │ └── views │ │ ├── books │ │ ├── _form.html.erb │ │ ├── edit.html.erb │ │ ├── index.csv.am │ │ ├── index.html.erb │ │ ├── new.html.erb │ │ ├── search.html.erb │ │ ├── search.json.jbuilder │ │ ├── show.html.erb │ │ └── show.json.jbuilder │ │ ├── handlers │ │ ├── index.csv.am │ │ └── index.html.md │ │ └── layouts │ │ ├── _header.html.erb │ │ └── application.html.erb ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── setup │ └── spring ├── config.ru ├── config │ ├── application.rb │ ├── boot.rb │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── cookies_serializer.rb │ │ ├── filter_parameter_logging.rb │ │ ├── handlers.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── session_store.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ ├── routes.rb │ └── secrets.yml ├── db │ ├── migrate │ │ └── 20150620072912_create_books.rb │ ├── schema.rb │ └── seeds.rb ├── lib │ ├── assets │ │ └── .keep │ ├── csv_handler.rb │ ├── markdown_handler.rb │ └── tasks │ │ └── .keep ├── log │ └── .keep ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── favicon.ico │ └── robots.txt ├── test │ ├── controllers │ │ ├── .keep │ │ └── books_controller_test.rb │ ├── fixtures │ │ ├── .keep │ │ └── books.yml │ ├── helpers │ │ └── .keep │ ├── integration │ │ ├── .keep │ │ ├── csv_handler_test.rb │ │ └── markdown_handler_test.rb │ ├── mailers │ │ └── .keep │ ├── models │ │ ├── .keep │ │ └── book_test.rb │ └── test_helper.rb └── vendor │ └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep ├── colorpicker ├── app.css ├── app.js ├── index.html ├── spectrum.css └── spectrum.js ├── covers └── covers.html ├── monthly ├── index.html ├── jquery.monthly.css └── jquery.monthly.js ├── pretty-select ├── index.html └── styles.css ├── vendor ├── images │ ├── animated-overlay.gif │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ ├── ui-bg_flat_75_ffffff_40x100.png │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ ├── ui-bg_glass_65_ffffff_1x400.png │ ├── ui-bg_glass_75_dadada_1x400.png │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ ├── ui-bg_glass_95_fef1ec_1x400.png │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── ui-icons_222222_256x240.png │ ├── ui-icons_2e83ff_256x240.png │ ├── ui-icons_454545_256x240.png │ ├── ui-icons_888888_256x240.png │ └── ui-icons_cd0a0a_256x240.png ├── jquery-1.11.1.js ├── jquery-ui-1.10.4.js └── jquery-ui-1.10.4.smoothness.css └── week-picker ├── README.md ├── index.html ├── jquery-weekpicker.css └── jquery-weekpicker.js /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014 Arti Sinani 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Tutorials 2 | ========= 3 | 4 | Demos for [Lugolabs Blog](http://www.lugolabs.com/blog). 5 | 6 | --------- 7 | 8 | Copyright Lugo Labs. Uses [MIT-LICENSE](https://github.com/lugolabs/tutorials/blob/master/MIT-LICENSE). 9 | -------------------------------------------------------------------------------- /amazing/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | !/log/.keep 17 | /tmp 18 | -------------------------------------------------------------------------------- /amazing/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | 4 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 5 | gem 'rails', '4.2.1.rc3' 6 | # Use sqlite3 as the database for Active Record 7 | gem 'sqlite3' 8 | # Use SCSS for stylesheets 9 | gem 'sass-rails', '~> 5.0' 10 | # Use Uglifier as compressor for JavaScript assets 11 | gem 'uglifier', '>= 1.3.0' 12 | # Use CoffeeScript for .coffee assets and views 13 | gem 'coffee-rails', '~> 4.1.0' 14 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 15 | # gem 'therubyracer', platforms: :ruby 16 | 17 | # Use jquery as the JavaScript library 18 | gem 'jquery-rails' 19 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 20 | gem 'turbolinks' 21 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 22 | gem 'jbuilder', '~> 2.0' 23 | # bundle exec rake doc:rails generates the API under doc/api. 24 | gem 'sdoc', '~> 0.4.0', group: :doc 25 | 26 | # Use ActiveModel has_secure_password 27 | # gem 'bcrypt', '~> 3.1.7' 28 | 29 | # Use Unicorn as the app server 30 | # gem 'unicorn' 31 | 32 | # Use Capistrano for deployment 33 | # gem 'capistrano-rails', group: :development 34 | 35 | gem 'redcarpet' 36 | gem 'pygmentize' 37 | gem 'jquery-ui-rails' 38 | 39 | group :development, :test do 40 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 41 | gem 'byebug' 42 | 43 | # Access an IRB console on exception pages or by using <%= console %> in views 44 | gem 'web-console', '~> 2.0' 45 | 46 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 47 | gem 'spring' 48 | end 49 | 50 | -------------------------------------------------------------------------------- /amazing/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (4.2.1.rc3) 5 | actionpack (= 4.2.1.rc3) 6 | actionview (= 4.2.1.rc3) 7 | activejob (= 4.2.1.rc3) 8 | mail (~> 2.5, >= 2.5.4) 9 | rails-dom-testing (~> 1.0, >= 1.0.5) 10 | actionpack (4.2.1.rc3) 11 | actionview (= 4.2.1.rc3) 12 | activesupport (= 4.2.1.rc3) 13 | rack (~> 1.6) 14 | rack-test (~> 0.6.2) 15 | rails-dom-testing (~> 1.0, >= 1.0.5) 16 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 17 | actionview (4.2.1.rc3) 18 | activesupport (= 4.2.1.rc3) 19 | builder (~> 3.1) 20 | erubis (~> 2.7.0) 21 | rails-dom-testing (~> 1.0, >= 1.0.5) 22 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 23 | activejob (4.2.1.rc3) 24 | activesupport (= 4.2.1.rc3) 25 | globalid (>= 0.3.0) 26 | activemodel (4.2.1.rc3) 27 | activesupport (= 4.2.1.rc3) 28 | builder (~> 3.1) 29 | activerecord (4.2.1.rc3) 30 | activemodel (= 4.2.1.rc3) 31 | activesupport (= 4.2.1.rc3) 32 | arel (~> 6.0) 33 | activesupport (4.2.1.rc3) 34 | i18n (~> 0.7) 35 | json (~> 1.7, >= 1.7.7) 36 | minitest (~> 5.1) 37 | thread_safe (~> 0.3, >= 0.3.4) 38 | tzinfo (~> 1.1) 39 | arel (6.0.0) 40 | binding_of_caller (0.7.2) 41 | debug_inspector (>= 0.0.1) 42 | builder (3.2.2) 43 | byebug (5.0.0) 44 | columnize (= 0.9.0) 45 | coffee-rails (4.1.0) 46 | coffee-script (>= 2.2.0) 47 | railties (>= 4.0.0, < 5.0) 48 | coffee-script (2.4.1) 49 | coffee-script-source 50 | execjs 51 | coffee-script-source (1.9.1.1) 52 | columnize (0.9.0) 53 | debug_inspector (0.0.2) 54 | erubis (2.7.0) 55 | execjs (2.5.2) 56 | globalid (0.3.5) 57 | activesupport (>= 4.1.0) 58 | i18n (0.7.0) 59 | jbuilder (2.3.0) 60 | activesupport (>= 3.0.0, < 5) 61 | multi_json (~> 1.2) 62 | jquery-rails (4.0.4) 63 | rails-dom-testing (~> 1.0) 64 | railties (>= 4.2.0) 65 | thor (>= 0.14, < 2.0) 66 | jquery-ui-rails (5.0.3) 67 | railties (>= 3.2.16) 68 | json (1.8.3) 69 | loofah (2.0.2) 70 | nokogiri (>= 1.5.9) 71 | mail (2.6.3) 72 | mime-types (>= 1.16, < 3) 73 | mime-types (2.6.1) 74 | mini_portile (0.6.2) 75 | minitest (5.7.0) 76 | multi_json (1.11.1) 77 | nokogiri (1.6.6.2) 78 | mini_portile (~> 0.6.0) 79 | pygmentize (0.0.3) 80 | rack (1.6.4) 81 | rack-test (0.6.3) 82 | rack (>= 1.0) 83 | rails (4.2.1.rc3) 84 | actionmailer (= 4.2.1.rc3) 85 | actionpack (= 4.2.1.rc3) 86 | actionview (= 4.2.1.rc3) 87 | activejob (= 4.2.1.rc3) 88 | activemodel (= 4.2.1.rc3) 89 | activerecord (= 4.2.1.rc3) 90 | activesupport (= 4.2.1.rc3) 91 | bundler (>= 1.3.0, < 2.0) 92 | railties (= 4.2.1.rc3) 93 | sprockets-rails 94 | rails-deprecated_sanitizer (1.0.3) 95 | activesupport (>= 4.2.0.alpha) 96 | rails-dom-testing (1.0.6) 97 | activesupport (>= 4.2.0.beta, < 5.0) 98 | nokogiri (~> 1.6.0) 99 | rails-deprecated_sanitizer (>= 1.0.1) 100 | rails-html-sanitizer (1.0.2) 101 | loofah (~> 2.0) 102 | railties (4.2.1.rc3) 103 | actionpack (= 4.2.1.rc3) 104 | activesupport (= 4.2.1.rc3) 105 | rake (>= 0.8.7) 106 | thor (>= 0.18.1, < 2.0) 107 | rake (10.4.2) 108 | rdoc (4.2.0) 109 | json (~> 1.4) 110 | redcarpet (3.1.2) 111 | sass (3.4.14) 112 | sass-rails (5.0.3) 113 | railties (>= 4.0.0, < 5.0) 114 | sass (~> 3.1) 115 | sprockets (>= 2.8, < 4.0) 116 | sprockets-rails (>= 2.0, < 4.0) 117 | tilt (~> 1.1) 118 | sdoc (0.4.1) 119 | json (~> 1.7, >= 1.7.7) 120 | rdoc (~> 4.0) 121 | spring (1.3.6) 122 | sprockets (3.2.0) 123 | rack (~> 1.0) 124 | sprockets-rails (2.3.1) 125 | actionpack (>= 3.0) 126 | activesupport (>= 3.0) 127 | sprockets (>= 2.8, < 4.0) 128 | sqlite3 (1.3.10) 129 | thor (0.19.1) 130 | thread_safe (0.3.5) 131 | tilt (1.4.1) 132 | turbolinks (2.5.3) 133 | coffee-rails 134 | tzinfo (1.2.2) 135 | thread_safe (~> 0.1) 136 | uglifier (2.7.1) 137 | execjs (>= 0.3.0) 138 | json (>= 1.8.0) 139 | web-console (2.1.3) 140 | activemodel (>= 4.0) 141 | binding_of_caller (>= 0.7.2) 142 | railties (>= 4.0) 143 | sprockets-rails (>= 2.0, < 4.0) 144 | 145 | PLATFORMS 146 | ruby 147 | 148 | DEPENDENCIES 149 | byebug 150 | coffee-rails (~> 4.1.0) 151 | jbuilder (~> 2.0) 152 | jquery-rails 153 | jquery-ui-rails 154 | pygmentize 155 | rails (= 4.2.1.rc3) 156 | redcarpet 157 | sass-rails (~> 5.0) 158 | sdoc (~> 0.4.0) 159 | spring 160 | sqlite3 161 | turbolinks 162 | uglifier (>= 1.3.0) 163 | web-console (~> 2.0) 164 | -------------------------------------------------------------------------------- /amazing/README.rdoc: -------------------------------------------------------------------------------- 1 | == README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | 26 | 27 | Please feel free to use a different markup language if you do not plan to run 28 | rake doc:app. 29 | -------------------------------------------------------------------------------- /amazing/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /amazing/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/app/assets/images/.keep -------------------------------------------------------------------------------- /amazing/app/assets/javascripts/app.js: -------------------------------------------------------------------------------- 1 | var app = window.app = {}; 2 | -------------------------------------------------------------------------------- /amazing/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require jquery-ui/autocomplete 16 | //= require turbolinks 17 | 18 | //= require app 19 | //= require books 20 | -------------------------------------------------------------------------------- /amazing/app/assets/javascripts/books.js: -------------------------------------------------------------------------------- 1 | app.Books = function() { 2 | this._input = $('#books-search-txt'); 3 | this._initAutocomplete(); 4 | }; 5 | 6 | app.Books.prototype = { 7 | _initAutocomplete: function() { 8 | this._input 9 | .autocomplete({ 10 | source: '/books/search', 11 | appendTo: '#books-search-results', 12 | select: $.proxy(this._select, this) 13 | }) 14 | .autocomplete('instance')._renderItem = $.proxy(this._render, this); 15 | }, 16 | 17 | _render: function(ul, item) { 18 | var markup = [ 19 | '', 20 | '', 21 | '', 22 | '' + item.title + '', 23 | '' + item.author + '', 24 | '' + item.price + ' ' + item.published_at + '' 25 | ]; 26 | return $('
  • ') 27 | .append(markup.join('')) 28 | .appendTo(ul); 29 | }, 30 | 31 | _select: function(e, ui) { 32 | this._input.val(ui.item.title + ' - ' + ui.item.author); 33 | return false; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /amazing/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require jquery-ui/datepicker 14 | *= require reset 15 | *= require layout 16 | *= require header 17 | *= require books 18 | */ 19 | -------------------------------------------------------------------------------- /amazing/app/assets/stylesheets/books.scss: -------------------------------------------------------------------------------- 1 | .page-books { 2 | .books-search { 3 | text-align: center; 4 | max-width: 35em; 5 | margin: 2em auto; 6 | padding: 2em; 7 | 8 | input { 9 | width: 100%; 10 | font-size: 1em; 11 | padding: .5em 1.3em; 12 | background: transparent; 13 | border: 1px solid #ddd; 14 | border-radius: 2em; 15 | 16 | &:focus { 17 | border-color: #A5CEF5; 18 | } 19 | } 20 | 21 | .results { 22 | text-align: left; 23 | 24 | .ui-widget-content { 25 | background: #fff; 26 | font-size: .9em; 27 | padding: .5em 0; 28 | border-color: #ddd; 29 | box-shadow: 0 .1em .2em rgba(187, 187, 187, 0.64); 30 | line-height: 1.2; 31 | max-height: 20em; 32 | overflow: hidden; 33 | overflow-y: auto; 34 | } 35 | 36 | .ui-menu-item { 37 | font-family: 'Helvetica Neue', Helvetica, sans-serif; 38 | padding: .4em .6em .4em 6.2em; 39 | position: relative; 40 | border: 0; 41 | border-left: 5px solid transparent; 42 | position: relative; 43 | height: 6.5em; 44 | 45 | .img { 46 | position: absolute; 47 | width: 5em; 48 | height: 6em; 49 | top: .4em; 50 | left: .6em; 51 | overflow: hidden; 52 | 53 | img { 54 | max-width: 100%; 55 | } 56 | } 57 | 58 | .title { 59 | display: block; 60 | color: #555; 61 | } 62 | 63 | .author { 64 | display: block; 65 | font-size: .8em; 66 | text-transform: uppercase; 67 | color: #aaa; 68 | margin-top: .6em; 69 | letter-spacing: 1px; 70 | } 71 | 72 | .price { 73 | display: block; 74 | font-size: .8em; 75 | color: #aaa; 76 | margin-top: .5em; 77 | } 78 | } 79 | 80 | .ui-state-focus { 81 | background: #fff; 82 | border-left-color: #08c; 83 | font-weight: 300; 84 | 85 | .title { 86 | color: #08c; 87 | } 88 | 89 | .price, 90 | .author { 91 | color: #08c; 92 | } 93 | } 94 | } 95 | } 96 | 97 | .books-list { 98 | .book { 99 | padding-left: 12em; 100 | height: 13em; 101 | position: relative; 102 | line-height: 1.2; 103 | } 104 | 105 | .img { 106 | position: absolute; 107 | left: 0; 108 | width: 10em; 109 | 110 | img { 111 | max-width: 100%; 112 | } 113 | } 114 | 115 | .title { 116 | font-size: 1.3em; 117 | } 118 | 119 | .author { 120 | color: #888; 121 | margin-bottom: .4em; 122 | } 123 | 124 | .details { 125 | color: #aaa; 126 | font-size: .9em; 127 | 128 | span { 129 | display: inline-block; 130 | margin-right: 1em; 131 | } 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /amazing/app/assets/stylesheets/header.scss: -------------------------------------------------------------------------------- 1 | .app-header { 2 | border-bottom: 1px solid rgba(165, 221, 245, 0.61); 3 | margin-bottom: 3em; 4 | background: rgba(238, 238, 238, 0.47); 5 | 6 | .inner { 7 | padding: 1em 0; 8 | } 9 | 10 | .logo { 11 | font-size: 1.3em; 12 | float: left; 13 | } 14 | 15 | .nav { 16 | float: right; 17 | 18 | li { 19 | display: inline-block; 20 | font-size: .7em; 21 | text-transform: uppercase; 22 | letter-spacing: 1px; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /amazing/app/assets/stylesheets/layout.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Helvetica Neue', Helvetica, sans-serif; 3 | font-size: 100%; 4 | font-weight: 300; 5 | } 6 | 7 | input { 8 | font-family: 'Helvetica Neue', Helvetica, sans-serif; 9 | font-weight: 300; 10 | } 11 | 12 | a { 13 | color: #08c; 14 | text-decoration: none; 15 | 16 | &:hover { 17 | color: #f99; 18 | } 19 | } 20 | 21 | .app-cont { 22 | max-width: 60em; 23 | margin: 0 auto; 24 | } 25 | 26 | .app-title { 27 | margin-bottom: 2em; 28 | 29 | &.cf { 30 | h1 { 31 | float: left; 32 | font-size: 1.2em; 33 | } 34 | 35 | a { 36 | float: right; 37 | text-decoration: underline; 38 | font-size: .9em; 39 | display: inline-block; 40 | margin-left: 1em; 41 | } 42 | } 43 | } 44 | 45 | @media (max-width: 60em) { 46 | .app-cont { 47 | margin-left: 1em; 48 | margin-right: 1em; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /amazing/app/assets/stylesheets/pygments.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight .c { color: #999988; font-style: italic } /* Comment */ 3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 4 | .highlight .k { color: #000000; font-weight: bold } /* Keyword */ 5 | .highlight .o { color: #000000; font-weight: bold } /* Operator */ 6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 7 | .highlight .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */ 8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ 9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ 12 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 13 | .highlight .gh { color: #999999 } /* Generic.Heading */ 14 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 15 | .highlight .go { color: #888888 } /* Generic.Output */ 16 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 17 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 18 | .highlight .gu { color: #aaaaaa } /* Generic.Subheading */ 19 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 20 | .highlight .kc { color: #000000; font-weight: bold } /* Keyword.Constant */ 21 | .highlight .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */ 22 | .highlight .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */ 23 | .highlight .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */ 24 | .highlight .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */ 25 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 26 | .highlight .m { color: #009999 } /* Literal.Number */ 27 | .highlight .s { color: #d01040 } /* Literal.String */ 28 | .highlight .na { color: #008080 } /* Name.Attribute */ 29 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 30 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ 31 | .highlight .no { color: #008080 } /* Name.Constant */ 32 | .highlight .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */ 33 | .highlight .ni { color: #800080 } /* Name.Entity */ 34 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ 35 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ 36 | .highlight .nl { color: #990000; font-weight: bold } /* Name.Label */ 37 | .highlight .nn { color: #555555 } /* Name.Namespace */ 38 | .highlight .nt { color: #000080 } /* Name.Tag */ 39 | .highlight .nv { color: #008080 } /* Name.Variable */ 40 | .highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ 41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 42 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 43 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 44 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 45 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 46 | .highlight .sb { color: #d01040 } /* Literal.String.Backtick */ 47 | .highlight .sc { color: #d01040 } /* Literal.String.Char */ 48 | .highlight .sd { color: #d01040 } /* Literal.String.Doc */ 49 | .highlight .s2 { color: #d01040 } /* Literal.String.Double */ 50 | .highlight .se { color: #d01040 } /* Literal.String.Escape */ 51 | .highlight .sh { color: #d01040 } /* Literal.String.Heredoc */ 52 | .highlight .si { color: #d01040 } /* Literal.String.Interpol */ 53 | .highlight .sx { color: #d01040 } /* Literal.String.Other */ 54 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 55 | .highlight .s1 { color: #d01040 } /* Literal.String.Single */ 56 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 57 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 58 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 59 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 60 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 61 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ 62 | 63 | pre { 64 | padding: .8em; 65 | font-family: Consolas, "Liberation Mono", 'Menlo', 'Courier New', 'Terminal', monospace; 66 | font-size: 1.1em; 67 | overflow: auto; 68 | line-height: 1.5em; 69 | background: #f9f9f9; 70 | } 71 | 72 | .highlight { 73 | margin: 1em 0; 74 | 75 | } 76 | 77 | .highlight .k, 78 | .highlight .kd, 79 | .highlight .kc, 80 | .highlight .m, 81 | .highlight .nc { 82 | font-weight: normal; 83 | } 84 | 85 | p code { 86 | background-color: #F7F7F9; 87 | border: 1px solid #E1E1E8; 88 | color: #666; 89 | padding: .1em .3em; 90 | border-radius: .2em; 91 | } 92 | -------------------------------------------------------------------------------- /amazing/app/assets/stylesheets/reset.css: -------------------------------------------------------------------------------- 1 | /* RESET */ 2 | 3 | /* http://meyerweb.com/eric/tools/css/reset/ 4 | v2.0 | 20110126 5 | License: none (public domain) 6 | */ 7 | 8 | html, body, div, span, applet, object, iframe, 9 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 10 | a, abbr, acronym, address, big, cite, code, 11 | del, dfn, em, img, ins, kbd, q, s, samp, 12 | small, strike, strong, sub, sup, tt, var, 13 | b, u, i, center, 14 | dl, dt, dd, ol, ul, li, 15 | fieldset, form, label, legend, 16 | table, caption, tbody, tfoot, thead, tr, th, td, 17 | article, aside, canvas, details, embed, 18 | figure, figcaption, footer, header, hgroup, 19 | menu, nav, output, ruby, section, summary, 20 | time, mark, audio, video { 21 | margin: 0; 22 | padding: 0; 23 | border: 0; 24 | font-size: 100%; 25 | vertical-align: baseline; 26 | } 27 | /* HTML5 display-role reset for older browsers */ 28 | article, aside, details, figcaption, figure, 29 | footer, header, hgroup, menu, nav, section { 30 | display: block; 31 | } 32 | body { 33 | line-height: 1; 34 | } 35 | ol, ul { 36 | list-style: none; 37 | } 38 | blockquote, q { 39 | quotes: none; 40 | } 41 | blockquote:before, blockquote:after, 42 | q:before, q:after { 43 | content: ''; 44 | content: none; 45 | } 46 | table { 47 | border-collapse: collapse; 48 | border-spacing: 0; 49 | } 50 | 51 | .cf:before, .cf:after { content:""; display:table; } 52 | .cf:after { clear:both; } 53 | .cf { zoom:1; } 54 | 55 | *:focus { 56 | outline: none; 57 | } 58 | 59 | * { 60 | box-sizing: border-box; 61 | } 62 | -------------------------------------------------------------------------------- /amazing/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /amazing/app/controllers/books_controller.rb: -------------------------------------------------------------------------------- 1 | class BooksController < ApplicationController 2 | before_action :set_book, only: [:show, :edit, :update, :destroy] 3 | 4 | # GET /books 5 | # GET /books.json 6 | def index 7 | @books = Book.order(:title).limit(50) 8 | end 9 | 10 | def search 11 | respond_to do |format| 12 | format.html 13 | format.json { @books = Book.search(params[:term]) } 14 | end 15 | end 16 | 17 | # GET /books/1 18 | # GET /books/1.json 19 | def show 20 | end 21 | 22 | # GET /books/new 23 | def new 24 | @book = Book.new 25 | end 26 | 27 | # GET /books/1/edit 28 | def edit 29 | end 30 | 31 | # POST /books 32 | # POST /books.json 33 | def create 34 | @book = Book.new(book_params) 35 | 36 | respond_to do |format| 37 | if @book.save 38 | format.html { redirect_to @book, notice: 'Book was successfully created.' } 39 | format.json { render :show, status: :created, location: @book } 40 | else 41 | format.html { render :new } 42 | format.json { render json: @book.errors, status: :unprocessable_entity } 43 | end 44 | end 45 | end 46 | 47 | # PATCH/PUT /books/1 48 | # PATCH/PUT /books/1.json 49 | def update 50 | respond_to do |format| 51 | if @book.update(book_params) 52 | format.html { redirect_to @book, notice: 'Book was successfully updated.' } 53 | format.json { render :show, status: :ok, location: @book } 54 | else 55 | format.html { render :edit } 56 | format.json { render json: @book.errors, status: :unprocessable_entity } 57 | end 58 | end 59 | end 60 | 61 | # DELETE /books/1 62 | # DELETE /books/1.json 63 | def destroy 64 | @book.destroy 65 | respond_to do |format| 66 | format.html { redirect_to books_url, notice: 'Book was successfully destroyed.' } 67 | format.json { head :no_content } 68 | end 69 | end 70 | 71 | private 72 | # Use callbacks to share common setup or constraints between actions. 73 | def set_book 74 | @book = Book.find(params[:id]) 75 | end 76 | 77 | # Never trust parameters from the scary internet, only allow the white list through. 78 | def book_params 79 | params.require(:book).permit(:title, :author, :price, :published_at) 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /amazing/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /amazing/app/controllers/handlers_controller.rb: -------------------------------------------------------------------------------- 1 | class HandlersController < ApplicationController 2 | def index 3 | @books = [] 4 | @books << Book.new(title: 'Da Vinci Code', author: 'Dan Brown') 5 | @books << Book.new(title: 'Name of the Rose', author: 'Umberto Eco') 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /amazing/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def page_class 3 | "page-#{controller_name} #{action_name.gsub(/-/, '_')}" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /amazing/app/helpers/books_helper.rb: -------------------------------------------------------------------------------- 1 | module BooksHelper 2 | end 3 | -------------------------------------------------------------------------------- /amazing/app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/app/mailers/.keep -------------------------------------------------------------------------------- /amazing/app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/app/models/.keep -------------------------------------------------------------------------------- /amazing/app/models/book.rb: -------------------------------------------------------------------------------- 1 | class Book < ActiveRecord::Base 2 | def self.search(term) 3 | where('LOWER(title) LIKE :term OR LOWER(author) LIKE :term', term: "%#{term.downcase}%") 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /amazing/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/app/models/concerns/.keep -------------------------------------------------------------------------------- /amazing/app/views/books/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@book) do |f| %> 2 | <% if @book.errors.any? %> 3 |
    4 |

    <%= pluralize(@book.errors.count, "error") %> prohibited this book from being saved:

    5 | 6 | 11 |
    12 | <% end %> 13 | 14 |
    15 | <%= f.label :title %>
    16 | <%= f.text_field :title %> 17 |
    18 |
    19 | <%= f.label :author %>
    20 | <%= f.text_field :author %> 21 |
    22 |
    23 | <%= f.label :price %>
    24 | <%= f.text_field :price %> 25 |
    26 |
    27 | <%= f.label :published_at %>
    28 | <%= f.datetime_select :published_at %> 29 |
    30 |
    31 | <%= f.submit %> 32 |
    33 | <% end %> 34 | -------------------------------------------------------------------------------- /amazing/app/views/books/edit.html.erb: -------------------------------------------------------------------------------- 1 |

    Editing Book

    2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Show', @book %> | 6 | <%= link_to 'Back', books_path %> 7 | -------------------------------------------------------------------------------- /amazing/app/views/books/index.csv.am: -------------------------------------------------------------------------------- 1 | csv << ['Title', 'Author', 'Price', 'Publication date', 'Image url'] 2 | 3 | @books.each do |book| 4 | csv << [ 5 | book.title, 6 | book.author, 7 | number_to_currency(book.price), 8 | book.published_at.strftime('%B %Y'), 9 | book.image_url 10 | ] 11 | end 12 | -------------------------------------------------------------------------------- /amazing/app/views/books/index.html.erb: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |

    Books

    5 | <%= link_to 'New Book', new_book_path %> 6 | <%= link_to 'Download (CSV)', books_path(:format => :csv) %> 7 |
    8 | 9 |
    10 | <% @books.each do |book| %> 11 |
    12 |

    13 | <%= image_tag book.image_url %> 14 |

    15 |

    <%= book.title %>

    16 |

    by <%= book.author %>

    17 |

    18 | <%= number_to_currency(book.price) %> 19 | Published on <%= book.published_at.strftime('%B %Y') %> 20 |

    21 |
    22 | <% end %> 23 |
    24 | 25 |
    26 | 27 | -------------------------------------------------------------------------------- /amazing/app/views/books/new.html.erb: -------------------------------------------------------------------------------- 1 |

    New Book

    2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Back', books_path %> 6 | -------------------------------------------------------------------------------- /amazing/app/views/books/search.html.erb: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |

    Books

    5 | <%= link_to 'New Book', new_book_path %> 6 |
    7 | 8 |
    9 | 13 |
    14 | 15 |
    16 | 17 | <%= content_for :script do %> 18 | new app.Books; 19 | <% end %> 20 | -------------------------------------------------------------------------------- /amazing/app/views/books/search.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array!(@books) do |book| 2 | json.title book.title 3 | json.author book.author 4 | json.price number_to_currency(book.price) 5 | json.published_at book.published_at.strftime('%B %Y') 6 | json.image_url book.image_url 7 | end 8 | -------------------------------------------------------------------------------- /amazing/app/views/books/show.html.erb: -------------------------------------------------------------------------------- 1 |

    <%= notice %>

    2 | 3 |

    4 | Title: 5 | <%= @book.title %> 6 |

    7 | 8 |

    9 | Author: 10 | <%= @book.author %> 11 |

    12 | 13 |

    14 | Price: 15 | <%= @book.price %> 16 |

    17 | 18 |

    19 | Published at: 20 | <%= @book.published_at %> 21 |

    22 | 23 | <%= link_to 'Edit', edit_book_path(@book) %> | 24 | <%= link_to 'Back', books_path %> 25 | -------------------------------------------------------------------------------- /amazing/app/views/books/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @book, :id, :title, :author, :price, :published_at, :created_at, :updated_at 2 | -------------------------------------------------------------------------------- /amazing/app/views/handlers/index.csv.am: -------------------------------------------------------------------------------- 1 | csv << ['Title', 'Author'] 2 | 3 | @books.each do |book| 4 | csv << [ 5 | book.title, 6 | book.author 7 | ] 8 | end 9 | -------------------------------------------------------------------------------- /amazing/app/views/handlers/index.html.md: -------------------------------------------------------------------------------- 1 | **Markdown** is great. 2 | 3 | ```js 4 | var foo = 111; 5 | ``` 6 | -------------------------------------------------------------------------------- /amazing/app/views/layouts/_header.html.erb: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    4 | <%= link_to 'amazing books', root_path %> 5 |

    6 | 7 | 10 |
    11 |
    12 | -------------------------------------------------------------------------------- /amazing/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Amazing 5 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> 6 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= render 'layouts/header' %> 12 | <%= yield %> 13 | 14 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /amazing/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /amazing/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | require_relative '../config/boot' 8 | require 'rails/commands' 9 | -------------------------------------------------------------------------------- /amazing/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | require_relative '../config/boot' 7 | require 'rake' 8 | Rake.application.run 9 | -------------------------------------------------------------------------------- /amazing/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /amazing/bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m) 11 | Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq } 12 | gem "spring", match[1] 13 | require "spring/binstub" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /amazing/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /amazing/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Amazing 10 | class Application < Rails::Application 11 | config.autoload_paths += %W(#{config.root}/lib) 12 | 13 | # Settings in config/environments/* take precedence over those specified here. 14 | # Application configuration should go into files in config/initializers 15 | # -- all .rb files in that directory are automatically loaded. 16 | 17 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 18 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 19 | # config.time_zone = 'Central Time (US & Canada)' 20 | 21 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 22 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 23 | # config.i18n.default_locale = :de 24 | 25 | # Do not swallow errors in after_commit/after_rollback callbacks. 26 | config.active_record.raise_in_transactional_callbacks = true 27 | 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /amazing/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /amazing/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | development: 13 | <<: *default 14 | database: db/development.sqlite3 15 | 16 | # Warning: The database defined as "test" will be erased and 17 | # re-generated from your development database when you run "rake". 18 | # Do not set this db to the same as development or production. 19 | test: 20 | <<: *default 21 | database: db/test.sqlite3 22 | 23 | production: 24 | <<: *default 25 | database: db/production.sqlite3 26 | -------------------------------------------------------------------------------- /amazing/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /amazing/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /amazing/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like 20 | # NGINX, varnish or squid. 21 | # config.action_dispatch.rack_cache = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? 26 | 27 | # Compress JavaScripts and CSS. 28 | config.assets.js_compressor = :uglifier 29 | # config.assets.css_compressor = :sass 30 | 31 | # Do not fallback to assets pipeline if a precompiled asset is missed. 32 | config.assets.compile = false 33 | 34 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 35 | # yet still be able to expire them through the digest params. 36 | config.assets.digest = true 37 | 38 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 39 | 40 | # Specifies the header that your server uses for sending files. 41 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 42 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 43 | 44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 45 | # config.force_ssl = true 46 | 47 | # Use the lowest log level to ensure availability of diagnostic information 48 | # when problems arise. 49 | config.log_level = :debug 50 | 51 | # Prepend all log lines with the following tags. 52 | # config.log_tags = [ :subdomain, :uuid ] 53 | 54 | # Use a different logger for distributed setups. 55 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 56 | 57 | # Use a different cache store in production. 58 | # config.cache_store = :mem_cache_store 59 | 60 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 61 | # config.action_controller.asset_host = 'http://assets.example.com' 62 | 63 | # Ignore bad email addresses and do not raise email delivery errors. 64 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 65 | # config.action_mailer.raise_delivery_errors = false 66 | 67 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 68 | # the I18n.default_locale when a translation cannot be found). 69 | config.i18n.fallbacks = true 70 | 71 | # Send deprecation notices to registered listeners. 72 | config.active_support.deprecation = :notify 73 | 74 | # Use default logging formatter so that PID and timestamp are not suppressed. 75 | config.log_formatter = ::Logger::Formatter.new 76 | 77 | # Do not dump schema after migrations. 78 | config.active_record.dump_schema_after_migration = false 79 | end 80 | -------------------------------------------------------------------------------- /amazing/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static file server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Randomize the order test cases are executed. 35 | config.active_support.test_order = :random 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /amazing/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /amazing/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /amazing/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | 5 | 6 | -------------------------------------------------------------------------------- /amazing/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /amazing/config/initializers/handlers.rb: -------------------------------------------------------------------------------- 1 | ActionView::Template.register_template_handler :md, MarkdownHandler 2 | ActionView::Template.register_template_handler :am, CsvHandler::Handler 3 | -------------------------------------------------------------------------------- /amazing/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /amazing/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register "text/csv", :csv 6 | -------------------------------------------------------------------------------- /amazing/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_amazing_session' 4 | -------------------------------------------------------------------------------- /amazing/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /amazing/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /amazing/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | resources :books do 3 | get :search, :on => :collection 4 | end 5 | 6 | resources :handlers, :only => [:index] 7 | 8 | root 'books#index' 9 | end 10 | -------------------------------------------------------------------------------- /amazing/config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: 5d7aaad4c5f6ef629e9028aba09d7f9c3ff771e709274f3bc94885fd7f4cddeaab0be36e2ba88f7f8c5af3023f985491c9e316cab4e90a53af56d1735fe57ca0 15 | 16 | test: 17 | secret_key_base: c2c74b46f4ae0e94ad818d4a7e02d318c84c4d26c7810f6c45f8bc55767d7a23dba75a16ec841c0f898a059c8b3fd270bd9d0e702b2f05f417b876523caf635f 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /amazing/db/migrate/20150620072912_create_books.rb: -------------------------------------------------------------------------------- 1 | class CreateBooks < ActiveRecord::Migration 2 | def change 3 | create_table :books do |t| 4 | t.string :title 5 | t.string :author 6 | t.decimal :price 7 | t.datetime :published_at 8 | t.string :image_url 9 | 10 | t.timestamps null: false 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /amazing/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20150620072912) do 15 | 16 | create_table "books", force: :cascade do |t| 17 | t.string "title" 18 | t.string "author" 19 | t.decimal "price" 20 | t.datetime "published_at" 21 | t.string "image_url" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /amazing/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | 5 | Book.create([ 6 | { title: "Sapiens: A Brief History of Humankind", author: "Yuval Noah Harari", price: 16.0, published_at: DateTime.new(2015, 2, 12), image_url: "http://ecx.images-amazon.com/images/I/415tYy%2BYfEL._AA160_.jpg" }, 7 | { title: "Humans of New York", author: "Brandon Stanton", price: 22.0, published_at: DateTime.new(2013, 5, 12), image_url: "http://ecx.images-amazon.com/images/I/61zFR-dbLfL._AA160_.jpg" }, 8 | { title: "Capital in the Twenty-First Century", author: "Thomas Piketty and Arthur Goldhammer", price: 11.0, published_at: DateTime.new(2015, 5, 12), image_url: "http://ecx.images-amazon.com/images/I/41FDimPnPEL._AA160_.jpg" }, 9 | { title: "The Boys in the Boat", author: "Daniel James Brown", price: 26.0, published_at: DateTime.new(2015, 5, 12), image_url: "http://ecx.images-amazon.com/images/I/51bbeZOdp5L._AA160_.jpg" }, 10 | { title: "Red Notice: A True Story of High Finance, Murder, and One Man's Fight for Justice", author: "Bill Browder", price: 16.0, published_at: DateTime.new(2015, 5, 12), image_url: "http://ecx.images-amazon.com/images/I/510UWROQjSL._AA160_.jpg" }, 11 | { title: "The Innovators: How a Group of Hackers, Geniuses, and Geeks Created the Digital Revolution", author: "Walter Isaacson", price: 16.0, published_at: DateTime.new(2015, 5, 12), image_url: "http://ecx.images-amazon.com/images/I/519KsxAU05L._AA160_.jpg" }, 12 | { title: "The Half Has Never Been Told: Slavery and the Making of American Capitalism", author: "Edward E. Baptist", price: 16.0, published_at: DateTime.new(2014, 5, 12), image_url: "http://ecx.images-amazon.com/images/I/51RGjjDctHL._AA160_.jpg" }, 13 | { title: "Deep Down Dark: The Untold Stories of 33 Men Buried in a Chilean Mine, and the Miracle That Set Them Free", author: "Héctor Tobar", price: 36.0, published_at: DateTime.new(2014, 10, 12), image_url: "http://ecx.images-amazon.com/images/I/51u9DXPdbkL._AA160_.jpg" }, 14 | { title: "Undeniable: Evolution and the Science of Creation", author: "Bill Nye and Corey S. Powell", price: 16.0, published_at: DateTime.new(2014, 11, 12), image_url: "http://ecx.images-amazon.com/images/I/51jIthhp2HL._AA160_.jpg" } 15 | ]) 16 | -------------------------------------------------------------------------------- /amazing/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/lib/assets/.keep -------------------------------------------------------------------------------- /amazing/lib/csv_handler.rb: -------------------------------------------------------------------------------- 1 | require 'csv' 2 | 3 | module CsvHandler 4 | class CsvGenerator 5 | def self.generate 6 | file = CSV.generate do |csv| 7 | yield csv 8 | end 9 | file.html_safe 10 | end 11 | end 12 | 13 | class Handler 14 | def self.call (template) 15 | %{ 16 | CsvHandler::CsvGenerator.generate do |csv| 17 | #{template.source} 18 | end 19 | } 20 | end 21 | end 22 | end 23 | 24 | -------------------------------------------------------------------------------- /amazing/lib/markdown_handler.rb: -------------------------------------------------------------------------------- 1 | class MarkdownHandler 2 | class << self 3 | def call(template) 4 | compiled_source = erb.call(template) 5 | "MarkdownHandler.render(begin;#{compiled_source};end)" 6 | end 7 | 8 | def render(text) 9 | key = cache_key(text) 10 | Rails.cache.fetch key do 11 | markdown.render(text).html_safe 12 | end 13 | end 14 | 15 | private 16 | 17 | def cache_key(text) 18 | Digest::MD5.hexdigest(text) 19 | end 20 | 21 | def markdown 22 | @markdown ||= Redcarpet::Markdown.new(HTMLWithPygments, fenced_code_blocks: true, autolink: true, space_after_headers: true) 23 | end 24 | 25 | def erb 26 | @erb ||= ActionView::Template.registered_template_handler(:erb) 27 | end 28 | end 29 | 30 | class HTMLWithPygments < Redcarpet::Render::HTML 31 | def block_code(code, lang) 32 | lang = lang && lang.split.first || "text" 33 | output = add_code_tags( 34 | Pygmentize.process(code, lang), lang 35 | ) 36 | end 37 | 38 | def add_code_tags(code, lang) 39 | code = code.sub(/
    /,'
    ' + lang + '
    ')
    40 |       code = code.sub(/<\/pre>/,"
    ") 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /amazing/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/lib/tasks/.keep -------------------------------------------------------------------------------- /amazing/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/log/.keep -------------------------------------------------------------------------------- /amazing/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    The page you were looking for doesn't exist.

    62 |

    You may have mistyped the address or the page may have moved.

    63 |
    64 |

    If you are the application owner check the logs for more information.

    65 |
    66 | 67 | 68 | -------------------------------------------------------------------------------- /amazing/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    The change you wanted was rejected.

    62 |

    Maybe you tried to change something you didn't have access to.

    63 |
    64 |

    If you are the application owner check the logs for more information.

    65 |
    66 | 67 | 68 | -------------------------------------------------------------------------------- /amazing/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    We're sorry, but something went wrong.

    62 |
    63 |

    If you are the application owner check the logs for more information.

    64 |
    65 | 66 | 67 | -------------------------------------------------------------------------------- /amazing/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/public/favicon.ico -------------------------------------------------------------------------------- /amazing/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /amazing/test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/test/controllers/.keep -------------------------------------------------------------------------------- /amazing/test/controllers/books_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BooksControllerTest < ActionController::TestCase 4 | setup do 5 | @book = books(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:books) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create book" do 20 | assert_difference('Book.count') do 21 | post :create, book: { author: @book.author, price: @book.price, published_at: @book.published_at, title: @book.title } 22 | end 23 | 24 | assert_redirected_to book_path(assigns(:book)) 25 | end 26 | 27 | test "should show book" do 28 | get :show, id: @book 29 | assert_response :success 30 | end 31 | 32 | test "should get edit" do 33 | get :edit, id: @book 34 | assert_response :success 35 | end 36 | 37 | test "should update book" do 38 | patch :update, id: @book, book: { author: @book.author, price: @book.price, published_at: @book.published_at, title: @book.title } 39 | assert_redirected_to book_path(assigns(:book)) 40 | end 41 | 42 | test "should destroy book" do 43 | assert_difference('Book.count', -1) do 44 | delete :destroy, id: @book 45 | end 46 | 47 | assert_redirected_to books_path 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /amazing/test/fixtures/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/test/fixtures/.keep -------------------------------------------------------------------------------- /amazing/test/fixtures/books.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | title: MyString 5 | author: MyString 6 | price: 9.99 7 | published_at: 2015-06-20 08:29:12 8 | 9 | two: 10 | title: MyString 11 | author: MyString 12 | price: 9.99 13 | published_at: 2015-06-20 08:29:12 14 | -------------------------------------------------------------------------------- /amazing/test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/test/helpers/.keep -------------------------------------------------------------------------------- /amazing/test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/test/integration/.keep -------------------------------------------------------------------------------- /amazing/test/integration/csv_handler_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CsvHandlerTest < ActionDispatch::IntegrationTest 4 | test ".csv renders CSV" do 5 | get '/handlers.csv' 6 | assert_equal "Title,Author\nDa Vinci Code,Dan Brown\nName of the Rose,Umberto Eco\n", response.body 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /amazing/test/integration/markdown_handler_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MarkdownHandlerTest < ActionDispatch::IntegrationTest 4 | test ".md renders markdown" do 5 | get '/handlers.md' 6 | assert_match 'Markdown is great.', response.body, "tags" 7 | assert_match '', response.body, "language class" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /amazing/test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/test/mailers/.keep -------------------------------------------------------------------------------- /amazing/test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/test/models/.keep -------------------------------------------------------------------------------- /amazing/test/models/book_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BookTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /amazing/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 7 | fixtures :all 8 | 9 | # Add more helper methods to be used by all tests here... 10 | end 11 | -------------------------------------------------------------------------------- /amazing/vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /amazing/vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/amazing/vendor/assets/stylesheets/.keep -------------------------------------------------------------------------------- /colorpicker/app.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | background: #2F4347; 4 | margin: 0; 5 | padding: 0; 6 | text-align: center; 7 | } 8 | 9 | .container { 10 | margin: 3em auto; 11 | width: 20em; 12 | } 13 | 14 | .result { 15 | width: 5em; 16 | height: 5em; 17 | border-radius: 30%; 18 | box-shadow: 0 2px 6px #000; 19 | background: #95C066; 20 | display: inline-block; 21 | vertical-align: middle; 22 | margin-left: 2em; 23 | } 24 | 25 | .output { 26 | margin-bottom: 5em; 27 | padding: 1em; 28 | color: #fff; 29 | border-bottom: 2px dashed #42595E; 30 | text-align: center; 31 | text-transform: uppercase; 32 | font-size: .8em; 33 | text-shadow: 0 -1px 0 #2B3E42; 34 | color: #475D62; 35 | } 36 | 37 | /* spectrum */ 38 | .sp-container { 39 | border: none; 40 | box-shadow: 0 0 .8em #aaa; 41 | } 42 | 43 | .sp-replacer { 44 | background: transparent; 45 | padding-right: 14px; 46 | border-color: #475D62; 47 | } 48 | 49 | .sp-replacer:hover, 50 | .sp-replacer.sp-active { 51 | border-color: #536E74; 52 | } 53 | 54 | .sp-preview { 55 | position: relative; 56 | border: none; 57 | } 58 | 59 | .sp-preview:before { 60 | content: ''; 61 | position: absolute; 62 | top: 7px; 63 | left: 30px; 64 | border-top: 5px solid #5D7980; 65 | border-left: 5px solid transparent; 66 | border-right: 5px solid transparent; 67 | } 68 | 69 | .sp-replacer:hover .sp-preview:before, 70 | .sp-replacer.sp-active .sp-preview:before { 71 | border-top-color: #819BA1; 72 | } 73 | 74 | .sp-preview:after { 75 | content: ''; 76 | position: absolute; 77 | top: 7px; 78 | left: 31px; 79 | border-top: 4px solid #2F4347; 80 | border-left: 4px solid transparent; 81 | border-right: 4px solid transparent; 82 | } 83 | 84 | .sp-dd { 85 | display: none; 86 | } 87 | 88 | .sp-container button { 89 | background: transparent; 90 | font-size: 1em; 91 | text-shadow: none; 92 | border-radius: 1em; 93 | padding-left: .8em; 94 | padding-right: .8em; 95 | box-shadow: none; 96 | outline: none; 97 | } 98 | 99 | /* footer */ 100 | 101 | .footer { 102 | position: absolute; 103 | bottom: 1em; 104 | width: 100%; 105 | } 106 | 107 | .footer a, .footer a:visited { 108 | color: #64848B; 109 | text-decoration: none; 110 | } 111 | 112 | .footer a:hover { 113 | color: #fff; 114 | } 115 | -------------------------------------------------------------------------------- /colorpicker/app.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var app = { 3 | start: function() { 4 | this.output = $('#output'); 5 | this.result = $('#result'); 6 | var self = this, 7 | initialColor = this.result.css('background'); 8 | var colorPicker = $('#color-picker').spectrum({ 9 | chooseText: 'ok', 10 | color: initialColor, 11 | move: function(col) { self.onMove(col.toHexString()); }, 12 | change: function(col) { self.onChange(col.toHexString()); }, 13 | hide: function(col) { self.onHide(col.toHexString()); } 14 | }); 15 | this.broadcast(colorPicker.spectrum('get').toHexString()); 16 | }, 17 | 18 | onMove: function(color) { 19 | this.result.css('background', color); 20 | }, 21 | 22 | onChange: function(color) { 23 | this.result.css('background', color); 24 | this.broadcast(color); 25 | }, 26 | 27 | onHide: function(color) { 28 | this.result.css('background', color); 29 | this.broadcast(color); 30 | }, 31 | 32 | broadcast: function(color) { 33 | this.output.html('Final color: ' + color); 34 | } 35 | }; 36 | 37 | $(function () { 38 | app.start(); 39 | }); 40 | })(); 41 | -------------------------------------------------------------------------------- /colorpicker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | colorpicker 5 | 6 | 7 | 8 | 9 |
    10 |
    11 | 12 |
    13 | 14 | 15 |
    16 |
    17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /colorpicker/spectrum.css: -------------------------------------------------------------------------------- 1 | /*** 2 | Spectrum Colorpicker v1.6.1 3 | https://github.com/bgrins/spectrum 4 | Author: Brian Grinstead 5 | License: MIT 6 | ***/ 7 | 8 | .sp-container { 9 | position:absolute; 10 | top:0; 11 | left:0; 12 | display:inline-block; 13 | *display: inline; 14 | *zoom: 1; 15 | /* https://github.com/bgrins/spectrum/issues/40 */ 16 | z-index: 9999994; 17 | overflow: hidden; 18 | } 19 | .sp-container.sp-flat { 20 | position: relative; 21 | } 22 | 23 | /* Fix for * { box-sizing: border-box; } */ 24 | .sp-container, 25 | .sp-container * { 26 | -webkit-box-sizing: content-box; 27 | -moz-box-sizing: content-box; 28 | box-sizing: content-box; 29 | } 30 | 31 | /* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */ 32 | .sp-top { 33 | position:relative; 34 | width: 100%; 35 | display:inline-block; 36 | } 37 | .sp-top-inner { 38 | position:absolute; 39 | top:0; 40 | left:0; 41 | bottom:0; 42 | right:0; 43 | } 44 | .sp-color { 45 | position: absolute; 46 | top:0; 47 | left:0; 48 | bottom:0; 49 | right:20%; 50 | } 51 | .sp-hue { 52 | position: absolute; 53 | top:0; 54 | right:0; 55 | bottom:0; 56 | left:84%; 57 | height: 100%; 58 | } 59 | 60 | .sp-clear-enabled .sp-hue { 61 | top:33px; 62 | height: 77.5%; 63 | } 64 | 65 | .sp-fill { 66 | padding-top: 80%; 67 | } 68 | .sp-sat, .sp-val { 69 | position: absolute; 70 | top:0; 71 | left:0; 72 | right:0; 73 | bottom:0; 74 | } 75 | 76 | .sp-alpha-enabled .sp-top { 77 | margin-bottom: 18px; 78 | } 79 | .sp-alpha-enabled .sp-alpha { 80 | display: block; 81 | } 82 | .sp-alpha-handle { 83 | position:absolute; 84 | top:-4px; 85 | bottom: -4px; 86 | width: 6px; 87 | left: 50%; 88 | cursor: pointer; 89 | border: 1px solid black; 90 | background: white; 91 | opacity: .8; 92 | } 93 | .sp-alpha { 94 | display: none; 95 | position: absolute; 96 | bottom: -14px; 97 | right: 0; 98 | left: 0; 99 | height: 8px; 100 | } 101 | .sp-alpha-inner { 102 | border: solid 1px #333; 103 | } 104 | 105 | .sp-clear { 106 | display: none; 107 | } 108 | 109 | .sp-clear.sp-clear-display { 110 | background-position: center; 111 | } 112 | 113 | .sp-clear-enabled .sp-clear { 114 | display: block; 115 | position:absolute; 116 | top:0px; 117 | right:0; 118 | bottom:0; 119 | left:84%; 120 | height: 28px; 121 | } 122 | 123 | /* Don't allow text selection */ 124 | .sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button { 125 | -webkit-user-select:none; 126 | -moz-user-select: -moz-none; 127 | -o-user-select:none; 128 | user-select: none; 129 | } 130 | 131 | .sp-container.sp-input-disabled .sp-input-container { 132 | display: none; 133 | } 134 | .sp-container.sp-buttons-disabled .sp-button-container { 135 | display: none; 136 | } 137 | .sp-container.sp-palette-buttons-disabled .sp-palette-button-container { 138 | display: none; 139 | } 140 | .sp-palette-only .sp-picker-container { 141 | display: none; 142 | } 143 | .sp-palette-disabled .sp-palette-container { 144 | display: none; 145 | } 146 | 147 | .sp-initial-disabled .sp-initial { 148 | display: none; 149 | } 150 | 151 | 152 | /* Gradients for hue, saturation and value instead of images. Not pretty... but it works */ 153 | .sp-sat { 154 | background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0))); 155 | background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0)); 156 | background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); 157 | background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); 158 | background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); 159 | background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0)); 160 | -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)"; 161 | filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81'); 162 | } 163 | .sp-val { 164 | background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0))); 165 | background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); 166 | background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); 167 | background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); 168 | background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); 169 | background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0)); 170 | -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)"; 171 | filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000'); 172 | } 173 | 174 | .sp-hue { 175 | background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); 176 | background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); 177 | background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); 178 | background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000)); 179 | background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); 180 | background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); 181 | } 182 | 183 | /* IE filters do not support multiple color stops. 184 | Generate 6 divs, line them up, and do two color gradients for each. 185 | Yes, really. 186 | */ 187 | .sp-1 { 188 | height:17%; 189 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00'); 190 | } 191 | .sp-2 { 192 | height:16%; 193 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00'); 194 | } 195 | .sp-3 { 196 | height:17%; 197 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff'); 198 | } 199 | .sp-4 { 200 | height:17%; 201 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff'); 202 | } 203 | .sp-5 { 204 | height:16%; 205 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff'); 206 | } 207 | .sp-6 { 208 | height:17%; 209 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000'); 210 | } 211 | 212 | .sp-hidden { 213 | display: none !important; 214 | } 215 | 216 | /* Clearfix hack */ 217 | .sp-cf:before, .sp-cf:after { content: ""; display: table; } 218 | .sp-cf:after { clear: both; } 219 | .sp-cf { *zoom: 1; } 220 | 221 | /* Mobile devices, make hue slider bigger so it is easier to slide */ 222 | @media (max-device-width: 480px) { 223 | .sp-color { right: 40%; } 224 | .sp-hue { left: 63%; } 225 | .sp-fill { padding-top: 60%; } 226 | } 227 | .sp-dragger { 228 | border-radius: 5px; 229 | height: 5px; 230 | width: 5px; 231 | border: 1px solid #fff; 232 | background: #000; 233 | cursor: pointer; 234 | position:absolute; 235 | top:0; 236 | left: 0; 237 | } 238 | .sp-slider { 239 | position: absolute; 240 | top:0; 241 | cursor:pointer; 242 | height: 3px; 243 | left: -1px; 244 | right: -1px; 245 | border: 1px solid #000; 246 | background: white; 247 | opacity: .8; 248 | } 249 | 250 | /* 251 | Theme authors: 252 | Here are the basic themeable display options (colors, fonts, global widths). 253 | See http://bgrins.github.io/spectrum/themes/ for instructions. 254 | */ 255 | 256 | .sp-container { 257 | border-radius: 0; 258 | background-color: #ECECEC; 259 | border: solid 1px #f0c49B; 260 | padding: 0; 261 | } 262 | .sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear { 263 | font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; 264 | -webkit-box-sizing: border-box; 265 | -moz-box-sizing: border-box; 266 | -ms-box-sizing: border-box; 267 | box-sizing: border-box; 268 | } 269 | .sp-top { 270 | margin-bottom: 3px; 271 | } 272 | .sp-color, .sp-hue, .sp-clear { 273 | border: solid 1px #666; 274 | } 275 | 276 | /* Input */ 277 | .sp-input-container { 278 | float:right; 279 | width: 100px; 280 | margin-bottom: 4px; 281 | } 282 | .sp-initial-disabled .sp-input-container { 283 | width: 100%; 284 | } 285 | .sp-input { 286 | font-size: 12px !important; 287 | border: 1px inset; 288 | padding: 4px 5px; 289 | margin: 0; 290 | width: 100%; 291 | background:transparent; 292 | border-radius: 3px; 293 | color: #222; 294 | } 295 | .sp-input:focus { 296 | border: 1px solid orange; 297 | } 298 | .sp-input.sp-validation-error { 299 | border: 1px solid red; 300 | background: #fdd; 301 | } 302 | .sp-picker-container , .sp-palette-container { 303 | float:left; 304 | position: relative; 305 | padding: 10px; 306 | padding-bottom: 300px; 307 | margin-bottom: -290px; 308 | } 309 | .sp-picker-container { 310 | width: 172px; 311 | border-left: solid 1px #fff; 312 | } 313 | 314 | /* Palettes */ 315 | .sp-palette-container { 316 | border-right: solid 1px #ccc; 317 | } 318 | 319 | .sp-palette-only .sp-palette-container { 320 | border: 0; 321 | } 322 | 323 | .sp-palette .sp-thumb-el { 324 | display: block; 325 | position:relative; 326 | float:left; 327 | width: 24px; 328 | height: 15px; 329 | margin: 3px; 330 | cursor: pointer; 331 | border:solid 2px transparent; 332 | } 333 | .sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active { 334 | border-color: orange; 335 | } 336 | .sp-thumb-el { 337 | position:relative; 338 | } 339 | 340 | /* Initial */ 341 | .sp-initial { 342 | float: left; 343 | border: solid 1px #333; 344 | } 345 | .sp-initial span { 346 | width: 30px; 347 | height: 25px; 348 | border:none; 349 | display:block; 350 | float:left; 351 | margin:0; 352 | } 353 | 354 | .sp-initial .sp-clear-display { 355 | background-position: center; 356 | } 357 | 358 | /* Buttons */ 359 | .sp-palette-button-container, 360 | .sp-button-container { 361 | float: right; 362 | } 363 | 364 | /* Replacer (the little preview div that shows up instead of the ) */ 365 | .sp-replacer { 366 | margin:0; 367 | overflow:hidden; 368 | cursor:pointer; 369 | padding: 4px; 370 | display:inline-block; 371 | *zoom: 1; 372 | *display: inline; 373 | border: solid 1px #91765d; 374 | background: #eee; 375 | color: #333; 376 | vertical-align: middle; 377 | } 378 | .sp-replacer:hover, .sp-replacer.sp-active { 379 | border-color: #F0C49B; 380 | color: #111; 381 | } 382 | .sp-replacer.sp-disabled { 383 | cursor:default; 384 | border-color: silver; 385 | color: silver; 386 | } 387 | .sp-dd { 388 | padding: 2px 0; 389 | height: 16px; 390 | line-height: 16px; 391 | float:left; 392 | font-size:10px; 393 | } 394 | .sp-preview { 395 | position:relative; 396 | width:25px; 397 | height: 20px; 398 | border: solid 1px #222; 399 | margin-right: 5px; 400 | float:left; 401 | z-index: 0; 402 | } 403 | 404 | .sp-palette { 405 | *width: 220px; 406 | max-width: 220px; 407 | } 408 | .sp-palette .sp-thumb-el { 409 | width:16px; 410 | height: 16px; 411 | margin:2px 1px; 412 | border: solid 1px #d0d0d0; 413 | } 414 | 415 | .sp-container { 416 | padding-bottom:0; 417 | } 418 | 419 | 420 | /* Buttons: http://hellohappy.org/css3-buttons/ */ 421 | .sp-container button { 422 | background-color: #eeeeee; 423 | background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc); 424 | background-image: -moz-linear-gradient(top, #eeeeee, #cccccc); 425 | background-image: -ms-linear-gradient(top, #eeeeee, #cccccc); 426 | background-image: -o-linear-gradient(top, #eeeeee, #cccccc); 427 | background-image: linear-gradient(to bottom, #eeeeee, #cccccc); 428 | border: 1px solid #ccc; 429 | border-bottom: 1px solid #bbb; 430 | border-radius: 3px; 431 | color: #333; 432 | font-size: 14px; 433 | line-height: 1; 434 | padding: 5px 4px; 435 | text-align: center; 436 | text-shadow: 0 1px 0 #eee; 437 | vertical-align: middle; 438 | } 439 | .sp-container button:hover { 440 | background-color: #dddddd; 441 | background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb); 442 | background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb); 443 | background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb); 444 | background-image: -o-linear-gradient(top, #dddddd, #bbbbbb); 445 | background-image: linear-gradient(to bottom, #dddddd, #bbbbbb); 446 | border: 1px solid #bbb; 447 | border-bottom: 1px solid #999; 448 | cursor: pointer; 449 | text-shadow: 0 1px 0 #ddd; 450 | } 451 | .sp-container button:active { 452 | border: 1px solid #aaa; 453 | border-bottom: 1px solid #888; 454 | -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; 455 | -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; 456 | -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; 457 | -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; 458 | box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; 459 | } 460 | .sp-cancel { 461 | font-size: 11px; 462 | color: #d93f3f !important; 463 | margin:0; 464 | padding:2px; 465 | margin-right: 5px; 466 | vertical-align: middle; 467 | text-decoration:none; 468 | 469 | } 470 | .sp-cancel:hover { 471 | color: #d93f3f !important; 472 | text-decoration: underline; 473 | } 474 | 475 | 476 | .sp-palette span:hover, .sp-palette span.sp-thumb-active { 477 | border-color: #000; 478 | } 479 | 480 | .sp-preview, .sp-alpha, .sp-thumb-el { 481 | position:relative; 482 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); 483 | } 484 | .sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner { 485 | display:block; 486 | position:absolute; 487 | top:0;left:0;bottom:0;right:0; 488 | } 489 | 490 | .sp-palette .sp-thumb-inner { 491 | background-position: 50% 50%; 492 | background-repeat: no-repeat; 493 | } 494 | 495 | .sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner { 496 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=); 497 | } 498 | 499 | .sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner { 500 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=); 501 | } 502 | 503 | .sp-clear-display { 504 | background-repeat:no-repeat; 505 | background-position: center; 506 | background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==); 507 | } 508 | -------------------------------------------------------------------------------- /covers/covers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Covers 5 | 6 | 60 | 61 | 62 |
    63 |
    64 |

    Covers

    65 |
      66 |
      67 |
        68 |
        69 | 70 | 71 | 72 | 73 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /monthly/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jQuery Monthly 5 | 6 | 7 | 17 | 18 | 19 | 20 |
        21 | 22 |
        23 | 24 | 25 | 26 | 27 | 28 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /monthly/jquery.monthly.css: -------------------------------------------------------------------------------- 1 | .monthly-wrp { 2 | border: 1px solid #eee; 3 | padding: 1em; 4 | top: 6px; 5 | z-index: 1000; 6 | box-shadow: 0 0 5px rgba(153, 153, 153, 0.2); 7 | border-radius: .2em; 8 | background: #fff; 9 | } 10 | 11 | .monthly-wrp:before { 12 | content: ''; 13 | border-bottom: 6px solid #fff; 14 | border-left: 6px solid transparent; 15 | border-right: 6px solid transparent; 16 | position: absolute; 17 | top: -6px; 18 | left: 6px; 19 | z-index: 1002; 20 | } 21 | 22 | .monthly-wrp:after { 23 | content: ''; 24 | border-bottom: 6px solid #eee; 25 | border-left: 6px solid transparent; 26 | border-right: 6px solid transparent; 27 | position: absolute; 28 | top: -7px; 29 | left: 6px; 30 | z-index: 1001; 31 | } 32 | 33 | .monthly-wrp .years { 34 | margin-bottom: .8em; 35 | text-align: center; 36 | } 37 | 38 | .monthly-wrp .years select { 39 | font-size: 1em; 40 | width: 100%; 41 | } 42 | 43 | .monthly-wrp .years select:focus { 44 | outline: none; 45 | } 46 | 47 | .monthly-wrp table { 48 | border-collapse: collapse; 49 | table-layout: fixed; 50 | } 51 | 52 | .monthly-wrp td { 53 | padding: .1em; 54 | } 55 | 56 | .monthly-wrp table button { 57 | width: 100%; 58 | border: none; 59 | background: #F7EEEE; 60 | font-size: .8em; 61 | padding: .6em; 62 | cursor: pointer; 63 | border-radius: .2em; 64 | } 65 | 66 | .monthly-wrp table button:hover { 67 | background: #EFDDDD; 68 | } 69 | 70 | .monthly-wrp table button:focus { 71 | outline: none; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /monthly/jquery.monthly.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.monthly = function(options) { 4 | 5 | var months = options.months || ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 6 | 7 | Monthly = function(el) { 8 | this._el = $(el); 9 | this._init(); 10 | this._render(); 11 | this._renderYears(); 12 | this._renderMonths(); 13 | this._bind(); 14 | }; 15 | 16 | Monthly.prototype = { 17 | _init: function() { 18 | this._el.html(months[0] + ' ' + options.years[0]); 19 | }, 20 | 21 | _render: function() { 22 | var linkPosition = this._el.offset(), 23 | cssOptions = { 24 | display: 'none', 25 | position: 'absolute', 26 | top: linkPosition.top + this._el.height() + (options.topOffset || 0), 27 | left: linkPosition.left 28 | }; 29 | this._container = $('
        ') 30 | .css(cssOptions) 31 | .appendTo($('body')); 32 | }, 33 | 34 | _bind: function() { 35 | var self = this; 36 | this._el.on('click', $.proxy(this._show, this)); 37 | $(document).on('click', $.proxy(this._hide, this)); 38 | this._yearsSelect.on('click', function(e) { e.stopPropagation(); }); 39 | this._container.on('click', 'button', $.proxy(this._selectMonth, this)); 40 | }, 41 | 42 | _show: function(e) { 43 | e.preventDefault(); 44 | e.stopPropagation(); 45 | this._container.css('display', 'inline-block'); 46 | }, 47 | 48 | _hide: function() { 49 | this._container.css('display', 'none'); 50 | }, 51 | 52 | _selectMonth: function(e) { 53 | var monthIndex = $(e.target).data('value'), 54 | month = months[monthIndex], 55 | year = this._yearsSelect.val(); 56 | this._el.html(month + ' ' + year); 57 | if (options.onMonthSelect) { 58 | options.onMonthSelect(monthIndex, year); 59 | } 60 | }, 61 | 62 | _renderYears: function() { 63 | var markup = $.map(options.years, function(year) { 64 | return ''; 65 | }); 66 | var yearsWrap = $('
        ').appendTo(this._container); 67 | this._yearsSelect = $(' 10 | 11 | 12 | 13 | 14 | 15 |
        16 | 17 | 18 | -------------------------------------------------------------------------------- /pretty-select/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 4em; 3 | font-family: "Helvetica Neue", Helvetica, sans-serif; 4 | background: #F5ACB7; 5 | text-align: center; 6 | } 7 | 8 | .select { 9 | font-size: 16px; 10 | position: relative; 11 | display: inline-block; 12 | } 13 | 14 | .select .arr { 15 | background: #fff; 16 | bottom: 5px; 17 | position: absolute; 18 | right: 5px; 19 | top: 5px; 20 | width: 50px; 21 | pointer-events: none; 22 | } 23 | 24 | .select .arr:before { 25 | content: ''; 26 | position: absolute; 27 | top: 50%; 28 | right: 24px; 29 | margin-top: -5px; 30 | pointer-events: none; 31 | border-top: 10px solid #EB5168; 32 | border-left: 10px solid transparent; 33 | border-right: 10px solid transparent; 34 | } 35 | 36 | .select .arr:after { 37 | content: ''; 38 | position: absolute; 39 | top: 50%; 40 | right: 28px; 41 | margin-top: -5px; 42 | pointer-events: none; 43 | border-top: 6px solid #fff; 44 | border-left: 6px solid transparent; 45 | border-right: 6px solid transparent; 46 | } 47 | 48 | .select select { 49 | outline: none; 50 | -webkit-appearance: none; 51 | display: block; 52 | padding: 1.2em 3em 1.3em 1.5em; 53 | margin: 0; 54 | 55 | transition: border-color 0.2s; 56 | border: 5px solid #EB5168; 57 | border-radius: 5px; 58 | 59 | background: #fff; 60 | color: #555; 61 | line-height: normal; 62 | font-family: inherit; 63 | font-size: inherit; 64 | line-height: inherit; 65 | } 66 | 67 | .select select:focus { 68 | border-color:#1A70FF; 69 | } 70 | 71 | .select select:focus + .arr:before { 72 | border-top-color:#1A70FF; 73 | } 74 | -------------------------------------------------------------------------------- /vendor/images/animated-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/animated-overlay.gif -------------------------------------------------------------------------------- /vendor/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /vendor/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /vendor/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /vendor/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /vendor/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /vendor/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /vendor/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /vendor/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /vendor/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /vendor/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /vendor/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /vendor/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /vendor/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lugolabs/tutorials/e3398392cb0781e4e85650f4c2af85da183a3c96/vendor/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /vendor/jquery-ui-1.10.4.smoothness.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.10.4 - 2014-04-21 2 | * http://jqueryui.com 3 | * Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css 4 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px 5 | * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ 6 | 7 | /* Layout helpers 8 | ----------------------------------*/ 9 | .ui-helper-hidden { 10 | display: none; 11 | } 12 | .ui-helper-hidden-accessible { 13 | border: 0; 14 | clip: rect(0 0 0 0); 15 | height: 1px; 16 | margin: -1px; 17 | overflow: hidden; 18 | padding: 0; 19 | position: absolute; 20 | width: 1px; 21 | } 22 | .ui-helper-reset { 23 | margin: 0; 24 | padding: 0; 25 | border: 0; 26 | outline: 0; 27 | line-height: 1.3; 28 | text-decoration: none; 29 | font-size: 100%; 30 | list-style: none; 31 | } 32 | .ui-helper-clearfix:before, 33 | .ui-helper-clearfix:after { 34 | content: ""; 35 | display: table; 36 | border-collapse: collapse; 37 | } 38 | .ui-helper-clearfix:after { 39 | clear: both; 40 | } 41 | .ui-helper-clearfix { 42 | min-height: 0; /* support: IE7 */ 43 | } 44 | .ui-helper-zfix { 45 | width: 100%; 46 | height: 100%; 47 | top: 0; 48 | left: 0; 49 | position: absolute; 50 | opacity: 0; 51 | filter:Alpha(Opacity=0); 52 | } 53 | 54 | .ui-front { 55 | z-index: 100; 56 | } 57 | 58 | 59 | /* Interaction Cues 60 | ----------------------------------*/ 61 | .ui-state-disabled { 62 | cursor: default !important; 63 | } 64 | 65 | 66 | /* Icons 67 | ----------------------------------*/ 68 | 69 | /* states and images */ 70 | .ui-icon { 71 | display: block; 72 | text-indent: -99999px; 73 | overflow: hidden; 74 | background-repeat: no-repeat; 75 | } 76 | 77 | 78 | /* Misc visuals 79 | ----------------------------------*/ 80 | 81 | /* Overlays */ 82 | .ui-widget-overlay { 83 | position: fixed; 84 | top: 0; 85 | left: 0; 86 | width: 100%; 87 | height: 100%; 88 | } 89 | .ui-resizable { 90 | position: relative; 91 | } 92 | .ui-resizable-handle { 93 | position: absolute; 94 | font-size: 0.1px; 95 | display: block; 96 | } 97 | .ui-resizable-disabled .ui-resizable-handle, 98 | .ui-resizable-autohide .ui-resizable-handle { 99 | display: none; 100 | } 101 | .ui-resizable-n { 102 | cursor: n-resize; 103 | height: 7px; 104 | width: 100%; 105 | top: -5px; 106 | left: 0; 107 | } 108 | .ui-resizable-s { 109 | cursor: s-resize; 110 | height: 7px; 111 | width: 100%; 112 | bottom: -5px; 113 | left: 0; 114 | } 115 | .ui-resizable-e { 116 | cursor: e-resize; 117 | width: 7px; 118 | right: -5px; 119 | top: 0; 120 | height: 100%; 121 | } 122 | .ui-resizable-w { 123 | cursor: w-resize; 124 | width: 7px; 125 | left: -5px; 126 | top: 0; 127 | height: 100%; 128 | } 129 | .ui-resizable-se { 130 | cursor: se-resize; 131 | width: 12px; 132 | height: 12px; 133 | right: 1px; 134 | bottom: 1px; 135 | } 136 | .ui-resizable-sw { 137 | cursor: sw-resize; 138 | width: 9px; 139 | height: 9px; 140 | left: -5px; 141 | bottom: -5px; 142 | } 143 | .ui-resizable-nw { 144 | cursor: nw-resize; 145 | width: 9px; 146 | height: 9px; 147 | left: -5px; 148 | top: -5px; 149 | } 150 | .ui-resizable-ne { 151 | cursor: ne-resize; 152 | width: 9px; 153 | height: 9px; 154 | right: -5px; 155 | top: -5px; 156 | } 157 | .ui-selectable-helper { 158 | position: absolute; 159 | z-index: 100; 160 | border: 1px dotted black; 161 | } 162 | .ui-accordion .ui-accordion-header { 163 | display: block; 164 | cursor: pointer; 165 | position: relative; 166 | margin-top: 2px; 167 | padding: .5em .5em .5em .7em; 168 | min-height: 0; /* support: IE7 */ 169 | } 170 | .ui-accordion .ui-accordion-icons { 171 | padding-left: 2.2em; 172 | } 173 | .ui-accordion .ui-accordion-noicons { 174 | padding-left: .7em; 175 | } 176 | .ui-accordion .ui-accordion-icons .ui-accordion-icons { 177 | padding-left: 2.2em; 178 | } 179 | .ui-accordion .ui-accordion-header .ui-accordion-header-icon { 180 | position: absolute; 181 | left: .5em; 182 | top: 50%; 183 | margin-top: -8px; 184 | } 185 | .ui-accordion .ui-accordion-content { 186 | padding: 1em 2.2em; 187 | border-top: 0; 188 | overflow: auto; 189 | } 190 | .ui-autocomplete { 191 | position: absolute; 192 | top: 0; 193 | left: 0; 194 | cursor: default; 195 | } 196 | .ui-button { 197 | display: inline-block; 198 | position: relative; 199 | padding: 0; 200 | line-height: normal; 201 | margin-right: .1em; 202 | cursor: pointer; 203 | vertical-align: middle; 204 | text-align: center; 205 | overflow: visible; /* removes extra width in IE */ 206 | } 207 | .ui-button, 208 | .ui-button:link, 209 | .ui-button:visited, 210 | .ui-button:hover, 211 | .ui-button:active { 212 | text-decoration: none; 213 | } 214 | /* to make room for the icon, a width needs to be set here */ 215 | .ui-button-icon-only { 216 | width: 2.2em; 217 | } 218 | /* button elements seem to need a little more width */ 219 | button.ui-button-icon-only { 220 | width: 2.4em; 221 | } 222 | .ui-button-icons-only { 223 | width: 3.4em; 224 | } 225 | button.ui-button-icons-only { 226 | width: 3.7em; 227 | } 228 | 229 | /* button text element */ 230 | .ui-button .ui-button-text { 231 | display: block; 232 | line-height: normal; 233 | } 234 | .ui-button-text-only .ui-button-text { 235 | padding: .4em 1em; 236 | } 237 | .ui-button-icon-only .ui-button-text, 238 | .ui-button-icons-only .ui-button-text { 239 | padding: .4em; 240 | text-indent: -9999999px; 241 | } 242 | .ui-button-text-icon-primary .ui-button-text, 243 | .ui-button-text-icons .ui-button-text { 244 | padding: .4em 1em .4em 2.1em; 245 | } 246 | .ui-button-text-icon-secondary .ui-button-text, 247 | .ui-button-text-icons .ui-button-text { 248 | padding: .4em 2.1em .4em 1em; 249 | } 250 | .ui-button-text-icons .ui-button-text { 251 | padding-left: 2.1em; 252 | padding-right: 2.1em; 253 | } 254 | /* no icon support for input elements, provide padding by default */ 255 | input.ui-button { 256 | padding: .4em 1em; 257 | } 258 | 259 | /* button icon element(s) */ 260 | .ui-button-icon-only .ui-icon, 261 | .ui-button-text-icon-primary .ui-icon, 262 | .ui-button-text-icon-secondary .ui-icon, 263 | .ui-button-text-icons .ui-icon, 264 | .ui-button-icons-only .ui-icon { 265 | position: absolute; 266 | top: 50%; 267 | margin-top: -8px; 268 | } 269 | .ui-button-icon-only .ui-icon { 270 | left: 50%; 271 | margin-left: -8px; 272 | } 273 | .ui-button-text-icon-primary .ui-button-icon-primary, 274 | .ui-button-text-icons .ui-button-icon-primary, 275 | .ui-button-icons-only .ui-button-icon-primary { 276 | left: .5em; 277 | } 278 | .ui-button-text-icon-secondary .ui-button-icon-secondary, 279 | .ui-button-text-icons .ui-button-icon-secondary, 280 | .ui-button-icons-only .ui-button-icon-secondary { 281 | right: .5em; 282 | } 283 | 284 | /* button sets */ 285 | .ui-buttonset { 286 | margin-right: 7px; 287 | } 288 | .ui-buttonset .ui-button { 289 | margin-left: 0; 290 | margin-right: -.3em; 291 | } 292 | 293 | /* workarounds */ 294 | /* reset extra padding in Firefox, see h5bp.com/l */ 295 | input.ui-button::-moz-focus-inner, 296 | button.ui-button::-moz-focus-inner { 297 | border: 0; 298 | padding: 0; 299 | } 300 | .ui-datepicker { 301 | width: 17em; 302 | padding: .2em .2em 0; 303 | display: none; 304 | } 305 | .ui-datepicker .ui-datepicker-header { 306 | position: relative; 307 | padding: .2em 0; 308 | } 309 | .ui-datepicker .ui-datepicker-prev, 310 | .ui-datepicker .ui-datepicker-next { 311 | position: absolute; 312 | top: 2px; 313 | width: 1.8em; 314 | height: 1.8em; 315 | } 316 | .ui-datepicker .ui-datepicker-prev-hover, 317 | .ui-datepicker .ui-datepicker-next-hover { 318 | top: 1px; 319 | } 320 | .ui-datepicker .ui-datepicker-prev { 321 | left: 2px; 322 | } 323 | .ui-datepicker .ui-datepicker-next { 324 | right: 2px; 325 | } 326 | .ui-datepicker .ui-datepicker-prev-hover { 327 | left: 1px; 328 | } 329 | .ui-datepicker .ui-datepicker-next-hover { 330 | right: 1px; 331 | } 332 | .ui-datepicker .ui-datepicker-prev span, 333 | .ui-datepicker .ui-datepicker-next span { 334 | display: block; 335 | position: absolute; 336 | left: 50%; 337 | margin-left: -8px; 338 | top: 50%; 339 | margin-top: -8px; 340 | } 341 | .ui-datepicker .ui-datepicker-title { 342 | margin: 0 2.3em; 343 | line-height: 1.8em; 344 | text-align: center; 345 | } 346 | .ui-datepicker .ui-datepicker-title select { 347 | font-size: 1em; 348 | margin: 1px 0; 349 | } 350 | .ui-datepicker select.ui-datepicker-month, 351 | .ui-datepicker select.ui-datepicker-year { 352 | width: 49%; 353 | } 354 | .ui-datepicker table { 355 | width: 100%; 356 | font-size: .9em; 357 | border-collapse: collapse; 358 | margin: 0 0 .4em; 359 | } 360 | .ui-datepicker th { 361 | padding: .7em .3em; 362 | text-align: center; 363 | font-weight: bold; 364 | border: 0; 365 | } 366 | .ui-datepicker td { 367 | border: 0; 368 | padding: 1px; 369 | } 370 | .ui-datepicker td span, 371 | .ui-datepicker td a { 372 | display: block; 373 | padding: .2em; 374 | text-align: right; 375 | text-decoration: none; 376 | } 377 | .ui-datepicker .ui-datepicker-buttonpane { 378 | background-image: none; 379 | margin: .7em 0 0 0; 380 | padding: 0 .2em; 381 | border-left: 0; 382 | border-right: 0; 383 | border-bottom: 0; 384 | } 385 | .ui-datepicker .ui-datepicker-buttonpane button { 386 | float: right; 387 | margin: .5em .2em .4em; 388 | cursor: pointer; 389 | padding: .2em .6em .3em .6em; 390 | width: auto; 391 | overflow: visible; 392 | } 393 | .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { 394 | float: left; 395 | } 396 | 397 | /* with multiple calendars */ 398 | .ui-datepicker.ui-datepicker-multi { 399 | width: auto; 400 | } 401 | .ui-datepicker-multi .ui-datepicker-group { 402 | float: left; 403 | } 404 | .ui-datepicker-multi .ui-datepicker-group table { 405 | width: 95%; 406 | margin: 0 auto .4em; 407 | } 408 | .ui-datepicker-multi-2 .ui-datepicker-group { 409 | width: 50%; 410 | } 411 | .ui-datepicker-multi-3 .ui-datepicker-group { 412 | width: 33.3%; 413 | } 414 | .ui-datepicker-multi-4 .ui-datepicker-group { 415 | width: 25%; 416 | } 417 | .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, 418 | .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { 419 | border-left-width: 0; 420 | } 421 | .ui-datepicker-multi .ui-datepicker-buttonpane { 422 | clear: left; 423 | } 424 | .ui-datepicker-row-break { 425 | clear: both; 426 | width: 100%; 427 | font-size: 0; 428 | } 429 | 430 | /* RTL support */ 431 | .ui-datepicker-rtl { 432 | direction: rtl; 433 | } 434 | .ui-datepicker-rtl .ui-datepicker-prev { 435 | right: 2px; 436 | left: auto; 437 | } 438 | .ui-datepicker-rtl .ui-datepicker-next { 439 | left: 2px; 440 | right: auto; 441 | } 442 | .ui-datepicker-rtl .ui-datepicker-prev:hover { 443 | right: 1px; 444 | left: auto; 445 | } 446 | .ui-datepicker-rtl .ui-datepicker-next:hover { 447 | left: 1px; 448 | right: auto; 449 | } 450 | .ui-datepicker-rtl .ui-datepicker-buttonpane { 451 | clear: right; 452 | } 453 | .ui-datepicker-rtl .ui-datepicker-buttonpane button { 454 | float: left; 455 | } 456 | .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, 457 | .ui-datepicker-rtl .ui-datepicker-group { 458 | float: right; 459 | } 460 | .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, 461 | .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { 462 | border-right-width: 0; 463 | border-left-width: 1px; 464 | } 465 | .ui-dialog { 466 | overflow: hidden; 467 | position: absolute; 468 | top: 0; 469 | left: 0; 470 | padding: .2em; 471 | outline: 0; 472 | } 473 | .ui-dialog .ui-dialog-titlebar { 474 | padding: .4em 1em; 475 | position: relative; 476 | } 477 | .ui-dialog .ui-dialog-title { 478 | float: left; 479 | margin: .1em 0; 480 | white-space: nowrap; 481 | width: 90%; 482 | overflow: hidden; 483 | text-overflow: ellipsis; 484 | } 485 | .ui-dialog .ui-dialog-titlebar-close { 486 | position: absolute; 487 | right: .3em; 488 | top: 50%; 489 | width: 20px; 490 | margin: -10px 0 0 0; 491 | padding: 1px; 492 | height: 20px; 493 | } 494 | .ui-dialog .ui-dialog-content { 495 | position: relative; 496 | border: 0; 497 | padding: .5em 1em; 498 | background: none; 499 | overflow: auto; 500 | } 501 | .ui-dialog .ui-dialog-buttonpane { 502 | text-align: left; 503 | border-width: 1px 0 0 0; 504 | background-image: none; 505 | margin-top: .5em; 506 | padding: .3em 1em .5em .4em; 507 | } 508 | .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { 509 | float: right; 510 | } 511 | .ui-dialog .ui-dialog-buttonpane button { 512 | margin: .5em .4em .5em 0; 513 | cursor: pointer; 514 | } 515 | .ui-dialog .ui-resizable-se { 516 | width: 12px; 517 | height: 12px; 518 | right: -5px; 519 | bottom: -5px; 520 | background-position: 16px 16px; 521 | } 522 | .ui-draggable .ui-dialog-titlebar { 523 | cursor: move; 524 | } 525 | .ui-menu { 526 | list-style: none; 527 | padding: 2px; 528 | margin: 0; 529 | display: block; 530 | outline: none; 531 | } 532 | .ui-menu .ui-menu { 533 | margin-top: -3px; 534 | position: absolute; 535 | } 536 | .ui-menu .ui-menu-item { 537 | margin: 0; 538 | padding: 0; 539 | width: 100%; 540 | /* support: IE10, see #8844 */ 541 | list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); 542 | } 543 | .ui-menu .ui-menu-divider { 544 | margin: 5px -2px 5px -2px; 545 | height: 0; 546 | font-size: 0; 547 | line-height: 0; 548 | border-width: 1px 0 0 0; 549 | } 550 | .ui-menu .ui-menu-item a { 551 | text-decoration: none; 552 | display: block; 553 | padding: 2px .4em; 554 | line-height: 1.5; 555 | min-height: 0; /* support: IE7 */ 556 | font-weight: normal; 557 | } 558 | .ui-menu .ui-menu-item a.ui-state-focus, 559 | .ui-menu .ui-menu-item a.ui-state-active { 560 | font-weight: normal; 561 | margin: -1px; 562 | } 563 | 564 | .ui-menu .ui-state-disabled { 565 | font-weight: normal; 566 | margin: .4em 0 .2em; 567 | line-height: 1.5; 568 | } 569 | .ui-menu .ui-state-disabled a { 570 | cursor: default; 571 | } 572 | 573 | /* icon support */ 574 | .ui-menu-icons { 575 | position: relative; 576 | } 577 | .ui-menu-icons .ui-menu-item a { 578 | position: relative; 579 | padding-left: 2em; 580 | } 581 | 582 | /* left-aligned */ 583 | .ui-menu .ui-icon { 584 | position: absolute; 585 | top: .2em; 586 | left: .2em; 587 | } 588 | 589 | /* right-aligned */ 590 | .ui-menu .ui-menu-icon { 591 | position: static; 592 | float: right; 593 | } 594 | .ui-progressbar { 595 | height: 2em; 596 | text-align: left; 597 | overflow: hidden; 598 | } 599 | .ui-progressbar .ui-progressbar-value { 600 | margin: -1px; 601 | height: 100%; 602 | } 603 | .ui-progressbar .ui-progressbar-overlay { 604 | background: url("images/animated-overlay.gif"); 605 | height: 100%; 606 | filter: alpha(opacity=25); 607 | opacity: 0.25; 608 | } 609 | .ui-progressbar-indeterminate .ui-progressbar-value { 610 | background-image: none; 611 | } 612 | .ui-slider { 613 | position: relative; 614 | text-align: left; 615 | } 616 | .ui-slider .ui-slider-handle { 617 | position: absolute; 618 | z-index: 2; 619 | width: 1.2em; 620 | height: 1.2em; 621 | cursor: default; 622 | } 623 | .ui-slider .ui-slider-range { 624 | position: absolute; 625 | z-index: 1; 626 | font-size: .7em; 627 | display: block; 628 | border: 0; 629 | background-position: 0 0; 630 | } 631 | 632 | /* For IE8 - See #6727 */ 633 | .ui-slider.ui-state-disabled .ui-slider-handle, 634 | .ui-slider.ui-state-disabled .ui-slider-range { 635 | filter: inherit; 636 | } 637 | 638 | .ui-slider-horizontal { 639 | height: .8em; 640 | } 641 | .ui-slider-horizontal .ui-slider-handle { 642 | top: -.3em; 643 | margin-left: -.6em; 644 | } 645 | .ui-slider-horizontal .ui-slider-range { 646 | top: 0; 647 | height: 100%; 648 | } 649 | .ui-slider-horizontal .ui-slider-range-min { 650 | left: 0; 651 | } 652 | .ui-slider-horizontal .ui-slider-range-max { 653 | right: 0; 654 | } 655 | 656 | .ui-slider-vertical { 657 | width: .8em; 658 | height: 100px; 659 | } 660 | .ui-slider-vertical .ui-slider-handle { 661 | left: -.3em; 662 | margin-left: 0; 663 | margin-bottom: -.6em; 664 | } 665 | .ui-slider-vertical .ui-slider-range { 666 | left: 0; 667 | width: 100%; 668 | } 669 | .ui-slider-vertical .ui-slider-range-min { 670 | bottom: 0; 671 | } 672 | .ui-slider-vertical .ui-slider-range-max { 673 | top: 0; 674 | } 675 | .ui-spinner { 676 | position: relative; 677 | display: inline-block; 678 | overflow: hidden; 679 | padding: 0; 680 | vertical-align: middle; 681 | } 682 | .ui-spinner-input { 683 | border: none; 684 | background: none; 685 | color: inherit; 686 | padding: 0; 687 | margin: .2em 0; 688 | vertical-align: middle; 689 | margin-left: .4em; 690 | margin-right: 22px; 691 | } 692 | .ui-spinner-button { 693 | width: 16px; 694 | height: 50%; 695 | font-size: .5em; 696 | padding: 0; 697 | margin: 0; 698 | text-align: center; 699 | position: absolute; 700 | cursor: default; 701 | display: block; 702 | overflow: hidden; 703 | right: 0; 704 | } 705 | /* more specificity required here to override default borders */ 706 | .ui-spinner a.ui-spinner-button { 707 | border-top: none; 708 | border-bottom: none; 709 | border-right: none; 710 | } 711 | /* vertically center icon */ 712 | .ui-spinner .ui-icon { 713 | position: absolute; 714 | margin-top: -8px; 715 | top: 50%; 716 | left: 0; 717 | } 718 | .ui-spinner-up { 719 | top: 0; 720 | } 721 | .ui-spinner-down { 722 | bottom: 0; 723 | } 724 | 725 | /* TR overrides */ 726 | .ui-spinner .ui-icon-triangle-1-s { 727 | /* need to fix icons sprite */ 728 | background-position: -65px -16px; 729 | } 730 | .ui-tabs { 731 | position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ 732 | padding: .2em; 733 | } 734 | .ui-tabs .ui-tabs-nav { 735 | margin: 0; 736 | padding: .2em .2em 0; 737 | } 738 | .ui-tabs .ui-tabs-nav li { 739 | list-style: none; 740 | float: left; 741 | position: relative; 742 | top: 0; 743 | margin: 1px .2em 0 0; 744 | border-bottom-width: 0; 745 | padding: 0; 746 | white-space: nowrap; 747 | } 748 | .ui-tabs .ui-tabs-nav .ui-tabs-anchor { 749 | float: left; 750 | padding: .5em 1em; 751 | text-decoration: none; 752 | } 753 | .ui-tabs .ui-tabs-nav li.ui-tabs-active { 754 | margin-bottom: -1px; 755 | padding-bottom: 1px; 756 | } 757 | .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, 758 | .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, 759 | .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { 760 | cursor: text; 761 | } 762 | .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { 763 | cursor: pointer; 764 | } 765 | .ui-tabs .ui-tabs-panel { 766 | display: block; 767 | border-width: 0; 768 | padding: 1em 1.4em; 769 | background: none; 770 | } 771 | .ui-tooltip { 772 | padding: 8px; 773 | position: absolute; 774 | z-index: 9999; 775 | max-width: 300px; 776 | -webkit-box-shadow: 0 0 5px #aaa; 777 | box-shadow: 0 0 5px #aaa; 778 | } 779 | body .ui-tooltip { 780 | border-width: 2px; 781 | } 782 | 783 | /* Component containers 784 | ----------------------------------*/ 785 | .ui-widget { 786 | font-family: Verdana,Arial,sans-serif; 787 | font-size: 1.1em; 788 | } 789 | .ui-widget .ui-widget { 790 | font-size: 1em; 791 | } 792 | .ui-widget input, 793 | .ui-widget select, 794 | .ui-widget textarea, 795 | .ui-widget button { 796 | font-family: Verdana,Arial,sans-serif; 797 | font-size: 1em; 798 | } 799 | .ui-widget-content { 800 | border: 1px solid #aaaaaa; 801 | background: #ffffff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x; 802 | color: #222222; 803 | } 804 | .ui-widget-content a { 805 | color: #222222; 806 | } 807 | .ui-widget-header { 808 | border: 1px solid #aaaaaa; 809 | background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x; 810 | color: #222222; 811 | font-weight: bold; 812 | } 813 | .ui-widget-header a { 814 | color: #222222; 815 | } 816 | 817 | /* Interaction states 818 | ----------------------------------*/ 819 | .ui-state-default, 820 | .ui-widget-content .ui-state-default, 821 | .ui-widget-header .ui-state-default { 822 | border: 1px solid #d3d3d3; 823 | background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x; 824 | font-weight: normal; 825 | color: #555555; 826 | } 827 | .ui-state-default a, 828 | .ui-state-default a:link, 829 | .ui-state-default a:visited { 830 | color: #555555; 831 | text-decoration: none; 832 | } 833 | .ui-state-hover, 834 | .ui-widget-content .ui-state-hover, 835 | .ui-widget-header .ui-state-hover, 836 | .ui-state-focus, 837 | .ui-widget-content .ui-state-focus, 838 | .ui-widget-header .ui-state-focus { 839 | border: 1px solid #999999; 840 | background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x; 841 | font-weight: normal; 842 | color: #212121; 843 | } 844 | .ui-state-hover a, 845 | .ui-state-hover a:hover, 846 | .ui-state-hover a:link, 847 | .ui-state-hover a:visited, 848 | .ui-state-focus a, 849 | .ui-state-focus a:hover, 850 | .ui-state-focus a:link, 851 | .ui-state-focus a:visited { 852 | color: #212121; 853 | text-decoration: none; 854 | } 855 | .ui-state-active, 856 | .ui-widget-content .ui-state-active, 857 | .ui-widget-header .ui-state-active { 858 | border: 1px solid #aaaaaa; 859 | background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x; 860 | font-weight: normal; 861 | color: #212121; 862 | } 863 | .ui-state-active a, 864 | .ui-state-active a:link, 865 | .ui-state-active a:visited { 866 | color: #212121; 867 | text-decoration: none; 868 | } 869 | 870 | /* Interaction Cues 871 | ----------------------------------*/ 872 | .ui-state-highlight, 873 | .ui-widget-content .ui-state-highlight, 874 | .ui-widget-header .ui-state-highlight { 875 | border: 1px solid #fcefa1; 876 | background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x; 877 | color: #363636; 878 | } 879 | .ui-state-highlight a, 880 | .ui-widget-content .ui-state-highlight a, 881 | .ui-widget-header .ui-state-highlight a { 882 | color: #363636; 883 | } 884 | .ui-state-error, 885 | .ui-widget-content .ui-state-error, 886 | .ui-widget-header .ui-state-error { 887 | border: 1px solid #cd0a0a; 888 | background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x; 889 | color: #cd0a0a; 890 | } 891 | .ui-state-error a, 892 | .ui-widget-content .ui-state-error a, 893 | .ui-widget-header .ui-state-error a { 894 | color: #cd0a0a; 895 | } 896 | .ui-state-error-text, 897 | .ui-widget-content .ui-state-error-text, 898 | .ui-widget-header .ui-state-error-text { 899 | color: #cd0a0a; 900 | } 901 | .ui-priority-primary, 902 | .ui-widget-content .ui-priority-primary, 903 | .ui-widget-header .ui-priority-primary { 904 | font-weight: bold; 905 | } 906 | .ui-priority-secondary, 907 | .ui-widget-content .ui-priority-secondary, 908 | .ui-widget-header .ui-priority-secondary { 909 | opacity: .7; 910 | filter:Alpha(Opacity=70); 911 | font-weight: normal; 912 | } 913 | .ui-state-disabled, 914 | .ui-widget-content .ui-state-disabled, 915 | .ui-widget-header .ui-state-disabled { 916 | opacity: .35; 917 | filter:Alpha(Opacity=35); 918 | background-image: none; 919 | } 920 | .ui-state-disabled .ui-icon { 921 | filter:Alpha(Opacity=35); /* For IE8 - See #6059 */ 922 | } 923 | 924 | /* Icons 925 | ----------------------------------*/ 926 | 927 | /* states and images */ 928 | .ui-icon { 929 | width: 16px; 930 | height: 16px; 931 | } 932 | .ui-icon, 933 | .ui-widget-content .ui-icon { 934 | background-image: url("images/ui-icons_222222_256x240.png"); 935 | } 936 | .ui-widget-header .ui-icon { 937 | background-image: url("images/ui-icons_222222_256x240.png"); 938 | } 939 | .ui-state-default .ui-icon { 940 | background-image: url("images/ui-icons_888888_256x240.png"); 941 | } 942 | .ui-state-hover .ui-icon, 943 | .ui-state-focus .ui-icon { 944 | background-image: url("images/ui-icons_454545_256x240.png"); 945 | } 946 | .ui-state-active .ui-icon { 947 | background-image: url("images/ui-icons_454545_256x240.png"); 948 | } 949 | .ui-state-highlight .ui-icon { 950 | background-image: url("images/ui-icons_2e83ff_256x240.png"); 951 | } 952 | .ui-state-error .ui-icon, 953 | .ui-state-error-text .ui-icon { 954 | background-image: url("images/ui-icons_cd0a0a_256x240.png"); 955 | } 956 | 957 | /* positioning */ 958 | .ui-icon-blank { background-position: 16px 16px; } 959 | .ui-icon-carat-1-n { background-position: 0 0; } 960 | .ui-icon-carat-1-ne { background-position: -16px 0; } 961 | .ui-icon-carat-1-e { background-position: -32px 0; } 962 | .ui-icon-carat-1-se { background-position: -48px 0; } 963 | .ui-icon-carat-1-s { background-position: -64px 0; } 964 | .ui-icon-carat-1-sw { background-position: -80px 0; } 965 | .ui-icon-carat-1-w { background-position: -96px 0; } 966 | .ui-icon-carat-1-nw { background-position: -112px 0; } 967 | .ui-icon-carat-2-n-s { background-position: -128px 0; } 968 | .ui-icon-carat-2-e-w { background-position: -144px 0; } 969 | .ui-icon-triangle-1-n { background-position: 0 -16px; } 970 | .ui-icon-triangle-1-ne { background-position: -16px -16px; } 971 | .ui-icon-triangle-1-e { background-position: -32px -16px; } 972 | .ui-icon-triangle-1-se { background-position: -48px -16px; } 973 | .ui-icon-triangle-1-s { background-position: -64px -16px; } 974 | .ui-icon-triangle-1-sw { background-position: -80px -16px; } 975 | .ui-icon-triangle-1-w { background-position: -96px -16px; } 976 | .ui-icon-triangle-1-nw { background-position: -112px -16px; } 977 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; } 978 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; } 979 | .ui-icon-arrow-1-n { background-position: 0 -32px; } 980 | .ui-icon-arrow-1-ne { background-position: -16px -32px; } 981 | .ui-icon-arrow-1-e { background-position: -32px -32px; } 982 | .ui-icon-arrow-1-se { background-position: -48px -32px; } 983 | .ui-icon-arrow-1-s { background-position: -64px -32px; } 984 | .ui-icon-arrow-1-sw { background-position: -80px -32px; } 985 | .ui-icon-arrow-1-w { background-position: -96px -32px; } 986 | .ui-icon-arrow-1-nw { background-position: -112px -32px; } 987 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; } 988 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } 989 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; } 990 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } 991 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; } 992 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; } 993 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; } 994 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; } 995 | .ui-icon-arrowthick-1-n { background-position: 0 -48px; } 996 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } 997 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; } 998 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; } 999 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; } 1000 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } 1001 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; } 1002 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } 1003 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } 1004 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } 1005 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } 1006 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } 1007 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } 1008 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } 1009 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } 1010 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } 1011 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } 1012 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } 1013 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } 1014 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } 1015 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } 1016 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } 1017 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } 1018 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } 1019 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } 1020 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } 1021 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } 1022 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } 1023 | .ui-icon-arrow-4 { background-position: 0 -80px; } 1024 | .ui-icon-arrow-4-diag { background-position: -16px -80px; } 1025 | .ui-icon-extlink { background-position: -32px -80px; } 1026 | .ui-icon-newwin { background-position: -48px -80px; } 1027 | .ui-icon-refresh { background-position: -64px -80px; } 1028 | .ui-icon-shuffle { background-position: -80px -80px; } 1029 | .ui-icon-transfer-e-w { background-position: -96px -80px; } 1030 | .ui-icon-transferthick-e-w { background-position: -112px -80px; } 1031 | .ui-icon-folder-collapsed { background-position: 0 -96px; } 1032 | .ui-icon-folder-open { background-position: -16px -96px; } 1033 | .ui-icon-document { background-position: -32px -96px; } 1034 | .ui-icon-document-b { background-position: -48px -96px; } 1035 | .ui-icon-note { background-position: -64px -96px; } 1036 | .ui-icon-mail-closed { background-position: -80px -96px; } 1037 | .ui-icon-mail-open { background-position: -96px -96px; } 1038 | .ui-icon-suitcase { background-position: -112px -96px; } 1039 | .ui-icon-comment { background-position: -128px -96px; } 1040 | .ui-icon-person { background-position: -144px -96px; } 1041 | .ui-icon-print { background-position: -160px -96px; } 1042 | .ui-icon-trash { background-position: -176px -96px; } 1043 | .ui-icon-locked { background-position: -192px -96px; } 1044 | .ui-icon-unlocked { background-position: -208px -96px; } 1045 | .ui-icon-bookmark { background-position: -224px -96px; } 1046 | .ui-icon-tag { background-position: -240px -96px; } 1047 | .ui-icon-home { background-position: 0 -112px; } 1048 | .ui-icon-flag { background-position: -16px -112px; } 1049 | .ui-icon-calendar { background-position: -32px -112px; } 1050 | .ui-icon-cart { background-position: -48px -112px; } 1051 | .ui-icon-pencil { background-position: -64px -112px; } 1052 | .ui-icon-clock { background-position: -80px -112px; } 1053 | .ui-icon-disk { background-position: -96px -112px; } 1054 | .ui-icon-calculator { background-position: -112px -112px; } 1055 | .ui-icon-zoomin { background-position: -128px -112px; } 1056 | .ui-icon-zoomout { background-position: -144px -112px; } 1057 | .ui-icon-search { background-position: -160px -112px; } 1058 | .ui-icon-wrench { background-position: -176px -112px; } 1059 | .ui-icon-gear { background-position: -192px -112px; } 1060 | .ui-icon-heart { background-position: -208px -112px; } 1061 | .ui-icon-star { background-position: -224px -112px; } 1062 | .ui-icon-link { background-position: -240px -112px; } 1063 | .ui-icon-cancel { background-position: 0 -128px; } 1064 | .ui-icon-plus { background-position: -16px -128px; } 1065 | .ui-icon-plusthick { background-position: -32px -128px; } 1066 | .ui-icon-minus { background-position: -48px -128px; } 1067 | .ui-icon-minusthick { background-position: -64px -128px; } 1068 | .ui-icon-close { background-position: -80px -128px; } 1069 | .ui-icon-closethick { background-position: -96px -128px; } 1070 | .ui-icon-key { background-position: -112px -128px; } 1071 | .ui-icon-lightbulb { background-position: -128px -128px; } 1072 | .ui-icon-scissors { background-position: -144px -128px; } 1073 | .ui-icon-clipboard { background-position: -160px -128px; } 1074 | .ui-icon-copy { background-position: -176px -128px; } 1075 | .ui-icon-contact { background-position: -192px -128px; } 1076 | .ui-icon-image { background-position: -208px -128px; } 1077 | .ui-icon-video { background-position: -224px -128px; } 1078 | .ui-icon-script { background-position: -240px -128px; } 1079 | .ui-icon-alert { background-position: 0 -144px; } 1080 | .ui-icon-info { background-position: -16px -144px; } 1081 | .ui-icon-notice { background-position: -32px -144px; } 1082 | .ui-icon-help { background-position: -48px -144px; } 1083 | .ui-icon-check { background-position: -64px -144px; } 1084 | .ui-icon-bullet { background-position: -80px -144px; } 1085 | .ui-icon-radio-on { background-position: -96px -144px; } 1086 | .ui-icon-radio-off { background-position: -112px -144px; } 1087 | .ui-icon-pin-w { background-position: -128px -144px; } 1088 | .ui-icon-pin-s { background-position: -144px -144px; } 1089 | .ui-icon-play { background-position: 0 -160px; } 1090 | .ui-icon-pause { background-position: -16px -160px; } 1091 | .ui-icon-seek-next { background-position: -32px -160px; } 1092 | .ui-icon-seek-prev { background-position: -48px -160px; } 1093 | .ui-icon-seek-end { background-position: -64px -160px; } 1094 | .ui-icon-seek-start { background-position: -80px -160px; } 1095 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ 1096 | .ui-icon-seek-first { background-position: -80px -160px; } 1097 | .ui-icon-stop { background-position: -96px -160px; } 1098 | .ui-icon-eject { background-position: -112px -160px; } 1099 | .ui-icon-volume-off { background-position: -128px -160px; } 1100 | .ui-icon-volume-on { background-position: -144px -160px; } 1101 | .ui-icon-power { background-position: 0 -176px; } 1102 | .ui-icon-signal-diag { background-position: -16px -176px; } 1103 | .ui-icon-signal { background-position: -32px -176px; } 1104 | .ui-icon-battery-0 { background-position: -48px -176px; } 1105 | .ui-icon-battery-1 { background-position: -64px -176px; } 1106 | .ui-icon-battery-2 { background-position: -80px -176px; } 1107 | .ui-icon-battery-3 { background-position: -96px -176px; } 1108 | .ui-icon-circle-plus { background-position: 0 -192px; } 1109 | .ui-icon-circle-minus { background-position: -16px -192px; } 1110 | .ui-icon-circle-close { background-position: -32px -192px; } 1111 | .ui-icon-circle-triangle-e { background-position: -48px -192px; } 1112 | .ui-icon-circle-triangle-s { background-position: -64px -192px; } 1113 | .ui-icon-circle-triangle-w { background-position: -80px -192px; } 1114 | .ui-icon-circle-triangle-n { background-position: -96px -192px; } 1115 | .ui-icon-circle-arrow-e { background-position: -112px -192px; } 1116 | .ui-icon-circle-arrow-s { background-position: -128px -192px; } 1117 | .ui-icon-circle-arrow-w { background-position: -144px -192px; } 1118 | .ui-icon-circle-arrow-n { background-position: -160px -192px; } 1119 | .ui-icon-circle-zoomin { background-position: -176px -192px; } 1120 | .ui-icon-circle-zoomout { background-position: -192px -192px; } 1121 | .ui-icon-circle-check { background-position: -208px -192px; } 1122 | .ui-icon-circlesmall-plus { background-position: 0 -208px; } 1123 | .ui-icon-circlesmall-minus { background-position: -16px -208px; } 1124 | .ui-icon-circlesmall-close { background-position: -32px -208px; } 1125 | .ui-icon-squaresmall-plus { background-position: -48px -208px; } 1126 | .ui-icon-squaresmall-minus { background-position: -64px -208px; } 1127 | .ui-icon-squaresmall-close { background-position: -80px -208px; } 1128 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } 1129 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } 1130 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; } 1131 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } 1132 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } 1133 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; } 1134 | 1135 | 1136 | /* Misc visuals 1137 | ----------------------------------*/ 1138 | 1139 | /* Corner radius */ 1140 | .ui-corner-all, 1141 | .ui-corner-top, 1142 | .ui-corner-left, 1143 | .ui-corner-tl { 1144 | border-top-left-radius: 4px; 1145 | } 1146 | .ui-corner-all, 1147 | .ui-corner-top, 1148 | .ui-corner-right, 1149 | .ui-corner-tr { 1150 | border-top-right-radius: 4px; 1151 | } 1152 | .ui-corner-all, 1153 | .ui-corner-bottom, 1154 | .ui-corner-left, 1155 | .ui-corner-bl { 1156 | border-bottom-left-radius: 4px; 1157 | } 1158 | .ui-corner-all, 1159 | .ui-corner-bottom, 1160 | .ui-corner-right, 1161 | .ui-corner-br { 1162 | border-bottom-right-radius: 4px; 1163 | } 1164 | 1165 | /* Overlays */ 1166 | .ui-widget-overlay { 1167 | background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x; 1168 | opacity: .3; 1169 | filter: Alpha(Opacity=30); 1170 | } 1171 | .ui-widget-shadow { 1172 | margin: -8px 0 0 -8px; 1173 | padding: 8px; 1174 | background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x; 1175 | opacity: .3; 1176 | filter: Alpha(Opacity=30); 1177 | border-radius: 8px; 1178 | } 1179 | -------------------------------------------------------------------------------- /week-picker/README.md: -------------------------------------------------------------------------------- 1 | jQuery weekpicker 2 | ----------------- 3 | 4 | Turn the [jQuery UI datepicker](http://jqueryui.com/datepicker) into a weekpicker. Check the [walkthrough](https://www.lugolabs.com/articles/turn-jquery-ui-datepicker-into-a-weekpicker) at Lugo Labs. 5 | -------------------------------------------------------------------------------- /week-picker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jQuery Week Picker 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 |

        jQuery weekpicker

        17 | 18 |
        19 |
        Week starting:
        20 | 21 | 22 | 23 | 24 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /week-picker/jquery-weekpicker.css: -------------------------------------------------------------------------------- 1 | .ui-datepicker { 2 | border-radius: 0; 3 | padding: 0 0 1.5em; 4 | border: 0; 5 | box-shadow: 2px 2px 5px #aaa; 6 | width: 14.5em; 7 | } 8 | 9 | .ui-datepicker table { 10 | font-size: 13px; 11 | } 12 | 13 | .ui-datepicker th, 14 | .ui-datepicker td { 15 | padding: 0; 16 | width: 10px; 17 | } 18 | 19 | .ui-datepicker th { 20 | text-transform: uppercase; 21 | color: #E3797D; 22 | font-size: .8em; 23 | padding-bottom: 1em; 24 | } 25 | 26 | .ui-datepicker .ui-datepicker-header { 27 | border: none; 28 | border-radius: 0; 29 | background: #4ECDC4; 30 | color: #fff; 31 | margin-bottom: 2em; 32 | } 33 | 34 | .ui-datepicker .ui-datepicker-title { 35 | line-height: 1; 36 | padding: 3em 0; 37 | font-family: 'Oswald', sans-serif; 38 | text-transform: uppercase; 39 | } 40 | 41 | .ui-datepicker .ui-datepicker-month { 42 | display: block; 43 | font-size: 1.8em; 44 | margin-bottom: .4em; 45 | } 46 | 47 | .ui-datepicker .ui-datepicker-year { 48 | color: rgba(255, 255, 255, 0.7); 49 | } 50 | 51 | .ui-datepicker .ui-datepicker-prev, 52 | .ui-datepicker .ui-datepicker-next { 53 | top: 50%; 54 | margin-top: -16px; 55 | border: 0; 56 | cursor: pointer; 57 | } 58 | 59 | .ui-datepicker .ui-datepicker-prev { 60 | left: 10px; 61 | } 62 | 63 | .ui-datepicker .ui-datepicker-next { 64 | right: 10px; 65 | } 66 | 67 | .ui-datepicker .ui-datepicker-prev .ui-icon { 68 | background-position: -96px -32px; 69 | } 70 | 71 | .ui-datepicker .ui-datepicker-prev:hover .ui-icon { 72 | background-position: -96px -48px; 73 | } 74 | 75 | .ui-datepicker .ui-datepicker-next .ui-icon { 76 | background-position: -32px -32px; 77 | } 78 | 79 | .ui-datepicker .ui-datepicker-next:hover .ui-icon { 80 | background-position: -32px -48px; 81 | } 82 | 83 | .ui-datepicker .ui-state-default { 84 | border: none; 85 | background: transparent; 86 | padding: 0; 87 | height: 30px; 88 | line-height: 30px; 89 | text-align: center; 90 | } 91 | 92 | .ui-datepicker td.ui-datepicker-current-day .ui-state-default, 93 | .ui-datepicker .ui-state-hover { 94 | background: #4ECDC4; 95 | color: #fff; 96 | } 97 | 98 | .ui-datepicker .ui-priority-secondary, 99 | .ui-datepicker .ui-widget-content .ui-priority-secondary, 100 | .ui-datepicker .ui-widget-header .ui-priority-secondary { 101 | opacity: .4; 102 | filter: Alpha(Opacity=40); 103 | } 104 | -------------------------------------------------------------------------------- /week-picker/jquery-weekpicker.js: -------------------------------------------------------------------------------- 1 | (function($, undefined) { 2 | 3 | $.widget('lugolabs.weekpicker', { 4 | _weekOptions: { 5 | showOtherMonths: true, 6 | selectOtherMonths: true 7 | }, 8 | 9 | _create: function() { 10 | var self = this; 11 | this._dateFormat = this.options.dateFormat || $.datepicker._defaults.dateFormat; 12 | var date = this._initialDate(); 13 | this._setWeek(date); 14 | this._extendRestrictedWeeks(); 15 | var onSelect = this.options.onSelect; 16 | this._picker = $(this.element).datepicker($.extend(this.options, this._weekOptions, { 17 | onSelect: function(dateText, inst) { 18 | self._select(dateText, inst, onSelect); 19 | }, 20 | beforeShowDay: function(date) { 21 | return self._showDay(date); 22 | }, 23 | onChangeMonthYear: function(year, month, inst) { 24 | self._selectCurrentWeek(); 25 | } 26 | })); 27 | $(document) 28 | .on('mousemove', '.ui-datepicker-calendar tr', function() { $(this).find('td a').addClass('ui-state-hover'); }) 29 | .on('mouseleave', '.ui-datepicker-calendar tr', function() { $(this).find('td a').removeClass('ui-state-hover'); }); 30 | this._picker.datepicker('setDate', date); 31 | }, 32 | 33 | _initialDate: function() { 34 | if (this.options.currentText) { 35 | return $.datepicker.parseDate(this._dateFormat, this.options.currentText); 36 | } else { 37 | return new Date; 38 | } 39 | }, 40 | 41 | _select: function(dateText, inst, onSelect) { 42 | this._setWeek(this._picker.datepicker('getDate')); 43 | var startDateText = $.datepicker.formatDate(this._dateFormat, this._startDate, inst.settings); 44 | this._picker.val(startDateText); 45 | if (onSelect) onSelect(dateText, startDateText, this._startDate, this._endDate, inst); 46 | }, 47 | 48 | _showDay: function(date) { 49 | var dt = jQuery.datepicker.formatDate(this._dateFormat, date); 50 | var show = this._restrictDates.indexOf(dt) < 0; 51 | var cssClass = date >= this._startDate && date <= this._endDate ? 'ui-datepicker-current-day' : ''; 52 | return [show, cssClass]; 53 | }, 54 | 55 | _setWeek: function(date) { 56 | var explodedDate = this._explodeDate(date); 57 | this._startDate = new Date(explodedDate.year, explodedDate.month, explodedDate.day); 58 | this._endDate = new Date(explodedDate.year, explodedDate.month, explodedDate.day + 6); 59 | }, 60 | 61 | _selectCurrentWeek: function() { 62 | $('.ui-datepicker-calendar') 63 | .find('.ui-datepicker-current-day a') 64 | .addClass('ui-state-active'); 65 | }, 66 | 67 | _extendRestrictedWeeks: function() { 68 | this._restrictDates = []; 69 | if (this.options.restrictWeeks && this.options.restrictWeeks.length) { 70 | var date, explodedDate; 71 | for (var i = 0; i < this.options.restrictWeeks.length; i++) { 72 | date = $.datepicker.parseDate(this._dateFormat, this.options.restrictWeeks[i]); 73 | for (var j = 0; j < 7; j++) { 74 | explodedDate = this._explodeDate(date); 75 | date = new Date(explodedDate.year, explodedDate.month, explodedDate.day + j); 76 | this._restrictDates.push(jQuery.datepicker.formatDate(this._dateFormat, date)); 77 | } 78 | } 79 | } 80 | }, 81 | 82 | _explodeDate: function(date) { 83 | return { 84 | year: date.getFullYear(), 85 | month: date.getMonth(), 86 | day: date.getDate() - date.getDay() 87 | }; 88 | } 89 | }); 90 | 91 | })(jQuery); 92 | --------------------------------------------------------------------------------