├── README ├── log └── .gitkeep ├── lib ├── tasks │ └── .gitkeep └── assets │ └── .gitkeep ├── public ├── favicon.ico ├── assets │ ├── application-ccb8034635849c44627859332fda6a01.css │ ├── rails-bd9ad5a560b5a3a7be0808c5cd76a798.png │ ├── capture-1-4ebb65f5c8c19cc19aa0c1047fb4604a.png │ ├── capture-2-828313ace750a6ff45b8035208cb3353.png │ ├── ICanHaz-b4b81e9871b46f7e192a5e1d3182010b.min.js.gz │ ├── application-3fdab497b8fb70d20cfc5495239dfc29.js.gz │ ├── application-48f8c652bc0b152ec609cf2202317868.js.gz │ ├── application-645a8b4d274aac42bd12222aa417167d.js.gz │ ├── application-c3225ee84ce409dadad4c616f4ae974b.js.gz │ ├── application-d93c351b259a97f5602cf0828502bac4.js.gz │ ├── jquery-8a50feed8d29566738ad005e19fe1c2d.min.js.gz │ ├── application-1256e2bab720fa68d08bf74acc61842c.css.gz │ ├── application-2d1f3e4d1da28508d80d84d36a4fa4ca.css.gz │ ├── application-ccb8034635849c44627859332fda6a01.css.gz │ ├── application-eca11a164e7a94a5e569b5696333d218.css.gz │ ├── jquery-ui-7e33882a28fc84ad0e0e47e46cbf901c.min.js.gz │ ├── application-2d1f3e4d1da28508d80d84d36a4fa4ca.css │ ├── manifest.yml │ ├── application-eca11a164e7a94a5e569b5696333d218.css │ ├── application-1256e2bab720fa68d08bf74acc61842c.css │ ├── ICanHaz-b4b81e9871b46f7e192a5e1d3182010b.min.js │ └── jquery-8a50feed8d29566738ad005e19fe1c2d.min.js ├── robots.txt ├── 422.html ├── 404.html └── 500.html ├── test ├── unit │ ├── .gitkeep │ ├── helpers │ │ ├── homes_helper_test.rb │ │ └── thanks_helper_test.rb │ ├── user_test.rb │ └── thank_test.rb ├── fixtures │ ├── .gitkeep │ ├── thanks.yml │ └── users.yml ├── functional │ ├── .gitkeep │ ├── homes_controller_test.rb │ └── thanks_controller_test.rb ├── integration │ └── .gitkeep ├── performance │ └── browsing_test.rb └── test_helper.rb ├── app ├── mailers │ └── .gitkeep ├── models │ ├── .gitkeep │ ├── user.rb │ └── thank.rb ├── helpers │ ├── homes_helper.rb │ ├── thanks_helper.rb │ ├── application_helper.rb │ ├── layout_helper.rb │ └── error_messages_helper.rb ├── .DS_Store ├── assets │ ├── .DS_Store │ ├── images │ │ ├── .DS_Store │ │ ├── rails.png │ │ ├── capture-1.png │ │ └── capture-2.png │ ├── stylesheets │ │ ├── homes.css.scss │ │ ├── common.css.scss │ │ ├── application.css │ │ └── thanks.css.scss │ └── javascripts │ │ ├── homes.js.coffee │ │ ├── application.js │ │ └── thanks.js.coffee ├── controllers │ ├── homes_controller.rb │ ├── application_controller.rb │ └── thanks_controller.rb └── views │ ├── thanks │ ├── edit.html.haml │ ├── show.html.haml │ ├── new.html.haml │ ├── _form.html.haml │ └── index.html.haml │ ├── devise │ ├── mailer │ │ ├── confirmation_instructions.html.erb │ │ ├── unlock_instructions.html.erb │ │ └── reset_password_instructions.html.erb │ ├── unlocks │ │ └── new.html.erb │ ├── confirmations │ │ └── new.html.erb │ ├── shared │ │ └── _links.erb │ ├── passwords │ │ ├── new.html.haml │ │ └── edit.html.haml │ ├── sessions │ │ └── new.html.haml │ └── registrations │ │ ├── new.html.haml │ │ └── edit.html.haml │ ├── layouts │ └── application.html.haml │ └── homes │ └── index.html.haml ├── vendor ├── plugins │ └── .gitkeep └── assets │ ├── stylesheets │ └── .gitkeep │ └── javascripts │ ├── ICanHaz.min.js │ └── underscore.js ├── .DS_Store ├── .gitignore ├── config.ru ├── config ├── routes.rb ├── environment.rb ├── boot.rb ├── initializers │ ├── mime_types.rb │ ├── ext.rb │ ├── inflections.rb │ ├── backtrace_silencers.rb │ ├── session_store.rb │ ├── secret_token.rb │ ├── wrap_parameters.rb │ └── devise.rb ├── locales │ ├── en.yml │ ├── translation_ja.yml │ ├── devise.en.yml │ ├── devise.ja.yml │ └── ja.yml ├── database.yml ├── environments │ ├── development.rb │ ├── test.rb │ └── production.rb └── application.rb ├── doc └── README_FOR_APP ├── Rakefile ├── db ├── migrate │ ├── 20110907054247_create_thanks.rb │ └── 20110907082955_devise_create_users.rb ├── seeds.rb └── schema.rb ├── script └── rails ├── Gemfile └── Gemfile.lock /README: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /log/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/unit/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/functional/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/integration/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/helpers/homes_helper.rb: -------------------------------------------------------------------------------- 1 | module HomesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/thanks_helper.rb: -------------------------------------------------------------------------------- 1 | module ThanksHelper 2 | end 3 | -------------------------------------------------------------------------------- /public/assets/application-ccb8034635849c44627859332fda6a01.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/.DS_Store -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/app/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | db/*.sqlite3 3 | log/*.log 4 | tmp/ 5 | .sass-cache/ 6 | -------------------------------------------------------------------------------- /app/assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/app/assets/.DS_Store -------------------------------------------------------------------------------- /app/assets/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/app/assets/images/.DS_Store -------------------------------------------------------------------------------- /app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/app/assets/images/rails.png -------------------------------------------------------------------------------- /app/assets/images/capture-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/app/assets/images/capture-1.png -------------------------------------------------------------------------------- /app/assets/images/capture-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/app/assets/images/capture-2.png -------------------------------------------------------------------------------- /app/assets/stylesheets/homes.css.scss: -------------------------------------------------------------------------------- 1 | .homes-index-page { 2 | .hero-unit { 3 | margin-top: 5px; 4 | } 5 | } -------------------------------------------------------------------------------- /app/controllers/homes_controller.rb: -------------------------------------------------------------------------------- 1 | class HomesController < ApplicationController 2 | def index 3 | end 4 | 5 | end 6 | -------------------------------------------------------------------------------- /test/unit/helpers/homes_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HomesHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/unit/helpers/thanks_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ThanksHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/common.css.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | margin-top: 25px; 3 | padding: 10px; 4 | border-top: 1px solid #CCC; 5 | } -------------------------------------------------------------------------------- /app/views/thanks/edit.html.haml: -------------------------------------------------------------------------------- 1 | %h1 Editing thank 2 | 3 | = render 'form' 4 | 5 | = link_to 'Show', @thank 6 | \| 7 | = link_to 'Back', thanks_path 8 | -------------------------------------------------------------------------------- /app/views/thanks/show.html.haml: -------------------------------------------------------------------------------- 1 | %p#notice= notice 2 | 3 | 4 | = link_to 'Edit', edit_thank_path(@thank) 5 | \| 6 | = link_to 'Back', thanks_path 7 | -------------------------------------------------------------------------------- /public/assets/rails-bd9ad5a560b5a3a7be0808c5cd76a798.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/rails-bd9ad5a560b5a3a7be0808c5cd76a798.png -------------------------------------------------------------------------------- /test/unit/user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UserTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /public/assets/capture-1-4ebb65f5c8c19cc19aa0c1047fb4604a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/capture-1-4ebb65f5c8c19cc19aa0c1047fb4604a.png -------------------------------------------------------------------------------- /public/assets/capture-2-828313ace750a6ff45b8035208cb3353.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/capture-2-828313ace750a6ff45b8035208cb3353.png -------------------------------------------------------------------------------- /test/unit/thank_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ThankTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /public/assets/ICanHaz-b4b81e9871b46f7e192a5e1d3182010b.min.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/ICanHaz-b4b81e9871b46f7e192a5e1d3182010b.min.js.gz -------------------------------------------------------------------------------- /public/assets/application-3fdab497b8fb70d20cfc5495239dfc29.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-3fdab497b8fb70d20cfc5495239dfc29.js.gz -------------------------------------------------------------------------------- /public/assets/application-48f8c652bc0b152ec609cf2202317868.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-48f8c652bc0b152ec609cf2202317868.js.gz -------------------------------------------------------------------------------- /public/assets/application-645a8b4d274aac42bd12222aa417167d.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-645a8b4d274aac42bd12222aa417167d.js.gz -------------------------------------------------------------------------------- /public/assets/application-c3225ee84ce409dadad4c616f4ae974b.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-c3225ee84ce409dadad4c616f4ae974b.js.gz -------------------------------------------------------------------------------- /public/assets/application-d93c351b259a97f5602cf0828502bac4.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-d93c351b259a97f5602cf0828502bac4.js.gz -------------------------------------------------------------------------------- /public/assets/jquery-8a50feed8d29566738ad005e19fe1c2d.min.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/jquery-8a50feed8d29566738ad005e19fe1c2d.min.js.gz -------------------------------------------------------------------------------- /app/views/thanks/new.html.haml: -------------------------------------------------------------------------------- 1 | - title '感謝の気持ちをメモする - 5Thanks' 2 | 3 | .page-header 4 | %h1 5 | 感謝の気持ちをメモする 6 | 7 | .row 8 | .span16 9 | = render 'form' 10 | -------------------------------------------------------------------------------- /public/assets/application-1256e2bab720fa68d08bf74acc61842c.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-1256e2bab720fa68d08bf74acc61842c.css.gz -------------------------------------------------------------------------------- /public/assets/application-2d1f3e4d1da28508d80d84d36a4fa4ca.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-2d1f3e4d1da28508d80d84d36a4fa4ca.css.gz -------------------------------------------------------------------------------- /public/assets/application-ccb8034635849c44627859332fda6a01.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-ccb8034635849c44627859332fda6a01.css.gz -------------------------------------------------------------------------------- /public/assets/application-eca11a164e7a94a5e569b5696333d218.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/application-eca11a164e7a94a5e569b5696333d218.css.gz -------------------------------------------------------------------------------- /public/assets/jquery-ui-7e33882a28fc84ad0e0e47e46cbf901c.min.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/func09/5Thanks/HEAD/public/assets/jquery-ui-7e33882a28fc84ad0e0e47e46cbf901c.min.js.gz -------------------------------------------------------------------------------- /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 Kanshabox::Application 5 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Kanshabox::Application.routes.draw do 2 | root :to => 'homes#index' 3 | resources :thanks, :only => [:index, :new, :create, :destroy] 4 | devise_for :users 5 | end 6 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Kanshabox::Application.initialize! 6 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | def after_sign_in_path_for(resource) 4 | thanks_path || root_path 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.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 | -------------------------------------------------------------------------------- /test/functional/homes_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HomesControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | end 8 | 9 | end 10 | -------------------------------------------------------------------------------- /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_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /app/assets/javascripts/homes.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @resource.email %>!

2 | 3 |

You can confirm your account through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %>

6 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Kanshabox::Application.load_tasks 8 | -------------------------------------------------------------------------------- /db/migrate/20110907054247_create_thanks.rb: -------------------------------------------------------------------------------- 1 | class CreateThanks < ActiveRecord::Migration 2 | def change 3 | create_table :thanks do |t| 4 | t.integer :user_id 5 | t.string :what 6 | t.string :message 7 | t.datetime :date_at 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /config/initializers/ext.rb: -------------------------------------------------------------------------------- 1 | module ThisMonth 2 | def this_month? 3 | ((Date.today.beginning_of_month)..(Date.today.end_of_month)).include?(self.to_date) 4 | end 5 | end 6 | 7 | class Date 8 | include ThisMonth 9 | end 10 | class DateTime 11 | include ThisMonth 12 | end 13 | class Time 14 | include ThisMonth 15 | end 16 | -------------------------------------------------------------------------------- /app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive amount of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %>

8 | -------------------------------------------------------------------------------- /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 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll automatically include all the stylesheets available in this directory 3 | * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at 4 | * the top of the compiled file, but it's generally better to create a new file per style scope. 5 | *= require_self 6 | *= require_tree . 7 | */ -------------------------------------------------------------------------------- /test/fixtures/thanks.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/Fixtures.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/users.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/Fixtures.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /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 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'rails/performance_test_help' 3 | 4 | class BrowsingTest < ActionDispatch::PerformanceTest 5 | # Refer to the documentation for all available options 6 | # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] 7 | # :output => 'tmp/performance', :formats => [:flat] } 8 | 9 | def test_homepage 10 | get '/' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/devise/unlocks/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend unlock instructions

2 | 3 | <%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
<%= f.label :email %>
7 | <%= f.email_field :email %>
8 | 9 |
<%= f.submit "Resend unlock instructions" %>
10 | <% end %> 11 | 12 | <%= render :partial => "devise/shared/links" %> -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Kanshabox::Application.config.session_store :cookie_store, key: '_kanshabox_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Kanshabox::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /app/views/devise/confirmations/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend confirmation instructions

2 | 3 | <%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
<%= f.label :email %>
7 | <%= f.email_field :email %>
8 | 9 |
<%= f.submit "Resend confirmation instructions" %>
10 | <% end %> 11 | 12 | <%= render :partial => "devise/shared/links" %> -------------------------------------------------------------------------------- /app/views/devise/shared/_links.erb: -------------------------------------------------------------------------------- 1 | <%- if controller_name != 'sessions' %> 2 | <%= link_to "登録済みの方はログインへ", new_session_path(resource_name) %>
3 | <% end -%> 4 | 5 | <%- if devise_mapping.registerable? && controller_name != 'registrations' %> 6 | <%= link_to "まだ登録していない方は新規登録へ", new_registration_path(resource_name) %>
7 | <% end -%> 8 | 9 | <%- if devise_mapping.recoverable? && controller_name != 'passwords' %> 10 | <%= link_to "パスワードを忘れた方", new_password_path(resource_name) %>
11 | <% end -%> 12 | 13 | -------------------------------------------------------------------------------- /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|csv) for all tests in alphabetical order. 7 | # 8 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 9 | # -- they do not yet inherit this setting 10 | fixtures :all 11 | 12 | # Add more helper methods to be used by all tests here... 13 | end 14 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Kanshabox::Application.config.secret_token = 'e613294fa5341b58506261627c87d9d19607b005bbbefe1e551cf3f6abca08f7cac144d4dcd503760497012cf44e788e83329a323270d08b471ade7e73c20c8a' 8 | -------------------------------------------------------------------------------- /public/assets/application-2d1f3e4d1da28508d80d84d36a4fa4ca.css: -------------------------------------------------------------------------------- 1 | .homes-index-page .hero-unit{margin-top:5px}dl dt.date{position:relative;padding-left:60px;min-height:50px}dl dt.date h3{font-size:25px}dl dt.date .count{position:absolute;display:block;left:0px;width:50px;height:40px;background:#ff115c;color:#FFF}dl dt.date .count .num{display:block;font-size:18px;padding:5px 10px 0;text-align:center}dl dt.date .count .label{display:block;margin-top:-2px;text-align:center;font-size:11px;font-weight:normal}dl dd.thanks{border-bottom:1px dashed #CCC;margin-bottom:10px} 2 | -------------------------------------------------------------------------------- /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] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /public/assets/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | capture-1.png: capture-1-4ebb65f5c8c19cc19aa0c1047fb4604a.png 3 | capture-2.png: capture-2-828313ace750a6ff45b8035208cb3353.png 4 | rails.png: rails-bd9ad5a560b5a3a7be0808c5cd76a798.png 5 | ICanHaz.min.js: ICanHaz-b4b81e9871b46f7e192a5e1d3182010b.min.js 6 | jquery-ui.min.js: jquery-ui-7e33882a28fc84ad0e0e47e46cbf901c.min.js 7 | jquery.min.js: jquery-8a50feed8d29566738ad005e19fe1c2d.min.js 8 | application.js: application-d93c351b259a97f5602cf0828502bac4.js 9 | application.css: application-1256e2bab720fa68d08bf74acc61842c.css 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into including all the files listed below. 2 | // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically 3 | // be included in the compiled file accessible from http://example.com/assets/application.js 4 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 5 | // the compiled file. 6 | // 7 | //= require jquery 8 | //= require jquery_ujs 9 | //= require underscore 10 | //= require ICanHaz.min 11 | //= require_tree . 12 | -------------------------------------------------------------------------------- /app/views/devise/mailer/reset_password_instructions.html.erb: -------------------------------------------------------------------------------- 1 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2 |  「5Thanks」より、ID・パスワード再発行のお知らせ 3 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  4 | <%= @resource.email %>様 5 | 6 | 「5Thanks」をご利用頂き、誠にありがとうございます。 7 | 8 | 9 | ↓こちらがパスワード再設定用のアドレスです。このURLにアクセスしてください。 10 | 11 | <%= edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %> 12 | 13 | <ご注意> 14 | ・お使いのメールソフトによってはリンクが異常になっている場合があります。 15 |  この場合はURLをブラウザのアドレス欄にコピー&ペーストしてアクセスしてください。 16 | ・一定期間経過してもログインされなかった場合は、この再設定用URLは無効となります。 17 |  その場合はもう一度お申し込み下さい。 18 | 19 | ▼ログインはこちらより行えます。 20 | <%= new_user_session_url %> 21 | 22 | -------------------------------------------------------------------------------- /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 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /public/assets/application-eca11a164e7a94a5e569b5696333d218.css: -------------------------------------------------------------------------------- 1 | .homes-index-page .hero-unit{margin-top:5px}.thanks-index-page p.empty-message{padding:60px 0;font-size:20px;font-weight:bold;line-height:150%}dl dt.date{position:relative;padding-left:60px;min-height:50px}dl dt.date h3{font-size:25px}dl dt.date .count{position:absolute;display:block;left:0px;width:50px;height:40px;background:#ff115c;color:#FFF}dl dt.date .count .num{display:block;font-size:18px;padding:5px 10px 0;text-align:center}dl dt.date .count .label{display:block;margin-top:-2px;text-align:center;font-size:11px;font-weight:normal}dl dd.thanks{border-bottom:1px dashed #CCC;margin-bottom:10px}dl dt.more a.btn{width:550px;text-align:center} 2 | -------------------------------------------------------------------------------- /app/helpers/layout_helper.rb: -------------------------------------------------------------------------------- 1 | # These helper methods can be called in your template to set variables to be used in the layout 2 | # This module should be included in all views globally, 3 | # to do so you may need to add this line to your ApplicationController 4 | # helper :layout 5 | module LayoutHelper 6 | def title(page_title, show_title = true) 7 | content_for(:title) { h(page_title.to_s) } 8 | @show_title = show_title 9 | end 10 | 11 | def show_title? 12 | @show_title 13 | end 14 | 15 | def stylesheet(*args) 16 | content_for(:head) { stylesheet_link_tag(*args) } 17 | end 18 | 19 | def javascript(*args) 20 | content_for(:head) { javascript_include_tag(*args) } 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | # Include default devise modules. Others available are: 3 | # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable 4 | devise :database_authenticatable, :registerable, 5 | :recoverable, :rememberable, :trackable, :validatable 6 | 7 | # Setup accessible (or protected) attributes for your model 8 | attr_accessible :email, :password, :password_confirmation, :remember_me, :username 9 | 10 | has_many :thanks 11 | 12 | validates :username, :uniqueness => { :case_sensitive => false }, 13 | :length => { :in => 3..15 }, 14 | :format => { :with => /^[a-z0-9_]+$/ } 15 | 16 | 17 | end 18 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

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

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /app/views/devise/passwords/new.html.haml: -------------------------------------------------------------------------------- 1 | - title 'パスワードを忘れた方 - 5Thanks' 2 | 3 | .page-header 4 | %h2 パスワードを忘れた方 5 | 6 | .row 7 | .span10 8 | = form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| 9 | -if resource.errors.any? 10 | .alert-message.block-message.error 11 | %h3= "#{resource.errors.count}つのエラーのため保存できませんでした。" 12 | %ul 13 | - resource.errors.full_messages.each do |msg| 14 | %li= msg 15 | 16 | %fieldset 17 | .clearfix 18 | = f.label :email 19 | .input 20 | = f.email_field :email 21 | .actions 22 | = f.submit "パスワードを再登録するためのメールを送る", :class => 'btn primary' 23 | 24 | .span6 25 | = render :partial => "devise/shared/links" 26 | 27 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

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

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |

We've been notified about this issue and we'll take a look at it shortly.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /app/models/thank.rb: -------------------------------------------------------------------------------- 1 | class Thank < ActiveRecord::Base 2 | 3 | belongs_to :user 4 | validates :what, :length => { :in => 1..20 } 5 | validates :message, :length => { :in => 1..140 } 6 | 7 | def self.filter(params) 8 | thanks = self.where('') 9 | if params[:date] 10 | date = Date.parse(params[:date]) 11 | thanks = where(:date_at => (date.beginning_of_day)..(date.end_of_day)) 12 | end 13 | thanks 14 | end 15 | 16 | # def to_json_with_ext 17 | # { 18 | # :id => self.id, 19 | # :date_at => self.date_at, 20 | # :what => self.what, 21 | # :message => self.message, 22 | # :user_id => self.user_id, 23 | # # :total_count => Thank.where(:user_id => self.user_id).count, 24 | # # :date_count 25 | # }.to_json 26 | # end 27 | # alias_method_chain :to_json, :ext 28 | 29 | end 30 | -------------------------------------------------------------------------------- /app/views/devise/sessions/new.html.haml: -------------------------------------------------------------------------------- 1 | - title '5Thanksへログイン' 2 | .page-header 3 | %h2 5Thanksへログイン 4 | 5 | .row 6 | .span10 7 | = form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| 8 | 9 | %fieldset 10 | .clearfix 11 | = f.label :email, 'メールアドレス' 12 | .input 13 | = f.text_field :email 14 | .clearfix 15 | = f.label :password, 'パスワード' 16 | .input 17 | = f.password_field :password 18 | - if devise_mapping.rememberable? 19 | %ul.inputs-list 20 | %li 21 | %label 22 | = f.check_box :remember_me 23 | %span パスワードを覚えておく 24 | .actions 25 | = f.submit "ログイン", :class => 'btn primary' 26 | .span6 27 | = render :partial => "devise/shared/links" 28 | -------------------------------------------------------------------------------- /public/assets/application-1256e2bab720fa68d08bf74acc61842c.css: -------------------------------------------------------------------------------- 1 | .footer{margin-top:25px;padding:10px;border-top:1px solid #CCC}.homes-index-page .hero-unit{margin-top:5px}.thanks-index-page p.empty-message{padding:60px 0;font-size:20px;font-weight:bold;line-height:150%}dl dt.date{position:relative;padding-left:60px;min-height:50px}dl dt.date time{display:block;font-size:30px;line-height:30px;padding:4px}dl dt.date .count{position:absolute;display:block;left:0px;width:50px;height:40px;background:#ff115c;color:#FFF}dl dt.date .count .num{display:block;font-size:18px;padding:5px 10px 0;text-align:center}dl dt.date .count .label{display:block;margin-top:-2px;text-align:center;font-size:11px;font-weight:normal}dl dd.thanks{border-bottom:1px dashed #CCC;margin-bottom:10px}dl dd.thanks ol li{margin-bottom:10px}dl dd.thanks ol li:hover{background:#EEE}dl dd.thanks ol li b{font-size:15px}dl dd.thanks ol li p.message{font-size:13px} 2 | -------------------------------------------------------------------------------- /config/locales/translation_ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | activerecord: 3 | models: 4 | user: "ユーザー" #g 5 | thank: "ありがとうございます" #g 6 | 7 | attributes: 8 | user: 9 | email: "メール" #g 10 | encrypted_password: "暗号化されたパスワード" #g 11 | reset_password_token: "パスワードリセットトークン" #g 12 | reset_password_sent_at: "で送信されたパスワードをリセットする" #g 13 | remember_created_at: "で作成した覚えている" #g 14 | current_sign_in_at: "での現在の記号" #g 15 | last_sign_in_at: "での最後の記号" #g 16 | current_sign_in_ip: "IPの現在の記号" #g 17 | last_sign_in_ip: "IPの最後の記号" #g 18 | username: "ユーザー名" #g 19 | thanks: "感謝" #g 20 | password: "パスワード" 21 | password_confirmation: "パスワード確認" 22 | current_password: "現在のパスワード" 23 | 24 | thank: 25 | what: "誰 or 何に?" #g 26 | message: "メッセージ" #g 27 | date_at: "日付" #g 28 | user: "ユーザー" #g 29 | -------------------------------------------------------------------------------- /app/views/thanks/_form.html.haml: -------------------------------------------------------------------------------- 1 | = form_for @thank do |f| 2 | -if @thank.errors.any? 3 | .alert-message.block-message.error 4 | %h3= "#{pluralize(@thank.errors.count, "つのエラー")}のため保存できませんでした。" 5 | %ul 6 | - @thank.errors.full_messages.each do |msg| 7 | %li= msg 8 | 9 | .fieldset 10 | .clearfix 11 | %label 誰 or 何に? 12 | .input 13 | = f.text_field :what 14 | へ 15 | .help-block 例:両親、子ども、先生、友人、お天気、音楽 etc 16 | .clearfix 17 | %label 感謝の言葉 18 | .input 19 | = f.text_area :message, :size => '70x2', :class => 'xxlarge' 20 | .help-block 21 | 自分の人生でありがたいと思うことはなんですか? 22 | %br 23 | 書きながら思い浮かべてみよう。 24 | .clearfix(style='display:none;') 25 | %label いつの感謝? 26 | .input 27 | = f.date_select :date_at 28 | .clearfix 29 | .input 30 | = f.submit '感謝をメモする', :class => 'btn primary' 31 | -------------------------------------------------------------------------------- /db/migrate/20110907082955_devise_create_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateUsers < ActiveRecord::Migration 2 | def self.up 3 | create_table(:users) do |t| 4 | t.database_authenticatable :null => false 5 | t.recoverable 6 | t.rememberable 7 | t.trackable 8 | 9 | # t.encryptable 10 | # t.confirmable 11 | # t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both 12 | # t.token_authenticatable 13 | 14 | t.string :username 15 | 16 | t.timestamps 17 | end 18 | 19 | add_index :users, :email, :unique => true 20 | add_index :users, :reset_password_token, :unique => true 21 | # add_index :users, :confirmation_token, :unique => true 22 | # add_index :users, :unlock_token, :unique => true 23 | # add_index :users, :authentication_token, :unique => true 24 | end 25 | 26 | def self.down 27 | drop_table :users 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'rails', '3.1.0' 4 | 5 | # Bundle edge Rails instead: 6 | # gem 'rails', :git => 'git://github.com/rails/rails.git' 7 | 8 | gem 'sqlite3' 9 | # for heroku 10 | group :production do 11 | gem 'pg' 12 | gem 'therubyracer-heroku' 13 | end 14 | 15 | # Gems used only for assets and not required 16 | # in production environments by default. 17 | group :assets do 18 | gem 'sass-rails', " ~> 3.1.0" 19 | gem 'coffee-rails', "~> 3.1.0" 20 | gem 'uglifier' 21 | end 22 | 23 | gem 'devise' 24 | gem 'haml-rails' 25 | gem 'kaminari' 26 | gem 'jquery-rails' 27 | gem 'i18n_generators' 28 | gem 'nifty-generators' 29 | 30 | # Use unicorn as the web server 31 | # gem 'unicorn' 32 | 33 | # Deploy with Capistrano 34 | # gem 'capistrano' 35 | 36 | # To use debugger 37 | # gem 'ruby-debug19', :require => 'ruby-debug' 38 | 39 | group :test do 40 | # Pretty printed test output 41 | gem 'turn', :require => false 42 | end 43 | -------------------------------------------------------------------------------- /app/views/devise/passwords/edit.html.haml: -------------------------------------------------------------------------------- 1 | - title 'パスワードを変更する - 5Thanks' 2 | 3 | .page-header 4 | %h2 パスワードを変更する 5 | 6 | .row 7 | .span10 8 | = form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| 9 | -if resource.errors.any? 10 | .alert-message.block-message.error 11 | %h3= "#{resource.errors.count}つのエラーのため保存できませんでした。" 12 | %ul 13 | - resource.errors.full_messages.each do |msg| 14 | %li= msg 15 | = f.hidden_field :reset_password_token 16 | 17 | %fieldset 18 | .clearfix 19 | = f.label :password, 'パスワード' 20 | .input 21 | = f.password_field :password 22 | .clearfix 23 | = f.label :password_confirmation, 'パスワード確認' 24 | .input 25 | = f.password_field :password_confirmation 26 | .actions 27 | = f.submit "パスワードを変更", :class => 'btn primary' 28 | 29 | .span6 30 | = render :partial => "devise/shared/links" 31 | 32 | -------------------------------------------------------------------------------- /app/helpers/error_messages_helper.rb: -------------------------------------------------------------------------------- 1 | module ErrorMessagesHelper 2 | # Render error messages for the given objects. The :message and :header_message options are allowed. 3 | def error_messages_for(*objects) 4 | options = objects.extract_options! 5 | options[:header_message] ||= I18n.t(:"activerecord.errors.header", :default => "Invalid Fields") 6 | options[:message] ||= I18n.t(:"activerecord.errors.message", :default => "Correct the following errors and try again.") 7 | messages = objects.compact.map { |o| o.errors.full_messages }.flatten 8 | unless messages.empty? 9 | content_tag(:div, :class => "error_messages") do 10 | list_items = messages.map { |msg| content_tag(:li, msg) } 11 | content_tag(:h2, options[:header_message]) + content_tag(:p, options[:message]) + content_tag(:ul, list_items.join.html_safe) 12 | end 13 | end 14 | end 15 | 16 | module FormBuilderAdditions 17 | def error_messages(options = {}) 18 | @template.error_messages_for(@object, options) 19 | end 20 | end 21 | end 22 | 23 | ActionView::Helpers::FormBuilder.send(:include, ErrorMessagesHelper::FormBuilderAdditions) 24 | -------------------------------------------------------------------------------- /app/views/devise/registrations/new.html.haml: -------------------------------------------------------------------------------- 1 | - title '5Thanksへ新規登録する' 2 | .page-header 3 | %h2 5Thanksへ新規登録する 4 | 5 | .row 6 | .span10 7 | = form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| 8 | -if resource.errors.any? 9 | .alert-message.block-message.error 10 | %h3= "#{resource.errors.count}つのエラーのため保存できませんでした。" 11 | %ul 12 | - resource.errors.full_messages.each do |msg| 13 | %li= msg 14 | 15 | %fieldset 16 | .clearfix 17 | = f.label :email, 'メールアドレス' 18 | .input 19 | = f.text_field :email 20 | .clearfix 21 | = f.label :username, 'ユーザー名' 22 | .input 23 | = f.text_field :username 24 | %span.help-inline 半角英数字3文字〜15文字まで。 25 | .clearfix 26 | = f.label :password, 'パスワード' 27 | .input 28 | = f.password_field :password 29 | .clearfix 30 | = f.label :password_confirmation, 'パスワード確認' 31 | .input 32 | = f.password_field :password_confirmation 33 | .actions 34 | = f.submit "登録", :class => 'btn primary' 35 | .span6 36 | = render :partial => "devise/shared/links" 37 | -------------------------------------------------------------------------------- /test/functional/thanks_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ThanksControllerTest < ActionController::TestCase 4 | setup do 5 | @thank = thanks(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:thanks) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create thank" do 20 | assert_difference('Thank.count') do 21 | post :create, thank: @thank.attributes 22 | end 23 | 24 | assert_redirected_to thank_path(assigns(:thank)) 25 | end 26 | 27 | test "should show thank" do 28 | get :show, id: @thank.to_param 29 | assert_response :success 30 | end 31 | 32 | test "should get edit" do 33 | get :edit, id: @thank.to_param 34 | assert_response :success 35 | end 36 | 37 | test "should update thank" do 38 | put :update, id: @thank.to_param, thank: @thank.attributes 39 | assert_redirected_to thank_path(assigns(:thank)) 40 | end 41 | 42 | test "should destroy thank" do 43 | assert_difference('Thank.count', -1) do 44 | delete :destroy, id: @thank.to_param 45 | end 46 | 47 | assert_redirected_to thanks_path 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /app/assets/stylesheets/thanks.css.scss: -------------------------------------------------------------------------------- 1 | .thanks-index-page { 2 | p.empty-message { 3 | padding: 60px 0; 4 | font-size: 20px; 5 | font-weight: bold; 6 | line-height: 150%; 7 | } 8 | } 9 | 10 | dl { 11 | dt.date { 12 | position: relative; 13 | padding-left: 60px; 14 | min-height: 50px; 15 | time { 16 | display: block; 17 | font-size: 30px; 18 | line-height: 30px; 19 | padding: 4px; 20 | } 21 | .count { 22 | position: absolute; 23 | display: block; 24 | left: 0px; 25 | width: 50px; 26 | height: 40px; 27 | background: #ff115c; 28 | color: #FFF; 29 | .num { 30 | display: block; 31 | font-size: 18px; 32 | padding: 5px 10px 0; 33 | text-align: center; 34 | } 35 | .label { 36 | display: block; 37 | margin-top: -2px; 38 | text-align: center; 39 | font-size: 11px; 40 | font-weight: normal; 41 | } 42 | } 43 | } 44 | dd.thanks { 45 | border-bottom: 1px dashed #CCC; 46 | margin-bottom: 10px; 47 | ol { 48 | li { 49 | margin-bottom: 10px; 50 | &:hover { background: #EEE; } 51 | b { font-size: 15px;} 52 | p.message { font-size: 13px; } 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Kanshabox::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 | # 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_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 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Do not compress assets 26 | config.assets.compress = false 27 | 28 | # Expands the lines which load the assets 29 | config.assets.debug = true 30 | 31 | config.action_mailer.default_url_options = { 32 | :host => 'localhost:3000' 33 | } 34 | end 35 | -------------------------------------------------------------------------------- /app/views/devise/registrations/edit.html.haml: -------------------------------------------------------------------------------- 1 | - title '設定 - 5Thanks' 2 | .page-header 3 | %h2 設定 4 | 5 | .row 6 | .span10 7 | = form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| 8 | -if resource.errors.any? 9 | .alert-message.block-message.error 10 | %h3= "#{resource.errors.count}つのエラーのため保存できませんでした。" 11 | %ul 12 | - resource.errors.full_messages.each do |msg| 13 | %li= msg 14 | %fieldset 15 | .clearfix 16 | = f.label :email 17 | .input 18 | = f.email_field :email 19 | .clearfix 20 | = f.label :username 21 | .input 22 | = f.text_field :username 23 | .clearfix 24 | = f.label :password 25 | .input 26 | = f.password_field :password 27 | .clearfix 28 | = f.label :password_confirmation 29 | .input 30 | = f.password_field :password_confirmation 31 | .clearfix 32 | = f.label :current_password 33 | .input 34 | = f.password_field :current_password 35 | .help-block 設定を変更するためには現在のパスワードが必要です。 36 | .actions 37 | = f.submit "更新する", :class => 'btn primary' 38 | 39 | .span6 40 | %h3 退会 41 | %p 42 | = link_to "このアカウントを削除する", registration_path(resource_name), :confirm => "お気に召さずにごめんなさい。\n退会するとあなたの#{current_user.thanks.count}つの感謝がシステム上から消えてしまいます。\nでもあなたの心に残っているのでよろしいですよね?", :method => :delete 43 | 44 | -------------------------------------------------------------------------------- /app/assets/javascripts/thanks.js.coffee: -------------------------------------------------------------------------------- 1 | $ -> 2 | if $('.thanks-new-page').is(':visible') 3 | 4 | # 入力フォーム監視 5 | observeInputs = (e)-> 6 | values = $('#thank_what,#thank_message').map (index,node)-> $(node).val() 7 | if _.all(values, (value)-> value != '') 8 | $('input[name=commit]').removeAttr('disabled') 9 | else 10 | $('input[name=commit]').attr('disabled','disabled') 11 | observeInputs() 12 | $('#thank_what,#thank_message') 13 | .bind('keyup', observeInputs) 14 | .bind('change', observeInputs) 15 | 16 | 17 | if $('.thanks-index-page').is(':visible') 18 | 19 | $('.thanks li') 20 | .bind('mouseover', (e)-> 21 | $(this).find('.destroy').show() 22 | ) 23 | .bind('mouseout', (e)-> 24 | $(this).find('.destroy').hide() 25 | ) 26 | 27 | updateSystemMessage = (thanksNode)-> 28 | count = $(thanksNode).find('li:visible').size() 29 | $(thanksNode).find('.system-message p').hide() 30 | if count == 0 31 | $(thanksNode).find('.empty-thanks-message').show() 32 | else if count >= 5 33 | $(thanksNode).find('.full-thanks-message').show() 34 | else 35 | $(thanksNode).find('.notyet-thanks-message').show() 36 | $(thanksNode).find('.notyet-thanks-message .num').text(5 - count) 37 | 38 | $('dd.thanks').each((i,node)->updateSystemMessage($(node))) 39 | 40 | # Thank 削除 41 | $('.btn-destroy') 42 | .bind('ajax:success',(e,res,status)-> 43 | console.log(res) 44 | if status == 'success' 45 | thank = $(this).parents('li') 46 | thank.fadeOut(1000, ()-> 47 | date = thank.parents('dd').data('date') 48 | count = $("dd[data-date=#{date}] li:visible").size() 49 | $("dt[data-date=#{date}]").find('.num').text(count) 50 | updateSystemMessage($("dd[data-date=#{date}]")) 51 | ) 52 | ) 53 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Kanshabox::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 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Use SQL instead of Active Record's schema dumper when creating the test database. 33 | # This is necessary if your schema can't be completely dumped by the schema dumper, 34 | # like if you have constraints or database-specific column types 35 | # config.active_record.schema_format = :sql 36 | 37 | # Print deprecation notices to the stderr 38 | config.active_support.deprecation = :stderr 39 | 40 | # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets 41 | config.assets.allow_debugging = true 42 | end 43 | -------------------------------------------------------------------------------- /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 to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20110907082955) do 15 | 16 | create_table "thanks", :force => true do |t| 17 | t.integer "user_id" 18 | t.string "what" 19 | t.string "message" 20 | t.datetime "date_at" 21 | t.datetime "created_at" 22 | t.datetime "updated_at" 23 | end 24 | 25 | create_table "users", :force => true do |t| 26 | t.string "email", :default => "", :null => false 27 | t.string "encrypted_password", :limit => 128, :default => "", :null => false 28 | t.string "reset_password_token" 29 | t.datetime "reset_password_sent_at" 30 | t.datetime "remember_created_at" 31 | t.integer "sign_in_count", :default => 0 32 | t.datetime "current_sign_in_at" 33 | t.datetime "last_sign_in_at" 34 | t.string "current_sign_in_ip" 35 | t.string "last_sign_in_ip" 36 | t.string "username" 37 | t.datetime "created_at" 38 | t.datetime "updated_at" 39 | end 40 | 41 | add_index "users", ["email"], :name => "index_users_on_email", :unique => true 42 | add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true 43 | 44 | end 45 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | if defined?(Bundler) 6 | # If you precompile assets before deploying to production, use this line 7 | Bundler.require *Rails.groups(:assets => %w(development test)) 8 | # If you want your assets lazily compiled in production, use this line 9 | # Bundler.require(:default, :assets, Rails.env) 10 | end 11 | 12 | module Kanshabox 13 | class Application < Rails::Application 14 | # Settings in config/environments/* take precedence over those specified here. 15 | # Application configuration should go into files in config/initializers 16 | # -- all .rb files in that directory are automatically loaded. 17 | 18 | # Custom directories with classes and modules you want to be autoloadable. 19 | # config.autoload_paths += %W(#{config.root}/extras) 20 | 21 | # Only load the plugins named here, in the order given (default is alphabetical). 22 | # :all can be used as a placeholder for all plugins not explicitly named. 23 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 24 | 25 | # Activate observers that should always be running. 26 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 27 | 28 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 29 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 30 | config.time_zone = 'Tokyo' 31 | 32 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 33 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 34 | config.i18n.default_locale = :ja 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 | 42 | # Enable the asset pipeline 43 | config.assets.enabled = true 44 | 45 | # Version of your assets, change this if you want to expire all your assets 46 | config.assets.version = '1.0' 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %title 5 | = yield(:title) || "5Thanks" 6 | %meta{"http-equiv"=>"Content-Type", :content=>"text/html; charset=utf-8"}/ 7 | = stylesheet_link_tag 'http://twitter.github.com/bootstrap/assets/css/bootstrap-1.2.0.min.css' 8 | = stylesheet_link_tag "application" 9 | = javascript_include_tag "application" 10 | = csrf_meta_tag 11 | = yield(:head) 12 | - if Rails.env.production? 13 | :javascript 14 | var _gaq = _gaq || []; 15 | _gaq.push(['_setAccount', 'UA-845066-11']); 16 | _gaq.push(['_trackPageview']); 17 | 18 | (function() { 19 | var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; 20 | ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 21 | var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); 22 | })(); 23 | %body(class='#{controller_name}-#{action_name}-page') 24 | 25 | .topbar 26 | .fill 27 | .container 28 | %h3 29 | %a(href='/') 30 | 5Thanks 31 | - if user_signed_in? 32 | %ul 33 | %li= link_to 'あなたの感謝', thanks_path 34 | %li= link_to '新しい感謝', new_thank_path 35 | %ul.nav.secondary-nav 36 | %li= link_to '設定', edit_user_registration_path 37 | %li= link_to 'ログアウト', destroy_user_session_path, :method => :delete 38 | - else 39 | %ul.nav.secondary-nav 40 | %li= link_to '新規登録', new_user_registration_path 41 | %li= link_to 'ログイン', new_user_session_path 42 | 43 | .container(style='margin-top: 40px; padding-top: 10px') 44 | - flash.each do |name, msg| 45 | .alert-message.small(class='#{name}')= msg 46 | 47 | .container 48 | .pageContent 49 | = yield 50 | 51 | .container.footer 52 | Powered by Heroku, Rails3.1, Twitter Bootstrap 53 | Create by @func09. Github 54 | 55 | :javascript 56 | if($('.alert-message.small').is(':visible')){ 57 | setTimeout(function(){ 58 | $('.alert-message.small').fadeOut() 59 | }, 3000); 60 | } 61 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Kanshabox::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 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to Rails.root.join("public/assets") 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Use a different logger for distributed setups 37 | # config.logger = SyslogLogger.new 38 | 39 | # Use a different cache store in production 40 | # config.cache_store = :mem_cache_store 41 | 42 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 43 | # config.action_controller.asset_host = "http://assets.example.com" 44 | 45 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 46 | # config.assets.precompile += %w( search.js ) 47 | 48 | # Disable delivery errors, bad email addresses will be ignored 49 | # config.action_mailer.raise_delivery_errors = false 50 | 51 | # Enable threaded mode 52 | # config.threadsafe! 53 | 54 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 55 | # the I18n.default_locale when a translation can not be found) 56 | config.i18n.fallbacks = true 57 | 58 | # Send deprecation notices to registered listeners 59 | config.active_support.deprecation = :notify 60 | 61 | config.action_mailer.default_url_options = { 62 | :host => 'fivethanks.heroku.com' 63 | } 64 | 65 | ActionMailer::Base.smtp_settings = { 66 | :address => "smtp.sendgrid.net", 67 | :port => "25", 68 | :authentication => :plain, 69 | :user_name => ENV['SENDGRID_USERNAME'], 70 | :password => ENV['SENDGRID_PASSWORD'], 71 | :domain => ENV['SENDGRID_DOMAIN'] 72 | } 73 | 74 | end 75 | -------------------------------------------------------------------------------- /app/views/homes/index.html.haml: -------------------------------------------------------------------------------- 1 | - title '5Thanks - 感謝できることを毎日5つメモするツール' 2 | .hero-unit 3 | %h1 Welcome, 5Thanks 4 | %p 5 | 5Thanksは、毎日5つの感謝できることをメモして、ポジティブに生きたい人のためのツールです。 6 | .row 7 | .span9 8 | 9 | %h2 5Thanksについて 10 | %p 11 | 書籍「ハーバードの人生を変える授業」の中にある 12 | %blockquote 13 | ちょっとした事でもいいので、毎日感謝できることを5つ書く 14 | %p 15 | を実践するためのツールです。「ハーバードの人生を変える授業」によれば、これを続けた人は人生を肯定的に評価できるようになり、幸福感が高くなり、ポジティブな気分を味わうようになったそうです。 16 | 17 | %h3 サービスの特徴 18 | %ol 19 | %li 20 | %b 簡単なメモ登録 21 | %p 22 | 誰、何に対して、どんな感謝をしたのか書くだけのシンプルなツールです。 23 | %br 24 | = image_tag 'capture-2.png' 25 | %li 26 | %b 振り返りやすい 27 | %p 28 | メモは日毎に整理されて、過去のメモを読み返しやすいです。 29 | = image_tag 'capture-1.png' 30 | %li 31 | %b プライベートなメモ 32 | %p 33 | 感謝のメモは他の人から見られることはありません。 34 | 35 | .span7 36 | %h3 お知らせ 37 | %p 38 | %b 2011-09-12 39 | %br 「クリック募金dff」のバナーを表示するようにしました。何か良い事したいなと思った時にクリックしてみてください。 40 | %p 41 | %b 2011-09-08 42 | %br 5Thanksリリースしました! 43 | 44 | %hr 45 | %p これまで#{Thank.count}の感謝がメモされました 46 | %p #{User.count}人が5Thanksを利用しています。 47 | %p 48 | = link_to 'ユーザー登録して感謝の気持ちをメモし始める', new_user_registration_path, :class => 'btn primary xlarge' 49 | 50 | .share 51 | このエントリーをはてなブックマークに追加 52 | ツイート 53 | 54 | -------------------------------------------------------------------------------- /app/controllers/thanks_controller.rb: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | class ThanksController < ApplicationController 3 | before_filter :authenticate_user! 4 | # GET /thanks 5 | # GET /thanks.json 6 | def index 7 | if params[:m] 8 | @month = Date.parse(params[:m].concat('-01')).beginning_of_month if params[:m] 9 | else 10 | @month = Date.today.beginning_of_month 11 | end 12 | # メモした月リストを作成 13 | @months = current_user.thanks.group(:date_at).count 14 | .keys.group_by{|key,value| key.strftime('%Y-%m') }.keys.map{|d| Date.parse("#{d}-01") }.sort.reverse 15 | @thanks = current_user.thanks 16 | .where(:date_at => (@month.beginning_of_month)..(@month.end_of_month)) 17 | .order('date_at DESC') 18 | .group_by{|t| t.date_at} 19 | 20 | respond_to do |format| 21 | format.html # index.html.erb 22 | end 23 | end 24 | 25 | # GET /thanks/1 26 | # GET /thanks/1.json 27 | def show 28 | @thank = Thank.find(params[:id]) 29 | 30 | respond_to do |format| 31 | format.html # show.html.erb 32 | format.json { render json: @thank } 33 | end 34 | end 35 | 36 | # GET /thanks/new 37 | # GET /thanks/new.json 38 | def new 39 | date = Date.today 40 | if params[:date] 41 | date = DateTime.parse(params[:date]) 42 | end 43 | 44 | @thank = Thank.new :date_at => date 45 | 46 | respond_to do |format| 47 | format.html # new.html.erb 48 | format.json { render json: @thank } 49 | end 50 | end 51 | 52 | # GET /thanks/1/edit 53 | def edit 54 | @thank = Thank.find(params[:id]) 55 | end 56 | 57 | # POST /thanks 58 | # POST /thanks.json 59 | def create 60 | @thank = current_user.thanks.build(params[:thank]) 61 | 62 | respond_to do |format| 63 | if @thank.save 64 | format.html { redirect_to thanks_path, notice: '感謝の気持ちが増えました!' } 65 | format.json { render json: @thank, status: :created, location: @thank } 66 | else 67 | format.html { render action: "new" } 68 | format.json { render json: @thank.errors, status: :unprocessable_entity } 69 | end 70 | end 71 | end 72 | 73 | # PUT /thanks/1 74 | # PUT /thanks/1.json 75 | def update 76 | @thank = Thank.find(params[:id]) 77 | 78 | respond_to do |format| 79 | if @thank.update_attributes(params[:thank]) 80 | format.html { redirect_to @thank, notice: 'Thank was successfully updated.' } 81 | format.json { head :ok } 82 | else 83 | format.html { render action: "edit" } 84 | format.json { render json: @thank.errors, status: :unprocessable_entity } 85 | end 86 | end 87 | end 88 | 89 | # DELETE /thanks/1 90 | # DELETE /thanks/1.json 91 | def destroy 92 | @thank = Thank.find(params[:id]) 93 | @thank.destroy 94 | 95 | respond_to do |format| 96 | format.html { redirect_to thanks_url } 97 | format.json { render json: @thank, status: :created } 98 | end 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /config/locales/devise.en.yml: -------------------------------------------------------------------------------- 1 | # Additional translations at http://github.com/plataformatec/devise/wiki/I18n 2 | 3 | en: 4 | errors: 5 | messages: 6 | expired: "has expired, please request a new one" 7 | not_found: "not found" 8 | already_confirmed: "was already confirmed, please try signing in" 9 | not_locked: "was not locked" 10 | not_saved: 11 | one: "1 error prohibited this %{resource} from being saved:" 12 | other: "%{count} errors prohibited this %{resource} from being saved:" 13 | 14 | devise: 15 | failure: 16 | already_authenticated: 'You are already signed in.' 17 | unauthenticated: 'You need to sign in or sign up before continuing.' 18 | unconfirmed: 'You have to confirm your account before continuing.' 19 | locked: 'Your account is locked.' 20 | invalid: 'Invalid email or password.' 21 | invalid_token: 'Invalid authentication token.' 22 | timeout: 'Your session expired, please sign in again to continue.' 23 | inactive: 'Your account was not activated yet.' 24 | sessions: 25 | signed_in: 'Signed in successfully.' 26 | signed_out: 'Signed out successfully.' 27 | passwords: 28 | send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.' 29 | updated: 'Your password was changed successfully. You are now signed in.' 30 | send_paranoid_instructions: "If your e-mail exists on our database, you will receive a password recovery link on your e-mail" 31 | confirmations: 32 | send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.' 33 | send_paranoid_instructions: 'If your e-mail exists on our database, you will receive an email with instructions about how to confirm your account in a few minutes.' 34 | confirmed: 'Your account was successfully confirmed. You are now signed in.' 35 | registrations: 36 | signed_up: 'Welcome! You have signed up successfully.' 37 | inactive_signed_up: 'You have signed up successfully. However, we could not sign you in because your account is %{reason}.' 38 | updated: 'You updated your account successfully.' 39 | destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.' 40 | reasons: 41 | inactive: 'inactive' 42 | unconfirmed: 'unconfirmed' 43 | locked: 'locked' 44 | unlocks: 45 | send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.' 46 | unlocked: 'Your account was successfully unlocked. You are now signed in.' 47 | send_paranoid_instructions: 'If your account exists, you will receive an email with instructions about how to unlock it in a few minutes.' 48 | omniauth_callbacks: 49 | success: 'Successfully authorized from %{kind} account.' 50 | failure: 'Could not authorize you from %{kind} because "%{reason}".' 51 | mailer: 52 | confirmation_instructions: 53 | subject: 'Confirmation instructions' 54 | reset_password_instructions: 55 | subject: 'Reset password instructions' 56 | unlock_instructions: 57 | subject: 'Unlock Instructions' 58 | -------------------------------------------------------------------------------- /app/views/thanks/index.html.haml: -------------------------------------------------------------------------------- 1 | - if @month.this_month? 2 | - title "今月のあなたの感謝の言葉 - 5Thanks" 3 | - else 4 | - title "#{@month.strftime("%Y年%m月")}のあなたの感謝の言葉 - 5Thanks" 5 | 6 | .page-header 7 | %h1 8 | - if @month.this_month? 9 | 今月のあなたの感謝の言葉 10 | - else 11 | #{@month.strftime("%Y年%m月")}のあなたの感謝の言葉 12 | %p 13 | - unless current_user.thanks.count == 0 14 | あなたは今日までに#{current_user.thanks.count}個の感謝メモを残しました 15 | 16 | .row 17 | .span10 18 | - unless @thanks.count > 0 19 | %p.empty-message 20 | - if @month.end_of_month.future? 21 | 今月はまだ感謝メモをつけていません。 22 | %br 23 | = link_to "さぁ、感謝できることをメモしましょう!", new_thank_path 24 | - else 25 | この月は感謝メモがありませんでした 26 | - else 27 | %dl 28 | - if @month.this_month? and not @thanks.keys.first.today? 29 | - @thanks[Date.today] = [] 30 | - for date in @thanks.keys.sort.reverse 31 | - thanks = @thanks[date] 32 | %dt.date(data-date='#{date.strftime("%Y-%m-%d")}') 33 | %span.count 34 | %span.num= thanks.count 35 | %span.label thx 36 | - if date.today? 37 | - label_when = "今日" 38 | %time(datetime='') 今日 39 | - else 40 | - label_when = "この日" 41 | %time(datetime='#{date.strftime("%Y-%m-%d")}')= date.strftime("%Y/%m/%d") 42 | %dd.thanks(data-date='#{date.strftime("%Y-%m-%d")}') 43 | %ol 44 | - for thank in thanks 45 | %li(data-thank-id='#{thank.id}') 46 | %b= "#{thank.what}へ" 47 | %span.destroy(style='display:none;') 48 | = link_to 'x', thank_path(thank,:format => :json), :remote => true, :class => 'btn-destroy', :method => :delete 49 | %br 50 | %p.message= thank.message 51 | .system-message 52 | - if date.today? 53 | %p.empty-thanks-message(style='display:none;') 54 | 今日はまだ感謝をメモしてないよ。 55 | = link_to "ちょっとした事でいいんだよ", new_thank_path 56 | %p.full-thanks-message(style='display:none;') 57 | 今日もいっぱい良いことがあったね! 58 | = link_to "もっと感謝したことはある?", new_thank_path 59 | %p.notyet-thanks-message(style='display:none;') 60 | 今日はあと#{5-thanks.size}個の感謝をメモろう。 61 | = link_to "あとちょっと!", new_thank_path 62 | - else 63 | %p.full-thanks-message(style='display:none;') 64 | いっぱい良いことがあったね! 65 | = link_to "もっと感謝したいことはある?", new_thank_path(:date => date.strftime("%Y%m%d")) 66 | %p.notyet-thanks-message(style='display:none;') 67 | もう少し感謝のメモを書こう。 68 | = link_to "思い出してみて!", new_thank_path(:date => date.strftime("%Y%m%d")) 69 | .span6 70 | %p 71 | クリックで救える命がある。 72 | %ul 73 | - for date in @months 74 | %li 75 | = link_to date.strftime('%Y年%m月'), thanks_path(:m => date.strftime('%Y-%m')) 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /config/locales/devise.ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | errors: 3 | messages: 4 | not_found: "は見つかりませんでした" 5 | # not_found: "not found" 6 | already_confirmed: "は既に登録済みです" 7 | # already_confirmed: "was already confirmed" 8 | not_locked: "は凍結されていません" 9 | # not_locked: "was not locked" 10 | not_saved: 11 | one: "1つのエラーがありました。" 12 | other: "%{count}つのエラーがありました。" 13 | 14 | devise: 15 | omniauth_callbacks: 16 | # success: 'Successfully authorized from %{kind} account.' 17 | success: '%{kind} アカウントの認証に成功しました' 18 | # failure: 'Could not authorize you from %{kind} because "%{reason}".' 19 | failure: '%{kind} からの認証に失敗しました。 理由: "%{reason}".' 20 | failure: 21 | already_authenticated: 'すでにログインしています。' 22 | # already_authenticated: 'You are already signed in.' 23 | unauthenticated: 'ログインしてください。' 24 | # unauthenticated: 'You need to sign in or sign up before continuing.' 25 | unconfirmed: '本登録を行ってください。' 26 | # unconfirmed: 'You have to confirm your account before continuing.' 27 | locked: 'あなたのアカウントは凍結されています。' 28 | # locked: 'Your account is locked.' 29 | invalid: 'メールアドレスかパスワードが違います。' 30 | # invalid: 'Invalid email or password.' 31 | invalid_token: '認証キーが不正です。' 32 | # invalid_token: 'Invalid authentication token.' 33 | timeout: 'セッションがタイムアウトしました。もう一度ログインしてください。' 34 | # timeout: 'Your session expired, please sign in again to continue.' 35 | inactive: 'アカウントがアクティベートされていません。' 36 | # inactive: 'Your account was not activated yet.' 37 | sessions: 38 | signed_in: 'ログインしました。' 39 | # signed_in: 'Signed in successfully.' 40 | signed_out: 'ログアウトしました。' 41 | # signed_out: 'Signed out successfully.' 42 | passwords: 43 | send_instructions: 'パスワードのリセット方法を数分以内にメールでご連絡します。' 44 | # send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.' 45 | updated: 'パスワードを変更しました。' 46 | # updated: 'Your password was changed successfully. You are now signed in.' 47 | confirmations: 48 | send_instructions: '登録方法を数分以内にメールでご連絡します。' 49 | # send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.' 50 | confirmed: 'アカウントを登録しました。' 51 | # confirmed: 'Your account was successfully confirmed. You are now signed in.' 52 | registrations: 53 | signed_up: 'アカウント登録を受け付けました。確認のメールをお送りします。' 54 | # signed_up: 'You have signed up successfully. If enabled, a confirmation was sent to your e-mail.' 55 | updated: 'アカウントを更新しました。' 56 | # updated: 'You updated your account successfully.' 57 | destroyed: 'アカウントを削除しました。またのご利用をお待ちしております。' 58 | # destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.' 59 | inactive_signed_up: '新規登録に成功しました。 しかしアカウントにログインしていません。理由: %{reason}.' 60 | # inactive_signed_up: 'You have signed up successfully. However, we could not sign you in because your account is %{reason}.' 61 | unlocks: 62 | send_instructions: 'アカウントの凍結解除方法を数分以内にメールでご連絡します。' 63 | # send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.' 64 | unlocked: 'アカウントを凍結解除しました。' 65 | # unlocked: 'Your account was successfully unlocked. You are now signed in.' 66 | mailer: 67 | confirmation_instructions: 68 | subject: 'アカウントの登録方法' 69 | # subject: 'Confirmation instructions' 70 | reset_password_instructions: 71 | subject: 'パスワードの再設定' 72 | # subject: 'Reset password instructions' 73 | unlock_instructions: 74 | subject: 'アカウントの凍結解除' 75 | # subject: 'Unlock Instructions' 76 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | actionmailer (3.1.0) 5 | actionpack (= 3.1.0) 6 | mail (~> 2.3.0) 7 | actionpack (3.1.0) 8 | activemodel (= 3.1.0) 9 | activesupport (= 3.1.0) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | i18n (~> 0.6) 13 | rack (~> 1.3.2) 14 | rack-cache (~> 1.0.3) 15 | rack-mount (~> 0.8.2) 16 | rack-test (~> 0.6.1) 17 | sprockets (~> 2.0.0) 18 | activemodel (3.1.0) 19 | activesupport (= 3.1.0) 20 | bcrypt-ruby (~> 3.0.0) 21 | builder (~> 3.0.0) 22 | i18n (~> 0.6) 23 | activerecord (3.1.0) 24 | activemodel (= 3.1.0) 25 | activesupport (= 3.1.0) 26 | arel (~> 2.2.1) 27 | tzinfo (~> 0.3.29) 28 | activeresource (3.1.0) 29 | activemodel (= 3.1.0) 30 | activesupport (= 3.1.0) 31 | activesupport (3.1.0) 32 | multi_json (~> 1.0) 33 | ansi (1.3.0) 34 | arel (2.2.1) 35 | bcrypt-ruby (3.0.0) 36 | builder (3.0.0) 37 | coffee-rails (3.1.0) 38 | coffee-script (>= 2.2.0) 39 | railties (~> 3.1.0.rc1) 40 | coffee-script (2.2.0) 41 | coffee-script-source 42 | execjs 43 | coffee-script-source (1.1.2) 44 | devise (1.4.4) 45 | bcrypt-ruby (~> 3.0) 46 | orm_adapter (~> 0.0.3) 47 | warden (~> 1.0.3) 48 | erubis (2.7.0) 49 | execjs (1.2.4) 50 | multi_json (~> 1.0) 51 | haml (3.1.2) 52 | haml-rails (0.3.4) 53 | actionpack (~> 3.0) 54 | activesupport (~> 3.0) 55 | haml (~> 3.0) 56 | railties (~> 3.0) 57 | hike (1.2.1) 58 | i18n (0.6.0) 59 | i18n_generators (1.0.3) 60 | jquery-rails (1.0.13) 61 | railties (~> 3.0) 62 | thor (~> 0.14) 63 | kaminari (0.12.4) 64 | rails (>= 3.0.0) 65 | mail (2.3.0) 66 | i18n (>= 0.4.0) 67 | mime-types (~> 1.16) 68 | treetop (~> 1.4.8) 69 | mime-types (1.16) 70 | multi_json (1.0.3) 71 | nifty-generators (0.4.6) 72 | orm_adapter (0.0.5) 73 | pg (0.11.0) 74 | polyglot (0.3.2) 75 | rack (1.3.2) 76 | rack-cache (1.0.3) 77 | rack (>= 0.4) 78 | rack-mount (0.8.3) 79 | rack (>= 1.0.0) 80 | rack-ssl (1.3.2) 81 | rack 82 | rack-test (0.6.1) 83 | rack (>= 1.0) 84 | rails (3.1.0) 85 | actionmailer (= 3.1.0) 86 | actionpack (= 3.1.0) 87 | activerecord (= 3.1.0) 88 | activeresource (= 3.1.0) 89 | activesupport (= 3.1.0) 90 | bundler (~> 1.0) 91 | railties (= 3.1.0) 92 | railties (3.1.0) 93 | actionpack (= 3.1.0) 94 | activesupport (= 3.1.0) 95 | rack-ssl (~> 1.3.2) 96 | rake (>= 0.8.7) 97 | rdoc (~> 3.4) 98 | thor (~> 0.14.6) 99 | rake (0.9.2) 100 | rdoc (3.9.4) 101 | sass (3.1.7) 102 | sass-rails (3.1.0) 103 | actionpack (~> 3.1.0) 104 | railties (~> 3.1.0) 105 | sass (>= 3.1.4) 106 | sprockets (2.0.0) 107 | hike (~> 1.2) 108 | rack (~> 1.0) 109 | tilt (~> 1.1, != 1.3.0) 110 | sqlite3 (1.3.4) 111 | therubyracer-heroku (0.8.1.pre3) 112 | thor (0.14.6) 113 | tilt (1.3.3) 114 | treetop (1.4.10) 115 | polyglot 116 | polyglot (>= 0.3.1) 117 | turn (0.8.2) 118 | ansi (>= 1.2.2) 119 | tzinfo (0.3.29) 120 | uglifier (1.0.3) 121 | execjs (>= 0.3.0) 122 | multi_json (>= 1.0.2) 123 | warden (1.0.5) 124 | rack (>= 1.0) 125 | 126 | PLATFORMS 127 | ruby 128 | 129 | DEPENDENCIES 130 | coffee-rails (~> 3.1.0) 131 | devise 132 | haml-rails 133 | i18n_generators 134 | jquery-rails 135 | kaminari 136 | nifty-generators 137 | pg 138 | rails (= 3.1.0) 139 | sass-rails (~> 3.1.0) 140 | sqlite3 141 | therubyracer-heroku 142 | turn 143 | uglifier 144 | -------------------------------------------------------------------------------- /public/assets/ICanHaz-b4b81e9871b46f7e192a5e1d3182010b.min.js: -------------------------------------------------------------------------------- 1 | (function(a){var b=function(){var a=function(){};return a.prototype={otag:"{{",ctag:"}}",pragmas:{},buffer:[],pragmas_implemented:{"IMPLICIT-ITERATOR":!0},context:{},render:function(a,b,c,d){d||(this.context=b,this.buffer=[]);if(!this.includes("",a)){if(d)return a;this.send(a);return}a=this.render_pragmas(a),a=this.render_section(a,b,c);if(d)return this.render_tags(a,b,c,d);this.render_tags(a,b,c,d)},send:function(a){a!=""&&this.buffer.push(a)},render_pragmas:function(a){if(!this.includes("%",a))return a;var b=this;return a.replace(RegExp(this.otag+"%([\\w-]+) ?([\\w]+=[\\w]+)?"+this.ctag),function(a,c,d){if(!b.pragmas_implemented[c])throw{message:"This implementation of mustache doesn't understand the '"+c+"' pragma"};return b.pragmas[c]={},d&&(a=d.split("="),b.pragmas[c][a[0]]=a[1]),""})},render_partial:function(a,b,c){a=this.trim(a);if(!c||c[a]===undefined)throw{message:"unknown_partial '"+a+"'"};return typeof b[a]!="object"?this.render(c[a],b,c,!0):this.render(c[a],b[a],c,!0)},render_section:function(a,b,c){if(!this.includes("#",a)&&!this.includes("^",a))return a;var d=this;return a.replace(RegExp(this.otag+"(\\^|\\#)\\s*(.+)\\s*"+this.ctag+"\n*([\\s\\S]+?)"+this.otag+"\\/\\s*\\2\\s*"+this.ctag+"\\s*","mg"),function(a,e,f,g){a=d.find(f,b);if(e=="^")return!a||d.is_array(a)&&a.length===0?d.render(g,b,c,!0):"";if(e=="#")return d.is_array(a)?d.map(a,function(a){return d.render(g,d.create_context(a),c,!0)}).join(""):d.is_object(a)?d.render(g,d.create_context(a),c,!0):typeof a=="function"?a.call(b,g,function(a){return d.render(a,b,c,!0)}):a?d.render(g,b,c,!0):""})},render_tags:function(a,b,c,d){var e=this,f=function(){return RegExp(e.otag+"(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?"+e.ctag+"+","g")},g=f(),h=function(a,d,h){switch(d){case"!":return"";case"=":return e.set_delimiters(h),g=f(),"";case">":return e.render_partial(h,b,c);case"{":return e.find(h,b);default:return e.escape(e.find(h,b))}};a=a.split("\n");for(var i=0;i\\]/g,function(a){switch(a){case"&":return"&";case"\\":return"\\\\";case'"':return'"';case"<":return"<";case">":return">";default:return a}})},create_context:function(a){if(this.is_object(a))return a;var b=".";this.pragmas["IMPLICIT-ITERATOR"]&&(b=this.pragmas["IMPLICIT-ITERATOR"].iterator);var c={};return c[b]=a,c},is_object:function(a){return a&&typeof a=="object"},is_array:function(a){return Object.prototype.toString.call(a)==="[object Array]"},trim:function(a){return a.replace(/^\s*|\s*$/g,"")},map:function(a,b){if(typeof a.map=="function")return a.map(b);for(var c=[],d=a.length,e=0;e|\\{|%)?([^\\/#\\^]+?)\\1?"+e.ctag+"+","g")},k=j(),h=function(o,m,l){switch(m){case "!":return"";case "=":e.set_delimiters(l);k=j();return"";case ">":return e.render_partial(l,b,c);case "{":return e.find(l,b);default:return e.escape(e.find(l,b))}};a=a.split("\n");for(var g=0;g\\]/g,function(b){switch(b){case "&":return"&";case "\\":return"\\\\";case '"':return'"';case "<":return"<";case ">":return">";default:return b}})},create_context:function(a){if(this.is_object(a))return a;else{var b=".";if(this.pragmas["IMPLICIT-ITERATOR"])b=this.pragmas["IMPLICIT-ITERATOR"].iterator;var c={};c[b]=a;return c}}, 7 | is_object:function(a){return a&&typeof a=="object"},is_array:function(a){return Object.prototype.toString.call(a)==="[object Array]"},trim:function(a){return a.replace(/^\s*|\s*$/g,"")},map:function(a,b){if(typeof a.map=="function")return a.map(b);else{for(var c=[],d=a.length,e=0;e Mailer Configuration 5 | # Configure the e-mail address which will be shown in Devise::Mailer, 6 | # note that it will be overwritten if you use your own mailer class with default "from" parameter. 7 | config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com" 8 | 9 | # Configure the class responsible to send e-mails. 10 | # config.mailer = "Devise::Mailer" 11 | 12 | # ==> ORM configuration 13 | # Load and configure the ORM. Supports :active_record (default) and 14 | # :mongoid (bson_ext recommended) by default. Other ORMs may be 15 | # available as additional gems. 16 | require 'devise/orm/active_record' 17 | 18 | # ==> Configuration for any authentication mechanism 19 | # Configure which keys are used when authenticating a user. The default is 20 | # just :email. You can configure it to use [:username, :subdomain], so for 21 | # authenticating a user, both parameters are required. Remember that those 22 | # parameters are used only when authenticating and not when retrieving from 23 | # session. If you need permissions, you should implement that in a before filter. 24 | # You can also supply a hash where the value is a boolean determining whether 25 | # or not authentication should be aborted when the value is not present. 26 | # config.authentication_keys = [ :email ] 27 | 28 | # Configure parameters from the request object used for authentication. Each entry 29 | # given should be a request method and it will automatically be passed to the 30 | # find_for_authentication method and considered in your model lookup. For instance, 31 | # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. 32 | # The same considerations mentioned for authentication_keys also apply to request_keys. 33 | # config.request_keys = [] 34 | 35 | # Configure which authentication keys should be case-insensitive. 36 | # These keys will be downcased upon creating or modifying a user and when used 37 | # to authenticate or find a user. Default is :email. 38 | config.case_insensitive_keys = [ :email ] 39 | 40 | # Configure which authentication keys should have whitespace stripped. 41 | # These keys will have whitespace before and after removed upon creating or 42 | # modifying a user and when used to authenticate or find a user. Default is :email. 43 | config.strip_whitespace_keys = [ :email ] 44 | 45 | # Tell if authentication through request.params is enabled. True by default. 46 | # config.params_authenticatable = true 47 | 48 | # Tell if authentication through HTTP Basic Auth is enabled. False by default. 49 | # config.http_authenticatable = false 50 | 51 | # If http headers should be returned for AJAX requests. True by default. 52 | # config.http_authenticatable_on_xhr = true 53 | 54 | # The realm used in Http Basic Authentication. "Application" by default. 55 | # config.http_authentication_realm = "Application" 56 | 57 | # It will change confirmation, password recovery and other workflows 58 | # to behave the same regardless if the e-mail provided was right or wrong. 59 | # Does not affect registerable. 60 | # config.paranoid = true 61 | 62 | # ==> Configuration for :database_authenticatable 63 | # For bcrypt, this is the cost for hashing the password and defaults to 10. If 64 | # using other encryptors, it sets how many times you want the password re-encrypted. 65 | # 66 | # Limiting the stretches to just one in testing will increase the performance of 67 | # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use 68 | # a value less than 10 in other environments. 69 | config.stretches = Rails.env.test? ? 1 : 10 70 | 71 | # Setup a pepper to generate the encrypted password. 72 | # config.pepper = "358597d57a823f59f16fae766ab11b37478dd71364604a8734fd27cd74f35cb5c3fb044b22c87a5e57f03c80068c42c47d21a68f75355802f53ec45fb643514a" 73 | 74 | # ==> Configuration for :confirmable 75 | # The time you want to give your user to confirm his account. During this time 76 | # he will be able to access your application without confirming. Default is 0.days 77 | # When confirm_within is zero, the user won't be able to sign in without confirming. 78 | # You can use this to let your user access some features of your application 79 | # without confirming the account, but blocking it after a certain period 80 | # (ie 2 days). 81 | # config.confirm_within = 2.days 82 | 83 | # Defines which key will be used when confirming an account 84 | # config.confirmation_keys = [ :email ] 85 | 86 | # ==> Configuration for :rememberable 87 | # The time the user will be remembered without asking for credentials again. 88 | # config.remember_for = 2.weeks 89 | 90 | # If true, a valid remember token can be re-used between multiple browsers. 91 | # config.remember_across_browsers = true 92 | 93 | # If true, extends the user's remember period when remembered via cookie. 94 | # config.extend_remember_period = false 95 | 96 | # If true, uses the password salt as remember token. This should be turned 97 | # to false if you are not using database authenticatable. 98 | config.use_salt_as_remember_token = true 99 | 100 | # Options to be passed to the created cookie. For instance, you can set 101 | # :secure => true in order to force SSL only cookies. 102 | # config.cookie_options = {} 103 | 104 | # ==> Configuration for :validatable 105 | # Range for password length. Default is 6..128. 106 | # config.password_length = 6..128 107 | 108 | # Email regex used to validate email formats. It simply asserts that 109 | # an one (and only one) @ exists in the given string. This is mainly 110 | # to give user feedback and not to assert the e-mail validity. 111 | # config.email_regexp = /\A[^@]+@[^@]+\z/ 112 | 113 | # ==> Configuration for :timeoutable 114 | # The time you want to timeout the user session without activity. After this 115 | # time the user will be asked for credentials again. Default is 30 minutes. 116 | # config.timeout_in = 30.minutes 117 | 118 | # ==> Configuration for :lockable 119 | # Defines which strategy will be used to lock an account. 120 | # :failed_attempts = Locks an account after a number of failed attempts to sign in. 121 | # :none = No lock strategy. You should handle locking by yourself. 122 | # config.lock_strategy = :failed_attempts 123 | 124 | # Defines which key will be used when locking and unlocking an account 125 | # config.unlock_keys = [ :email ] 126 | 127 | # Defines which strategy will be used to unlock an account. 128 | # :email = Sends an unlock link to the user email 129 | # :time = Re-enables login after a certain amount of time (see :unlock_in below) 130 | # :both = Enables both strategies 131 | # :none = No unlock strategy. You should handle unlocking by yourself. 132 | # config.unlock_strategy = :both 133 | 134 | # Number of authentication tries before locking an account if lock_strategy 135 | # is failed attempts. 136 | # config.maximum_attempts = 20 137 | 138 | # Time interval to unlock the account if :time is enabled as unlock_strategy. 139 | # config.unlock_in = 1.hour 140 | 141 | # ==> Configuration for :recoverable 142 | # 143 | # Defines which key will be used when recovering the password for an account 144 | # config.reset_password_keys = [ :email ] 145 | 146 | # Time interval you can reset your password with a reset password key. 147 | # Don't put a too small interval or your users won't have the time to 148 | # change their passwords. 149 | config.reset_password_within = 2.hours 150 | 151 | # ==> Configuration for :encryptable 152 | # Allow you to use another encryption algorithm besides bcrypt (default). You can use 153 | # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, 154 | # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) 155 | # and :restful_authentication_sha1 (then you should set stretches to 10, and copy 156 | # REST_AUTH_SITE_KEY to pepper) 157 | # config.encryptor = :sha512 158 | 159 | # ==> Configuration for :token_authenticatable 160 | # Defines name of the authentication token params key 161 | # config.token_authentication_key = :auth_token 162 | 163 | # If true, authentication through token does not store user in session and needs 164 | # to be supplied on each request. Useful if you are using the token as API token. 165 | # config.stateless_token = false 166 | 167 | # ==> Scopes configuration 168 | # Turn scoped views on. Before rendering "sessions/new", it will first check for 169 | # "users/sessions/new". It's turned off by default because it's slower if you 170 | # are using only default views. 171 | # config.scoped_views = false 172 | 173 | # Configure the default scope given to Warden. By default it's the first 174 | # devise role declared in your routes (usually :user). 175 | # config.default_scope = :user 176 | 177 | # Configure sign_out behavior. 178 | # Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope). 179 | # The default is true, which means any logout action will sign out all active scopes. 180 | # config.sign_out_all_scopes = true 181 | 182 | # ==> Navigation configuration 183 | # Lists the formats that should be treated as navigational. Formats like 184 | # :html, should redirect to the sign in page when the user does not have 185 | # access, but formats like :xml or :json, should return 401. 186 | # 187 | # If you have any extra navigational formats, like :iphone or :mobile, you 188 | # should add them to the navigational formats lists. 189 | # 190 | # The :"*/*" and "*/*" formats below is required to match Internet 191 | # Explorer requests. 192 | # config.navigational_formats = [:"*/*", "*/*", :html] 193 | 194 | # The default HTTP method used to sign out a resource. Default is :delete. 195 | config.sign_out_via = :delete 196 | 197 | # ==> OmniAuth 198 | # Add a new OmniAuth provider. Check the wiki for more information on setting 199 | # up on your models and hooks. 200 | # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo' 201 | 202 | # ==> Warden configuration 203 | # If you want to use other strategies, that are not supported by Devise, or 204 | # change the failure app, you can configure them inside the config.warden block. 205 | # 206 | # config.warden do |manager| 207 | # manager.failure_app = AnotherApp 208 | # manager.intercept_401 = false 209 | # manager.default_strategies(:scope => :user).unshift :some_external_strategy 210 | # end 211 | end 212 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.1.7 2 | // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. 3 | // Underscore is freely distributable under the MIT license. 4 | // Portions of Underscore are inspired or borrowed from Prototype, 5 | // Oliver Steele's Functional, and John Resig's Micro-Templating. 6 | // For all details and documentation: 7 | // http://documentcloud.github.com/underscore 8 | 9 | (function() { 10 | 11 | // Baseline setup 12 | // -------------- 13 | 14 | // Establish the root object, `window` in the browser, or `global` on the server. 15 | var root = this; 16 | 17 | // Save the previous value of the `_` variable. 18 | var previousUnderscore = root._; 19 | 20 | // Establish the object that gets returned to break out of a loop iteration. 21 | var breaker = {}; 22 | 23 | // Save bytes in the minified (but not gzipped) version: 24 | var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; 25 | 26 | // Create quick reference variables for speed access to core prototypes. 27 | var slice = ArrayProto.slice, 28 | unshift = ArrayProto.unshift, 29 | toString = ObjProto.toString, 30 | hasOwnProperty = ObjProto.hasOwnProperty; 31 | 32 | // All **ECMAScript 5** native function implementations that we hope to use 33 | // are declared here. 34 | var 35 | nativeForEach = ArrayProto.forEach, 36 | nativeMap = ArrayProto.map, 37 | nativeReduce = ArrayProto.reduce, 38 | nativeReduceRight = ArrayProto.reduceRight, 39 | nativeFilter = ArrayProto.filter, 40 | nativeEvery = ArrayProto.every, 41 | nativeSome = ArrayProto.some, 42 | nativeIndexOf = ArrayProto.indexOf, 43 | nativeLastIndexOf = ArrayProto.lastIndexOf, 44 | nativeIsArray = Array.isArray, 45 | nativeKeys = Object.keys, 46 | nativeBind = FuncProto.bind; 47 | 48 | // Create a safe reference to the Underscore object for use below. 49 | var _ = function(obj) { return new wrapper(obj); }; 50 | 51 | // Export the Underscore object for **CommonJS**, with backwards-compatibility 52 | // for the old `require()` API. If we're not in CommonJS, add `_` to the 53 | // global object. 54 | if (typeof module !== 'undefined' && module.exports) { 55 | module.exports = _; 56 | _._ = _; 57 | } else { 58 | // Exported as a string, for Closure Compiler "advanced" mode. 59 | root['_'] = _; 60 | } 61 | 62 | // Current version. 63 | _.VERSION = '1.1.7'; 64 | 65 | // Collection Functions 66 | // -------------------- 67 | 68 | // The cornerstone, an `each` implementation, aka `forEach`. 69 | // Handles objects with the built-in `forEach`, arrays, and raw objects. 70 | // Delegates to **ECMAScript 5**'s native `forEach` if available. 71 | var each = _.each = _.forEach = function(obj, iterator, context) { 72 | if (obj == null) return; 73 | if (nativeForEach && obj.forEach === nativeForEach) { 74 | obj.forEach(iterator, context); 75 | } else if (obj.length === +obj.length) { 76 | for (var i = 0, l = obj.length; i < l; i++) { 77 | if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; 78 | } 79 | } else { 80 | for (var key in obj) { 81 | if (hasOwnProperty.call(obj, key)) { 82 | if (iterator.call(context, obj[key], key, obj) === breaker) return; 83 | } 84 | } 85 | } 86 | }; 87 | 88 | // Return the results of applying the iterator to each element. 89 | // Delegates to **ECMAScript 5**'s native `map` if available. 90 | _.map = function(obj, iterator, context) { 91 | var results = []; 92 | if (obj == null) return results; 93 | if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); 94 | each(obj, function(value, index, list) { 95 | results[results.length] = iterator.call(context, value, index, list); 96 | }); 97 | return results; 98 | }; 99 | 100 | // **Reduce** builds up a single result from a list of values, aka `inject`, 101 | // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. 102 | _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { 103 | var initial = memo !== void 0; 104 | if (obj == null) obj = []; 105 | if (nativeReduce && obj.reduce === nativeReduce) { 106 | if (context) iterator = _.bind(iterator, context); 107 | return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); 108 | } 109 | each(obj, function(value, index, list) { 110 | if (!initial) { 111 | memo = value; 112 | initial = true; 113 | } else { 114 | memo = iterator.call(context, memo, value, index, list); 115 | } 116 | }); 117 | if (!initial) throw new TypeError("Reduce of empty array with no initial value"); 118 | return memo; 119 | }; 120 | 121 | // The right-associative version of reduce, also known as `foldr`. 122 | // Delegates to **ECMAScript 5**'s native `reduceRight` if available. 123 | _.reduceRight = _.foldr = function(obj, iterator, memo, context) { 124 | if (obj == null) obj = []; 125 | if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { 126 | if (context) iterator = _.bind(iterator, context); 127 | return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); 128 | } 129 | var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse(); 130 | return _.reduce(reversed, iterator, memo, context); 131 | }; 132 | 133 | // Return the first value which passes a truth test. Aliased as `detect`. 134 | _.find = _.detect = function(obj, iterator, context) { 135 | var result; 136 | any(obj, function(value, index, list) { 137 | if (iterator.call(context, value, index, list)) { 138 | result = value; 139 | return true; 140 | } 141 | }); 142 | return result; 143 | }; 144 | 145 | // Return all the elements that pass a truth test. 146 | // Delegates to **ECMAScript 5**'s native `filter` if available. 147 | // Aliased as `select`. 148 | _.filter = _.select = function(obj, iterator, context) { 149 | var results = []; 150 | if (obj == null) return results; 151 | if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); 152 | each(obj, function(value, index, list) { 153 | if (iterator.call(context, value, index, list)) results[results.length] = value; 154 | }); 155 | return results; 156 | }; 157 | 158 | // Return all the elements for which a truth test fails. 159 | _.reject = function(obj, iterator, context) { 160 | var results = []; 161 | if (obj == null) return results; 162 | each(obj, function(value, index, list) { 163 | if (!iterator.call(context, value, index, list)) results[results.length] = value; 164 | }); 165 | return results; 166 | }; 167 | 168 | // Determine whether all of the elements match a truth test. 169 | // Delegates to **ECMAScript 5**'s native `every` if available. 170 | // Aliased as `all`. 171 | _.every = _.all = function(obj, iterator, context) { 172 | var result = true; 173 | if (obj == null) return result; 174 | if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); 175 | each(obj, function(value, index, list) { 176 | if (!(result = result && iterator.call(context, value, index, list))) return breaker; 177 | }); 178 | return result; 179 | }; 180 | 181 | // Determine if at least one element in the object matches a truth test. 182 | // Delegates to **ECMAScript 5**'s native `some` if available. 183 | // Aliased as `any`. 184 | var any = _.some = _.any = function(obj, iterator, context) { 185 | iterator = iterator || _.identity; 186 | var result = false; 187 | if (obj == null) return result; 188 | if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); 189 | each(obj, function(value, index, list) { 190 | if (result |= iterator.call(context, value, index, list)) return breaker; 191 | }); 192 | return !!result; 193 | }; 194 | 195 | // Determine if a given value is included in the array or object using `===`. 196 | // Aliased as `contains`. 197 | _.include = _.contains = function(obj, target) { 198 | var found = false; 199 | if (obj == null) return found; 200 | if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; 201 | any(obj, function(value) { 202 | if (found = value === target) return true; 203 | }); 204 | return found; 205 | }; 206 | 207 | // Invoke a method (with arguments) on every item in a collection. 208 | _.invoke = function(obj, method) { 209 | var args = slice.call(arguments, 2); 210 | return _.map(obj, function(value) { 211 | return (method.call ? method || value : value[method]).apply(value, args); 212 | }); 213 | }; 214 | 215 | // Convenience version of a common use case of `map`: fetching a property. 216 | _.pluck = function(obj, key) { 217 | return _.map(obj, function(value){ return value[key]; }); 218 | }; 219 | 220 | // Return the maximum element or (element-based computation). 221 | _.max = function(obj, iterator, context) { 222 | if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); 223 | var result = {computed : -Infinity}; 224 | each(obj, function(value, index, list) { 225 | var computed = iterator ? iterator.call(context, value, index, list) : value; 226 | computed >= result.computed && (result = {value : value, computed : computed}); 227 | }); 228 | return result.value; 229 | }; 230 | 231 | // Return the minimum element (or element-based computation). 232 | _.min = function(obj, iterator, context) { 233 | if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); 234 | var result = {computed : Infinity}; 235 | each(obj, function(value, index, list) { 236 | var computed = iterator ? iterator.call(context, value, index, list) : value; 237 | computed < result.computed && (result = {value : value, computed : computed}); 238 | }); 239 | return result.value; 240 | }; 241 | 242 | // Sort the object's values by a criterion produced by an iterator. 243 | _.sortBy = function(obj, iterator, context) { 244 | return _.pluck(_.map(obj, function(value, index, list) { 245 | return { 246 | value : value, 247 | criteria : iterator.call(context, value, index, list) 248 | }; 249 | }).sort(function(left, right) { 250 | var a = left.criteria, b = right.criteria; 251 | return a < b ? -1 : a > b ? 1 : 0; 252 | }), 'value'); 253 | }; 254 | 255 | // Groups the object's values by a criterion produced by an iterator 256 | _.groupBy = function(obj, iterator) { 257 | var result = {}; 258 | each(obj, function(value, index) { 259 | var key = iterator(value, index); 260 | (result[key] || (result[key] = [])).push(value); 261 | }); 262 | return result; 263 | }; 264 | 265 | // Use a comparator function to figure out at what index an object should 266 | // be inserted so as to maintain order. Uses binary search. 267 | _.sortedIndex = function(array, obj, iterator) { 268 | iterator || (iterator = _.identity); 269 | var low = 0, high = array.length; 270 | while (low < high) { 271 | var mid = (low + high) >> 1; 272 | iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; 273 | } 274 | return low; 275 | }; 276 | 277 | // Safely convert anything iterable into a real, live array. 278 | _.toArray = function(iterable) { 279 | if (!iterable) return []; 280 | if (iterable.toArray) return iterable.toArray(); 281 | if (_.isArray(iterable)) return slice.call(iterable); 282 | if (_.isArguments(iterable)) return slice.call(iterable); 283 | return _.values(iterable); 284 | }; 285 | 286 | // Return the number of elements in an object. 287 | _.size = function(obj) { 288 | return _.toArray(obj).length; 289 | }; 290 | 291 | // Array Functions 292 | // --------------- 293 | 294 | // Get the first element of an array. Passing **n** will return the first N 295 | // values in the array. Aliased as `head`. The **guard** check allows it to work 296 | // with `_.map`. 297 | _.first = _.head = function(array, n, guard) { 298 | return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; 299 | }; 300 | 301 | // Returns everything but the first entry of the array. Aliased as `tail`. 302 | // Especially useful on the arguments object. Passing an **index** will return 303 | // the rest of the values in the array from that index onward. The **guard** 304 | // check allows it to work with `_.map`. 305 | _.rest = _.tail = function(array, index, guard) { 306 | return slice.call(array, (index == null) || guard ? 1 : index); 307 | }; 308 | 309 | // Get the last element of an array. 310 | _.last = function(array) { 311 | return array[array.length - 1]; 312 | }; 313 | 314 | // Trim out all falsy values from an array. 315 | _.compact = function(array) { 316 | return _.filter(array, function(value){ return !!value; }); 317 | }; 318 | 319 | // Return a completely flattened version of an array. 320 | _.flatten = function(array) { 321 | return _.reduce(array, function(memo, value) { 322 | if (_.isArray(value)) return memo.concat(_.flatten(value)); 323 | memo[memo.length] = value; 324 | return memo; 325 | }, []); 326 | }; 327 | 328 | // Return a version of the array that does not contain the specified value(s). 329 | _.without = function(array) { 330 | return _.difference(array, slice.call(arguments, 1)); 331 | }; 332 | 333 | // Produce a duplicate-free version of the array. If the array has already 334 | // been sorted, you have the option of using a faster algorithm. 335 | // Aliased as `unique`. 336 | _.uniq = _.unique = function(array, isSorted) { 337 | return _.reduce(array, function(memo, el, i) { 338 | if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el; 339 | return memo; 340 | }, []); 341 | }; 342 | 343 | // Produce an array that contains the union: each distinct element from all of 344 | // the passed-in arrays. 345 | _.union = function() { 346 | return _.uniq(_.flatten(arguments)); 347 | }; 348 | 349 | // Produce an array that contains every item shared between all the 350 | // passed-in arrays. (Aliased as "intersect" for back-compat.) 351 | _.intersection = _.intersect = function(array) { 352 | var rest = slice.call(arguments, 1); 353 | return _.filter(_.uniq(array), function(item) { 354 | return _.every(rest, function(other) { 355 | return _.indexOf(other, item) >= 0; 356 | }); 357 | }); 358 | }; 359 | 360 | // Take the difference between one array and another. 361 | // Only the elements present in just the first array will remain. 362 | _.difference = function(array, other) { 363 | return _.filter(array, function(value){ return !_.include(other, value); }); 364 | }; 365 | 366 | // Zip together multiple lists into a single array -- elements that share 367 | // an index go together. 368 | _.zip = function() { 369 | var args = slice.call(arguments); 370 | var length = _.max(_.pluck(args, 'length')); 371 | var results = new Array(length); 372 | for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); 373 | return results; 374 | }; 375 | 376 | // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), 377 | // we need this function. Return the position of the first occurrence of an 378 | // item in an array, or -1 if the item is not included in the array. 379 | // Delegates to **ECMAScript 5**'s native `indexOf` if available. 380 | // If the array is large and already in sort order, pass `true` 381 | // for **isSorted** to use binary search. 382 | _.indexOf = function(array, item, isSorted) { 383 | if (array == null) return -1; 384 | var i, l; 385 | if (isSorted) { 386 | i = _.sortedIndex(array, item); 387 | return array[i] === item ? i : -1; 388 | } 389 | if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); 390 | for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i; 391 | return -1; 392 | }; 393 | 394 | 395 | // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. 396 | _.lastIndexOf = function(array, item) { 397 | if (array == null) return -1; 398 | if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); 399 | var i = array.length; 400 | while (i--) if (array[i] === item) return i; 401 | return -1; 402 | }; 403 | 404 | // Generate an integer Array containing an arithmetic progression. A port of 405 | // the native Python `range()` function. See 406 | // [the Python documentation](http://docs.python.org/library/functions.html#range). 407 | _.range = function(start, stop, step) { 408 | if (arguments.length <= 1) { 409 | stop = start || 0; 410 | start = 0; 411 | } 412 | step = arguments[2] || 1; 413 | 414 | var len = Math.max(Math.ceil((stop - start) / step), 0); 415 | var idx = 0; 416 | var range = new Array(len); 417 | 418 | while(idx < len) { 419 | range[idx++] = start; 420 | start += step; 421 | } 422 | 423 | return range; 424 | }; 425 | 426 | // Function (ahem) Functions 427 | // ------------------ 428 | 429 | // Create a function bound to a given object (assigning `this`, and arguments, 430 | // optionally). Binding with arguments is also known as `curry`. 431 | // Delegates to **ECMAScript 5**'s native `Function.bind` if available. 432 | // We check for `func.bind` first, to fail fast when `func` is undefined. 433 | _.bind = function(func, obj) { 434 | if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); 435 | var args = slice.call(arguments, 2); 436 | return function() { 437 | return func.apply(obj, args.concat(slice.call(arguments))); 438 | }; 439 | }; 440 | 441 | // Bind all of an object's methods to that object. Useful for ensuring that 442 | // all callbacks defined on an object belong to it. 443 | _.bindAll = function(obj) { 444 | var funcs = slice.call(arguments, 1); 445 | if (funcs.length == 0) funcs = _.functions(obj); 446 | each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); 447 | return obj; 448 | }; 449 | 450 | // Memoize an expensive function by storing its results. 451 | _.memoize = function(func, hasher) { 452 | var memo = {}; 453 | hasher || (hasher = _.identity); 454 | return function() { 455 | var key = hasher.apply(this, arguments); 456 | return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); 457 | }; 458 | }; 459 | 460 | // Delays a function for the given number of milliseconds, and then calls 461 | // it with the arguments supplied. 462 | _.delay = function(func, wait) { 463 | var args = slice.call(arguments, 2); 464 | return setTimeout(function(){ return func.apply(func, args); }, wait); 465 | }; 466 | 467 | // Defers a function, scheduling it to run after the current call stack has 468 | // cleared. 469 | _.defer = function(func) { 470 | return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); 471 | }; 472 | 473 | // Internal function used to implement `_.throttle` and `_.debounce`. 474 | var limit = function(func, wait, debounce) { 475 | var timeout; 476 | return function() { 477 | var context = this, args = arguments; 478 | var throttler = function() { 479 | timeout = null; 480 | func.apply(context, args); 481 | }; 482 | if (debounce) clearTimeout(timeout); 483 | if (debounce || !timeout) timeout = setTimeout(throttler, wait); 484 | }; 485 | }; 486 | 487 | // Returns a function, that, when invoked, will only be triggered at most once 488 | // during a given window of time. 489 | _.throttle = function(func, wait) { 490 | return limit(func, wait, false); 491 | }; 492 | 493 | // Returns a function, that, as long as it continues to be invoked, will not 494 | // be triggered. The function will be called after it stops being called for 495 | // N milliseconds. 496 | _.debounce = function(func, wait) { 497 | return limit(func, wait, true); 498 | }; 499 | 500 | // Returns a function that will be executed at most one time, no matter how 501 | // often you call it. Useful for lazy initialization. 502 | _.once = function(func) { 503 | var ran = false, memo; 504 | return function() { 505 | if (ran) return memo; 506 | ran = true; 507 | return memo = func.apply(this, arguments); 508 | }; 509 | }; 510 | 511 | // Returns the first function passed as an argument to the second, 512 | // allowing you to adjust arguments, run code before and after, and 513 | // conditionally execute the original function. 514 | _.wrap = function(func, wrapper) { 515 | return function() { 516 | var args = [func].concat(slice.call(arguments)); 517 | return wrapper.apply(this, args); 518 | }; 519 | }; 520 | 521 | // Returns a function that is the composition of a list of functions, each 522 | // consuming the return value of the function that follows. 523 | _.compose = function() { 524 | var funcs = slice.call(arguments); 525 | return function() { 526 | var args = slice.call(arguments); 527 | for (var i = funcs.length - 1; i >= 0; i--) { 528 | args = [funcs[i].apply(this, args)]; 529 | } 530 | return args[0]; 531 | }; 532 | }; 533 | 534 | // Returns a function that will only be executed after being called N times. 535 | _.after = function(times, func) { 536 | return function() { 537 | if (--times < 1) { return func.apply(this, arguments); } 538 | }; 539 | }; 540 | 541 | 542 | // Object Functions 543 | // ---------------- 544 | 545 | // Retrieve the names of an object's properties. 546 | // Delegates to **ECMAScript 5**'s native `Object.keys` 547 | _.keys = nativeKeys || function(obj) { 548 | if (obj !== Object(obj)) throw new TypeError('Invalid object'); 549 | var keys = []; 550 | for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key; 551 | return keys; 552 | }; 553 | 554 | // Retrieve the values of an object's properties. 555 | _.values = function(obj) { 556 | return _.map(obj, _.identity); 557 | }; 558 | 559 | // Return a sorted list of the function names available on the object. 560 | // Aliased as `methods` 561 | _.functions = _.methods = function(obj) { 562 | var names = []; 563 | for (var key in obj) { 564 | if (_.isFunction(obj[key])) names.push(key); 565 | } 566 | return names.sort(); 567 | }; 568 | 569 | // Extend a given object with all the properties in passed-in object(s). 570 | _.extend = function(obj) { 571 | each(slice.call(arguments, 1), function(source) { 572 | for (var prop in source) { 573 | if (source[prop] !== void 0) obj[prop] = source[prop]; 574 | } 575 | }); 576 | return obj; 577 | }; 578 | 579 | // Fill in a given object with default properties. 580 | _.defaults = function(obj) { 581 | each(slice.call(arguments, 1), function(source) { 582 | for (var prop in source) { 583 | if (obj[prop] == null) obj[prop] = source[prop]; 584 | } 585 | }); 586 | return obj; 587 | }; 588 | 589 | // Create a (shallow-cloned) duplicate of an object. 590 | _.clone = function(obj) { 591 | return _.isArray(obj) ? obj.slice() : _.extend({}, obj); 592 | }; 593 | 594 | // Invokes interceptor with the obj, and then returns obj. 595 | // The primary purpose of this method is to "tap into" a method chain, in 596 | // order to perform operations on intermediate results within the chain. 597 | _.tap = function(obj, interceptor) { 598 | interceptor(obj); 599 | return obj; 600 | }; 601 | 602 | // Perform a deep comparison to check if two objects are equal. 603 | _.isEqual = function(a, b) { 604 | // Check object identity. 605 | if (a === b) return true; 606 | // Different types? 607 | var atype = typeof(a), btype = typeof(b); 608 | if (atype != btype) return false; 609 | // Basic equality test (watch out for coercions). 610 | if (a == b) return true; 611 | // One is falsy and the other truthy. 612 | if ((!a && b) || (a && !b)) return false; 613 | // Unwrap any wrapped objects. 614 | if (a._chain) a = a._wrapped; 615 | if (b._chain) b = b._wrapped; 616 | // One of them implements an isEqual()? 617 | if (a.isEqual) return a.isEqual(b); 618 | if (b.isEqual) return b.isEqual(a); 619 | // Check dates' integer values. 620 | if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); 621 | // Both are NaN? 622 | if (_.isNaN(a) && _.isNaN(b)) return false; 623 | // Compare regular expressions. 624 | if (_.isRegExp(a) && _.isRegExp(b)) 625 | return a.source === b.source && 626 | a.global === b.global && 627 | a.ignoreCase === b.ignoreCase && 628 | a.multiline === b.multiline; 629 | // If a is not an object by this point, we can't handle it. 630 | if (atype !== 'object') return false; 631 | // Check for different array lengths before comparing contents. 632 | if (a.length && (a.length !== b.length)) return false; 633 | // Nothing else worked, deep compare the contents. 634 | var aKeys = _.keys(a), bKeys = _.keys(b); 635 | // Different object sizes? 636 | if (aKeys.length != bKeys.length) return false; 637 | // Recursive comparison of contents. 638 | for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false; 639 | return true; 640 | }; 641 | 642 | // Is a given array or object empty? 643 | _.isEmpty = function(obj) { 644 | if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; 645 | for (var key in obj) if (hasOwnProperty.call(obj, key)) return false; 646 | return true; 647 | }; 648 | 649 | // Is a given value a DOM element? 650 | _.isElement = function(obj) { 651 | return !!(obj && obj.nodeType == 1); 652 | }; 653 | 654 | // Is a given value an array? 655 | // Delegates to ECMA5's native Array.isArray 656 | _.isArray = nativeIsArray || function(obj) { 657 | return toString.call(obj) === '[object Array]'; 658 | }; 659 | 660 | // Is a given variable an object? 661 | _.isObject = function(obj) { 662 | return obj === Object(obj); 663 | }; 664 | 665 | // Is a given variable an arguments object? 666 | _.isArguments = function(obj) { 667 | return !!(obj && hasOwnProperty.call(obj, 'callee')); 668 | }; 669 | 670 | // Is a given value a function? 671 | _.isFunction = function(obj) { 672 | return !!(obj && obj.constructor && obj.call && obj.apply); 673 | }; 674 | 675 | // Is a given value a string? 676 | _.isString = function(obj) { 677 | return !!(obj === '' || (obj && obj.charCodeAt && obj.substr)); 678 | }; 679 | 680 | // Is a given value a number? 681 | _.isNumber = function(obj) { 682 | return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed)); 683 | }; 684 | 685 | // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript 686 | // that does not equal itself. 687 | _.isNaN = function(obj) { 688 | return obj !== obj; 689 | }; 690 | 691 | // Is a given value a boolean? 692 | _.isBoolean = function(obj) { 693 | return obj === true || obj === false; 694 | }; 695 | 696 | // Is a given value a date? 697 | _.isDate = function(obj) { 698 | return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear); 699 | }; 700 | 701 | // Is the given value a regular expression? 702 | _.isRegExp = function(obj) { 703 | return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false)); 704 | }; 705 | 706 | // Is a given value equal to null? 707 | _.isNull = function(obj) { 708 | return obj === null; 709 | }; 710 | 711 | // Is a given variable undefined? 712 | _.isUndefined = function(obj) { 713 | return obj === void 0; 714 | }; 715 | 716 | // Utility Functions 717 | // ----------------- 718 | 719 | // Run Underscore.js in *noConflict* mode, returning the `_` variable to its 720 | // previous owner. Returns a reference to the Underscore object. 721 | _.noConflict = function() { 722 | root._ = previousUnderscore; 723 | return this; 724 | }; 725 | 726 | // Keep the identity function around for default iterators. 727 | _.identity = function(value) { 728 | return value; 729 | }; 730 | 731 | // Run a function **n** times. 732 | _.times = function (n, iterator, context) { 733 | for (var i = 0; i < n; i++) iterator.call(context, i); 734 | }; 735 | 736 | // Add your own custom functions to the Underscore object, ensuring that 737 | // they're correctly added to the OOP wrapper as well. 738 | _.mixin = function(obj) { 739 | each(_.functions(obj), function(name){ 740 | addToWrapper(name, _[name] = obj[name]); 741 | }); 742 | }; 743 | 744 | // Generate a unique integer id (unique within the entire client session). 745 | // Useful for temporary DOM ids. 746 | var idCounter = 0; 747 | _.uniqueId = function(prefix) { 748 | var id = idCounter++; 749 | return prefix ? prefix + id : id; 750 | }; 751 | 752 | // By default, Underscore uses ERB-style template delimiters, change the 753 | // following template settings to use alternative delimiters. 754 | _.templateSettings = { 755 | evaluate : /<%([\s\S]+?)%>/g, 756 | interpolate : /<%=([\s\S]+?)%>/g 757 | }; 758 | 759 | // JavaScript micro-templating, similar to John Resig's implementation. 760 | // Underscore templating handles arbitrary delimiters, preserves whitespace, 761 | // and correctly escapes quotes within interpolated code. 762 | _.template = function(str, data) { 763 | var c = _.templateSettings; 764 | var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + 765 | 'with(obj||{}){__p.push(\'' + 766 | str.replace(/\\/g, '\\\\') 767 | .replace(/'/g, "\\'") 768 | .replace(c.interpolate, function(match, code) { 769 | return "'," + code.replace(/\\'/g, "'") + ",'"; 770 | }) 771 | .replace(c.evaluate || null, function(match, code) { 772 | return "');" + code.replace(/\\'/g, "'") 773 | .replace(/[\r\n\t]/g, ' ') + "__p.push('"; 774 | }) 775 | .replace(/\r/g, '\\r') 776 | .replace(/\n/g, '\\n') 777 | .replace(/\t/g, '\\t') 778 | + "');}return __p.join('');"; 779 | var func = new Function('obj', tmpl); 780 | return data ? func(data) : func; 781 | }; 782 | 783 | // The OOP Wrapper 784 | // --------------- 785 | 786 | // If Underscore is called as a function, it returns a wrapped object that 787 | // can be used OO-style. This wrapper holds altered versions of all the 788 | // underscore functions. Wrapped objects may be chained. 789 | var wrapper = function(obj) { this._wrapped = obj; }; 790 | 791 | // Expose `wrapper.prototype` as `_.prototype` 792 | _.prototype = wrapper.prototype; 793 | 794 | // Helper function to continue chaining intermediate results. 795 | var result = function(obj, chain) { 796 | return chain ? _(obj).chain() : obj; 797 | }; 798 | 799 | // A method to easily add functions to the OOP wrapper. 800 | var addToWrapper = function(name, func) { 801 | wrapper.prototype[name] = function() { 802 | var args = slice.call(arguments); 803 | unshift.call(args, this._wrapped); 804 | return result(func.apply(_, args), this._chain); 805 | }; 806 | }; 807 | 808 | // Add all of the Underscore functions to the wrapper object. 809 | _.mixin(_); 810 | 811 | // Add all mutator Array functions to the wrapper. 812 | each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { 813 | var method = ArrayProto[name]; 814 | wrapper.prototype[name] = function() { 815 | method.apply(this._wrapped, arguments); 816 | return result(this._wrapped, this._chain); 817 | }; 818 | }); 819 | 820 | // Add all accessor Array functions to the wrapper. 821 | each(['concat', 'join', 'slice'], function(name) { 822 | var method = ArrayProto[name]; 823 | wrapper.prototype[name] = function() { 824 | return result(method.apply(this._wrapped, arguments), this._chain); 825 | }; 826 | }); 827 | 828 | // Start chaining a wrapped Underscore object. 829 | wrapper.prototype.chain = function() { 830 | this._chain = true; 831 | return this; 832 | }; 833 | 834 | // Extracts the result from a wrapped and chained object. 835 | wrapper.prototype.value = function() { 836 | return this._wrapped; 837 | }; 838 | 839 | })(); 840 | -------------------------------------------------------------------------------- /public/assets/jquery-8a50feed8d29566738ad005e19fe1c2d.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery JavaScript Library v1.6.2 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 Jun 30 14:16:56 2011 -0400 15 | */ 16 | (function(a,b){function c(a){return J.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function d(a){if(!cl[a]){var b=G.body,c=J("<"+a+">").appendTo(b),d=c.css("display");c.remove();if(d==="none"||d===""){cm||(cm=G.createElement("iframe"),cm.frameBorder=cm.width=cm.height=0),b.appendChild(cm);if(!cn||!cm.createElement)cn=(cm.contentWindow||cm.contentDocument).document,cn.write((G.compatMode==="CSS1Compat"?"":"")+""),cn.close();c=cn.createElement(a),cn.body.appendChild(c),d=J.css(c,"display"),b.removeChild(cm)}cl[a]=d}return cl[a]}function e(a,b){var c={};return J.each(cr.concat.apply([],cr.slice(0,b)),function(){c[this]=a}),c}function f(){cs=b}function g(){return setTimeout(f,0),cs=J.now()}function h(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function i(){try{return new a.XMLHttpRequest}catch(b){}}function j(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},f,g,h=d.length,i,j=d[0],k,l,m,n,o;for(f=1;f0)return c!=="border"&&J.each(e,function(){c||(d-=parseFloat(J.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(J.css(a,c+this))||0:d-=parseFloat(J.css(a,"border"+this+"Width"))||0}),d+"px";d=bK(a,b,b);if(d<0||d==null)d=a.style[b]||0;return d=parseFloat(d)||0,c&&J.each(e,function(){d+=parseFloat(J.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(J.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(J.css(a,c+this))||0)}),d+"px"}function p(a,b){b.src?J.ajax({url:b.src,async:!1,dataType:"script"}):J.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function q(a){J.nodeName(a,"input")?r(a):"getElementsByTagName"in a&&J.grep(a.getElementsByTagName("input"),r)}function r(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function s(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function t(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(J.expando)}}function u(a,b){if(b.nodeType===1&&!!J.hasData(a)){var c=J.expando,d=J.data(a),e=J.data(b,d);if(d=d[c]){var f=d.events;e=e[c]=J.extend({},d);if(f){delete e.handle,e.events={};for(var g in f)for(var h=0,i=f[g].length;h=0===c})}function x(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function y(a,b){return(a&&a!=="*"?a+".":"")+b.replace($,"`").replace(_,"&")}function z(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o=[],p=[],q=J._data(this,"events");if(!(a.liveFired===this||!q||!q.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(m=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var r=q.live.slice(0);for(h=0;hc)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,n=e.handleObj.origHandler.apply(e.elem,arguments);if(n===!1||a.isPropagationStopped()){c=e.level,n===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function A(a,c,d){var e=J.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,J.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function B(){return!0}function C(){return!1}function D(a,c,d){var e=c+"defer",f=c+"queue",g=c+"mark",h=J.data(a,e,b,!0);h&&(d==="queue"||!J.data(a,f,b,!0))&&(d==="mark"||!J.data(a,g,b,!0))&&setTimeout(function(){!J.data(a,f,b,!0)&&!J.data(a,g,b,!0)&&(J.removeData(a,e,!0),h.resolve())},0)}function E(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function F(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(N,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:J.isNaN(d)?M.test(d)?J.parseJSON(d):d:parseFloat(d)}catch(f){}J.data(a,c,d)}else d=b}return d}var G=a.document,H=a.navigator,I=a.location,J=function(){function c(){if(!d.isReady){try{G.documentElement.doScroll("left")}catch(a){setTimeout(c,1);return}d.ready()}}var d=function(a,b){return new d.fn.init(a,b,g)},e=a.jQuery,f=a.$,g,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,i=/\S/,j=/^\s+/,k=/\s+$/,l=/\d/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z])/ig,w=function(a,b){return b.toUpperCase()},x=H.userAgent,y,z,A,B=Object.prototype.toString,C=Object.prototype.hasOwnProperty,D=Array.prototype.push,E=Array.prototype.slice,F=String.prototype.trim,I=Array.prototype.indexOf,J={};return d.fn=d.prototype={constructor:d,init:function(a,c,e){var f,g,i,j;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(a==="body"&&!c&&G.body)return this.context=G,this[0]=G.body,this.selector=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?f=h.exec(a):f=[null,a,null];if(f&&(f[1]||!c)){if(f[1])return c=c instanceof d?c[0]:c,j=c?c.ownerDocument||c:G,i=m.exec(a),i?d.isPlainObject(c)?(a=[G.createElement(i[1])],d.fn.attr.call(a,c,!0)):a=[j.createElement(i[1])]:(i=d.buildFragment([f[1]],[j]),a=(i.cacheable?d.clone(i.fragment):i.fragment).childNodes),d.merge(this,a);g=G.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return e.find(a);this.length=1,this[0]=g}return this.context=G,this.selector=a,this}return!c||c.jquery?(c||e).find(a):this.constructor(c).find(a)}return d.isFunction(a)?e.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),d.makeArray(a,this))},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return E.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 e=this.constructor();return d.isArray(a)?D.apply(e,a):d.merge(e,a),e.prevObject=this,e.context=this.context,b==="find"?e.selector=this.selector+(this.selector?" ":"")+c:b&&(e.selector=this.selector+"."+b+"("+c+")"),e},each:function(a,b){return d.each(this,a,b)},ready:function(a){return d.bindReady(),z.done(a),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(E.apply(this,arguments),"slice",E.call(arguments).join(","))},map:function(a){return this.pushStack(d.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:D,sort:[].sort,splice:[].splice},d.fn.init.prototype=d.fn,d.extend=d.fn.extend=function(){var a,c,e,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"&&!d.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;z.resolveWith(G,[d]),d.fn.trigger&&d(G).trigger("ready").unbind("ready")}},bindReady:function(){if(!z){z=d._Deferred();if(G.readyState==="complete")return setTimeout(d.ready,1);if(G.addEventListener)G.addEventListener("DOMContentLoaded",A,!1),a.addEventListener("load",d.ready,!1);else if(G.attachEvent){G.attachEvent("onreadystatechange",A),a.attachEvent("onload",d.ready);var b=!1;try{b=a.frameElement==null}catch(e){}G.documentElement.doScroll&&b&&c()}}},isFunction:function(a){return d.type(a)==="function"},isArray:Array.isArray||function(a){return d.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!l.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[B.call(a)]||"object"},isPlainObject:function(a){if(!a||d.type(a)!=="object"||a.nodeType||d.isWindow(a))return!1;if(a.constructor&&!C.call(a,"constructor")&&!C.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||C.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=d.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();d.error("Invalid JSON: "+b)},parseXML:function(b,c,e){return a.DOMParser?(e=new DOMParser,c=e.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),e=c.documentElement,(!e||!e.nodeName||e.nodeName==="parsererror")&&d.error("Invalid XML: "+b),c},noop:function(){},globalEval:function(b){b&&i.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(v,w)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,e){var f,g=0,h=a.length,i=h===b||d.isFunction(a);if(e){if(i){for(f in a)if(c.apply(a[f],e)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||d.isArray(a));if(k)for(;i1?L.call(arguments,0):b,--f||g.resolveWith(g,L.call(c,0))}}var c=arguments,d=0,e=c.length,f=e,g=e<=1&&a&&J.isFunction(a.promise)?a:J.Deferred();if(e>1){for(;d
a",c=a.getElementsByTagName("*"),d=a.getElementsByTagName("a")[0];if(!c||!c.length||!d)return{};e=G.createElement("select"),f=e.appendChild(G.createElement("option")),g=a.getElementsByTagName("input")[0],i={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.55$/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:g.value==="on",optSelected:f.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},g.checked=!0,i.noCloneChecked=g.cloneNode(!0).checked,e.disabled=!0,i.optDisabled=!f.disabled;try{delete a.test}catch(t){i.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){i.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),g=G.createElement("input"),g.value="t",g.setAttribute("type","radio"),i.radioValue=g.value==="t",g.setAttribute("checked","checked"),a.appendChild(g),j=G.createDocumentFragment(),j.appendChild(a.firstChild),i.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",k=G.getElementsByTagName("body")[0],m=G.createElement(k?"div":"body"),n={visibility:"hidden",width:0,height:0,border:0,margin:0},k&&J.extend(n,{position:"absolute",left:-1e3,top:-1e3});for(r in n)m.style[r]=n[r];m.appendChild(a),l=k||b,l.insertBefore(m,l.firstChild),i.appendChecked=g.checked,i.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,i.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",i.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",o=a.getElementsByTagName("td"),s=o[0].offsetHeight===0,o[0].style.display="",o[1].style.display="none",i.reliableHiddenOffsets=s&&o[0].offsetHeight===0,a.innerHTML="",G.defaultView&&G.defaultView.getComputedStyle&&(h=G.createElement("div"),h.style.width="0",h.style.marginRight="0",a.appendChild(h),i.reliableMarginRight=(parseInt((G.defaultView.getComputedStyle(h,null)||{marginRight:0}).marginRight,10)||0)===0),m.innerHTML="",l.removeChild(m);if(a.attachEvent)for(r in{submit:1,change:1,focusin:1})q="on"+r,s=q in a,s||(a.setAttribute(q,"return;"),s=typeof a[q]=="function"),i[r+"Bubbles"]=s;return m=j=e=f=k=h=a=g=null,i}(),J.boxModel=J.support.boxModel;var M=/^(?:\{.*\}|\[.*\])$/,N=/([a-z])([A-Z])/g;J.extend({cache:{},uuid:0,expando:"jQuery"+(J.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?J.cache[a[J.expando]]:a[J.expando],!!a&&!E(a)},data:function(a,c,d,e){if(!!J.acceptData(a)){var f=J.expando,g=typeof c=="string",h,i=a.nodeType,j=i?J.cache:a,k=i?a[J.expando]:a[J.expando]&&J.expando;if((!k||e&&k&&!j[k][f])&&g&&d===b)return;k||(i?a[J.expando]=k=++J.uuid:k=J.expando),j[k]||(j[k]={},i||(j[k].toJSON=J.noop));if(typeof c=="object"||typeof c=="function")e?j[k][f]=J.extend(j[k][f],c):j[k]=J.extend(j[k],c);return h=j[k],e&&(h[f]||(h[f]={}),h=h[f]),d!==b&&(h[J.camelCase(c)]=d),c==="events"&&!h[c]?h[f]&&h[f].events:g?h[J.camelCase(c)]||h[c]:h}},removeData:function(b,c,d){if(!!J.acceptData(b)){var e=J.expando,f=b.nodeType,g=f?J.cache:b,h=f?b[J.expando]:J.expando;if(!g[h])return;if(c){var i=d?g[h][e]:g[h];if(i){delete i[c];if(!E(i))return}}if(d){delete g[h][e];if(!E(g[h]))return}var j=g[h][e];J.support.deleteExpando||g!=a?delete g[h]:g[h]=null,j?(g[h]={},f||(g[h].toJSON=J.noop),g[h][e]=j):f&&(J.support.deleteExpando?delete b[J.expando]:b.removeAttribute?b.removeAttribute(J.expando):b[J.expando]=null)}},_data:function(a,b,c){return J.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=J.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),J.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=J.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,f;for(var g=0,h=e.length;g-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length)return e?(c=J.valHooks[e.nodeName.toLowerCase()]||J.valHooks[e.type],c&&"get"in c&&(d=c.get(e,"value"))!==b?d:(d=e.value,typeof d=="string"?d.replace(Q,""):d==null?"":d)):b;var f=J.isFunction(a);return this.each(function(d){var e=J(this),g;if(this.nodeType===1){f?g=a.call(this,d,e.val()):g=a,g==null?g="":typeof g=="number"?g+="":J.isArray(g)&&(g=J.map(g,function(a){return a==null?"":a+""})),c=J.valHooks[this.nodeName.toLowerCase()]||J.valHooks[this.type];if(!c||!("set"in c)||c.set(this,g,"value")===b)this.value=g}})}}),J.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,f=a.type==="select-one";if(c<0)return null;for(var g=f?c:0,h=f?c+1:e.length;g=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var f=a.nodeType;if(!a||f===3||f===8||f===2)return b;if(e&&c in J.attrFn)return J(a)[c](d);if("getAttribute"in a){var g,h,i=f!==1||!J.isXMLDoc(a);return i&&(c=J.attrFix[c]||c,h=J.attrHooks[c],h||(U.test(c)?h=X:W&&c!=="className"&&(J.nodeName(a,"form")||V.test(c))&&(h=W))),d!==b?d===null?(J.removeAttr(a,c),b):h&&"set"in h&&i&&(g=h.set(a,d,c))!==b?g:(a.setAttribute(c,""+d),d):h&&"get"in h&&i&&(g=h.get(a,c))!==null?g:(g=a.getAttribute(c),g===null?b:g)}return J.prop(a,c,d)},removeAttr:function(a,b){var c;a.nodeType===1&&(b=J.attrFix[b]||b,J.support.getSetAttribute?a.removeAttribute(b):(J.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),U.test(b)&&(c=J.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(R.test(a.nodeName)&&a.parentNode)J.error("type property can't be changed");else if(!J.support.radioValue&&b==="radio"&&J.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):S.test(a.nodeName)||T.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){return W&&J.nodeName(a,"button")?W.get(a,b):b in a?a.value:null},set:function(a,b,c){if(W&&J.nodeName(a,"button"))return W.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var f,g,h=e!==1||!J.isXMLDoc(a);return h&&(c=J.propFix[c]||c,g=J.propHooks[c]),d!==b?g&&"set"in g&&(f=g.set(a,d,c))!==b?f:a[c]=d:g&&"get"in g&&(f=g.get(a,c))!==b?f:a[c]},propHooks:{}}),X={get:function(a,c){return J.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?J.removeAttr(a,c):(d=J.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},J.support.getSetAttribute||(J.attrFix=J.propFix,W=J.attrHooks.name=J.attrHooks.title=J.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d)return d.nodeValue=b,b}},J.each(["width","height"],function(a,b){J.attrHooks[b]=J.extend(J.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})})),J.support.hrefNormalized||J.each(["href","src","width","height"],function(a,c){J.attrHooks[c]=J.extend(J.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),J.support.style||(J.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),J.support.optSelected||(J.propHooks.selected=J.extend(J.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),J.support.checkOn||J.each(["radio","checkbox"],function(){J.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),J.each(["radio","checkbox"],function(){J.valHooks[this]=J.extend(J.valHooks[this],{set:function(a,b){if(J.isArray(b))return a.checked=J.inArray(J(a).val(),b)>=0}})});var Y=/\.(.*)$/,Z=/^(?:textarea|input|select)$/i,$=/\./g,_=/ /g,ba=/[^\w\s.|`]/g,bb=function(a){return a.replace(ba,"\\$&")};J.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var f,g;d.handler&&(f=d,d=f.handler),d.guid||(d.guid=J.guid++);var h=J._data(a);if(!h)return;var i=h.events,j=h.handle;i||(h.events=i={}),j||(h.handle=j=function(a){return typeof J!="undefined"&&(!a||J.event.triggered!==a.type)?J.event.handle.apply(j.elem,arguments):b}),j.elem=a,c=c.split(" ");var k,l=0,m;while(k=c[l++]){g=f?J.extend({},f):{handler:d,data:e},k.indexOf(".")>-1?(m=k.split("."),k=m.shift(),g.namespace=m.slice(0).sort().join(".")):(m=[],g.namespace=""),g.type=k,g.guid||(g.guid=d.guid);var n=i[k],o=J.event.special[k]||{};if(!n){n=i[k]=[];if(!o.setup||o.setup.call(a,e,m,j)===!1)a.addEventListener?a.addEventListener(k,j,!1):a.attachEvent&&a.attachEvent("on"+k,j)}o.add&&(o.add.call(a,g),g.handler.guid||(g.handler.guid=d.guid)),n.push(g),J.event.global[k]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var f,g,h,i,j=0,k,l,m,n,o,p,q,r=J.hasData(a)&&J._data(a),s=r&&r.events;if(!r||!s)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(g in s)J.event.remove(a,g+c);return}c=c.split(" ");while(g=c[j++]){q=g,p=null,k=g.indexOf(".")<0,l=[],k||(l=g.split("."),g=l.shift(),m=new RegExp("(^|\\.)"+J.map(l.slice(0).sort(),bb).join("\\.(?:.*\\.)?")+"(\\.|$)")),o=s[g];if(!o)continue;if(!d){for(i=0;i=0&&(g=g.slice(0,-1),i=!0),g.indexOf(".")>=0&&(h=g.split("."),g=h.shift(),h.sort());if(!!e&&!J.event.customEvent[g]||!!J.event.global[g]){c=typeof c=="object"?c[J.expando]?c:new J.Event(g,c):new J.Event(g),c.type=g,c.exclusive= 17 | i,c.namespace=h.join("."),c.namespace_re=new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.)?")+"(\\.|$)");if(f||!e)c.preventDefault(),c.stopPropagation();if(!e){J.each(J.cache,function(){var a=J.expando,b=this[a];b&&b.events&&b.events[g]&&J.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?J.makeArray(d):[],d.unshift(c);var j=e,k=g.indexOf(":")<0?"on"+g:"";do{var l=J._data(j,"handle");c.currentTarget=j,l&&l.apply(j,d),k&&J.acceptData(j)&&j[k]&&j[k].apply(j,d)===!1&&(c.result=!1,c.preventDefault()),j=j.parentNode||j.ownerDocument||j===c.target.ownerDocument&&a}while(j&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var m,n=J.event.special[g]||{};if((!n._default||n._default.call(e.ownerDocument,c)===!1)&&(g!=="click"||!J.nodeName(e,"a"))&&J.acceptData(e)){try{k&&e[g]&&(m=e[k],m&&(e[k]=null),J.event.triggered=g,e[g]())}catch(o){}m&&(e[k]=m),J.event.triggered=b}}return c.result}},handle:function(c){c=J.event.fix(c||a.event);var d=((J._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,f=Array.prototype.slice.call(arguments,0);f[0]=c,c.currentTarget=this;for(var g=0,h=d.length;g-1?J.map(a.options,function(a){return a.selected}).join("-"):"":J.nodeName(a,"select")&&(c=a.selectedIndex),c},bg=function(a){var c=a.target,d,e;if(!!Z.test(c.nodeName)&&!c.readOnly){d=J._data(c,"_change_data"),e=bf(c),(a.type!=="focusout"||c.type!=="radio")&&J._data(c,"_change_data",e);if(d===b||e===d)return;if(d!=null||e)a.type="change",a.liveFired=b,J.event.trigger(a,arguments[1],c)}};J.event.special.change={filters:{focusout:bg,beforedeactivate:bg,click:function(a){var b=a.target,c=J.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||J.nodeName(b,"select"))&&bg.call(this,a)},keydown:function(a){var b=a.target,c=J.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!J.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&bg.call(this,a)},beforeactivate:function(a){var b=a.target;J._data(b,"_change_data",bf(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in be)J.event.add(this,c+".specialChange",be[c]);return Z.test(this.nodeName)},teardown:function(a){return J.event.remove(this,".specialChange"),Z.test(this.nodeName)}},be=J.event.special.change.filters,be.focus=be.beforeactivate}J.support.focusinBubbles||J.each({focus:"focusin",blur:"focusout"},function(a,b){function c(a){var c=J.event.fix(a);c.type=b,c.originalEvent={},J.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;J.event.special[b]={setup:function(){d++===0&&G.addEventListener(a,c,!0)},teardown:function(){--d===0&&G.removeEventListener(a,c,!0)}}}),J.each(["bind","one"],function(a,c){J.fn[c]=function(a,d,e){var f;if(typeof a=="object"){for(var g in a)this[c](g,d,a[g],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(f=function(a){return J(this).unbind(a,f),e.apply(this,arguments)},f.guid=e.guid||J.guid++):f=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var h=0,i=this.length;h0?this.bind(b,a,c):this.trigger(b)},J.attrFn&&(J.attrFn[b]=!0)}),function(){function a(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function c(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){return h=!1,0});var k=function(a,b,c,e){c=c||[],b=b||G;var g=b;if(b.nodeType!==1&&b.nodeType!==9)return[];if(!a||typeof a!="string")return c;var h,i,j,n,o,q,r,s,u=!0,v=k.isXML(b),w=[],x=a;do{d.exec(""),h=d.exec(x);if(h){x=h[3],w.push(h[1]);if(h[2]){n=h[3];break}}}while(h);if(w.length>1&&m.exec(a))if(w.length===2&&l.relative[w[0]])i=t(w[0]+w[1],b);else{i=l.relative[w[0]]?[b]:k(w.shift(),b);while(w.length)a=w.shift(),l.relative[a]&&(a+=w.shift()),i=t(a,i)}else{!e&&w.length>1&&b.nodeType===9&&!v&&l.match.ID.test(w[0])&&!l.match.ID.test(w[w.length-1])&&(o=k.find(w.shift(),b,v),b=o.expr?k.filter(o.expr,o.set)[0]:o.set[0]);if(b){o=e?{expr:w.pop(),set:p(e)}:k.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&b.parentNode?b.parentNode:b,v),i=o.expr?k.filter(o.expr,o.set):o.set,w.length>0?j=p(i):u=!1;while(w.length)q=w.pop(),r=q,l.relative[q]?r=w.pop():q="",r==null&&(r=b),l.relative[q](j,r,v)}else j=w=[]}j||(j=i),j||k.error(q||a);if(f.call(j)==="[object Array]")if(!u)c.push.apply(c,j);else if(b&&b.nodeType===1)for(s=0;j[s]!=null;s++)j[s]&&(j[s]===!0||j[s].nodeType===1&&k.contains(b,j[s]))&&c.push(i[s]);else for(s=0;j[s]!=null;s++)j[s]&&j[s].nodeType===1&&c.push(i[s]);else p(j,c);return n&&(k(n,g,c,e),k.uniqueSort(c)),c};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);return a[0]=e++,a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");return!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" "),a},PSEUDO:function(a,b,c,e,f){if(a[1]==="not")if((d.exec(a[3])||"").length>1||/^\w/.test(a[3]))a[3]=k(a[3],null,null,b);else{var g=k.filter(a[3],b,c,!0^f);return c||e.push.apply(e,g),!1}else if(l.match.POS.test(a[0])||l.match.CHILD.test(a[0]))return!0;return a},POS:function(a){return a.unshift(!0),a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){return a=Array.prototype.slice.call(a,0),b?(b.push.apply(b,a),b):a};try{Array.prototype.slice.call(G.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(f.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",d.insertBefore(a,d.firstChild),G.getElementById(c)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),d.removeChild(a),d=a=null}(),function(){var a=G.createElement("div");a.appendChild(G.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),G.querySelectorAll&&function(){var a=k,b=G.createElement("div"),c="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,d,e,f){d=d||G;if(!f&&!k.isXML(d)){var g=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(g&&(d.nodeType===1||d.nodeType===9)){if(g[1])return p(d.getElementsByTagName(b),e);if(g[2]&&l.find.CLASS&&d.getElementsByClassName)return p(d.getElementsByClassName(g[2]),e)}if(d.nodeType===9){if(b==="body"&&d.body)return p([d.body],e);if(g&&g[3]){var h=d.getElementById(g[3]);if(!h||!h.parentNode)return p([],e);if(h.id===g[3])return p([h],e)}try{return p(d.querySelectorAll(b),e)}catch(i){}}else if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){var j=d,m=d.getAttribute("id"),n=m||c,o=d.parentNode,q=/^\s*[+~]/.test(b);m?n=n.replace(/'/g,"\\$&"):d.setAttribute("id",n),q&&o&&(d=d.parentNode);try{if(!q||o)return p(d.querySelectorAll("[id='"+n+"'] "+b),e)}catch(r){}finally{m||j.removeAttribute("id")}}}return a(b,d,e,f)};for(var d in a)k[d]=a[d];b=null}}(),function(){var a=G.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var c=!b.call(G.createElement("div"),"div"),d=!1;try{b.call(G.documentElement,"[test!='']:sizzle")}catch(e){d=!0}k.matchesSelector=function(a,e){e=e.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(d||!l.match.PSEUDO.test(e)&&!/!=/.test(e)){var f=b.call(a,e);if(f||!c||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(e,null,null,[a]).length>0}}}(),function(){var a=G.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),G.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:G.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var t=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(g=f;g0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,f=this[0];if(J.isArray(a)){var g,h,i={},j=1;if(f&&a.length){for(d=0,e=a.length;d-1:J(f).is(g))&&c.push({selector:h,elem:f,level:j});f=f.parentNode,j++}}return c}var k=bn.test(a)||typeof a!="string"?J(a,b||this.context):0;for(d=0,e=this.length;d-1:J.find.matchesSelector(f,a)){c.push(f);break}f=f.parentNode;if(!f||!f.ownerDocument||f===b||f.nodeType===11)break}}return c=c.length>1?J.unique(c):c,this.pushStack(c,"closest",a)},index:function(a){return!a||typeof a=="string"?J.inArray(this[0],a?J(a):this.parent().children()):J.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?J(a,b):J.makeArray(a&&a.nodeType?[a]:a),d=J.merge(this.get(),c);return this.pushStack(x(c[0])||x(d[0])?d:J.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),J.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return J.dir(a,"parentNode")},parentsUntil:function(a,b,c){return J.dir(a,"parentNode",c)},next:function(a){return J.nth(a,2,"nextSibling")},prev:function(a){return J.nth(a,2,"previousSibling")},nextAll:function(a){return J.dir(a,"nextSibling")},prevAll:function(a){return J.dir(a,"previousSibling")},nextUntil:function(a,b,c){return J.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return J.dir(a,"previousSibling",c)},siblings:function(a){return J.sibling(a.parentNode.firstChild,a)},children:function(a){return J.sibling(a.firstChild)},contents:function(a){return J.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:J.makeArray(a.childNodes)}},function(a,b){J.fn[a]=function(c,d){var e=J.map(this,b,c),f=bm.call(arguments);return bi.test(a)||(d=c),d&&typeof d=="string"&&(e=J.filter(d,e)),e=this.length>1&&!bo[a]?J.unique(e):e,(this.length>1||bk.test(d))&&bj.test(a)&&(e=e.reverse()),this.pushStack(e,a,f.join(","))}}),J.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?J.find.matchesSelector(b[0],a)?[b[0]]:[]:J.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!J(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bp=/ jQuery\d+="(?:\d+|null)"/g,bq=/^\s+/,br=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,bs=/<([\w:]+)/,bt=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,J.support.htmlSerialize||(bz._default=[1,"div
","
"]),J.fn.extend({text:function(a){return J.isFunction(a)?this.each(function(b){var c=J(this);c.text(a.call(this,b,c.text()))}):typeof a!="object"&&a!==b?this.empty().append((this[0]&&this[0].ownerDocument||G).createTextNode(a)):J.text(this)},wrapAll:function(a){if(J.isFunction(a))return this.each(function(b){J(this).wrapAll(a.call(this,b))});if(this[0]){var b=J(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return J.isFunction(a)?this.each(function(b){J(this).wrapInner(a.call(this,b))}):this.each(function(){var b=J(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){J(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){J.nodeName(this,"body")||J(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=J(arguments[0]);return a.push.apply(a,this.toArray()),this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);return a.push.apply(a,J(arguments[0]).toArray()),a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||J.filter(a,[d]).length)!b&&d.nodeType===1&&(J.cleanData(d.getElementsByTagName("*")),J.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&J.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return J.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(bp,""):null;if(typeof a=="string"&&!bv.test(a)&&(J.support.leadingWhitespace||!bq.test(a))&&!bz[(bs.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(br,"<$1>");try{for(var c=0,d=this.length;c1&&k0?this.clone(!0):this).get();J(e[g])[b](i),d=d.concat(i)}return this.pushStack(d,a,e.selector)}}),J.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,f,g;if((!J.support.noCloneEvent||!J.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!J.isXMLDoc 18 | (a)){t(a,d),e=s(a),f=s(d);for(g=0;e[g];++g)t(e[g],f[g])}if(b){u(a,d);if(c){e=s(a),f=s(d);for(g=0;e[g];++g)u(e[g],f[g])}}return e=f=null,d},clean:function(a,b,c,d){var e;b=b||G,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||G);var f=[],g;for(var h=0,i;(i=a[h])!=null;h++){typeof i=="number"&&(i+="");if(!i)continue;if(typeof i=="string")if(!bu.test(i))i=b.createTextNode(i);else{i=i.replace(br,"<$1>");var j=(bs.exec(i)||["",""])[1].toLowerCase(),k=bz[j]||bz._default,l=k[0],m=b.createElement("div");m.innerHTML=k[1]+i+k[2];while(l--)m=m.lastChild;if(!J.support.tbody){var n=bt.test(i),o=j==="table"&&!n?m.firstChild&&m.firstChild.childNodes:k[1]===""&&!n?m.childNodes:[];for(g=o.length-1;g>=0;--g)J.nodeName(o[g],"tbody")&&!o[g].childNodes.length&&o[g].parentNode.removeChild(o[g])}!J.support.leadingWhitespace&&bq.test(i)&&m.insertBefore(b.createTextNode(bq.exec(i)[0]),m.firstChild),i=m.childNodes}var p;if(!J.support.appendChecked)if(i[0]&&typeof (p=i.length)=="number")for(g=0;g=0)return b+"px"}}}),J.support.opacity||(J.cssHooks.opacity={get:function(a,b){return bB.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=J.isNaN(b)?"":"alpha(opacity="+b*100+")",f=d&&d.filter||c.filter||"";c.filter=bA.test(f)?f.replace(bA,e):f+" "+e}}),J(function(){J.support.reliableMarginRight||(J.cssHooks.marginRight={get:function(a,b){var c;return J.swap(a,{display:"inline-block"},function(){b?c=bK(a,"margin-right","marginRight"):c=a.style.marginRight}),c}})}),G.defaultView&&G.defaultView.getComputedStyle&&(bL=function(a,c){var d,e,f;c=c.replace(bC,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(f=e.getComputedStyle(a,null))d=f.getPropertyValue(c),d===""&&!J.contains(a.ownerDocument.documentElement,a)&&(d=J.style(a,c));return d}),G.documentElement.currentStyle&&(bM=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;return!bD.test(d)&&bE.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e)),d===""?"auto":d}),bK=bL||bM,J.expr&&J.expr.filters&&(J.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!J.support.reliableHiddenOffsets&&(a.style.display||J.css(a,"display"))==="none"},J.expr.filters.visible=function(a){return!J.expr.filters.hidden(a)});var bN=/%20/g,bO=/\[\]$/,bP=/\r?\n/g,bQ=/#.*$/,bR=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bS=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bT=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bU=/^(?:GET|HEAD)$/,bV=/^\/\//,bW=/\?/,bX=/)<[^<]*)*<\/script>/gi,bY=/^(?:select|textarea)/i,bZ=/\s+/,b$=/([?&])_=[^&]*/,b_=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,ca=J.fn.load,cb={},cc={},cd,ce;try{cd=I.href}catch(cf){cd=G.createElement("a"),cd.href="",cd=cd.href}ce=b_.exec(cd.toLowerCase())||[],J.fn.extend({load:function(a,c,d){if(typeof a!="string"&&ca)return ca.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}var g="GET";c&&(J.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=J.param(c,J.ajaxSettings.traditional),g="POST"));var h=this;return J.ajax({url:a,type:g,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),h.html(f?J("
").append(c.replace(bX,"")).find(f):c)),d&&h.each(d,[c,b,a])}}),this},serialize:function(){return J.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?J.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bY.test(this.nodeName)||bS.test(this.type))}).map(function(a,b){var c=J(this).val();return c==null?null:J.isArray(c)?J.map(c,function(a,c){return{name:b.name,value:a.replace(bP,"\r\n")}}):{name:b.name,value:c.replace(bP,"\r\n")}}).get()}}),J.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){J.fn[b]=function(a){return this.bind(b,a)}}),J.each(["get","post"],function(a,c){J[c]=function(a,d,e,f){return J.isFunction(d)&&(f=f||e,e=d,d=b),J.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),J.extend({getScript:function(a,c){return J.get(a,b,c,"script")},getJSON:function(a,b,c){return J.get(a,b,c,"json")},ajaxSetup:function(a,b){b?J.extend(!0,a,J.ajaxSettings,b):(b=a,a=J.extend(!0,J.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in J.ajaxSettings&&(a[c]=J.ajaxSettings[c]);return a},ajaxSettings:{url:cd,isLocal:bT.test(ce[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":J.parseJSON,"text xml":J.parseXML}},ajaxPrefilter:n(cb),ajaxTransport:n(cc),ajax:function(a,c){function d(a,c,d,m){if(v!==2){v=2,t&&clearTimeout(t),s=b,q=m||"",y.readyState=a?4:0;var o,p,r,u=d?k(e,y,d):b,x,z;if(a>=200&&a<300||a===304){if(e.ifModified){if(x=y.getResponseHeader("Last-Modified"))J.lastModified[n]=x;if(z=y.getResponseHeader("Etag"))J.etag[n]=z}if(a===304)c="notmodified",o=!0;else try{p=j(e,u),c="success",o=!0}catch(A){c="parsererror",r=A}}else{r=c;if(!c||a)c="error",a<0&&(a=0)}y.status=a,y.statusText=c,o?h.resolveWith(f,[p,c,y]):h.rejectWith(f,[y,c,r]),y.statusCode(l),l=b,w&&g.trigger("ajax"+(o?"Success":"Error"),[y,e,o?p:r]),i.resolveWith(f,[y,c]),w&&(g.trigger("ajaxComplete",[y,e]),--J.active||J.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var e=J.ajaxSetup({},c),f=e.context||e,g=f!==e&&(f.nodeType||f instanceof J)?J(f):J.event,h=J.Deferred(),i=J._Deferred(),l=e.statusCode||{},n,o={},p={},q,r,s,t,u,v=0,w,x,y={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=p[c]=p[c]||a,o[a]=b}return this},getAllResponseHeaders:function(){return v===2?q:null},getResponseHeader:function(a){var c;if(v===2){if(!r){r={};while(c=bR.exec(q))r[c[1].toLowerCase()]=c[2]}c=r[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(e.mimeType=a),this},abort:function(a){return a=a||"abort",s&&s.abort(a),d(0,a),this}};h.promise(y),y.success=y.done,y.error=y.fail,y.complete=i.done,y.statusCode=function(a){if(a){var b;if(v<2)for(b in a)l[b]=[l[b],a[b]];else b=a[y.status],y.then(b,b)}return this},e.url=((a||e.url)+"").replace(bQ,"").replace(bV,ce[1]+"//"),e.dataTypes=J.trim(e.dataType||"*").toLowerCase().split(bZ),e.crossDomain==null&&(u=b_.exec(e.url.toLowerCase()),e.crossDomain=!(!u||u[1]==ce[1]&&u[2]==ce[2]&&(u[3]||(u[1]==="http:"?80:443))==(ce[3]||(ce[1]==="http:"?80:443)))),e.data&&e.processData&&typeof e.data!="string"&&(e.data=J.param(e.data,e.traditional)),m(cb,e,c,y);if(v===2)return!1;w=e.global,e.type=e.type.toUpperCase(),e.hasContent=!bU.test(e.type),w&&J.active++===0&&J.event.trigger("ajaxStart");if(!e.hasContent){e.data&&(e.url+=(bW.test(e.url)?"&":"?")+e.data),n=e.url;if(e.cache===!1){var z=J.now(),A=e.url.replace(b$,"$1_="+z);e.url=A+(A===e.url?(bW.test(e.url)?"&":"?")+"_="+z:"")}}(e.data&&e.hasContent&&e.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",e.contentType),e.ifModified&&(n=n||e.url,J.lastModified[n]&&y.setRequestHeader("If-Modified-Since",J.lastModified[n]),J.etag[n]&&y.setRequestHeader("If-None-Match",J.etag[n])),y.setRequestHeader("Accept",e.dataTypes[0]&&e.accepts[e.dataTypes[0]]?e.accepts[e.dataTypes[0]]+(e.dataTypes[0]!=="*"?", */*; q=0.01":""):e.accepts["*"]);for(x in e.headers)y.setRequestHeader(x,e.headers[x]);if(!e.beforeSend||e.beforeSend.call(f,y,e)!==!1&&v!==2){for(x in{success:1,error:1,complete:1})y[x](e[x]);s=m(cc,e,c,y);if(!s)d(-1,"No Transport");else{y.readyState=1,w&&g.trigger("ajaxSend",[y,e]),e.async&&e.timeout>0&&(t=setTimeout(function(){y.abort("timeout")},e.timeout));try{v=1,s.send(o,d)}catch(B){status<2?d(-1,B):J.error(B)}}return y}return y.abort(),!1},param:function(a,c){var d=[],e=function(a,b){b=J.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=J.ajaxSettings.traditional);if(J.isArray(a)||a.jquery&&!J.isPlainObject(a))J.each(a,function(){e(this.name,this.value)});else for(var f in a)l(f,a[f],c,e);return d.join("&").replace(bN,"+")}}),J.extend({active:0,lastModified:{},etag:{}});var cg=J.now(),ch=/(\=)\?(&|$)|\?\?/i;J.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return J.expando+"_"+cg++}}),J.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ch.test(b.url)||e&&ch.test(b.data))){var f,g=b.jsonpCallback=J.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h=a[g],i=b.url,j=b.data,k="$1"+g+"$2";return b.jsonp!==!1&&(i=i.replace(ch,k),b.url===i&&(e&&(j=j.replace(ch,k)),b.data===j&&(i+=(/\?/.test(i)?"&":"?")+b.jsonp+"="+g))),b.url=i,b.data=j,a[g]=function(a){f=[a]},d.always(function(){a[g]=h,f&&J.isFunction(h)&&a[g](f[0])}),b.converters["script json"]=function(){return f||J.error(g+" was not called"),f[0]},b.dataTypes[0]="json","script"}}),J.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return J.globalEval(a),a}}}),J.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),J.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=G.head||G.getElementsByTagName("head")[0]||G.documentElement;return{send:function(e,f){c=G.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||f(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var ci=a.ActiveXObject?function(){for(var a in ck)ck[a](0,1)}:!1,cj=0,ck;J.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&i()||h()}:i,function(a){J.extend(J.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(J.ajaxSettings.xhr()),J.support.ajax&&J.ajaxTransport(function(c){if(!c.crossDomain||J.support.cors){var d;return{send:function(e,f){var g=c.xhr(),h,i;c.username?g.open(c.type,c.url,c.async,c.username,c.password):g.open(c.type,c.url,c.async);if(c.xhrFields)for(i in c.xhrFields)g[i]=c.xhrFields[i];c.mimeType&&g.overrideMimeType&&g.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(i in e)g.setRequestHeader(i,e[i])}catch(j){}g.send(c.hasContent&&c.data||null),d=function(a,e){var i,j,k,l,m;try{if(d&&(e||g.readyState===4)){d=b,h&&(g.onreadystatechange=J.noop,ci&&delete ck[h]);if(e)g.readyState!==4&&g.abort();else{i=g.status,k=g.getAllResponseHeaders(),l={},m=g.responseXML,m&&m.documentElement&&(l.xml=m),l.text=g.responseText;try{j=g.statusText}catch(n){j=""}!i&&c.isLocal&&!c.crossDomain?i=l.text?200:404:i===1223&&(i=204)}}}catch(o){e||f(-1,o)}l&&f(i,j,l,k)},!c.async||g.readyState===4?d():(h=++cj,ci&&(ck||(ck={},J(a).unload(ci)),ck[h]=d),g.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cl={},cm,cn,co=/^(?:toggle|show|hide)$/,cp=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cq,cr=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cs,ct=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;J.fn.extend({show:function(a,b,c){var f,g;if(a||a===0)return this.animate(e("show",3),a,b,c);for(var h=0,i=this.length;h=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(f in e.animatedProperties)e.animatedProperties[f]!==!0&&(c=!1);if(c){e.overflow!=null&&!J.support.shrinkWrapBlocks&&J.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&J(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)J.style(d,i,e.orig[i]);e.complete.call(d)}return!1}return e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=J.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update(),!0}},J.extend(J.fx,{tick:function(){for(var a=J.timers,b=0;b
";J.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=h,a.insertBefore(b,a.firstChild),c=b.firstChild,d=c.firstChild,f=c.nextSibling.firstChild.firstChild,this.doesNotAddBorder=d.offsetTop!==5,this.doesAddBorderForTableAndCells=f.offsetTop===5,d.style.position="fixed",d.style.top="20px",this.supportsFixedPosition=d.offsetTop===20||d.offsetTop===15,d.style.position=d.style.top="",c.style.overflow="hidden",c.style.position="relative",this.subtractsBorderForOverflowNotVisible=d.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==g,a.removeChild(b),J.offset.initialize=J.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;return J.offset.initialize(),J.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(J.css(a,"marginTop"))||0,c+=parseFloat(J.css(a,"marginLeft"))||0),{top:b,left:c}},setOffset:function(a,b,c){var d=J.css(a,"position");d==="static"&&(a.style.position="relative");var e=J(a),f=e.offset(),g=J.css(a,"top"),h=J.css(a,"left"),i=(d==="absolute"||d==="fixed")&&J.inArray("auto",[g,h])>-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),J.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},J.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cv.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(J.css(a,"marginTop"))||0,c.left-=parseFloat(J.css(a,"marginLeft"))||0,d.top+=parseFloat(J.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(J.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||G.body;while(a&&!cv.test(a.nodeName)&&J.css(a,"position")==="static")a=a.offsetParent;return a})}}),J.each(["Left","Top"],function(a,d){var e="scroll"+d;J.fn[e]=function(d){var f,g;return d===b?(f=this[0],f?(g=c(f),g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:J.support.boxModel&&g.document.documentElement[e]||g.document.body[e]:f[e]):null):this.each(function(){g=c(this),g?g.scrollTo(a?J(g).scrollLeft():d,a?d:J(g).scrollTop()):this[e]=d})}}),J.each(["Height","Width"],function(a,c){var d=c.toLowerCase();J.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(J.css(a,d,"padding")):null},J.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(J.css(b,d,a?"margin":"border")):null},J.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(J.isFunction(a))return this.each(function(b){var c=J(this);c[d](a.call(this,b,c[d]()))});if(J.isWindow(e)){var f=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&f||e.document.body["client"+c]||f}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var g=J.css(e,d),h=parseFloat(g);return J.isNaN(h)?g:h}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=J})(window) --------------------------------------------------------------------------------