We've been notified about this issue and we'll take a look at it shortly.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/controllers/events_controller.rb:
--------------------------------------------------------------------------------
1 | class EventsController < ApplicationController
2 | def index
3 | @events = Event.limit(10)
4 | @event = Event.new
5 |
6 | respond_to do |format|
7 | format.html
8 | format.csv do
9 | require 'csv'
10 | send_data(CSV.generate do |csv|
11 | csv << ["Start", "Finished", "Duration (sec)", "Tags", "Created", "Updated"]
12 | @events.each do |event|
13 | csv << [event.started_at.to_s(:csv), event.finished_at.to_s(:csv), (event.finished_at - event.started_at).round(2),
14 | event.tag_list, event.created_at.to_s(:csv), event.updated_at.to_s(:csv)]
15 | end
16 | end)
17 | end
18 | end
19 | end
20 |
21 | def create
22 | @event = Event.new(params[:event])
23 |
24 | if @event.save
25 | @events = Event.limit(10)
26 | @event = Event.new
27 | end
28 | end
29 |
30 | def destroy
31 | @event = Event.find(params[:id])
32 | @event.destroy
33 |
34 | @events = Event.limit(10)
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Events::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 webserver when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Log error messages when you accidentally call methods on nil.
10 | config.whiny_nils = true
11 |
12 | # Show full error reports and disable caching
13 | config.consider_all_requests_local = true
14 | config.action_view.debug_rjs = true
15 | config.action_controller.perform_caching = false
16 |
17 | # Don't care if the mailer can't send
18 | config.action_mailer.raise_delivery_errors = false
19 |
20 | # Print deprecation notices to the Rails logger
21 | config.active_support.deprecation = :log
22 |
23 | # Only use best-standards-support built into browsers
24 | config.action_dispatch.best_standards_support = :builtin
25 | end
26 |
27 |
--------------------------------------------------------------------------------
/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | * { margin: 0; padding: 0; font: 16px/1.3em Helvetica, Arial, sans-serif; }
2 |
3 | #wrapper { width: 800px; margin: 0 auto; }
4 |
5 | h1 { font-size: 150%; margin: 15px 0; font-weight: bold; }
6 | p { margin: 15px 0; }
7 |
8 | .clear { clear: both; }
9 |
10 | input[type=button] { padding: auto; }
11 |
12 | #new_event { font-size: 140%; }
13 | #new_event input { padding: 5px; }
14 |
15 | #event_started_fields { display: none; }
16 |
17 | #event_start, #event_submit { width: 110px; }
18 | #event_tag_list { border: 1px solid #303030; margin: 0 5px; width: 558px; }
19 | #event_start, #event_submit, #event_tag_list { float: left; }
20 |
21 | #events_list_wrapper table { width: 800px; }
22 |
23 | table { border-collapse: collapse; margin: 15px 0; }
24 | table td, table th { padding: 5px; border: 1px solid #808080; }
25 | table tr:first-child td, table tr:first-child th { border-top: none; }
26 | table tr:last-child td, table tr:last-child th { border-bottom: none; }
27 | table td:first-child, table th:first-child { border-left: none; }
28 | table td:last-child, table th:last-child { border-right: none; }
--------------------------------------------------------------------------------
/public/stylesheets/scaffold._css:
--------------------------------------------------------------------------------
1 | body { background-color: #fff; color: #333; }
2 |
3 | body, p, ol, ul, td {
4 | font-family: verdana, arial, helvetica, sans-serif;
5 | font-size: 13px;
6 | line-height: 18px;
7 | }
8 |
9 | pre {
10 | background-color: #eee;
11 | padding: 10px;
12 | font-size: 11px;
13 | }
14 |
15 | a { color: #000; }
16 | a:visited { color: #666; }
17 | a:hover { color: #fff; background-color:#000; }
18 |
19 | div.field, div.actions {
20 | margin-bottom: 10px;
21 | }
22 |
23 | #notice {
24 | color: green;
25 | }
26 |
27 | .field_with_errors {
28 | padding: 2px;
29 | background-color: red;
30 | display: table;
31 | }
32 |
33 | #error_explanation {
34 | width: 450px;
35 | border: 2px solid red;
36 | padding: 7px;
37 | padding-bottom: 0;
38 | margin-bottom: 20px;
39 | background-color: #f0f0f0;
40 | }
41 |
42 | #error_explanation h2 {
43 | text-align: left;
44 | font-weight: bold;
45 | padding: 5px 5px 5px 15px;
46 | font-size: 12px;
47 | margin: -7px;
48 | margin-bottom: 0px;
49 | background-color: #c00;
50 | color: #fff;
51 | }
52 |
53 | #error_explanation ul li {
54 | font-size: 12px;
55 | list-style: square;
56 | }
57 |
--------------------------------------------------------------------------------
/test/functional/events_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class EventsControllerTest < ActionController::TestCase
4 | setup do
5 | @event = events(:one)
6 | end
7 |
8 | test "should get index" do
9 | get :index
10 | assert_response :success
11 | assert_not_nil assigns(:events)
12 | end
13 |
14 | test "should get new" do
15 | get :new
16 | assert_response :success
17 | end
18 |
19 | test "should create event" do
20 | assert_difference('Event.count') do
21 | post :create, :event => @event.attributes
22 | end
23 |
24 | assert_redirected_to event_path(assigns(:event))
25 | end
26 |
27 | test "should show event" do
28 | get :show, :id => @event.to_param
29 | assert_response :success
30 | end
31 |
32 | test "should get edit" do
33 | get :edit, :id => @event.to_param
34 | assert_response :success
35 | end
36 |
37 | test "should update event" do
38 | put :update, :id => @event.to_param, :event => @event.attributes
39 | assert_redirected_to event_path(assigns(:event))
40 | end
41 |
42 | test "should destroy event" do
43 | assert_difference('Event.count', -1) do
44 | delete :destroy, :id => @event.to_param
45 | end
46 |
47 | assert_redirected_to events_path
48 | end
49 | end
50 |
--------------------------------------------------------------------------------
/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # Note that this schema.rb definition is the authoritative source for your
6 | # database schema. If you need to create the application database on another
7 | # system, you should be using db:schema:load, not running all the migrations
8 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 | # you'll amass, the slower it'll run and the greater likelihood for issues).
10 | #
11 | # It's strongly recommended to check this file into your version control system.
12 |
13 | ActiveRecord::Schema.define(:version => 20110710040901) do
14 |
15 | create_table "events", :force => true do |t|
16 | t.datetime "started_at"
17 | t.datetime "finished_at"
18 | t.datetime "created_at"
19 | t.datetime "updated_at"
20 | end
21 |
22 | create_table "taggings", :force => true do |t|
23 | t.integer "tag_id"
24 | t.integer "taggable_id"
25 | t.string "taggable_type"
26 | t.integer "tagger_id"
27 | t.string "tagger_type"
28 | t.string "context"
29 | t.datetime "created_at"
30 | end
31 |
32 | add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
33 | add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context"
34 |
35 | create_table "tags", :force => true do |t|
36 | t.string "name"
37 | end
38 |
39 | end
40 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Events::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 | # Log error messages when you accidentally call methods on nil.
11 | config.whiny_nils = true
12 |
13 | # Show full error reports and disable caching
14 | config.consider_all_requests_local = true
15 | config.action_controller.perform_caching = false
16 |
17 | # Raise exceptions instead of rendering exception templates
18 | config.action_dispatch.show_exceptions = false
19 |
20 | # Disable request forgery protection in test environment
21 | config.action_controller.allow_forgery_protection = false
22 |
23 | # Tell Action Mailer not to deliver emails to the real world.
24 | # The :test delivery method accumulates sent emails in the
25 | # ActionMailer::Base.deliveries array.
26 | config.action_mailer.delivery_method = :test
27 |
28 | # Use SQL instead of Active Record's schema dumper when creating the test database.
29 | # This is necessary if your schema can't be completely dumped by the schema dumper,
30 | # like if you have constraints or database-specific column types
31 | # config.active_record.schema_format = :sql
32 |
33 | # Print deprecation notices to the stderr
34 | config.active_support.deprecation = :stderr
35 | end
36 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Events::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # The production environment is meant for finished, "live" apps.
5 | # Code is not reloaded between requests
6 | config.cache_classes = true
7 |
8 | # Full error reports are disabled and caching is turned on
9 | config.consider_all_requests_local = false
10 | config.action_controller.perform_caching = true
11 |
12 | # Specifies the header that your server uses for sending files
13 | config.action_dispatch.x_sendfile_header = "X-Sendfile"
14 |
15 | # For nginx:
16 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
17 |
18 | # If you have no front-end server that supports something like X-Sendfile,
19 | # just comment this out and Rails will serve the files
20 |
21 | # See everything in the log (default is :info)
22 | # config.log_level = :debug
23 |
24 | # Use a different logger for distributed setups
25 | # config.logger = SyslogLogger.new
26 |
27 | # Use a different cache store in production
28 | # config.cache_store = :mem_cache_store
29 |
30 | # Disable Rails's static asset server
31 | # In production, Apache or nginx will already do this
32 | config.serve_static_assets = true
33 |
34 | # Enable serving of images, stylesheets, and javascripts from an asset server
35 | # config.action_controller.asset_host = "http://assets.example.com"
36 |
37 | # Disable delivery errors, bad email addresses will be ignored
38 | # config.action_mailer.raise_delivery_errors = false
39 |
40 | # Enable threaded mode
41 | # config.threadsafe!
42 |
43 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
44 | # the I18n.default_locale when a translation can not be found)
45 | config.i18n.fallbacks = true
46 |
47 | # Send deprecation notices to registered listeners
48 | config.active_support.deprecation = :notify
49 | end
50 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Events::Application.routes.draw do
2 | resources :events do
3 | collection do
4 | get :get_started_at
5 | end
6 | end
7 |
8 | root :to => 'events#index'
9 |
10 | # The priority is based upon order of creation:
11 | # first created -> highest priority.
12 |
13 | # Sample of regular route:
14 | # match 'products/:id' => 'catalog#view'
15 | # Keep in mind you can assign values other than :controller and :action
16 |
17 | # Sample of named route:
18 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
19 | # This route can be invoked with purchase_url(:id => product.id)
20 |
21 | # Sample resource route (maps HTTP verbs to controller actions automatically):
22 | # resources :products
23 |
24 | # Sample resource route with options:
25 | # resources :products do
26 | # member do
27 | # get 'short'
28 | # post 'toggle'
29 | # end
30 | #
31 | # collection do
32 | # get 'sold'
33 | # end
34 | # end
35 |
36 | # Sample resource route with sub-resources:
37 | # resources :products do
38 | # resources :comments, :sales
39 | # resource :seller
40 | # end
41 |
42 | # Sample resource route with more complex sub-resources
43 | # resources :products do
44 | # resources :comments
45 | # resources :sales do
46 | # get 'recent', :on => :collection
47 | # end
48 | # end
49 |
50 | # Sample resource route within a namespace:
51 | # namespace :admin do
52 | # # Directs /admin/products/* to Admin::ProductsController
53 | # # (app/controllers/admin/products_controller.rb)
54 | # resources :products
55 | # end
56 |
57 | # You can have the root of your site routed with "root"
58 | # just remember to delete public/index.html.
59 | # root :to => "welcome#index"
60 |
61 | # See how all your routes lay out with "rake routes"
62 |
63 | # This is a legacy wild controller route that's not recommended for RESTful applications.
64 | # Note: This route will make all actions in every controller accessible via GET requests.
65 | # match ':controller(/:action(/:id(.:format)))'
66 | end
67 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require 'rails/all'
4 |
5 | # If you have a Gemfile, require the gems listed there, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(:default, Rails.env) if defined?(Bundler)
8 |
9 | module Events
10 | class Application < Rails::Application
11 | # Settings in config/environments/* take precedence over those specified here.
12 | # Application configuration should go into files in config/initializers
13 | # -- all .rb files in that directory are automatically loaded.
14 |
15 | # Custom directories with classes and modules you want to be autoloadable.
16 | # config.autoload_paths += %W(#{config.root}/extras)
17 |
18 | # Only load the plugins named here, in the order given (default is alphabetical).
19 | # :all can be used as a placeholder for all plugins not explicitly named.
20 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
21 |
22 | # Activate observers that should always be running.
23 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
24 |
25 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
26 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
27 | config.time_zone = 'Canberra'
28 |
29 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
30 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
31 | # config.i18n.default_locale = :de
32 |
33 | # JavaScript files you want as :defaults (application.js is always included).
34 | # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
35 |
36 | # Configure the default encoding used in templates for Ruby 1.9.
37 | config.encoding = "utf-8"
38 |
39 | # Configure sensitive parameters which will be filtered from the log file.
40 | config.filter_parameters += [:password]
41 | end
42 | end
43 |
44 | ::Time::DATE_FORMATS[:default] = "%d %B %Y %I:%M%p"
45 | ::Time::DATE_FORMATS[:date] = "%d %B %Y"
46 | ::Time::DATE_FORMATS[:time] = "%I:%M%p"
47 | ::Time::DATE_FORMATS[:csv] = "%Y-%m-%d %I:%M:%S%p"
48 |
49 | ActsAsTaggableOn::TagList.delimiter = ' '
50 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://rubygems.org/
3 | specs:
4 | abstract (1.0.0)
5 | actionmailer (3.0.7)
6 | actionpack (= 3.0.7)
7 | mail (~> 2.2.15)
8 | actionpack (3.0.7)
9 | activemodel (= 3.0.7)
10 | activesupport (= 3.0.7)
11 | builder (~> 2.1.2)
12 | erubis (~> 2.6.6)
13 | i18n (~> 0.5.0)
14 | rack (~> 1.2.1)
15 | rack-mount (~> 0.6.14)
16 | rack-test (~> 0.5.7)
17 | tzinfo (~> 0.3.23)
18 | activemodel (3.0.7)
19 | activesupport (= 3.0.7)
20 | builder (~> 2.1.2)
21 | i18n (~> 0.5.0)
22 | activerecord (3.0.7)
23 | activemodel (= 3.0.7)
24 | activesupport (= 3.0.7)
25 | arel (~> 2.0.2)
26 | tzinfo (~> 0.3.23)
27 | activeresource (3.0.7)
28 | activemodel (= 3.0.7)
29 | activesupport (= 3.0.7)
30 | activesupport (3.0.7)
31 | acts-as-taggable-on (2.1.0)
32 | arel (2.0.10)
33 | builder (2.1.2)
34 | daemons (1.0.10)
35 | dotiw (1.0.0)
36 | actionpack (~> 3.0.0)
37 | erubis (2.6.6)
38 | abstract (>= 1.0.0)
39 | gem_plugin (0.2.3)
40 | haml (3.0.22)
41 | haml-rails (0.3.4)
42 | actionpack (~> 3.0)
43 | activesupport (~> 3.0)
44 | haml (~> 3.0)
45 | railties (~> 3.0)
46 | i18n (0.5.0)
47 | jquery-rails (1.0.12)
48 | railties (~> 3.0)
49 | thor (~> 0.14)
50 | jrails (0.6.0)
51 | mail (2.2.19)
52 | activesupport (>= 2.3.6)
53 | i18n (>= 0.4.0)
54 | mime-types (~> 1.16)
55 | treetop (~> 1.4.8)
56 | mime-types (1.16)
57 | mongrel (1.2.0.pre2)
58 | daemons (~> 1.0.10)
59 | gem_plugin (~> 0.2.3)
60 | polyglot (0.3.1)
61 | rack (1.2.1)
62 | rack-mount (0.6.14)
63 | rack (>= 1.0.0)
64 | rack-test (0.5.7)
65 | rack (>= 1.0)
66 | rails (3.0.7)
67 | actionmailer (= 3.0.7)
68 | actionpack (= 3.0.7)
69 | activerecord (= 3.0.7)
70 | activeresource (= 3.0.7)
71 | activesupport (= 3.0.7)
72 | bundler (~> 1.0)
73 | railties (= 3.0.7)
74 | railties (3.0.7)
75 | actionpack (= 3.0.7)
76 | activesupport (= 3.0.7)
77 | rake (>= 0.8.7)
78 | thor (~> 0.14.4)
79 | rake (0.9.2)
80 | sqlite3 (1.3.3)
81 | thor (0.14.6)
82 | treetop (1.4.9)
83 | polyglot (>= 0.3.1)
84 | tzinfo (0.3.27)
85 |
86 | PLATFORMS
87 | ruby
88 |
89 | DEPENDENCIES
90 | acts-as-taggable-on (= 2.1.0)
91 | dotiw (= 1.0.0)
92 | haml (= 3.0.22)
93 | haml-rails (= 0.3.4)
94 | jquery-rails (>= 1.0.12)
95 | jrails (= 0.6.0)
96 | mongrel (= 1.2.0.pre2)
97 | rails (= 3.0.7)
98 | sqlite3 (= 1.3.3)
99 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | == Welcome to Rails
2 |
3 | Rails is a web-application framework that includes everything needed to create
4 | database-backed web applications according to the Model-View-Control pattern.
5 |
6 | This pattern splits the view (also called the presentation) into "dumb"
7 | templates that are primarily responsible for inserting pre-built data in between
8 | HTML tags. The model contains the "smart" domain objects (such as Account,
9 | Product, Person, Post) that holds all the business logic and knows how to
10 | persist themselves to a database. The controller handles the incoming requests
11 | (such as Save New Account, Update Product, Show Post) by manipulating the model
12 | and directing data to the view.
13 |
14 | In Rails, the model is handled by what's called an object-relational mapping
15 | layer entitled Active Record. This layer allows you to present the data from
16 | database rows as objects and embellish these data objects with business logic
17 | methods. You can read more about Active Record in
18 | link:files/vendor/rails/activerecord/README.html.
19 |
20 | The controller and view are handled by the Action Pack, which handles both
21 | layers by its two parts: Action View and Action Controller. These two layers
22 | are bundled in a single package due to their heavy interdependence. This is
23 | unlike the relationship between the Active Record and Action Pack that is much
24 | more separate. Each of these packages can be used independently outside of
25 | Rails. You can read more about Action Pack in
26 | link:files/vendor/rails/actionpack/README.html.
27 |
28 |
29 | == Getting Started
30 |
31 | 1. At the command prompt, create a new Rails application:
32 | rails new myapp (where myapp is the application name)
33 |
34 | 2. Change directory to myapp and start the web server:
35 | cd myapp; rails server (run with --help for options)
36 |
37 | 3. Go to http://localhost:3000/ and you'll see:
38 | "Welcome aboard: You're riding Ruby on Rails!"
39 |
40 | 4. Follow the guidelines to start developing your application. You can find
41 | the following resources handy:
42 |
43 | * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
44 | * Ruby on Rails Tutorial Book: http://www.railstutorial.org/
45 |
46 |
47 | == Debugging Rails
48 |
49 | Sometimes your application goes wrong. Fortunately there are a lot of tools that
50 | will help you debug it and get it back on the rails.
51 |
52 | First area to check is the application log files. Have "tail -f" commands
53 | running on the server.log and development.log. Rails will automatically display
54 | debugging and runtime information to these files. Debugging info will also be
55 | shown in the browser on requests from 127.0.0.1.
56 |
57 | You can also log your own messages directly into the log file from your code
58 | using the Ruby logger class from inside your controllers. Example:
59 |
60 | class WeblogController < ActionController::Base
61 | def destroy
62 | @weblog = Weblog.find(params[:id])
63 | @weblog.destroy
64 | logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
65 | end
66 | end
67 |
68 | The result will be a message in your log file along the lines of:
69 |
70 | Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
71 |
72 | More information on how to use the logger is at http://www.ruby-doc.org/core/
73 |
74 | Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
75 | several books available online as well:
76 |
77 | * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
78 | * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
79 |
80 | These two books will bring you up to speed on the Ruby language and also on
81 | programming in general.
82 |
83 |
84 | == Debugger
85 |
86 | Debugger support is available through the debugger command when you start your
87 | Mongrel or WEBrick server with --debugger. This means that you can break out of
88 | execution at any point in the code, investigate and change the model, and then,
89 | resume execution! You need to install ruby-debug to run the server in debugging
90 | mode. With gems, use sudo gem install ruby-debug. Example:
91 |
92 | class WeblogController < ActionController::Base
93 | def index
94 | @posts = Post.find(:all)
95 | debugger
96 | end
97 | end
98 |
99 | So the controller will accept the action, run the first line, then present you
100 | with a IRB prompt in the server window. Here you can do things like:
101 |
102 | >> @posts.inspect
103 | => "[#nil, "body"=>nil, "id"=>"1"}>,
105 | #"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
107 | >> @posts.first.title = "hello from a debugger"
108 | => "hello from a debugger"
109 |
110 | ...and even better, you can examine how your runtime objects actually work:
111 |
112 | >> f = @posts.first
113 | => #nil, "body"=>nil, "id"=>"1"}>
114 | >> f.
115 | Display all 152 possibilities? (y or n)
116 |
117 | Finally, when you're ready to resume execution, you can enter "cont".
118 |
119 |
120 | == Console
121 |
122 | The console is a Ruby shell, which allows you to interact with your
123 | application's domain model. Here you'll have all parts of the application
124 | configured, just like it is when the application is running. You can inspect
125 | domain models, change values, and save to the database. Starting the script
126 | without arguments will launch it in the development environment.
127 |
128 | To start the console, run rails console from the application
129 | directory.
130 |
131 | Options:
132 |
133 | * Passing the -s, --sandbox argument will rollback any modifications
134 | made to the database.
135 | * Passing an environment name as an argument will load the corresponding
136 | environment. Example: rails console production.
137 |
138 | To reload your controllers and models after launching the console run
139 | reload!
140 |
141 | More information about irb can be found at:
142 | link:http://www.rubycentral.com/pickaxe/irb.html
143 |
144 |
145 | == dbconsole
146 |
147 | You can go to the command line of your database directly through rails
148 | dbconsole. You would be connected to the database with the credentials
149 | defined in database.yml. Starting the script without arguments will connect you
150 | to the development database. Passing an argument will connect you to a different
151 | database, like rails dbconsole production. Currently works for MySQL,
152 | PostgreSQL and SQLite 3.
153 |
154 | == Description of Contents
155 |
156 | The default directory structure of a generated Ruby on Rails application:
157 |
158 | |-- app
159 | | |-- controllers
160 | | |-- helpers
161 | | |-- mailers
162 | | |-- models
163 | | `-- views
164 | | `-- layouts
165 | |-- config
166 | | |-- environments
167 | | |-- initializers
168 | | `-- locales
169 | |-- db
170 | |-- doc
171 | |-- lib
172 | | `-- tasks
173 | |-- log
174 | |-- public
175 | | |-- images
176 | | |-- javascripts
177 | | `-- stylesheets
178 | |-- script
179 | |-- test
180 | | |-- fixtures
181 | | |-- functional
182 | | |-- integration
183 | | |-- performance
184 | | `-- unit
185 | |-- tmp
186 | | |-- cache
187 | | |-- pids
188 | | |-- sessions
189 | | `-- sockets
190 | `-- vendor
191 | `-- plugins
192 |
193 | app
194 | Holds all the code that's specific to this particular application.
195 |
196 | app/controllers
197 | Holds controllers that should be named like weblogs_controller.rb for
198 | automated URL mapping. All controllers should descend from
199 | ApplicationController which itself descends from ActionController::Base.
200 |
201 | app/models
202 | Holds models that should be named like post.rb. Models descend from
203 | ActiveRecord::Base by default.
204 |
205 | app/views
206 | Holds the template files for the view that should be named like
207 | weblogs/index.html.erb for the WeblogsController#index action. All views use
208 | eRuby syntax by default.
209 |
210 | app/views/layouts
211 | Holds the template files for layouts to be used with views. This models the
212 | common header/footer method of wrapping views. In your views, define a layout
213 | using the layout :default and create a file named default.html.erb.
214 | Inside default.html.erb, call <% yield %> to render the view using this
215 | layout.
216 |
217 | app/helpers
218 | Holds view helpers that should be named like weblogs_helper.rb. These are
219 | generated for you automatically when using generators for controllers.
220 | Helpers can be used to wrap functionality for your views into methods.
221 |
222 | config
223 | Configuration files for the Rails environment, the routing map, the database,
224 | and other dependencies.
225 |
226 | db
227 | Contains the database schema in schema.rb. db/migrate contains all the
228 | sequence of Migrations for your schema.
229 |
230 | doc
231 | This directory is where your application documentation will be stored when
232 | generated using rake doc:app
233 |
234 | lib
235 | Application specific libraries. Basically, any kind of custom code that
236 | doesn't belong under controllers, models, or helpers. This directory is in
237 | the load path.
238 |
239 | public
240 | The directory available for the web server. Contains subdirectories for
241 | images, stylesheets, and javascripts. Also contains the dispatchers and the
242 | default HTML files. This should be set as the DOCUMENT_ROOT of your web
243 | server.
244 |
245 | script
246 | Helper scripts for automation and generation.
247 |
248 | test
249 | Unit and functional tests along with fixtures. When using the rails generate
250 | command, template test files will be generated for you and placed in this
251 | directory.
252 |
253 | vendor
254 | External libraries that the application depends on. Also includes the plugins
255 | subdirectory. If the app has frozen rails, those gems also go here, under
256 | vendor/rails/. This directory is in the load path.
257 |
--------------------------------------------------------------------------------
/public/javascripts/jquery_ujs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Unobtrusive scripting adapter for jQuery
3 | *
4 | * Requires jQuery 1.4.4 or later.
5 | * https://github.com/rails/jquery-ujs
6 |
7 | * Uploading file using rails.js
8 | * =============================
9 | *
10 | * By default, browsers do not allow files to be uploaded via AJAX. As a result, if there are any non-blank file fields
11 | * in the remote form, this adapter aborts the AJAX submission and allows the form to submit through standard means.
12 | *
13 | * The `ajax:aborted:file` event allows you to bind your own handler to process the form submission however you wish.
14 | *
15 | * Ex:
16 | * $('form').live('ajax:aborted:file', function(event, elements){
17 | * // Implement own remote file-transfer handler here for non-blank file inputs passed in `elements`.
18 | * // Returning false in this handler tells rails.js to disallow standard form submission
19 | * return false;
20 | * });
21 | *
22 | * The `ajax:aborted:file` event is fired when a file-type input is detected with a non-blank value.
23 | *
24 | * Third-party tools can use this hook to detect when an AJAX file upload is attempted, and then use
25 | * techniques like the iframe method to upload the file instead.
26 | *
27 | * Required fields in rails.js
28 | * ===========================
29 | *
30 | * If any blank required inputs (required="required") are detected in the remote form, the whole form submission
31 | * is canceled. Note that this is unlike file inputs, which still allow standard (non-AJAX) form submission.
32 | *
33 | * The `ajax:aborted:required` event allows you to bind your own handler to inform the user of blank required inputs.
34 | *
35 | * !! Note that Opera does not fire the form's submit event if there are blank required inputs, so this event may never
36 | * get fired in Opera. This event is what causes other browsers to exhibit the same submit-aborting behavior.
37 | *
38 | * Ex:
39 | * $('form').live('ajax:aborted:required', function(event, elements){
40 | * // Returning false in this handler tells rails.js to submit the form anyway.
41 | * // The blank required inputs are passed to this function in `elements`.
42 | * return ! confirm("Would you like to submit the form with missing info?");
43 | * });
44 | */
45 |
46 | (function($, undefined) {
47 | // Shorthand to make it a little easier to call public rails functions from within rails.js
48 | var rails;
49 |
50 | $.rails = rails = {
51 | // Link elements bound by jquery-ujs
52 | linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]',
53 |
54 | // Select elements bound by jquery-ujs
55 | selectChangeSelector: 'select[data-remote]',
56 |
57 | // Form elements bound by jquery-ujs
58 | formSubmitSelector: 'form',
59 |
60 | // Form input elements bound by jquery-ujs
61 | formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])',
62 |
63 | // Form input elements disabled during form submission
64 | disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]',
65 |
66 | // Form input elements re-enabled after form submission
67 | enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled',
68 |
69 | // Form required input elements
70 | requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])',
71 |
72 | // Form file input elements
73 | fileInputSelector: 'input:file',
74 |
75 | // Make sure that every Ajax request sends the CSRF token
76 | CSRFProtection: function(xhr) {
77 | var token = $('meta[name="csrf-token"]').attr('content');
78 | if (token) xhr.setRequestHeader('X-CSRF-Token', token);
79 | },
80 |
81 | // Triggers an event on an element and returns false if the event result is false
82 | fire: function(obj, name, data) {
83 | var event = $.Event(name);
84 | obj.trigger(event, data);
85 | return event.result !== false;
86 | },
87 |
88 | // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
89 | confirm: function(message) {
90 | return confirm(message);
91 | },
92 |
93 | // Default ajax function, may be overridden with custom function in $.rails.ajax
94 | ajax: function(options) {
95 | return $.ajax(options);
96 | },
97 |
98 | // Submits "remote" forms and links with ajax
99 | handleRemote: function(element) {
100 | var method, url, data,
101 | crossDomain = element.data('cross-domain') || null,
102 | dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
103 |
104 | if (rails.fire(element, 'ajax:before')) {
105 |
106 | if (element.is('form')) {
107 | method = element.attr('method');
108 | url = element.attr('action');
109 | data = element.serializeArray();
110 | // memoized value from clicked submit button
111 | var button = element.data('ujs:submit-button');
112 | if (button) {
113 | data.push(button);
114 | element.data('ujs:submit-button', null);
115 | }
116 | } else if (element.is('select')) {
117 | method = element.data('method');
118 | url = element.data('url');
119 | data = element.serialize();
120 | if (element.data('params')) data = data + "&" + element.data('params');
121 | } else {
122 | method = element.data('method');
123 | url = element.attr('href');
124 | data = element.data('params') || null;
125 | }
126 |
127 | options = {
128 | type: method || 'GET', data: data, dataType: dataType, crossDomain: crossDomain,
129 | // stopping the "ajax:beforeSend" event will cancel the ajax request
130 | beforeSend: function(xhr, settings) {
131 | if (settings.dataType === undefined) {
132 | xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
133 | }
134 | return rails.fire(element, 'ajax:beforeSend', [xhr, settings]);
135 | },
136 | success: function(data, status, xhr) {
137 | element.trigger('ajax:success', [data, status, xhr]);
138 | },
139 | complete: function(xhr, status) {
140 | element.trigger('ajax:complete', [xhr, status]);
141 | },
142 | error: function(xhr, status, error) {
143 | element.trigger('ajax:error', [xhr, status, error]);
144 | }
145 | };
146 | // Do not pass url to `ajax` options if blank
147 | if (url) { $.extend(options, { url: url }); }
148 |
149 | rails.ajax(options);
150 | }
151 | },
152 |
153 | // Handles "data-method" on links such as:
154 | // Delete
155 | handleMethod: function(link) {
156 | var href = link.attr('href'),
157 | method = link.data('method'),
158 | csrf_token = $('meta[name=csrf-token]').attr('content'),
159 | csrf_param = $('meta[name=csrf-param]').attr('content'),
160 | form = $(''),
161 | metadata_input = '';
162 |
163 | if (csrf_param !== undefined && csrf_token !== undefined) {
164 | metadata_input += '';
165 | }
166 |
167 | form.hide().append(metadata_input).appendTo('body');
168 | form.submit();
169 | },
170 |
171 | /* Disables form elements:
172 | - Caches element value in 'ujs:enable-with' data store
173 | - Replaces element text with value of 'data-disable-with' attribute
174 | - Adds disabled=disabled attribute
175 | */
176 | disableFormElements: function(form) {
177 | form.find(rails.disableSelector).each(function() {
178 | var element = $(this), method = element.is('button') ? 'html' : 'val';
179 | element.data('ujs:enable-with', element[method]());
180 | element[method](element.data('disable-with'));
181 | element.attr('disabled', 'disabled');
182 | });
183 | },
184 |
185 | /* Re-enables disabled form elements:
186 | - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
187 | - Removes disabled attribute
188 | */
189 | enableFormElements: function(form) {
190 | form.find(rails.enableSelector).each(function() {
191 | var element = $(this), method = element.is('button') ? 'html' : 'val';
192 | if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with'));
193 | element.removeAttr('disabled');
194 | });
195 | },
196 |
197 | /* For 'data-confirm' attribute:
198 | - Fires `confirm` event
199 | - Shows the confirmation dialog
200 | - Fires the `confirm:complete` event
201 |
202 | Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
203 | Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
204 | Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
205 | return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
206 | */
207 | allowAction: function(element) {
208 | var message = element.data('confirm'),
209 | answer = false, callback;
210 | if (!message) { return true; }
211 |
212 | if (rails.fire(element, 'confirm')) {
213 | answer = rails.confirm(message);
214 | callback = rails.fire(element, 'confirm:complete', [answer]);
215 | }
216 | return answer && callback;
217 | },
218 |
219 | // Helper function which checks for blank inputs in a form that match the specified CSS selector
220 | blankInputs: function(form, specifiedSelector, nonBlank) {
221 | var inputs = $(), input,
222 | selector = specifiedSelector || 'input,textarea';
223 | form.find(selector).each(function() {
224 | input = $(this);
225 | // Collect non-blank inputs if nonBlank option is true, otherwise, collect blank inputs
226 | if (nonBlank ? input.val() : !input.val()) {
227 | inputs = inputs.add(input);
228 | }
229 | });
230 | return inputs.length ? inputs : false;
231 | },
232 |
233 | // Helper function which checks for non-blank inputs in a form that match the specified CSS selector
234 | nonBlankInputs: function(form, specifiedSelector) {
235 | return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
236 | },
237 |
238 | // Helper function, needed to provide consistent behavior in IE
239 | stopEverything: function(e) {
240 | $(e.target).trigger('ujs:everythingStopped');
241 | e.stopImmediatePropagation();
242 | return false;
243 | },
244 |
245 | // find all the submit events directly bound to the form and
246 | // manually invoke them. If anyone returns false then stop the loop
247 | callFormSubmitBindings: function(form) {
248 | var events = form.data('events'), continuePropagation = true;
249 | if (events !== undefined && events['submit'] !== undefined) {
250 | $.each(events['submit'], function(i, obj){
251 | if (typeof obj.handler === 'function') return continuePropagation = obj.handler(obj.data);
252 | });
253 | }
254 | return continuePropagation;
255 | }
256 | };
257 |
258 | // ajaxPrefilter is a jQuery 1.5 feature
259 | if ('ajaxPrefilter' in $) {
260 | $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
261 | } else {
262 | $(document).ajaxSend(function(e, xhr, options){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
263 | }
264 |
265 | $(rails.linkClickSelector).live('click.rails', function(e) {
266 | var link = $(this);
267 | if (!rails.allowAction(link)) return rails.stopEverything(e);
268 |
269 | if (link.data('remote') !== undefined) {
270 | rails.handleRemote(link);
271 | return false;
272 | } else if (link.data('method')) {
273 | rails.handleMethod(link);
274 | return false;
275 | }
276 | });
277 |
278 | $(rails.selectChangeSelector).live('change.rails', function(e) {
279 | var link = $(this);
280 | if (!rails.allowAction(link)) return rails.stopEverything(e);
281 |
282 | rails.handleRemote(link);
283 | return false;
284 | });
285 |
286 | $(rails.formSubmitSelector).live('submit.rails', function(e) {
287 | var form = $(this),
288 | remote = form.data('remote') !== undefined,
289 | blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector),
290 | nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
291 |
292 | if (!rails.allowAction(form)) return rails.stopEverything(e);
293 |
294 | // skip other logic when required values are missing or file upload is present
295 | if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
296 | return rails.stopEverything(e);
297 | }
298 |
299 | if (remote) {
300 | if (nonBlankFileInputs) {
301 | return rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
302 | }
303 |
304 | // If browser does not support submit bubbling, then this live-binding will be called before direct
305 | // bindings. Therefore, we should directly call any direct bindings before remotely submitting form.
306 | if (!$.support.submitBubbles && rails.callFormSubmitBindings(form) === false) return rails.stopEverything(e);
307 |
308 | rails.handleRemote(form);
309 | return false;
310 | } else {
311 | // slight timeout so that the submit button gets properly serialized
312 | setTimeout(function(){ rails.disableFormElements(form); }, 13);
313 | }
314 | });
315 |
316 | $(rails.formInputClickSelector).live('click.rails', function(event) {
317 | var button = $(this);
318 |
319 | if (!rails.allowAction(button)) return rails.stopEverything(event);
320 |
321 | // register the pressed submit button
322 | var name = button.attr('name'),
323 | data = name ? {name:name, value:button.val()} : null;
324 |
325 | button.closest('form').data('ujs:submit-button', data);
326 | });
327 |
328 | $(rails.formSubmitSelector).live('ajax:beforeSend.rails', function(event) {
329 | if (this == event.target) rails.disableFormElements($(this));
330 | });
331 |
332 | $(rails.formSubmitSelector).live('ajax:complete.rails', function(event) {
333 | if (this == event.target) rails.enableFormElements($(this));
334 | });
335 |
336 | })( jQuery );
337 |
--------------------------------------------------------------------------------
/public/javascripts/jquery.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery JavaScript Library v1.6.1
3 | * http://jquery.com/
4 | *
5 | * Copyright 2011, John Resig
6 | * Dual licensed under the MIT or GPL Version 2 licenses.
7 | * http://jquery.org/license
8 | *
9 | * Includes Sizzle.js
10 | * http://sizzlejs.com/
11 | * Copyright 2011, The Dojo Foundation
12 | * Released under the MIT, BSD, and GPL Licenses.
13 | *
14 | * Date: Thu May 12 15:04:36 2011 -0400
15 | */
16 | (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!cj[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),c.body.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write("");b=cl.createElement(a),cl.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ck)}cj[a]=d}return cj[a]}function cu(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function ct(){cq=b}function cs(){setTimeout(ct,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g=0===c})}function W(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function O(a,b){return(a&&a!=="*"?a+".":"")+b.replace(A,"`").replace(B,"&")}function N(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function L(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function F(){return!0}function E(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.1",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};f=c.createElement("select"),g=f.appendChild(c.createElement("option")),h=a.getElementsByTagName("input")[0],j={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},h.checked=!0,j.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,j.optDisabled=!g.disabled;try{delete a.test}catch(s){j.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function b(){j.noCloneEvent=!1,a.detachEvent("onclick",b)}),a.cloneNode(!0).fireEvent("onclick")),h=c.createElement("input"),h.value="t",h.setAttribute("type","radio"),j.radioValue=h.value==="t",h.setAttribute("checked","checked"),a.appendChild(h),k=c.createDocumentFragment(),k.appendChild(a.firstChild),j.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",l=c.createElement("body"),m={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(q in m)l.style[q]=m[q];l.appendChild(a),b.insertBefore(l,b.firstChild),j.appendChecked=h.checked,j.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,j.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="",j.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="